From 1736f2ffc7c92eff5cd117ee7a9c0cb78207dce1 Mon Sep 17 00:00:00 2001 From: Wagyourtail Date: Fri, 23 Dec 2022 16:34:49 -0700 Subject: [PATCH 001/405] replace the world scanner with a 500x faster one --- .../baritone/launch/mixins/MixinBitArray.java | 10 + .../mixins/MixinBlockStateContainer.java | 10 + src/main/java/baritone/BaritoneProvider.java | 3 +- .../baritone/cache/FasterWorldScanner.java | 270 ++++++++++++++++++ .../command/defaults/MineCommand.java | 3 +- .../command/defaults/PathCommand.java | 3 +- .../command/defaults/RepackCommand.java | 3 +- .../java/baritone/process/FarmProcess.java | 3 +- .../java/baritone/process/MineProcess.java | 3 +- .../baritone/utils/accessor/IBitArray.java | 4 + .../utils/accessor/IBlockStateContainer.java | 6 + 11 files changed, 312 insertions(+), 6 deletions(-) create mode 100644 src/main/java/baritone/cache/FasterWorldScanner.java diff --git a/src/launch/java/baritone/launch/mixins/MixinBitArray.java b/src/launch/java/baritone/launch/mixins/MixinBitArray.java index bece3e3bf..bf7d9e535 100644 --- a/src/launch/java/baritone/launch/mixins/MixinBitArray.java +++ b/src/launch/java/baritone/launch/mixins/MixinBitArray.java @@ -64,4 +64,14 @@ public abstract class MixinBitArray implements IBitArray { return out; } + + @Override + public long getMaxEntryValue() { + return maxEntryValue; + } + + @Override + public int getBitsPerEntry() { + return bitsPerEntry; + } } diff --git a/src/launch/java/baritone/launch/mixins/MixinBlockStateContainer.java b/src/launch/java/baritone/launch/mixins/MixinBlockStateContainer.java index f1cc28b9f..566c3cf8b 100644 --- a/src/launch/java/baritone/launch/mixins/MixinBlockStateContainer.java +++ b/src/launch/java/baritone/launch/mixins/MixinBlockStateContainer.java @@ -35,6 +35,16 @@ public abstract class MixinBlockStateContainer implements IBlockStateContainer { @Shadow protected IBlockStatePalette palette; + @Override + public IBlockStatePalette getPalette() { + return palette; + } + + @Override + public BitArray getStorage() { + return storage; + } + @Override public IBlockState getAtPalette(int index) { return palette.getBlockState(index); diff --git a/src/main/java/baritone/BaritoneProvider.java b/src/main/java/baritone/BaritoneProvider.java index d5457cf85..c49c02e10 100644 --- a/src/main/java/baritone/BaritoneProvider.java +++ b/src/main/java/baritone/BaritoneProvider.java @@ -22,6 +22,7 @@ import baritone.api.IBaritoneProvider; import baritone.api.cache.IWorldScanner; import baritone.api.command.ICommandSystem; import baritone.api.schematic.ISchematicSystem; +import baritone.cache.FasterWorldScanner; import baritone.cache.WorldScanner; import baritone.command.CommandSystem; import baritone.command.ExampleBaritoneControl; @@ -59,7 +60,7 @@ public final class BaritoneProvider implements IBaritoneProvider { @Override public IWorldScanner getWorldScanner() { - return WorldScanner.INSTANCE; + return FasterWorldScanner.INSTANCE; } @Override diff --git a/src/main/java/baritone/cache/FasterWorldScanner.java b/src/main/java/baritone/cache/FasterWorldScanner.java new file mode 100644 index 000000000..f1829f9f0 --- /dev/null +++ b/src/main/java/baritone/cache/FasterWorldScanner.java @@ -0,0 +1,270 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.cache; + +import baritone.api.cache.ICachedWorld; +import baritone.api.cache.IWorldScanner; +import baritone.api.utils.BetterBlockPos; +import baritone.api.utils.BlockOptionalMetaLookup; +import baritone.api.utils.IPlayerContext; +import baritone.utils.accessor.IBitArray; +import baritone.utils.accessor.IBlockStateContainer; +import io.netty.buffer.Unpooled; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.BitArray; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.world.chunk.*; +import net.minecraft.world.chunk.storage.ExtendedBlockStorage; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.BiConsumer; +import java.util.function.IntConsumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public enum FasterWorldScanner implements IWorldScanner { + INSTANCE; + @Override + public List scanChunkRadius(IPlayerContext ctx, BlockOptionalMetaLookup filter, int max, int yLevelThreshold, int maxSearchRadius) { + return new WorldScannerContext(filter, ctx).scanAroundPlayerRange(maxSearchRadius); + } + + @Override + public List scanChunk(IPlayerContext ctx, BlockOptionalMetaLookup filter, ChunkPos pos, int max, int yLevelThreshold) { + return new WorldScannerContext(filter, ctx).scanAroundPlayerUntilCount(max); + } + + @Override + public int repack(IPlayerContext ctx) { + return this.repack(ctx, 40); + } + + @Override + public int repack(IPlayerContext ctx, int range) { + IChunkProvider chunkProvider = ctx.world().getChunkProvider(); + ICachedWorld cachedWorld = ctx.worldData().getCachedWorld(); + + BetterBlockPos playerPos = ctx.playerFeet(); + + int playerChunkX = playerPos.getX() >> 4; + int playerChunkZ = playerPos.getZ() >> 4; + + int minX = playerChunkX - range; + int minZ = playerChunkZ - range; + int maxX = playerChunkX + range; + int maxZ = playerChunkZ + range; + + int queued = 0; + for (int x = minX; x <= maxX; x++) { + for (int z = minZ; z <= maxZ; z++) { + Chunk chunk = chunkProvider.getLoadedChunk(x, z); + + if (chunk != null && !chunk.isEmpty()) { + queued++; + cachedWorld.queueForPacking(chunk); + } + } + } + + return queued; + } + + // for porting, see {@link https://github.com/JsMacros/JsMacros/blob/backport-1.12.2/common/src/main/java/xyz/wagyourtail/jsmacros/client/api/classes/worldscanner/WorldScanner.java} + public static class WorldScannerContext { + private final BlockOptionalMetaLookup filter; + private final IPlayerContext ctx; + private final Map cachedFilter = new ConcurrentHashMap<>(); + + public WorldScannerContext(BlockOptionalMetaLookup filter, IPlayerContext ctx) { + this.filter = filter; + this.ctx = ctx; + } + + public List getChunkRange(int centerX, int centerZ, int chunkrange) { + List chunks = new ArrayList<>(); + for (int x = centerX - chunkrange; x <= centerX + chunkrange; x++) { + for (int z = centerZ - chunkrange; z <= centerZ + chunkrange; z++) { + chunks.add(new ChunkPos(x, z)); + } + } + return chunks; + } + + public List scanAroundPlayerRange(int range) { + return scanAroundPlayer(range, -1); + } + + public List scanAroundPlayerUntilCount(int count) { + return scanAroundPlayer(32, count); + } + + public List scanAroundPlayer(int range, int maxCount) { + assert ctx.player() != null; + return scanChunkRange(ctx.playerFeet().x >> 4, ctx.playerFeet().z >> 4, range, maxCount); + } + + public List scanChunkRange(int centerX, int centerZ, int chunkRange, int maxBlocks) { + assert ctx.world() != null; + if (chunkRange < 0) { + throw new IllegalArgumentException("chunkRange must be >= 0"); + } + return scanChunksInternal(getChunkRange(centerX, centerZ, chunkRange), maxBlocks); + } + + private List scanChunksInternal(List chunkPositions, int maxBlocks) { + assert ctx.world() != null; + return chunkPositions.parallelStream().flatMap(this::scanChunkInternal).limit(maxBlocks <= 0 ? Long.MAX_VALUE : maxBlocks).collect(Collectors.toList()); + } + private Stream scanChunkInternal(ChunkPos pos) { + IChunkProvider chunkProvider = ctx.world().getChunkProvider(); + // if chunk is not loaded, return empty stream + if (!chunkProvider.isChunkGeneratedAt(pos.x, pos.z)) { + return Stream.empty(); + } + + long chunkX = (long) pos.x << 4; + long chunkZ = (long) pos.z << 4; + + List blocks = new ArrayList<>(); + + streamChunkSections(chunkProvider.getLoadedChunk(pos.x, pos.z), (section, isInFilter) -> { + int yOffset = section.getYLocation(); + BitArray array = (BitArray) ((IBlockStateContainer) section.getData()).getStorage(); + forEach(array, isInFilter, place -> blocks.add(new BlockPos( + chunkX + ((place & 255) & 15), + yOffset + (place >> 8), + chunkZ + ((place & 255) >> 4) + ))); + }); + return blocks.stream(); + } + + private void streamChunkSections(Chunk chunk, BiConsumer consumer) { + for (ExtendedBlockStorage section : chunk.getBlockStorageArray()) { + if (section == null || section.isEmpty()) { + continue; + } + + BlockStateContainer sectionContainer = section.getData(); + //this won't work if the PaletteStorage is of the type EmptyPaletteStorage + if (((IBlockStateContainer) sectionContainer).getStorage() == null) { + continue; + } + + boolean[] isInFilter = getIncludedFilterIndices(((IBlockStateContainer) sectionContainer).getPalette()); + if (isInFilter.length == 0) { + continue; + } + consumer.accept(section, isInFilter); + } + } + + private boolean getFilterResult(IBlockState state) { + Boolean v; + return (v = cachedFilter.get(state)) == null ? addCachedState(state) : v; + } + + private boolean addCachedState(IBlockState state) { + boolean isInFilter = false; + + if (filter != null) { + isInFilter = filter.has(state); + } + + cachedFilter.put(state, isInFilter); + return isInFilter; + } + + private boolean[] getIncludedFilterIndices(IBlockStatePalette palette) { + boolean commonBlockFound = false; + Int2ObjectOpenHashMap paletteMap = getPalette(palette); + int size = paletteMap.size(); + + boolean[] isInFilter = new boolean[size]; + + for (int i = 0; i < size; i++) { + IBlockState state = paletteMap.get(i); + if (getFilterResult(state)) { + isInFilter[i] = true; + commonBlockFound = true; + } else { + isInFilter[i] = false; + } + } + + if (!commonBlockFound) { + return new boolean[0]; + } + return isInFilter; + } + + private static void forEach(BitArray array, boolean[] isInFilter, IntConsumer action) { + int counter = 0; + long[] storage = array.getBackingLongArray(); + int arraySize = array.size(); + int elementBits = ((IBitArray) array).getBitsPerEntry(); + long maxValue = ((IBitArray) array).getMaxEntryValue(); + int storageLength = storage.length; + + if (storageLength != 0) { + int lastStorageIdx = 0; + long row = storage[0]; + long nextRow = storageLength > 1 ? storage[1] : 0L; + + for (int idx = 0; idx < arraySize; idx++) { + int n = idx * elementBits; + int storageIdx = n >> 6; + int p = (idx + 1) * elementBits - 1 >> 6; + int q = n ^ storageIdx << 6; + if (storageIdx != lastStorageIdx) { + row = nextRow; + nextRow = storageIdx + 1 < storageLength ? storage[storageIdx + 1] : 0L; + lastStorageIdx = storageIdx; + } + if (storageIdx == p) { + if (isInFilter[(int) (row >>> q & maxValue)]) { + action.accept(counter); + } else { + if (isInFilter[(int) ((row >>> q | nextRow << (64 - q)) & maxValue)]) { + action.accept(counter); + } + } + } + } + } + } + + private static Int2ObjectOpenHashMap getPalette(IBlockStatePalette palette) { + PacketBuffer buf = new PacketBuffer(Unpooled.buffer()); + palette.write(buf); + int size = buf.readVarInt(); + Int2ObjectOpenHashMap paletteMap = new Int2ObjectOpenHashMap<>(size); + for (int i = 0; i < size; i++) { + paletteMap.put(i, Block.BLOCK_STATE_IDS.getByValue(buf.readVarInt())); + } + return paletteMap; + } + } +} diff --git a/src/main/java/baritone/command/defaults/MineCommand.java b/src/main/java/baritone/command/defaults/MineCommand.java index 63712fe3e..1ab5c3321 100644 --- a/src/main/java/baritone/command/defaults/MineCommand.java +++ b/src/main/java/baritone/command/defaults/MineCommand.java @@ -17,6 +17,7 @@ package baritone.command.defaults; +import baritone.api.BaritoneAPI; import baritone.api.IBaritone; import baritone.api.command.Command; import baritone.api.command.argument.IArgConsumer; @@ -45,7 +46,7 @@ public class MineCommand extends Command { while (args.hasAny()) { boms.add(args.getDatatypeFor(ForBlockOptionalMeta.INSTANCE)); } - WorldScanner.INSTANCE.repack(ctx); + BaritoneAPI.getProvider().getWorldScanner().repack(ctx); logDirect(String.format("Mining %s", boms.toString())); baritone.getMineProcess().mine(quantity, boms.toArray(new BlockOptionalMeta[0])); } diff --git a/src/main/java/baritone/command/defaults/PathCommand.java b/src/main/java/baritone/command/defaults/PathCommand.java index 182a1e5bc..24f47d625 100644 --- a/src/main/java/baritone/command/defaults/PathCommand.java +++ b/src/main/java/baritone/command/defaults/PathCommand.java @@ -17,6 +17,7 @@ package baritone.command.defaults; +import baritone.api.BaritoneAPI; import baritone.api.IBaritone; import baritone.api.command.Command; import baritone.api.command.argument.IArgConsumer; @@ -38,7 +39,7 @@ public class PathCommand extends Command { public void execute(String label, IArgConsumer args) throws CommandException { ICustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess(); args.requireMax(0); - WorldScanner.INSTANCE.repack(ctx); + BaritoneAPI.getProvider().getWorldScanner().repack(ctx); customGoalProcess.path(); logDirect("Now pathing"); } diff --git a/src/main/java/baritone/command/defaults/RepackCommand.java b/src/main/java/baritone/command/defaults/RepackCommand.java index cafbea524..cd054b10b 100644 --- a/src/main/java/baritone/command/defaults/RepackCommand.java +++ b/src/main/java/baritone/command/defaults/RepackCommand.java @@ -17,6 +17,7 @@ package baritone.command.defaults; +import baritone.api.BaritoneAPI; import baritone.api.IBaritone; import baritone.api.command.Command; import baritone.api.command.argument.IArgConsumer; @@ -36,7 +37,7 @@ public class RepackCommand extends Command { @Override public void execute(String label, IArgConsumer args) throws CommandException { args.requireMax(0); - logDirect(String.format("Queued %d chunks for repacking", WorldScanner.INSTANCE.repack(ctx))); + logDirect(String.format("Queued %d chunks for repacking", BaritoneAPI.getProvider().getWorldScanner().repack(ctx))); } @Override diff --git a/src/main/java/baritone/process/FarmProcess.java b/src/main/java/baritone/process/FarmProcess.java index 0ef85f07d..73c575d22 100644 --- a/src/main/java/baritone/process/FarmProcess.java +++ b/src/main/java/baritone/process/FarmProcess.java @@ -18,6 +18,7 @@ package baritone.process; import baritone.Baritone; +import baritone.api.BaritoneAPI; import baritone.api.pathing.goals.Goal; import baritone.api.pathing.goals.GoalBlock; import baritone.api.pathing.goals.GoalComposite; @@ -189,7 +190,7 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro } if (Baritone.settings().mineGoalUpdateInterval.value != 0 && tickCount++ % Baritone.settings().mineGoalUpdateInterval.value == 0) { - Baritone.getExecutor().execute(() -> locations = WorldScanner.INSTANCE.scanChunkRadius(ctx, scan, 256, 10, 10)); + Baritone.getExecutor().execute(() -> locations = BaritoneAPI.getProvider().getWorldScanner().scanChunkRadius(ctx, scan, 256, 10, 10)); } if (locations == null) { return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); diff --git a/src/main/java/baritone/process/MineProcess.java b/src/main/java/baritone/process/MineProcess.java index 1ec47cd92..a10a569aa 100644 --- a/src/main/java/baritone/process/MineProcess.java +++ b/src/main/java/baritone/process/MineProcess.java @@ -18,6 +18,7 @@ package baritone.process; import baritone.Baritone; +import baritone.api.BaritoneAPI; import baritone.api.pathing.goals.*; import baritone.api.process.IMineProcess; import baritone.api.process.PathingCommand; @@ -355,7 +356,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro locs = prune(ctx, locs, filter, max, blacklist, dropped); if (!untracked.isEmpty() || (Baritone.settings().extendCacheOnThreshold.value && locs.size() < max)) { - locs.addAll(WorldScanner.INSTANCE.scanChunkRadius( + locs.addAll(BaritoneAPI.getProvider().getWorldScanner().scanChunkRadius( ctx.getBaritone().getPlayerContext(), filter, max, diff --git a/src/main/java/baritone/utils/accessor/IBitArray.java b/src/main/java/baritone/utils/accessor/IBitArray.java index baea5c1da..08f54584c 100644 --- a/src/main/java/baritone/utils/accessor/IBitArray.java +++ b/src/main/java/baritone/utils/accessor/IBitArray.java @@ -3,4 +3,8 @@ package baritone.utils.accessor; public interface IBitArray { int[] toArray(); + + long getMaxEntryValue(); + + int getBitsPerEntry(); } diff --git a/src/main/java/baritone/utils/accessor/IBlockStateContainer.java b/src/main/java/baritone/utils/accessor/IBlockStateContainer.java index 39572fc5d..bd280aeb1 100644 --- a/src/main/java/baritone/utils/accessor/IBlockStateContainer.java +++ b/src/main/java/baritone/utils/accessor/IBlockStateContainer.java @@ -1,9 +1,15 @@ package baritone.utils.accessor; import net.minecraft.block.state.IBlockState; +import net.minecraft.util.BitArray; +import net.minecraft.world.chunk.IBlockStatePalette; public interface IBlockStateContainer { + IBlockStatePalette getPalette(); + + BitArray getStorage(); + IBlockState getAtPalette(int index); int[] storageArray(); From 0b6088cd2df5ee5a099ec7a63fa00ad0378d0c6a Mon Sep 17 00:00:00 2001 From: Wagyourtail Date: Fri, 23 Dec 2022 16:58:10 -0700 Subject: [PATCH 002/405] fix getting the block from the pallete, and change the chunk scan order to spiral out --- .../baritone/cache/FasterWorldScanner.java | 62 ++++++++++--------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/src/main/java/baritone/cache/FasterWorldScanner.java b/src/main/java/baritone/cache/FasterWorldScanner.java index f1829f9f0..189374dd6 100644 --- a/src/main/java/baritone/cache/FasterWorldScanner.java +++ b/src/main/java/baritone/cache/FasterWorldScanner.java @@ -102,12 +102,27 @@ public enum FasterWorldScanner implements IWorldScanner { this.ctx = ctx; } - public List getChunkRange(int centerX, int centerZ, int chunkrange) { + public List getChunkRange(int centerX, int centerZ, int chunkRadius) { List chunks = new ArrayList<>(); - for (int x = centerX - chunkrange; x <= centerX + chunkrange; x++) { - for (int z = centerZ - chunkrange; z <= centerZ + chunkrange; z++) { + // spiral out + int x = centerX; + int z = centerZ; + int dx = 0; + int dz = -1; + int t = Math.max(chunkRadius, 1); + int maxI = t * t; + for (int i = 0; i < maxI; i++) { + if ((-chunkRadius / 2 <= x) && (x <= chunkRadius / 2) && (-chunkRadius / 2 <= z) && (z <= chunkRadius / 2)) { chunks.add(new ChunkPos(x, z)); } + // idk how this works, copilot did it + if ((x == z) || ((x < 0) && (x == -z)) || ((x > 0) && (x == 1 - z))) { + t = dx; + dx = -dz; + dz = t; + } + x += dx; + z += dz; } return chunks; } @@ -221,36 +236,25 @@ public enum FasterWorldScanner implements IWorldScanner { } private static void forEach(BitArray array, boolean[] isInFilter, IntConsumer action) { - int counter = 0; - long[] storage = array.getBackingLongArray(); + long[] longArray = array.getBackingLongArray(); int arraySize = array.size(); - int elementBits = ((IBitArray) array).getBitsPerEntry(); - long maxValue = ((IBitArray) array).getMaxEntryValue(); - int storageLength = storage.length; + int bitsPerEntry = ((IBitArray) array).getBitsPerEntry(); + long maxEntryValue = ((IBitArray) array).getMaxEntryValue(); - if (storageLength != 0) { - int lastStorageIdx = 0; - long row = storage[0]; - long nextRow = storageLength > 1 ? storage[1] : 0L; + for (int idx = 0, kl = bitsPerEntry - 1; idx < arraySize; idx++, kl += bitsPerEntry) { + final int i = idx * bitsPerEntry; + final int j = i >> 6; + final int l = i & 63; + final int k = kl >> 6; + final long jl = longArray[j] >>> l; - for (int idx = 0; idx < arraySize; idx++) { - int n = idx * elementBits; - int storageIdx = n >> 6; - int p = (idx + 1) * elementBits - 1 >> 6; - int q = n ^ storageIdx << 6; - if (storageIdx != lastStorageIdx) { - row = nextRow; - nextRow = storageIdx + 1 < storageLength ? storage[storageIdx + 1] : 0L; - lastStorageIdx = storageIdx; + if (j == k) { + if (isInFilter[(int) (jl & maxEntryValue)]) { + action.accept(idx); } - if (storageIdx == p) { - if (isInFilter[(int) (row >>> q & maxValue)]) { - action.accept(counter); - } else { - if (isInFilter[(int) ((row >>> q | nextRow << (64 - q)) & maxValue)]) { - action.accept(counter); - } - } + } else { + if (isInFilter[(int) ((jl | longArray[k] << (64 - l)) & maxEntryValue)]) { + action.accept(idx); } } } From 12b596e53696212515087f458167775d45d12a85 Mon Sep 17 00:00:00 2001 From: Wagyourtail Date: Fri, 23 Dec 2022 17:10:37 -0700 Subject: [PATCH 003/405] fix spiral --- .../baritone/cache/FasterWorldScanner.java | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/main/java/baritone/cache/FasterWorldScanner.java b/src/main/java/baritone/cache/FasterWorldScanner.java index 189374dd6..ce4a8cd48 100644 --- a/src/main/java/baritone/cache/FasterWorldScanner.java +++ b/src/main/java/baritone/cache/FasterWorldScanner.java @@ -105,24 +105,16 @@ public enum FasterWorldScanner implements IWorldScanner { public List getChunkRange(int centerX, int centerZ, int chunkRadius) { List chunks = new ArrayList<>(); // spiral out - int x = centerX; - int z = centerZ; - int dx = 0; - int dz = -1; - int t = Math.max(chunkRadius, 1); - int maxI = t * t; - for (int i = 0; i < maxI; i++) { - if ((-chunkRadius / 2 <= x) && (x <= chunkRadius / 2) && (-chunkRadius / 2 <= z) && (z <= chunkRadius / 2)) { - chunks.add(new ChunkPos(x, z)); + chunks.add(new ChunkPos(centerX, centerZ)); + for (int i = 1; i < chunkRadius; i++) { + for (int x = centerX - i; x <= centerX + i; x++) { + chunks.add(new ChunkPos(x, centerZ - i)); + chunks.add(new ChunkPos(x, centerZ + i)); } - // idk how this works, copilot did it - if ((x == z) || ((x < 0) && (x == -z)) || ((x > 0) && (x == 1 - z))) { - t = dx; - dx = -dz; - dz = t; + for (int z = centerZ - i + 1; z <= centerZ + i - 1; z++) { + chunks.add(new ChunkPos(centerX - i, z)); + chunks.add(new ChunkPos(centerX + i, z)); } - x += dx; - z += dz; } return chunks; } From 0ae59755e3ade3f576d4e83ae9b4b5abef542b75 Mon Sep 17 00:00:00 2001 From: Wagyourtail Date: Fri, 23 Dec 2022 17:25:23 -0700 Subject: [PATCH 004/405] make limit not happen if it shouldn't --- .../baritone/cache/FasterWorldScanner.java | 44 ++++++++++++++----- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/src/main/java/baritone/cache/FasterWorldScanner.java b/src/main/java/baritone/cache/FasterWorldScanner.java index ce4a8cd48..535e925e1 100644 --- a/src/main/java/baritone/cache/FasterWorldScanner.java +++ b/src/main/java/baritone/cache/FasterWorldScanner.java @@ -30,6 +30,7 @@ import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.network.PacketBuffer; import net.minecraft.util.BitArray; +import net.minecraft.util.ObjectIntIdentityMap; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkPos; import net.minecraft.world.chunk.*; @@ -142,8 +143,20 @@ public enum FasterWorldScanner implements IWorldScanner { private List scanChunksInternal(List chunkPositions, int maxBlocks) { assert ctx.world() != null; - return chunkPositions.parallelStream().flatMap(this::scanChunkInternal).limit(maxBlocks <= 0 ? Long.MAX_VALUE : maxBlocks).collect(Collectors.toList()); + try { + Stream posStream = chunkPositions.parallelStream().flatMap(this::scanChunkInternal); + if (maxBlocks >= 0) { + // WARNING: this can be expensive if maxBlocks is large... + // see limit's javadoc + posStream = posStream.limit(maxBlocks); + } + return posStream.collect(Collectors.toList()); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } } + private Stream scanChunkInternal(ChunkPos pos) { IChunkProvider chunkProvider = ctx.world().getChunkProvider(); // if chunk is not loaded, return empty stream @@ -206,13 +219,13 @@ public enum FasterWorldScanner implements IWorldScanner { private boolean[] getIncludedFilterIndices(IBlockStatePalette palette) { boolean commonBlockFound = false; - Int2ObjectOpenHashMap paletteMap = getPalette(palette); + ObjectIntIdentityMap paletteMap = getPalette(palette); int size = paletteMap.size(); boolean[] isInFilter = new boolean[size]; for (int i = 0; i < size; i++) { - IBlockState state = paletteMap.get(i); + IBlockState state = paletteMap.getByValue(i); if (getFilterResult(state)) { isInFilter[i] = true; commonBlockFound = true; @@ -252,15 +265,24 @@ public enum FasterWorldScanner implements IWorldScanner { } } - private static Int2ObjectOpenHashMap getPalette(IBlockStatePalette palette) { - PacketBuffer buf = new PacketBuffer(Unpooled.buffer()); - palette.write(buf); - int size = buf.readVarInt(); - Int2ObjectOpenHashMap paletteMap = new Int2ObjectOpenHashMap<>(size); - for (int i = 0; i < size; i++) { - paletteMap.put(i, Block.BLOCK_STATE_IDS.getByValue(buf.readVarInt())); + /** + * cheats to get the actual map of id -> blockstate from the various palette implementations + */ + private static ObjectIntIdentityMap getPalette(IBlockStatePalette palette) { + if (palette instanceof BlockStatePaletteRegistry) { + return Block.BLOCK_STATE_IDS; + } else { + PacketBuffer buf = new PacketBuffer(Unpooled.buffer()); + palette.write(buf); + int size = buf.readVarInt(); + ObjectIntIdentityMap states = new ObjectIntIdentityMap<>(); + for (int i = 0; i < size; i++) { + IBlockState state = Block.BLOCK_STATE_IDS.getByValue(buf.readVarInt()); + assert state != null; + states.put(state, i); + } + return states; } - return paletteMap; } } } From 96f432d2d550ca92a8e96c66981696a62bb628b1 Mon Sep 17 00:00:00 2001 From: Wagyourtail Date: Fri, 23 Dec 2022 17:26:46 -0700 Subject: [PATCH 005/405] add comment --- src/main/java/baritone/cache/FasterWorldScanner.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/baritone/cache/FasterWorldScanner.java b/src/main/java/baritone/cache/FasterWorldScanner.java index 535e925e1..6c110decb 100644 --- a/src/main/java/baritone/cache/FasterWorldScanner.java +++ b/src/main/java/baritone/cache/FasterWorldScanner.java @@ -93,6 +93,7 @@ public enum FasterWorldScanner implements IWorldScanner { } // for porting, see {@link https://github.com/JsMacros/JsMacros/blob/backport-1.12.2/common/src/main/java/xyz/wagyourtail/jsmacros/client/api/classes/worldscanner/WorldScanner.java} + // tho I did change some things... public static class WorldScannerContext { private final BlockOptionalMetaLookup filter; private final IPlayerContext ctx; From ecdec87e7a7a8107eefe20a7797decf4ad1e7972 Mon Sep 17 00:00:00 2001 From: Wagyourtail Date: Sat, 24 Dec 2022 11:43:54 -0700 Subject: [PATCH 006/405] fix using wrong functions in scan --- src/main/java/baritone/cache/FasterWorldScanner.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/baritone/cache/FasterWorldScanner.java b/src/main/java/baritone/cache/FasterWorldScanner.java index 6c110decb..ace429de9 100644 --- a/src/main/java/baritone/cache/FasterWorldScanner.java +++ b/src/main/java/baritone/cache/FasterWorldScanner.java @@ -25,7 +25,6 @@ import baritone.api.utils.IPlayerContext; import baritone.utils.accessor.IBitArray; import baritone.utils.accessor.IBlockStateContainer; import io.netty.buffer.Unpooled; -import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.network.PacketBuffer; @@ -49,12 +48,12 @@ public enum FasterWorldScanner implements IWorldScanner { INSTANCE; @Override public List scanChunkRadius(IPlayerContext ctx, BlockOptionalMetaLookup filter, int max, int yLevelThreshold, int maxSearchRadius) { - return new WorldScannerContext(filter, ctx).scanAroundPlayerRange(maxSearchRadius); + return new WorldScannerContext(filter, ctx).scanAroundPlayer(maxSearchRadius, max); } @Override public List scanChunk(IPlayerContext ctx, BlockOptionalMetaLookup filter, ChunkPos pos, int max, int yLevelThreshold) { - return new WorldScannerContext(filter, ctx).scanAroundPlayerUntilCount(max); + return new WorldScannerContext(filter, ctx).scanChunkInternal(pos).collect(Collectors.toList()); } @Override From ce1fb49252e897f0b223e1bbdc18bb096ac56678 Mon Sep 17 00:00:00 2001 From: Wagyourtail Date: Sat, 24 Dec 2022 11:52:48 -0700 Subject: [PATCH 007/405] spiral always pick closest chunk first now --- .../baritone/cache/FasterWorldScanner.java | 42 ++++++++++--------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/main/java/baritone/cache/FasterWorldScanner.java b/src/main/java/baritone/cache/FasterWorldScanner.java index ace429de9..efb80245a 100644 --- a/src/main/java/baritone/cache/FasterWorldScanner.java +++ b/src/main/java/baritone/cache/FasterWorldScanner.java @@ -91,34 +91,38 @@ public enum FasterWorldScanner implements IWorldScanner { return queued; } - // for porting, see {@link https://github.com/JsMacros/JsMacros/blob/backport-1.12.2/common/src/main/java/xyz/wagyourtail/jsmacros/client/api/classes/worldscanner/WorldScanner.java} - // tho I did change some things... + // ordered in a way that the closest blocks are generally first + public List getChunkRange(int centerX, int centerZ, int chunkRadius) { + List chunks = new ArrayList<>(); + // spiral out + chunks.add(new ChunkPos(centerX, centerZ)); + for (int i = 1; i < chunkRadius; i++) { + for (int j = 0; j <= i; j++) { + chunks.add(new ChunkPos(centerX - j, centerZ - i)); + chunks.add(new ChunkPos(centerX + j, centerZ - i)); + chunks.add(new ChunkPos(centerX - j, centerZ + i)); + chunks.add(new ChunkPos(centerX + j, centerZ + i)); + if (j != 0 && j != i) { + chunks.add(new ChunkPos(centerX - i, centerZ - j)); + chunks.add(new ChunkPos(centerX + i, centerZ - j)); + chunks.add(new ChunkPos(centerX - i, centerZ + j)); + chunks.add(new ChunkPos(centerX + i, centerZ + j)); + } + } + } + return chunks; + } + public static class WorldScannerContext { private final BlockOptionalMetaLookup filter; private final IPlayerContext ctx; - private final Map cachedFilter = new ConcurrentHashMap<>(); public WorldScannerContext(BlockOptionalMetaLookup filter, IPlayerContext ctx) { this.filter = filter; this.ctx = ctx; } - public List getChunkRange(int centerX, int centerZ, int chunkRadius) { - List chunks = new ArrayList<>(); - // spiral out - chunks.add(new ChunkPos(centerX, centerZ)); - for (int i = 1; i < chunkRadius; i++) { - for (int x = centerX - i; x <= centerX + i; x++) { - chunks.add(new ChunkPos(x, centerZ - i)); - chunks.add(new ChunkPos(x, centerZ + i)); - } - for (int z = centerZ - i + 1; z <= centerZ + i - 1; z++) { - chunks.add(new ChunkPos(centerX - i, z)); - chunks.add(new ChunkPos(centerX + i, z)); - } - } - return chunks; - } + public List scanAroundPlayerRange(int range) { return scanAroundPlayer(range, -1); From 6260c6d3d7edd984a8b2b900770d4d11c60d4dbd Mon Sep 17 00:00:00 2001 From: Wagyourtail Date: Sat, 24 Dec 2022 12:11:26 -0700 Subject: [PATCH 008/405] apply suggestions --- .../baritone/api/utils/BlockOptionalMeta.java | 4 + .../api/utils/BlockOptionalMetaLookup.java | 25 +- .../baritone/cache/FasterWorldScanner.java | 279 ++++++++---------- 3 files changed, 132 insertions(+), 176 deletions(-) diff --git a/src/api/java/baritone/api/utils/BlockOptionalMeta.java b/src/api/java/baritone/api/utils/BlockOptionalMeta.java index a9a34a4aa..e86341816 100644 --- a/src/api/java/baritone/api/utils/BlockOptionalMeta.java +++ b/src/api/java/baritone/api/utils/BlockOptionalMeta.java @@ -315,4 +315,8 @@ public final class BlockOptionalMeta { return null; } + + public Set getAllBlockStates() { + return blockstates; + } } diff --git a/src/api/java/baritone/api/utils/BlockOptionalMetaLookup.java b/src/api/java/baritone/api/utils/BlockOptionalMetaLookup.java index 041c6162c..8fb52fb52 100644 --- a/src/api/java/baritone/api/utils/BlockOptionalMetaLookup.java +++ b/src/api/java/baritone/api/utils/BlockOptionalMetaLookup.java @@ -22,15 +22,22 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.item.ItemStack; import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.stream.Stream; public class BlockOptionalMetaLookup { - + private final Set blockSet = new HashSet<>(); + private final Set blockStateSet = new HashSet<>(); private final BlockOptionalMeta[] boms; public BlockOptionalMetaLookup(BlockOptionalMeta... boms) { this.boms = boms; + for (BlockOptionalMeta bom : boms) { + blockSet.add(bom.getBlock()); + blockStateSet.addAll(bom.getAllBlockStates()); + } } public BlockOptionalMetaLookup(Block... blocks) { @@ -52,23 +59,11 @@ public class BlockOptionalMetaLookup { } public boolean has(Block block) { - for (BlockOptionalMeta bom : boms) { - if (bom.getBlock() == block) { - return true; - } - } - - return false; + return blockSet.contains(block); } public boolean has(IBlockState state) { - for (BlockOptionalMeta bom : boms) { - if (bom.matches(state)) { - return true; - } - } - - return false; + return blockStateSet.contains(state); } public boolean has(ItemStack stack) { diff --git a/src/main/java/baritone/cache/FasterWorldScanner.java b/src/main/java/baritone/cache/FasterWorldScanner.java index efb80245a..7a46f04ff 100644 --- a/src/main/java/baritone/cache/FasterWorldScanner.java +++ b/src/main/java/baritone/cache/FasterWorldScanner.java @@ -37,8 +37,6 @@ import net.minecraft.world.chunk.storage.ExtendedBlockStorage; import java.util.ArrayList; import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiConsumer; import java.util.function.IntConsumer; import java.util.stream.Collectors; @@ -48,12 +46,16 @@ public enum FasterWorldScanner implements IWorldScanner { INSTANCE; @Override public List scanChunkRadius(IPlayerContext ctx, BlockOptionalMetaLookup filter, int max, int yLevelThreshold, int maxSearchRadius) { - return new WorldScannerContext(filter, ctx).scanAroundPlayer(maxSearchRadius, max); + assert ctx.world() != null; + if (maxSearchRadius < 0) { + throw new IllegalArgumentException("chunkRange must be >= 0"); + } + return scanChunksInternal(ctx, filter, getChunkRange(ctx.playerFeet().x >> 4, ctx.playerFeet().z >> 4, maxSearchRadius), max); } @Override public List scanChunk(IPlayerContext ctx, BlockOptionalMetaLookup filter, ChunkPos pos, int max, int yLevelThreshold) { - return new WorldScannerContext(filter, ctx).scanChunkInternal(pos).collect(Collectors.toList()); + return scanChunkInternal(ctx, filter, pos).limit(max).collect(Collectors.toList()); } @Override @@ -92,15 +94,17 @@ public enum FasterWorldScanner implements IWorldScanner { } // ordered in a way that the closest blocks are generally first - public List getChunkRange(int centerX, int centerZ, int chunkRadius) { + public static List getChunkRange(int centerX, int centerZ, int chunkRadius) { List chunks = new ArrayList<>(); // spiral out chunks.add(new ChunkPos(centerX, centerZ)); for (int i = 1; i < chunkRadius; i++) { for (int j = 0; j <= i; j++) { chunks.add(new ChunkPos(centerX - j, centerZ - i)); - chunks.add(new ChunkPos(centerX + j, centerZ - i)); - chunks.add(new ChunkPos(centerX - j, centerZ + i)); + if (j != 0) { + chunks.add(new ChunkPos(centerX + j, centerZ - i)); + chunks.add(new ChunkPos(centerX - j, centerZ + i)); + } chunks.add(new ChunkPos(centerX + j, centerZ + i)); if (j != 0 && j != i) { chunks.add(new ChunkPos(centerX - i, centerZ - j)); @@ -113,180 +117,133 @@ public enum FasterWorldScanner implements IWorldScanner { return chunks; } - public static class WorldScannerContext { - private final BlockOptionalMetaLookup filter; - private final IPlayerContext ctx; - - public WorldScannerContext(BlockOptionalMetaLookup filter, IPlayerContext ctx) { - this.filter = filter; - this.ctx = ctx; - } - - - - public List scanAroundPlayerRange(int range) { - return scanAroundPlayer(range, -1); - } - - public List scanAroundPlayerUntilCount(int count) { - return scanAroundPlayer(32, count); - } - - public List scanAroundPlayer(int range, int maxCount) { - assert ctx.player() != null; - return scanChunkRange(ctx.playerFeet().x >> 4, ctx.playerFeet().z >> 4, range, maxCount); - } - - public List scanChunkRange(int centerX, int centerZ, int chunkRange, int maxBlocks) { - assert ctx.world() != null; - if (chunkRange < 0) { - throw new IllegalArgumentException("chunkRange must be >= 0"); - } - return scanChunksInternal(getChunkRange(centerX, centerZ, chunkRange), maxBlocks); - } - - private List scanChunksInternal(List chunkPositions, int maxBlocks) { - assert ctx.world() != null; - try { - Stream posStream = chunkPositions.parallelStream().flatMap(this::scanChunkInternal); + private List scanChunksInternal(IPlayerContext ctx, BlockOptionalMetaLookup lookup, List chunkPositions, int maxBlocks) { + assert ctx.world() != null; + try { + Stream posStream = chunkPositions.parallelStream().flatMap(p -> scanChunkInternal(ctx, lookup, p)); if (maxBlocks >= 0) { // WARNING: this can be expensive if maxBlocks is large... // see limit's javadoc posStream = posStream.limit(maxBlocks); } return posStream.collect(Collectors.toList()); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + private Stream scanChunkInternal(IPlayerContext ctx, BlockOptionalMetaLookup lookup, ChunkPos pos) { + IChunkProvider chunkProvider = ctx.world().getChunkProvider(); + // if chunk is not loaded, return empty stream + if (!chunkProvider.isChunkGeneratedAt(pos.x, pos.z)) { + return Stream.empty(); } - private Stream scanChunkInternal(ChunkPos pos) { - IChunkProvider chunkProvider = ctx.world().getChunkProvider(); - // if chunk is not loaded, return empty stream - if (!chunkProvider.isChunkGeneratedAt(pos.x, pos.z)) { - return Stream.empty(); + long chunkX = (long) pos.x << 4; + long chunkZ = (long) pos.z << 4; + + List blocks = new ArrayList<>(); + + collectChunkSections(lookup, chunkProvider.getLoadedChunk(pos.x, pos.z), (section, isInFilter) -> { + int yOffset = section.getYLocation(); + BitArray array = (BitArray) ((IBlockStateContainer) section.getData()).getStorage(); + collectBlockLocations(array, isInFilter, place -> blocks.add(new BlockPos( + chunkX + ((place & 255) & 15), + yOffset + (place >> 8), + chunkZ + ((place & 255) >> 4) + ))); + }); + return blocks.stream(); + } + + + + private void collectChunkSections(BlockOptionalMetaLookup lookup, Chunk chunk, BiConsumer consumer) { + for (ExtendedBlockStorage section : chunk.getBlockStorageArray()) { + if (section == null || section.isEmpty()) { + continue; } - long chunkX = (long) pos.x << 4; - long chunkZ = (long) pos.z << 4; - - List blocks = new ArrayList<>(); - - streamChunkSections(chunkProvider.getLoadedChunk(pos.x, pos.z), (section, isInFilter) -> { - int yOffset = section.getYLocation(); - BitArray array = (BitArray) ((IBlockStateContainer) section.getData()).getStorage(); - forEach(array, isInFilter, place -> blocks.add(new BlockPos( - chunkX + ((place & 255) & 15), - yOffset + (place >> 8), - chunkZ + ((place & 255) >> 4) - ))); - }); - return blocks.stream(); - } - - private void streamChunkSections(Chunk chunk, BiConsumer consumer) { - for (ExtendedBlockStorage section : chunk.getBlockStorageArray()) { - if (section == null || section.isEmpty()) { - continue; - } - - BlockStateContainer sectionContainer = section.getData(); - //this won't work if the PaletteStorage is of the type EmptyPaletteStorage - if (((IBlockStateContainer) sectionContainer).getStorage() == null) { - continue; - } - - boolean[] isInFilter = getIncludedFilterIndices(((IBlockStateContainer) sectionContainer).getPalette()); - if (isInFilter.length == 0) { - continue; - } - consumer.accept(section, isInFilter); - } - } - - private boolean getFilterResult(IBlockState state) { - Boolean v; - return (v = cachedFilter.get(state)) == null ? addCachedState(state) : v; - } - - private boolean addCachedState(IBlockState state) { - boolean isInFilter = false; - - if (filter != null) { - isInFilter = filter.has(state); + BlockStateContainer sectionContainer = section.getData(); + //this won't work if the PaletteStorage is of the type EmptyPaletteStorage + if (((IBlockStateContainer) sectionContainer).getStorage() == null) { + continue; } - cachedFilter.put(state, isInFilter); - return isInFilter; - } - - private boolean[] getIncludedFilterIndices(IBlockStatePalette palette) { - boolean commonBlockFound = false; - ObjectIntIdentityMap paletteMap = getPalette(palette); - int size = paletteMap.size(); - - boolean[] isInFilter = new boolean[size]; - - for (int i = 0; i < size; i++) { - IBlockState state = paletteMap.getByValue(i); - if (getFilterResult(state)) { - isInFilter[i] = true; - commonBlockFound = true; - } else { - isInFilter[i] = false; - } + boolean[] isInFilter = getIncludedFilterIndices(lookup, ((IBlockStateContainer) sectionContainer).getPalette()); + if (isInFilter.length == 0) { + continue; } - - if (!commonBlockFound) { - return new boolean[0]; - } - return isInFilter; + consumer.accept(section, isInFilter); } + } - private static void forEach(BitArray array, boolean[] isInFilter, IntConsumer action) { - long[] longArray = array.getBackingLongArray(); - int arraySize = array.size(); - int bitsPerEntry = ((IBitArray) array).getBitsPerEntry(); - long maxEntryValue = ((IBitArray) array).getMaxEntryValue(); + private boolean[] getIncludedFilterIndices(BlockOptionalMetaLookup lookup, IBlockStatePalette palette) { + boolean commonBlockFound = false; + ObjectIntIdentityMap paletteMap = getPalette(palette); + int size = paletteMap.size(); - for (int idx = 0, kl = bitsPerEntry - 1; idx < arraySize; idx++, kl += bitsPerEntry) { - final int i = idx * bitsPerEntry; - final int j = i >> 6; - final int l = i & 63; - final int k = kl >> 6; - final long jl = longArray[j] >>> l; + boolean[] isInFilter = new boolean[size]; - if (j == k) { - if (isInFilter[(int) (jl & maxEntryValue)]) { - action.accept(idx); - } - } else { - if (isInFilter[(int) ((jl | longArray[k] << (64 - l)) & maxEntryValue)]) { - action.accept(idx); - } - } - } - } - - /** - * cheats to get the actual map of id -> blockstate from the various palette implementations - */ - private static ObjectIntIdentityMap getPalette(IBlockStatePalette palette) { - if (palette instanceof BlockStatePaletteRegistry) { - return Block.BLOCK_STATE_IDS; + for (int i = 0; i < size; i++) { + IBlockState state = paletteMap.getByValue(i); + if (lookup.has(state)) { + isInFilter[i] = true; + commonBlockFound = true; } else { - PacketBuffer buf = new PacketBuffer(Unpooled.buffer()); - palette.write(buf); - int size = buf.readVarInt(); - ObjectIntIdentityMap states = new ObjectIntIdentityMap<>(); - for (int i = 0; i < size; i++) { - IBlockState state = Block.BLOCK_STATE_IDS.getByValue(buf.readVarInt()); - assert state != null; - states.put(state, i); + isInFilter[i] = false; + } + } + + if (!commonBlockFound) { + return new boolean[0]; + } + return isInFilter; + } + + private static void collectBlockLocations(BitArray array, boolean[] isInFilter, IntConsumer action) { + long[] longArray = array.getBackingLongArray(); + int arraySize = array.size(); + int bitsPerEntry = ((IBitArray) array).getBitsPerEntry(); + long maxEntryValue = ((IBitArray) array).getMaxEntryValue(); + + for (int idx = 0, kl = bitsPerEntry - 1; idx < arraySize; idx++, kl += bitsPerEntry) { + final int i = idx * bitsPerEntry; + final int j = i >> 6; + final int l = i & 63; + final int k = kl >> 6; + final long jl = longArray[j] >>> l; + + if (j == k) { + if (isInFilter[(int) (jl & maxEntryValue)]) { + action.accept(idx); + } + } else { + if (isInFilter[(int) ((jl | longArray[k] << (64 - l)) & maxEntryValue)]) { + action.accept(idx); } - return states; } } } + + /** + * cheats to get the actual map of id -> blockstate from the various palette implementations + */ + private static ObjectIntIdentityMap getPalette(IBlockStatePalette palette) { + if (palette instanceof BlockStatePaletteRegistry) { + return Block.BLOCK_STATE_IDS; + } else { + PacketBuffer buf = new PacketBuffer(Unpooled.buffer()); + palette.write(buf); + int size = buf.readVarInt(); + ObjectIntIdentityMap states = new ObjectIntIdentityMap<>(); + for (int i = 0; i < size; i++) { + IBlockState state = Block.BLOCK_STATE_IDS.getByValue(buf.readVarInt()); + assert state != null; + states.put(state, i); + } + return states; + } + } } From c04eb066cb84e8a4362f913c301fc03da346718c Mon Sep 17 00:00:00 2001 From: William Gray Date: Wed, 28 Dec 2022 01:06:10 +0000 Subject: [PATCH 009/405] Update src/main/java/baritone/cache/FasterWorldScanner.java Co-authored-by: ZacSharp <68165024+ZacSharp@users.noreply.github.com> --- src/main/java/baritone/cache/FasterWorldScanner.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/baritone/cache/FasterWorldScanner.java b/src/main/java/baritone/cache/FasterWorldScanner.java index 7a46f04ff..4dd480f25 100644 --- a/src/main/java/baritone/cache/FasterWorldScanner.java +++ b/src/main/java/baritone/cache/FasterWorldScanner.java @@ -106,11 +106,13 @@ public enum FasterWorldScanner implements IWorldScanner { chunks.add(new ChunkPos(centerX - j, centerZ + i)); } chunks.add(new ChunkPos(centerX + j, centerZ + i)); - if (j != 0 && j != i) { + if (j != i) { chunks.add(new ChunkPos(centerX - i, centerZ - j)); chunks.add(new ChunkPos(centerX + i, centerZ - j)); - chunks.add(new ChunkPos(centerX - i, centerZ + j)); - chunks.add(new ChunkPos(centerX + i, centerZ + j)); + if (j != 0) { + chunks.add(new ChunkPos(centerX - i, centerZ + j)); + chunks.add(new ChunkPos(centerX + i, centerZ + j)); + } } } } From 98a748afb3340ad979a09a62623ddefcdb2d7887 Mon Sep 17 00:00:00 2001 From: Wagyourtail Date: Tue, 27 Dec 2022 22:42:38 -0700 Subject: [PATCH 010/405] fix stream limit. immutable's in BOML --- .../baritone/api/utils/BlockOptionalMeta.java | 8 ++++-- .../api/utils/BlockOptionalMetaLookup.java | 28 ++++++++++++------- .../baritone/cache/FasterWorldScanner.java | 6 +++- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/api/java/baritone/api/utils/BlockOptionalMeta.java b/src/api/java/baritone/api/utils/BlockOptionalMeta.java index e86341816..e0f491fba 100644 --- a/src/api/java/baritone/api/utils/BlockOptionalMeta.java +++ b/src/api/java/baritone/api/utils/BlockOptionalMeta.java @@ -41,8 +41,8 @@ public final class BlockOptionalMeta { private final int meta; private final boolean noMeta; private final Set blockstates; - private final ImmutableSet stateHashes; - private final ImmutableSet stackHashes; + private final Set stateHashes; + private final Set stackHashes; private static final Pattern pattern = Pattern.compile("^(.+?)(?::(\\d+))?$"); private static final Map normalizations; @@ -319,4 +319,8 @@ public final class BlockOptionalMeta { public Set getAllBlockStates() { return blockstates; } + + public Set stackHashes() { + return stackHashes; + } } diff --git a/src/api/java/baritone/api/utils/BlockOptionalMetaLookup.java b/src/api/java/baritone/api/utils/BlockOptionalMetaLookup.java index 8fb52fb52..6d236e90e 100644 --- a/src/api/java/baritone/api/utils/BlockOptionalMetaLookup.java +++ b/src/api/java/baritone/api/utils/BlockOptionalMetaLookup.java @@ -17,6 +17,7 @@ package baritone.api.utils; +import com.google.common.collect.ImmutableSet; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.item.ItemStack; @@ -28,34 +29,41 @@ import java.util.Set; import java.util.stream.Stream; public class BlockOptionalMetaLookup { - private final Set blockSet = new HashSet<>(); - private final Set blockStateSet = new HashSet<>(); + private final Set blockSet; + private final Set blockStateSet; private final BlockOptionalMeta[] boms; public BlockOptionalMetaLookup(BlockOptionalMeta... boms) { this.boms = boms; + Set blocks = new HashSet<>(); + Set blockStates = new HashSet<>(); + Set stacks = new HashSet<>(); for (BlockOptionalMeta bom : boms) { - blockSet.add(bom.getBlock()); - blockStateSet.addAll(bom.getAllBlockStates()); + blocks.add(bom.getBlock()); + blockStates.addAll(bom.getAllBlockStates()); + stacks.addAll(bom.stackHashes()); } + this.blockSet = ImmutableSet.copyOf(blocks); + this.blockStateSet = ImmutableSet.copyOf(blockStates); } public BlockOptionalMetaLookup(Block... blocks) { - this.boms = Stream.of(blocks) + this(Stream.of(blocks) .map(BlockOptionalMeta::new) - .toArray(BlockOptionalMeta[]::new); + .toArray(BlockOptionalMeta[]::new)); + } public BlockOptionalMetaLookup(List blocks) { - this.boms = blocks.stream() + this(blocks.stream() .map(BlockOptionalMeta::new) - .toArray(BlockOptionalMeta[]::new); + .toArray(BlockOptionalMeta[]::new)); } public BlockOptionalMetaLookup(String... blocks) { - this.boms = Stream.of(blocks) + this(Stream.of(blocks) .map(BlockOptionalMeta::new) - .toArray(BlockOptionalMeta[]::new); + .toArray(BlockOptionalMeta[]::new)); } public boolean has(Block block) { diff --git a/src/main/java/baritone/cache/FasterWorldScanner.java b/src/main/java/baritone/cache/FasterWorldScanner.java index 4dd480f25..e133f0e49 100644 --- a/src/main/java/baritone/cache/FasterWorldScanner.java +++ b/src/main/java/baritone/cache/FasterWorldScanner.java @@ -55,7 +55,11 @@ public enum FasterWorldScanner implements IWorldScanner { @Override public List scanChunk(IPlayerContext ctx, BlockOptionalMetaLookup filter, ChunkPos pos, int max, int yLevelThreshold) { - return scanChunkInternal(ctx, filter, pos).limit(max).collect(Collectors.toList()); + Stream stream = scanChunkInternal(ctx, filter, pos); + if (max >= 0) { + stream = stream.limit(max); + } + return stream.collect(Collectors.toList()); } @Override From e55db05f204a8e913ee90b9f3400b40a1abec509 Mon Sep 17 00:00:00 2001 From: Wagyourtail Date: Tue, 27 Dec 2022 23:30:35 -0700 Subject: [PATCH 011/405] sacrifice a bit of speed for better block ordering --- .../baritone/cache/FasterWorldScanner.java | 57 ++++++++++++++----- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/src/main/java/baritone/cache/FasterWorldScanner.java b/src/main/java/baritone/cache/FasterWorldScanner.java index e133f0e49..d4c20766e 100644 --- a/src/main/java/baritone/cache/FasterWorldScanner.java +++ b/src/main/java/baritone/cache/FasterWorldScanner.java @@ -36,10 +36,13 @@ import net.minecraft.world.chunk.*; import net.minecraft.world.chunk.storage.ExtendedBlockStorage; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; +import java.util.Objects; import java.util.function.BiConsumer; import java.util.function.IntConsumer; import java.util.stream.Collectors; +import java.util.stream.IntStream; import java.util.stream.Stream; public enum FasterWorldScanner implements IWorldScanner { @@ -146,43 +149,59 @@ public enum FasterWorldScanner implements IWorldScanner { return Stream.empty(); } - long chunkX = (long) pos.x << 4; - long chunkZ = (long) pos.z << 4; + long inChunkX = (long) pos.x << 4; + long inChunkZ = (long) pos.z << 4; - List blocks = new ArrayList<>(); + int playerY = ctx.playerFeet().y; + int playerSection = ctx.playerFeet().y >> 4; - collectChunkSections(lookup, chunkProvider.getLoadedChunk(pos.x, pos.z), (section, isInFilter) -> { + + return streamChunkSections(lookup, chunkProvider.getLoadedChunk(pos.x, pos.z), playerSection).flatMap((data) -> { + ExtendedBlockStorage section = data.section; + boolean[] isInFilter = data.isInFilter; + List blocks = new ArrayList<>(); int yOffset = section.getYLocation(); BitArray array = (BitArray) ((IBlockStateContainer) section.getData()).getStorage(); collectBlockLocations(array, isInFilter, place -> blocks.add(new BlockPos( - chunkX + ((place & 255) & 15), + (int) inChunkX + ((place & 255) & 15), yOffset + (place >> 8), - chunkZ + ((place & 255) >> 4) + (int) inChunkZ + ((place & 255) >> 4) ))); + return blocks.stream().sorted((a, b) -> { + int distA = Math.abs(a.getY() - playerY); + int distB = Math.abs(b.getY() - playerY); + return Integer.compare(distA, distB); + }); }); - return blocks.stream(); } - private void collectChunkSections(BlockOptionalMetaLookup lookup, Chunk chunk, BiConsumer consumer) { - for (ExtendedBlockStorage section : chunk.getBlockStorageArray()) { + private Stream streamChunkSections(BlockOptionalMetaLookup lookup, Chunk chunk, int playerSection) { + ExtendedBlockStorage[] sections = chunk.getBlockStorageArray(); + // order sections by distance to player + + return IntStream.range(0, sections.length) + .boxed() + .sorted(Comparator.comparingInt(a -> Math.abs(a - playerSection))) + .map(i -> { + ExtendedBlockStorage section = sections[i]; if (section == null || section.isEmpty()) { - continue; + return null; } BlockStateContainer sectionContainer = section.getData(); //this won't work if the PaletteStorage is of the type EmptyPaletteStorage if (((IBlockStateContainer) sectionContainer).getStorage() == null) { - continue; + return null; } boolean[] isInFilter = getIncludedFilterIndices(lookup, ((IBlockStateContainer) sectionContainer).getPalette()); if (isInFilter.length == 0) { - continue; + return null; } - consumer.accept(section, isInFilter); - } + return new SectionData(section, isInFilter); + }).filter(Objects::nonNull); } private boolean[] getIncludedFilterIndices(BlockOptionalMetaLookup lookup, IBlockStatePalette palette) { @@ -252,4 +271,14 @@ public enum FasterWorldScanner implements IWorldScanner { return states; } } + + private static class SectionData { + ExtendedBlockStorage section; + boolean[] isInFilter; + + SectionData(ExtendedBlockStorage section, boolean[] isInFilter) { + this.section = section; + this.isInFilter = isInFilter; + } + } } From a367031fe248e01910c00122ab75c91c586ed005 Mon Sep 17 00:00:00 2001 From: Wagyourtail Date: Tue, 27 Dec 2022 23:30:35 -0700 Subject: [PATCH 012/405] Revert "sacrifice a bit of speed for better block ordering" This reverts commit e55db05f204a8e913ee90b9f3400b40a1abec509. --- .../baritone/cache/FasterWorldScanner.java | 57 +++++-------------- 1 file changed, 14 insertions(+), 43 deletions(-) diff --git a/src/main/java/baritone/cache/FasterWorldScanner.java b/src/main/java/baritone/cache/FasterWorldScanner.java index d4c20766e..e133f0e49 100644 --- a/src/main/java/baritone/cache/FasterWorldScanner.java +++ b/src/main/java/baritone/cache/FasterWorldScanner.java @@ -36,13 +36,10 @@ import net.minecraft.world.chunk.*; import net.minecraft.world.chunk.storage.ExtendedBlockStorage; import java.util.ArrayList; -import java.util.Comparator; import java.util.List; -import java.util.Objects; import java.util.function.BiConsumer; import java.util.function.IntConsumer; import java.util.stream.Collectors; -import java.util.stream.IntStream; import java.util.stream.Stream; public enum FasterWorldScanner implements IWorldScanner { @@ -149,59 +146,43 @@ public enum FasterWorldScanner implements IWorldScanner { return Stream.empty(); } - long inChunkX = (long) pos.x << 4; - long inChunkZ = (long) pos.z << 4; + long chunkX = (long) pos.x << 4; + long chunkZ = (long) pos.z << 4; - int playerY = ctx.playerFeet().y; - int playerSection = ctx.playerFeet().y >> 4; + List blocks = new ArrayList<>(); - - return streamChunkSections(lookup, chunkProvider.getLoadedChunk(pos.x, pos.z), playerSection).flatMap((data) -> { - ExtendedBlockStorage section = data.section; - boolean[] isInFilter = data.isInFilter; - List blocks = new ArrayList<>(); + collectChunkSections(lookup, chunkProvider.getLoadedChunk(pos.x, pos.z), (section, isInFilter) -> { int yOffset = section.getYLocation(); BitArray array = (BitArray) ((IBlockStateContainer) section.getData()).getStorage(); collectBlockLocations(array, isInFilter, place -> blocks.add(new BlockPos( - (int) inChunkX + ((place & 255) & 15), + chunkX + ((place & 255) & 15), yOffset + (place >> 8), - (int) inChunkZ + ((place & 255) >> 4) + chunkZ + ((place & 255) >> 4) ))); - return blocks.stream().sorted((a, b) -> { - int distA = Math.abs(a.getY() - playerY); - int distB = Math.abs(b.getY() - playerY); - return Integer.compare(distA, distB); - }); }); + return blocks.stream(); } - private Stream streamChunkSections(BlockOptionalMetaLookup lookup, Chunk chunk, int playerSection) { - ExtendedBlockStorage[] sections = chunk.getBlockStorageArray(); - // order sections by distance to player - - return IntStream.range(0, sections.length) - .boxed() - .sorted(Comparator.comparingInt(a -> Math.abs(a - playerSection))) - .map(i -> { - ExtendedBlockStorage section = sections[i]; + private void collectChunkSections(BlockOptionalMetaLookup lookup, Chunk chunk, BiConsumer consumer) { + for (ExtendedBlockStorage section : chunk.getBlockStorageArray()) { if (section == null || section.isEmpty()) { - return null; + continue; } BlockStateContainer sectionContainer = section.getData(); //this won't work if the PaletteStorage is of the type EmptyPaletteStorage if (((IBlockStateContainer) sectionContainer).getStorage() == null) { - return null; + continue; } boolean[] isInFilter = getIncludedFilterIndices(lookup, ((IBlockStateContainer) sectionContainer).getPalette()); if (isInFilter.length == 0) { - return null; + continue; } - return new SectionData(section, isInFilter); - }).filter(Objects::nonNull); + consumer.accept(section, isInFilter); + } } private boolean[] getIncludedFilterIndices(BlockOptionalMetaLookup lookup, IBlockStatePalette palette) { @@ -271,14 +252,4 @@ public enum FasterWorldScanner implements IWorldScanner { return states; } } - - private static class SectionData { - ExtendedBlockStorage section; - boolean[] isInFilter; - - SectionData(ExtendedBlockStorage section, boolean[] isInFilter) { - this.section = section; - this.isInFilter = isInFilter; - } - } } From 746faf6df6ea9d615dd2bcd421cef446d1b9f922 Mon Sep 17 00:00:00 2001 From: Wagyourtail Date: Wed, 28 Dec 2022 01:05:17 -0700 Subject: [PATCH 013/405] faster section reorder --- .../baritone/cache/FasterWorldScanner.java | 48 ++++++++++++------- .../java/baritone/process/MineProcess.java | 2 +- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/main/java/baritone/cache/FasterWorldScanner.java b/src/main/java/baritone/cache/FasterWorldScanner.java index e133f0e49..9adbf76b0 100644 --- a/src/main/java/baritone/cache/FasterWorldScanner.java +++ b/src/main/java/baritone/cache/FasterWorldScanner.java @@ -149,9 +149,11 @@ public enum FasterWorldScanner implements IWorldScanner { long chunkX = (long) pos.x << 4; long chunkZ = (long) pos.z << 4; + int playerSectionY = ctx.playerFeet().y >> 4; + List blocks = new ArrayList<>(); - collectChunkSections(lookup, chunkProvider.getLoadedChunk(pos.x, pos.z), (section, isInFilter) -> { + collectChunkSections(lookup, chunkProvider.getLoadedChunk(pos.x, pos.z), playerSectionY, (section, isInFilter) -> { int yOffset = section.getYLocation(); BitArray array = (BitArray) ((IBlockStateContainer) section.getData()).getStorage(); collectBlockLocations(array, isInFilter, place -> blocks.add(new BlockPos( @@ -165,26 +167,40 @@ public enum FasterWorldScanner implements IWorldScanner { - private void collectChunkSections(BlockOptionalMetaLookup lookup, Chunk chunk, BiConsumer consumer) { - for (ExtendedBlockStorage section : chunk.getBlockStorageArray()) { - if (section == null || section.isEmpty()) { - continue; + private void collectChunkSections(BlockOptionalMetaLookup lookup, Chunk chunk, int playerSection, BiConsumer consumer) { + // iterate over sections relative to player + ExtendedBlockStorage[] sections = chunk.getBlockStorageArray(); + int l = sections.length; + int i = playerSection - 1; + int j = playerSection; + for (; i >= 0 || j < l; ++j, --i) { + if (j < l) { + visitSection(lookup, sections[j], consumer); } - - BlockStateContainer sectionContainer = section.getData(); - //this won't work if the PaletteStorage is of the type EmptyPaletteStorage - if (((IBlockStateContainer) sectionContainer).getStorage() == null) { - continue; + if (i >= 0) { + visitSection(lookup, sections[i], consumer); } - - boolean[] isInFilter = getIncludedFilterIndices(lookup, ((IBlockStateContainer) sectionContainer).getPalette()); - if (isInFilter.length == 0) { - continue; - } - consumer.accept(section, isInFilter); } } + private void visitSection(BlockOptionalMetaLookup lookup, ExtendedBlockStorage section, BiConsumer consumer) { + if (section == null || section.isEmpty()) { + return; + } + + BlockStateContainer sectionContainer = section.getData(); + //this won't work if the PaletteStorage is of the type EmptyPaletteStorage + if (((IBlockStateContainer) sectionContainer).getStorage() == null) { + return; + } + + boolean[] isInFilter = getIncludedFilterIndices(lookup, ((IBlockStateContainer) sectionContainer).getPalette()); + if (isInFilter.length == 0) { + return; + } + consumer.accept(section, isInFilter); + } + private boolean[] getIncludedFilterIndices(BlockOptionalMetaLookup lookup, IBlockStatePalette palette) { boolean commonBlockFound = false; ObjectIntIdentityMap paletteMap = getPalette(palette); diff --git a/src/main/java/baritone/process/MineProcess.java b/src/main/java/baritone/process/MineProcess.java index 807dbc303..137313de9 100644 --- a/src/main/java/baritone/process/MineProcess.java +++ b/src/main/java/baritone/process/MineProcess.java @@ -54,7 +54,7 @@ import static baritone.api.pathing.movement.ActionCosts.COST_INF; */ public final class MineProcess extends BaritoneProcessHelper implements IMineProcess { - private static final int ORE_LOCATIONS_COUNT = 64; + private static final int ORE_LOCATIONS_COUNT = 32; private BlockOptionalMetaLookup filter; private List knownOreLocations; From b71c9e776ac62cef47e2ec05f484195e850d5e52 Mon Sep 17 00:00:00 2001 From: Wagyourtail Date: Wed, 28 Dec 2022 01:09:46 -0700 Subject: [PATCH 014/405] oops didn't mean to commit that --- src/main/java/baritone/process/MineProcess.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/process/MineProcess.java b/src/main/java/baritone/process/MineProcess.java index 137313de9..807dbc303 100644 --- a/src/main/java/baritone/process/MineProcess.java +++ b/src/main/java/baritone/process/MineProcess.java @@ -54,7 +54,7 @@ import static baritone.api.pathing.movement.ActionCosts.COST_INF; */ public final class MineProcess extends BaritoneProcessHelper implements IMineProcess { - private static final int ORE_LOCATIONS_COUNT = 32; + private static final int ORE_LOCATIONS_COUNT = 64; private BlockOptionalMetaLookup filter; private List knownOreLocations; From 26cceede153a290926bc83e286ea874a6c5519a0 Mon Sep 17 00:00:00 2001 From: Entropy5 <44469915+Entropy5@users.noreply.github.com> Date: Tue, 17 Jan 2023 06:33:01 +0100 Subject: [PATCH 015/405] litematica support for buildonlyselection, mostly rycbars --- .../java/baritone/process/BuilderProcess.java | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index f3f138c96..14093dc6a 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -166,19 +166,23 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil return false; } - if (Baritone.settings().mapArtMode.value) { - parsed = new MapArtSchematic((IStaticSchematic) parsed); - } - - if (Baritone.settings().buildOnlySelection.value) { - parsed = new SelectionSchematic(parsed, origin, baritone.getSelectionManager().getSelections()); - } - + parsed = applyMapArtAndSelection(origin, parsed); build(name, parsed, origin); return true; } + private ISchematic applyMapArtAndSelection(Vec3i origin, ISchematic schematic) { + if (Baritone.settings().mapArtMode.value) { + schematic = new MapArtSchematic((IStaticSchematic) schematic); + } + + if (Baritone.settings().buildOnlySelection.value) { + schematic = new SelectionSchematic(schematic, origin, baritone.getSelectionManager().getSelections()); + } + return schematic; + } + @Override public void buildOpenSchematic() { if (SchematicaHelper.isSchematicaPresent()) { @@ -217,7 +221,8 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil try { LitematicaSchematic schematic1 = new LitematicaSchematic(CompressedStreamTools.readCompressed(Files.newInputStream(LitematicaHelper.getSchematicFile(i).toPath())), false); Vec3i correctedOrigin = LitematicaHelper.getCorrectedOrigin(schematic1, i); - LitematicaSchematic schematic2 = LitematicaHelper.blackMagicFuckery(schematic1, i); + ISchematic schematic2 = LitematicaHelper.blackMagicFuckery(schematic1, i); + schematic2 = applyMapArtAndSelection(origin, schematic2); build(name, schematic2, correctedOrigin); } catch (IOException e) { logDirect("Schematic File could not be loaded."); From 7404414e7a180925502aa6ad1063a321f121cd3a Mon Sep 17 00:00:00 2001 From: Wagyourtail Date: Fri, 20 Jan 2023 23:43:00 -0700 Subject: [PATCH 016/405] less impure --- .../baritone/cache/FasterWorldScanner.java | 47 +++++++++++-------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/src/main/java/baritone/cache/FasterWorldScanner.java b/src/main/java/baritone/cache/FasterWorldScanner.java index 9adbf76b0..a813e9119 100644 --- a/src/main/java/baritone/cache/FasterWorldScanner.java +++ b/src/main/java/baritone/cache/FasterWorldScanner.java @@ -25,6 +25,8 @@ import baritone.api.utils.IPlayerContext; import baritone.utils.accessor.IBitArray; import baritone.utils.accessor.IBlockStateContainer; import io.netty.buffer.Unpooled; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.network.PacketBuffer; @@ -126,6 +128,7 @@ public enum FasterWorldScanner implements IWorldScanner { private List scanChunksInternal(IPlayerContext ctx, BlockOptionalMetaLookup lookup, List chunkPositions, int maxBlocks) { assert ctx.world() != null; try { + // p -> scanChunkInternal(ctx, lookup, p) Stream posStream = chunkPositions.parallelStream().flatMap(p -> scanChunkInternal(ctx, lookup, p)); if (maxBlocks >= 0) { // WARNING: this can be expensive if maxBlocks is large... @@ -151,39 +154,30 @@ public enum FasterWorldScanner implements IWorldScanner { int playerSectionY = ctx.playerFeet().y >> 4; - List blocks = new ArrayList<>(); - - collectChunkSections(lookup, chunkProvider.getLoadedChunk(pos.x, pos.z), playerSectionY, (section, isInFilter) -> { - int yOffset = section.getYLocation(); - BitArray array = (BitArray) ((IBlockStateContainer) section.getData()).getStorage(); - collectBlockLocations(array, isInFilter, place -> blocks.add(new BlockPos( - chunkX + ((place & 255) & 15), - yOffset + (place >> 8), - chunkZ + ((place & 255) >> 4) - ))); - }); - return blocks.stream(); + return collectChunkSections(lookup, chunkProvider.getLoadedChunk(pos.x, pos.z), chunkX, chunkZ, playerSectionY).stream(); } - private void collectChunkSections(BlockOptionalMetaLookup lookup, Chunk chunk, int playerSection, BiConsumer consumer) { + private List collectChunkSections(BlockOptionalMetaLookup lookup, Chunk chunk, long chunkX, long chunkZ, int playerSection) { // iterate over sections relative to player + List blocks = new ArrayList<>(); ExtendedBlockStorage[] sections = chunk.getBlockStorageArray(); int l = sections.length; int i = playerSection - 1; int j = playerSection; for (; i >= 0 || j < l; ++j, --i) { if (j < l) { - visitSection(lookup, sections[j], consumer); + visitSection(lookup, sections[j], blocks, chunkX, chunkZ); } if (i >= 0) { - visitSection(lookup, sections[i], consumer); + visitSection(lookup, sections[i], blocks, chunkX, chunkZ); } } + return blocks; } - private void visitSection(BlockOptionalMetaLookup lookup, ExtendedBlockStorage section, BiConsumer consumer) { + private void visitSection(BlockOptionalMetaLookup lookup, ExtendedBlockStorage section, List blocks, long chunkX, long chunkZ) { if (section == null || section.isEmpty()) { return; } @@ -198,7 +192,17 @@ public enum FasterWorldScanner implements IWorldScanner { if (isInFilter.length == 0) { return; } - consumer.accept(section, isInFilter); + + + int yOffset = section.getYLocation(); + BitArray array = ((IBlockStateContainer) section.getData()).getStorage(); + for (int place : collectBlockLocations(array, isInFilter)) { + blocks.add(new BlockPos( + chunkX + ((place & 255) & 15), + yOffset + (place >> 8), + chunkZ + ((place & 255) >> 4) + )); + } } private boolean[] getIncludedFilterIndices(BlockOptionalMetaLookup lookup, IBlockStatePalette palette) { @@ -224,12 +228,14 @@ public enum FasterWorldScanner implements IWorldScanner { return isInFilter; } - private static void collectBlockLocations(BitArray array, boolean[] isInFilter, IntConsumer action) { + private static IntList collectBlockLocations(BitArray array, boolean[] isInFilter) { long[] longArray = array.getBackingLongArray(); int arraySize = array.size(); int bitsPerEntry = ((IBitArray) array).getBitsPerEntry(); long maxEntryValue = ((IBitArray) array).getMaxEntryValue(); + IntList positions = new IntArrayList(); + for (int idx = 0, kl = bitsPerEntry - 1; idx < arraySize; idx++, kl += bitsPerEntry) { final int i = idx * bitsPerEntry; final int j = i >> 6; @@ -239,14 +245,15 @@ public enum FasterWorldScanner implements IWorldScanner { if (j == k) { if (isInFilter[(int) (jl & maxEntryValue)]) { - action.accept(idx); + positions.add(idx); } } else { if (isInFilter[(int) ((jl | longArray[k] << (64 - l)) & maxEntryValue)]) { - action.accept(idx); + positions.add(idx); } } } + return positions; } /** From 413cc1469f0fdcefd84952924fc182ba0e3c390b Mon Sep 17 00:00:00 2001 From: Entropy5 <44469915+Entropy5@users.noreply.github.com> Date: Fri, 27 Jan 2023 14:23:08 +0100 Subject: [PATCH 017/405] zac suggestion (number 2), test ongoing --- src/main/java/baritone/process/BuilderProcess.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index 14093dc6a..85be6516a 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -157,7 +157,6 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil if (!format.isPresent()) { return false; } - ISchematic parsed; try { parsed = format.get().parse(new FileInputStream(schematic)); @@ -165,18 +164,16 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil e.printStackTrace(); return false; } - - parsed = applyMapArtAndSelection(origin, parsed); - + parsed = applyMapArtAndSelection(origin, (IStaticSchematic) parsed); build(name, parsed, origin); return true; } - private ISchematic applyMapArtAndSelection(Vec3i origin, ISchematic schematic) { + private ISchematic applyMapArtAndSelection(Vec3i origin, IStaticSchematic parsed) { + ISchematic schematic = parsed; if (Baritone.settings().mapArtMode.value) { - schematic = new MapArtSchematic((IStaticSchematic) schematic); + schematic = new MapArtSchematic(parsed); } - if (Baritone.settings().buildOnlySelection.value) { schematic = new SelectionSchematic(schematic, origin, baritone.getSelectionManager().getSelections()); } @@ -222,7 +219,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil LitematicaSchematic schematic1 = new LitematicaSchematic(CompressedStreamTools.readCompressed(Files.newInputStream(LitematicaHelper.getSchematicFile(i).toPath())), false); Vec3i correctedOrigin = LitematicaHelper.getCorrectedOrigin(schematic1, i); ISchematic schematic2 = LitematicaHelper.blackMagicFuckery(schematic1, i); - schematic2 = applyMapArtAndSelection(origin, schematic2); + schematic2 = applyMapArtAndSelection(origin, (IStaticSchematic) schematic2); build(name, schematic2, correctedOrigin); } catch (IOException e) { logDirect("Schematic File could not be loaded."); From 334d9c119b6269e1896963905a214667eae24dcb Mon Sep 17 00:00:00 2001 From: Wagyourtail Date: Sat, 28 Jan 2023 00:44:54 -0700 Subject: [PATCH 018/405] remove the allocation of an intlist per section --- .../baritone/cache/FasterWorldScanner.java | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/main/java/baritone/cache/FasterWorldScanner.java b/src/main/java/baritone/cache/FasterWorldScanner.java index a813e9119..4a41eaf10 100644 --- a/src/main/java/baritone/cache/FasterWorldScanner.java +++ b/src/main/java/baritone/cache/FasterWorldScanner.java @@ -196,13 +196,7 @@ public enum FasterWorldScanner implements IWorldScanner { int yOffset = section.getYLocation(); BitArray array = ((IBlockStateContainer) section.getData()).getStorage(); - for (int place : collectBlockLocations(array, isInFilter)) { - blocks.add(new BlockPos( - chunkX + ((place & 255) & 15), - yOffset + (place >> 8), - chunkZ + ((place & 255) >> 4) - )); - } + collectBlockLocations(array, isInFilter, blocks, chunkX, chunkZ, yOffset); } private boolean[] getIncludedFilterIndices(BlockOptionalMetaLookup lookup, IBlockStatePalette palette) { @@ -228,14 +222,12 @@ public enum FasterWorldScanner implements IWorldScanner { return isInFilter; } - private static IntList collectBlockLocations(BitArray array, boolean[] isInFilter) { + private static void collectBlockLocations(BitArray array, boolean[] isInFilter, List blocks, long chunkX, long chunkZ, int yOffset) { long[] longArray = array.getBackingLongArray(); int arraySize = array.size(); int bitsPerEntry = ((IBitArray) array).getBitsPerEntry(); long maxEntryValue = ((IBitArray) array).getMaxEntryValue(); - IntList positions = new IntArrayList(); - for (int idx = 0, kl = bitsPerEntry - 1; idx < arraySize; idx++, kl += bitsPerEntry) { final int i = idx * bitsPerEntry; final int j = i >> 6; @@ -245,15 +237,24 @@ public enum FasterWorldScanner implements IWorldScanner { if (j == k) { if (isInFilter[(int) (jl & maxEntryValue)]) { - positions.add(idx); + //noinspection DuplicateExpressions + blocks.add(new BlockPos( + chunkX + ((idx & 255) & 15), + yOffset + (idx >> 8), + chunkZ + ((idx & 255) >> 4) + )); } } else { if (isInFilter[(int) ((jl | longArray[k] << (64 - l)) & maxEntryValue)]) { - positions.add(idx); + //noinspection DuplicateExpressions + blocks.add(new BlockPos( + chunkX + ((idx & 255) & 15), + yOffset + (idx >> 8), + chunkZ + ((idx & 255) >> 4) + )); } } } - return positions; } /** From 6de266a106534b06f73550846d51aacd436b6ec7 Mon Sep 17 00:00:00 2001 From: Wagyourtail Date: Sat, 28 Jan 2023 01:39:58 -0700 Subject: [PATCH 019/405] remove extra method call --- .../baritone/cache/FasterWorldScanner.java | 55 +++++++++---------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/src/main/java/baritone/cache/FasterWorldScanner.java b/src/main/java/baritone/cache/FasterWorldScanner.java index 4a41eaf10..fbdc238ce 100644 --- a/src/main/java/baritone/cache/FasterWorldScanner.java +++ b/src/main/java/baritone/cache/FasterWorldScanner.java @@ -193,41 +193,15 @@ public enum FasterWorldScanner implements IWorldScanner { return; } - - int yOffset = section.getYLocation(); BitArray array = ((IBlockStateContainer) section.getData()).getStorage(); - collectBlockLocations(array, isInFilter, blocks, chunkX, chunkZ, yOffset); - } - - private boolean[] getIncludedFilterIndices(BlockOptionalMetaLookup lookup, IBlockStatePalette palette) { - boolean commonBlockFound = false; - ObjectIntIdentityMap paletteMap = getPalette(palette); - int size = paletteMap.size(); - - boolean[] isInFilter = new boolean[size]; - - for (int i = 0; i < size; i++) { - IBlockState state = paletteMap.getByValue(i); - if (lookup.has(state)) { - isInFilter[i] = true; - commonBlockFound = true; - } else { - isInFilter[i] = false; - } - } - - if (!commonBlockFound) { - return new boolean[0]; - } - return isInFilter; - } - - private static void collectBlockLocations(BitArray array, boolean[] isInFilter, List blocks, long chunkX, long chunkZ, int yOffset) { long[] longArray = array.getBackingLongArray(); int arraySize = array.size(); int bitsPerEntry = ((IBitArray) array).getBitsPerEntry(); long maxEntryValue = ((IBitArray) array).getMaxEntryValue(); + + int yOffset = section.getYLocation(); + for (int idx = 0, kl = bitsPerEntry - 1; idx < arraySize; idx++, kl += bitsPerEntry) { final int i = idx * bitsPerEntry; final int j = i >> 6; @@ -257,6 +231,29 @@ public enum FasterWorldScanner implements IWorldScanner { } } + private boolean[] getIncludedFilterIndices(BlockOptionalMetaLookup lookup, IBlockStatePalette palette) { + boolean commonBlockFound = false; + ObjectIntIdentityMap paletteMap = getPalette(palette); + int size = paletteMap.size(); + + boolean[] isInFilter = new boolean[size]; + + for (int i = 0; i < size; i++) { + IBlockState state = paletteMap.getByValue(i); + if (lookup.has(state)) { + isInFilter[i] = true; + commonBlockFound = true; + } else { + isInFilter[i] = false; + } + } + + if (!commonBlockFound) { + return new boolean[0]; + } + return isInFilter; + } + /** * cheats to get the actual map of id -> blockstate from the various palette implementations */ From c1b58f8a0182ecdf10d5c56a5bec05aabbc119b5 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sat, 18 Feb 2023 15:12:17 -0800 Subject: [PATCH 020/405] link 1.19 --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index e2c83ddec..5a59867d1 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ Minecraft Minecraft Minecraft + Minecraft

@@ -64,6 +65,8 @@ If you need Forge or Fabric 1.17.1, look [here](https://github.com/cabaletta/bar If you need Forge or Fabric 1.18.2, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.8.3) and get the `api-forge` or `api-fabric` jar. **For 1.18.2 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.8.3/baritone-api-fabric-1.8.3.jar)**. **For 1.18.2 Forge, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.8.3/baritone-api-forge-1.8.3.jar)**. +If you need Forge or Fabric 1.19.3, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.9.1) and get the `api-forge` or `api-fabric` jar. **For 1.19.3 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-fabric-1.9.1.jar)**. **For 1.19.3 Forge, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-forge-1.9.1.jar)**. + This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/), the original version of the bot for Minecraft 1.8.9, rebuilt for 1.12.2 onwards. Baritone focuses on reliability and particularly performance (it's over [30x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths). From b622adf3000fe4deba204f052c0ac7c530361f23 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sat, 18 Feb 2023 15:13:15 -0800 Subject: [PATCH 021/405] ugh why was this changed since 1.18 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5a59867d1..d0fd1dc83 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ If you need Forge or Fabric 1.17.1, look [here](https://github.com/cabaletta/bar If you need Forge or Fabric 1.18.2, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.8.3) and get the `api-forge` or `api-fabric` jar. **For 1.18.2 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.8.3/baritone-api-fabric-1.8.3.jar)**. **For 1.18.2 Forge, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.8.3/baritone-api-forge-1.8.3.jar)**. -If you need Forge or Fabric 1.19.3, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.9.1) and get the `api-forge` or `api-fabric` jar. **For 1.19.3 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-fabric-1.9.1.jar)**. **For 1.19.3 Forge, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-forge-1.9.1.jar)**. +If you need Forge or Fabric 1.19.3, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.9.1) and get the `api-forge` or `api-fabric` jar. **For 1.19.3 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-fabric-api-1.9.1.jar)**. **For 1.19.3 Forge, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-forge-api-1.9.1.jar)**. This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/), the original version of the bot for Minecraft 1.8.9, rebuilt for 1.12.2 onwards. Baritone focuses on reliability and particularly performance (it's over [30x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths). From 814c17522a1a3dc4db0f465a4c4e3c0603e74527 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sat, 18 Feb 2023 15:20:50 -0800 Subject: [PATCH 022/405] changed it back to the old way by manually renaming the release files --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d0fd1dc83..5a59867d1 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ If you need Forge or Fabric 1.17.1, look [here](https://github.com/cabaletta/bar If you need Forge or Fabric 1.18.2, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.8.3) and get the `api-forge` or `api-fabric` jar. **For 1.18.2 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.8.3/baritone-api-fabric-1.8.3.jar)**. **For 1.18.2 Forge, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.8.3/baritone-api-forge-1.8.3.jar)**. -If you need Forge or Fabric 1.19.3, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.9.1) and get the `api-forge` or `api-fabric` jar. **For 1.19.3 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-fabric-api-1.9.1.jar)**. **For 1.19.3 Forge, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-forge-api-1.9.1.jar)**. +If you need Forge or Fabric 1.19.3, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.9.1) and get the `api-forge` or `api-fabric` jar. **For 1.19.3 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-fabric-1.9.1.jar)**. **For 1.19.3 Forge, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-forge-1.9.1.jar)**. This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/), the original version of the bot for Minecraft 1.8.9, rebuilt for 1.12.2 onwards. Baritone focuses on reliability and particularly performance (it's over [30x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths). From 1e7e504650222dc24e82379f1e81fbbb3c793e3e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sat, 18 Feb 2023 15:37:37 -0800 Subject: [PATCH 023/405] v1.6.4 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 798b5b354..cfce46351 100755 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ */ group 'baritone' -version '1.6.3' +version '1.6.4' buildscript { repositories { From 6e5fec576fe837f4af83d09b7dccfc974233c5b6 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sat, 18 Feb 2023 15:38:40 -0800 Subject: [PATCH 024/405] v1.7.3 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 6e8b1ff4a..370de3110 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ org.gradle.jvmargs=-Xmx2048M -mod_version=1.7.2 +mod_version=1.7.3 maven_group=baritone archives_base_name=baritone From 24e047c12e807fc4ee6528f4698c560b70e5a641 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sat, 18 Feb 2023 15:41:19 -0800 Subject: [PATCH 025/405] v1.8.4 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 77cfe8cf6..4a9d6249d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ org.gradle.jvmargs=-Xmx2048M -mod_version=1.8.3 +mod_version=1.8.4 maven_group=baritone archives_base_name=baritone From 174bdd230742486dd858be2032255f59724a0e6e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sat, 18 Feb 2023 16:42:05 -0800 Subject: [PATCH 026/405] overhaul readme --- README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 5a59867d1..0a511013b 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Minecraft Minecraft Minecraft - Minecraft + Minecraft Minecraft Minecraft

@@ -49,23 +49,23 @@ A Minecraft pathfinder bot. -[**Baritone Discord Server**](http://discord.gg/s6fRBAUpmr) - Baritone is the pathfinding system used in [Impact](https://impactclient.net/) since 4.4. There's a [showcase video](https://youtu.be/CZkLXWo4Fg4) made by @Adovin#0730 on Baritone which I recommend. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a (very old!) video I made showing off what it can do. -[Tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa) +[**Baritone Discord Server**](http://discord.gg/s6fRBAUpmr) -The easiest way to install Baritone is to install [Impact](https://impactclient.net/), which comes with Baritone. The second easiest way (for 1.12.2 only) is to -install the v1.2.* `api-forge` jar from [releases](https://github.com/cabaletta/baritone/releases). **For 1.12.2 Forge, just click -[here](https://github.com/cabaletta/baritone/releases/download/v1.2.17/baritone-api-forge-1.2.17.jar)**. Otherwise, see [Installation & setup](SETUP.md). Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it. +**Quick download links:** -For 1.16.5, [click here](https://www.youtube.com/watch?v=_4eVJ9Qz2J8) and see description. If you need Forge or Fabric 1.16.5, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.6.3) and get the `api-forge` or `api-fabric` jar. **For 1.16.5 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.6.3/baritone-api-fabric-1.6.3.jar)**. +| Forge | Fabric | +|---------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------| +| [1.12.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.2.17/baritone-api-forge-1.2.17.jar) | | +| [1.16.5 Forge](https://github.com/cabaletta/baritone/releases/download/v1.6.4/baritone-api-forge-1.6.4.jar) | [1.16.5 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.6.4/baritone-api-fabric-1.6.4.jar) | +| [1.17.1 Forge](https://github.com/cabaletta/baritone/releases/download/v1.7.3/baritone-api-forge-1.7.3.jar) | [1.17.1 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.7.3/baritone-api-fabric-1.7.3.jar) | +| [1.18.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.8.4/baritone-api-forge-1.8.4.jar) | [1.18.2 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.8.4/baritone-api-fabric-1.8.4.jar) | +| [1.19.3 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-forge-1.9.1.jar) | [1.19.3 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-fabric-1.9.1.jar) | -If you need Forge or Fabric 1.17.1, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.7.2) and get the `api-forge` or `api-fabric` jar. **For 1.17.1 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.7.2/baritone-api-fabric-1.7.2.jar)**. +**How to immediately get started:** Type `#goto 1000 500` in chat to go to x=1000 z=500. Type `#mine diamond_ore` to mine diamond ore. Type `#stop` to stop. For more, read [the usage page](USAGE.md) and/or watch this [tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa) -If you need Forge or Fabric 1.18.2, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.8.3) and get the `api-forge` or `api-fabric` jar. **For 1.18.2 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.8.3/baritone-api-fabric-1.8.3.jar)**. **For 1.18.2 Forge, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.8.3/baritone-api-forge-1.8.3.jar)**. - -If you need Forge or Fabric 1.19.3, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.9.1) and get the `api-forge` or `api-fabric` jar. **For 1.19.3 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-fabric-1.9.1.jar)**. **For 1.19.3 Forge, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-forge-1.9.1.jar)**. +For other versions of Minecraft or more complicated situations or for development, see [Installation & setup](SETUP.md). Also consider just installing [Impact](https://impactclient.net/), which comes with Baritone and is easier to install than wrangling with version JSONs and zips. For 1.16.5, [click here](https://www.youtube.com/watch?v=_4eVJ9Qz2J8) and see description. Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it. This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/), the original version of the bot for Minecraft 1.8.9, rebuilt for 1.12.2 onwards. Baritone focuses on reliability and particularly performance (it's over [30x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths). From 9efc5122538b63db9cf57e1a83048a4882169c0b Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Sun, 19 Feb 2023 19:17:11 +0100 Subject: [PATCH 027/405] Make tab completion usable Now behaves almost identical to vanilla tab completion --- .../mixins/MixinCommandSuggestionHelper.java | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/launch/java/baritone/launch/mixins/MixinCommandSuggestionHelper.java b/src/launch/java/baritone/launch/mixins/MixinCommandSuggestionHelper.java index 00497ab6b..5603246d4 100644 --- a/src/launch/java/baritone/launch/mixins/MixinCommandSuggestionHelper.java +++ b/src/launch/java/baritone/launch/mixins/MixinCommandSuggestionHelper.java @@ -19,6 +19,7 @@ package baritone.launch.mixins; import baritone.api.BaritoneAPI; import baritone.api.event.events.TabCompleteEvent; +import com.mojang.brigadier.ParseResults; import com.mojang.brigadier.context.StringRange; import com.mojang.brigadier.suggestion.Suggestion; import com.mojang.brigadier.suggestion.Suggestions; @@ -51,9 +52,18 @@ public class MixinCommandSuggestionHelper { @Final private List exceptionList; + @Shadow + private ParseResults parseResults; + @Shadow private CompletableFuture suggestionsFuture; + @Shadow + private CommandSuggestionHelper.Suggestions suggestions; + + @Shadow + boolean isApplyingSuggestion; + @Inject( method = "init", at = @At("HEAD"), @@ -74,27 +84,32 @@ public class MixinCommandSuggestionHelper { if (event.completions != null) { ci.cancel(); + this.parseResults = null; // stop coloring + + if (this.isApplyingSuggestion) { // Supress suggestions update when cycling suggestions. + return; + } + + this.inputField.setSuggestion(null); // clear old suggestions + this.suggestions = null; // TODO: Support populating the command usage this.exceptionList.clear(); if (event.completions.length == 0) { this.suggestionsFuture = Suggestions.empty(); } else { - int offset = this.inputField.getText().endsWith(" ") - ? this.inputField.getCursorPosition() - : this.inputField.getText().lastIndexOf(" ") + 1; // If there is no space this is still 0 haha yes + StringRange range = StringRange.between(prefix.lastIndexOf(" ") + 1, prefix.length()); // if there is no space this starts at 0 List suggestionList = Stream.of(event.completions) - .map(s -> new Suggestion(StringRange.between(offset, offset + s.length()), s)) + .map(s -> new Suggestion(range, s)) .collect(Collectors.toList()); - Suggestions suggestions = new Suggestions( - StringRange.between(offset, offset + suggestionList.stream().mapToInt(s -> s.getText().length()).max().orElse(0)), - suggestionList); + Suggestions suggestions = new Suggestions(range, suggestionList); this.suggestionsFuture = new CompletableFuture<>(); this.suggestionsFuture.complete(suggestions); } + ((CommandSuggestionHelper) (Object) this).updateSuggestions(true); // actually populate the suggestions list from the suggestions future } } } From f1ead19b6e0ea41e7a2343d56b4dcab417140725 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 28 Feb 2023 23:44:33 -0800 Subject: [PATCH 028/405] option to only move inventory when stationary --- src/api/java/baritone/api/Settings.java | 10 +++ src/main/java/baritone/Baritone.java | 6 ++ .../baritone/behavior/InventoryBehavior.java | 38 ++++++-- .../java/baritone/process/BuilderProcess.java | 5 +- .../process/InventoryPauserProcess.java | 90 +++++++++++++++++++ 5 files changed, 141 insertions(+), 8 deletions(-) create mode 100644 src/main/java/baritone/process/InventoryPauserProcess.java diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 9e3e6a385..38661d8be 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -69,6 +69,16 @@ public final class Settings { */ public final Setting allowInventory = new Setting<>(false); + /** + * Wait this many ticks between InventoryBehavior moving inventory items + */ + public final Setting ticksBetweenInventoryMoves = new Setting<>(1); + + /** + * Come to a halt before doing any inventory moves. Intended for anticheat such as 2b2t + */ + public final Setting inventoryMoveOnlyIfStationary = new Setting<>(false); + /** * Disable baritone's auto-tool at runtime, but still assume that another mod will provide auto tool functionality *

diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index 71c2c455a..61db54211 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -80,6 +80,7 @@ public class Baritone implements IBaritone { private ExploreProcess exploreProcess; private BackfillProcess backfillProcess; private FarmProcess farmProcess; + private InventoryPauserProcess inventoryPauserProcess; private PathingControlManager pathingControlManager; private SelectionManager selectionManager; @@ -115,6 +116,7 @@ public class Baritone implements IBaritone { this.pathingControlManager.registerProcess(exploreProcess = new ExploreProcess(this)); this.pathingControlManager.registerProcess(backfillProcess = new BackfillProcess(this)); this.pathingControlManager.registerProcess(farmProcess = new FarmProcess(this)); + this.pathingControlManager.registerProcess(inventoryPauserProcess = new InventoryPauserProcess(this)); } this.worldProvider = new WorldProvider(); @@ -183,6 +185,10 @@ public class Baritone implements IBaritone { return this.farmProcess; } + public InventoryPauserProcess getInventoryPauserProcess() { + return this.inventoryPauserProcess; + } + @Override public PathingBehavior getPathingBehavior() { return this.pathingBehavior; diff --git a/src/main/java/baritone/behavior/InventoryBehavior.java b/src/main/java/baritone/behavior/InventoryBehavior.java index 3dce5c0b5..93dc200cc 100644 --- a/src/main/java/baritone/behavior/InventoryBehavior.java +++ b/src/main/java/baritone/behavior/InventoryBehavior.java @@ -19,6 +19,7 @@ package baritone.behavior; import baritone.Baritone; import baritone.api.event.events.TickEvent; +import baritone.api.utils.Helper; import baritone.utils.ToolSet; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; @@ -34,7 +35,10 @@ import java.util.OptionalInt; import java.util.Random; import java.util.function.Predicate; -public final class InventoryBehavior extends Behavior { +public final class InventoryBehavior extends Behavior implements Helper { + + int ticksSinceLastInventoryMove; + int[] lastTickRequestedMove; // not everything asks every tick, so remember the request while coming to a halt public InventoryBehavior(Baritone baritone) { super(baritone); @@ -52,20 +56,28 @@ public final class InventoryBehavior extends Behavior { // we have a crafting table or a chest or something open return; } + ticksSinceLastInventoryMove++; if (firstValidThrowaway() >= 9) { // aka there are none on the hotbar, but there are some in main inventory - swapWithHotBar(firstValidThrowaway(), 8); + requestSwapWithHotBar(firstValidThrowaway(), 8); } int pick = bestToolAgainst(Blocks.STONE, ItemPickaxe.class); if (pick >= 9) { - swapWithHotBar(pick, 0); + requestSwapWithHotBar(pick, 0); + } + if (lastTickRequestedMove != null) { + logDebug("Remembering to move " + lastTickRequestedMove[0] + " " + lastTickRequestedMove[1] + " from a previous tick"); + requestSwapWithHotBar(lastTickRequestedMove[0], lastTickRequestedMove[1]); } } - public void attemptToPutOnHotbar(int inMainInvy, Predicate disallowedHotbar) { + public boolean attemptToPutOnHotbar(int inMainInvy, Predicate disallowedHotbar) { OptionalInt destination = getTempHotbarSlot(disallowedHotbar); if (destination.isPresent()) { - swapWithHotBar(inMainInvy, destination.getAsInt()); + if (!requestSwapWithHotBar(inMainInvy, destination.getAsInt())) { + return false; + } } + return true; } public OptionalInt getTempHotbarSlot(Predicate disallowedHotbar) { @@ -89,8 +101,20 @@ public final class InventoryBehavior extends Behavior { return OptionalInt.of(candidates.get(new Random().nextInt(candidates.size()))); } - private void swapWithHotBar(int inInventory, int inHotbar) { + private boolean requestSwapWithHotBar(int inInventory, int inHotbar) { + lastTickRequestedMove = new int[]{inInventory, inHotbar}; + if (ticksSinceLastInventoryMove < Baritone.settings().ticksBetweenInventoryMoves.value) { + logDebug("Inventory move requested but delaying " + ticksSinceLastInventoryMove + " " + Baritone.settings().ticksBetweenInventoryMoves.value); + return false; + } + if (Baritone.settings().inventoryMoveOnlyIfStationary.value && !baritone.getInventoryPauserProcess().stationaryForInventoryMove()) { + logDebug("Inventory move requested but delaying until stationary"); + return false; + } ctx.playerController().windowClick(ctx.player().inventoryContainer.windowId, inInventory < 9 ? inInventory + 36 : inInventory, inHotbar, ClickType.SWAP, ctx.player()); + ticksSinceLastInventoryMove = 0; + lastTickRequestedMove = null; + return true; } private int firstValidThrowaway() { // TODO offhand idk @@ -192,8 +216,8 @@ public final class InventoryBehavior extends Behavior { if (allowInventory) { for (int i = 9; i < 36; i++) { if (desired.test(inv.get(i))) { - swapWithHotBar(i, 7); if (select) { + requestSwapWithHotBar(i, 7); p.inventory.currentItem = 7; } return true; diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index 85be6516a..c7868a4a0 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -562,7 +562,10 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil for (int i = 9; i < 36; i++) { for (IBlockState desired : noValidHotbarOption) { if (valid(approxPlaceable.get(i), desired, true)) { - baritone.getInventoryBehavior().attemptToPutOnHotbar(i, usefulSlots::contains); + if (!baritone.getInventoryBehavior().attemptToPutOnHotbar(i, usefulSlots::contains)) { + // awaiting inventory move, so pause + return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); + } break outer; } } diff --git a/src/main/java/baritone/process/InventoryPauserProcess.java b/src/main/java/baritone/process/InventoryPauserProcess.java new file mode 100644 index 000000000..ab210532b --- /dev/null +++ b/src/main/java/baritone/process/InventoryPauserProcess.java @@ -0,0 +1,90 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.process; + +import baritone.Baritone; +import baritone.api.process.PathingCommand; +import baritone.api.process.PathingCommandType; +import baritone.utils.BaritoneProcessHelper; + +public class InventoryPauserProcess extends BaritoneProcessHelper { + + boolean pauseRequestedLastTick; + boolean safeToCancelLastTick; + int ticksOfStationary; + + public InventoryPauserProcess(Baritone baritone) { + super(baritone); + } + + @Override + public boolean isActive() { + if (mc.player == null || mc.world == null) { + return false; + } + return true; + } + + private double motion() { + return Math.sqrt(mc.player.motionX * mc.player.motionX + mc.player.motionZ * mc.player.motionZ); + } + + private boolean stationaryNow() { + return motion() < 0.00001; + } + + public boolean stationaryForInventoryMove() { + pauseRequestedLastTick = true; + return safeToCancelLastTick && ticksOfStationary > 1; + } + + @Override + public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { + //logDebug(pauseRequestedLastTick + " " + safeToCancelLastTick + " " + ticksOfStationary); + safeToCancelLastTick = isSafeToCancel; + if (pauseRequestedLastTick) { + pauseRequestedLastTick = false; + if (stationaryNow()) { + ticksOfStationary++; + } + return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); + } + ticksOfStationary = 0; + return new PathingCommand(null, PathingCommandType.DEFER); + } + + @Override + public void onLostControl() { + + } + + @Override + public String displayName0() { + return "inventory pauser"; + } + + @Override + public double priority() { + return 5.1; // slightly higher than backfill + } + + @Override + public boolean isTemporary() { + return true; + } +} From c9d7a5bea61ae28aeeb5e01e7520217fd487b371 Mon Sep 17 00:00:00 2001 From: leijurv Date: Tue, 28 Feb 2023 23:56:34 -0800 Subject: [PATCH 029/405] kami blue to lambda --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0a511013b..0aec1468d 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@

Impact integration - KAMI Blue integration + Lambda integration ForgeHax integration Aristois add-on integration rootNET integration From 790a4f6769f462dd1fb92d64b2f5855f10c86dce Mon Sep 17 00:00:00 2001 From: Leijurv Date: Wed, 1 Mar 2023 00:25:30 -0800 Subject: [PATCH 030/405] command to load settings from a specific file --- src/api/java/baritone/api/BaritoneAPI.java | 2 +- .../java/baritone/api/utils/SettingsUtil.java | 22 +++++++++++-------- .../baritone/command/defaults/SetCommand.java | 18 +++++++++++++-- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/api/java/baritone/api/BaritoneAPI.java b/src/api/java/baritone/api/BaritoneAPI.java index 53937bd80..935bf9e4f 100644 --- a/src/api/java/baritone/api/BaritoneAPI.java +++ b/src/api/java/baritone/api/BaritoneAPI.java @@ -35,7 +35,7 @@ public final class BaritoneAPI { static { settings = new Settings(); - SettingsUtil.readAndApply(settings); + SettingsUtil.readAndApply(settings, SettingsUtil.SETTINGS_DEFAULT_NAME); ServiceLoader baritoneLoader = ServiceLoader.load(IBaritoneProvider.class); Iterator instances = baritoneLoader.iterator(); diff --git a/src/api/java/baritone/api/utils/SettingsUtil.java b/src/api/java/baritone/api/utils/SettingsUtil.java index f47f515a8..50e2363a6 100644 --- a/src/api/java/baritone/api/utils/SettingsUtil.java +++ b/src/api/java/baritone/api/utils/SettingsUtil.java @@ -48,7 +48,7 @@ import static net.minecraft.client.Minecraft.getMinecraft; public class SettingsUtil { - private static final Path SETTINGS_PATH = getMinecraft().gameDir.toPath().resolve("baritone").resolve("settings.txt"); + public static final String SETTINGS_DEFAULT_NAME = "settings.txt"; private static final Pattern SETTING_PATTERN = Pattern.compile("^(?[^ ]+) +(?.+)"); // key and value split by the first space private static final String[] JAVA_ONLY_SETTINGS = {"logger", "notifier", "toaster"}; @@ -68,12 +68,12 @@ public class SettingsUtil { } } - public static void readAndApply(Settings settings) { + public static void readAndApply(Settings settings, String settingsName) { try { - forEachLine(SETTINGS_PATH, line -> { + forEachLine(settingsByName(settingsName), line -> { Matcher matcher = SETTING_PATTERN.matcher(line); if (!matcher.matches()) { - System.out.println("Invalid syntax in setting file: " + line); + Helper.HELPER.logDirect("Invalid syntax in setting file: " + line); return; } @@ -82,29 +82,33 @@ public class SettingsUtil { try { parseAndApply(settings, settingName, settingValue); } catch (Exception ex) { - System.out.println("Unable to parse line " + line); + Helper.HELPER.logDirect("Unable to parse line " + line); ex.printStackTrace(); } }); } catch (NoSuchFileException ignored) { - System.out.println("Baritone settings file not found, resetting."); + Helper.HELPER.logDirect("Baritone settings file not found, resetting."); } catch (Exception ex) { - System.out.println("Exception while reading Baritone settings, some settings may be reset to default values!"); + Helper.HELPER.logDirect("Exception while reading Baritone settings, some settings may be reset to default values!"); ex.printStackTrace(); } } public static synchronized void save(Settings settings) { - try (BufferedWriter out = Files.newBufferedWriter(SETTINGS_PATH)) { + try (BufferedWriter out = Files.newBufferedWriter(settingsByName(SETTINGS_DEFAULT_NAME))) { for (Settings.Setting setting : modifiedSettings(settings)) { out.write(settingToString(setting) + "\n"); } } catch (Exception ex) { - System.out.println("Exception thrown while saving Baritone settings!"); + Helper.HELPER.logDirect("Exception thrown while saving Baritone settings!"); ex.printStackTrace(); } } + private static Path settingsByName(String name) { + return getMinecraft().gameDir.toPath().resolve("baritone").resolve(name); + } + public static List modifiedSettings(Settings settings) { List modified = new ArrayList<>(); for (Settings.Setting setting : settings.allSettings) { diff --git a/src/main/java/baritone/command/defaults/SetCommand.java b/src/main/java/baritone/command/defaults/SetCommand.java index fd9bb0457..255dd6b28 100644 --- a/src/main/java/baritone/command/defaults/SetCommand.java +++ b/src/main/java/baritone/command/defaults/SetCommand.java @@ -57,6 +57,18 @@ public class SetCommand extends Command { logDirect("Settings saved"); return; } + if (Arrays.asList("load", "ld").contains(arg)) { + String file = SETTINGS_DEFAULT_NAME; + if (args.hasAny()) { + file = args.getString(); + } + // reset to defaults + SettingsUtil.modifiedSettings(Baritone.settings()).forEach(Settings.Setting::reset); + // then load from disk + SettingsUtil.readAndApply(Baritone.settings(), file); + logDirect("Settings reloaded from " + file); + return; + } boolean viewModified = Arrays.asList("m", "mod", "modified").contains(arg); boolean viewAll = Arrays.asList("all", "l", "list").contains(arg); boolean paginate = viewModified || viewAll; @@ -228,7 +240,7 @@ public class SetCommand extends Command { return new TabCompleteHelper() .addSettings() .sortAlphabetically() - .prepend("list", "modified", "reset", "toggle", "save") + .prepend("list", "modified", "reset", "toggle", "save", "load") .filterPrefix(arg) .stream(); } @@ -255,7 +267,9 @@ public class SetCommand extends Command { "> set reset all - Reset ALL SETTINGS to their defaults", "> set reset - Reset a setting to its default", "> set toggle - Toggle a boolean setting", - "> set save - Save all settings (this is automatic tho)" + "> set save - Save all settings (this is automatic tho)", + "> set load - Load settings from settings.txt", + "> set load [filename] - Load settings from another file in your minecraft/baritone" ); } } From 6698505dd83b239f67d5ca459196d011c852ed49 Mon Sep 17 00:00:00 2001 From: Wagyourtail Date: Mon, 13 Mar 2023 15:31:18 -0700 Subject: [PATCH 031/405] make wp c not throw npe on invalid tag name --- .../java/baritone/command/defaults/WaypointsCommand.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/baritone/command/defaults/WaypointsCommand.java b/src/main/java/baritone/command/defaults/WaypointsCommand.java index cf420e90a..3016745e1 100644 --- a/src/main/java/baritone/command/defaults/WaypointsCommand.java +++ b/src/main/java/baritone/command/defaults/WaypointsCommand.java @@ -149,7 +149,11 @@ public class WaypointsCommand extends Command { logDirect(component); } else if (action == Action.CLEAR) { args.requireMax(1); - IWaypoint.Tag tag = IWaypoint.Tag.getByName(args.getString()); + String name = args.getString(); + IWaypoint.Tag tag = IWaypoint.Tag.getByName(name); + if (tag == null) { + throw new CommandInvalidStateException("Invalid tag, \"" + name + "\""); + } IWaypoint[] waypoints = ForWaypoints.getWaypointsByTag(this.baritone, tag); for (IWaypoint waypoint : waypoints) { ForWaypoints.waypoints(this.baritone).removeWaypoint(waypoint); From 3200d976d732a9920a5c650f450265e95ecc3ef0 Mon Sep 17 00:00:00 2001 From: leijurv Date: Tue, 14 Mar 2023 18:35:15 -0700 Subject: [PATCH 032/405] 1.19.4 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0aec1468d..3cf5402e9 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ Baritone is the pathfinding system used in [Impact](https://impactclient.net/) s | [1.17.1 Forge](https://github.com/cabaletta/baritone/releases/download/v1.7.3/baritone-api-forge-1.7.3.jar) | [1.17.1 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.7.3/baritone-api-fabric-1.7.3.jar) | | [1.18.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.8.4/baritone-api-forge-1.8.4.jar) | [1.18.2 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.8.4/baritone-api-fabric-1.8.4.jar) | | [1.19.3 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-forge-1.9.1.jar) | [1.19.3 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-fabric-1.9.1.jar) | +| | [1.19.4 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.2/baritone-api-fabric-1.9.2.jar) | **How to immediately get started:** Type `#goto 1000 500` in chat to go to x=1000 z=500. Type `#mine diamond_ore` to mine diamond ore. Type `#stop` to stop. For more, read [the usage page](USAGE.md) and/or watch this [tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa) From ff1732011ed8cc9642a3d92bfe62e31d10a51708 Mon Sep 17 00:00:00 2001 From: leijurv Date: Mon, 20 Mar 2023 22:07:51 -0700 Subject: [PATCH 033/405] vid is outdated and doesn't get to the point fast enough, so let's move it lower down --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3cf5402e9..7a35e1199 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ A Minecraft pathfinder bot. -Baritone is the pathfinding system used in [Impact](https://impactclient.net/) since 4.4. There's a [showcase video](https://youtu.be/CZkLXWo4Fg4) made by @Adovin#0730 on Baritone which I recommend. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a (very old!) video I made showing off what it can do. +Baritone is the pathfinding system used in [Impact](https://impactclient.net/) since 4.4. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a (very old!) video I made showing off what it can do. [**Baritone Discord Server**](http://discord.gg/s6fRBAUpmr) @@ -66,7 +66,7 @@ Baritone is the pathfinding system used in [Impact](https://impactclient.net/) s **How to immediately get started:** Type `#goto 1000 500` in chat to go to x=1000 z=500. Type `#mine diamond_ore` to mine diamond ore. Type `#stop` to stop. For more, read [the usage page](USAGE.md) and/or watch this [tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa) -For other versions of Minecraft or more complicated situations or for development, see [Installation & setup](SETUP.md). Also consider just installing [Impact](https://impactclient.net/), which comes with Baritone and is easier to install than wrangling with version JSONs and zips. For 1.16.5, [click here](https://www.youtube.com/watch?v=_4eVJ9Qz2J8) and see description. Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it. +For other versions of Minecraft or more complicated situations or for development, see [Installation & setup](SETUP.md). Also consider just installing [Impact](https://impactclient.net/), which comes with Baritone and is easier to install than wrangling with version JSONs and zips. For 1.16.5, [click here](https://www.youtube.com/watch?v=_4eVJ9Qz2J8) and see description. Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it. There's a [showcase video](https://youtu.be/CZkLXWo4Fg4) made by @Adovin#6313 on Baritone which I recommend. This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/), the original version of the bot for Minecraft 1.8.9, rebuilt for 1.12.2 onwards. Baritone focuses on reliability and particularly performance (it's over [30x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths). From 0cf89e0b2a6edfe589eaf804d6562368d0a0fcd2 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 2 Apr 2023 15:20:26 -0700 Subject: [PATCH 034/405] Revert "fix items and #click" This reverts commit 4168401aa1ce2d2423602ea21e1527d54846d8fd. --- gradle.properties | 4 +- .../baritone/api/utils/BlockOptionalMeta.java | 86 +++++-------------- src/main/java/baritone/utils/GuiClick.java | 9 +- tweaker/build.gradle | 2 +- 4 files changed, 28 insertions(+), 73 deletions(-) diff --git a/gradle.properties b/gradle.properties index 7b0d1f440..208dbb3e7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,6 +4,6 @@ mod_version=1.9.1 maven_group=baritone archives_base_name=baritone -minecraft_version=1.19.3 -forge_version=1.19.3-44.0.1 +minecraft_version=1.19.2 +forge_version=1.19.2-43.0.0 fabric_version=0.14.11 diff --git a/src/api/java/baritone/api/utils/BlockOptionalMeta.java b/src/api/java/baritone/api/utils/BlockOptionalMeta.java index b144240d0..2ba6f3ed1 100644 --- a/src/api/java/baritone/api/utils/BlockOptionalMeta.java +++ b/src/api/java/baritone/api/utils/BlockOptionalMeta.java @@ -19,30 +19,26 @@ package baritone.api.utils; import baritone.api.utils.accessor.IItemStack; import com.google.common.collect.ImmutableSet; +import com.google.common.util.concurrent.ThreadFactoryBuilder; import io.netty.util.concurrent.ThreadPerTaskExecutor; -import net.minecraft.client.Minecraft; +import net.minecraft.SharedConstants; import net.minecraft.core.BlockPos; -import net.minecraft.resources.ResourceKey; +import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.progress.ChunkProgressListener; import net.minecraft.server.packs.*; +import net.minecraft.server.packs.metadata.pack.PackMetadataSection; +import net.minecraft.server.packs.repository.PackRepository; import net.minecraft.server.packs.repository.ServerPacksSource; import net.minecraft.server.packs.resources.MultiPackResourceManager; import net.minecraft.server.packs.resources.ReloadableResourceManager; import net.minecraft.util.RandomSource; import net.minecraft.util.Unit; -import net.minecraft.world.flag.FeatureFlagSet; +import net.minecraft.world.flag.FeatureFlags; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.CustomSpawner; -import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.dimension.LevelStem; -import net.minecraft.world.level.storage.LevelStorageSource; -import net.minecraft.world.level.storage.ServerLevelData; import net.minecraft.world.level.storage.loot.BuiltInLootTables; import net.minecraft.world.level.storage.loot.LootContext; import net.minecraft.world.level.storage.loot.LootTables; @@ -50,14 +46,13 @@ import net.minecraft.world.level.storage.loot.PredicateManager; import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; import net.minecraft.world.level.storage.loot.parameters.LootContextParams; import net.minecraft.world.phys.Vec3; -import sun.misc.Unsafe; +import org.apache.logging.log4j.core.jmx.Server; import javax.annotation.Nonnull; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.*; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; import java.util.regex.MatchResult; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -69,7 +64,7 @@ public final class BlockOptionalMeta { private final ImmutableSet stateHashes; private final ImmutableSet stackHashes; private static final Pattern pattern = Pattern.compile("^(.+?)(?::(\\d+))?$"); - private static LootTables lootTables; + private static LootTables manager; private static PredicateManager predicate = new PredicateManager(); private static Map> drops = new HashMap<>(); @@ -173,11 +168,11 @@ public final class BlockOptionalMeta { } public static LootTables getManager() { - if (lootTables == null) { + if (manager == null) { MultiPackResourceManager resources = new MultiPackResourceManager(PackType.SERVER_DATA, List.of(getVanillaServerPack())); ReloadableResourceManager resourceManager = new ReloadableResourceManager(PackType.SERVER_DATA); - lootTables = new LootTables(predicate); - resourceManager.registerReloadListener(lootTables); + manager = new LootTables(predicate); + resourceManager.registerReloadListener(manager); try { resourceManager.createReload(new ThreadPerTaskExecutor(Thread::new), new ThreadPerTaskExecutor(Thread::new), CompletableFuture.completedFuture(Unit.INSTANCE), resources.listPacks().toList()).done().get(); } catch (Exception exception) { @@ -185,7 +180,7 @@ public final class BlockOptionalMeta { } } - return lootTables; + return manager; } public static PredicateManager getPredicateManager() { @@ -199,55 +194,20 @@ public final class BlockOptionalMeta { return Collections.emptyList(); } else { List items = new ArrayList<>(); - try { - getManager().get(lootTableLocation).getRandomItems( - new LootContext.Builder(ServerLevelStub.fastCreate()) - .withRandom(RandomSource.create()) - .withParameter(LootContextParams.ORIGIN, Vec3.atLowerCornerOf(BlockPos.ZERO)) - .withParameter(LootContextParams.TOOL, ItemStack.EMPTY) - .withOptionalParameter(LootContextParams.BLOCK_ENTITY, null) - .withParameter(LootContextParams.BLOCK_STATE, block.defaultBlockState()) - .create(LootContextParamSets.BLOCK), + + // the other overload for generate doesnt work in forge because forge adds code that requires a non null world + getManager().get(lootTableLocation).getRandomItems( + new LootContext.Builder((ServerLevel null) + .withRandom(RandomSource.create()) + .withParameter(LootContextParams.ORIGIN, Vec3.atLowerCornerOf(BlockPos.ZERO)) + .withParameter(LootContextParams.TOOL, ItemStack.EMPTY) + .withOptionalParameter(LootContextParams.BLOCK_ENTITY, null) + .withParameter(LootContextParams.BLOCK_STATE, block.defaultBlockState()) + .create(LootContextParamSets.BLOCK), stack -> items.add(stack.getItem()) - ); - } catch (Exception e) { - e.printStackTrace(); - } + ); return items; } }); } - - private static class ServerLevelStub extends ServerLevel { - private static Minecraft client = Minecraft.getInstance(); - private static Unsafe unsafe = getUnsafe(); - public ServerLevelStub(MinecraftServer $$0, Executor $$1, LevelStorageSource.LevelStorageAccess $$2, ServerLevelData $$3, ResourceKey $$4, LevelStem $$5, ChunkProgressListener $$6, boolean $$7, long $$8, List $$9, boolean $$10) { - super($$0, $$1, $$2, $$3, $$4, $$5, $$6, $$7, $$8, $$9, $$10); - } - - @Override - public FeatureFlagSet enabledFeatures() { - assert client.level != null; - return client.level.enabledFeatures(); - } - - public static ServerLevelStub fastCreate() { - try { - return (ServerLevelStub) unsafe.allocateInstance(ServerLevelStub.class); - } catch (InstantiationException e) { - throw new RuntimeException(e); - } - } - - public static Unsafe getUnsafe() { - try { - Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); - theUnsafe.setAccessible(true); - return (Unsafe) theUnsafe.get(null); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - } } diff --git a/src/main/java/baritone/utils/GuiClick.java b/src/main/java/baritone/utils/GuiClick.java index b3b2dc500..876d5fb42 100644 --- a/src/main/java/baritone/utils/GuiClick.java +++ b/src/main/java/baritone/utils/GuiClick.java @@ -80,7 +80,6 @@ public class GuiClick extends Screen implements Helper { HitResult result = player.level.clip(new ClipContext(near.add(viewerPos), far.add(viewerPos), ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player)); if (result != null && result.getType() == HitResult.Type.BLOCK) { currentMouseOver = ((BlockHitResult) result).getBlockPos(); - System.out.println("currentMouseOver = " + currentMouseOver); } } } @@ -159,13 +158,9 @@ public class GuiClick extends Screen implements Helper { y = y * 2 - 1; Vector4f pos = new Vector4f((float) x, (float) y, (float) z, 1.0F); - projectionViewMatrix.transform(pos); + projectionViewMatrix.transformProject(pos); - if (pos.w() == 0) { - return null; - } - - pos.mul(1/pos.w()); + pos.normalize(); return new Vec3(pos.x(), pos.y(), pos.z()); } } diff --git a/tweaker/build.gradle b/tweaker/build.gradle index ce623af6c..1b6304189 100644 --- a/tweaker/build.gradle +++ b/tweaker/build.gradle @@ -17,7 +17,7 @@ import baritone.gradle.task.CreateDistTask import baritone.gradle.task.ProguardTask -//import baritone.gradle.task.TweakerJsonAssembler +import baritone.gradle.task.TweakerJsonAssembler plugins { id "com.github.johnrengelman.shadow" version "7.0.0" From e4d725d9aae4683b439d44edd1d404dc5e034407 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 2 Apr 2023 15:24:50 -0700 Subject: [PATCH 035/405] Revert "loottables broke & #click not working" This reverts commit 3e082b21d584e6c05544ee0505cd40c79d4eb6fd. --- fabric/src/main/resources/fabric.mod.json | 2 +- forge/src/main/resources/META-INF/mods.toml | 2 +- gradle.properties | 4 ++-- settings.gradle | 1 - .../api/command/datatypes/BlockById.java | 9 ++++--- .../command/datatypes/EntityClassById.java | 9 ++++--- .../api/event/events/RenderEvent.java | 2 +- .../baritone/api/utils/BlockOptionalMeta.java | 23 +++++++----------- .../java/baritone/api/utils/BlockUtils.java | 5 ++-- .../java/baritone/api/utils/SettingsUtil.java | 5 ++-- .../mixins/MixinClientPlayNetHandler.java | 24 ------------------- .../mixins/MixinClientPlayerEntity.java | 17 +++++++++++++ .../launch/mixins/MixinWorldRenderer.java | 2 +- .../command/defaults/FindCommand.java | 9 ++++--- .../command/defaults/FollowCommand.java | 3 +-- .../pathing/movement/MovementHelper.java | 2 +- src/main/java/baritone/utils/GuiClick.java | 15 +++++++----- src/main/java/baritone/utils/IRenderer.java | 2 +- .../java/baritone/utils/PathRenderer.java | 2 +- .../format/defaults/LitematicaSchematic.java | 3 +-- .../format/defaults/MCEditSchematic.java | 3 +-- .../format/defaults/SpongeSchematic.java | 3 +-- tweaker/build.gradle | 2 +- 23 files changed, 65 insertions(+), 84 deletions(-) diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 62a815d0f..539fed3a8 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -26,6 +26,6 @@ "depends": { "fabricloader": ">=0.11.0", - "minecraft": "1.19.3" + "minecraft": "1.19.2" } } \ No newline at end of file diff --git a/forge/src/main/resources/META-INF/mods.toml b/forge/src/main/resources/META-INF/mods.toml index 2a25bf8ed..9297ed74b 100644 --- a/forge/src/main/resources/META-INF/mods.toml +++ b/forge/src/main/resources/META-INF/mods.toml @@ -35,6 +35,6 @@ A Minecraft pathfinder bot. modId="minecraft" mandatory=true # This version range declares a minimum of the current minecraft version up to but not including the next major version -versionRange="[1.19.3]" +versionRange="[1.19.2]" ordering="NONE" side="BOTH" \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 208dbb3e7..4c3f5b494 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,5 +5,5 @@ maven_group=baritone archives_base_name=baritone minecraft_version=1.19.2 -forge_version=1.19.2-43.0.0 -fabric_version=0.14.11 +forge_version=1.19.2-43.1.65 +fabric_version=0.14.9 diff --git a/settings.gradle b/settings.gradle index 7809c35c6..2475b0845 100755 --- a/settings.gradle +++ b/settings.gradle @@ -44,7 +44,6 @@ rootProject.name = 'baritone' include("tweaker") if (System.getProperty("Baritone.enabled_platforms") == null) { System.setProperty("Baritone.enabled_platforms", "fabric,forge") -// System.setProperty("Baritone.enabled_platforms", "fabric") } for (platform in System.getProperty("Baritone.enabled_platforms").split(",")) { include(platform) diff --git a/src/api/java/baritone/api/command/datatypes/BlockById.java b/src/api/java/baritone/api/command/datatypes/BlockById.java index 21562e188..5e63fcf25 100644 --- a/src/api/java/baritone/api/command/datatypes/BlockById.java +++ b/src/api/java/baritone/api/command/datatypes/BlockById.java @@ -19,12 +19,11 @@ package baritone.api.command.datatypes; import baritone.api.command.exception.CommandException; import baritone.api.command.helpers.TabCompleteHelper; -import net.minecraft.core.registries.BuiltInRegistries; +import java.util.stream.Stream; +import net.minecraft.core.Registry; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.block.Block; -import java.util.stream.Stream; - public enum BlockById implements IDatatypeFor { INSTANCE; @@ -32,7 +31,7 @@ public enum BlockById implements IDatatypeFor { public Block get(IDatatypeContext ctx) throws CommandException { ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString()); Block block; - if ((block = BuiltInRegistries.BLOCK.getOptional(id).orElse(null)) == null) { + if ((block = Registry.BLOCK.getOptional(id).orElse(null)) == null) { throw new IllegalArgumentException("no block found by that id"); } return block; @@ -42,7 +41,7 @@ public enum BlockById implements IDatatypeFor { public Stream tabComplete(IDatatypeContext ctx) throws CommandException { return new TabCompleteHelper() .append( - BuiltInRegistries.BLOCK.keySet() + Registry.BLOCK.keySet() .stream() .map(Object::toString) ) diff --git a/src/api/java/baritone/api/command/datatypes/EntityClassById.java b/src/api/java/baritone/api/command/datatypes/EntityClassById.java index d7cb75734..aff7a2d94 100644 --- a/src/api/java/baritone/api/command/datatypes/EntityClassById.java +++ b/src/api/java/baritone/api/command/datatypes/EntityClassById.java @@ -19,12 +19,11 @@ package baritone.api.command.datatypes; import baritone.api.command.exception.CommandException; import baritone.api.command.helpers.TabCompleteHelper; -import net.minecraft.core.registries.BuiltInRegistries; +import java.util.stream.Stream; +import net.minecraft.core.Registry; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.EntityType; -import java.util.stream.Stream; - public enum EntityClassById implements IDatatypeFor { INSTANCE; @@ -32,7 +31,7 @@ public enum EntityClassById implements IDatatypeFor { public EntityType get(IDatatypeContext ctx) throws CommandException { ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString()); EntityType entity; - if ((entity = BuiltInRegistries.ENTITY_TYPE.getOptional(id).orElse(null)) == null) { + if ((entity = Registry.ENTITY_TYPE.getOptional(id).orElse(null)) == null) { throw new IllegalArgumentException("no entity found by that id"); } return entity; @@ -41,7 +40,7 @@ public enum EntityClassById implements IDatatypeFor { @Override public Stream tabComplete(IDatatypeContext ctx) throws CommandException { return new TabCompleteHelper() - .append(BuiltInRegistries.ENTITY_TYPE.stream().map(Object::toString)) + .append(Registry.ENTITY_TYPE.stream().map(Object::toString)) .filterPrefixNamespaced(ctx.getConsumer().getString()) .sortAlphabetically() .stream(); diff --git a/src/api/java/baritone/api/event/events/RenderEvent.java b/src/api/java/baritone/api/event/events/RenderEvent.java index a12a4dd5c..cb7a0414c 100644 --- a/src/api/java/baritone/api/event/events/RenderEvent.java +++ b/src/api/java/baritone/api/event/events/RenderEvent.java @@ -18,7 +18,7 @@ package baritone.api.event.events; import com.mojang.blaze3d.vertex.PoseStack; -import org.joml.Matrix4f; +import com.mojang.math.Matrix4f; /** * @author Brady diff --git a/src/api/java/baritone/api/utils/BlockOptionalMeta.java b/src/api/java/baritone/api/utils/BlockOptionalMeta.java index 2ba6f3ed1..aaeed981f 100644 --- a/src/api/java/baritone/api/utils/BlockOptionalMeta.java +++ b/src/api/java/baritone/api/utils/BlockOptionalMeta.java @@ -19,22 +19,18 @@ package baritone.api.utils; import baritone.api.utils.accessor.IItemStack; import com.google.common.collect.ImmutableSet; -import com.google.common.util.concurrent.ThreadFactoryBuilder; import io.netty.util.concurrent.ThreadPerTaskExecutor; -import net.minecraft.SharedConstants; import net.minecraft.core.BlockPos; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.*; import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.packs.*; -import net.minecraft.server.packs.metadata.pack.PackMetadataSection; +import net.minecraft.server.packs.PackResources; +import net.minecraft.server.packs.PackType; +import net.minecraft.server.packs.repository.Pack; import net.minecraft.server.packs.repository.PackRepository; import net.minecraft.server.packs.repository.ServerPacksSource; -import net.minecraft.server.packs.resources.MultiPackResourceManager; import net.minecraft.server.packs.resources.ReloadableResourceManager; import net.minecraft.util.RandomSource; import net.minecraft.util.Unit; -import net.minecraft.world.flag.FeatureFlags; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.Block; @@ -46,8 +42,6 @@ import net.minecraft.world.level.storage.loot.PredicateManager; import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; import net.minecraft.world.level.storage.loot.parameters.LootContextParams; import net.minecraft.world.phys.Vec3; -import org.apache.logging.log4j.core.jmx.Server; - import javax.annotation.Nonnull; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -169,16 +163,17 @@ public final class BlockOptionalMeta { public static LootTables getManager() { if (manager == null) { - MultiPackResourceManager resources = new MultiPackResourceManager(PackType.SERVER_DATA, List.of(getVanillaServerPack())); + PackRepository rpl = new PackRepository(PackType.SERVER_DATA, new ServerPacksSource()); + rpl.reload(); + PackResources thePack = rpl.getAvailablePacks().iterator().next().open(); ReloadableResourceManager resourceManager = new ReloadableResourceManager(PackType.SERVER_DATA); manager = new LootTables(predicate); resourceManager.registerReloadListener(manager); try { - resourceManager.createReload(new ThreadPerTaskExecutor(Thread::new), new ThreadPerTaskExecutor(Thread::new), CompletableFuture.completedFuture(Unit.INSTANCE), resources.listPacks().toList()).done().get(); + resourceManager.createReload(new ThreadPerTaskExecutor(Thread::new), new ThreadPerTaskExecutor(Thread::new), CompletableFuture.completedFuture(Unit.INSTANCE), Collections.singletonList(thePack)).done().get(); } catch (Exception exception) { throw new RuntimeException(exception); } - } return manager; } @@ -197,7 +192,7 @@ public final class BlockOptionalMeta { // the other overload for generate doesnt work in forge because forge adds code that requires a non null world getManager().get(lootTableLocation).getRandomItems( - new LootContext.Builder((ServerLevel null) + new LootContext.Builder((ServerLevel) null) .withRandom(RandomSource.create()) .withParameter(LootContextParams.ORIGIN, Vec3.atLowerCornerOf(BlockPos.ZERO)) .withParameter(LootContextParams.TOOL, ItemStack.EMPTY) diff --git a/src/api/java/baritone/api/utils/BlockUtils.java b/src/api/java/baritone/api/utils/BlockUtils.java index a43d78e87..cc4204f8e 100644 --- a/src/api/java/baritone/api/utils/BlockUtils.java +++ b/src/api/java/baritone/api/utils/BlockUtils.java @@ -20,7 +20,6 @@ package baritone.api.utils; import java.util.HashMap; import java.util.Map; import net.minecraft.core.Registry; -import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.block.Block; @@ -29,7 +28,7 @@ public class BlockUtils { private static transient Map resourceCache = new HashMap<>(); public static String blockToString(Block block) { - ResourceLocation loc = BuiltInRegistries.BLOCK.getKey(block); + ResourceLocation loc = Registry.BLOCK.getKey(block); String name = loc.getPath(); // normally, only write the part after the minecraft: if (!loc.getNamespace().equals("minecraft")) { // Baritone is running on top of forge with mods installed, perhaps? @@ -57,7 +56,7 @@ public class BlockUtils { if (resourceCache.containsKey(name)) { return null; // cached as null } - block = BuiltInRegistries.BLOCK.getOptional(ResourceLocation.tryParse(name.contains(":") ? name : "minecraft:" + name)).orElse(null); + block = Registry.BLOCK.getOptional(ResourceLocation.tryParse(name.contains(":") ? name : "minecraft:" + name)).orElse(null); Map copy = new HashMap<>(resourceCache); // read only copy is safe, wont throw concurrentmodification copy.put(name, block); resourceCache = copy; diff --git a/src/api/java/baritone/api/utils/SettingsUtil.java b/src/api/java/baritone/api/utils/SettingsUtil.java index 9e82c05de..5b9358a21 100644 --- a/src/api/java/baritone/api/utils/SettingsUtil.java +++ b/src/api/java/baritone/api/utils/SettingsUtil.java @@ -23,7 +23,6 @@ import net.minecraft.client.Minecraft; import net.minecraft.core.Direction; import net.minecraft.core.Registry; import net.minecraft.core.Vec3i; -import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.Item; import net.minecraft.world.level.block.Block; @@ -253,8 +252,8 @@ public class SettingsUtil { ), ITEM( Item.class, - str -> BuiltInRegistries.ITEM.get(new ResourceLocation(str.trim())), // TODO this now returns AIR on failure instead of null, is that an issue? - item -> BuiltInRegistries.ITEM.getKey(item).toString() + str -> Registry.ITEM.get(new ResourceLocation(str.trim())), // TODO this now returns AIR on failure instead of null, is that an issue? + item -> Registry.ITEM.getKey(item).toString() ), LIST() { @Override diff --git a/src/launch/java/baritone/launch/mixins/MixinClientPlayNetHandler.java b/src/launch/java/baritone/launch/mixins/MixinClientPlayNetHandler.java index e718685c9..df3fbf09f 100644 --- a/src/launch/java/baritone/launch/mixins/MixinClientPlayNetHandler.java +++ b/src/launch/java/baritone/launch/mixins/MixinClientPlayNetHandler.java @@ -20,19 +20,14 @@ package baritone.launch.mixins; import baritone.Baritone; import baritone.api.BaritoneAPI; import baritone.api.IBaritone; -import baritone.api.event.events.ChatEvent; import baritone.api.event.events.ChunkEvent; import baritone.api.event.events.type.EventState; import baritone.cache.CachedChunk; -import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientPacketListener; import net.minecraft.client.player.LocalPlayer; -import net.minecraft.network.chat.Component; import net.minecraft.network.protocol.game.*; import net.minecraft.world.level.ChunkPos; -import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -68,25 +63,6 @@ public class MixinClientPlayNetHandler { } }*/ - @Shadow @Final private Minecraft minecraft; - - @Inject( - method = "sendChat(Ljava/lang/String;)V", - at = @At("HEAD"), - cancellable = true - ) - private void sendChatMessage(String string, CallbackInfo ci) { - ChatEvent event = new ChatEvent(string); - IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(this.minecraft.player); - if (baritone == null) { - return; - } - baritone.getGameEventHandler().onSendChatMessage(event); - if (event.isCancelled()) { - ci.cancel(); - } - } - @Inject( method = "handleLevelChunkWithLight", at = @At("RETURN") diff --git a/src/launch/java/baritone/launch/mixins/MixinClientPlayerEntity.java b/src/launch/java/baritone/launch/mixins/MixinClientPlayerEntity.java index 22ca083e0..e5f3e0375 100644 --- a/src/launch/java/baritone/launch/mixins/MixinClientPlayerEntity.java +++ b/src/launch/java/baritone/launch/mixins/MixinClientPlayerEntity.java @@ -41,6 +41,23 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(LocalPlayer.class) public class MixinClientPlayerEntity { + @Inject( + method = "sendChat(Ljava/lang/String;Lnet/minecraft/network/chat/Component;)V", + at = @At("HEAD"), + cancellable = true + ) + private void sendChatMessage(String string, Component component, CallbackInfo ci) { + ChatEvent event = new ChatEvent(string); + IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((LocalPlayer) (Object) this); + if (baritone == null) { + return; + } + baritone.getGameEventHandler().onSendChatMessage(event); + if (event.isCancelled()) { + ci.cancel(); + } + } + @Inject( method = "tick", at = @At( diff --git a/src/launch/java/baritone/launch/mixins/MixinWorldRenderer.java b/src/launch/java/baritone/launch/mixins/MixinWorldRenderer.java index a6cf48899..622721281 100644 --- a/src/launch/java/baritone/launch/mixins/MixinWorldRenderer.java +++ b/src/launch/java/baritone/launch/mixins/MixinWorldRenderer.java @@ -21,11 +21,11 @@ import baritone.api.BaritoneAPI; import baritone.api.IBaritone; import baritone.api.event.events.RenderEvent; import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Matrix4f; import net.minecraft.client.Camera; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.LightTexture; -import org.joml.Matrix4f; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/src/main/java/baritone/command/defaults/FindCommand.java b/src/main/java/baritone/command/defaults/FindCommand.java index 500981873..913156400 100644 --- a/src/main/java/baritone/command/defaults/FindCommand.java +++ b/src/main/java/baritone/command/defaults/FindCommand.java @@ -27,7 +27,6 @@ import baritone.api.utils.BetterBlockPos; import baritone.cache.CachedChunk; import net.minecraft.core.Registry; import net.minecraft.ChatFormatting; -import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.chat.ClickEvent; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.HoverEvent; @@ -58,7 +57,7 @@ public class FindCommand extends Command { Component[] components = toFind.stream() .flatMap(block -> ctx.worldData().getCachedWorld().getLocationsOf( - BuiltInRegistries.BLOCK.getKey(block).getPath(), + Registry.BLOCK.getKey(block).getPath(), Integer.MAX_VALUE, origin.x, origin.y, @@ -92,9 +91,9 @@ public class FindCommand extends Command { public Stream tabComplete(String label, IArgConsumer args) throws CommandException { return new TabCompleteHelper() .append( - CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.stream() - .map(BuiltInRegistries.BLOCK::getKey) - .map(Object::toString) + CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.stream() + .map(Registry.BLOCK::getKey) + .map(Object::toString) ) .filterPrefixNamespaced(args.getString()) .sortAlphabetically() diff --git a/src/main/java/baritone/command/defaults/FollowCommand.java b/src/main/java/baritone/command/defaults/FollowCommand.java index b7e708377..46c6a1c60 100644 --- a/src/main/java/baritone/command/defaults/FollowCommand.java +++ b/src/main/java/baritone/command/defaults/FollowCommand.java @@ -31,7 +31,6 @@ import java.util.*; import java.util.function.Predicate; import java.util.stream.Stream; import net.minecraft.core.Registry; -import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; @@ -85,7 +84,7 @@ public class FollowCommand extends Command { } else { logDirect("Following these types of entities:"); classes.stream() - .map(BuiltInRegistries.ENTITY_TYPE::getKey) + .map(Registry.ENTITY_TYPE::getKey) .map(Objects::requireNonNull) .map(ResourceLocation::toString) .forEach(this::logDirect); diff --git a/src/main/java/baritone/pathing/movement/MovementHelper.java b/src/main/java/baritone/pathing/movement/MovementHelper.java index b636ef9c2..128fa5e16 100644 --- a/src/main/java/baritone/pathing/movement/MovementHelper.java +++ b/src/main/java/baritone/pathing/movement/MovementHelper.java @@ -724,7 +724,7 @@ public interface MovementHelper extends ActionCosts, Helper { static boolean isBlockNormalCube(BlockState state) { Block block = state.getBlock(); - if (block instanceof BambooStalkBlock + if (block instanceof BambooBlock || block instanceof MovingPistonBlock || block instanceof ScaffoldingBlock || block instanceof ShulkerBoxBlock diff --git a/src/main/java/baritone/utils/GuiClick.java b/src/main/java/baritone/utils/GuiClick.java index 876d5fb42..d0a435e1f 100644 --- a/src/main/java/baritone/utils/GuiClick.java +++ b/src/main/java/baritone/utils/GuiClick.java @@ -24,6 +24,8 @@ import baritone.api.utils.BetterBlockPos; import baritone.api.utils.Helper; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Matrix4f; +import com.mojang.math.Vector4f; import net.minecraft.ChatFormatting; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.player.LocalPlayer; @@ -37,8 +39,6 @@ import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; -import org.joml.Matrix4f; -import org.joml.Vector4f; import java.awt.*; import java.util.Collections; @@ -118,8 +118,8 @@ public class GuiClick extends Screen implements Helper { } public void onRender(PoseStack modelViewStack, Matrix4f projectionMatrix) { - this.projectionViewMatrix = new Matrix4f(projectionMatrix); - this.projectionViewMatrix.mul(modelViewStack.last().pose()); + this.projectionViewMatrix = projectionMatrix.copy(); + this.projectionViewMatrix.multiply(modelViewStack.last().pose()); this.projectionViewMatrix.invert(); if (currentMouseOver != null) { @@ -158,9 +158,12 @@ public class GuiClick extends Screen implements Helper { y = y * 2 - 1; Vector4f pos = new Vector4f((float) x, (float) y, (float) z, 1.0F); - projectionViewMatrix.transformProject(pos); + pos.transform(this.projectionViewMatrix); + if (pos.w() == 0) { + return null; + } - pos.normalize(); + pos.perspectiveDivide(); return new Vec3(pos.x(), pos.y(), pos.z()); } } diff --git a/src/main/java/baritone/utils/IRenderer.java b/src/main/java/baritone/utils/IRenderer.java index 380fbd9e0..d07bf44fa 100644 --- a/src/main/java/baritone/utils/IRenderer.java +++ b/src/main/java/baritone/utils/IRenderer.java @@ -23,9 +23,9 @@ import baritone.api.utils.Helper; import baritone.utils.accessor.IEntityRenderManager; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.*; +import com.mojang.math.Matrix4f; import java.awt.*; import net.minecraft.world.phys.AABB; -import org.joml.Matrix4f; import static org.lwjgl.opengl.GL11.*; diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index f18db52b2..5f50962e7 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -30,6 +30,7 @@ import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexFormat; +import com.mojang.math.Matrix4f; import java.awt.*; import java.util.Collection; import java.util.Collections; @@ -44,7 +45,6 @@ import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; -import org.joml.Matrix4f; import static org.lwjgl.opengl.GL11.*; diff --git a/src/main/java/baritone/utils/schematic/format/defaults/LitematicaSchematic.java b/src/main/java/baritone/utils/schematic/format/defaults/LitematicaSchematic.java index 65cdec058..9fd672d62 100644 --- a/src/main/java/baritone/utils/schematic/format/defaults/LitematicaSchematic.java +++ b/src/main/java/baritone/utils/schematic/format/defaults/LitematicaSchematic.java @@ -20,7 +20,6 @@ package baritone.utils.schematic.format.defaults; import baritone.utils.schematic.StaticSchematic; import net.minecraft.core.Registry; import net.minecraft.core.Vec3i; -import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.resources.ResourceLocation; @@ -94,7 +93,7 @@ public final class LitematicaSchematic extends StaticSchematic { BlockState[] blockList = new BlockState[blockStatePalette.size()]; for (int i = 0; i < blockStatePalette.size(); i++) { - Block block = BuiltInRegistries.BLOCK.get(new ResourceLocation((((CompoundTag) blockStatePalette.get(i)).getString("Name")))); + Block block = Registry.BLOCK.get(new ResourceLocation((((CompoundTag) blockStatePalette.get(i)).getString("Name")))); CompoundTag properties = ((CompoundTag) blockStatePalette.get(i)).getCompound("Properties"); blockList[i] = getBlockState(block, properties); diff --git a/src/main/java/baritone/utils/schematic/format/defaults/MCEditSchematic.java b/src/main/java/baritone/utils/schematic/format/defaults/MCEditSchematic.java index 3018021a5..4693ea387 100644 --- a/src/main/java/baritone/utils/schematic/format/defaults/MCEditSchematic.java +++ b/src/main/java/baritone/utils/schematic/format/defaults/MCEditSchematic.java @@ -19,7 +19,6 @@ package baritone.utils.schematic.format.defaults; import baritone.utils.schematic.StaticSchematic; import net.minecraft.core.Registry; -import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.datafix.fixes.ItemIdFix; @@ -63,7 +62,7 @@ public final class MCEditSchematic extends StaticSchematic { // additional is 0 through 15 inclusive since it's & 0xF above blockID |= additional[blockInd] << 8; } - Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.tryParse(ItemIdFix.getItem(blockID))); + Block block = Registry.BLOCK.get(ResourceLocation.tryParse(ItemIdFix.getItem(blockID))); // int meta = metadata[blockInd] & 0xFF; // this.states[x][z][y] = block.getStateFromMeta(meta); this.states[x][z][y] = block.defaultBlockState(); diff --git a/src/main/java/baritone/utils/schematic/format/defaults/SpongeSchematic.java b/src/main/java/baritone/utils/schematic/format/defaults/SpongeSchematic.java index 12163cbff..3c00b08c6 100644 --- a/src/main/java/baritone/utils/schematic/format/defaults/SpongeSchematic.java +++ b/src/main/java/baritone/utils/schematic/format/defaults/SpongeSchematic.java @@ -26,7 +26,6 @@ import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; import net.minecraft.core.Registry; -import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.block.Block; @@ -107,7 +106,7 @@ public final class SpongeSchematic extends StaticSchematic { private BlockState deserialize() { if (this.blockState == null) { - Block block = BuiltInRegistries.BLOCK.get(this.resourceLocation); + Block block = Registry.BLOCK.get(this.resourceLocation); this.blockState = block.defaultBlockState(); this.properties.keySet().stream().sorted(String::compareTo).forEachOrdered(key -> { diff --git a/tweaker/build.gradle b/tweaker/build.gradle index 1b6304189..ce623af6c 100644 --- a/tweaker/build.gradle +++ b/tweaker/build.gradle @@ -17,7 +17,7 @@ import baritone.gradle.task.CreateDistTask import baritone.gradle.task.ProguardTask -import baritone.gradle.task.TweakerJsonAssembler +//import baritone.gradle.task.TweakerJsonAssembler plugins { id "com.github.johnrengelman.shadow" version "7.0.0" From acce20c573a78688c2b1092e412fbc933dddff5b Mon Sep 17 00:00:00 2001 From: Wagyourtail Date: Sun, 2 Apr 2023 17:01:49 -0700 Subject: [PATCH 036/405] remove 1.19.3 method in blockOptionalMeta --- build.gradle | 3 +-- buildSrc/build.gradle | 2 +- .../baritone/gradle/task/ProguardTask.java | 2 +- .../baritone/api/utils/BlockOptionalMeta.java | 20 ------------------- 4 files changed, 3 insertions(+), 24 deletions(-) diff --git a/build.gradle b/build.gradle index 471bb608f..b139b8438 100755 --- a/build.gradle +++ b/build.gradle @@ -126,8 +126,7 @@ jar { } remapJar { - targetNamespace = "named" - fallbackTargetNamespace = "intermediary" + target = "mojmap" } javadoc { diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 14b7dc3bb..e6c1468a7 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -36,5 +36,5 @@ dependencies { implementation group: 'com.google.code.gson', name: 'gson', version: '2.9.0' implementation group: 'commons-io', name: 'commons-io', version: '2.6' - implementation group: 'xyz.wagyourtail.unimined', name: 'xyz.wagyourtail.unimined.gradle.plugin', version: '0.3.4' + implementation group: 'xyz.wagyourtail.unimined', name: 'xyz.wagyourtail.unimined.gradle.plugin', version: '0.4.9' } \ No newline at end of file diff --git a/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java b/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java index 5d80a65ea..52d1d93dc 100644 --- a/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java +++ b/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java @@ -81,7 +81,7 @@ public class ProguardTask extends BaritoneGradleTask { MinecraftProvider provider = this.getProject().getExtensions().getByType(MinecraftProvider.class); private File getMcJar() { - return provider.getMinecraftWithMapping(EnvType.COMBINED, provider.getMcPatcher().getProdNamespace(), provider.getMcPatcher().getProdFallbackNamespace()).toFile(); + return provider.getMinecraftWithMapping(EnvType.COMBINED, provider.getMcPatcher().getProdNamespace(), provider.getMcPatcher().getProdNamespace()).toFile(); } private boolean isMcJar(File f) { diff --git a/src/api/java/baritone/api/utils/BlockOptionalMeta.java b/src/api/java/baritone/api/utils/BlockOptionalMeta.java index aaeed981f..13fe102ac 100644 --- a/src/api/java/baritone/api/utils/BlockOptionalMeta.java +++ b/src/api/java/baritone/api/utils/BlockOptionalMeta.java @@ -25,7 +25,6 @@ import net.minecraft.resources.*; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.packs.PackResources; import net.minecraft.server.packs.PackType; -import net.minecraft.server.packs.repository.Pack; import net.minecraft.server.packs.repository.PackRepository; import net.minecraft.server.packs.repository.ServerPacksSource; import net.minecraft.server.packs.resources.ReloadableResourceManager; @@ -43,8 +42,6 @@ import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; import net.minecraft.world.level.storage.loot.parameters.LootContextParams; import net.minecraft.world.phys.Vec3; import javax.annotation.Nonnull; -import java.lang.reflect.Field; -import java.lang.reflect.Method; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.regex.MatchResult; @@ -144,23 +141,6 @@ public final class BlockOptionalMeta { return null; } - private static Method getVanillaServerPack; - - private static VanillaPackResources getVanillaServerPack() { - if (getVanillaServerPack == null) { - getVanillaServerPack = Arrays.stream(ServerPacksSource.class.getDeclaredMethods()).filter(field -> field.getReturnType() == VanillaPackResources.class).findFirst().orElseThrow(); - getVanillaServerPack.setAccessible(true); - } - - try { - return (VanillaPackResources) getVanillaServerPack.invoke(null); - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - public static LootTables getManager() { if (manager == null) { PackRepository rpl = new PackRepository(PackType.SERVER_DATA, new ServerPacksSource()); From f334b3b76572d6aa2bfdf643c0c957103441b201 Mon Sep 17 00:00:00 2001 From: Wagyourtail Date: Mon, 10 Apr 2023 18:40:48 -0700 Subject: [PATCH 037/405] update setup.md --- SETUP.md | 67 +++++--------------------------------------------------- 1 file changed, 6 insertions(+), 61 deletions(-) diff --git a/SETUP.md b/SETUP.md index 57866b192..1daeb9f89 100644 --- a/SETUP.md +++ b/SETUP.md @@ -43,13 +43,13 @@ If another one of your Forge mods has a Baritone integration, you want `baritone ## Command Line On Mac OSX and Linux, use `./gradlew` instead of `gradlew`. -If you have errors with a package missing please make sure you have setup your environment, and are using Oracle JDK 8 for 1.12.2-1.16.5, JDK 16 for 1.17.1, and JDK 17 for 1.18.1. +If you have errors with a package missing please make sure you have setup your environment, and are using Oracle JDK 8 for 1.12.2-1.16.5, JDK 16+ for 1.17.1, and JDK 17+ for 1.18.1. To check which java you are using do `java -version` in a command prompt or terminal. If you are using anything above OpenJDK 8 for 1.12.2-1.16.5, it might not work because the Java distributions above JDK 8 using may not have the needed javax classes. -Open JDK download: https://openjdk.java.net/install/ +Download java: https://adoptium.net/ #### macOS guide In order to get JDK 8, Try running the following command: `% /usr/libexec/java_home -V` @@ -66,68 +66,13 @@ In order to get JDK 8 running in the **current terminal window** you will have t To add OpenJDK 8 to your PATH add the export line to the end of your `.zshrc / .bashrc` if you want it to apply to each new terminal. If you're using bash change the .bachrc and if you're using zsh change the .zshrc -Setting up the Environment: +### Building Baritone -``` -$ gradlew setupDecompWorkspace -$ gradlew --refresh-dependencies -``` +These tasks depend on the minecraft version, but are (for the most part) standard for building mods. -Building Baritone: - -``` -$ gradlew build -``` - -For minecraft 1.15.2+, run the following instead to include the Forge jars: - -``` -$ gradlew build -Pbaritone.forge_build -``` - -Do this instead for Fabric jars: - -``` -$ gradlew build -Pbaritone.fabric_build -``` - -Running Baritone: - -``` -$ gradlew runClient -``` - -For information on how to build baritone, see [Building Baritone](#building-baritone) +for more details, see [the build ci action](/.github/workflows/gradle_build.yml) ## IntelliJ - Open the project in IntelliJ as a Gradle project - - ![Image](https://i.imgur.com/jw7Q6vY.png) - -- Run the Gradle tasks `setupDecompWorkspace` then `genIntellijRuns` - - ![Image](https://i.imgur.com/QEfVvWP.png) - - Refresh the Gradle project (or, to be safe, just restart IntelliJ) - - ![Image](https://i.imgur.com/3V7EdWr.png) - -- Select the "Minecraft Client" launch config - - ![Image](https://i.imgur.com/1qz2QGV.png) - -- Click on ``Edit Configurations...`` from the same dropdown and select the "Minecraft Client" config - - ![Image](https://i.imgur.com/s4ly0ZF.png) - -- In `Edit Configurations...` you need to select `baritone_launch` for `Use classpath of module:`. - - ![Image](https://i.imgur.com/hrLhG9u.png) - -## IntelliJ - -- Navigate to the gradle tasks on the right tab as follows - - ![Image](https://i.imgur.com/PE6r9iN.png) - -- Double click on **build** to run it +- depending on the minecraft version, you may need to run `setupDecompWorkspace` or `genIntellijRuns` in order to get everything working \ No newline at end of file From 35ab687d5e7ba76128571a24f985c90e7849a6ab Mon Sep 17 00:00:00 2001 From: leijurv Date: Tue, 11 Apr 2023 16:00:22 -0700 Subject: [PATCH 038/405] 1.9.3 download links --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7a35e1199..f54584118 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ Baritone is the pathfinding system used in [Impact](https://impactclient.net/) s | [1.17.1 Forge](https://github.com/cabaletta/baritone/releases/download/v1.7.3/baritone-api-forge-1.7.3.jar) | [1.17.1 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.7.3/baritone-api-fabric-1.7.3.jar) | | [1.18.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.8.4/baritone-api-forge-1.8.4.jar) | [1.18.2 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.8.4/baritone-api-fabric-1.8.4.jar) | | [1.19.3 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-forge-1.9.1.jar) | [1.19.3 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-fabric-1.9.1.jar) | -| | [1.19.4 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.2/baritone-api-fabric-1.9.2.jar) | +| [1.19.4 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-forge-1.9.3.jar) | [1.19.4 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-fabric-1.9.3.jar) | **How to immediately get started:** Type `#goto 1000 500` in chat to go to x=1000 z=500. Type `#mine diamond_ore` to mine diamond ore. Type `#stop` to stop. For more, read [the usage page](USAGE.md) and/or watch this [tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa) From 6eeeeb3a1b3b921f5619a178aab0500497cfc292 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 11 Apr 2023 19:50:51 -0700 Subject: [PATCH 039/405] v1.9.4 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 4c3f5b494..04999bf13 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ org.gradle.jvmargs=-Xmx4G -mod_version=1.9.1 +mod_version=1.9.4 maven_group=baritone archives_base_name=baritone From 5f2eadbfa663909ceb41073c021f2934c56ceb56 Mon Sep 17 00:00:00 2001 From: leijurv Date: Tue, 11 Apr 2023 20:36:29 -0700 Subject: [PATCH 040/405] download links for 1.19.2 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f54584118..8ae8090d7 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,7 @@ Baritone is the pathfinding system used in [Impact](https://impactclient.net/) s | [1.16.5 Forge](https://github.com/cabaletta/baritone/releases/download/v1.6.4/baritone-api-forge-1.6.4.jar) | [1.16.5 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.6.4/baritone-api-fabric-1.6.4.jar) | | [1.17.1 Forge](https://github.com/cabaletta/baritone/releases/download/v1.7.3/baritone-api-forge-1.7.3.jar) | [1.17.1 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.7.3/baritone-api-fabric-1.7.3.jar) | | [1.18.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.8.4/baritone-api-forge-1.8.4.jar) | [1.18.2 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.8.4/baritone-api-fabric-1.8.4.jar) | +| [1.19.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.4/baritone-api-forge-1.9.4.jar) | [1.19.2 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.4/baritone-api-fabric-1.9.4.jar) | | [1.19.3 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-forge-1.9.1.jar) | [1.19.3 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-fabric-1.9.1.jar) | | [1.19.4 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-forge-1.9.3.jar) | [1.19.4 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-fabric-1.9.3.jar) | From e8a4a9fdac983a5270595a6e89dc9cad480cd988 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Mon, 24 Apr 2023 16:23:38 +0200 Subject: [PATCH 041/405] Make cocoa farmable --- .../java/baritone/process/FarmProcess.java | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/src/main/java/baritone/process/FarmProcess.java b/src/main/java/baritone/process/FarmProcess.java index 73c575d22..a9188299c 100644 --- a/src/main/java/baritone/process/FarmProcess.java +++ b/src/main/java/baritone/process/FarmProcess.java @@ -21,6 +21,7 @@ import baritone.Baritone; import baritone.api.BaritoneAPI; import baritone.api.pathing.goals.Goal; import baritone.api.pathing.goals.GoalBlock; +import baritone.api.pathing.goals.GoalGetToBlock; import baritone.api.pathing.goals.GoalComposite; import baritone.api.process.IFarmProcess; import baritone.api.process.PathingCommand; @@ -119,6 +120,7 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro PUMPKIN(Blocks.PUMPKIN, state -> true), MELON(Blocks.MELON_BLOCK, state -> true), NETHERWART(Blocks.NETHER_WART, state -> state.getValue(BlockNetherWart.AGE) >= 3), + COCOA(Blocks.COCOA, state -> state.getValue(BlockCocoa.AGE) >= 2), SUGARCANE(Blocks.REEDS, null) { @Override public boolean readyToHarvest(World world, BlockPos pos, IBlockState state) { @@ -176,6 +178,10 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro return !stack.isEmpty() && stack.getItem().equals(Items.NETHER_WART); } + private boolean isCocoa(ItemStack stack) { + return !stack.isEmpty() && stack.getItem() instanceof ItemDye && EnumDyeColor.byDyeDamage(stack.getMetadata()) == EnumDyeColor.BROWN; + } + @Override public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { ArrayList scan = new ArrayList<>(); @@ -184,6 +190,7 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro } if (Baritone.settings().replantCrops.value) { scan.add(Blocks.FARMLAND); + scan.add(Blocks.LOG); if (Baritone.settings().replantNetherWart.value) { scan.add(Blocks.SOUL_SAND); } @@ -199,6 +206,7 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro List openFarmland = new ArrayList<>(); List bonemealable = new ArrayList<>(); List openSoulsand = new ArrayList<>(); + List openLog = new ArrayList<>(); for (BlockPos pos : locations) { //check if the target block is out of range. if (range != 0 && pos.getDistance(center.getX(), center.getY(), center.getZ()) > range) { @@ -219,6 +227,19 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro } continue; } + if (state.getBlock() == Blocks.LOG) { + // yes, both log blocks and the planks block define separate properties but share the enum + if (state.getValue(BlockOldLog.VARIANT) != BlockPlanks.EnumType.JUNGLE) { + continue; + } + for (EnumFacing direction : EnumFacing.Plane.HORIZONTAL) { + if (ctx.world().getBlockState(pos.offset(direction)).getBlock() instanceof BlockAir) { + openLog.add(pos); + break; + } + } + continue; + } if (readyForHarvest(ctx.world(), pos, state)) { toBreak.add(pos); continue; @@ -259,6 +280,25 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro } } } + for (BlockPos pos : openLog) { + for (EnumFacing dir : EnumFacing.Plane.HORIZONTAL) { + if (!(ctx.world().getBlockState(pos.offset(dir)).getBlock() instanceof BlockAir)) { + continue; + } + Vec3d faceCenter = new Vec3d(pos).add(0.5, 0.5, 0.5).add(new Vec3d(dir.getDirectionVec()).scale(0.5)); + Optional rot = RotationUtils.reachableOffset(ctx.player(), pos, faceCenter, ctx.playerController().getBlockReachDistance(), false); + if (rot.isPresent() && isSafeToCancel && baritone.getInventoryBehavior().throwaway(true, this::isCocoa)) { + RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot.get(), ctx.playerController().getBlockReachDistance()); + if (result.typeOfHit == RayTraceResult.Type.BLOCK && result.sideHit == dir) { + baritone.getLookBehavior().updateTarget(rot.get(), true); + if (ctx.isLookingAt(pos)) { + baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true); + } + return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); + } + } + } + } for (BlockPos pos : bonemealable) { Optional rot = RotationUtils.reachable(ctx, pos); if (rot.isPresent() && isSafeToCancel && baritone.getInventoryBehavior().throwaway(true, this::isBoneMeal)) { @@ -293,6 +333,15 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro goalz.add(new GoalBlock(pos.up())); } } + if (baritone.getInventoryBehavior().throwaway(false, this::isCocoa)) { + for (BlockPos pos : openLog) { + for (EnumFacing direction : EnumFacing.Plane.HORIZONTAL) { + if (ctx.world().getBlockState(pos.offset(direction)).getBlock() instanceof BlockAir) { + goalz.add(new GoalGetToBlock(pos.offset(direction))); + } + } + } + } if (baritone.getInventoryBehavior().throwaway(false, this::isBoneMeal)) { for (BlockPos pos : bonemealable) { goalz.add(new GoalBlock(pos)); @@ -301,7 +350,7 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro for (Entity entity : ctx.world().loadedEntityList) { if (entity instanceof EntityItem && entity.onGround) { EntityItem ei = (EntityItem) entity; - if (PICKUP_DROPPED.contains(ei.getItem().getItem())) { + if (PICKUP_DROPPED.contains(ei.getItem().getItem()) || isCocoa(ei.getItem())) { // +0.1 because of farmland's 0.9375 dummy height lol goalz.add(new GoalBlock(new BlockPos(entity.posX, entity.posY + 0.1, entity.posZ))); } From e4cd35ac3391ca6b0e9993e4cd0dd1d34ffc9a12 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Mon, 24 Apr 2023 13:15:06 +0200 Subject: [PATCH 042/405] =?UTF-8?q?=E2=9C=A8=20Add=20maxYLevelWhileMining?= =?UTF-8?q?=20setting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/java/baritone/api/Settings.java | 5 +++++ src/main/java/baritone/process/MineProcess.java | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 38661d8be..c13cde2f7 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -853,6 +853,11 @@ public final class Settings { */ public final Setting minYLevelWhileMining = new Setting<>(0); + /** + * Sets the maximum y level to mine ores at. + */ + public final Setting maxYLevelWhileMining = new Setting<>(255); // 1.17+ defaults to maximum possible world height + /** * This will only allow baritone to mine exposed ores, can be used to stop ore obfuscators on servers that use them. */ diff --git a/src/main/java/baritone/process/MineProcess.java b/src/main/java/baritone/process/MineProcess.java index 9af09a819..6880dd86c 100644 --- a/src/main/java/baritone/process/MineProcess.java +++ b/src/main/java/baritone/process/MineProcess.java @@ -437,6 +437,8 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro .filter(pos -> pos.getY() >= Baritone.settings().minYLevelWhileMining.value) + .filter(pos -> pos.getY() <= Baritone.settings().maxYLevelWhileMining.value) + .filter(pos -> !blacklist.contains(pos)) .sorted(Comparator.comparingDouble(ctx.getBaritone().getPlayerContext().player()::getDistanceSq)) From 271c2ff636ce1e6504cff363589008f9802a9633 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Mon, 24 Apr 2023 22:38:12 +0200 Subject: [PATCH 043/405] Extend BlockOptionalMeta parsing to parse block properties --- .../baritone/api/utils/BlockOptionalMeta.java | 57 +++++++++++++++---- 1 file changed, 46 insertions(+), 11 deletions(-) diff --git a/src/api/java/baritone/api/utils/BlockOptionalMeta.java b/src/api/java/baritone/api/utils/BlockOptionalMeta.java index e0f491fba..9864d5144 100644 --- a/src/api/java/baritone/api/utils/BlockOptionalMeta.java +++ b/src/api/java/baritone/api/utils/BlockOptionalMeta.java @@ -19,6 +19,7 @@ package baritone.api.utils; import baritone.api.utils.accessor.IItemStack; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableMap; import net.minecraft.block.*; import net.minecraft.block.properties.IProperty; import net.minecraft.block.state.IBlockState; @@ -36,21 +37,24 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; public final class BlockOptionalMeta { + // id:meta or id[] or id[properties] where id and properties are any text with at least one character and meta is a one or two digit number + private static final Pattern PATTERN = Pattern.compile("^(?.+?)(?::(?\\d\\d?)|\\[(?.+?)?\\])?$"); private final Block block; private final int meta; private final boolean noMeta; + private final String propertiesDescription; // exists so toString() can return something more useful than a list of all blockstates private final Set blockstates; private final Set stateHashes; private final Set stackHashes; - private static final Pattern pattern = Pattern.compile("^(.+?)(?::(\\d+))?$"); private static final Map normalizations; public BlockOptionalMeta(@Nonnull Block block, @Nullable Integer meta) { this.block = block; this.noMeta = meta == null; this.meta = noMeta ? 0 : meta; - this.blockstates = getStates(block, meta); + this.propertiesDescription = "{}"; + this.blockstates = getStates(block, meta, Collections.emptyMap()); this.stateHashes = getStateHashes(blockstates); this.stackHashes = getStackHashes(blockstates); } @@ -60,24 +64,27 @@ public final class BlockOptionalMeta { } public BlockOptionalMeta(@Nonnull String selector) { - Matcher matcher = pattern.matcher(selector); + Matcher matcher = PATTERN.matcher(selector); if (!matcher.find()) { throw new IllegalArgumentException("invalid block selector"); } - MatchResult matchResult = matcher.toMatchResult(); - noMeta = matchResult.group(2) == null; + noMeta = matcher.group("meta") == null; - ResourceLocation id = new ResourceLocation(matchResult.group(1)); + ResourceLocation id = new ResourceLocation(matcher.group("id")); if (!Block.REGISTRY.containsKey(id)) { throw new IllegalArgumentException("Invalid block ID"); } - block = Block.REGISTRY.getObject(id); - meta = noMeta ? 0 : Integer.parseInt(matchResult.group(2)); - blockstates = getStates(block, getMeta()); + + String props = matcher.group("properties"); + Map, ?> properties = props == null || props.equals("") ? Collections.emptyMap() : parseProperties(block, props); + + propertiesDescription = props == null ? "{}" : "{" + props.replace("=", ":") + "}"; + meta = noMeta ? 0 : Integer.parseInt(matcher.group("meta")); + blockstates = getStates(block, getMeta(), properties); stateHashes = getStateHashes(blockstates); stackHashes = getStackHashes(blockstates); } @@ -243,9 +250,32 @@ public final class BlockOptionalMeta { return state.getBlock().getMetaFromState(normalize(state)); } - private static Set getStates(@Nonnull Block block, @Nullable Integer meta) { + private static Map, ?> parseProperties(Block block, String raw) { + ImmutableMap.Builder, Object> builder = ImmutableMap.builder(); + for (String pair : raw.split(",")) { + String[] parts = pair.split("="); + if (parts.length != 2) { + throw new IllegalArgumentException(String.format("\"%s\" is not a valid property-value pair", pair)); + } + String rawKey = parts[0]; + String rawValue = parts[1]; + IProperty key = block.getBlockState().getProperty(rawKey); + Comparable value = castToIProperty(key).parseValue(rawValue) + .toJavaUtil().orElseThrow(() -> new IllegalArgumentException(String.format( + "\"%s\" is not a valid value for %s on %s", + rawValue, key, block + ))); + builder.put(key, value); + } + return builder.build(); + } + + private static Set getStates(@Nonnull Block block, @Nullable Integer meta, @Nonnull Map, ?> properties) { return block.getBlockState().getValidStates().stream() .filter(blockstate -> meta == null || stateMeta(blockstate) == meta) + .filter(blockstate -> properties.entrySet().stream().allMatch(entry -> + blockstate.getValue(entry.getKey()) == entry.getValue() + )) .collect(Collectors.toSet()); } @@ -274,6 +304,7 @@ public final class BlockOptionalMeta { return block; } + @Deprecated // deprecated because getMeta() == null no longer implies that this BOM only cares about the block public Integer getMeta() { return noMeta ? null : meta; } @@ -300,7 +331,11 @@ public final class BlockOptionalMeta { @Override public String toString() { - return String.format("BlockOptionalMeta{block=%s,meta=%s}", block, getMeta()); + if (noMeta) { + return String.format("BlockOptionalMeta{block=%s,properties=%s}", block, propertiesDescription); + } else { + return String.format("BlockOptionalMeta{block=%s,meta=%s}", block, getMeta()); + } } public static IBlockState blockStateFromStack(ItemStack stack) { From c45a714b77b2e22b15108be5dfa822ffbd7a90dd Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Mon, 8 May 2023 03:51:38 +0200 Subject: [PATCH 044/405] Fix considering states unplaceable even if buildIgnoreProperties allows it --- src/main/java/baritone/process/BuilderProcess.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index c7868a4a0..a10085afe 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -691,7 +691,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil incorrectPositions.forEach(pos -> { IBlockState state = bcc.bsi.get0(pos); if (state.getBlock() instanceof BlockAir) { - if (approxPlaceable.contains(bcc.getSchematic(pos.x, pos.y, pos.z, state))) { + if (containsBlockState(approxPlaceable, bcc.getSchematic(pos.x, pos.y, pos.z, state))) { placeable.add(pos); } else { IBlockState desired = bcc.getSchematic(pos.x, pos.y, pos.z, state); @@ -922,6 +922,15 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil return true; } + private boolean containsBlockState(Collection states, IBlockState state) { + for (IBlockState testee : states) { + if (sameBlockstate(testee, state)) { + return true; + } + } + return false; + } + private boolean valid(IBlockState current, IBlockState desired, boolean itemVerify) { if (desired == null) { return true; From 80ec9023ce221dc147b4d12ad85f85abea965574 Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 4 Jun 2023 12:31:34 -0500 Subject: [PATCH 045/405] Replace `JAVA_ONLY_SETTINGS` array with `@JavaOnly` annotation --- src/api/java/baritone/api/Settings.java | 27 +++++++++++++++++++ .../command/helpers/TabCompleteHelper.java | 2 +- .../java/baritone/api/utils/SettingsUtil.java | 15 ++++------- .../command/ExampleBaritoneControl.java | 4 +-- .../baritone/command/defaults/SetCommand.java | 4 +-- 5 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index c13cde2f7..b7a4e41a4 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -29,6 +29,10 @@ import net.minecraft.util.math.Vec3i; import net.minecraft.util.text.ITextComponent; import java.awt.*; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; @@ -1154,6 +1158,7 @@ public final class Settings { * via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting * {@link Setting#value}; */ + @JavaOnly public final Setting> logger = new Setting<>(msg -> Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(msg)); /** @@ -1161,6 +1166,7 @@ public final class Settings { * via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting * {@link Setting#value}; */ + @JavaOnly public final Setting> notifier = new Setting<>(NotificationHelper::notify); /** @@ -1168,6 +1174,7 @@ public final class Settings { * via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting * {@link Setting#value}; */ + @JavaOnly public final Setting> toaster = new Setting<>(BaritoneToast::addOrUpdate); /** @@ -1312,6 +1319,7 @@ public final class Settings { public T value; public final T defaultValue; private String name; + private boolean javaOnly; @SuppressWarnings("unchecked") private Setting(T value) { @@ -1320,6 +1328,7 @@ public final class Settings { } this.value = value; this.defaultValue = value; + this.javaOnly = false; } /** @@ -1356,8 +1365,25 @@ public final class Settings { public final Type getType() { return settingTypes.get(this); } + + /** + * This should always be the same as whether the setting can be parsed from or serialized to a string; in other + * words, the only way to modify it is by writing to {@link #value} programatically. + * + * @return {@code true} if the setting can not be set or read by the user + */ + public boolean isJavaOnly() { + return javaOnly; + } } + /** + * Marks a {@link Setting} field as being {@link Setting#isJavaOnly() Java-only} + */ + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + private @interface JavaOnly {} + // here be dragons Settings() { @@ -1373,6 +1399,7 @@ public final class Settings { Setting setting = (Setting) field.get(this); String name = field.getName(); setting.name = name; + setting.javaOnly = field.isAnnotationPresent(JavaOnly.class); name = name.toLowerCase(); if (tmpByName.containsKey(name)) { throw new IllegalStateException("Duplicate setting name"); diff --git a/src/api/java/baritone/api/command/helpers/TabCompleteHelper.java b/src/api/java/baritone/api/command/helpers/TabCompleteHelper.java index e438da308..96706d08b 100644 --- a/src/api/java/baritone/api/command/helpers/TabCompleteHelper.java +++ b/src/api/java/baritone/api/command/helpers/TabCompleteHelper.java @@ -253,7 +253,7 @@ public class TabCompleteHelper { public TabCompleteHelper addSettings() { return append( BaritoneAPI.getSettings().allSettings.stream() - .filter(s -> !SettingsUtil.javaOnlySetting(s)) + .filter(s -> !s.isJavaOnly()) .map(Settings.Setting::getName) .sorted(String.CASE_INSENSITIVE_ORDER) ); diff --git a/src/api/java/baritone/api/utils/SettingsUtil.java b/src/api/java/baritone/api/utils/SettingsUtil.java index 50e2363a6..0b9c64737 100644 --- a/src/api/java/baritone/api/utils/SettingsUtil.java +++ b/src/api/java/baritone/api/utils/SettingsUtil.java @@ -50,7 +50,6 @@ public class SettingsUtil { public static final String SETTINGS_DEFAULT_NAME = "settings.txt"; private static final Pattern SETTING_PATTERN = Pattern.compile("^(?[^ ]+) +(?.+)"); // key and value split by the first space - private static final String[] JAVA_ONLY_SETTINGS = {"logger", "notifier", "toaster"}; private static boolean isComment(String line) { return line.startsWith("#") || line.startsWith("//"); @@ -116,7 +115,7 @@ public class SettingsUtil { System.out.println("NULL SETTING?" + setting.getName()); continue; } - if (javaOnlySetting(setting)) { + if (setting.isJavaOnly()) { continue; // NO } if (setting.value == setting.defaultValue) { @@ -170,7 +169,7 @@ public class SettingsUtil { } public static String settingToString(Settings.Setting setting) throws IllegalStateException { - if (javaOnlySetting(setting)) { + if (setting.isJavaOnly()) { return setting.getName(); } @@ -178,18 +177,14 @@ public class SettingsUtil { } /** - * This should always be the same as whether the setting can be parsed from or serialized to a string + * Deprecated. Use {@link Settings.Setting#isJavaOnly()} instead. * * @param setting The Setting * @return true if the setting can not be set or read by the user */ + @Deprecated public static boolean javaOnlySetting(Settings.Setting setting) { - for (String name : JAVA_ONLY_SETTINGS) { // no JAVA_ONLY_SETTINGS.contains(...) because that would be case sensitive - if (setting.getName().equalsIgnoreCase(name)) { - return true; - } - } - return false; + return setting.isJavaOnly(); } public static void parseAndApply(Settings settings, String settingName, String settingValue) throws IllegalStateException, NumberFormatException { diff --git a/src/main/java/baritone/command/ExampleBaritoneControl.java b/src/main/java/baritone/command/ExampleBaritoneControl.java index 7050bf302..28ced07f4 100644 --- a/src/main/java/baritone/command/ExampleBaritoneControl.java +++ b/src/main/java/baritone/command/ExampleBaritoneControl.java @@ -124,7 +124,7 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener } } else if (argc.hasExactlyOne()) { for (Settings.Setting setting : settings.allSettings) { - if (SettingsUtil.javaOnlySetting(setting)) { + if (setting.isJavaOnly()) { continue; } if (setting.getName().equalsIgnoreCase(pair.getFirst())) { @@ -177,7 +177,7 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener .stream(); } Settings.Setting setting = settings.byLowerName.get(argc.getString().toLowerCase(Locale.US)); - if (setting != null && !SettingsUtil.javaOnlySetting(setting)) { + if (setting != null && !setting.isJavaOnly()) { if (setting.getValueClass() == Boolean.class) { TabCompleteHelper helper = new TabCompleteHelper(); if ((Boolean) setting.value) { diff --git a/src/main/java/baritone/command/defaults/SetCommand.java b/src/main/java/baritone/command/defaults/SetCommand.java index 255dd6b28..dd6f1204b 100644 --- a/src/main/java/baritone/command/defaults/SetCommand.java +++ b/src/main/java/baritone/command/defaults/SetCommand.java @@ -77,7 +77,7 @@ public class SetCommand extends Command { args.requireMax(1); List toPaginate = (viewModified ? SettingsUtil.modifiedSettings(Baritone.settings()) : Baritone.settings().allSettings).stream() - .filter(s -> !javaOnlySetting(s)) + .filter(s -> !s.isJavaOnly()) .filter(s -> s.getName().toLowerCase(Locale.US).contains(search.toLowerCase(Locale.US))) .sorted((s1, s2) -> String.CASE_INSENSITIVE_ORDER.compare(s1.getName(), s2.getName())) .collect(Collectors.toList()); @@ -141,7 +141,7 @@ public class SetCommand extends Command { if (setting == null) { throw new CommandInvalidTypeException(args.consumed(), "a valid setting"); } - if (javaOnlySetting(setting)) { + if (setting.isJavaOnly()) { // ideally it would act as if the setting didn't exist // but users will see it in Settings.java or its javadoc // so at some point we have to tell them or they will see it as a bug From 0d14bde5839887990236966bd5f09d46841c373f Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 7 Jun 2023 16:31:52 -0500 Subject: [PATCH 046/405] Working sphere/cylinder build commands for `#sel` --- .../api/schematic/CylinderSchematic.java | 50 ++++++++++++++++ .../api/schematic/SphereSchematic.java | 54 ++++++++++++++++++ .../baritone/command/defaults/SelCommand.java | 57 +++++++++++++++---- 3 files changed, 151 insertions(+), 10 deletions(-) create mode 100644 src/api/java/baritone/api/schematic/CylinderSchematic.java create mode 100644 src/api/java/baritone/api/schematic/SphereSchematic.java diff --git a/src/api/java/baritone/api/schematic/CylinderSchematic.java b/src/api/java/baritone/api/schematic/CylinderSchematic.java new file mode 100644 index 000000000..3ba8bc9b8 --- /dev/null +++ b/src/api/java/baritone/api/schematic/CylinderSchematic.java @@ -0,0 +1,50 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.api.schematic; + +import net.minecraft.block.state.IBlockState; + +/** + * @author Brady + */ +public class CylinderSchematic extends MaskSchematic { + + private final double cx, cz, rx, rz; + private final boolean filled; + + public CylinderSchematic(ISchematic schematic, boolean filled) { + super(schematic); + this.cx = schematic.widthX() / 2.0; + this.cz = schematic.lengthZ() / 2.0; + this.rx = this.cx * this.cx; + this.rz = this.cz * this.cz; + this.filled = filled; + } + + @Override + protected boolean partOfMask(int x, int y, int z, IBlockState currentState) { + double dx = Math.abs((x + 0.5) - this.cx); + double dz = Math.abs((z + 0.5) - this.cz); + return !this.outside(dx, dz) + && (this.filled || outside(dx + 1, dz) || outside(dx, dz + 1)); + } + + private boolean outside(double dx, double dz) { + return dx * dx / this.rx + dz * dz / this.rz > 1; + } +} diff --git a/src/api/java/baritone/api/schematic/SphereSchematic.java b/src/api/java/baritone/api/schematic/SphereSchematic.java new file mode 100644 index 000000000..0ca987760 --- /dev/null +++ b/src/api/java/baritone/api/schematic/SphereSchematic.java @@ -0,0 +1,54 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.api.schematic; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.Vec3d; + +/** + * @author Brady + */ +public class SphereSchematic extends MaskSchematic { + + private final double cx, cy, cz, rx, ry, rz; + private final boolean filled; + + public SphereSchematic(ISchematic schematic, boolean filled) { + super(schematic); + this.cx = schematic.widthX() / 2.0; + this.cy = schematic.heightY() / 2.0; + this.cz = schematic.lengthZ() / 2.0; + this.rx = this.cx * this.cx; + this.ry = this.cy * this.cy; + this.rz = this.cz * this.cz; + this.filled = filled; + } + + @Override + protected boolean partOfMask(int x, int y, int z, IBlockState currentState) { + double dx = Math.abs((x + 0.5) - this.cx); + double dy = Math.abs((y + 0.5) - this.cy); + double dz = Math.abs((z + 0.5) - this.cz); + return !this.outside(dx, dy, dz) + && (this.filled || outside(dx + 1, dy, dz) || outside(dx, dy + 1, dz) || outside(dx, dy, dz + 1)); + } + + private boolean outside(double dx,double dy, double dz) { + return dx * dx / this.rx + dy * dy / this.ry + dz * dz / this.rz > 1; + } +} diff --git a/src/main/java/baritone/command/defaults/SelCommand.java b/src/main/java/baritone/command/defaults/SelCommand.java index 5677eec3c..dcdd05b74 100644 --- a/src/main/java/baritone/command/defaults/SelCommand.java +++ b/src/main/java/baritone/command/defaults/SelCommand.java @@ -117,7 +117,7 @@ public class SelCommand extends Command { logDirect("Undid pos2"); } } - } else if (action == Action.SET || action == Action.WALLS || action == Action.SHELL || action == Action.CLEARAREA || action == Action.REPLACE) { + } else if (action.isFillAction()) { BlockOptionalMeta type = action == Action.CLEARAREA ? new BlockOptionalMeta(Blocks.AIR) : args.getDatatypeFor(ForBlockOptionalMeta.INSTANCE); @@ -151,14 +151,10 @@ public class SelCommand extends Command { for (ISelection selection : selections) { Vec3i size = selection.size(); BetterBlockPos min = selection.min(); - ISchematic schematic = new FillSchematic(size.getX(), size.getY(), size.getZ(), type); - if (action == Action.WALLS) { - schematic = new WallsSchematic(schematic); - } else if (action == Action.SHELL) { - schematic = new ShellSchematic(schematic); - } else if (action == Action.REPLACE) { - schematic = new ReplaceSchematic(schematic, replaces); - } + ISchematic schematic = action.createFillMask( + new FillSchematic(size.getX(), size.getY(), size.getZ(), type), + replaces + ); composite.put(schematic, min.x - origin.x, min.y - origin.y, min.z - origin.z); } baritone.getBuilderProcess().build("Fill", composite, origin); @@ -254,7 +250,7 @@ public class SelCommand extends Command { if (args.hasAtMost(3)) { return args.tabCompleteDatatype(RelativeBlockPos.INSTANCE); } - } else if (action == Action.SET || action == Action.WALLS || action == Action.CLEARAREA || action == Action.REPLACE) { + } else if (action.isFillAction()) { if (args.hasExactlyOne() || action == Action.REPLACE) { while (args.has(2)) { args.get(); @@ -305,6 +301,10 @@ public class SelCommand extends Command { "> sel set/fill/s/f [block] - Completely fill all selections with a block.", "> sel walls/w [block] - Fill in the walls of the selection with a specified block.", "> sel shell/shl [block] - The same as walls, but fills in a ceiling and floor too.", + "> sel sphere/sph [block] - Fills the selection with a sphere bounded by the sides.", + "> sel hsphere/hsph [block] - The same as sphere, but hollow.", + "> sel cylinder/cyl [block] - Fills the selection with a cylinder bounded by the sides.", + "> sel hcylinder/hcyl [block] - The same as cylinder, but hollow.", "> sel cleararea/ca - Basically 'set air'.", "> sel replace/r - Replaces blocks with another block.", "> sel copy/cp - Copy the selected area relative to the specified or your position.", @@ -324,6 +324,10 @@ public class SelCommand extends Command { SET("set", "fill", "s", "f"), WALLS("walls", "w"), SHELL("shell", "shl"), + SPHERE("sphere", "sph"), + HSPHERE("hsphere", "hsph"), + CYLINDER("cylinder", "cyl"), + HCYLINDER("hcylinder", "hcyl"), CLEARAREA("cleararea", "ca"), REPLACE("replace", "r"), EXPAND("expand", "ex"), @@ -355,6 +359,39 @@ public class SelCommand extends Command { } return names.toArray(new String[0]); } + + public final boolean isFillAction() { + return this == SET + || this == WALLS + || this == SHELL + || this == SPHERE + || this == HSPHERE + || this == CYLINDER + || this == HCYLINDER + || this == CLEARAREA + || this == REPLACE; + } + + public final ISchematic createFillMask(ISchematic fill, BlockOptionalMetaLookup replaces) { + switch (this) { + case WALLS: + return new WallsSchematic(fill); + case SHELL: + return new ShellSchematic(fill); + case REPLACE: + return new ReplaceSchematic(fill, replaces); + case SPHERE: + return new SphereSchematic(fill, true); + case HSPHERE: + return new SphereSchematic(fill, false); + case CYLINDER: + return new CylinderSchematic(fill, true); + case HCYLINDER: + return new CylinderSchematic(fill, false); + } + // Silent fail + return fill; + } } enum TransformTarget { From 34abbfb5daced3623e9a2a17da8018042980d758 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 7 Jun 2023 17:38:26 -0500 Subject: [PATCH 047/405] appease codacy --- .../api/schematic/CylinderSchematic.java | 19 +++++++------ .../api/schematic/SphereSchematic.java | 28 +++++++++++-------- .../baritone/command/defaults/SelCommand.java | 5 ++-- 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/src/api/java/baritone/api/schematic/CylinderSchematic.java b/src/api/java/baritone/api/schematic/CylinderSchematic.java index 3ba8bc9b8..75726348d 100644 --- a/src/api/java/baritone/api/schematic/CylinderSchematic.java +++ b/src/api/java/baritone/api/schematic/CylinderSchematic.java @@ -24,27 +24,30 @@ import net.minecraft.block.state.IBlockState; */ public class CylinderSchematic extends MaskSchematic { - private final double cx, cz, rx, rz; + private final double centerX; + private final double centerZ; + private final double radiusSqX; + private final double radiusSqZ; private final boolean filled; public CylinderSchematic(ISchematic schematic, boolean filled) { super(schematic); - this.cx = schematic.widthX() / 2.0; - this.cz = schematic.lengthZ() / 2.0; - this.rx = this.cx * this.cx; - this.rz = this.cz * this.cz; + this.centerX = schematic.widthX() / 2.0; + this.centerZ = schematic.lengthZ() / 2.0; + this.radiusSqX = this.centerX * this.centerX; + this.radiusSqZ = this.centerZ * this.centerZ; this.filled = filled; } @Override protected boolean partOfMask(int x, int y, int z, IBlockState currentState) { - double dx = Math.abs((x + 0.5) - this.cx); - double dz = Math.abs((z + 0.5) - this.cz); + double dx = Math.abs((x + 0.5) - this.centerX); + double dz = Math.abs((z + 0.5) - this.centerZ); return !this.outside(dx, dz) && (this.filled || outside(dx + 1, dz) || outside(dx, dz + 1)); } private boolean outside(double dx, double dz) { - return dx * dx / this.rx + dz * dz / this.rz > 1; + return dx * dx / this.radiusSqX + dz * dz / this.radiusSqZ > 1; } } diff --git a/src/api/java/baritone/api/schematic/SphereSchematic.java b/src/api/java/baritone/api/schematic/SphereSchematic.java index 0ca987760..1cf0a579f 100644 --- a/src/api/java/baritone/api/schematic/SphereSchematic.java +++ b/src/api/java/baritone/api/schematic/SphereSchematic.java @@ -18,37 +18,41 @@ package baritone.api.schematic; import net.minecraft.block.state.IBlockState; -import net.minecraft.util.math.Vec3d; /** * @author Brady */ public class SphereSchematic extends MaskSchematic { - private final double cx, cy, cz, rx, ry, rz; + private final double centerX; + private final double centerY; + private final double centerZ; + private final double radiusSqX; + private final double radiusSqY; + private final double radiusSqZ; private final boolean filled; public SphereSchematic(ISchematic schematic, boolean filled) { super(schematic); - this.cx = schematic.widthX() / 2.0; - this.cy = schematic.heightY() / 2.0; - this.cz = schematic.lengthZ() / 2.0; - this.rx = this.cx * this.cx; - this.ry = this.cy * this.cy; - this.rz = this.cz * this.cz; + this.centerX = schematic.widthX() / 2.0; + this.centerY = schematic.heightY() / 2.0; + this.centerZ = schematic.lengthZ() / 2.0; + this.radiusSqX = this.centerX * this.centerX; + this.radiusSqY = this.centerY * this.centerY; + this.radiusSqZ = this.centerZ * this.centerZ; this.filled = filled; } @Override protected boolean partOfMask(int x, int y, int z, IBlockState currentState) { - double dx = Math.abs((x + 0.5) - this.cx); - double dy = Math.abs((y + 0.5) - this.cy); - double dz = Math.abs((z + 0.5) - this.cz); + double dx = Math.abs((x + 0.5) - this.centerX); + double dy = Math.abs((y + 0.5) - this.centerY); + double dz = Math.abs((z + 0.5) - this.centerZ); return !this.outside(dx, dy, dz) && (this.filled || outside(dx + 1, dy, dz) || outside(dx, dy + 1, dz) || outside(dx, dy, dz + 1)); } private boolean outside(double dx,double dy, double dz) { - return dx * dx / this.rx + dy * dy / this.ry + dz * dz / this.rz > 1; + return dx * dx / this.radiusSqX + dy * dy / this.radiusSqY + dz * dz / this.radiusSqZ > 1; } } diff --git a/src/main/java/baritone/command/defaults/SelCommand.java b/src/main/java/baritone/command/defaults/SelCommand.java index dcdd05b74..40df5c294 100644 --- a/src/main/java/baritone/command/defaults/SelCommand.java +++ b/src/main/java/baritone/command/defaults/SelCommand.java @@ -388,9 +388,10 @@ public class SelCommand extends Command { return new CylinderSchematic(fill, true); case HCYLINDER: return new CylinderSchematic(fill, false); + default: + // Silent fail + return fill; } - // Silent fail - return fill; } } From b6c52cd8e1fd567afdefe428876f7ed0c2a7a4e4 Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 8 Jun 2023 11:52:13 -0500 Subject: [PATCH 048/405] Cache mask in a `boolean[][][]` --- .../api/schematic/CachedMaskSchematic.java | 53 +++++++++++++++++++ .../api/schematic/CylinderSchematic.java | 43 +++++++-------- .../api/schematic/SphereSchematic.java | 51 ++++++++---------- 3 files changed, 92 insertions(+), 55 deletions(-) create mode 100644 src/api/java/baritone/api/schematic/CachedMaskSchematic.java diff --git a/src/api/java/baritone/api/schematic/CachedMaskSchematic.java b/src/api/java/baritone/api/schematic/CachedMaskSchematic.java new file mode 100644 index 000000000..19bcf4e3a --- /dev/null +++ b/src/api/java/baritone/api/schematic/CachedMaskSchematic.java @@ -0,0 +1,53 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.api.schematic; + +import net.minecraft.block.state.IBlockState; + +/** + * @author Brady + */ +public abstract class CachedMaskSchematic extends MaskSchematic { + + /** + * Mask array with {@code y,z,x} indexing + */ + private final boolean[][][] mask; + + public CachedMaskSchematic(ISchematic schematic, StaticMaskFunction maskFunction) { + super(schematic); + this.mask = new boolean[schematic.heightY()][schematic.lengthZ()][schematic.widthX()]; + for (int y = 0; y < schematic.heightY(); y++) { + for (int z = 0; z < schematic.lengthZ(); z++) { + for (int x = 0; x < schematic.widthX(); x++) { + this.mask[y][z][x] = maskFunction.partOfMask(x, y, z); + } + } + } + } + + @Override + protected final boolean partOfMask(int x, int y, int z, IBlockState currentState) { + return this.mask[y][z][x]; + } + + @FunctionalInterface + public interface StaticMaskFunction { + boolean partOfMask(int x, int y, int z); + } +} diff --git a/src/api/java/baritone/api/schematic/CylinderSchematic.java b/src/api/java/baritone/api/schematic/CylinderSchematic.java index 75726348d..055f12875 100644 --- a/src/api/java/baritone/api/schematic/CylinderSchematic.java +++ b/src/api/java/baritone/api/schematic/CylinderSchematic.java @@ -17,37 +17,30 @@ package baritone.api.schematic; -import net.minecraft.block.state.IBlockState; - /** * @author Brady */ -public class CylinderSchematic extends MaskSchematic { - - private final double centerX; - private final double centerZ; - private final double radiusSqX; - private final double radiusSqZ; - private final boolean filled; +public final class CylinderSchematic extends CachedMaskSchematic { public CylinderSchematic(ISchematic schematic, boolean filled) { - super(schematic); - this.centerX = schematic.widthX() / 2.0; - this.centerZ = schematic.lengthZ() / 2.0; - this.radiusSqX = this.centerX * this.centerX; - this.radiusSqZ = this.centerZ * this.centerZ; - this.filled = filled; - } + super(schematic, new StaticMaskFunction() { - @Override - protected boolean partOfMask(int x, int y, int z, IBlockState currentState) { - double dx = Math.abs((x + 0.5) - this.centerX); - double dz = Math.abs((z + 0.5) - this.centerZ); - return !this.outside(dx, dz) - && (this.filled || outside(dx + 1, dz) || outside(dx, dz + 1)); - } + private final double centerX = schematic.widthX() / 2.0; + private final double centerZ = schematic.lengthZ() / 2.0; + private final double radiusSqX = this.centerX * this.centerX; + private final double radiusSqZ = this.centerZ * this.centerZ; - private boolean outside(double dx, double dz) { - return dx * dx / this.radiusSqX + dz * dz / this.radiusSqZ > 1; + @Override + public boolean partOfMask(int x, int y, int z) { + double dx = Math.abs((x + 0.5) - this.centerX); + double dz = Math.abs((z + 0.5) - this.centerZ); + return !this.outside(dx, dz) + && (filled || outside(dx + 1, dz) || outside(dx, dz + 1)); + } + + private boolean outside(double dx, double dz) { + return dx * dx / this.radiusSqX + dz * dz / this.radiusSqZ > 1; + } + }); } } diff --git a/src/api/java/baritone/api/schematic/SphereSchematic.java b/src/api/java/baritone/api/schematic/SphereSchematic.java index 1cf0a579f..987b87198 100644 --- a/src/api/java/baritone/api/schematic/SphereSchematic.java +++ b/src/api/java/baritone/api/schematic/SphereSchematic.java @@ -17,42 +17,33 @@ package baritone.api.schematic; -import net.minecraft.block.state.IBlockState; - /** * @author Brady */ -public class SphereSchematic extends MaskSchematic { - - private final double centerX; - private final double centerY; - private final double centerZ; - private final double radiusSqX; - private final double radiusSqY; - private final double radiusSqZ; - private final boolean filled; +public final class SphereSchematic extends CachedMaskSchematic { public SphereSchematic(ISchematic schematic, boolean filled) { - super(schematic); - this.centerX = schematic.widthX() / 2.0; - this.centerY = schematic.heightY() / 2.0; - this.centerZ = schematic.lengthZ() / 2.0; - this.radiusSqX = this.centerX * this.centerX; - this.radiusSqY = this.centerY * this.centerY; - this.radiusSqZ = this.centerZ * this.centerZ; - this.filled = filled; - } + super(schematic, new StaticMaskFunction() { - @Override - protected boolean partOfMask(int x, int y, int z, IBlockState currentState) { - double dx = Math.abs((x + 0.5) - this.centerX); - double dy = Math.abs((y + 0.5) - this.centerY); - double dz = Math.abs((z + 0.5) - this.centerZ); - return !this.outside(dx, dy, dz) - && (this.filled || outside(dx + 1, dy, dz) || outside(dx, dy + 1, dz) || outside(dx, dy, dz + 1)); - } + private final double centerX = schematic.widthX() / 2.0; + private final double centerY = schematic.heightY() / 2.0; + private final double centerZ = schematic.lengthZ() / 2.0; + private final double radiusSqX = this.centerX * this.centerX; + private final double radiusSqY = this.centerY * this.centerY; + private final double radiusSqZ = this.centerZ * this.centerZ; - private boolean outside(double dx,double dy, double dz) { - return dx * dx / this.radiusSqX + dy * dy / this.radiusSqY + dz * dz / this.radiusSqZ > 1; + @Override + public boolean partOfMask(int x, int y, int z) { + double dx = Math.abs((x + 0.5) - this.centerX); + double dy = Math.abs((y + 0.5) - this.centerY); + double dz = Math.abs((z + 0.5) - this.centerZ); + return !this.outside(dx, dy, dz) + && (filled || outside(dx + 1, dy, dz) || outside(dx, dy + 1, dz) || outside(dx, dy, dz + 1)); + } + + private boolean outside(double dx,double dy, double dz) { + return dx * dx / this.radiusSqX + dy * dy / this.radiusSqY + dz * dz / this.radiusSqZ > 1; + } + }); } } From a1b1ef88cf4d83ca027e05e589fc46ff148be634 Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 8 Jun 2023 15:46:32 -0500 Subject: [PATCH 049/405] Use a Supplier to mimic a switch expression --- .../baritone/command/defaults/SelCommand.java | 55 ++++++++++--------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/src/main/java/baritone/command/defaults/SelCommand.java b/src/main/java/baritone/command/defaults/SelCommand.java index 40df5c294..85b3e4307 100644 --- a/src/main/java/baritone/command/defaults/SelCommand.java +++ b/src/main/java/baritone/command/defaults/SelCommand.java @@ -50,6 +50,7 @@ import java.awt.*; import java.util.List; import java.util.*; import java.util.function.Function; +import java.util.function.UnaryOperator; import java.util.stream.Stream; public class SelCommand extends Command { @@ -121,7 +122,7 @@ public class SelCommand extends Command { BlockOptionalMeta type = action == Action.CLEARAREA ? new BlockOptionalMeta(Blocks.AIR) : args.getDatatypeFor(ForBlockOptionalMeta.INSTANCE); - BlockOptionalMetaLookup replaces = null; + BlockOptionalMetaLookup replaces; if (action == Action.REPLACE) { args.requireMin(1); List replacesList = new ArrayList<>(); @@ -133,6 +134,7 @@ public class SelCommand extends Command { replaces = new BlockOptionalMetaLookup(replacesList.toArray(new BlockOptionalMeta[0])); } else { args.requireMax(0); + replaces = null; } ISelection[] selections = manager.getSelections(); if (selections.length == 0) { @@ -151,10 +153,31 @@ public class SelCommand extends Command { for (ISelection selection : selections) { Vec3i size = selection.size(); BetterBlockPos min = selection.min(); - ISchematic schematic = action.createFillMask( - new FillSchematic(size.getX(), size.getY(), size.getZ(), type), - replaces - ); + + // Java 8 so no switch expressions 😿 + UnaryOperator create = fill -> { + switch (action) { + case WALLS: + return new WallsSchematic(fill); + case SHELL: + return new ShellSchematic(fill); + case REPLACE: + return new ReplaceSchematic(fill, replaces); + case SPHERE: + return new SphereSchematic(fill, true); + case HSPHERE: + return new SphereSchematic(fill, false); + case CYLINDER: + return new CylinderSchematic(fill, true); + case HCYLINDER: + return new CylinderSchematic(fill, false); + default: + // Silent fail + return fill; + } + }; + + ISchematic schematic = create.apply(new FillSchematic(size.getX(), size.getY(), size.getZ(), type)); composite.put(schematic, min.x - origin.x, min.y - origin.y, min.z - origin.z); } baritone.getBuilderProcess().build("Fill", composite, origin); @@ -371,28 +394,6 @@ public class SelCommand extends Command { || this == CLEARAREA || this == REPLACE; } - - public final ISchematic createFillMask(ISchematic fill, BlockOptionalMetaLookup replaces) { - switch (this) { - case WALLS: - return new WallsSchematic(fill); - case SHELL: - return new ShellSchematic(fill); - case REPLACE: - return new ReplaceSchematic(fill, replaces); - case SPHERE: - return new SphereSchematic(fill, true); - case HSPHERE: - return new SphereSchematic(fill, false); - case CYLINDER: - return new CylinderSchematic(fill, true); - case HCYLINDER: - return new CylinderSchematic(fill, false); - default: - // Silent fail - return fill; - } - } } enum TransformTarget { From 26574b4a9b23a67d1555b8717a084bcca51503b8 Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 8 Jun 2023 16:32:33 -0500 Subject: [PATCH 050/405] Add optional axis parameter for `#sel cyl` --- .../api/command/datatypes/ForAxis.java | 43 +++++++++++++++++++ .../api/schematic/CylinderSchematic.java | 32 +++++++++----- .../baritone/command/defaults/SelCommand.java | 25 ++++++++--- 3 files changed, 84 insertions(+), 16 deletions(-) create mode 100644 src/api/java/baritone/api/command/datatypes/ForAxis.java diff --git a/src/api/java/baritone/api/command/datatypes/ForAxis.java b/src/api/java/baritone/api/command/datatypes/ForAxis.java new file mode 100644 index 000000000..48efb39b7 --- /dev/null +++ b/src/api/java/baritone/api/command/datatypes/ForAxis.java @@ -0,0 +1,43 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.api.command.datatypes; + +import baritone.api.command.exception.CommandException; +import baritone.api.command.helpers.TabCompleteHelper; +import net.minecraft.util.EnumFacing; + +import java.util.Locale; +import java.util.stream.Stream; + +public enum ForAxis implements IDatatypeFor { + INSTANCE; + + @Override + public EnumFacing.Axis get(IDatatypeContext ctx) throws CommandException { + return EnumFacing.Axis.valueOf(ctx.getConsumer().getString().toUpperCase(Locale.US)); + } + + @Override + public Stream tabComplete(IDatatypeContext ctx) throws CommandException { + return new TabCompleteHelper() + .append(Stream.of(EnumFacing.Axis.values()) + .map(EnumFacing.Axis::getName).map(String::toLowerCase)) + .filterPrefix(ctx.getConsumer().getString()) + .stream(); + } +} diff --git a/src/api/java/baritone/api/schematic/CylinderSchematic.java b/src/api/java/baritone/api/schematic/CylinderSchematic.java index 055f12875..342c6e373 100644 --- a/src/api/java/baritone/api/schematic/CylinderSchematic.java +++ b/src/api/java/baritone/api/schematic/CylinderSchematic.java @@ -17,29 +17,39 @@ package baritone.api.schematic; +import net.minecraft.util.EnumFacing; + /** * @author Brady */ public final class CylinderSchematic extends CachedMaskSchematic { - public CylinderSchematic(ISchematic schematic, boolean filled) { + public CylinderSchematic(ISchematic schematic, boolean filled, EnumFacing.Axis alignment) { super(schematic, new StaticMaskFunction() { - private final double centerX = schematic.widthX() / 2.0; - private final double centerZ = schematic.lengthZ() / 2.0; - private final double radiusSqX = this.centerX * this.centerX; - private final double radiusSqZ = this.centerZ * this.centerZ; + private final double centerA = this.getA(schematic.widthX(), schematic.heightY()) / 2.0; + private final double centerB = this.getB(schematic.heightY(), schematic.lengthZ()) / 2.0; + private final double radiusSqA = this.centerA * this.centerA; + private final double radiusSqB = this.centerB * this.centerB; @Override public boolean partOfMask(int x, int y, int z) { - double dx = Math.abs((x + 0.5) - this.centerX); - double dz = Math.abs((z + 0.5) - this.centerZ); - return !this.outside(dx, dz) - && (filled || outside(dx + 1, dz) || outside(dx, dz + 1)); + double da = Math.abs((this.getA(x, y) + 0.5) - this.centerA); + double db = Math.abs((this.getB(y, z) + 0.5) - this.centerB); + return !this.outside(da, db) + && (filled || outside(da + 1, db) || outside(da, db + 1)); } - private boolean outside(double dx, double dz) { - return dx * dx / this.radiusSqX + dz * dz / this.radiusSqZ > 1; + private boolean outside(double da, double db) { + return da * da / this.radiusSqA + db * db / this.radiusSqB > 1; + } + + private int getA(int x, int y) { + return alignment == EnumFacing.Axis.X ? y : x; + } + + private int getB(int y, int z) { + return alignment == EnumFacing.Axis.Z ? y : z; } }); } diff --git a/src/main/java/baritone/command/defaults/SelCommand.java b/src/main/java/baritone/command/defaults/SelCommand.java index 85b3e4307..72c5cd1c0 100644 --- a/src/main/java/baritone/command/defaults/SelCommand.java +++ b/src/main/java/baritone/command/defaults/SelCommand.java @@ -21,6 +21,7 @@ import baritone.Baritone; import baritone.api.IBaritone; import baritone.api.command.Command; import baritone.api.command.argument.IArgConsumer; +import baritone.api.command.datatypes.ForAxis; import baritone.api.command.datatypes.ForBlockOptionalMeta; import baritone.api.command.datatypes.ForEnumFacing; import baritone.api.command.datatypes.RelativeBlockPos; @@ -122,7 +123,9 @@ public class SelCommand extends Command { BlockOptionalMeta type = action == Action.CLEARAREA ? new BlockOptionalMeta(Blocks.AIR) : args.getDatatypeFor(ForBlockOptionalMeta.INSTANCE); - BlockOptionalMetaLookup replaces; + + final BlockOptionalMetaLookup replaces; // Action.REPLACE + final EnumFacing.Axis alignment; // Action.(H)CYLINDER if (action == Action.REPLACE) { args.requireMin(1); List replacesList = new ArrayList<>(); @@ -132,9 +135,15 @@ public class SelCommand extends Command { } type = args.getDatatypeFor(ForBlockOptionalMeta.INSTANCE); replaces = new BlockOptionalMetaLookup(replacesList.toArray(new BlockOptionalMeta[0])); + alignment = null; + } else if (action == Action.CYLINDER || action == Action.HCYLINDER) { + args.requireMax(1); + alignment = args.hasAny() ? args.getDatatypeFor(ForAxis.INSTANCE) : EnumFacing.Axis.Y; + replaces = null; } else { args.requireMax(0); replaces = null; + alignment = null; } ISelection[] selections = manager.getSelections(); if (selections.length == 0) { @@ -168,9 +177,9 @@ public class SelCommand extends Command { case HSPHERE: return new SphereSchematic(fill, false); case CYLINDER: - return new CylinderSchematic(fill, true); + return new CylinderSchematic(fill, true, alignment); case HCYLINDER: - return new CylinderSchematic(fill, false); + return new CylinderSchematic(fill, false, alignment); default: // Silent fail return fill; @@ -279,6 +288,12 @@ public class SelCommand extends Command { args.get(); } return args.tabCompleteDatatype(ForBlockOptionalMeta.INSTANCE); + } else if (action == Action.CYLINDER || action == Action.HCYLINDER) { + if (args.hasExactly(2)) { + if (args.getDatatypeForOrNull(ForBlockOptionalMeta.INSTANCE) != null) { + return args.tabCompleteDatatype(ForAxis.INSTANCE); + } + } } } else if (action == Action.EXPAND || action == Action.CONTRACT || action == Action.SHIFT) { if (args.hasExactlyOne()) { @@ -326,8 +341,8 @@ public class SelCommand extends Command { "> sel shell/shl [block] - The same as walls, but fills in a ceiling and floor too.", "> sel sphere/sph [block] - Fills the selection with a sphere bounded by the sides.", "> sel hsphere/hsph [block] - The same as sphere, but hollow.", - "> sel cylinder/cyl [block] - Fills the selection with a cylinder bounded by the sides.", - "> sel hcylinder/hcyl [block] - The same as cylinder, but hollow.", + "> sel cylinder/cyl [block] - Fills the selection with a cylinder bounded by the sides, oriented about the given axis. (default=y)", + "> sel hcylinder/hcyl [block] - The same as cylinder, but hollow.", "> sel cleararea/ca - Basically 'set air'.", "> sel replace/r - Replaces blocks with another block.", "> sel copy/cp - Copy the selected area relative to the specified or your position.", From f232bbdb15cb6a07296b1a093a1213794e051e25 Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 8 Jun 2023 16:36:32 -0500 Subject: [PATCH 051/405] Clean up formatting --- .../baritone/api/schematic/CylinderSchematic.java | 8 ++++++-- .../java/baritone/api/schematic/SphereSchematic.java | 11 ++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/api/java/baritone/api/schematic/CylinderSchematic.java b/src/api/java/baritone/api/schematic/CylinderSchematic.java index 342c6e373..29b5aa5b3 100644 --- a/src/api/java/baritone/api/schematic/CylinderSchematic.java +++ b/src/api/java/baritone/api/schematic/CylinderSchematic.java @@ -36,8 +36,12 @@ public final class CylinderSchematic extends CachedMaskSchematic { public boolean partOfMask(int x, int y, int z) { double da = Math.abs((this.getA(x, y) + 0.5) - this.centerA); double db = Math.abs((this.getB(y, z) + 0.5) - this.centerB); - return !this.outside(da, db) - && (filled || outside(da + 1, db) || outside(da, db + 1)); + if (this.outside(da, db)) { + return false; + } + return filled + || this.outside(da + 1, db) + || this.outside(da, db + 1); } private boolean outside(double da, double db) { diff --git a/src/api/java/baritone/api/schematic/SphereSchematic.java b/src/api/java/baritone/api/schematic/SphereSchematic.java index 987b87198..074e6ec51 100644 --- a/src/api/java/baritone/api/schematic/SphereSchematic.java +++ b/src/api/java/baritone/api/schematic/SphereSchematic.java @@ -37,11 +37,16 @@ public final class SphereSchematic extends CachedMaskSchematic { double dx = Math.abs((x + 0.5) - this.centerX); double dy = Math.abs((y + 0.5) - this.centerY); double dz = Math.abs((z + 0.5) - this.centerZ); - return !this.outside(dx, dy, dz) - && (filled || outside(dx + 1, dy, dz) || outside(dx, dy + 1, dz) || outside(dx, dy, dz + 1)); + if (this.outside(dx, dy, dz)) { + return false; + } + return filled + || this.outside(dx + 1, dy, dz) + || this.outside(dx, dy + 1, dz) + || this.outside(dx, dy, dz + 1); } - private boolean outside(double dx,double dy, double dz) { + private boolean outside(double dx, double dy, double dz) { return dx * dx / this.radiusSqX + dy * dy / this.radiusSqY + dz * dz / this.radiusSqZ > 1; } }); From 9729e63d980ace7038f2a79f78805b1fa21cc6c9 Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 9 Jun 2023 17:25:29 -0500 Subject: [PATCH 052/405] Create and utilize new `Mask` type Added factory method to `MaskSchematic` for creation using a `Mask` Sort-of mocks the schematic structure, without the block states ofc --- .../api/schematic/CachedMaskSchematic.java | 53 -------------- .../api/schematic/CylinderSchematic.java | 60 ---------------- .../baritone/api/schematic/MaskSchematic.java | 11 +++ .../api/schematic/SphereSchematic.java | 54 --------------- .../api/schematic/mask/AbstractMask.java | 49 +++++++++++++ .../baritone/api/schematic/mask/Mask.java | 41 +++++++++++ .../api/schematic/mask/PreComputedMask.java | 44 ++++++++++++ .../api/schematic/mask/StaticMask.java | 62 +++++++++++++++++ .../schematic/mask/shape/CylinderMask.java | 69 +++++++++++++++++++ .../api/schematic/mask/shape/SphereMask.java | 64 +++++++++++++++++ .../baritone/command/defaults/SelCommand.java | 10 +-- 11 files changed, 346 insertions(+), 171 deletions(-) delete mode 100644 src/api/java/baritone/api/schematic/CachedMaskSchematic.java delete mode 100644 src/api/java/baritone/api/schematic/CylinderSchematic.java delete mode 100644 src/api/java/baritone/api/schematic/SphereSchematic.java create mode 100644 src/api/java/baritone/api/schematic/mask/AbstractMask.java create mode 100644 src/api/java/baritone/api/schematic/mask/Mask.java create mode 100644 src/api/java/baritone/api/schematic/mask/PreComputedMask.java create mode 100644 src/api/java/baritone/api/schematic/mask/StaticMask.java create mode 100644 src/api/java/baritone/api/schematic/mask/shape/CylinderMask.java create mode 100644 src/api/java/baritone/api/schematic/mask/shape/SphereMask.java diff --git a/src/api/java/baritone/api/schematic/CachedMaskSchematic.java b/src/api/java/baritone/api/schematic/CachedMaskSchematic.java deleted file mode 100644 index 19bcf4e3a..000000000 --- a/src/api/java/baritone/api/schematic/CachedMaskSchematic.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of Baritone. - * - * Baritone is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Baritone is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Baritone. If not, see . - */ - -package baritone.api.schematic; - -import net.minecraft.block.state.IBlockState; - -/** - * @author Brady - */ -public abstract class CachedMaskSchematic extends MaskSchematic { - - /** - * Mask array with {@code y,z,x} indexing - */ - private final boolean[][][] mask; - - public CachedMaskSchematic(ISchematic schematic, StaticMaskFunction maskFunction) { - super(schematic); - this.mask = new boolean[schematic.heightY()][schematic.lengthZ()][schematic.widthX()]; - for (int y = 0; y < schematic.heightY(); y++) { - for (int z = 0; z < schematic.lengthZ(); z++) { - for (int x = 0; x < schematic.widthX(); x++) { - this.mask[y][z][x] = maskFunction.partOfMask(x, y, z); - } - } - } - } - - @Override - protected final boolean partOfMask(int x, int y, int z, IBlockState currentState) { - return this.mask[y][z][x]; - } - - @FunctionalInterface - public interface StaticMaskFunction { - boolean partOfMask(int x, int y, int z); - } -} diff --git a/src/api/java/baritone/api/schematic/CylinderSchematic.java b/src/api/java/baritone/api/schematic/CylinderSchematic.java deleted file mode 100644 index 29b5aa5b3..000000000 --- a/src/api/java/baritone/api/schematic/CylinderSchematic.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of Baritone. - * - * Baritone is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Baritone is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Baritone. If not, see . - */ - -package baritone.api.schematic; - -import net.minecraft.util.EnumFacing; - -/** - * @author Brady - */ -public final class CylinderSchematic extends CachedMaskSchematic { - - public CylinderSchematic(ISchematic schematic, boolean filled, EnumFacing.Axis alignment) { - super(schematic, new StaticMaskFunction() { - - private final double centerA = this.getA(schematic.widthX(), schematic.heightY()) / 2.0; - private final double centerB = this.getB(schematic.heightY(), schematic.lengthZ()) / 2.0; - private final double radiusSqA = this.centerA * this.centerA; - private final double radiusSqB = this.centerB * this.centerB; - - @Override - public boolean partOfMask(int x, int y, int z) { - double da = Math.abs((this.getA(x, y) + 0.5) - this.centerA); - double db = Math.abs((this.getB(y, z) + 0.5) - this.centerB); - if (this.outside(da, db)) { - return false; - } - return filled - || this.outside(da + 1, db) - || this.outside(da, db + 1); - } - - private boolean outside(double da, double db) { - return da * da / this.radiusSqA + db * db / this.radiusSqB > 1; - } - - private int getA(int x, int y) { - return alignment == EnumFacing.Axis.X ? y : x; - } - - private int getB(int y, int z) { - return alignment == EnumFacing.Axis.Z ? y : z; - } - }); - } -} diff --git a/src/api/java/baritone/api/schematic/MaskSchematic.java b/src/api/java/baritone/api/schematic/MaskSchematic.java index 229f58d5b..2853c6e58 100644 --- a/src/api/java/baritone/api/schematic/MaskSchematic.java +++ b/src/api/java/baritone/api/schematic/MaskSchematic.java @@ -17,6 +17,7 @@ package baritone.api.schematic; +import baritone.api.schematic.mask.Mask; import net.minecraft.block.state.IBlockState; import java.util.List; @@ -41,4 +42,14 @@ public abstract class MaskSchematic extends AbstractSchematic { public IBlockState desiredState(int x, int y, int z, IBlockState current, List approxPlaceable) { return schematic.desiredState(x, y, z, current, approxPlaceable); } + + public static MaskSchematic create(ISchematic schematic, Mask function) { + return new MaskSchematic(schematic) { + + @Override + protected boolean partOfMask(int x, int y, int z, IBlockState currentState) { + return function.partOfMask(x, y, z, currentState); + } + }; + } } diff --git a/src/api/java/baritone/api/schematic/SphereSchematic.java b/src/api/java/baritone/api/schematic/SphereSchematic.java deleted file mode 100644 index 074e6ec51..000000000 --- a/src/api/java/baritone/api/schematic/SphereSchematic.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of Baritone. - * - * Baritone is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Baritone is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Baritone. If not, see . - */ - -package baritone.api.schematic; - -/** - * @author Brady - */ -public final class SphereSchematic extends CachedMaskSchematic { - - public SphereSchematic(ISchematic schematic, boolean filled) { - super(schematic, new StaticMaskFunction() { - - private final double centerX = schematic.widthX() / 2.0; - private final double centerY = schematic.heightY() / 2.0; - private final double centerZ = schematic.lengthZ() / 2.0; - private final double radiusSqX = this.centerX * this.centerX; - private final double radiusSqY = this.centerY * this.centerY; - private final double radiusSqZ = this.centerZ * this.centerZ; - - @Override - public boolean partOfMask(int x, int y, int z) { - double dx = Math.abs((x + 0.5) - this.centerX); - double dy = Math.abs((y + 0.5) - this.centerY); - double dz = Math.abs((z + 0.5) - this.centerZ); - if (this.outside(dx, dy, dz)) { - return false; - } - return filled - || this.outside(dx + 1, dy, dz) - || this.outside(dx, dy + 1, dz) - || this.outside(dx, dy, dz + 1); - } - - private boolean outside(double dx, double dy, double dz) { - return dx * dx / this.radiusSqX + dy * dy / this.radiusSqY + dz * dz / this.radiusSqZ > 1; - } - }); - } -} diff --git a/src/api/java/baritone/api/schematic/mask/AbstractMask.java b/src/api/java/baritone/api/schematic/mask/AbstractMask.java new file mode 100644 index 000000000..ce92af0ec --- /dev/null +++ b/src/api/java/baritone/api/schematic/mask/AbstractMask.java @@ -0,0 +1,49 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.api.schematic.mask; + +/** + * @author Brady + */ +public abstract class AbstractMask implements Mask { + + private final int widthX; + private final int heightY; + private final int lengthZ; + + public AbstractMask(int widthX, int heightY, int lengthZ) { + this.widthX = widthX; + this.heightY = heightY; + this.lengthZ = lengthZ; + } + + @Override + public int widthX() { + return this.widthX; + } + + @Override + public int heightY() { + return this.heightY; + } + + @Override + public int lengthZ() { + return this.lengthZ; + } +} diff --git a/src/api/java/baritone/api/schematic/mask/Mask.java b/src/api/java/baritone/api/schematic/mask/Mask.java new file mode 100644 index 000000000..540c2cee1 --- /dev/null +++ b/src/api/java/baritone/api/schematic/mask/Mask.java @@ -0,0 +1,41 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.api.schematic.mask; + +import net.minecraft.block.state.IBlockState; + +/** + * @author Brady + */ +public interface Mask { + + /** + * @param x The relative x position of the block + * @param y The relative y position of the block + * @param z The relative z position of the block + * @param currentState The current state of that block in the world, may be {@code null} + * @return Whether the given position is included in this mask + */ + boolean partOfMask(int x, int y, int z, IBlockState currentState); + + int widthX(); + + int heightY(); + + int lengthZ(); +} diff --git a/src/api/java/baritone/api/schematic/mask/PreComputedMask.java b/src/api/java/baritone/api/schematic/mask/PreComputedMask.java new file mode 100644 index 000000000..aed26cc94 --- /dev/null +++ b/src/api/java/baritone/api/schematic/mask/PreComputedMask.java @@ -0,0 +1,44 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.api.schematic.mask; + +/** + * @author Brady + */ +final class PreComputedMask extends AbstractMask implements StaticMask { + + private final boolean[][][] mask; + + public PreComputedMask(StaticMask mask) { + super(mask.widthX(), mask.heightY(), mask.lengthZ()); + + this.mask = new boolean[this.heightY()][this.lengthZ()][this.widthX()]; + for (int y = 0; y < this.heightY(); y++) { + for (int z = 0; z < this.lengthZ(); z++) { + for (int x = 0; x < this.widthX(); x++) { + this.mask[y][z][x] = mask.partOfMask(x, y, z); + } + } + } + } + + @Override + public boolean partOfMask(int x, int y, int z) { + return this.mask[y][z][x]; + } +} diff --git a/src/api/java/baritone/api/schematic/mask/StaticMask.java b/src/api/java/baritone/api/schematic/mask/StaticMask.java new file mode 100644 index 000000000..ef50a65cc --- /dev/null +++ b/src/api/java/baritone/api/schematic/mask/StaticMask.java @@ -0,0 +1,62 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.api.schematic.mask; + +import net.minecraft.block.state.IBlockState; + +/** + * A mask that is context-free. In other words, it doesn't require the current block state to determine if a relative + * position is a part of the mask. + * + * @author Brady + */ +public interface StaticMask extends Mask { + + /** + * Determines if a given relative coordinate is included in this mask, without the need for the current block state. + * + * @param x The relative x position of the block + * @param y The relative y position of the block + * @param z The relative z position of the block + * @return Whether the given position is included in this mask + */ + boolean partOfMask(int x, int y, int z); + + /** + * Implements the parent {@link Mask#partOfMask partOfMask function} by calling the static function + * provided in this functional interface without needing the {@link IBlockState} argument. This {@code default} + * implementation should NOT be overriden. + * + * @param x The relative x position of the block + * @param y The relative y position of the block + * @param z The relative z position of the block + * @param currentState The current state of that block in the world, may be {@code null} + * @return Whether the given position is included in this mask + */ + @Override + default boolean partOfMask(int x, int y, int z, IBlockState currentState) { + return this.partOfMask(x, y, z); + } + + /** + * Returns a pre-computed mask using {@code this} function, with the specified size parameters. + */ + default StaticMask compute() { + return new PreComputedMask(this); + } +} diff --git a/src/api/java/baritone/api/schematic/mask/shape/CylinderMask.java b/src/api/java/baritone/api/schematic/mask/shape/CylinderMask.java new file mode 100644 index 000000000..71b0d43c9 --- /dev/null +++ b/src/api/java/baritone/api/schematic/mask/shape/CylinderMask.java @@ -0,0 +1,69 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.api.schematic.mask.shape; + +import baritone.api.schematic.mask.AbstractMask; +import baritone.api.schematic.mask.StaticMask; +import net.minecraft.util.EnumFacing; + +/** + * @author Brady + */ +public final class CylinderMask extends AbstractMask implements StaticMask { + + private final double centerA; + private final double centerB; + private final double radiusSqA; + private final double radiusSqB; + private final boolean filled; + private final EnumFacing.Axis alignment; + + public CylinderMask(int widthX, int heightY, int lengthZ, boolean filled, EnumFacing.Axis alignment) { + super(widthX, heightY, lengthZ); + this.centerA = this.getA(widthX, heightY) / 2.0; + this.centerB = this.getB(heightY, lengthZ) / 2.0; + this.radiusSqA = (this.centerA - 1) * (this.centerA - 1); + this.radiusSqB = (this.centerB - 1) * (this.centerB - 1); + this.filled = filled; + this.alignment = alignment; + } + + @Override + public boolean partOfMask(int x, int y, int z) { + double da = Math.abs((this.getA(x, y) + 0.5) - this.centerA); + double db = Math.abs((this.getB(y, z) + 0.5) - this.centerB); + if (this.outside(da, db)) { + return false; + } + return this.filled + || this.outside(da + 1, db) + || this.outside(da, db + 1); + } + + private boolean outside(double da, double db) { + return da * da / this.radiusSqA + db * db / this.radiusSqB > 1; + } + + private int getA(int x, int y) { + return this.alignment == EnumFacing.Axis.X ? y : x; + } + + private int getB(int y, int z) { + return this.alignment == EnumFacing.Axis.Z ? y : z; + } +} diff --git a/src/api/java/baritone/api/schematic/mask/shape/SphereMask.java b/src/api/java/baritone/api/schematic/mask/shape/SphereMask.java new file mode 100644 index 000000000..d805c98a8 --- /dev/null +++ b/src/api/java/baritone/api/schematic/mask/shape/SphereMask.java @@ -0,0 +1,64 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.api.schematic.mask.shape; + +import baritone.api.schematic.mask.AbstractMask; +import baritone.api.schematic.mask.StaticMask; + +/** + * @author Brady + */ +public final class SphereMask extends AbstractMask implements StaticMask { + + private final double centerX; + private final double centerY; + private final double centerZ; + private final double radiusSqX; + private final double radiusSqY; + private final double radiusSqZ; + private final boolean filled; + + public SphereMask(int widthX, int heightY, int lengthZ, boolean filled) { + super(widthX, heightY, lengthZ); + this.centerX = widthX / 2.0; + this.centerY = heightY / 2.0; + this.centerZ = lengthZ / 2.0; + this.radiusSqX = this.centerX * this.centerX; + this.radiusSqY = this.centerY * this.centerY; + this.radiusSqZ = this.centerZ * this.centerZ; + this.filled = filled; + } + + @Override + public boolean partOfMask(int x, int y, int z) { + double dx = Math.abs((x + 0.5) - this.centerX); + double dy = Math.abs((y + 0.5) - this.centerY); + double dz = Math.abs((z + 0.5) - this.centerZ); + if (this.outside(dx, dy, dz)) { + return false; + } + return this.filled + || this.outside(dx + 1, dy, dz) + || this.outside(dx, dy + 1, dz) + || this.outside(dx, dy, dz + 1); + } + + private boolean outside(double dx, double dy, double dz) { + return dx * dx / this.radiusSqX + dy * dy / this.radiusSqY + dz * dz / this.radiusSqZ > 1; + } +} diff --git a/src/main/java/baritone/command/defaults/SelCommand.java b/src/main/java/baritone/command/defaults/SelCommand.java index 72c5cd1c0..e1d2082ff 100644 --- a/src/main/java/baritone/command/defaults/SelCommand.java +++ b/src/main/java/baritone/command/defaults/SelCommand.java @@ -32,6 +32,8 @@ import baritone.api.command.helpers.TabCompleteHelper; import baritone.api.event.events.RenderEvent; import baritone.api.event.listener.AbstractGameEventListener; import baritone.api.schematic.*; +import baritone.api.schematic.mask.shape.CylinderMask; +import baritone.api.schematic.mask.shape.SphereMask; import baritone.api.selection.ISelection; import baritone.api.selection.ISelectionManager; import baritone.api.utils.BetterBlockPos; @@ -173,13 +175,13 @@ public class SelCommand extends Command { case REPLACE: return new ReplaceSchematic(fill, replaces); case SPHERE: - return new SphereSchematic(fill, true); + return MaskSchematic.create(fill, new SphereMask(size.getX(), size.getY(), size.getZ(), true).compute()); case HSPHERE: - return new SphereSchematic(fill, false); + return MaskSchematic.create(fill, new SphereMask(size.getX(), size.getY(), size.getZ(), false).compute()); case CYLINDER: - return new CylinderSchematic(fill, true, alignment); + return MaskSchematic.create(fill, new CylinderMask(size.getX(), size.getY(), size.getZ(), true, alignment).compute()); case HCYLINDER: - return new CylinderSchematic(fill, false, alignment); + return MaskSchematic.create(fill, new CylinderMask(size.getX(), size.getY(), size.getZ(), false, alignment).compute()); default: // Silent fail return fill; From 705a5a0712ccadac53ac6e132128bce48f6e29e0 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 11 Jun 2023 00:33:35 -0700 Subject: [PATCH 053/405] elytra prototype mvp --- src/api/java/baritone/api/Settings.java | 4 + src/main/java/baritone/Baritone.java | 2 + src/main/java/baritone/Elytra.java | 274 ++++++++++++++++++ .../java/baritone/utils/PathRenderer.java | 22 +- 4 files changed, 293 insertions(+), 9 deletions(-) create mode 100644 src/main/java/baritone/Elytra.java diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index b7a4e41a4..5463f3163 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -48,6 +48,10 @@ import java.util.function.Consumer; */ public final class Settings { + public final Setting elytraSimulationTicks = new Setting<>(20); + public final Setting elytraPitchRange = new Setting<>(25); + public final Setting elytraFireworkSpeed = new Setting<>(0.425); + /** * Allow Baritone to break blocks */ diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index 61db54211..a85155bcf 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -88,6 +88,7 @@ public class Baritone implements IBaritone { private IPlayerContext playerContext; private WorldProvider worldProvider; + public Elytra elytra; public BlockStateInterface bsi; @@ -100,6 +101,7 @@ public class Baritone implements IBaritone { { // the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist pathingBehavior = new PathingBehavior(this); + elytra = new Elytra(this); lookBehavior = new LookBehavior(this); inventoryBehavior = new InventoryBehavior(this); inputOverrideHandler = new InputOverrideHandler(this); diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java new file mode 100644 index 000000000..ac253868b --- /dev/null +++ b/src/main/java/baritone/Elytra.java @@ -0,0 +1,274 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone; + +import baritone.api.event.events.TickEvent; +import baritone.api.utils.BetterBlockPos; +import baritone.api.utils.Helper; +import baritone.api.utils.Rotation; +import baritone.api.utils.RotationUtils; +import baritone.behavior.Behavior; +import baritone.utils.BlockStateInterface; +import net.minecraft.block.material.Material; +import net.minecraft.entity.item.EntityFireworkRocket; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Elytra extends Behavior implements Helper { + + public static List path = new ArrayList<>(); + + static { + + try { + DataInputStream in = new DataInputStream(new FileInputStream(new File("/Users/leijurv/Dropbox/nether-pathfinder/build/test"))); + int count = in.readInt(); + System.out.println("Count: " + count); + for (int i = 0; i < count; i++) { + path.add(new BetterBlockPos((int) in.readDouble(), (int) in.readDouble(), (int) in.readDouble())); + } + removeBacktracks(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public int playerNear; + public int goingTo; + public int sinceFirework; + public BlockPos goal; + + protected Elytra(Baritone baritone) { + super(baritone); + } + + + @Override + public void onTick(TickEvent event) { + if (event.getType() == TickEvent.Type.OUT) { + return; + } + fixNearPlayer(); + baritone.getInputOverrideHandler().clearAllKeys(); + + if (ctx.player().isElytraFlying()) { + Vec3d start = ctx.playerFeetAsVec(); + boolean firework = firework(); + sinceFirework++; + if (!firework + && sinceFirework > 10 + && ctx.player().posY < path.get(goingTo).y + 5 // don't firework if trying to descend + && (ctx.player().posY < path.get(goingTo).y - 5 || ctx.playerFeetAsVec().distanceTo(new Vec3d(path.get(goingTo).x, ctx.player().posY, path.get(goingTo).z)) > 5) // UGH!!!!!!! + && new Vec3d(ctx.player().motionX, ctx.player().posY < path.get(goingTo).y ? Math.max(0, ctx.player().motionY) : ctx.player().motionY, ctx.player().motionZ).length() < Baritone.settings().elytraFireworkSpeed.value // ignore y component if we are BOTH below where we want to be AND descending + ) { + logDirect("firework"); + ctx.playerController().processRightClick(ctx.player(), ctx.world(), EnumHand.MAIN_HAND); + sinceFirework = 0; + } + long t = System.currentTimeMillis(); + for (int relaxation = 0; relaxation < 3; relaxation++) { // try for a strict solution first, then relax more and more (if we're in a corner or near some blocks, it will have to relax its constraints a bit) + int[] heights = firework ? new int[]{20, 10, 5, 0} : new int[]{0}; // attempt to gain height, if we can, so as not to waste the boost + boolean requireClear = relaxation == 0; + int steps = relaxation < 2 ? Baritone.settings().elytraSimulationTicks.value : 3; + int lookahead = relaxation == 0 ? 2 : 3; // ideally this would be expressed as a distance in blocks, rather than a number of voxel steps + for (int dy : heights) { + for (int i = Math.min(playerNear + 20, path.size()); i >= playerNear; i--) { + Vec3d dest = new Vec3d(path.get(i)).add(0, dy, 0); + if (dy != 0 && (i + lookahead >= path.size() || (!clearView(dest, new Vec3d(path.get(i + lookahead)).add(0, dy, 0)) || !clearView(dest, new Vec3d(path.get(i + lookahead)))))) { + // aka: don't go upwards if doing so would prevent us from being able to see the next position **OR** the modified next position + continue; + } + if (requireClear ? isClear(start, dest) : clearView(start, dest)) { + Rotation rot = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()); + ctx.player().rotationYaw = rot.getYaw(); + long a = System.currentTimeMillis(); + Float pitch = solvePitch(dest.subtract(start), steps); + if (pitch == null) { + continue; + } + long b = System.currentTimeMillis(); + ctx.player().rotationPitch = pitch; + System.out.println("Solved pitch in " + (b - a) + " total time " + (b - t)); + goingTo = i; + goal = path.get(i).add(0, dy, 0); + return; + } + } + } + } + logDirect("no pitch solution, probably gonna crash in a few ticks LOL!!!"); + } + } + + private boolean firework() { + return ctx.world().loadedEntityList.stream().anyMatch(x -> (x instanceof EntityFireworkRocket) && ((EntityFireworkRocket) x).isAttachedToEntity()); + } + + private boolean isClear(Vec3d start, Vec3d dest) { + Vec3d perpendicular = dest.subtract(start).crossProduct(new Vec3d(0, 1, 0)).normalize(); + return clearView(start, dest) + && clearView(start.add(0, 2, 0), dest.add(0, 2, 0)) + && clearView(start.add(0, -2, 0), dest.add(0, -2, 0)) + && clearView(start.add(perpendicular), dest.add(perpendicular)) + && clearView(start.subtract(perpendicular), dest.subtract(perpendicular)); + } + + private boolean clearView(Vec3d start, Vec3d dest) { + RayTraceResult result = ctx.world().rayTraceBlocks(start, dest, true, false, true); + return result == null || result.typeOfHit == RayTraceResult.Type.MISS; + } + + private Float solvePitch(Vec3d goalDirection, int steps) { + // we are at a certain velocity, but we have a target velocity + // what pitch would get us closest to our target velocity? + // yaw is easy so we only care about pitch + + goalDirection = goalDirection.normalize(); + Rotation good = RotationUtils.calcRotationFromVec3d(new Vec3d(0, 0, 0), goalDirection, ctx.playerRotations()); // lazy lol + + boolean firework = firework(); + Float bestPitch = null; + double bestDot = Double.NEGATIVE_INFINITY; + Vec3d motion = new Vec3d(ctx.player().motionX, ctx.player().motionY, ctx.player().motionZ); + BlockStateInterface bsi = new BlockStateInterface(ctx); + outer: + for (float pitch = Math.max(good.getPitch() - Baritone.settings().elytraPitchRange.value, -89); pitch < Math.min(good.getPitch() + Baritone.settings().elytraPitchRange.value, 89); pitch++) { + Vec3d stepped = motion; + Vec3d totalMotion = new Vec3d(0, 0, 0); + for (int i = 0; i < steps; i++) { + stepped = step(stepped, pitch, good.getYaw(), firework); + totalMotion = totalMotion.add(stepped); + + Vec3d actualPosition = ctx.playerFeetAsVec().add(totalMotion); + if (bsi.get0(MathHelper.floor(actualPosition.x), MathHelper.floor(actualPosition.y), MathHelper.floor(actualPosition.z)).getMaterial() != Material.AIR) { + continue outer; + } + if (bsi.get0(MathHelper.floor(actualPosition.x), MathHelper.floor(actualPosition.y) + 1, MathHelper.floor(actualPosition.z)).getMaterial() != Material.AIR) { + continue outer; + } + } + double directionalGoodness = goalDirection.dotProduct(totalMotion.normalize()); + // tried to incorporate a "speedGoodness" but it kept making it do stupid stuff (aka always losing altitude) + double goodness = directionalGoodness; + if (goodness > bestDot) { + bestDot = goodness; + bestPitch = pitch; + } + } + return bestPitch; + } + + public static Vec3d step(Vec3d motion, float rotationPitch, float rotationYaw, boolean firework) { + double motionX = motion.x; + double motionY = motion.y; + double motionZ = motion.z; + float flatZ = MathHelper.cos(-rotationYaw * 0.017453292F - (float) Math.PI); // 0.174... is Math.PI / 180 + float flatX = MathHelper.sin(-rotationYaw * 0.017453292F - (float) Math.PI); + float pitchBase = -MathHelper.cos(-rotationPitch * 0.017453292F); + float pitchHeight = MathHelper.sin(-rotationPitch * 0.017453292F); + Vec3d lookDirection = new Vec3d(flatX * pitchBase, pitchHeight, flatZ * pitchBase); + float pitchRadians = rotationPitch * 0.017453292F; + double pitchBase2 = Math.sqrt(lookDirection.x * lookDirection.x + lookDirection.z * lookDirection.z); + double flatMotion = Math.sqrt(motionX * motionX + motionZ * motionZ); + double thisIsAlwaysOne = lookDirection.length(); + float pitchBase3 = MathHelper.cos(pitchRadians); + //System.out.println("always the same lol " + -pitchBase + " " + pitchBase3); + //System.out.println("always the same lol " + Math.abs(pitchBase3) + " " + pitchBase2); + //System.out.println("always 1 lol " + thisIsAlwaysOne); + pitchBase3 = (float) ((double) pitchBase3 * (double) pitchBase3 * Math.min(1, thisIsAlwaysOne / 0.4)); + motionY += -0.08 + (double) pitchBase3 * 0.06; + if (motionY < 0 && pitchBase2 > 0) { + double speedModifier = motionY * -0.1 * (double) pitchBase3; + motionY += speedModifier; + motionX += lookDirection.x * speedModifier / pitchBase2; + motionZ += lookDirection.z * speedModifier / pitchBase2; + } + if (pitchRadians < 0) { // if you are looking down (below level) + double anotherSpeedModifier = flatMotion * (double) (-MathHelper.sin(pitchRadians)) * 0.04; + motionY += anotherSpeedModifier * 3.2; + motionX -= lookDirection.x * anotherSpeedModifier / pitchBase2; + motionZ -= lookDirection.z * anotherSpeedModifier / pitchBase2; + } + if (pitchBase2 > 0) { // this is always true unless you are looking literally straight up (let's just say the bot will never do that) + motionX += (lookDirection.x / pitchBase2 * flatMotion - motionX) * 0.1; + motionZ += (lookDirection.z / pitchBase2 * flatMotion - motionZ) * 0.1; + } + motionX *= 0.99; + motionY *= 0.98; + motionZ *= 0.99; + //System.out.println(motionX + " " + motionY + " " + motionZ); + if (firework) { + motionX += lookDirection.x * 0.1 + (lookDirection.x * 1.5 - motionX) * 0.5; + motionY += lookDirection.y * 0.1 + (lookDirection.y * 1.5 - motionY) * 0.5; + motionZ += lookDirection.z * 0.1 + (lookDirection.z * 1.5 - motionZ) * 0.5; + } + return new Vec3d(motionX, motionY, motionZ); + } + + public void fixNearPlayer() { + BetterBlockPos pos = ctx.playerFeet(); + for (int i = playerNear; i >= Math.max(playerNear - 1000, 0); i -= 10) { + if (path.get(i).distanceSq(pos) < path.get(playerNear).distanceSq(pos)) { + playerNear = i; // intentional: this changes the bound of the loop + } + } + for (int i = playerNear; i < Math.min(playerNear + 1000, path.size()); i += 10) { + if (path.get(i).distanceSq(pos) < path.get(playerNear).distanceSq(pos)) { + playerNear = i; // intentional: this changes the bound of the loop + } + } + for (int i = playerNear; i >= Math.max(playerNear - 50, 0); i--) { + if (path.get(i).distanceSq(pos) < path.get(playerNear).distanceSq(pos)) { + playerNear = i; // intentional: this changes the bound of the loop + } + } + for (int i = playerNear; i < Math.min(playerNear + 50, path.size()); i++) { + if (path.get(i).distanceSq(pos) < path.get(playerNear).distanceSq(pos)) { + playerNear = i; // intentional: this changes the bound of the loop + } + } + //System.out.println(playerNear); + } + + public static void removeBacktracks() { + Map positionFirstSeen = new HashMap<>(); + for (int i = 0; i < path.size(); i++) { + BetterBlockPos pos = path.get(i); + if (positionFirstSeen.containsKey(pos)) { + int j = positionFirstSeen.get(pos); + while (i > j) { + path.remove(i); + i--; + } + } else { + positionFirstSeen.put(pos, i); + } + } + } +} diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index 2fe224706..828479a5d 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -17,9 +17,9 @@ package baritone.utils; +import baritone.Elytra; import baritone.api.BaritoneAPI; import baritone.api.event.events.RenderEvent; -import baritone.api.pathing.calc.IPath; import baritone.api.pathing.goals.*; import baritone.api.utils.BetterBlockPos; import baritone.api.utils.Helper; @@ -96,33 +96,37 @@ public final class PathRenderer implements IRenderer { // Render the current path, if there is one if (current != null && current.getPath() != null) { int renderBegin = Math.max(current.getPosition() - 3, 0); - drawPath(current.getPath(), renderBegin, settings.colorCurrentPath.value, settings.fadePath.value, 10, 20); + drawPath(current.getPath().positions(), renderBegin, settings.colorCurrentPath.value, settings.fadePath.value, 10, 20); } if (next != null && next.getPath() != null) { - drawPath(next.getPath(), 0, settings.colorNextPath.value, settings.fadePath.value, 10, 20); + drawPath(next.getPath().positions(), 0, settings.colorNextPath.value, settings.fadePath.value, 10, 20); + } + + drawPath(Elytra.path.subList(Math.max(behavior.baritone.elytra.playerNear - 30, 0), Math.min(behavior.baritone.elytra.playerNear + 30, Elytra.path.size())), 0, Color.RED, false, 0, 0); + if (behavior.baritone.elytra.goal != null) { + drawDankLitGoalBox(renderView, new GoalBlock(behavior.baritone.elytra.goal), partialTicks, Color.GREEN); } // If there is a path calculation currently running, render the path calculation process behavior.getInProgress().ifPresent(currentlyRunning -> { currentlyRunning.bestPathSoFar().ifPresent(p -> { - drawPath(p, 0, settings.colorBestPathSoFar.value, settings.fadePath.value, 10, 20); + drawPath(p.positions(), 0, settings.colorBestPathSoFar.value, settings.fadePath.value, 10, 20); }); currentlyRunning.pathToMostRecentNodeConsidered().ifPresent(mr -> { - drawPath(mr, 0, settings.colorMostRecentConsidered.value, settings.fadePath.value, 10, 20); + drawPath(mr.positions(), 0, settings.colorMostRecentConsidered.value, settings.fadePath.value, 10, 20); drawManySelectionBoxes(renderView, Collections.singletonList(mr.getDest()), settings.colorMostRecentConsidered.value); }); }); } - public static void drawPath(IPath path, int startIndex, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0) { + public static void drawPath(List positions, int startIndex, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0) { IRenderer.startLines(color, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); int fadeStart = fadeStart0 + startIndex; int fadeEnd = fadeEnd0 + startIndex; - List positions = path.positions(); for (int i = startIndex, next; i < positions.size() - 1; i = next) { BetterBlockPos start = positions.get(i); BetterBlockPos end = positions.get(next = i + 1); @@ -131,12 +135,12 @@ public final class PathRenderer implements IRenderer { int dirY = end.y - start.y; int dirZ = end.z - start.z; - while (next + 1 < positions.size() && (!fadeOut || next + 1 < fadeStart) && + /*while (next + 1 < positions.size() && (!fadeOut || next + 1 < fadeStart) && (dirX == positions.get(next + 1).x - end.x && dirY == positions.get(next + 1).y - end.y && dirZ == positions.get(next + 1).z - end.z)) { end = positions.get(++next); - } + }*/ if (fadeOut) { float alpha; From 94d757104b027c121ca2bc39f658b09e10ea28a5 Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 11 Jun 2023 11:24:31 -0500 Subject: [PATCH 054/405] Clean ups --- .../java/baritone/command/defaults/SelCommand.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/baritone/command/defaults/SelCommand.java b/src/main/java/baritone/command/defaults/SelCommand.java index e1d2082ff..0a11c86a8 100644 --- a/src/main/java/baritone/command/defaults/SelCommand.java +++ b/src/main/java/baritone/command/defaults/SelCommand.java @@ -167,6 +167,10 @@ public class SelCommand extends Command { // Java 8 so no switch expressions 😿 UnaryOperator create = fill -> { + final int w = fill.widthX(); + final int h = fill.heightY(); + final int l = fill.lengthZ(); + switch (action) { case WALLS: return new WallsSchematic(fill); @@ -175,13 +179,13 @@ public class SelCommand extends Command { case REPLACE: return new ReplaceSchematic(fill, replaces); case SPHERE: - return MaskSchematic.create(fill, new SphereMask(size.getX(), size.getY(), size.getZ(), true).compute()); + return MaskSchematic.create(fill, new SphereMask(w, h, l, true).compute()); case HSPHERE: - return MaskSchematic.create(fill, new SphereMask(size.getX(), size.getY(), size.getZ(), false).compute()); + return MaskSchematic.create(fill, new SphereMask(w, h, l, false).compute()); case CYLINDER: - return MaskSchematic.create(fill, new CylinderMask(size.getX(), size.getY(), size.getZ(), true, alignment).compute()); + return MaskSchematic.create(fill, new CylinderMask(w, h, l, true, alignment).compute()); case HCYLINDER: - return MaskSchematic.create(fill, new CylinderMask(size.getX(), size.getY(), size.getZ(), false, alignment).compute()); + return MaskSchematic.create(fill, new CylinderMask(w, h, l, false, alignment).compute()); default: // Silent fail return fill; From ffd00080f256e216238c7887c8549fd8bd8ae40f Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 11 Jun 2023 11:27:51 -0500 Subject: [PATCH 055/405] Mask binary operators --- .../baritone/api/schematic/mask/Mask.java | 19 +++++ .../api/schematic/mask/StaticMask.java | 20 ++++++ .../mask/operator/BinaryOperatorMask.java | 71 +++++++++++++++++++ .../api/schematic/mask/operator/NotMask.java | 56 +++++++++++++++ .../api/utils/BooleanBinaryOperator.java | 27 +++++++ .../api/utils/BooleanBinaryOperators.java | 38 ++++++++++ 6 files changed, 231 insertions(+) create mode 100644 src/api/java/baritone/api/schematic/mask/operator/BinaryOperatorMask.java create mode 100644 src/api/java/baritone/api/schematic/mask/operator/NotMask.java create mode 100644 src/api/java/baritone/api/utils/BooleanBinaryOperator.java create mode 100644 src/api/java/baritone/api/utils/BooleanBinaryOperators.java diff --git a/src/api/java/baritone/api/schematic/mask/Mask.java b/src/api/java/baritone/api/schematic/mask/Mask.java index 540c2cee1..7df6f8f04 100644 --- a/src/api/java/baritone/api/schematic/mask/Mask.java +++ b/src/api/java/baritone/api/schematic/mask/Mask.java @@ -17,6 +17,9 @@ package baritone.api.schematic.mask; +import baritone.api.schematic.mask.operator.BinaryOperatorMask; +import baritone.api.schematic.mask.operator.NotMask; +import baritone.api.utils.BooleanBinaryOperators; import net.minecraft.block.state.IBlockState; /** @@ -38,4 +41,20 @@ public interface Mask { int heightY(); int lengthZ(); + + default Mask not() { + return new NotMask(this); + } + + default Mask union(Mask other) { + return new BinaryOperatorMask(this, other, BooleanBinaryOperators.OR); + } + + default Mask intersection(Mask other) { + return new BinaryOperatorMask(this, other, BooleanBinaryOperators.AND); + } + + default Mask xor(Mask other) { + return new BinaryOperatorMask(this, other, BooleanBinaryOperators.XOR); + } } diff --git a/src/api/java/baritone/api/schematic/mask/StaticMask.java b/src/api/java/baritone/api/schematic/mask/StaticMask.java index ef50a65cc..220a94828 100644 --- a/src/api/java/baritone/api/schematic/mask/StaticMask.java +++ b/src/api/java/baritone/api/schematic/mask/StaticMask.java @@ -17,6 +17,9 @@ package baritone.api.schematic.mask; +import baritone.api.schematic.mask.operator.BinaryOperatorMask; +import baritone.api.schematic.mask.operator.NotMask; +import baritone.api.utils.BooleanBinaryOperators; import net.minecraft.block.state.IBlockState; /** @@ -53,6 +56,23 @@ public interface StaticMask extends Mask { return this.partOfMask(x, y, z); } + @Override + default StaticMask not() { + return new NotMask.Static(this); + } + + default StaticMask union(StaticMask other) { + return new BinaryOperatorMask.Static(this, other, BooleanBinaryOperators.OR); + } + + default StaticMask intersection(StaticMask other) { + return new BinaryOperatorMask.Static(this, other, BooleanBinaryOperators.AND); + } + + default StaticMask xor(StaticMask other) { + return new BinaryOperatorMask.Static(this, other, BooleanBinaryOperators.XOR); + } + /** * Returns a pre-computed mask using {@code this} function, with the specified size parameters. */ diff --git a/src/api/java/baritone/api/schematic/mask/operator/BinaryOperatorMask.java b/src/api/java/baritone/api/schematic/mask/operator/BinaryOperatorMask.java new file mode 100644 index 000000000..e591c7873 --- /dev/null +++ b/src/api/java/baritone/api/schematic/mask/operator/BinaryOperatorMask.java @@ -0,0 +1,71 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.api.schematic.mask.operator; + +import baritone.api.schematic.mask.AbstractMask; +import baritone.api.schematic.mask.Mask; +import baritone.api.schematic.mask.StaticMask; +import baritone.api.utils.BooleanBinaryOperator; +import net.minecraft.block.state.IBlockState; + +/** + * @author Brady + */ +public final class BinaryOperatorMask extends AbstractMask { + + private final Mask a; + private final Mask b; + private final BooleanBinaryOperator operator; + + public BinaryOperatorMask(Mask a, Mask b, BooleanBinaryOperator operator) { + super(a.widthX(), a.heightY(), a.lengthZ()); + this.a = a; + this.b = b; + this.operator = operator; + } + + @Override + public boolean partOfMask(int x, int y, int z, IBlockState currentState) { + return this.operator.applyAsBoolean( + this.a.partOfMask(x, y, z, currentState), + this.b.partOfMask(x, y, z, currentState) + ); + } + + public static final class Static extends AbstractMask implements StaticMask { + + private final StaticMask a; + private final StaticMask b; + private final BooleanBinaryOperator operator; + + public Static(StaticMask a, StaticMask b, BooleanBinaryOperator operator) { + super(a.widthX(), a.heightY(), a.lengthZ()); + this.a = a; + this.b = b; + this.operator = operator; + } + + @Override + public boolean partOfMask(int x, int y, int z) { + return this.operator.applyAsBoolean( + this.a.partOfMask(x, y, z), + this.b.partOfMask(x, y, z) + ); + } + } +} diff --git a/src/api/java/baritone/api/schematic/mask/operator/NotMask.java b/src/api/java/baritone/api/schematic/mask/operator/NotMask.java new file mode 100644 index 000000000..f9f770b82 --- /dev/null +++ b/src/api/java/baritone/api/schematic/mask/operator/NotMask.java @@ -0,0 +1,56 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.api.schematic.mask.operator; + +import baritone.api.schematic.mask.AbstractMask; +import baritone.api.schematic.mask.Mask; +import baritone.api.schematic.mask.StaticMask; +import net.minecraft.block.state.IBlockState; + +/** + * @author Brady + */ +public final class NotMask extends AbstractMask { + + private final Mask source; + + public NotMask(Mask source) { + super(source.widthX(), source.heightY(), source.lengthZ()); + this.source = source; + } + + @Override + public boolean partOfMask(int x, int y, int z, IBlockState currentState) { + return !this.source.partOfMask(x, y, z, currentState); + } + + public static final class Static extends AbstractMask implements StaticMask { + + private final StaticMask source; + + public Static(StaticMask source) { + super(source.widthX(), source.heightY(), source.lengthZ()); + this.source = source; + } + + @Override + public boolean partOfMask(int x, int y, int z) { + return !this.source.partOfMask(x, y, z); + } + } +} diff --git a/src/api/java/baritone/api/utils/BooleanBinaryOperator.java b/src/api/java/baritone/api/utils/BooleanBinaryOperator.java new file mode 100644 index 000000000..cfb85e644 --- /dev/null +++ b/src/api/java/baritone/api/utils/BooleanBinaryOperator.java @@ -0,0 +1,27 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.api.utils; + +/** + * @author Brady + */ +@FunctionalInterface +public interface BooleanBinaryOperator { + + boolean applyAsBoolean(boolean a, boolean b); +} diff --git a/src/api/java/baritone/api/utils/BooleanBinaryOperators.java b/src/api/java/baritone/api/utils/BooleanBinaryOperators.java new file mode 100644 index 000000000..11605c965 --- /dev/null +++ b/src/api/java/baritone/api/utils/BooleanBinaryOperators.java @@ -0,0 +1,38 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.api.utils; + +/** + * @author Brady + */ +public enum BooleanBinaryOperators implements BooleanBinaryOperator { + OR((a, b) -> a || b), + AND((a, b) -> a && b), + XOR((a, b) -> a ^ b); + + private final BooleanBinaryOperator op; + + BooleanBinaryOperators(BooleanBinaryOperator op) { + this.op = op; + } + + @Override + public boolean applyAsBoolean(boolean a, boolean b) { + return this.op.applyAsBoolean(a, b); + } +} From 364ae87ef861dd12570a0db6081ad1d4f5d4a399 Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 11 Jun 2023 12:36:53 -0500 Subject: [PATCH 056/405] Add `blockFreeLook` setting --- src/api/java/baritone/api/Settings.java | 5 +++++ src/api/java/baritone/api/utils/Rotation.java | 8 +++++-- .../baritone/api/utils/RotationUtils.java | 6 +++-- .../java/baritone/behavior/LookBehavior.java | 22 ++++++++++++++----- .../pathing/movement/MovementHelper.java | 4 ++-- .../movement/movements/MovementDescend.java | 5 ++--- .../movement/movements/MovementPillar.java | 4 ++-- .../utils/player/PrimaryPlayerContext.java | 16 ++++++++++---- 8 files changed, 50 insertions(+), 20 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index b7a4e41a4..b49fce01b 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -723,6 +723,11 @@ public final class Settings { */ public final Setting freeLook = new Setting<>(true); + /** + * Break and place blocks without having to force the client-sided rotations + */ + public final Setting blockFreeLook = new Setting<>(true); + /** * Will cause some minor behavioral differences to ensure that Baritone works on anticheats. *

diff --git a/src/api/java/baritone/api/utils/Rotation.java b/src/api/java/baritone/api/utils/Rotation.java index 54f63ebfa..8dab287de 100644 --- a/src/api/java/baritone/api/utils/Rotation.java +++ b/src/api/java/baritone/api/utils/Rotation.java @@ -26,12 +26,12 @@ public class Rotation { /** * The yaw angle of this Rotation */ - private float yaw; + private final float yaw; /** * The pitch angle of this Rotation */ - private float pitch; + private final float pitch; public Rotation(float yaw, float pitch) { this.yaw = yaw; @@ -110,6 +110,10 @@ public class Rotation { ); } + public Rotation withPitch(float pitch) { + return new Rotation(this.yaw, pitch); + } + /** * Is really close to * diff --git a/src/api/java/baritone/api/utils/RotationUtils.java b/src/api/java/baritone/api/utils/RotationUtils.java index 39e68fd4f..7b30f4abb 100644 --- a/src/api/java/baritone/api/utils/RotationUtils.java +++ b/src/api/java/baritone/api/utils/RotationUtils.java @@ -162,7 +162,8 @@ public final class RotationUtils { public static Optional reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance, boolean wouldSneak) { IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(entity); - if (baritone.getPlayerContext().isLookingAt(pos)) { + IPlayerContext ctx = baritone.getPlayerContext(); + if (ctx.isLookingAt(pos)) { /* * why add 0.0001? * to indicate that we actually have a desired pitch @@ -173,7 +174,7 @@ public final class RotationUtils { * * or if you're a normal person literally all this does it ensure that we don't nudge the pitch to a normal level */ - Rotation hypothetical = new Rotation(entity.rotationYaw, entity.rotationPitch + 0.0001F); + Rotation hypothetical = ctx.playerRotations().add(new Rotation(0, 0.0001F)); if (wouldSneak) { // the concern here is: what if we're looking at it now, but as soon as we start sneaking we no longer are RayTraceResult result = RayTraceUtils.rayTraceTowards(entity, hypothetical, blockReachDistance, true); @@ -217,6 +218,7 @@ public final class RotationUtils { */ public static Optional reachableOffset(Entity entity, BlockPos pos, Vec3d offsetPos, double blockReachDistance, boolean wouldSneak) { Vec3d eyes = wouldSneak ? RayTraceUtils.inferSneakingEyePosition(entity) : entity.getPositionEyes(1.0F); + // TODO: pr/feature/blockFreeLook - Use playerRotations() here? Rotation rotation = calcRotationFromVec3d(eyes, offsetPos, new Rotation(entity.rotationYaw, entity.rotationPitch)); RayTraceResult result = RayTraceUtils.rayTraceTowards(entity, rotation, blockReachDistance, wouldSneak); //System.out.println(result); diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index 32e5c22f5..7db3da562 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -22,6 +22,7 @@ import baritone.api.Settings; import baritone.api.behavior.ILookBehavior; import baritone.api.event.events.PlayerUpdateEvent; import baritone.api.event.events.RotationMoveEvent; +import baritone.api.event.events.type.EventState; import baritone.api.utils.Rotation; public final class LookBehavior extends Behavior implements ILookBehavior { @@ -34,17 +35,19 @@ public final class LookBehavior extends Behavior implements ILookBehavior { */ private Rotation target; + private Rotation serverAngles; + /** * Whether or not rotations are currently being forced */ private boolean force; /** - * The last player yaw angle. Used when free looking + * The last player angles. Used when free looking * * @see Settings#freeLook */ - private float lastYaw; + private Rotation prevAngles; public LookBehavior(Baritone baritone) { super(baritone); @@ -53,11 +56,14 @@ public final class LookBehavior extends Behavior implements ILookBehavior { @Override public void updateTarget(Rotation target, boolean force) { this.target = target; - this.force = force || !Baritone.settings().freeLook.value; + this.force = !Baritone.settings().blockFreeLook.value && (force || !Baritone.settings().freeLook.value); } @Override public void onPlayerUpdate(PlayerUpdateEvent event) { + if (event.getState() == EventState.POST) { + this.serverAngles = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch); + } if (this.target == null) { return; } @@ -80,14 +86,16 @@ public final class LookBehavior extends Behavior implements ILookBehavior { this.target = null; } if (silent) { - this.lastYaw = ctx.player().rotationYaw; + this.prevAngles = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch); ctx.player().rotationYaw = this.target.getYaw(); + ctx.player().rotationPitch = this.target.getPitch(); } break; } case POST: { if (silent) { - ctx.player().rotationYaw = this.lastYaw; + ctx.player().rotationYaw = this.prevAngles.getYaw(); + ctx.player().rotationPitch = this.prevAngles.getPitch(); this.target = null; } break; @@ -103,6 +111,10 @@ public final class LookBehavior extends Behavior implements ILookBehavior { } } + public Rotation getEffectiveAngles() { + return this.serverAngles; + } + @Override public void onPlayerRotationMove(RotationMoveEvent event) { if (this.target != null) { diff --git a/src/main/java/baritone/pathing/movement/MovementHelper.java b/src/main/java/baritone/pathing/movement/MovementHelper.java index 575815ea2..b14b2d69c 100644 --- a/src/main/java/baritone/pathing/movement/MovementHelper.java +++ b/src/main/java/baritone/pathing/movement/MovementHelper.java @@ -599,9 +599,9 @@ public interface MovementHelper extends ActionCosts, Helper { static void moveTowards(IPlayerContext ctx, MovementState state, BlockPos pos) { state.setTarget(new MovementTarget( - new Rotation(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), + RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(pos), - ctx.playerRotations()).getYaw(), ctx.player().rotationPitch), + ctx.playerRotations()).withPitch(ctx.playerRotations().getPitch()), false )).setInput(Input.MOVE_FORWARD, true); } diff --git a/src/main/java/baritone/pathing/movement/movements/MovementDescend.java b/src/main/java/baritone/pathing/movement/movements/MovementDescend.java index d36843cdd..2d8180356 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementDescend.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementDescend.java @@ -234,11 +234,10 @@ public class MovementDescend extends Movement { if (safeMode()) { double destX = (src.getX() + 0.5) * 0.17 + (dest.getX() + 0.5) * 0.83; double destZ = (src.getZ() + 0.5) * 0.17 + (dest.getZ() + 0.5) * 0.83; - EntityPlayerSP player = ctx.player(); state.setTarget(new MovementState.MovementTarget( - new Rotation(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), + RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(destX, dest.getY(), destZ), - new Rotation(player.rotationYaw, player.rotationPitch)).getYaw(), player.rotationPitch), + ctx.playerRotations()).withPitch(ctx.playerRotations().getPitch()), false )).setInput(Input.MOVE_FORWARD, true); return state; diff --git a/src/main/java/baritone/pathing/movement/movements/MovementPillar.java b/src/main/java/baritone/pathing/movement/movements/MovementPillar.java index cfa9d9260..88f1e26ff 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementPillar.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementPillar.java @@ -190,9 +190,9 @@ public class MovementPillar extends Movement { boolean vine = fromDown.getBlock() == Blocks.VINE; Rotation rotation = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(positionToPlace), - new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch)); + ctx.playerRotations()); if (!ladder) { - state.setTarget(new MovementState.MovementTarget(new Rotation(ctx.player().rotationYaw, rotation.getPitch()), true)); + state.setTarget(new MovementState.MovementTarget(ctx.playerRotations().withPitch(rotation.getPitch()), true)); } boolean blockIsThere = MovementHelper.canWalkOn(ctx, src) || ladder; diff --git a/src/main/java/baritone/utils/player/PrimaryPlayerContext.java b/src/main/java/baritone/utils/player/PrimaryPlayerContext.java index 3cb498acd..cc35c156c 100644 --- a/src/main/java/baritone/utils/player/PrimaryPlayerContext.java +++ b/src/main/java/baritone/utils/player/PrimaryPlayerContext.java @@ -17,12 +17,11 @@ package baritone.utils.player; +import baritone.Baritone; import baritone.api.BaritoneAPI; import baritone.api.cache.IWorldData; -import baritone.api.utils.Helper; -import baritone.api.utils.IPlayerContext; -import baritone.api.utils.IPlayerController; -import baritone.api.utils.RayTraceUtils; +import baritone.api.utils.*; +import baritone.behavior.LookBehavior; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; @@ -57,6 +56,15 @@ public enum PrimaryPlayerContext implements IPlayerContext, Helper { return BaritoneAPI.getProvider().getPrimaryBaritone().getWorldProvider().getCurrentWorld(); } + @Override + public Rotation playerRotations() { + final Rotation lbTarget = ((LookBehavior) BaritoneAPI.getProvider().getPrimaryBaritone().getLookBehavior()).getEffectiveAngles(); + if (lbTarget == null || !Baritone.settings().blockFreeLook.value) { + return IPlayerContext.super.playerRotations(); + } + return lbTarget; + } + @Override public RayTraceResult objectMouseOver() { return RayTraceUtils.rayTraceTowards(player(), playerRotations(), playerController().getBlockReachDistance()); From fbe28e397e880e022c43af81c59dc8f088cd42b6 Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 11 Jun 2023 12:38:13 -0500 Subject: [PATCH 057/405] Make setting disabled by default --- src/api/java/baritone/api/Settings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index b49fce01b..bf3cb1bdd 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -726,7 +726,7 @@ public final class Settings { /** * Break and place blocks without having to force the client-sided rotations */ - public final Setting blockFreeLook = new Setting<>(true); + public final Setting blockFreeLook = new Setting<>(false); /** * Will cause some minor behavioral differences to ensure that Baritone works on anticheats. From a09e63d6aa654b85b3dbc75ad1044e1e4d031b45 Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 11 Jun 2023 13:14:52 -0500 Subject: [PATCH 058/405] appease codacy --- src/main/java/baritone/command/defaults/SelCommand.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/java/baritone/command/defaults/SelCommand.java b/src/main/java/baritone/command/defaults/SelCommand.java index 0a11c86a8..fb3608e75 100644 --- a/src/main/java/baritone/command/defaults/SelCommand.java +++ b/src/main/java/baritone/command/defaults/SelCommand.java @@ -294,12 +294,9 @@ public class SelCommand extends Command { args.get(); } return args.tabCompleteDatatype(ForBlockOptionalMeta.INSTANCE); - } else if (action == Action.CYLINDER || action == Action.HCYLINDER) { - if (args.hasExactly(2)) { - if (args.getDatatypeForOrNull(ForBlockOptionalMeta.INSTANCE) != null) { - return args.tabCompleteDatatype(ForAxis.INSTANCE); - } - } + } else if (args.hasExactly(2) && (action == Action.CYLINDER || action == Action.HCYLINDER)) { + args.get(); + return args.tabCompleteDatatype(ForAxis.INSTANCE); } } else if (action == Action.EXPAND || action == Action.CONTRACT || action == Action.SHIFT) { if (args.hasExactlyOne()) { From a602863426c32ace17de343c3c2306d5757bed81 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 11 Jun 2023 12:49:31 -0700 Subject: [PATCH 059/405] better elytra --- src/main/java/baritone/Elytra.java | 56 +++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index ac253868b..e50a098e6 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -78,6 +78,12 @@ public class Elytra extends Behavior implements Helper { baritone.getInputOverrideHandler().clearAllKeys(); if (ctx.player().isElytraFlying()) { + if (ctx.player().collidedHorizontally) { + logDirect("hbonk"); + } + if (ctx.player().collidedVertically) { + logDirect("vbonk"); + } Vec3d start = ctx.playerFeetAsVec(); boolean firework = firework(); sinceFirework++; @@ -97,12 +103,26 @@ public class Elytra extends Behavior implements Helper { boolean requireClear = relaxation == 0; int steps = relaxation < 2 ? Baritone.settings().elytraSimulationTicks.value : 3; int lookahead = relaxation == 0 ? 2 : 3; // ideally this would be expressed as a distance in blocks, rather than a number of voxel steps - for (int dy : heights) { - for (int i = Math.min(playerNear + 20, path.size()); i >= playerNear; i--) { + //int minStep = Math.max(0, playerNear - relaxation); + int minStep = playerNear; + for (int i = Math.min(playerNear + 20, path.size()); i >= minStep; i--) { + for (int dy : heights) { Vec3d dest = new Vec3d(path.get(i)).add(0, dy, 0); - if (dy != 0 && (i + lookahead >= path.size() || (!clearView(dest, new Vec3d(path.get(i + lookahead)).add(0, dy, 0)) || !clearView(dest, new Vec3d(path.get(i + lookahead)))))) { - // aka: don't go upwards if doing so would prevent us from being able to see the next position **OR** the modified next position - continue; + if (dy != 0) { + if (i + lookahead >= path.size()) { + continue; + } + if (start.distanceTo(dest) < 40) { + if (!clearView(dest, new Vec3d(path.get(i + lookahead)).add(0, dy, 0)) || !clearView(dest, new Vec3d(path.get(i + lookahead)))) { + // aka: don't go upwards if doing so would prevent us from being able to see the next position **OR** the modified next position + continue; + } + } else { + // but if it's far away, allow gaining altitude if we could lose it again by the time we get there + if (!clearView(dest, new Vec3d(path.get(i)))) { + continue; + } + } } if (requireClear ? isClear(start, dest) : clearView(start, dest)) { Rotation rot = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()); @@ -163,14 +183,17 @@ public class Elytra extends Behavior implements Helper { Vec3d totalMotion = new Vec3d(0, 0, 0); for (int i = 0; i < steps; i++) { stepped = step(stepped, pitch, good.getYaw(), firework); + Vec3d actualPositionPrevTick = ctx.playerFeetAsVec().add(totalMotion); totalMotion = totalMotion.add(stepped); - Vec3d actualPosition = ctx.playerFeetAsVec().add(totalMotion); - if (bsi.get0(MathHelper.floor(actualPosition.x), MathHelper.floor(actualPosition.y), MathHelper.floor(actualPosition.z)).getMaterial() != Material.AIR) { - continue outer; - } - if (bsi.get0(MathHelper.floor(actualPosition.x), MathHelper.floor(actualPosition.y) + 1, MathHelper.floor(actualPosition.z)).getMaterial() != Material.AIR) { - continue outer; + for (int x = MathHelper.floor(Math.min(actualPosition.x, actualPositionPrevTick.x) - 0.31); x <= Math.max(actualPosition.x, actualPositionPrevTick.x) + 0.31; x++) { + for (int y = MathHelper.floor(Math.min(actualPosition.y, actualPositionPrevTick.y) - 0.2); y <= Math.max(actualPosition.y, actualPositionPrevTick.y) + 0.8; y++) { + for (int z = MathHelper.floor(Math.min(actualPosition.z, actualPositionPrevTick.z) - 0.31); z <= Math.max(actualPosition.z, actualPositionPrevTick.z) + 0.31; z++) { + if (bsi.get0(x, y, z).getMaterial() != Material.AIR) { + continue outer; + } + } + } } } double directionalGoodness = goalDirection.dotProduct(totalMotion.normalize()); @@ -193,6 +216,11 @@ public class Elytra extends Behavior implements Helper { float pitchBase = -MathHelper.cos(-rotationPitch * 0.017453292F); float pitchHeight = MathHelper.sin(-rotationPitch * 0.017453292F); Vec3d lookDirection = new Vec3d(flatX * pitchBase, pitchHeight, flatZ * pitchBase); + if (firework) { + motionX += lookDirection.x * 0.1 + (lookDirection.x * 1.5 - motionX) * 0.5; + motionY += lookDirection.y * 0.1 + (lookDirection.y * 1.5 - motionY) * 0.5; + motionZ += lookDirection.z * 0.1 + (lookDirection.z * 1.5 - motionZ) * 0.5; + } float pitchRadians = rotationPitch * 0.017453292F; double pitchBase2 = Math.sqrt(lookDirection.x * lookDirection.x + lookDirection.z * lookDirection.z); double flatMotion = Math.sqrt(motionX * motionX + motionZ * motionZ); @@ -223,11 +251,7 @@ public class Elytra extends Behavior implements Helper { motionY *= 0.98; motionZ *= 0.99; //System.out.println(motionX + " " + motionY + " " + motionZ); - if (firework) { - motionX += lookDirection.x * 0.1 + (lookDirection.x * 1.5 - motionX) * 0.5; - motionY += lookDirection.y * 0.1 + (lookDirection.y * 1.5 - motionY) * 0.5; - motionZ += lookDirection.z * 0.1 + (lookDirection.z * 1.5 - motionZ) * 0.5; - } + return new Vec3d(motionX, motionY, motionZ); } From 77ca36c7947541faef6e1519823c4b06c913bc88 Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 11 Jun 2023 15:49:04 -0500 Subject: [PATCH 060/405] Use `playerRotations` in `reachableOffset` --- src/api/java/baritone/api/utils/RotationUtils.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/api/java/baritone/api/utils/RotationUtils.java b/src/api/java/baritone/api/utils/RotationUtils.java index 7b30f4abb..0d5a3ad1f 100644 --- a/src/api/java/baritone/api/utils/RotationUtils.java +++ b/src/api/java/baritone/api/utils/RotationUtils.java @@ -216,10 +216,10 @@ public final class RotationUtils { * @param blockReachDistance The block reach distance of the entity * @return The optional rotation */ - public static Optional reachableOffset(Entity entity, BlockPos pos, Vec3d offsetPos, double blockReachDistance, boolean wouldSneak) { + public static Optional reachableOffset(EntityPlayerSP entity, BlockPos pos, Vec3d offsetPos, double blockReachDistance, boolean wouldSneak) { + IPlayerContext ctx = BaritoneAPI.getProvider().getBaritoneForPlayer(entity).getPlayerContext(); Vec3d eyes = wouldSneak ? RayTraceUtils.inferSneakingEyePosition(entity) : entity.getPositionEyes(1.0F); - // TODO: pr/feature/blockFreeLook - Use playerRotations() here? - Rotation rotation = calcRotationFromVec3d(eyes, offsetPos, new Rotation(entity.rotationYaw, entity.rotationPitch)); + Rotation rotation = calcRotationFromVec3d(eyes, offsetPos, ctx.playerRotations()); RayTraceResult result = RayTraceUtils.rayTraceTowards(entity, rotation, blockReachDistance, wouldSneak); //System.out.println(result); if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) { @@ -242,7 +242,7 @@ public final class RotationUtils { * @param blockReachDistance The block reach distance of the entity * @return The optional rotation */ - public static Optional reachableCenter(Entity entity, BlockPos pos, double blockReachDistance, boolean wouldSneak) { + public static Optional reachableCenter(EntityPlayerSP entity, BlockPos pos, double blockReachDistance, boolean wouldSneak) { return reachableOffset(entity, pos, VecUtils.calculateBlockCenter(entity.world, pos), blockReachDistance, wouldSneak); } } From c48c2aa45cc0904ae8c994064ad226a4527ad163 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 11 Jun 2023 13:57:21 -0700 Subject: [PATCH 061/405] allow even more desperate motion --- src/main/java/baritone/Elytra.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index e50a098e6..1534b211d 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -128,7 +128,7 @@ public class Elytra extends Behavior implements Helper { Rotation rot = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()); ctx.player().rotationYaw = rot.getYaw(); long a = System.currentTimeMillis(); - Float pitch = solvePitch(dest.subtract(start), steps); + Float pitch = solvePitch(dest.subtract(start), steps, relaxation == 2); if (pitch == null) { continue; } @@ -164,7 +164,7 @@ public class Elytra extends Behavior implements Helper { return result == null || result.typeOfHit == RayTraceResult.Type.MISS; } - private Float solvePitch(Vec3d goalDirection, int steps) { + private Float solvePitch(Vec3d goalDirection, int steps, boolean desperate) { // we are at a certain velocity, but we have a target velocity // what pitch would get us closest to our target velocity? // yaw is easy so we only care about pitch @@ -177,8 +177,10 @@ public class Elytra extends Behavior implements Helper { double bestDot = Double.NEGATIVE_INFINITY; Vec3d motion = new Vec3d(ctx.player().motionX, ctx.player().motionY, ctx.player().motionZ); BlockStateInterface bsi = new BlockStateInterface(ctx); + float minPitch = desperate ? -90 : Math.max(good.getPitch() - Baritone.settings().elytraPitchRange.value, -89); + float maxPitch = desperate ? 90 : Math.min(good.getPitch() + Baritone.settings().elytraPitchRange.value, 89); outer: - for (float pitch = Math.max(good.getPitch() - Baritone.settings().elytraPitchRange.value, -89); pitch < Math.min(good.getPitch() + Baritone.settings().elytraPitchRange.value, 89); pitch++) { + for (float pitch = minPitch; pitch <= maxPitch; pitch++) { Vec3d stepped = motion; Vec3d totalMotion = new Vec3d(0, 0, 0); for (int i = 0; i < steps; i++) { From 4317dca024ec0d68b3d402b82777a453f7c121b1 Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 11 Jun 2023 18:35:34 -0500 Subject: [PATCH 062/405] Determine target mode (client/server) in `updateTarget` --- src/api/java/baritone/api/Settings.java | 3 +- .../baritone/api/behavior/ILookBehavior.java | 13 +- .../java/baritone/behavior/LookBehavior.java | 125 +++++++++++------- 3 files changed, 87 insertions(+), 54 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index bf3cb1bdd..bcd3eaa63 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -724,7 +724,8 @@ public final class Settings { public final Setting freeLook = new Setting<>(true); /** - * Break and place blocks without having to force the client-sided rotations + * Break and place blocks without having to force the client-sided rotations. Having this setting enabled implies + * {@link #freeLook}. */ public final Setting blockFreeLook = new Setting<>(false); diff --git a/src/api/java/baritone/api/behavior/ILookBehavior.java b/src/api/java/baritone/api/behavior/ILookBehavior.java index 058a5dd88..218e8b59a 100644 --- a/src/api/java/baritone/api/behavior/ILookBehavior.java +++ b/src/api/java/baritone/api/behavior/ILookBehavior.java @@ -26,14 +26,11 @@ import baritone.api.utils.Rotation; public interface ILookBehavior extends IBehavior { /** - * Updates the current {@link ILookBehavior} target to target - * the specified rotations on the next tick. If force is {@code true}, - * then freeLook will be overriden and angles will be set regardless. - * If any sort of block interaction is required, force should be {@code true}, - * otherwise, it should be {@code false}; + * Updates the current {@link ILookBehavior} target to target the specified rotations on the next tick. If any sort + * of block interaction is required, {@code blockInteract} should be {@code true}. * - * @param rotation The target rotations - * @param force Whether or not to "force" the rotations + * @param rotation The target rotations + * @param blockInteract Whether the target rotations are needed for a block interaction */ - void updateTarget(Rotation rotation, boolean force); + void updateTarget(Rotation rotation, boolean blockInteract); } diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index 7db3da562..93e0af3bf 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -28,19 +28,11 @@ import baritone.api.utils.Rotation; public final class LookBehavior extends Behavior implements ILookBehavior { /** - * Target's values are as follows: - *

- * getFirst() -> yaw - * getSecond() -> pitch + * The current look target, may be {@code null}. */ - private Rotation target; + private Target target; - private Rotation serverAngles; - - /** - * Whether or not rotations are currently being forced - */ - private boolean force; + private Rotation serverRotation; /** * The last player angles. Used when free looking @@ -54,50 +46,60 @@ public final class LookBehavior extends Behavior implements ILookBehavior { } @Override - public void updateTarget(Rotation target, boolean force) { - this.target = target; - this.force = !Baritone.settings().blockFreeLook.value && (force || !Baritone.settings().freeLook.value); + public void updateTarget(Rotation rotation, boolean blockInteract) { + this.target = new Target(rotation, blockInteract); } @Override public void onPlayerUpdate(PlayerUpdateEvent event) { + // Capture the player rotation before it's reset to determine the rotation the server knows + // Alternatively, this could be done with a packet event... Maybe that's a better idea. if (event.getState() == EventState.POST) { - this.serverAngles = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch); + this.serverRotation = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch); } + + // There's nothing left to be done if there isn't a set target if (this.target == null) { return; } - // Whether or not we're going to silently set our angles - boolean silent = Baritone.settings().antiCheatCompatibility.value && !this.force; - switch (event.getState()) { case PRE: { - if (this.force) { - ctx.player().rotationYaw = this.target.getYaw(); - float oldPitch = ctx.player().rotationPitch; - float desiredPitch = this.target.getPitch(); - ctx.player().rotationPitch = desiredPitch; - ctx.player().rotationYaw += (Math.random() - 0.5) * Baritone.settings().randomLooking.value; - ctx.player().rotationPitch += (Math.random() - 0.5) * Baritone.settings().randomLooking.value; - if (desiredPitch == oldPitch && !Baritone.settings().freeLook.value) { - nudgeToLevel(); + switch (this.target.mode) { + case CLIENT: { + ctx.player().rotationYaw = this.target.rotation.getYaw(); + float oldPitch = ctx.player().rotationPitch; + float desiredPitch = this.target.rotation.getPitch(); + ctx.player().rotationPitch = desiredPitch; + ctx.player().rotationYaw += (Math.random() - 0.5) * Baritone.settings().randomLooking.value; + ctx.player().rotationPitch += (Math.random() - 0.5) * Baritone.settings().randomLooking.value; + if (desiredPitch == oldPitch && !Baritone.settings().freeLook.value) { + nudgeToLevel(); + } + // The target can be invalidated now since it won't be needed for RotationMoveEvent + this.target = null; + break; } - this.target = null; - } - if (silent) { - this.prevAngles = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch); - ctx.player().rotationYaw = this.target.getYaw(); - ctx.player().rotationPitch = this.target.getPitch(); + case SERVER: { + // Copy the player's actual angles + this.prevAngles = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch); + ctx.player().rotationYaw = this.target.rotation.getYaw(); + ctx.player().rotationPitch = this.target.rotation.getPitch(); + break; + } + default: + break; } break; } case POST: { - if (silent) { + // Reset the player's rotations back to their original values + if (this.target.mode == Target.Mode.SERVER) { ctx.player().rotationYaw = this.prevAngles.getYaw(); ctx.player().rotationPitch = this.prevAngles.getPitch(); - this.target = null; } + // The target is done being used for this game tick, so it can be invalidated + this.target = null; break; } default: @@ -107,25 +109,18 @@ public final class LookBehavior extends Behavior implements ILookBehavior { public void pig() { if (this.target != null) { - ctx.player().rotationYaw = this.target.getYaw(); + ctx.player().rotationYaw = this.target.rotation.getYaw(); } } public Rotation getEffectiveAngles() { - return this.serverAngles; + return this.serverRotation; } @Override public void onPlayerRotationMove(RotationMoveEvent event) { if (this.target != null) { - - event.setYaw(this.target.getYaw()); - - // If we have antiCheatCompatibility on, we're going to use the target value later in onPlayerUpdate() - // Also the type has to be MOTION_UPDATE because that is called after JUMP - if (!Baritone.settings().antiCheatCompatibility.value && event.getType() == RotationMoveEvent.Type.MOTION_UPDATE && !this.force) { - this.target = null; - } + event.setYaw(this.target.rotation.getYaw()); } } @@ -139,4 +134,44 @@ public final class LookBehavior extends Behavior implements ILookBehavior { ctx.player().rotationPitch--; } } + + private static class Target { + + public final Rotation rotation; + public final Mode mode; + + public Target(Rotation rotation, boolean blockInteract) { + this.rotation = rotation; + this.mode = Mode.resolve(blockInteract); + } + + enum Mode { + /** + * Angles will be set client-side and are visual to the player + */ + CLIENT, + + /** + * Angles will be set server-side and are silent to the player + */ + SERVER, + + /** + * Angles will remain unaffected on both the client and server + */ + NONE; + + static Mode resolve(boolean blockInteract) { + final Settings settings = Baritone.settings(); + final boolean antiCheat = settings.antiCheatCompatibility.value; + final boolean blockFreeLook = settings.blockFreeLook.value; + final boolean freeLook = settings.freeLook.value; + + if (!freeLook && !blockFreeLook) return CLIENT; + if (!blockFreeLook && blockInteract) return CLIENT; + if (antiCheat || blockInteract) return SERVER; + return NONE; + } + } + } } From a7d15d1e32a1438bce8223a3483a76dcd5d14444 Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 11 Jun 2023 18:43:48 -0500 Subject: [PATCH 063/405] Consistent naming and comments for clarification --- .../java/baritone/behavior/LookBehavior.java | 30 ++++++++++++------- .../utils/player/PrimaryPlayerContext.java | 2 +- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index 93e0af3bf..c38cee6f9 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -23,6 +23,7 @@ import baritone.api.behavior.ILookBehavior; import baritone.api.event.events.PlayerUpdateEvent; import baritone.api.event.events.RotationMoveEvent; import baritone.api.event.events.type.EventState; +import baritone.api.utils.IPlayerContext; import baritone.api.utils.Rotation; public final class LookBehavior extends Behavior implements ILookBehavior { @@ -32,14 +33,17 @@ public final class LookBehavior extends Behavior implements ILookBehavior { */ private Target target; + /** + * The rotation known to the server. Returned by {@link #getEffectiveRotation()} for use in {@link IPlayerContext}. + */ private Rotation serverRotation; /** - * The last player angles. Used when free looking + * The last player rotation. Used when free looking * * @see Settings#freeLook */ - private Rotation prevAngles; + private Rotation prevRotation; public LookBehavior(Baritone baritone) { super(baritone); @@ -81,8 +85,8 @@ public final class LookBehavior extends Behavior implements ILookBehavior { break; } case SERVER: { - // Copy the player's actual angles - this.prevAngles = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch); + // Copy the player's actual rotation + this.prevRotation = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch); ctx.player().rotationYaw = this.target.rotation.getYaw(); ctx.player().rotationPitch = this.target.rotation.getPitch(); break; @@ -95,8 +99,8 @@ public final class LookBehavior extends Behavior implements ILookBehavior { case POST: { // Reset the player's rotations back to their original values if (this.target.mode == Target.Mode.SERVER) { - ctx.player().rotationYaw = this.prevAngles.getYaw(); - ctx.player().rotationPitch = this.prevAngles.getPitch(); + ctx.player().rotationYaw = this.prevRotation.getYaw(); + ctx.player().rotationPitch = this.prevRotation.getPitch(); } // The target is done being used for this game tick, so it can be invalidated this.target = null; @@ -113,7 +117,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior { } } - public Rotation getEffectiveAngles() { + public Rotation getEffectiveRotation() { return this.serverRotation; } @@ -147,17 +151,17 @@ public final class LookBehavior extends Behavior implements ILookBehavior { enum Mode { /** - * Angles will be set client-side and are visual to the player + * Rotation will be set client-side and is visual to the player */ CLIENT, /** - * Angles will be set server-side and are silent to the player + * Rotation will be set server-side and is silent to the player */ SERVER, /** - * Angles will remain unaffected on both the client and server + * Rotation will remain unaffected on both the client and server */ NONE; @@ -169,7 +173,13 @@ public final class LookBehavior extends Behavior implements ILookBehavior { if (!freeLook && !blockFreeLook) return CLIENT; if (!blockFreeLook && blockInteract) return CLIENT; + + // Regardless of if antiCheatCompatibility is enabled, if a blockInteract is requested then the player + // rotation needs to be set somehow, otherwise Baritone will halt since objectMouseOver() will just be + // whatever the player is mousing over visually. Let's just settle for setting it silently. if (antiCheat || blockInteract) return SERVER; + + // Pathing regularly without antiCheatCompatibility, don't set the player rotation return NONE; } } diff --git a/src/main/java/baritone/utils/player/PrimaryPlayerContext.java b/src/main/java/baritone/utils/player/PrimaryPlayerContext.java index cc35c156c..e4484f0be 100644 --- a/src/main/java/baritone/utils/player/PrimaryPlayerContext.java +++ b/src/main/java/baritone/utils/player/PrimaryPlayerContext.java @@ -58,7 +58,7 @@ public enum PrimaryPlayerContext implements IPlayerContext, Helper { @Override public Rotation playerRotations() { - final Rotation lbTarget = ((LookBehavior) BaritoneAPI.getProvider().getPrimaryBaritone().getLookBehavior()).getEffectiveAngles(); + final Rotation lbTarget = ((LookBehavior) BaritoneAPI.getProvider().getPrimaryBaritone().getLookBehavior()).getEffectiveRotation(); if (lbTarget == null || !Baritone.settings().blockFreeLook.value) { return IPlayerContext.super.playerRotations(); } From bb36ebfc0c7cb39ac24852fef1b28c25c995975d Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 11 Jun 2023 20:09:37 -0500 Subject: [PATCH 064/405] Use `IPlayerContext` for all `RotationUtils` methods Deprecates all old overloads --- .../baritone/api/utils/RotationUtils.java | 87 +++++++++++++------ .../baritone/pathing/movement/Movement.java | 2 +- .../movement/movements/MovementPillar.java | 2 +- .../java/baritone/process/BuilderProcess.java | 2 +- .../java/baritone/process/FarmProcess.java | 4 +- .../baritone/process/GetToBlockProcess.java | 2 +- .../java/baritone/process/MineProcess.java | 2 +- 7 files changed, 66 insertions(+), 35 deletions(-) diff --git a/src/api/java/baritone/api/utils/RotationUtils.java b/src/api/java/baritone/api/utils/RotationUtils.java index 0d5a3ad1f..1991ab878 100644 --- a/src/api/java/baritone/api/utils/RotationUtils.java +++ b/src/api/java/baritone/api/utils/RotationUtils.java @@ -134,14 +134,14 @@ public final class RotationUtils { * @param ctx Context for the viewing entity * @param pos The target block position * @return The optional rotation - * @see #reachable(EntityPlayerSP, BlockPos, double) + * @see #reachable(IPlayerContext, BlockPos, double) */ public static Optional reachable(IPlayerContext ctx, BlockPos pos) { - return reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance()); + return reachable(ctx, pos, false); } public static Optional reachable(IPlayerContext ctx, BlockPos pos, boolean wouldSneak) { - return reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance(), wouldSneak); + return reachable(ctx, pos, ctx.playerController().getBlockReachDistance(), wouldSneak); } /** @@ -151,18 +151,16 @@ public final class RotationUtils { * side that is reachable. The return type will be {@link Optional#empty()} if the entity is * unable to reach any of the sides of the block. * - * @param entity The viewing entity + * @param ctx Context for the viewing entity * @param pos The target block position * @param blockReachDistance The block reach distance of the entity * @return The optional rotation */ - public static Optional reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance) { - return reachable(entity, pos, blockReachDistance, false); + public static Optional reachable(IPlayerContext ctx, BlockPos pos, double blockReachDistance) { + return reachable(ctx, pos, blockReachDistance, false); } - public static Optional reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance, boolean wouldSneak) { - IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(entity); - IPlayerContext ctx = baritone.getPlayerContext(); + public static Optional reachable(IPlayerContext ctx, BlockPos pos, double blockReachDistance, boolean wouldSneak) { if (ctx.isLookingAt(pos)) { /* * why add 0.0001? @@ -177,7 +175,7 @@ public final class RotationUtils { Rotation hypothetical = ctx.playerRotations().add(new Rotation(0, 0.0001F)); if (wouldSneak) { // the concern here is: what if we're looking at it now, but as soon as we start sneaking we no longer are - RayTraceResult result = RayTraceUtils.rayTraceTowards(entity, hypothetical, blockReachDistance, true); + RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), hypothetical, blockReachDistance, true); if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK && result.getBlockPos().equals(pos)) { return Optional.of(hypothetical); // yes, if we sneaked we would still be looking at the block } @@ -185,19 +183,19 @@ public final class RotationUtils { return Optional.of(hypothetical); } } - Optional possibleRotation = reachableCenter(entity, pos, blockReachDistance, wouldSneak); + Optional possibleRotation = reachableCenter(ctx, pos, blockReachDistance, wouldSneak); //System.out.println("center: " + possibleRotation); if (possibleRotation.isPresent()) { return possibleRotation; } - IBlockState state = entity.world.getBlockState(pos); - AxisAlignedBB aabb = state.getBoundingBox(entity.world, pos); + IBlockState state = ctx.world().getBlockState(pos); + AxisAlignedBB aabb = state.getBoundingBox(ctx.world(), pos); for (Vec3d sideOffset : BLOCK_SIDE_MULTIPLIERS) { double xDiff = aabb.minX * sideOffset.x + aabb.maxX * (1 - sideOffset.x); double yDiff = aabb.minY * sideOffset.y + aabb.maxY * (1 - sideOffset.y); double zDiff = aabb.minZ * sideOffset.z + aabb.maxZ * (1 - sideOffset.z); - possibleRotation = reachableOffset(entity, pos, new Vec3d(pos).add(xDiff, yDiff, zDiff), blockReachDistance, wouldSneak); + possibleRotation = reachableOffset(ctx, pos, new Vec3d(pos).add(xDiff, yDiff, zDiff), blockReachDistance, wouldSneak); if (possibleRotation.isPresent()) { return possibleRotation; } @@ -210,16 +208,57 @@ public final class RotationUtils { * the given offsetted position. The return type will be {@link Optional#empty()} if * the entity is unable to reach the block with the offset applied. * - * @param entity The viewing entity + * @param ctx Context for the viewing entity * @param pos The target block position * @param offsetPos The position of the block with the offset applied. * @param blockReachDistance The block reach distance of the entity * @return The optional rotation */ - public static Optional reachableOffset(EntityPlayerSP entity, BlockPos pos, Vec3d offsetPos, double blockReachDistance, boolean wouldSneak) { - IPlayerContext ctx = BaritoneAPI.getProvider().getBaritoneForPlayer(entity).getPlayerContext(); - Vec3d eyes = wouldSneak ? RayTraceUtils.inferSneakingEyePosition(entity) : entity.getPositionEyes(1.0F); + public static Optional reachableOffset(IPlayerContext ctx, BlockPos pos, Vec3d offsetPos, double blockReachDistance, boolean wouldSneak) { + Vec3d eyes = wouldSneak ? RayTraceUtils.inferSneakingEyePosition(ctx.player()) : ctx.player().getPositionEyes(1.0F); Rotation rotation = calcRotationFromVec3d(eyes, offsetPos, ctx.playerRotations()); + RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rotation, blockReachDistance, wouldSneak); + //System.out.println(result); + if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) { + if (result.getBlockPos().equals(pos)) { + return Optional.of(rotation); + } + if (ctx.world().getBlockState(pos).getBlock() instanceof BlockFire && result.getBlockPos().equals(pos.down())) { + return Optional.of(rotation); + } + } + return Optional.empty(); + } + + /** + * Determines if the specified entity is able to reach the specified block where it is + * looking at the direct center of it's hitbox. + * + * @param ctx Context for the viewing entity + * @param pos The target block position + * @param blockReachDistance The block reach distance of the entity + * @return The optional rotation + */ + public static Optional reachableCenter(IPlayerContext ctx, BlockPos pos, double blockReachDistance, boolean wouldSneak) { + return reachableOffset(ctx, pos, VecUtils.calculateBlockCenter(ctx.world(), pos), blockReachDistance, wouldSneak); + } + + @Deprecated + public static Optional reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance) { + return reachable(entity, pos, blockReachDistance, false); + } + + @Deprecated + public static Optional reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance, boolean wouldSneak) { + IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(entity); + IPlayerContext ctx = baritone.getPlayerContext(); + return reachable(ctx, pos, blockReachDistance, wouldSneak); + } + + @Deprecated + public static Optional reachableOffset(Entity entity, BlockPos pos, Vec3d offsetPos, double blockReachDistance, boolean wouldSneak) { + Vec3d eyes = wouldSneak ? RayTraceUtils.inferSneakingEyePosition(entity) : entity.getPositionEyes(1.0F); + Rotation rotation = calcRotationFromVec3d(eyes, offsetPos, new Rotation(entity.rotationYaw, entity.rotationPitch)); RayTraceResult result = RayTraceUtils.rayTraceTowards(entity, rotation, blockReachDistance, wouldSneak); //System.out.println(result); if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) { @@ -233,16 +272,8 @@ public final class RotationUtils { return Optional.empty(); } - /** - * Determines if the specified entity is able to reach the specified block where it is - * looking at the direct center of it's hitbox. - * - * @param entity The viewing entity - * @param pos The target block position - * @param blockReachDistance The block reach distance of the entity - * @return The optional rotation - */ - public static Optional reachableCenter(EntityPlayerSP entity, BlockPos pos, double blockReachDistance, boolean wouldSneak) { + @Deprecated + public static Optional reachableCenter(Entity entity, BlockPos pos, double blockReachDistance, boolean wouldSneak) { return reachableOffset(entity, pos, VecUtils.calculateBlockCenter(entity.world, pos), blockReachDistance, wouldSneak); } } diff --git a/src/main/java/baritone/pathing/movement/Movement.java b/src/main/java/baritone/pathing/movement/Movement.java index c46b24dea..5a17d26c5 100644 --- a/src/main/java/baritone/pathing/movement/Movement.java +++ b/src/main/java/baritone/pathing/movement/Movement.java @@ -164,7 +164,7 @@ public abstract class Movement implements IMovement, MovementHelper { if (!MovementHelper.canWalkThrough(ctx, blockPos) && !(BlockStateInterface.getBlock(ctx, blockPos) instanceof BlockLiquid)) { // can't break liquid, so don't try somethingInTheWay = true; MovementHelper.switchToBestToolFor(ctx, BlockStateInterface.get(ctx, blockPos)); - Optional reachable = RotationUtils.reachable(ctx.player(), blockPos, ctx.playerController().getBlockReachDistance()); + Optional reachable = RotationUtils.reachable(ctx, blockPos, ctx.playerController().getBlockReachDistance()); if (reachable.isPresent()) { Rotation rotTowardsBlock = reachable.get(); state.setTarget(new MovementState.MovementTarget(rotTowardsBlock, true)); diff --git a/src/main/java/baritone/pathing/movement/movements/MovementPillar.java b/src/main/java/baritone/pathing/movement/movements/MovementPillar.java index 88f1e26ff..0198b28fe 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementPillar.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementPillar.java @@ -251,7 +251,7 @@ public class MovementPillar extends Movement { Block fr = frState.getBlock(); // TODO: Evaluate usage of getMaterial().isReplaceable() if (!(fr instanceof BlockAir || frState.getMaterial().isReplaceable())) { - RotationUtils.reachable(ctx.player(), src, ctx.playerController().getBlockReachDistance()) + RotationUtils.reachable(ctx, src, ctx.playerController().getBlockReachDistance()) .map(rot -> new MovementState.MovementTarget(rot, true)) .ifPresent(state::setTarget); state.setInput(Input.JUMP, false); // breaking is like 5x slower when you're jumping diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index c7868a4a0..6f8582457 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -283,7 +283,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil IBlockState curr = bcc.bsi.get0(x, y, z); if (curr.getBlock() != Blocks.AIR && !(curr.getBlock() instanceof BlockLiquid) && !valid(curr, desired, false)) { BetterBlockPos pos = new BetterBlockPos(x, y, z); - Optional rot = RotationUtils.reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance()); + Optional rot = RotationUtils.reachable(ctx, pos, ctx.playerController().getBlockReachDistance()); if (rot.isPresent()) { return Optional.of(new Tuple<>(pos, rot.get())); } diff --git a/src/main/java/baritone/process/FarmProcess.java b/src/main/java/baritone/process/FarmProcess.java index a9188299c..1536bdb61 100644 --- a/src/main/java/baritone/process/FarmProcess.java +++ b/src/main/java/baritone/process/FarmProcess.java @@ -268,7 +268,7 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro both.addAll(openSoulsand); for (BlockPos pos : both) { boolean soulsand = openSoulsand.contains(pos); - Optional rot = RotationUtils.reachableOffset(ctx.player(), pos, new Vec3d(pos.getX() + 0.5, pos.getY() + 1, pos.getZ() + 0.5), ctx.playerController().getBlockReachDistance(), false); + Optional rot = RotationUtils.reachableOffset(ctx, pos, new Vec3d(pos.getX() + 0.5, pos.getY() + 1, pos.getZ() + 0.5), ctx.playerController().getBlockReachDistance(), false); if (rot.isPresent() && isSafeToCancel && baritone.getInventoryBehavior().throwaway(true, soulsand ? this::isNetherWart : this::isPlantable)) { RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot.get(), ctx.playerController().getBlockReachDistance()); if (result.typeOfHit == RayTraceResult.Type.BLOCK && result.sideHit == EnumFacing.UP) { @@ -286,7 +286,7 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro continue; } Vec3d faceCenter = new Vec3d(pos).add(0.5, 0.5, 0.5).add(new Vec3d(dir.getDirectionVec()).scale(0.5)); - Optional rot = RotationUtils.reachableOffset(ctx.player(), pos, faceCenter, ctx.playerController().getBlockReachDistance(), false); + Optional rot = RotationUtils.reachableOffset(ctx, pos, faceCenter, ctx.playerController().getBlockReachDistance(), false); if (rot.isPresent() && isSafeToCancel && baritone.getInventoryBehavior().throwaway(true, this::isCocoa)) { RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot.get(), ctx.playerController().getBlockReachDistance()); if (result.typeOfHit == RayTraceResult.Type.BLOCK && result.sideHit == dir) { diff --git a/src/main/java/baritone/process/GetToBlockProcess.java b/src/main/java/baritone/process/GetToBlockProcess.java index 16fc3dda5..7f8376b84 100644 --- a/src/main/java/baritone/process/GetToBlockProcess.java +++ b/src/main/java/baritone/process/GetToBlockProcess.java @@ -210,7 +210,7 @@ public final class GetToBlockProcess extends BaritoneProcessHelper implements IG private boolean rightClick() { for (BlockPos pos : knownLocations) { - Optional reachable = RotationUtils.reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance()); + Optional reachable = RotationUtils.reachable(ctx, pos, ctx.playerController().getBlockReachDistance()); if (reachable.isPresent()) { baritone.getLookBehavior().updateTarget(reachable.get(), true); if (knownLocations.contains(ctx.getSelectedBlock().orElse(null))) { diff --git a/src/main/java/baritone/process/MineProcess.java b/src/main/java/baritone/process/MineProcess.java index 6880dd86c..e7d7b3365 100644 --- a/src/main/java/baritone/process/MineProcess.java +++ b/src/main/java/baritone/process/MineProcess.java @@ -397,7 +397,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro // is an x-ray and it'll get caught if (filter.has(bsi.get0(x, y, z))) { BlockPos pos = new BlockPos(x, y, z); - if ((Baritone.settings().legitMineIncludeDiagonals.value && knownOreLocations.stream().anyMatch(ore -> ore.distanceSq(pos) <= 2 /* sq means this is pytha dist <= sqrt(2) */)) || RotationUtils.reachable(ctx.player(), pos, fakedBlockReachDistance).isPresent()) { + if ((Baritone.settings().legitMineIncludeDiagonals.value && knownOreLocations.stream().anyMatch(ore -> ore.distanceSq(pos) <= 2 /* sq means this is pytha dist <= sqrt(2) */)) || RotationUtils.reachable(ctx, pos, fakedBlockReachDistance).isPresent()) { knownOreLocations.add(pos); } } From 35a996e2b0406b9689bd1be4ee87464c3dd600aa Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 11 Jun 2023 20:59:28 -0700 Subject: [PATCH 065/405] firework more often --- src/api/java/baritone/api/Settings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 5463f3163..4fe0c6281 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -50,7 +50,7 @@ public final class Settings { public final Setting elytraSimulationTicks = new Setting<>(20); public final Setting elytraPitchRange = new Setting<>(25); - public final Setting elytraFireworkSpeed = new Setting<>(0.425); + public final Setting elytraFireworkSpeed = new Setting<>(0.6); /** * Allow Baritone to break blocks From b9054cdfc9cd8a043ae32c71a9d414f1b025f536 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 11 Jun 2023 22:22:01 -0700 Subject: [PATCH 066/405] use more fireworks --- src/api/java/baritone/api/Settings.java | 2 ++ src/main/java/baritone/Elytra.java | 11 ++++++++--- src/main/java/baritone/utils/PathRenderer.java | 15 +++++++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 4fe0c6281..343fe823a 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -51,6 +51,8 @@ public final class Settings { public final Setting elytraSimulationTicks = new Setting<>(20); public final Setting elytraPitchRange = new Setting<>(25); public final Setting elytraFireworkSpeed = new Setting<>(0.6); + public final Setting wasteFireworks = new Setting<>(false); + public final Setting renderRaytraces = new Setting<>(false); /** * Allow Baritone to break blocks diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index 1534b211d..2be7932ea 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -24,6 +24,7 @@ import baritone.api.utils.Rotation; import baritone.api.utils.RotationUtils; import baritone.behavior.Behavior; import baritone.utils.BlockStateInterface; +import com.mojang.realmsclient.util.Pair; import net.minecraft.block.material.Material; import net.minecraft.entity.item.EntityFireworkRocket; import net.minecraft.util.EnumHand; @@ -64,6 +65,9 @@ public class Elytra extends Behavior implements Helper { public int sinceFirework; public BlockPos goal; + + public List> lines = new ArrayList<>(); + protected Elytra(Baritone baritone) { super(baritone); } @@ -76,7 +80,7 @@ public class Elytra extends Behavior implements Helper { } fixNearPlayer(); baritone.getInputOverrideHandler().clearAllKeys(); - + lines.clear(); if (ctx.player().isElytraFlying()) { if (ctx.player().collidedHorizontally) { logDirect("hbonk"); @@ -89,7 +93,7 @@ public class Elytra extends Behavior implements Helper { sinceFirework++; if (!firework && sinceFirework > 10 - && ctx.player().posY < path.get(goingTo).y + 5 // don't firework if trying to descend + && (Baritone.settings().wasteFireworks.value && ctx.player().posY < path.get(goingTo).y + 5) // don't firework if trying to descend && (ctx.player().posY < path.get(goingTo).y - 5 || ctx.playerFeetAsVec().distanceTo(new Vec3d(path.get(goingTo).x, ctx.player().posY, path.get(goingTo).z)) > 5) // UGH!!!!!!! && new Vec3d(ctx.player().motionX, ctx.player().posY < path.get(goingTo).y ? Math.max(0, ctx.player().motionY) : ctx.player().motionY, ctx.player().motionZ).length() < Baritone.settings().elytraFireworkSpeed.value // ignore y component if we are BOTH below where we want to be AND descending ) { @@ -101,7 +105,7 @@ public class Elytra extends Behavior implements Helper { for (int relaxation = 0; relaxation < 3; relaxation++) { // try for a strict solution first, then relax more and more (if we're in a corner or near some blocks, it will have to relax its constraints a bit) int[] heights = firework ? new int[]{20, 10, 5, 0} : new int[]{0}; // attempt to gain height, if we can, so as not to waste the boost boolean requireClear = relaxation == 0; - int steps = relaxation < 2 ? Baritone.settings().elytraSimulationTicks.value : 3; + int steps = relaxation < 2 ? firework ? 5 : Baritone.settings().elytraSimulationTicks.value : 3; int lookahead = relaxation == 0 ? 2 : 3; // ideally this would be expressed as a distance in blocks, rather than a number of voxel steps //int minStep = Math.max(0, playerNear - relaxation); int minStep = playerNear; @@ -160,6 +164,7 @@ public class Elytra extends Behavior implements Helper { } private boolean clearView(Vec3d start, Vec3d dest) { + lines.add(Pair.of(start, dest)); RayTraceResult result = ctx.world().rayTraceBlocks(start, dest, true, false, true); return result == null || result.typeOfHit == RayTraceResult.Type.MISS; } diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index 828479a5d..f4e9317b3 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -17,6 +17,7 @@ package baritone.utils; +import baritone.Baritone; import baritone.Elytra; import baritone.api.BaritoneAPI; import baritone.api.event.events.RenderEvent; @@ -26,6 +27,7 @@ import baritone.api.utils.Helper; import baritone.api.utils.interfaces.IGoalRenderPos; import baritone.behavior.PathingBehavior; import baritone.pathing.path.PathExecutor; +import com.mojang.realmsclient.util.Pair; import net.minecraft.block.state.IBlockState; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.tileentity.TileEntityBeaconRenderer; @@ -35,6 +37,7 @@ import net.minecraft.init.Blocks; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; import java.awt.*; import java.util.Collection; @@ -107,6 +110,18 @@ public final class PathRenderer implements IRenderer { if (behavior.baritone.elytra.goal != null) { drawDankLitGoalBox(renderView, new GoalBlock(behavior.baritone.elytra.goal), partialTicks, Color.GREEN); } + if (!behavior.baritone.elytra.lines.isEmpty() && Baritone.settings().renderRaytraces.value) { + IRenderer.startLines(Color.BLUE, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); + boolean orig = settings.renderPathAsLine.value; + settings.renderPathAsLine.value = true; + for (Pair line : behavior.baritone.elytra.lines) { + drawLine(line.first().x, line.first().y, line.first().z, line.second().x, line.second().y, line.second().z); + tessellator.draw(); + } + settings.renderPathAsLine.value = orig; + IRenderer.endLines(settings.renderPathIgnoreDepth.value); + } + // If there is a path calculation currently running, render the path calculation process behavior.getInProgress().ifPresent(currentlyRunning -> { From 4148b9818707841d1383c00d7e45a2a3de8e907c Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 11 Jun 2023 22:22:49 -0700 Subject: [PATCH 067/405] typo --- src/main/java/baritone/Elytra.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index 2be7932ea..14b64e547 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -93,7 +93,7 @@ public class Elytra extends Behavior implements Helper { sinceFirework++; if (!firework && sinceFirework > 10 - && (Baritone.settings().wasteFireworks.value && ctx.player().posY < path.get(goingTo).y + 5) // don't firework if trying to descend + && (Baritone.settings().wasteFireworks.value || ctx.player().posY < path.get(goingTo).y + 5) // don't firework if trying to descend && (ctx.player().posY < path.get(goingTo).y - 5 || ctx.playerFeetAsVec().distanceTo(new Vec3d(path.get(goingTo).x, ctx.player().posY, path.get(goingTo).z)) > 5) // UGH!!!!!!! && new Vec3d(ctx.player().motionX, ctx.player().posY < path.get(goingTo).y ? Math.max(0, ctx.player().motionY) : ctx.player().motionY, ctx.player().motionZ).length() < Baritone.settings().elytraFireworkSpeed.value // ignore y component if we are BOTH below where we want to be AND descending ) { From 410cfcf21a664a7e23fbd08923de3cbbc320117d Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 11 Jun 2023 22:40:35 -0700 Subject: [PATCH 068/405] typo, fix crash at end of path --- src/main/java/baritone/Elytra.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index 14b64e547..708f6621d 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -109,7 +109,7 @@ public class Elytra extends Behavior implements Helper { int lookahead = relaxation == 0 ? 2 : 3; // ideally this would be expressed as a distance in blocks, rather than a number of voxel steps //int minStep = Math.max(0, playerNear - relaxation); int minStep = playerNear; - for (int i = Math.min(playerNear + 20, path.size()); i >= minStep; i--) { + for (int i = Math.min(playerNear + 20, path.size() - 1); i >= minStep; i--) { for (int dy : heights) { Vec3d dest = new Vec3d(path.get(i)).add(0, dy, 0); if (dy != 0) { From 1d5ee079b4aea9925041eae05a923da513b1ba5e Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 12 Jun 2023 12:11:50 -0500 Subject: [PATCH 069/405] Read `serverRotation` from packet and invalidate on world load --- .../java/baritone/behavior/LookBehavior.java | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index c38cee6f9..d1e5d244f 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -20,11 +20,13 @@ package baritone.behavior; import baritone.Baritone; import baritone.api.Settings; import baritone.api.behavior.ILookBehavior; +import baritone.api.event.events.PacketEvent; import baritone.api.event.events.PlayerUpdateEvent; import baritone.api.event.events.RotationMoveEvent; -import baritone.api.event.events.type.EventState; +import baritone.api.event.events.WorldEvent; import baritone.api.utils.IPlayerContext; import baritone.api.utils.Rotation; +import net.minecraft.network.play.client.CPacketPlayer; public final class LookBehavior extends Behavior implements ILookBehavior { @@ -56,17 +58,9 @@ public final class LookBehavior extends Behavior implements ILookBehavior { @Override public void onPlayerUpdate(PlayerUpdateEvent event) { - // Capture the player rotation before it's reset to determine the rotation the server knows - // Alternatively, this could be done with a packet event... Maybe that's a better idea. - if (event.getState() == EventState.POST) { - this.serverRotation = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch); - } - - // There's nothing left to be done if there isn't a set target if (this.target == null) { return; } - switch (event.getState()) { case PRE: { switch (this.target.mode) { @@ -111,6 +105,24 @@ public final class LookBehavior extends Behavior implements ILookBehavior { } } + @Override + public void onSendPacket(PacketEvent event) { + if (!(event.getPacket() instanceof CPacketPlayer)) { + return; + } + + final CPacketPlayer packet = (CPacketPlayer) event.getPacket(); + if (packet instanceof CPacketPlayer.Rotation || packet instanceof CPacketPlayer.PositionRotation) { + this.serverRotation = new Rotation(packet.getYaw(0.0f), packet.getPitch(0.0f)); + } + } + + @Override + public void onWorldEvent(WorldEvent event) { + this.serverRotation = null; + this.target = null; + } + public void pig() { if (this.target != null) { ctx.player().rotationYaw = this.target.rotation.getYaw(); From 67a085c95fca4be8a6f85d4c2a5dfcc0bb9f3d89 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 12 Jun 2023 13:16:37 -0500 Subject: [PATCH 070/405] Batch together GL_LINES draw calls --- .../baritone/command/defaults/SelCommand.java | 2 +- .../baritone/selection/SelectionRenderer.java | 8 +-- src/main/java/baritone/utils/IRenderer.java | 16 +++-- .../java/baritone/utils/PathRenderer.java | 67 +++++++++++++------ 4 files changed, 61 insertions(+), 32 deletions(-) diff --git a/src/main/java/baritone/command/defaults/SelCommand.java b/src/main/java/baritone/command/defaults/SelCommand.java index 5677eec3c..d6c2e890d 100644 --- a/src/main/java/baritone/command/defaults/SelCommand.java +++ b/src/main/java/baritone/command/defaults/SelCommand.java @@ -72,7 +72,7 @@ public class SelCommand extends Command { float lineWidth = Baritone.settings().selectionLineWidth.value; boolean ignoreDepth = Baritone.settings().renderSelectionIgnoreDepth.value; IRenderer.startLines(color, opacity, lineWidth, ignoreDepth); - IRenderer.drawAABB(new AxisAlignedBB(pos1, pos1.add(1, 1, 1))); + IRenderer.emitAABB(new AxisAlignedBB(pos1, pos1.add(1, 1, 1))); IRenderer.endLines(ignoreDepth); } }); diff --git a/src/main/java/baritone/selection/SelectionRenderer.java b/src/main/java/baritone/selection/SelectionRenderer.java index 89104d030..b688e9670 100644 --- a/src/main/java/baritone/selection/SelectionRenderer.java +++ b/src/main/java/baritone/selection/SelectionRenderer.java @@ -23,27 +23,27 @@ public class SelectionRenderer implements IRenderer, AbstractGameEventListener { boolean ignoreDepth = settings.renderSelectionIgnoreDepth.value; float lineWidth = settings.selectionLineWidth.value; - if (!settings.renderSelection.value) { + if (!settings.renderSelection.value || selections.length == 0) { return; } IRenderer.startLines(settings.colorSelection.value, opacity, lineWidth, ignoreDepth); for (ISelection selection : selections) { - IRenderer.drawAABB(selection.aabb(), SELECTION_BOX_EXPANSION); + IRenderer.emitAABB(selection.aabb(), SELECTION_BOX_EXPANSION); } if (settings.renderSelectionCorners.value) { IRenderer.glColor(settings.colorSelectionPos1.value, opacity); for (ISelection selection : selections) { - IRenderer.drawAABB(new AxisAlignedBB(selection.pos1(), selection.pos1().add(1, 1, 1))); + IRenderer.emitAABB(new AxisAlignedBB(selection.pos1(), selection.pos1().add(1, 1, 1))); } IRenderer.glColor(settings.colorSelectionPos2.value, opacity); for (ISelection selection : selections) { - IRenderer.drawAABB(new AxisAlignedBB(selection.pos2(), selection.pos2().add(1, 1, 1))); + IRenderer.emitAABB(new AxisAlignedBB(selection.pos2(), selection.pos2().add(1, 1, 1))); } } diff --git a/src/main/java/baritone/utils/IRenderer.java b/src/main/java/baritone/utils/IRenderer.java index e5a5ee907..3476c0307 100644 --- a/src/main/java/baritone/utils/IRenderer.java +++ b/src/main/java/baritone/utils/IRenderer.java @@ -54,6 +54,7 @@ public interface IRenderer { if (ignoreDepth) { GlStateManager.disableDepth(); } + buffer.begin(GL_LINES, DefaultVertexFormats.POSITION); } static void startLines(Color color, float lineWidth, boolean ignoreDepth) { @@ -61,6 +62,7 @@ public interface IRenderer { } static void endLines(boolean ignoredDepth) { + tessellator.draw(); if (ignoredDepth) { GlStateManager.enableDepth(); } @@ -70,10 +72,9 @@ public interface IRenderer { GlStateManager.disableBlend(); } - static void drawAABB(AxisAlignedBB aabb) { + static void emitAABB(AxisAlignedBB aabb) { AxisAlignedBB toDraw = aabb.offset(-renderManager.viewerPosX, -renderManager.viewerPosY, -renderManager.viewerPosZ); - buffer.begin(GL_LINES, DefaultVertexFormats.POSITION); // bottom buffer.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex(); buffer.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).endVertex(); @@ -101,10 +102,15 @@ public interface IRenderer { buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).endVertex(); buffer.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).endVertex(); buffer.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).endVertex(); - tessellator.draw(); } - static void drawAABB(AxisAlignedBB aabb, double expand) { - drawAABB(aabb.grow(expand, expand, expand)); + static void emitAABB(AxisAlignedBB aabb, double expand) { + emitAABB(aabb.grow(expand, expand, expand)); + } + + static void drawAABB(AxisAlignedBB aabb) { + buffer.begin(GL_LINES, DefaultVertexFormats.POSITION); + emitAABB(aabb); + tessellator.draw(); } } diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index 2fe224706..2aef0ab54 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -29,7 +29,6 @@ import baritone.pathing.path.PathExecutor; import net.minecraft.block.state.IBlockState; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.tileentity.TileEntityBeaconRenderer; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.entity.Entity; import net.minecraft.init.Blocks; import net.minecraft.util.math.AxisAlignedBB; @@ -37,6 +36,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import java.awt.*; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -76,7 +76,7 @@ public final class PathRenderer implements IRenderer { } if (goal != null && settings.renderGoal.value) { - drawDankLitGoalBox(renderView, goal, partialTicks, settings.colorGoalBox.value); + drawGoal(renderView, goal, partialTicks, settings.colorGoalBox.value); } if (!settings.renderPath.value) { @@ -153,26 +153,28 @@ public final class PathRenderer implements IRenderer { IRenderer.glColor(color, alpha); } - drawLine(start.x, start.y, start.z, end.x, end.y, end.z); - - tessellator.draw(); + emitLine(start.x, start.y, start.z, end.x, end.y, end.z); } IRenderer.endLines(settings.renderPathIgnoreDepth.value); } - public static void drawLine(double x1, double y1, double z1, double x2, double y2, double z2) { + public static void emitLine(double x1, double y1, double z1, double x2, double y2, double z2) { double vpX = renderManager.viewerPosX; double vpY = renderManager.viewerPosY; double vpZ = renderManager.viewerPosZ; boolean renderPathAsFrickinThingy = !settings.renderPathAsLine.value; - buffer.begin(renderPathAsFrickinThingy ? GL_LINE_STRIP : GL_LINES, DefaultVertexFormats.POSITION); buffer.pos(x1 + 0.5D - vpX, y1 + 0.5D - vpY, z1 + 0.5D - vpZ).endVertex(); buffer.pos(x2 + 0.5D - vpX, y2 + 0.5D - vpY, z2 + 0.5D - vpZ).endVertex(); if (renderPathAsFrickinThingy) { + buffer.pos(x2 + 0.5D - vpX, y2 + 0.5D - vpY, z2 + 0.5D - vpZ).endVertex(); buffer.pos(x2 + 0.5D - vpX, y2 + 0.53D - vpY, z2 + 0.5D - vpZ).endVertex(); + + buffer.pos(x2 + 0.5D - vpX, y2 + 0.53D - vpY, z2 + 0.5D - vpZ).endVertex(); + buffer.pos(x1 + 0.5D - vpX, y1 + 0.53D - vpY, z1 + 0.5D - vpZ).endVertex(); + buffer.pos(x1 + 0.5D - vpX, y1 + 0.53D - vpY, z1 + 0.5D - vpZ).endVertex(); buffer.pos(x1 + 0.5D - vpX, y1 + 0.5D - vpY, z1 + 0.5D - vpZ).endVertex(); } @@ -194,13 +196,17 @@ public final class PathRenderer implements IRenderer { toDraw = state.getSelectedBoundingBox(player.world, pos); } - IRenderer.drawAABB(toDraw, .002D); + IRenderer.emitAABB(toDraw, .002D); }); IRenderer.endLines(settings.renderSelectionBoxesIgnoreDepth.value); } - public static void drawDankLitGoalBox(Entity player, Goal goal, float partialTicks, Color color) { + public static void drawGoal(Entity player, Goal goal, float partialTicks, Color color) { + drawGoal(player, goal, partialTicks, color, true); + } + + public static void drawGoal(Entity player, Goal goal, float partialTicks, Color color, boolean setupRender) { double renderPosX = renderManager.viewerPosX; double renderPosY = renderManager.viewerPosY; double renderPosZ = renderManager.viewerPosZ; @@ -232,6 +238,7 @@ public final class PathRenderer implements IRenderer { y2 -= 0.5; maxY--; } + drawDankLitGoalBox(color, minX, maxX, minZ, maxZ, minY, maxY, y1, y2, setupRender); } else if (goal instanceof GoalXZ) { GoalXZ goalPos = (GoalXZ) goal; @@ -273,14 +280,22 @@ public final class PathRenderer implements IRenderer { y2 = 0; minY = 0 - renderPosY; maxY = 256 - renderPosY; + drawDankLitGoalBox(color, minX, maxX, minZ, maxZ, minY, maxY, y1, y2, setupRender); } else if (goal instanceof GoalComposite) { - for (Goal g : ((GoalComposite) goal).goals()) { - drawDankLitGoalBox(player, g, partialTicks, color); + // Simple way to determine if goals can be batched, without having some sort of GoalRenderer + boolean batch = Arrays.stream(((GoalComposite) goal).goals()).allMatch(IGoalRenderPos.class::isInstance); + + if (batch) { + IRenderer.startLines(color, settings.goalRenderLineWidthPixels.value, settings.renderGoalIgnoreDepth.value); + } + for (Goal g : ((GoalComposite) goal).goals()) { + drawGoal(player, g, partialTicks, color, !batch); + } + if (batch) { + IRenderer.endLines(settings.renderGoalIgnoreDepth.value); } - return; } else if (goal instanceof GoalInverted) { - drawDankLitGoalBox(player, ((GoalInverted) goal).origin, partialTicks, settings.colorInvertedGoalBox.value); - return; + drawGoal(player, ((GoalInverted) goal).origin, partialTicks, settings.colorInvertedGoalBox.value); } else if (goal instanceof GoalYLevel) { GoalYLevel goalpos = (GoalYLevel) goal; minX = player.posX - settings.yLevelBoxSize.value - renderPosX; @@ -291,16 +306,18 @@ public final class PathRenderer implements IRenderer { maxY = minY + 2; y1 = 1 + y + goalpos.level - renderPosY; y2 = 1 - y + goalpos.level - renderPosY; - } else { - return; + drawDankLitGoalBox(color, minX, maxX, minZ, maxZ, minY, maxY, y1, y2, setupRender); } + } - IRenderer.startLines(color, settings.goalRenderLineWidthPixels.value, settings.renderGoalIgnoreDepth.value); + private static void drawDankLitGoalBox(Color color, double minX, double maxX, double minZ, double maxZ, double minY, double maxY, double y1, double y2, boolean setupRender) { + if (setupRender) { + IRenderer.startLines(color, settings.goalRenderLineWidthPixels.value, settings.renderGoalIgnoreDepth.value); + } renderHorizontalQuad(minX, maxX, minZ, maxZ, y1); renderHorizontalQuad(minX, maxX, minZ, maxZ, y2); - buffer.begin(GL_LINES, DefaultVertexFormats.POSITION); buffer.pos(minX, minY, minZ).endVertex(); buffer.pos(minX, maxY, minZ).endVertex(); buffer.pos(maxX, minY, minZ).endVertex(); @@ -309,19 +326,25 @@ public final class PathRenderer implements IRenderer { buffer.pos(maxX, maxY, maxZ).endVertex(); buffer.pos(minX, minY, maxZ).endVertex(); buffer.pos(minX, maxY, maxZ).endVertex(); - tessellator.draw(); - IRenderer.endLines(settings.renderGoalIgnoreDepth.value); + if (setupRender) { + IRenderer.endLines(settings.renderGoalIgnoreDepth.value); + } } private static void renderHorizontalQuad(double minX, double maxX, double minZ, double maxZ, double y) { if (y != 0) { - buffer.begin(GL_LINE_LOOP, DefaultVertexFormats.POSITION); buffer.pos(minX, y, minZ).endVertex(); buffer.pos(maxX, y, minZ).endVertex(); + + buffer.pos(maxX, y, minZ).endVertex(); + buffer.pos(maxX, y, maxZ).endVertex(); + buffer.pos(maxX, y, maxZ).endVertex(); buffer.pos(minX, y, maxZ).endVertex(); - tessellator.draw(); + + buffer.pos(minX, y, maxZ).endVertex(); + buffer.pos(minX, y, minZ).endVertex(); } } } From c8a0ae9e102e9f85efba642f8a52744d7dc2d1d1 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 12 Jun 2023 13:44:08 -0500 Subject: [PATCH 071/405] Do `nudgeToLevel` and `randomLooking` when using freeLook --- .../java/baritone/behavior/LookBehavior.java | 46 ++++++++----------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index d1e5d244f..0dc56a3e2 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -58,43 +58,37 @@ public final class LookBehavior extends Behavior implements ILookBehavior { @Override public void onPlayerUpdate(PlayerUpdateEvent event) { - if (this.target == null) { + if (this.target == null || this.target.mode == Target.Mode.NONE) { return; } switch (event.getState()) { case PRE: { - switch (this.target.mode) { - case CLIENT: { - ctx.player().rotationYaw = this.target.rotation.getYaw(); - float oldPitch = ctx.player().rotationPitch; - float desiredPitch = this.target.rotation.getPitch(); - ctx.player().rotationPitch = desiredPitch; - ctx.player().rotationYaw += (Math.random() - 0.5) * Baritone.settings().randomLooking.value; - ctx.player().rotationPitch += (Math.random() - 0.5) * Baritone.settings().randomLooking.value; - if (desiredPitch == oldPitch && !Baritone.settings().freeLook.value) { - nudgeToLevel(); - } - // The target can be invalidated now since it won't be needed for RotationMoveEvent - this.target = null; - break; - } - case SERVER: { - // Copy the player's actual rotation - this.prevRotation = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch); - ctx.player().rotationYaw = this.target.rotation.getYaw(); - ctx.player().rotationPitch = this.target.rotation.getPitch(); - break; - } - default: - break; + if (this.target.mode == Target.Mode.SERVER) { + this.prevRotation = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch); + } + + ctx.player().rotationYaw = this.target.rotation.getYaw(); + float oldPitch = ctx.playerRotations().getPitch(); + float desiredPitch = this.target.rotation.getPitch(); + ctx.player().rotationPitch = desiredPitch; + ctx.player().rotationYaw += (Math.random() - 0.5) * Baritone.settings().randomLooking.value; + ctx.player().rotationPitch += (Math.random() - 0.5) * Baritone.settings().randomLooking.value; + if (desiredPitch == oldPitch) { + nudgeToLevel(); + } + + if (this.target.mode == Target.Mode.CLIENT) { + // The target can be invalidated now since it won't be needed for RotationMoveEvent + this.target = null; } break; } case POST: { // Reset the player's rotations back to their original values - if (this.target.mode == Target.Mode.SERVER) { + if (this.prevRotation != null) { ctx.player().rotationYaw = this.prevRotation.getYaw(); ctx.player().rotationPitch = this.prevRotation.getPitch(); + this.prevRotation = null; } // The target is done being used for this game tick, so it can be invalidated this.target = null; From ed34ae73c002d5b23e0e6efc36283dfbe4c78fb7 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 12 Jun 2023 13:46:10 -0500 Subject: [PATCH 072/405] Fix `Mode.NONE` target invalidation --- src/main/java/baritone/behavior/LookBehavior.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index 0dc56a3e2..1e109482c 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -58,11 +58,14 @@ public final class LookBehavior extends Behavior implements ILookBehavior { @Override public void onPlayerUpdate(PlayerUpdateEvent event) { - if (this.target == null || this.target.mode == Target.Mode.NONE) { + if (this.target == null) { return; } switch (event.getState()) { case PRE: { + if (this.target.mode == Target.Mode.NONE) { + return; + } if (this.target.mode == Target.Mode.SERVER) { this.prevRotation = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch); } From de80527702af9419f9c932609f729361261f3427 Mon Sep 17 00:00:00 2001 From: John200410 <43681932+John200410@users.noreply.github.com> Date: Mon, 12 Jun 2023 17:16:07 -0400 Subject: [PATCH 073/405] Add proper level height to GoalXZ rendering --- src/main/java/baritone/utils/PathRenderer.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index 5f50962e7..ff225c829 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -252,6 +252,8 @@ public final class PathRenderer implements IRenderer, Helper { } } else if (goal instanceof GoalXZ) { GoalXZ goalPos = (GoalXZ) goal; + minY = mc.level.getMinBuildHeight(); + maxY = mc.level.getMaxBuildHeight(); if (settings.renderGoalXZBeacon.value) { glPushAttrib(GL_LIGHTING_BIT); @@ -273,8 +275,8 @@ public final class PathRenderer implements IRenderer, Helper { settings.renderGoalAnimated.value ? partialTicks : 0, 1.0F, settings.renderGoalAnimated.value ? player.level.getGameTime() : 0, - 0, - 256, + (int) minY, + (int) maxY, color.getColorComponents(null), // Arguments filled by the private method lol @@ -299,8 +301,8 @@ public final class PathRenderer implements IRenderer, Helper { y1 = 0; y2 = 0; - minY = 0 - renderPosY; - maxY = 256 - renderPosY; + minY -= renderPosY; + maxY -= renderPosY; } else if (goal instanceof GoalComposite) { for (Goal g : ((GoalComposite) goal).goals()) { drawDankLitGoalBox(stack, player, g, partialTicks, color); From 7da802a2389b832b79c41b26f6b4bf4025a9a84e Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 12 Jun 2023 16:21:05 -0500 Subject: [PATCH 074/405] Fix `censorCoordinates` recalc bug Adds `equals` and `toString` implementations where needed Replaces `toString` equality check with actual `equals` check in `forceRevalidate` --- .../baritone/api/pathing/goals/GoalAxis.java | 5 ++ .../baritone/api/pathing/goals/GoalBlock.java | 11 ++++ .../api/pathing/goals/GoalComposite.java | 9 +++ .../api/pathing/goals/GoalGetToBlock.java | 11 ++++ .../api/pathing/goals/GoalInverted.java | 11 ++++ .../baritone/api/pathing/goals/GoalNear.java | 12 ++++ .../api/pathing/goals/GoalRunAway.java | 12 ++++ .../pathing/goals/GoalStrictDirection.java | 13 +++++ .../api/pathing/goals/GoalTwoBlocks.java | 11 ++++ .../baritone/api/pathing/goals/GoalXZ.java | 10 ++++ .../api/pathing/goals/GoalYLevel.java | 9 +++ .../java/baritone/process/BuilderProcess.java | 57 +++++++++++++++++-- .../java/baritone/process/MineProcess.java | 15 +++++ .../baritone/utils/PathingControlManager.java | 2 +- 14 files changed, 183 insertions(+), 5 deletions(-) diff --git a/src/api/java/baritone/api/pathing/goals/GoalAxis.java b/src/api/java/baritone/api/pathing/goals/GoalAxis.java index 7c9b26705..ad8fb892e 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalAxis.java +++ b/src/api/java/baritone/api/pathing/goals/GoalAxis.java @@ -42,6 +42,11 @@ public class GoalAxis implements Goal { return flatAxisDistance * BaritoneAPI.getSettings().costHeuristic.value + GoalYLevel.calculate(BaritoneAPI.getSettings().axisHeight.value, y); } + @Override + public boolean equals(Object o) { + return o.getClass() == GoalAxis.class; + } + @Override public String toString() { return "GoalAxis"; diff --git a/src/api/java/baritone/api/pathing/goals/GoalBlock.java b/src/api/java/baritone/api/pathing/goals/GoalBlock.java index bd339549b..ad2c3eadb 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalBlock.java +++ b/src/api/java/baritone/api/pathing/goals/GoalBlock.java @@ -66,6 +66,17 @@ public class GoalBlock implements Goal, IGoalRenderPos { return calculate(xDiff, yDiff, zDiff); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + GoalBlock goal = (GoalBlock) o; + if (x != goal.x) return false; + if (y != goal.y) return false; + return z == goal.z; + } + @Override public String toString() { return String.format( diff --git a/src/api/java/baritone/api/pathing/goals/GoalComposite.java b/src/api/java/baritone/api/pathing/goals/GoalComposite.java index 47522492b..f407fe733 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalComposite.java +++ b/src/api/java/baritone/api/pathing/goals/GoalComposite.java @@ -67,6 +67,15 @@ public class GoalComposite implements Goal { return min; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + GoalComposite goal = (GoalComposite) o; + return Arrays.equals(goals, goal.goals); + } + @Override public String toString() { return "GoalComposite" + Arrays.toString(goals); diff --git a/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java b/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java index 8d6fdcb30..3d2c0713a 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java +++ b/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java @@ -60,6 +60,17 @@ public class GoalGetToBlock implements Goal, IGoalRenderPos { return GoalBlock.calculate(xDiff, yDiff < 0 ? yDiff + 1 : yDiff, zDiff); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + GoalGetToBlock goal = (GoalGetToBlock) o; + if (x != goal.x) return false; + if (y != goal.y) return false; + return z == goal.z; + } + @Override public String toString() { return String.format( diff --git a/src/api/java/baritone/api/pathing/goals/GoalInverted.java b/src/api/java/baritone/api/pathing/goals/GoalInverted.java index 354e2ce39..acfdd68b2 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalInverted.java +++ b/src/api/java/baritone/api/pathing/goals/GoalInverted.java @@ -17,6 +17,8 @@ package baritone.api.pathing.goals; +import java.util.Objects; + /** * Invert any goal. *

@@ -50,6 +52,15 @@ public class GoalInverted implements Goal { return Double.NEGATIVE_INFINITY; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + GoalInverted goal = (GoalInverted) o; + return Objects.equals(origin, goal.origin); + } + @Override public String toString() { return String.format("GoalInverted{%s}", origin.toString()); diff --git a/src/api/java/baritone/api/pathing/goals/GoalNear.java b/src/api/java/baritone/api/pathing/goals/GoalNear.java index 2252446cd..44f0ab040 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalNear.java +++ b/src/api/java/baritone/api/pathing/goals/GoalNear.java @@ -86,6 +86,18 @@ public class GoalNear implements Goal, IGoalRenderPos { return new BlockPos(x, y, z); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + GoalNear goal = (GoalNear) o; + if (x != goal.x) return false; + if (y != goal.y) return false; + if (z != goal.z) return false; + return rangeSq == goal.rangeSq; + } + @Override public String toString() { return String.format( diff --git a/src/api/java/baritone/api/pathing/goals/GoalRunAway.java b/src/api/java/baritone/api/pathing/goals/GoalRunAway.java index b704ae4a6..3d7caa734 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalRunAway.java +++ b/src/api/java/baritone/api/pathing/goals/GoalRunAway.java @@ -23,6 +23,7 @@ import it.unimi.dsi.fastutil.doubles.DoubleOpenHashSet; import net.minecraft.util.math.BlockPos; import java.util.Arrays; +import java.util.Objects; /** * Useful for automated combat (retreating specifically) @@ -124,6 +125,17 @@ public class GoalRunAway implements Goal { return maxInside; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + GoalRunAway goal = (GoalRunAway) o; + if (distanceSq != goal.distanceSq) return false; + if (!Arrays.equals(from, goal.from)) return false; + return Objects.equals(maintainY, goal.maintainY); + } + @Override public String toString() { if (maintainY != null) { diff --git a/src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java b/src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java index e93f47ac0..86208f0ca 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java +++ b/src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java @@ -69,6 +69,19 @@ public class GoalStrictDirection implements Goal { return Double.NEGATIVE_INFINITY; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + GoalStrictDirection goal = (GoalStrictDirection) o; + if (x != goal.x) return false; + if (y != goal.y) return false; + if (z != goal.z) return false; + if (dx != goal.dx) return false; + return dz == goal.dz; + } + @Override public String toString() { return String.format( diff --git a/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java b/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java index 27be981e4..4df65f609 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java +++ b/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java @@ -72,6 +72,17 @@ public class GoalTwoBlocks implements Goal, IGoalRenderPos { return new BlockPos(x, y, z); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + GoalTwoBlocks goal = (GoalTwoBlocks) o; + if (x != goal.x) return false; + if (y != goal.y) return false; + return z == goal.z; + } + @Override public String toString() { return String.format( diff --git a/src/api/java/baritone/api/pathing/goals/GoalXZ.java b/src/api/java/baritone/api/pathing/goals/GoalXZ.java index 63d39cd78..c77743389 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalXZ.java +++ b/src/api/java/baritone/api/pathing/goals/GoalXZ.java @@ -64,6 +64,16 @@ public class GoalXZ implements Goal { return calculate(xDiff, zDiff); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + GoalXZ goal = (GoalXZ) o; + if (x != goal.x) return false; + return z == goal.z; + } + @Override public String toString() { return String.format( diff --git a/src/api/java/baritone/api/pathing/goals/GoalYLevel.java b/src/api/java/baritone/api/pathing/goals/GoalYLevel.java index 603ef9bd1..8fc7850b9 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalYLevel.java +++ b/src/api/java/baritone/api/pathing/goals/GoalYLevel.java @@ -58,6 +58,15 @@ public class GoalYLevel implements Goal, ActionCosts { return 0; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + GoalYLevel goal = (GoalYLevel) o; + return level == goal.level; + } + @Override public String toString() { return String.format( diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index c7868a4a0..f9514fb95 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -30,10 +30,7 @@ import baritone.api.schematic.ISchematic; import baritone.api.schematic.IStaticSchematic; import baritone.api.schematic.SubstituteSchematic; import baritone.api.schematic.format.ISchematicFormat; -import baritone.api.utils.BetterBlockPos; -import baritone.api.utils.RayTraceUtils; -import baritone.api.utils.Rotation; -import baritone.api.utils.RotationUtils; +import baritone.api.utils.*; import baritone.api.utils.input.Input; import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.Movement; @@ -764,6 +761,16 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil return primary.heuristic(x, y, z); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + JankyGoalComposite goal = (JankyGoalComposite) o; + if (!Objects.equals(primary, goal.primary)) return false; + return Objects.equals(fallback, goal.fallback); + } + @Override public String toString() { return "JankyComposite Primary: " + primary + " Fallback: " + fallback; @@ -785,6 +792,16 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil // but any other adjacent works for breaking, including inside or below return super.isInGoal(x, y, z); } + + @Override + public String toString() { + return String.format( + "GoalBreak{x=%s,y=%s,z=%s}", + SettingsUtil.maybeCensor(x), + SettingsUtil.maybeCensor(y), + SettingsUtil.maybeCensor(z) + ); + } } private Goal placementGoal(BlockPos pos, BuilderCalculationContext bcc) { @@ -828,6 +845,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil this.allowSameLevel = allowSameLevel; } + @Override public boolean isInGoal(int x, int y, int z) { if (x == this.x && y == this.y && z == this.z) { return false; @@ -844,10 +862,30 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil return super.isInGoal(x, y, z); } + @Override public double heuristic(int x, int y, int z) { // prioritize lower y coordinates return this.y * 100 + super.heuristic(x, y, z); } + + @Override + public boolean equals(Object o) { + if (!super.equals(o)) return false; + + GoalAdjacent goal = (GoalAdjacent) o; + if (allowSameLevel != goal.allowSameLevel) return false; + return Objects.equals(no, goal.no); + } + + @Override + public String toString() { + return String.format( + "GoalAdjacent{x=%s,y=%s,z=%s}", + SettingsUtil.maybeCensor(x), + SettingsUtil.maybeCensor(y), + SettingsUtil.maybeCensor(z) + ); + } } public static class GoalPlace extends GoalBlock { @@ -856,10 +894,21 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil super(placeAt.up()); } + @Override public double heuristic(int x, int y, int z) { // prioritize lower y coordinates return this.y * 100 + super.heuristic(x, y, z); } + + @Override + public String toString() { + return String.format( + "GoalPlace{x=%s,y=%s,z=%s}", + SettingsUtil.maybeCensor(x), + SettingsUtil.maybeCensor(y), + SettingsUtil.maybeCensor(z) + ); + } } @Override diff --git a/src/main/java/baritone/process/MineProcess.java b/src/main/java/baritone/process/MineProcess.java index 6880dd86c..866dcc19d 100644 --- a/src/main/java/baritone/process/MineProcess.java +++ b/src/main/java/baritone/process/MineProcess.java @@ -319,6 +319,21 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro int zDiff = z - this.z; return GoalBlock.calculate(xDiff, yDiff < -1 ? yDiff + 2 : yDiff == -1 ? 0 : yDiff, zDiff); } + + @Override + public boolean equals(Object o) { + return super.equals(o); + } + + @Override + public String toString() { + return String.format( + "GoalThreeBlocks{x=%s,y=%s,z=%s}", + SettingsUtil.maybeCensor(x), + SettingsUtil.maybeCensor(y), + SettingsUtil.maybeCensor(z) + ); + } } public List droppedItemsScan() { diff --git a/src/main/java/baritone/utils/PathingControlManager.java b/src/main/java/baritone/utils/PathingControlManager.java index a83e53a1e..236e41cc6 100644 --- a/src/main/java/baritone/utils/PathingControlManager.java +++ b/src/main/java/baritone/utils/PathingControlManager.java @@ -160,7 +160,7 @@ public class PathingControlManager implements IPathingControlManager { if (newGoal.isInGoal(current.getPath().getDest())) { return false; } - return !newGoal.toString().equals(current.getPath().getGoal().toString()); + return !newGoal.equals(current.getPath().getGoal()); } return false; } From 5bdd5b0c0d095797021481a8816600c954883335 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 12 Jun 2023 16:50:02 -0500 Subject: [PATCH 075/405] =?UTF-8?q?=F0=9F=91=8C=20appease=20leijurv?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../baritone/api/pathing/goals/GoalBlock.java | 14 ++++++++----- .../api/pathing/goals/GoalComposite.java | 8 ++++++-- .../api/pathing/goals/GoalGetToBlock.java | 14 ++++++++----- .../api/pathing/goals/GoalInverted.java | 8 ++++++-- .../baritone/api/pathing/goals/GoalNear.java | 16 +++++++++------ .../api/pathing/goals/GoalRunAway.java | 14 ++++++++----- .../pathing/goals/GoalStrictDirection.java | 18 ++++++++++------- .../api/pathing/goals/GoalTwoBlocks.java | 14 ++++++++----- .../baritone/api/pathing/goals/GoalXZ.java | 11 ++++++---- .../api/pathing/goals/GoalYLevel.java | 8 ++++++-- .../java/baritone/process/BuilderProcess.java | 20 ++++++++++++------- 11 files changed, 95 insertions(+), 50 deletions(-) diff --git a/src/api/java/baritone/api/pathing/goals/GoalBlock.java b/src/api/java/baritone/api/pathing/goals/GoalBlock.java index ad2c3eadb..68d783aa3 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalBlock.java +++ b/src/api/java/baritone/api/pathing/goals/GoalBlock.java @@ -68,13 +68,17 @@ public class GoalBlock implements Goal, IGoalRenderPos { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } GoalBlock goal = (GoalBlock) o; - if (x != goal.x) return false; - if (y != goal.y) return false; - return z == goal.z; + return x == goal.x + && y != goal.y + && z == goal.z; } @Override diff --git a/src/api/java/baritone/api/pathing/goals/GoalComposite.java b/src/api/java/baritone/api/pathing/goals/GoalComposite.java index f407fe733..d64f8e33e 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalComposite.java +++ b/src/api/java/baritone/api/pathing/goals/GoalComposite.java @@ -69,8 +69,12 @@ public class GoalComposite implements Goal { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } GoalComposite goal = (GoalComposite) o; return Arrays.equals(goals, goal.goals); diff --git a/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java b/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java index 3d2c0713a..b5caafa48 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java +++ b/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java @@ -62,13 +62,17 @@ public class GoalGetToBlock implements Goal, IGoalRenderPos { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } GoalGetToBlock goal = (GoalGetToBlock) o; - if (x != goal.x) return false; - if (y != goal.y) return false; - return z == goal.z; + return x == goal.x + && y == goal.y + && z == goal.z; } @Override diff --git a/src/api/java/baritone/api/pathing/goals/GoalInverted.java b/src/api/java/baritone/api/pathing/goals/GoalInverted.java index acfdd68b2..e559088ef 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalInverted.java +++ b/src/api/java/baritone/api/pathing/goals/GoalInverted.java @@ -54,8 +54,12 @@ public class GoalInverted implements Goal { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } GoalInverted goal = (GoalInverted) o; return Objects.equals(origin, goal.origin); diff --git a/src/api/java/baritone/api/pathing/goals/GoalNear.java b/src/api/java/baritone/api/pathing/goals/GoalNear.java index 44f0ab040..166138ff4 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalNear.java +++ b/src/api/java/baritone/api/pathing/goals/GoalNear.java @@ -88,14 +88,18 @@ public class GoalNear implements Goal, IGoalRenderPos { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } GoalNear goal = (GoalNear) o; - if (x != goal.x) return false; - if (y != goal.y) return false; - if (z != goal.z) return false; - return rangeSq == goal.rangeSq; + return x == goal.x + && y == goal.y + && z == goal.z + && rangeSq == goal.rangeSq; } @Override diff --git a/src/api/java/baritone/api/pathing/goals/GoalRunAway.java b/src/api/java/baritone/api/pathing/goals/GoalRunAway.java index 3d7caa734..166ad5a98 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalRunAway.java +++ b/src/api/java/baritone/api/pathing/goals/GoalRunAway.java @@ -127,13 +127,17 @@ public class GoalRunAway implements Goal { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } GoalRunAway goal = (GoalRunAway) o; - if (distanceSq != goal.distanceSq) return false; - if (!Arrays.equals(from, goal.from)) return false; - return Objects.equals(maintainY, goal.maintainY); + return distanceSq == goal.distanceSq + && Arrays.equals(from, goal.from) + && Objects.equals(maintainY, goal.maintainY); } @Override diff --git a/src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java b/src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java index 86208f0ca..3d9909ad1 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java +++ b/src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java @@ -71,15 +71,19 @@ public class GoalStrictDirection implements Goal { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } GoalStrictDirection goal = (GoalStrictDirection) o; - if (x != goal.x) return false; - if (y != goal.y) return false; - if (z != goal.z) return false; - if (dx != goal.dx) return false; - return dz == goal.dz; + return x == goal.x + && y != goal.y + && z == goal.z + && dx == goal.dx + && dz == goal.dz; } @Override diff --git a/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java b/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java index 4df65f609..d6fff33a2 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java +++ b/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java @@ -74,13 +74,17 @@ public class GoalTwoBlocks implements Goal, IGoalRenderPos { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } GoalTwoBlocks goal = (GoalTwoBlocks) o; - if (x != goal.x) return false; - if (y != goal.y) return false; - return z == goal.z; + return x == goal.x + && y == goal.y + && z == goal.z; } @Override diff --git a/src/api/java/baritone/api/pathing/goals/GoalXZ.java b/src/api/java/baritone/api/pathing/goals/GoalXZ.java index c77743389..2c551d395 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalXZ.java +++ b/src/api/java/baritone/api/pathing/goals/GoalXZ.java @@ -66,12 +66,15 @@ public class GoalXZ implements Goal { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } GoalXZ goal = (GoalXZ) o; - if (x != goal.x) return false; - return z == goal.z; + return x == goal.x && z == goal.z; } @Override diff --git a/src/api/java/baritone/api/pathing/goals/GoalYLevel.java b/src/api/java/baritone/api/pathing/goals/GoalYLevel.java index 8fc7850b9..37745e8de 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalYLevel.java +++ b/src/api/java/baritone/api/pathing/goals/GoalYLevel.java @@ -60,8 +60,12 @@ public class GoalYLevel implements Goal, ActionCosts { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } GoalYLevel goal = (GoalYLevel) o; return level == goal.level; diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index f9514fb95..69368282d 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -763,12 +763,16 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } JankyGoalComposite goal = (JankyGoalComposite) o; - if (!Objects.equals(primary, goal.primary)) return false; - return Objects.equals(fallback, goal.fallback); + return Objects.equals(primary, goal.primary) + && Objects.equals(fallback, goal.fallback); } @Override @@ -870,11 +874,13 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil @Override public boolean equals(Object o) { - if (!super.equals(o)) return false; + if (!super.equals(o)) { + return false; + } GoalAdjacent goal = (GoalAdjacent) o; - if (allowSameLevel != goal.allowSameLevel) return false; - return Objects.equals(no, goal.no); + return allowSameLevel == goal.allowSameLevel + && Objects.equals(no, goal.no); } @Override From 8a65a1cfc593be38405bf9420be17988f93959c7 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 12 Jun 2023 16:52:20 -0500 Subject: [PATCH 076/405] =?UTF-8?q?=F0=9F=90=9B=20fix=20incorrect=20compar?= =?UTF-8?q?ison=20operator?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/java/baritone/api/pathing/goals/GoalBlock.java | 2 +- .../java/baritone/api/pathing/goals/GoalStrictDirection.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/java/baritone/api/pathing/goals/GoalBlock.java b/src/api/java/baritone/api/pathing/goals/GoalBlock.java index 68d783aa3..d76fdc7af 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalBlock.java +++ b/src/api/java/baritone/api/pathing/goals/GoalBlock.java @@ -77,7 +77,7 @@ public class GoalBlock implements Goal, IGoalRenderPos { GoalBlock goal = (GoalBlock) o; return x == goal.x - && y != goal.y + && y == goal.y && z == goal.z; } diff --git a/src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java b/src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java index 3d9909ad1..b8e4b43b2 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java +++ b/src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java @@ -80,7 +80,7 @@ public class GoalStrictDirection implements Goal { GoalStrictDirection goal = (GoalStrictDirection) o; return x == goal.x - && y != goal.y + && y == goal.y && z == goal.z && dx == goal.dx && dz == goal.dz; From c217a34f1368bff64bbf8123e9c7eae1a89e3881 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 12 Jun 2023 17:05:56 -0500 Subject: [PATCH 077/405] =?UTF-8?q?=F0=9F=90=9B=20fix=20batch=20render=20c?= =?UTF-8?q?olor=20bug=20by=20backporting=201.17+=20render=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/baritone/utils/IRenderer.java | 57 ++++++++++--------- .../java/baritone/utils/PathRenderer.java | 52 ++++++++--------- 2 files changed, 57 insertions(+), 52 deletions(-) diff --git a/src/main/java/baritone/utils/IRenderer.java b/src/main/java/baritone/utils/IRenderer.java index 3476c0307..26a7cf1ad 100644 --- a/src/main/java/baritone/utils/IRenderer.java +++ b/src/main/java/baritone/utils/IRenderer.java @@ -38,9 +38,14 @@ public interface IRenderer { RenderManager renderManager = Helper.mc.getRenderManager(); Settings settings = BaritoneAPI.getSettings(); + float[] color = new float[] {1.0F, 1.0F, 1.0F, 255.0F}; + static void glColor(Color color, float alpha) { float[] colorComponents = color.getColorComponents(null); - GlStateManager.color(colorComponents[0], colorComponents[1], colorComponents[2], alpha); + IRenderer.color[0] = colorComponents[0]; + IRenderer.color[1] = colorComponents[1]; + IRenderer.color[2] = colorComponents[2]; + IRenderer.color[3] = alpha; } static void startLines(Color color, float alpha, float lineWidth, boolean ignoreDepth) { @@ -54,7 +59,7 @@ public interface IRenderer { if (ignoreDepth) { GlStateManager.disableDepth(); } - buffer.begin(GL_LINES, DefaultVertexFormats.POSITION); + buffer.begin(GL_LINES, DefaultVertexFormats.POSITION_COLOR); } static void startLines(Color color, float lineWidth, boolean ignoreDepth) { @@ -76,32 +81,32 @@ public interface IRenderer { AxisAlignedBB toDraw = aabb.offset(-renderManager.viewerPosX, -renderManager.viewerPosY, -renderManager.viewerPosZ); // bottom - buffer.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).endVertex(); - buffer.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).endVertex(); - buffer.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).endVertex(); - buffer.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex(); + buffer.pos(toDraw.minX, toDraw.minY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.minX, toDraw.minY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); // top - buffer.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).endVertex(); - buffer.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).endVertex(); - buffer.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).endVertex(); - buffer.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex(); + buffer.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); // corners - buffer.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex(); - buffer.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).endVertex(); - buffer.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).endVertex(); - buffer.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).endVertex(); + buffer.pos(toDraw.minX, toDraw.minY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); } static void emitAABB(AxisAlignedBB aabb, double expand) { diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index 2aef0ab54..deec261d4 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -165,18 +165,18 @@ public final class PathRenderer implements IRenderer { double vpZ = renderManager.viewerPosZ; boolean renderPathAsFrickinThingy = !settings.renderPathAsLine.value; - buffer.pos(x1 + 0.5D - vpX, y1 + 0.5D - vpY, z1 + 0.5D - vpZ).endVertex(); - buffer.pos(x2 + 0.5D - vpX, y2 + 0.5D - vpY, z2 + 0.5D - vpZ).endVertex(); + buffer.pos(x1 + 0.5D - vpX, y1 + 0.5D - vpY, z1 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(x2 + 0.5D - vpX, y2 + 0.5D - vpY, z2 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); if (renderPathAsFrickinThingy) { - buffer.pos(x2 + 0.5D - vpX, y2 + 0.5D - vpY, z2 + 0.5D - vpZ).endVertex(); - buffer.pos(x2 + 0.5D - vpX, y2 + 0.53D - vpY, z2 + 0.5D - vpZ).endVertex(); + buffer.pos(x2 + 0.5D - vpX, y2 + 0.5D - vpY, z2 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(x2 + 0.5D - vpX, y2 + 0.53D - vpY, z2 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.pos(x2 + 0.5D - vpX, y2 + 0.53D - vpY, z2 + 0.5D - vpZ).endVertex(); - buffer.pos(x1 + 0.5D - vpX, y1 + 0.53D - vpY, z1 + 0.5D - vpZ).endVertex(); + buffer.pos(x2 + 0.5D - vpX, y2 + 0.53D - vpY, z2 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(x1 + 0.5D - vpX, y1 + 0.53D - vpY, z1 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.pos(x1 + 0.5D - vpX, y1 + 0.53D - vpY, z1 + 0.5D - vpZ).endVertex(); - buffer.pos(x1 + 0.5D - vpX, y1 + 0.5D - vpY, z1 + 0.5D - vpZ).endVertex(); + buffer.pos(x1 + 0.5D - vpX, y1 + 0.53D - vpY, z1 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(x1 + 0.5D - vpX, y1 + 0.5D - vpY, z1 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); } } @@ -310,22 +310,22 @@ public final class PathRenderer implements IRenderer { } } - private static void drawDankLitGoalBox(Color color, double minX, double maxX, double minZ, double maxZ, double minY, double maxY, double y1, double y2, boolean setupRender) { + private static void drawDankLitGoalBox(Color colorIn, double minX, double maxX, double minZ, double maxZ, double minY, double maxY, double y1, double y2, boolean setupRender) { if (setupRender) { - IRenderer.startLines(color, settings.goalRenderLineWidthPixels.value, settings.renderGoalIgnoreDepth.value); + IRenderer.startLines(colorIn, settings.goalRenderLineWidthPixels.value, settings.renderGoalIgnoreDepth.value); } renderHorizontalQuad(minX, maxX, minZ, maxZ, y1); renderHorizontalQuad(minX, maxX, minZ, maxZ, y2); - buffer.pos(minX, minY, minZ).endVertex(); - buffer.pos(minX, maxY, minZ).endVertex(); - buffer.pos(maxX, minY, minZ).endVertex(); - buffer.pos(maxX, maxY, minZ).endVertex(); - buffer.pos(maxX, minY, maxZ).endVertex(); - buffer.pos(maxX, maxY, maxZ).endVertex(); - buffer.pos(minX, minY, maxZ).endVertex(); - buffer.pos(minX, maxY, maxZ).endVertex(); + buffer.pos(minX, minY, minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(minX, maxY, minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(maxX, minY, minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(maxX, maxY, minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(maxX, minY, maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(maxX, maxY, maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(minX, minY, maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(minX, maxY, maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); if (setupRender) { IRenderer.endLines(settings.renderGoalIgnoreDepth.value); @@ -334,17 +334,17 @@ public final class PathRenderer implements IRenderer { private static void renderHorizontalQuad(double minX, double maxX, double minZ, double maxZ, double y) { if (y != 0) { - buffer.pos(minX, y, minZ).endVertex(); - buffer.pos(maxX, y, minZ).endVertex(); + buffer.pos(minX, y, minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(maxX, y, minZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.pos(maxX, y, minZ).endVertex(); - buffer.pos(maxX, y, maxZ).endVertex(); + buffer.pos(maxX, y, minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(maxX, y, maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.pos(maxX, y, maxZ).endVertex(); - buffer.pos(minX, y, maxZ).endVertex(); + buffer.pos(maxX, y, maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(minX, y, maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.pos(minX, y, maxZ).endVertex(); - buffer.pos(minX, y, minZ).endVertex(); + buffer.pos(minX, y, maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(minX, y, minZ).color(color[0], color[1], color[2], color[3]).endVertex(); } } } From 13fc58933d6cf1db497d5303d290f65588b6c652 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 12 Jun 2023 19:03:03 -0500 Subject: [PATCH 078/405] Don't bother returning `serverRotations` if no free look --- src/main/java/baritone/behavior/LookBehavior.java | 12 +++++++++--- .../baritone/utils/player/PrimaryPlayerContext.java | 7 ++----- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index 1e109482c..702c3738d 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -28,6 +28,8 @@ import baritone.api.utils.IPlayerContext; import baritone.api.utils.Rotation; import net.minecraft.network.play.client.CPacketPlayer; +import java.util.Optional; + public final class LookBehavior extends Behavior implements ILookBehavior { /** @@ -70,9 +72,9 @@ public final class LookBehavior extends Behavior implements ILookBehavior { this.prevRotation = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch); } - ctx.player().rotationYaw = this.target.rotation.getYaw(); float oldPitch = ctx.playerRotations().getPitch(); float desiredPitch = this.target.rotation.getPitch(); + ctx.player().rotationYaw = this.target.rotation.getYaw(); ctx.player().rotationPitch = desiredPitch; ctx.player().rotationYaw += (Math.random() - 0.5) * Baritone.settings().randomLooking.value; ctx.player().rotationPitch += (Math.random() - 0.5) * Baritone.settings().randomLooking.value; @@ -126,8 +128,12 @@ public final class LookBehavior extends Behavior implements ILookBehavior { } } - public Rotation getEffectiveRotation() { - return this.serverRotation; + public Optional getEffectiveRotation() { + if (Baritone.settings().freeLook.value || Baritone.settings().blockFreeLook.value) { + return Optional.of(this.serverRotation); + } + // If neither of the freeLook settings are on, just defer to the player's actual rotations + return Optional.empty(); } @Override diff --git a/src/main/java/baritone/utils/player/PrimaryPlayerContext.java b/src/main/java/baritone/utils/player/PrimaryPlayerContext.java index e4484f0be..20d82f2bc 100644 --- a/src/main/java/baritone/utils/player/PrimaryPlayerContext.java +++ b/src/main/java/baritone/utils/player/PrimaryPlayerContext.java @@ -58,11 +58,8 @@ public enum PrimaryPlayerContext implements IPlayerContext, Helper { @Override public Rotation playerRotations() { - final Rotation lbTarget = ((LookBehavior) BaritoneAPI.getProvider().getPrimaryBaritone().getLookBehavior()).getEffectiveRotation(); - if (lbTarget == null || !Baritone.settings().blockFreeLook.value) { - return IPlayerContext.super.playerRotations(); - } - return lbTarget; + return ((LookBehavior) BaritoneAPI.getProvider().getPrimaryBaritone().getLookBehavior()).getEffectiveRotation() + .orElseGet(IPlayerContext.super::playerRotations); } @Override From 4885d49d20debf7bc4f8328c11e08549e57c5abe Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 12 Jun 2023 20:00:03 -0500 Subject: [PATCH 079/405] Reorganize code --- .../java/baritone/behavior/LookBehavior.java | 32 ++++++++++++------- .../utils/player/PrimaryPlayerContext.java | 1 - 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index 702c3738d..db0c255f7 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -72,16 +72,23 @@ public final class LookBehavior extends Behavior implements ILookBehavior { this.prevRotation = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch); } - float oldPitch = ctx.playerRotations().getPitch(); + final float oldPitch = ctx.playerRotations().getPitch(); + + float desiredYaw = this.target.rotation.getYaw(); float desiredPitch = this.target.rotation.getPitch(); - ctx.player().rotationYaw = this.target.rotation.getYaw(); - ctx.player().rotationPitch = desiredPitch; - ctx.player().rotationYaw += (Math.random() - 0.5) * Baritone.settings().randomLooking.value; - ctx.player().rotationPitch += (Math.random() - 0.5) * Baritone.settings().randomLooking.value; + + // In other words, the target doesn't care about the pitch, so it used playerRotations().getPitch() + // and it's safe to adjust it to a normal level if (desiredPitch == oldPitch) { - nudgeToLevel(); + desiredPitch = nudgeToLevel(desiredPitch); } + desiredYaw += (Math.random() - 0.5) * Baritone.settings().randomLooking.value; + desiredPitch += (Math.random() - 0.5) * Baritone.settings().randomLooking.value; + + ctx.player().rotationYaw = desiredYaw; + ctx.player().rotationPitch = desiredPitch; + if (this.target.mode == Target.Mode.CLIENT) { // The target can be invalidated now since it won't be needed for RotationMoveEvent this.target = null; @@ -130,7 +137,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior { public Optional getEffectiveRotation() { if (Baritone.settings().freeLook.value || Baritone.settings().blockFreeLook.value) { - return Optional.of(this.serverRotation); + return Optional.ofNullable(this.serverRotation); } // If neither of the freeLook settings are on, just defer to the player's actual rotations return Optional.empty(); @@ -146,12 +153,13 @@ public final class LookBehavior extends Behavior implements ILookBehavior { /** * Nudges the player's pitch to a regular level. (Between {@code -20} and {@code 10}, increments are by {@code 1}) */ - private void nudgeToLevel() { - if (ctx.player().rotationPitch < -20) { - ctx.player().rotationPitch++; - } else if (ctx.player().rotationPitch > 10) { - ctx.player().rotationPitch--; + private float nudgeToLevel(float pitch) { + if (pitch < -20) { + return pitch + 1; + } else if (pitch > 10) { + return pitch - 1; } + return pitch; } private static class Target { diff --git a/src/main/java/baritone/utils/player/PrimaryPlayerContext.java b/src/main/java/baritone/utils/player/PrimaryPlayerContext.java index 20d82f2bc..02db73a5c 100644 --- a/src/main/java/baritone/utils/player/PrimaryPlayerContext.java +++ b/src/main/java/baritone/utils/player/PrimaryPlayerContext.java @@ -17,7 +17,6 @@ package baritone.utils.player; -import baritone.Baritone; import baritone.api.BaritoneAPI; import baritone.api.cache.IWorldData; import baritone.api.utils.*; From c8b8deb3d62d5a786054fd1939293cb71673258c Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 12 Jun 2023 21:04:30 -0500 Subject: [PATCH 080/405] Ensure angle delta is producible with mouse movement --- .../java/baritone/behavior/LookBehavior.java | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index db0c255f7..99e496e6f 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -24,6 +24,7 @@ import baritone.api.event.events.PacketEvent; import baritone.api.event.events.PlayerUpdateEvent; import baritone.api.event.events.RotationMoveEvent; import baritone.api.event.events.WorldEvent; +import baritone.api.utils.Helper; import baritone.api.utils.IPlayerContext; import baritone.api.utils.Rotation; import net.minecraft.network.play.client.CPacketPlayer; @@ -72,6 +73,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior { this.prevRotation = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch); } + final float oldYaw = ctx.playerRotations().getYaw(); final float oldPitch = ctx.playerRotations().getPitch(); float desiredYaw = this.target.rotation.getYaw(); @@ -86,8 +88,8 @@ public final class LookBehavior extends Behavior implements ILookBehavior { desiredYaw += (Math.random() - 0.5) * Baritone.settings().randomLooking.value; desiredPitch += (Math.random() - 0.5) * Baritone.settings().randomLooking.value; - ctx.player().rotationYaw = desiredYaw; - ctx.player().rotationPitch = desiredPitch; + ctx.player().rotationYaw = calculateMouseMove(oldYaw, desiredYaw); + ctx.player().rotationPitch = calculateMouseMove(oldPitch, desiredPitch); if (this.target.mode == Target.Mode.CLIENT) { // The target can be invalidated now since it won't be needed for RotationMoveEvent @@ -153,7 +155,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior { /** * Nudges the player's pitch to a regular level. (Between {@code -20} and {@code 10}, increments are by {@code 1}) */ - private float nudgeToLevel(float pitch) { + private static float nudgeToLevel(float pitch) { if (pitch < -20) { return pitch + 1; } else if (pitch > 10) { @@ -162,6 +164,22 @@ public final class LookBehavior extends Behavior implements ILookBehavior { return pitch; } + private static float calculateMouseMove(float current, float target) { + final float delta = target - current; + final int deltaPx = angleToMouse(delta); + return current + mouseToAngle(deltaPx); + } + + private static int angleToMouse(float angleDelta) { + final float minAngleChange = mouseToAngle(1); + return Math.round(angleDelta / minAngleChange); + } + + private static float mouseToAngle(int mouseDelta) { + final float f = Helper.mc.gameSettings.mouseSensitivity * 0.6f + 0.2f; + return mouseDelta * f * f * f * 8.0f * 0.15f; + } + private static class Target { public final Rotation rotation; From 2022d33d03296a41689fa4cd186b15ecc2e8a324 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 12 Jun 2023 21:12:49 -0500 Subject: [PATCH 081/405] Fix incorrect references to player and world --- .../java/baritone/command/defaults/SurfaceCommand.java | 8 ++++---- .../java/baritone/process/InventoryPauserProcess.java | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/baritone/command/defaults/SurfaceCommand.java b/src/main/java/baritone/command/defaults/SurfaceCommand.java index 842b8050c..5d914aded 100644 --- a/src/main/java/baritone/command/defaults/SurfaceCommand.java +++ b/src/main/java/baritone/command/defaults/SurfaceCommand.java @@ -38,13 +38,13 @@ public class SurfaceCommand extends Command { @Override public void execute(String label, IArgConsumer args) throws CommandException { - final BetterBlockPos playerPos = baritone.getPlayerContext().playerFeet(); - final int surfaceLevel = baritone.getPlayerContext().world().getSeaLevel(); - final int worldHeight = baritone.getPlayerContext().world().getActualHeight(); + final BetterBlockPos playerPos = ctx.playerFeet(); + final int surfaceLevel = ctx.world().getSeaLevel(); + final int worldHeight = ctx.world().getActualHeight(); // Ensure this command will not run if you are above the surface level and the block above you is air // As this would imply that your are already on the open surface - if (playerPos.getY() > surfaceLevel && mc.world.getBlockState(playerPos.up()).getBlock() instanceof BlockAir) { + if (playerPos.getY() > surfaceLevel && ctx.world().getBlockState(playerPos.up()).getBlock() instanceof BlockAir) { logDirect("Already at surface"); return; } diff --git a/src/main/java/baritone/process/InventoryPauserProcess.java b/src/main/java/baritone/process/InventoryPauserProcess.java index ab210532b..9752912b9 100644 --- a/src/main/java/baritone/process/InventoryPauserProcess.java +++ b/src/main/java/baritone/process/InventoryPauserProcess.java @@ -34,14 +34,14 @@ public class InventoryPauserProcess extends BaritoneProcessHelper { @Override public boolean isActive() { - if (mc.player == null || mc.world == null) { + if (ctx.player() == null || ctx.world() == null) { return false; } return true; } private double motion() { - return Math.sqrt(mc.player.motionX * mc.player.motionX + mc.player.motionZ * mc.player.motionZ); + return Math.sqrt(ctx.player().motionX * ctx.player().motionX + ctx.player().motionZ * ctx.player().motionZ); } private boolean stationaryNow() { From 76fe0d14d3199cf219d3a67ddada62f0153aa702 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 12 Jun 2023 21:13:10 -0500 Subject: [PATCH 082/405] Simplify some player context references --- src/main/java/baritone/command/defaults/GoalCommand.java | 2 +- src/main/java/baritone/command/defaults/GotoCommand.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/command/defaults/GoalCommand.java b/src/main/java/baritone/command/defaults/GoalCommand.java index 40822e057..a174ecad9 100644 --- a/src/main/java/baritone/command/defaults/GoalCommand.java +++ b/src/main/java/baritone/command/defaults/GoalCommand.java @@ -51,7 +51,7 @@ public class GoalCommand extends Command { } } else { args.requireMax(3); - BetterBlockPos origin = baritone.getPlayerContext().playerFeet(); + BetterBlockPos origin = ctx.playerFeet(); Goal goal = args.getDatatypePost(RelativeGoal.INSTANCE, origin); goalProcess.setGoal(goal); logDirect(String.format("Goal: %s", goal.toString())); diff --git a/src/main/java/baritone/command/defaults/GotoCommand.java b/src/main/java/baritone/command/defaults/GotoCommand.java index 896e3f5f8..333d7fa57 100644 --- a/src/main/java/baritone/command/defaults/GotoCommand.java +++ b/src/main/java/baritone/command/defaults/GotoCommand.java @@ -46,7 +46,7 @@ public class GotoCommand extends Command { // is no need to handle the case of empty arguments. if (args.peekDatatypeOrNull(RelativeCoordinate.INSTANCE) != null) { args.requireMax(3); - BetterBlockPos origin = baritone.getPlayerContext().playerFeet(); + BetterBlockPos origin = ctx.playerFeet(); Goal goal = args.getDatatypePost(RelativeGoal.INSTANCE, origin); logDirect(String.format("Going to: %s", goal.toString())); baritone.getCustomGoalProcess().setGoalAndPath(goal); From 44cd5dcd415bc01151797b97bbd5f591de46ac5f Mon Sep 17 00:00:00 2001 From: Leijurv Date: Mon, 12 Jun 2023 21:43:10 -0700 Subject: [PATCH 083/405] go around glowstone and nether fortresses --- src/main/java/baritone/Elytra.java | 154 +++++++++++++++++++++++++++-- 1 file changed, 145 insertions(+), 9 deletions(-) diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index 708f6621d..9607fbcdb 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -26,6 +26,7 @@ import baritone.behavior.Behavior; import baritone.utils.BlockStateInterface; import com.mojang.realmsclient.util.Pair; import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.item.EntityFireworkRocket; import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; @@ -36,10 +37,7 @@ import net.minecraft.util.math.Vec3d; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; public class Elytra extends Behavior implements Helper { @@ -65,6 +63,139 @@ public class Elytra extends Behavior implements Helper { public int sinceFirework; public BlockPos goal; + private void pathfindAroundObstacles() { + outer: + while (true) { + int rangeStartIncl = playerNear; + int rangeEndExcl = playerNear; + while (rangeEndExcl < path.size() && ctx.world().isBlockLoaded(path.get(rangeEndExcl), false)) { + rangeEndExcl++; + } + if (rangeStartIncl >= rangeEndExcl) { + // not loaded yet? + return; + } + if (!passable(ctx.world().getBlockState(path.get(rangeStartIncl)))) { + // we're in a wall + return; // previous iterations of this function SHOULD have fixed this by now :rage_cat: + } + for (int i = rangeStartIncl; i < rangeEndExcl - 1; i++) { + if (!clearView(pathAt(i), pathAt(i + 1))) { + // obstacle. where do we return to pathing? + // find the next valid segment + for (int j = i + 1; j < rangeEndExcl - 1; j++) { + if (clearView(pathAt(j), pathAt(j + 1))) { + // found it + // path from i to j + List newPath = simplePathfind(path.get(i), path.get(j)); + if (newPath == null) { + logDirect("no path"); + return; + } + path.subList(i + 1, j).clear(); + for (int k = newPath.size() - 1; k >= 0; k--) { + path.add(i + 1, newPath.get(k)); + } + logDirect("replaced path starting at " + path.get(i)); + removeBacktracks(); + break outer; // eventually "continue outer" + } + } + } + } + break; + } + } + + private int manhattanDist(BlockPos start, BlockPos dest) { + return Math.abs(start.getX() - dest.getX()) + Math.abs(start.getY() - dest.getY()) + Math.abs(start.getZ() - dest.getZ()); + } + + private class SearchNode { + BetterBlockPos pos; + int dist; + int heuristic; + SearchNode prev; + boolean canceled; + + public SearchNode(BetterBlockPos pos, int dist, int heuristic, SearchNode prev) { + this.pos = pos; + this.dist = dist; + this.heuristic = heuristic; + this.prev = prev; + } + } + + private List simplePathfind(BetterBlockPos start, BetterBlockPos dest) { + Map map = new HashMap<>(); + PriorityQueue queue = new PriorityQueue<>(Comparator.comparingInt(node -> node.dist + node.heuristic)); + SearchNode origin = new SearchNode(start, 0, manhattanDist(start, dest) * 10, null); + map.put(start, origin); + queue.add(origin); + int count = 0; + while (!queue.isEmpty()) { + if (count++ > 10000) { + logDirect("oopsie"); + return null; + } + SearchNode node = queue.poll(); + if (node.canceled) { + continue; + } + if (node.pos.equals(dest)) { + List path = new ArrayList<>(); + while (node != null) { + path.add(node.pos); + node = node.prev; + } + Collections.reverse(path); + return simplify(path); + } + BetterBlockPos[] adjs = new BetterBlockPos[]{node.pos.up(), node.pos.down(), node.pos.north(), node.pos.south(), node.pos.east(), node.pos.west()}; + boolean nearAWall = false; + for (BetterBlockPos adj : adjs) { + if (!passable(ctx.world().getBlockState(adj))) { + nearAWall = true; + break; + } + } + for (BetterBlockPos adj : adjs) { + if (!passable(ctx.world().getBlockState(adj))) { + continue; + } + int cost = node.dist + (nearAWall ? 11 : 10); + if (map.containsKey(adj)) { + if (map.get(adj).dist <= cost) { + continue; + } + map.get(adj).canceled = true; + } + map.put(adj, new SearchNode(adj, cost, manhattanDist(adj, dest) * 10, node)); + queue.add(map.get(adj)); + } + } + return null; + } + + private List simplify(List path) { + List simplified = new ArrayList<>(path); + for (int i = 0; i < simplified.size() - 2; i++) { + BlockPos dir = simplified.get(i + 1).subtract(simplified.get(i)); + while (i + 2 < simplified.size()) { + if (simplified.get(i + 2).subtract(simplified.get(i + 1)).equals(dir)) { + simplified.remove(i + 1); + } else { + break; + } + } + } + return simplified; + } + + private Vec3d pathAt(int i) { + return new Vec3d(path.get(i).x + 0.5, path.get(i).y + 0.5, path.get(i).z + 0.5); + } + public List> lines = new ArrayList<>(); @@ -81,6 +212,7 @@ public class Elytra extends Behavior implements Helper { fixNearPlayer(); baritone.getInputOverrideHandler().clearAllKeys(); lines.clear(); + pathfindAroundObstacles(); if (ctx.player().isElytraFlying()) { if (ctx.player().collidedHorizontally) { logDirect("hbonk"); @@ -94,7 +226,7 @@ public class Elytra extends Behavior implements Helper { if (!firework && sinceFirework > 10 && (Baritone.settings().wasteFireworks.value || ctx.player().posY < path.get(goingTo).y + 5) // don't firework if trying to descend - && (ctx.player().posY < path.get(goingTo).y - 5 || ctx.playerFeetAsVec().distanceTo(new Vec3d(path.get(goingTo).x, ctx.player().posY, path.get(goingTo).z)) > 5) // UGH!!!!!!! + && (ctx.player().posY < path.get(goingTo).y - 5 || ctx.playerFeetAsVec().distanceTo(new Vec3d(path.get(goingTo).x + 0.5, ctx.player().posY, path.get(goingTo).z + 0.5)) > 5) // UGH!!!!!!! && new Vec3d(ctx.player().motionX, ctx.player().posY < path.get(goingTo).y ? Math.max(0, ctx.player().motionY) : ctx.player().motionY, ctx.player().motionZ).length() < Baritone.settings().elytraFireworkSpeed.value // ignore y component if we are BOTH below where we want to be AND descending ) { logDirect("firework"); @@ -111,19 +243,19 @@ public class Elytra extends Behavior implements Helper { int minStep = playerNear; for (int i = Math.min(playerNear + 20, path.size() - 1); i >= minStep; i--) { for (int dy : heights) { - Vec3d dest = new Vec3d(path.get(i)).add(0, dy, 0); + Vec3d dest = pathAt(i).add(0, dy, 0); if (dy != 0) { if (i + lookahead >= path.size()) { continue; } if (start.distanceTo(dest) < 40) { - if (!clearView(dest, new Vec3d(path.get(i + lookahead)).add(0, dy, 0)) || !clearView(dest, new Vec3d(path.get(i + lookahead)))) { + if (!clearView(dest, pathAt(i + lookahead).add(0, dy, 0)) || !clearView(dest, pathAt(i + lookahead))) { // aka: don't go upwards if doing so would prevent us from being able to see the next position **OR** the modified next position continue; } } else { // but if it's far away, allow gaining altitude if we could lose it again by the time we get there - if (!clearView(dest, new Vec3d(path.get(i)))) { + if (!clearView(dest, pathAt(i))) { continue; } } @@ -196,7 +328,7 @@ public class Elytra extends Behavior implements Helper { for (int x = MathHelper.floor(Math.min(actualPosition.x, actualPositionPrevTick.x) - 0.31); x <= Math.max(actualPosition.x, actualPositionPrevTick.x) + 0.31; x++) { for (int y = MathHelper.floor(Math.min(actualPosition.y, actualPositionPrevTick.y) - 0.2); y <= Math.max(actualPosition.y, actualPositionPrevTick.y) + 0.8; y++) { for (int z = MathHelper.floor(Math.min(actualPosition.z, actualPositionPrevTick.z) - 0.31); z <= Math.max(actualPosition.z, actualPositionPrevTick.z) + 0.31; z++) { - if (bsi.get0(x, y, z).getMaterial() != Material.AIR) { + if (!passable(bsi.get0(x, y, z))) { continue outer; } } @@ -214,6 +346,10 @@ public class Elytra extends Behavior implements Helper { return bestPitch; } + private static boolean passable(IBlockState state) { + return state.getMaterial() == Material.AIR; + } + public static Vec3d step(Vec3d motion, float rotationPitch, float rotationYaw, boolean firework) { double motionX = motion.x; double motionY = motion.y; From 92509f07e9e3ec042ecbe3d93602f86645952694 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Mon, 12 Jun 2023 22:00:23 -0700 Subject: [PATCH 084/405] normal raytracer skips flowing lava (aka lavafalls) which is no good --- src/main/java/baritone/Elytra.java | 98 +++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-) diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index 9607fbcdb..2f724c692 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -28,6 +28,8 @@ import com.mojang.realmsclient.util.Pair; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.item.EntityFireworkRocket; +import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; @@ -297,7 +299,7 @@ public class Elytra extends Behavior implements Helper { private boolean clearView(Vec3d start, Vec3d dest) { lines.add(Pair.of(start, dest)); - RayTraceResult result = ctx.world().rayTraceBlocks(start, dest, true, false, true); + RayTraceResult result = rayTraceBlocks(start, dest); return result == null || result.typeOfHit == RayTraceResult.Type.MISS; } @@ -438,4 +440,98 @@ public class Elytra extends Behavior implements Helper { } } } + + public RayTraceResult rayTraceBlocks(Vec3d start, Vec3d end) { + int x1 = MathHelper.floor(end.x); + int y1 = MathHelper.floor(end.y); + int z1 = MathHelper.floor(end.z); + int x2 = MathHelper.floor(start.x); + int y2 = MathHelper.floor(start.y); + int z2 = MathHelper.floor(start.z); + BlockPos blockpos = new BlockPos(x2, y2, z2); + IBlockState iblockstate = ctx.world().getBlockState(blockpos); + if (!passable(iblockstate)) { + return Blocks.DIRT.getDefaultState().collisionRayTrace(ctx.world(), blockpos, start, end); + } + int steps = 200; + while (steps-- >= 0) { + if (Double.isNaN(start.x) || Double.isNaN(start.y) || Double.isNaN(start.z)) { + return null; + } + if (x2 == x1 && y2 == y1 && z2 == z1) { + return null; + } + boolean hitX = true; + boolean hitY = true; + boolean hitZ = true; + double nextX = 999.0D; + double nextY = 999.0D; + double nextZ = 999.0D; + if (x1 > x2) { + nextX = (double) x2 + 1.0D; + } else if (x1 < x2) { + nextX = (double) x2 + 0.0D; + } else { + hitX = false; + } + if (y1 > y2) { + nextY = (double) y2 + 1.0D; + } else if (y1 < y2) { + nextY = (double) y2 + 0.0D; + } else { + hitY = false; + } + if (z1 > z2) { + nextZ = (double) z2 + 1.0D; + } else if (z1 < z2) { + nextZ = (double) z2 + 0.0D; + } else { + hitZ = false; + } + double stepX = 999.0D; + double stepY = 999.0D; + double stepZ = 999.0D; + double dirX = end.x - start.x; + double dirY = end.y - start.y; + double dirZ = end.z - start.z; + if (hitX) { + stepX = (nextX - start.x) / dirX; + } + if (hitY) { + stepY = (nextY - start.y) / dirY; + } + if (hitZ) { + stepZ = (nextZ - start.z) / dirZ; + } + if (stepX == -0.0D) { + stepX = -1.0E-4D; + } + if (stepY == -0.0D) { + stepY = -1.0E-4D; + } + if (stepZ == -0.0D) { + stepZ = -1.0E-4D; + } + EnumFacing dir; + if (stepX < stepY && stepX < stepZ) { + dir = x1 > x2 ? EnumFacing.WEST : EnumFacing.EAST; + start = new Vec3d(nextX, start.y + dirY * stepX, start.z + dirZ * stepX); + } else if (stepY < stepZ) { + dir = y1 > y2 ? EnumFacing.DOWN : EnumFacing.UP; + start = new Vec3d(start.x + dirX * stepY, nextY, start.z + dirZ * stepY); + } else { + dir = z1 > z2 ? EnumFacing.NORTH : EnumFacing.SOUTH; + start = new Vec3d(start.x + dirX * stepZ, start.y + dirY * stepZ, nextZ); + } + x2 = MathHelper.floor(start.x) - (dir == EnumFacing.EAST ? 1 : 0); + y2 = MathHelper.floor(start.y) - (dir == EnumFacing.UP ? 1 : 0); + z2 = MathHelper.floor(start.z) - (dir == EnumFacing.SOUTH ? 1 : 0); + blockpos = new BlockPos(x2, y2, z2); + IBlockState iblockstate1 = ctx.world().getBlockState(blockpos); + if (!passable(iblockstate1)) { + return Blocks.DIRT.getDefaultState().collisionRayTrace(ctx.world(), blockpos, start, end); + } + } + return null; + } } From 714ebb2c2d1df2c37c01a1d25a42aa8267121463 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 13 Jun 2023 18:24:31 -0500 Subject: [PATCH 085/405] Deprecate `Helper.mc` and begin to replace usages --- src/api/java/baritone/api/utils/Helper.java | 7 +++--- .../baritone/api/utils/gui/BaritoneToast.java | 3 ++- src/main/java/baritone/Baritone.java | 18 ++++++++----- src/main/java/baritone/BaritoneProvider.java | 4 +-- .../java/baritone/behavior/LookBehavior.java | 8 +++--- .../java/baritone/cache/WorldProvider.java | 5 ++++ .../baritone/utils/InputOverrideHandler.java | 3 +-- ...ontext.java => BaritonePlayerContext.java} | 25 +++++++++++++------ ...ler.java => BaritonePlayerController.java} | 11 +++++--- 9 files changed, 55 insertions(+), 29 deletions(-) rename src/main/java/baritone/utils/player/{PrimaryPlayerContext.java => BaritonePlayerContext.java} (69%) rename src/main/java/baritone/utils/player/{PrimaryPlayerController.java => BaritonePlayerController.java} (91%) diff --git a/src/api/java/baritone/api/utils/Helper.java b/src/api/java/baritone/api/utils/Helper.java index 9bed37383..e49744b4f 100755 --- a/src/api/java/baritone/api/utils/Helper.java +++ b/src/api/java/baritone/api/utils/Helper.java @@ -44,6 +44,7 @@ public interface Helper { /** * Instance of the game */ + @Deprecated Minecraft mc = Minecraft.getMinecraft(); static ITextComponent getPrefix() { @@ -70,7 +71,7 @@ public interface Helper { * @param message The message to display in the popup */ default void logToast(ITextComponent title, ITextComponent message) { - mc.addScheduledTask(() -> BaritoneAPI.getSettings().toaster.value.accept(title, message)); + Minecraft.getMinecraft().addScheduledTask(() -> BaritoneAPI.getSettings().toaster.value.accept(title, message)); } /** @@ -131,7 +132,7 @@ public interface Helper { * @param error Whether to log as an error */ default void logNotificationDirect(String message, boolean error) { - mc.addScheduledTask(() -> BaritoneAPI.getSettings().notifier.value.accept(message, error)); + Minecraft.getMinecraft().addScheduledTask(() -> BaritoneAPI.getSettings().notifier.value.accept(message, error)); } /** @@ -168,7 +169,7 @@ public interface Helper { if (logAsToast) { logToast(getPrefix(), component); } else { - mc.addScheduledTask(() -> BaritoneAPI.getSettings().logger.value.accept(component)); + Minecraft.getMinecraft().addScheduledTask(() -> BaritoneAPI.getSettings().logger.value.accept(component)); } } diff --git a/src/api/java/baritone/api/utils/gui/BaritoneToast.java b/src/api/java/baritone/api/utils/gui/BaritoneToast.java index eb6361478..9e9a6403c 100644 --- a/src/api/java/baritone/api/utils/gui/BaritoneToast.java +++ b/src/api/java/baritone/api/utils/gui/BaritoneToast.java @@ -17,6 +17,7 @@ package baritone.api.utils.gui; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.toasts.GuiToast; import net.minecraft.client.gui.toasts.IToast; import net.minecraft.client.renderer.GlStateManager; @@ -73,6 +74,6 @@ public class BaritoneToast implements IToast { } public static void addOrUpdate(ITextComponent title, ITextComponent subtitle) { - addOrUpdate(net.minecraft.client.Minecraft.getMinecraft().getToastGui(), title, subtitle, baritone.api.BaritoneAPI.getSettings().toastTimer.value); + addOrUpdate(Minecraft.getMinecraft().getToastGui(), title, subtitle, baritone.api.BaritoneAPI.getSettings().toastTimer.value); } } diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index 61db54211..173cef876 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -21,7 +21,6 @@ import baritone.api.BaritoneAPI; import baritone.api.IBaritone; import baritone.api.Settings; import baritone.api.event.listener.IEventBus; -import baritone.api.utils.Helper; import baritone.api.utils.IPlayerContext; import baritone.behavior.*; import baritone.cache.WorldProvider; @@ -33,7 +32,7 @@ import baritone.utils.BlockStateInterface; import baritone.utils.GuiClick; import baritone.utils.InputOverrideHandler; import baritone.utils.PathingControlManager; -import baritone.utils.player.PrimaryPlayerContext; +import baritone.utils.player.BaritonePlayerContext; import net.minecraft.client.Minecraft; import java.io.File; @@ -64,6 +63,8 @@ public class Baritone implements IBaritone { } } + private final Minecraft mc; + private GameEventHandler gameEventHandler; private PathingBehavior pathingBehavior; @@ -91,11 +92,12 @@ public class Baritone implements IBaritone { public BlockStateInterface bsi; - Baritone() { + Baritone(Minecraft mc) { + this.mc = mc; this.gameEventHandler = new GameEventHandler(this); // Define this before behaviors try and get it, or else it will be null and the builds will fail! - this.playerContext = PrimaryPlayerContext.INSTANCE; + this.playerContext = new BaritonePlayerContext(this); { // the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist @@ -119,7 +121,7 @@ public class Baritone implements IBaritone { this.pathingControlManager.registerProcess(inventoryPauserProcess = new InventoryPauserProcess(this)); } - this.worldProvider = new WorldProvider(); + this.worldProvider = new WorldProvider(this); this.selectionManager = new SelectionManager(this); this.commandManager = new CommandManager(this); } @@ -219,11 +221,15 @@ public class Baritone implements IBaritone { new Thread(() -> { try { Thread.sleep(100); - Helper.mc.addScheduledTask(() -> Helper.mc.displayGuiScreen(new GuiClick())); + mc.addScheduledTask(() -> mc.displayGuiScreen(new GuiClick())); } catch (Exception ignored) {} }).start(); } + public Minecraft getMinecraft() { + return this.mc; + } + public static Settings settings() { return BaritoneAPI.getSettings(); } diff --git a/src/main/java/baritone/BaritoneProvider.java b/src/main/java/baritone/BaritoneProvider.java index c49c02e10..b7c2403d2 100644 --- a/src/main/java/baritone/BaritoneProvider.java +++ b/src/main/java/baritone/BaritoneProvider.java @@ -23,10 +23,10 @@ import baritone.api.cache.IWorldScanner; import baritone.api.command.ICommandSystem; import baritone.api.schematic.ISchematicSystem; import baritone.cache.FasterWorldScanner; -import baritone.cache.WorldScanner; import baritone.command.CommandSystem; import baritone.command.ExampleBaritoneControl; import baritone.utils.schematic.SchematicSystem; +import net.minecraft.client.Minecraft; import java.util.Collections; import java.util.List; @@ -41,7 +41,7 @@ public final class BaritoneProvider implements IBaritoneProvider { private final List all; { - this.primary = new Baritone(); + this.primary = new Baritone(Minecraft.getMinecraft()); this.all = Collections.singletonList(this.primary); // Setup chat control, just for the primary instance diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index 99e496e6f..2d237dfb8 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -164,19 +164,19 @@ public final class LookBehavior extends Behavior implements ILookBehavior { return pitch; } - private static float calculateMouseMove(float current, float target) { + private float calculateMouseMove(float current, float target) { final float delta = target - current; final int deltaPx = angleToMouse(delta); return current + mouseToAngle(deltaPx); } - private static int angleToMouse(float angleDelta) { + private int angleToMouse(float angleDelta) { final float minAngleChange = mouseToAngle(1); return Math.round(angleDelta / minAngleChange); } - private static float mouseToAngle(int mouseDelta) { - final float f = Helper.mc.gameSettings.mouseSensitivity * 0.6f + 0.2f; + private float mouseToAngle(int mouseDelta) { + final float f = baritone.getMinecraft().gameSettings.mouseSensitivity * 0.6f + 0.2f; return mouseDelta * f * f * f * 8.0f * 0.15f; } diff --git a/src/main/java/baritone/cache/WorldProvider.java b/src/main/java/baritone/cache/WorldProvider.java index 97b15a137..85d8a04bf 100644 --- a/src/main/java/baritone/cache/WorldProvider.java +++ b/src/main/java/baritone/cache/WorldProvider.java @@ -44,9 +44,14 @@ public class WorldProvider implements IWorldProvider, Helper { private static final Map worldCache = new HashMap<>(); // this is how the bots have the same cached world + private Baritone baritone; private WorldData currentWorld; private World mcWorld; // this let's us detect a broken load/unload hook + public WorldProvider(Baritone baritone) { + this.baritone = baritone; + } + @Override public final WorldData getCurrentWorld() { detectAndHandleBrokenLoading(); diff --git a/src/main/java/baritone/utils/InputOverrideHandler.java b/src/main/java/baritone/utils/InputOverrideHandler.java index d1c4689a2..b7f320e96 100755 --- a/src/main/java/baritone/utils/InputOverrideHandler.java +++ b/src/main/java/baritone/utils/InputOverrideHandler.java @@ -23,7 +23,6 @@ import baritone.api.event.events.TickEvent; import baritone.api.utils.IInputOverrideHandler; import baritone.api.utils.input.Input; import baritone.behavior.Behavior; -import net.minecraft.client.Minecraft; import net.minecraft.util.MovementInputFromOptions; import java.util.HashMap; @@ -100,7 +99,7 @@ public final class InputOverrideHandler extends Behavior implements IInputOverri } } else { if (ctx.player().movementInput.getClass() == PlayerMovementInput.class) { // allow other movement inputs that aren't this one, e.g. for a freecam - ctx.player().movementInput = new MovementInputFromOptions(Minecraft.getMinecraft().gameSettings); + ctx.player().movementInput = new MovementInputFromOptions(baritone.getMinecraft().gameSettings); } } // only set it if it was previously incorrect diff --git a/src/main/java/baritone/utils/player/PrimaryPlayerContext.java b/src/main/java/baritone/utils/player/BaritonePlayerContext.java similarity index 69% rename from src/main/java/baritone/utils/player/PrimaryPlayerContext.java rename to src/main/java/baritone/utils/player/BaritonePlayerContext.java index 02db73a5c..6af714942 100644 --- a/src/main/java/baritone/utils/player/PrimaryPlayerContext.java +++ b/src/main/java/baritone/utils/player/BaritonePlayerContext.java @@ -17,10 +17,11 @@ package baritone.utils.player; -import baritone.api.BaritoneAPI; +import baritone.Baritone; import baritone.api.cache.IWorldData; import baritone.api.utils.*; import baritone.behavior.LookBehavior; +import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; @@ -31,33 +32,41 @@ import net.minecraft.world.World; * @author Brady * @since 11/12/2018 */ -public enum PrimaryPlayerContext implements IPlayerContext, Helper { +public final class BaritonePlayerContext implements IPlayerContext { - INSTANCE; + private final Baritone baritone; + private final Minecraft mc; + private final IPlayerController playerController; + + public BaritonePlayerContext(Baritone baritone) { + this.baritone = baritone; + this.mc = baritone.getMinecraft(); + this.playerController = new BaritonePlayerController(baritone); + } @Override public EntityPlayerSP player() { - return mc.player; + return this.mc.player; } @Override public IPlayerController playerController() { - return PrimaryPlayerController.INSTANCE; + return this.playerController; } @Override public World world() { - return mc.world; + return this.mc.world; } @Override public IWorldData worldData() { - return BaritoneAPI.getProvider().getPrimaryBaritone().getWorldProvider().getCurrentWorld(); + return this.baritone.getWorldProvider().getCurrentWorld(); } @Override public Rotation playerRotations() { - return ((LookBehavior) BaritoneAPI.getProvider().getPrimaryBaritone().getLookBehavior()).getEffectiveRotation() + return ((LookBehavior) this.baritone.getLookBehavior()).getEffectiveRotation() .orElseGet(IPlayerContext.super::playerRotations); } diff --git a/src/main/java/baritone/utils/player/PrimaryPlayerController.java b/src/main/java/baritone/utils/player/BaritonePlayerController.java similarity index 91% rename from src/main/java/baritone/utils/player/PrimaryPlayerController.java rename to src/main/java/baritone/utils/player/BaritonePlayerController.java index b013f9161..95a55e026 100644 --- a/src/main/java/baritone/utils/player/PrimaryPlayerController.java +++ b/src/main/java/baritone/utils/player/BaritonePlayerController.java @@ -17,9 +17,10 @@ package baritone.utils.player; -import baritone.api.utils.Helper; +import baritone.Baritone; import baritone.api.utils.IPlayerController; import baritone.utils.accessor.IPlayerControllerMP; +import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.multiplayer.WorldClient; import net.minecraft.entity.player.EntityPlayer; @@ -39,9 +40,13 @@ import net.minecraft.world.World; * @author Brady * @since 12/14/2018 */ -public enum PrimaryPlayerController implements IPlayerController, Helper { +public final class BaritonePlayerController implements IPlayerController { - INSTANCE; + private final Minecraft mc; + + public BaritonePlayerController(Baritone baritone) { + this.mc = baritone.getMinecraft(); + } @Override public void syncHeldItem() { From ab3d9e9c47d04584150c8585367458dbc8558c97 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 13 Jun 2023 21:13:34 -0500 Subject: [PATCH 086/405] I LOVE `final` --- src/main/java/baritone/Baritone.java | 54 +++++++++---------- src/main/java/baritone/behavior/Behavior.java | 1 - .../baritone/behavior/PathingBehavior.java | 8 +-- .../java/baritone/cache/WorldProvider.java | 2 +- .../java/baritone/utils/BlockBreakHelper.java | 3 +- .../java/baritone/utils/BlockPlaceHelper.java | 3 +- .../utils/player/BaritonePlayerContext.java | 4 +- 7 files changed, 36 insertions(+), 39 deletions(-) diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index 173cef876..4a873c226 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -49,8 +49,8 @@ import java.util.concurrent.TimeUnit; */ public class Baritone implements IBaritone { - private static ThreadPoolExecutor threadPool; - private static File dir; + private static final ThreadPoolExecutor threadPool; + private static final File dir; static { threadPool = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>()); @@ -65,30 +65,30 @@ public class Baritone implements IBaritone { private final Minecraft mc; - private GameEventHandler gameEventHandler; + private final GameEventHandler gameEventHandler; - private PathingBehavior pathingBehavior; - private LookBehavior lookBehavior; - private InventoryBehavior inventoryBehavior; - private WaypointBehavior waypointBehavior; - private InputOverrideHandler inputOverrideHandler; + private final PathingBehavior pathingBehavior; + private final LookBehavior lookBehavior; + private final InventoryBehavior inventoryBehavior; + private final WaypointBehavior waypointBehavior; + private final InputOverrideHandler inputOverrideHandler; - private FollowProcess followProcess; - private MineProcess mineProcess; - private GetToBlockProcess getToBlockProcess; - private CustomGoalProcess customGoalProcess; - private BuilderProcess builderProcess; - private ExploreProcess exploreProcess; - private BackfillProcess backfillProcess; - private FarmProcess farmProcess; - private InventoryPauserProcess inventoryPauserProcess; + private final FollowProcess followProcess; + private final MineProcess mineProcess; + private final GetToBlockProcess getToBlockProcess; + private final CustomGoalProcess customGoalProcess; + private final BuilderProcess builderProcess; + private final ExploreProcess exploreProcess; + private final BackfillProcess backfillProcess; + private final FarmProcess farmProcess; + private final InventoryPauserProcess inventoryPauserProcess; - private PathingControlManager pathingControlManager; - private SelectionManager selectionManager; - private CommandManager commandManager; + private final PathingControlManager pathingControlManager; + private final SelectionManager selectionManager; + private final CommandManager commandManager; - private IPlayerContext playerContext; - private WorldProvider worldProvider; + private final IPlayerContext playerContext; + private final WorldProvider worldProvider; public BlockStateInterface bsi; @@ -101,11 +101,11 @@ public class Baritone implements IBaritone { { // the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist - pathingBehavior = new PathingBehavior(this); - lookBehavior = new LookBehavior(this); - inventoryBehavior = new InventoryBehavior(this); - inputOverrideHandler = new InputOverrideHandler(this); - waypointBehavior = new WaypointBehavior(this); + this.registerBehavior(pathingBehavior = new PathingBehavior(this)); + this.registerBehavior(lookBehavior = new LookBehavior(this)); + this.registerBehavior(inventoryBehavior = new InventoryBehavior(this)); + this.registerBehavior(inputOverrideHandler = new InputOverrideHandler(this)); + this.registerBehavior(waypointBehavior = new WaypointBehavior(this)); } this.pathingControlManager = new PathingControlManager(this); diff --git a/src/main/java/baritone/behavior/Behavior.java b/src/main/java/baritone/behavior/Behavior.java index 36273c026..848beb298 100644 --- a/src/main/java/baritone/behavior/Behavior.java +++ b/src/main/java/baritone/behavior/Behavior.java @@ -35,6 +35,5 @@ public class Behavior implements IBehavior { protected Behavior(Baritone baritone) { this.baritone = baritone; this.ctx = baritone.getPlayerContext(); - baritone.registerBehavior(this); } } diff --git a/src/main/java/baritone/behavior/PathingBehavior.java b/src/main/java/baritone/behavior/PathingBehavior.java index 33ef14ef2..23f2b1431 100644 --- a/src/main/java/baritone/behavior/PathingBehavior.java +++ b/src/main/java/baritone/behavior/PathingBehavior.java @@ -36,6 +36,7 @@ import baritone.pathing.path.PathExecutor; import baritone.utils.PathRenderer; import baritone.utils.PathingCommandContext; import baritone.utils.pathing.Favoring; +import net.minecraft.client.settings.GameSettings; import net.minecraft.util.math.BlockPos; import java.util.ArrayList; @@ -237,13 +238,14 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, @Override public void onPlayerUpdate(PlayerUpdateEvent event) { if (current != null) { + final GameSettings settings = baritone.getMinecraft().gameSettings; switch (event.getState()) { case PRE: - lastAutoJump = mc.gameSettings.autoJump; - mc.gameSettings.autoJump = false; + lastAutoJump = settings.autoJump; + settings.autoJump = false; break; case POST: - mc.gameSettings.autoJump = lastAutoJump; + settings.autoJump = lastAutoJump; break; default: break; diff --git a/src/main/java/baritone/cache/WorldProvider.java b/src/main/java/baritone/cache/WorldProvider.java index 85d8a04bf..d0458ea60 100644 --- a/src/main/java/baritone/cache/WorldProvider.java +++ b/src/main/java/baritone/cache/WorldProvider.java @@ -44,7 +44,7 @@ public class WorldProvider implements IWorldProvider, Helper { private static final Map worldCache = new HashMap<>(); // this is how the bots have the same cached world - private Baritone baritone; + private final Baritone baritone; private WorldData currentWorld; private World mcWorld; // this let's us detect a broken load/unload hook diff --git a/src/main/java/baritone/utils/BlockBreakHelper.java b/src/main/java/baritone/utils/BlockBreakHelper.java index 26e82cd78..c4ed11f0c 100644 --- a/src/main/java/baritone/utils/BlockBreakHelper.java +++ b/src/main/java/baritone/utils/BlockBreakHelper.java @@ -17,7 +17,6 @@ package baritone.utils; -import baritone.api.utils.Helper; import baritone.api.utils.IPlayerContext; import net.minecraft.util.EnumHand; import net.minecraft.util.math.RayTraceResult; @@ -26,7 +25,7 @@ import net.minecraft.util.math.RayTraceResult; * @author Brady * @since 8/25/2018 */ -public final class BlockBreakHelper implements Helper { +public final class BlockBreakHelper { private final IPlayerContext ctx; private boolean didBreakLastTick; diff --git a/src/main/java/baritone/utils/BlockPlaceHelper.java b/src/main/java/baritone/utils/BlockPlaceHelper.java index 440bfb93d..69dea61b8 100644 --- a/src/main/java/baritone/utils/BlockPlaceHelper.java +++ b/src/main/java/baritone/utils/BlockPlaceHelper.java @@ -18,13 +18,12 @@ package baritone.utils; import baritone.Baritone; -import baritone.api.utils.Helper; import baritone.api.utils.IPlayerContext; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumHand; import net.minecraft.util.math.RayTraceResult; -public class BlockPlaceHelper implements Helper { +public class BlockPlaceHelper { private final IPlayerContext ctx; private int rightClickTimer; diff --git a/src/main/java/baritone/utils/player/BaritonePlayerContext.java b/src/main/java/baritone/utils/player/BaritonePlayerContext.java index 6af714942..0bb118a1d 100644 --- a/src/main/java/baritone/utils/player/BaritonePlayerContext.java +++ b/src/main/java/baritone/utils/player/BaritonePlayerContext.java @@ -20,7 +20,6 @@ package baritone.utils.player; import baritone.Baritone; import baritone.api.cache.IWorldData; import baritone.api.utils.*; -import baritone.behavior.LookBehavior; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.util.math.RayTraceResult; @@ -66,8 +65,7 @@ public final class BaritonePlayerContext implements IPlayerContext { @Override public Rotation playerRotations() { - return ((LookBehavior) this.baritone.getLookBehavior()).getEffectiveRotation() - .orElseGet(IPlayerContext.super::playerRotations); + return this.baritone.getLookBehavior().getEffectiveRotation().orElseGet(IPlayerContext.super::playerRotations); } @Override From 382f82b0e0ec38d419fb58245d6ae143a34887f2 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 13 Jun 2023 21:17:42 -0500 Subject: [PATCH 087/405] Move `Minecraft` to `IPlayerContext` --- src/api/java/baritone/api/utils/IPlayerContext.java | 3 +++ src/main/java/baritone/Baritone.java | 6 +----- src/main/java/baritone/behavior/LookBehavior.java | 2 +- src/main/java/baritone/behavior/PathingBehavior.java | 7 +++---- .../java/baritone/utils/InputOverrideHandler.java | 2 +- .../baritone/utils/player/BaritonePlayerContext.java | 11 ++++++++--- .../utils/player/BaritonePlayerController.java | 4 ++-- 7 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/api/java/baritone/api/utils/IPlayerContext.java b/src/api/java/baritone/api/utils/IPlayerContext.java index fcc4c81cc..525f73ddc 100644 --- a/src/api/java/baritone/api/utils/IPlayerContext.java +++ b/src/api/java/baritone/api/utils/IPlayerContext.java @@ -19,6 +19,7 @@ package baritone.api.utils; import baritone.api.cache.IWorldData; import net.minecraft.block.BlockSlab; +import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; @@ -33,6 +34,8 @@ import java.util.Optional; */ public interface IPlayerContext { + Minecraft minecraft(); + EntityPlayerSP player(); IPlayerController playerController(); diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index 4a873c226..488850f82 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -97,7 +97,7 @@ public class Baritone implements IBaritone { this.gameEventHandler = new GameEventHandler(this); // Define this before behaviors try and get it, or else it will be null and the builds will fail! - this.playerContext = new BaritonePlayerContext(this); + this.playerContext = new BaritonePlayerContext(this, mc); { // the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist @@ -226,10 +226,6 @@ public class Baritone implements IBaritone { }).start(); } - public Minecraft getMinecraft() { - return this.mc; - } - public static Settings settings() { return BaritoneAPI.getSettings(); } diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index 2d237dfb8..67aa45e39 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -176,7 +176,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior { } private float mouseToAngle(int mouseDelta) { - final float f = baritone.getMinecraft().gameSettings.mouseSensitivity * 0.6f + 0.2f; + final float f = ctx.minecraft().gameSettings.mouseSensitivity * 0.6f + 0.2f; return mouseDelta * f * f * f * 8.0f * 0.15f; } diff --git a/src/main/java/baritone/behavior/PathingBehavior.java b/src/main/java/baritone/behavior/PathingBehavior.java index 23f2b1431..f5433fe8d 100644 --- a/src/main/java/baritone/behavior/PathingBehavior.java +++ b/src/main/java/baritone/behavior/PathingBehavior.java @@ -238,14 +238,13 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, @Override public void onPlayerUpdate(PlayerUpdateEvent event) { if (current != null) { - final GameSettings settings = baritone.getMinecraft().gameSettings; switch (event.getState()) { case PRE: - lastAutoJump = settings.autoJump; - settings.autoJump = false; + lastAutoJump = ctx.minecraft().gameSettings.autoJump; + ctx.minecraft().gameSettings.autoJump = false; break; case POST: - settings.autoJump = lastAutoJump; + ctx.minecraft().gameSettings.autoJump = lastAutoJump; break; default: break; diff --git a/src/main/java/baritone/utils/InputOverrideHandler.java b/src/main/java/baritone/utils/InputOverrideHandler.java index b7f320e96..f110b9ce1 100755 --- a/src/main/java/baritone/utils/InputOverrideHandler.java +++ b/src/main/java/baritone/utils/InputOverrideHandler.java @@ -99,7 +99,7 @@ public final class InputOverrideHandler extends Behavior implements IInputOverri } } else { if (ctx.player().movementInput.getClass() == PlayerMovementInput.class) { // allow other movement inputs that aren't this one, e.g. for a freecam - ctx.player().movementInput = new MovementInputFromOptions(baritone.getMinecraft().gameSettings); + ctx.player().movementInput = new MovementInputFromOptions(ctx.minecraft().gameSettings); } } // only set it if it was previously incorrect diff --git a/src/main/java/baritone/utils/player/BaritonePlayerContext.java b/src/main/java/baritone/utils/player/BaritonePlayerContext.java index 0bb118a1d..601d2bb72 100644 --- a/src/main/java/baritone/utils/player/BaritonePlayerContext.java +++ b/src/main/java/baritone/utils/player/BaritonePlayerContext.java @@ -37,10 +37,15 @@ public final class BaritonePlayerContext implements IPlayerContext { private final Minecraft mc; private final IPlayerController playerController; - public BaritonePlayerContext(Baritone baritone) { + public BaritonePlayerContext(Baritone baritone, Minecraft mc) { this.baritone = baritone; - this.mc = baritone.getMinecraft(); - this.playerController = new BaritonePlayerController(baritone); + this.mc = mc; + this.playerController = new BaritonePlayerController(mc); + } + + @Override + public Minecraft minecraft() { + return this.mc; } @Override diff --git a/src/main/java/baritone/utils/player/BaritonePlayerController.java b/src/main/java/baritone/utils/player/BaritonePlayerController.java index 95a55e026..b0e94e8c5 100644 --- a/src/main/java/baritone/utils/player/BaritonePlayerController.java +++ b/src/main/java/baritone/utils/player/BaritonePlayerController.java @@ -44,8 +44,8 @@ public final class BaritonePlayerController implements IPlayerController { private final Minecraft mc; - public BaritonePlayerController(Baritone baritone) { - this.mc = baritone.getMinecraft(); + public BaritonePlayerController(Minecraft mc) { + this.mc = mc; } @Override From c7f4e366e21d5e79d050cd28eeed57b8f6809691 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 13 Jun 2023 23:07:26 -0500 Subject: [PATCH 088/405] Remove `mc` references from `WorldProvider` Also refactored a bit, should be a lot easier to merge upwards to new game versions --- .../baritone/api/cache/IWorldProvider.java | 9 + src/main/java/baritone/Baritone.java | 26 +-- .../java/baritone/cache/WorldProvider.java | 176 ++++++++++-------- .../java/baritone/event/GameEventHandler.java | 2 +- .../player/BaritonePlayerController.java | 1 - 5 files changed, 124 insertions(+), 90 deletions(-) diff --git a/src/api/java/baritone/api/cache/IWorldProvider.java b/src/api/java/baritone/api/cache/IWorldProvider.java index 0e54ef469..b9ca149c7 100644 --- a/src/api/java/baritone/api/cache/IWorldProvider.java +++ b/src/api/java/baritone/api/cache/IWorldProvider.java @@ -17,6 +17,8 @@ package baritone.api.cache; +import java.util.function.Consumer; + /** * @author Brady * @since 9/24/2018 @@ -29,4 +31,11 @@ public interface IWorldProvider { * @return The current world data */ IWorldData getCurrentWorld(); + + default void ifWorldLoaded(Consumer callback) { + final IWorldData currentWorld = this.getCurrentWorld(); + if (currentWorld != null) { + callback.accept(currentWorld); + } + } } diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index 488850f82..7cfa15009 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -35,9 +35,9 @@ import baritone.utils.PathingControlManager; import baritone.utils.player.BaritonePlayerContext; import net.minecraft.client.Minecraft; -import java.io.File; import java.io.IOException; import java.nio.file.Files; +import java.nio.file.Path; import java.util.concurrent.Executor; import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadPoolExecutor; @@ -50,20 +50,13 @@ import java.util.concurrent.TimeUnit; public class Baritone implements IBaritone { private static final ThreadPoolExecutor threadPool; - private static final File dir; static { threadPool = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>()); - - dir = new File(Minecraft.getMinecraft().gameDir, "baritone"); - if (!Files.exists(dir.toPath())) { - try { - Files.createDirectories(dir.toPath()); - } catch (IOException ignored) {} - } } private final Minecraft mc; + private final Path directory; private final GameEventHandler gameEventHandler; @@ -96,6 +89,13 @@ public class Baritone implements IBaritone { this.mc = mc; this.gameEventHandler = new GameEventHandler(this); + this.directory = mc.gameDir.toPath().resolve("baritone"); + if (!Files.exists(this.directory)) { + try { + Files.createDirectories(this.directory); + } catch (IOException ignored) {} + } + // Define this before behaviors try and get it, or else it will be null and the builds will fail! this.playerContext = new BaritonePlayerContext(this, mc); @@ -226,12 +226,12 @@ public class Baritone implements IBaritone { }).start(); } - public static Settings settings() { - return BaritoneAPI.getSettings(); + public Path getDirectory() { + return this.directory; } - public static File getDir() { - return dir; + public static Settings settings() { + return BaritoneAPI.getSettings(); } public static Executor getExecutor() { diff --git a/src/main/java/baritone/cache/WorldProvider.java b/src/main/java/baritone/cache/WorldProvider.java index d0458ea60..59f671c99 100644 --- a/src/main/java/baritone/cache/WorldProvider.java +++ b/src/main/java/baritone/cache/WorldProvider.java @@ -19,108 +19,85 @@ package baritone.cache; import baritone.Baritone; import baritone.api.cache.IWorldProvider; -import baritone.api.utils.Helper; +import baritone.api.utils.IPlayerContext; import baritone.utils.accessor.IAnvilChunkLoader; import baritone.utils.accessor.IChunkProviderServer; -import net.minecraft.server.integrated.IntegratedServer; +import net.minecraft.client.multiplayer.ServerData; +import net.minecraft.util.Tuple; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import org.apache.commons.lang3.SystemUtils; -import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.HashMap; import java.util.Map; -import java.util.function.Consumer; +import java.util.Optional; /** * @author Brady * @since 8/4/2018 */ -public class WorldProvider implements IWorldProvider, Helper { +public class WorldProvider implements IWorldProvider { - private static final Map worldCache = new HashMap<>(); // this is how the bots have the same cached world + private static final Map worldCache = new HashMap<>(); private final Baritone baritone; + private final IPlayerContext ctx; private WorldData currentWorld; - private World mcWorld; // this let's us detect a broken load/unload hook + + /** + * This lets us detect a broken load/unload hook. + * @see #detectAndHandleBrokenLoading() + */ + private World mcWorld; public WorldProvider(Baritone baritone) { this.baritone = baritone; + this.ctx = baritone.getPlayerContext(); } @Override public final WorldData getCurrentWorld() { - detectAndHandleBrokenLoading(); + this.detectAndHandleBrokenLoading(); return this.currentWorld; } /** * Called when a new world is initialized to discover the * - * @param dimension The ID of the world's dimension + * @param world The new world */ - public final void initWorld(int dimension) { - File directory; - File readme; + public final void initWorld(World world) { + this.getSaveDirectories(world).ifPresent(dirs -> { + final Path worldDir = dirs.getFirst(); + final Path readmeDir = dirs.getSecond(); - IntegratedServer integratedServer = mc.getIntegratedServer(); - - // If there is an integrated server running (Aka Singleplayer) then do magic to find the world save file - if (mc.isSingleplayer()) { - WorldServer localServerWorld = integratedServer.getWorld(dimension); - IChunkProviderServer provider = (IChunkProviderServer) localServerWorld.getChunkProvider(); - IAnvilChunkLoader loader = (IAnvilChunkLoader) provider.getChunkLoader(); - directory = loader.getChunkSaveLocation(); - - // Gets the "depth" of this directory relative the the game's run directory, 2 is the location of the world - if (directory.toPath().relativize(mc.gameDir.toPath()).getNameCount() != 2) { - // subdirectory of the main save directory for this world - directory = directory.getParentFile(); - } - - directory = new File(directory, "baritone"); - readme = directory; - } else { // Otherwise, the server must be remote... - String folderName; - if (mc.getCurrentServerData() != null) { - folderName = mc.getCurrentServerData().serverIP; - } else { - //replaymod causes null currentServerData and false singleplayer. - System.out.println("World seems to be a replay. Not loading Baritone cache."); - currentWorld = null; - mcWorld = mc.world; - return; - } - if (SystemUtils.IS_OS_WINDOWS) { - folderName = folderName.replace(":", "_"); - } - directory = new File(Baritone.getDir(), folderName); - readme = Baritone.getDir(); - } - - // lol wtf is this baritone folder in my minecraft save? - try (FileOutputStream out = new FileOutputStream(new File(readme, "readme.txt"))) { - // good thing we have a readme - out.write("https://github.com/cabaletta/baritone\n".getBytes()); - } catch (IOException ignored) {} - - // We will actually store the world data in a subfolder: "DIM" - Path dir = new File(directory, "DIM" + dimension).toPath(); - if (!Files.exists(dir)) { try { - Files.createDirectories(dir); + // lol wtf is this baritone folder in my minecraft save? + // good thing we have a readme + Files.createDirectories(readmeDir); + Files.write( + readmeDir.resolve("readme.txt"), + "https://github.com/cabaletta/baritone\n".getBytes(StandardCharsets.US_ASCII) + ); } catch (IOException ignored) {} - } - System.out.println("Baritone world data dir: " + dir); - synchronized (worldCache) { - this.currentWorld = worldCache.computeIfAbsent(dir, d -> new WorldData(d, dimension)); - } - this.mcWorld = mc.world; + // We will actually store the world data in a subfolder: "DIM" + final Path worldDataDir = this.getWorldDataDirectory(worldDir, world); + try { + Files.createDirectories(worldDataDir); + } catch (IOException ignored) {} + + System.out.println("Baritone world data dir: " + worldDataDir); + synchronized (worldCache) { + final int dimension = world.provider.getDimensionType().getId(); + this.currentWorld = worldCache.computeIfAbsent(worldDataDir, d -> new WorldData(d, dimension)); + } + this.mcWorld = ctx.world(); + }); } public final void closeWorld() { @@ -133,26 +110,75 @@ public class WorldProvider implements IWorldProvider, Helper { world.onClose(); } - public final void ifWorldLoaded(Consumer currentWorldConsumer) { - detectAndHandleBrokenLoading(); - if (this.currentWorld != null) { - currentWorldConsumer.accept(this.currentWorld); - } + private Path getWorldDataDirectory(Path parent, World world) { + return parent.resolve("DIM" + world.provider.getDimensionType().getId()); } - private final void detectAndHandleBrokenLoading() { - if (this.mcWorld != mc.world) { + /** + * @param world The world + * @return An {@link Optional} containing the world's baritone dir and readme dir, or {@link Optional#empty()} if + * the world isn't valid for caching. + */ + private Optional> getSaveDirectories(World world) { + Path worldDir; + Path readmeDir; + + // If there is an integrated server running (Aka Singleplayer) then do magic to find the world save file + if (ctx.minecraft().isSingleplayer()) { + final int dimension = world.provider.getDimensionType().getId(); + final WorldServer localServerWorld = ctx.minecraft().getIntegratedServer().getWorld(dimension); + final IChunkProviderServer provider = (IChunkProviderServer) localServerWorld.getChunkProvider(); + final IAnvilChunkLoader loader = (IAnvilChunkLoader) provider.getChunkLoader(); + worldDir = loader.getChunkSaveLocation().toPath(); + + // Gets the "depth" of this directory relative to the game's run directory, 2 is the location of the world + if (worldDir.relativize(ctx.minecraft().gameDir.toPath()).getNameCount() != 2) { + // subdirectory of the main save directory for this world + worldDir = worldDir.getParent(); + } + + worldDir = worldDir.resolve("baritone"); + readmeDir = worldDir; + } else { // Otherwise, the server must be remote... + String folderName; + final ServerData serverData = ctx.minecraft().getCurrentServerData(); + if (serverData != null) { + folderName = serverData.serverIP; + } else { + //replaymod causes null currentServerData and false singleplayer. + System.out.println("World seems to be a replay. Not loading Baritone cache."); + currentWorld = null; + mcWorld = ctx.world(); + return Optional.empty(); + } + if (SystemUtils.IS_OS_WINDOWS) { + folderName = folderName.replace(":", "_"); + } + // TODO: This should probably be in "baritone/servers" + worldDir = baritone.getDirectory().resolve(folderName); + // Just write the readme to the baritone directory instead of each server save in it + readmeDir = baritone.getDirectory(); + } + + return Optional.of(new Tuple<>(worldDir, readmeDir)); + } + + /** + * Why does this exist instead of fixing the event? Some mods break the event. Lol. + */ + private void detectAndHandleBrokenLoading() { + if (this.mcWorld != ctx.world()) { if (this.currentWorld != null) { System.out.println("mc.world unloaded unnoticed! Unloading Baritone cache now."); closeWorld(); } - if (mc.world != null) { + if (ctx.world() != null) { System.out.println("mc.world loaded unnoticed! Loading Baritone cache now."); - initWorld(mc.world.provider.getDimensionType().getId()); + initWorld(ctx.world()); } - } else if (currentWorld == null && mc.world != null && (mc.isSingleplayer() || mc.getCurrentServerData() != null)) { + } else if (this.currentWorld == null && ctx.world() != null && (ctx.minecraft().isSingleplayer() || ctx.minecraft().getCurrentServerData() != null)) { System.out.println("Retrying to load Baritone cache"); - initWorld(mc.world.provider.getDimensionType().getId()); + initWorld(ctx.world()); } } } diff --git a/src/main/java/baritone/event/GameEventHandler.java b/src/main/java/baritone/event/GameEventHandler.java index 8916f7f37..0b46eb5e1 100644 --- a/src/main/java/baritone/event/GameEventHandler.java +++ b/src/main/java/baritone/event/GameEventHandler.java @@ -114,7 +114,7 @@ public final class GameEventHandler implements IEventBus, Helper { if (event.getState() == EventState.POST) { cache.closeWorld(); if (event.getWorld() != null) { - cache.initWorld(event.getWorld().provider.getDimensionType().getId()); + cache.initWorld(event.getWorld()); } } diff --git a/src/main/java/baritone/utils/player/BaritonePlayerController.java b/src/main/java/baritone/utils/player/BaritonePlayerController.java index b0e94e8c5..694ffab6c 100644 --- a/src/main/java/baritone/utils/player/BaritonePlayerController.java +++ b/src/main/java/baritone/utils/player/BaritonePlayerController.java @@ -17,7 +17,6 @@ package baritone.utils.player; -import baritone.Baritone; import baritone.api.utils.IPlayerController; import baritone.utils.accessor.IPlayerControllerMP; import net.minecraft.client.Minecraft; From dd7b492b0cf81bc102dee39bc7d7d70eaf44826d Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 13 Jun 2023 23:21:20 -0500 Subject: [PATCH 089/405] registerBehavior is called explicitly now --- src/main/java/baritone/Baritone.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index 7cfa15009..637af2e3b 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -100,7 +100,6 @@ public class Baritone implements IBaritone { this.playerContext = new BaritonePlayerContext(this, mc); { - // the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist this.registerBehavior(pathingBehavior = new PathingBehavior(this)); this.registerBehavior(lookBehavior = new LookBehavior(this)); this.registerBehavior(inventoryBehavior = new InventoryBehavior(this)); From 88e604426c64951d5f2a1a6818a16aab45b55651 Mon Sep 17 00:00:00 2001 From: leijurv Date: Tue, 13 Jun 2023 21:30:31 -0700 Subject: [PATCH 090/405] 1.20.1 --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8ae8090d7..c135ebdf8 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,9 @@ Minecraft Minecraft Minecraft - Minecraft + Minecraft + Minecraft + Minecraft

@@ -64,6 +66,7 @@ Baritone is the pathfinding system used in [Impact](https://impactclient.net/) s | [1.19.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.4/baritone-api-forge-1.9.4.jar) | [1.19.2 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.4/baritone-api-fabric-1.9.4.jar) | | [1.19.3 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-forge-1.9.1.jar) | [1.19.3 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-fabric-1.9.1.jar) | | [1.19.4 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-forge-1.9.3.jar) | [1.19.4 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-fabric-1.9.3.jar) | +| [1.20.1 Forge](https://github.com/cabaletta/baritone/releases/download/v1.10.1/baritone-api-forge-1.10.1.jar) | [1.20.1 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.10.1/baritone-api-fabric-1.10.1.jar) | **How to immediately get started:** Type `#goto 1000 500` in chat to go to x=1000 z=500. Type `#mine diamond_ore` to mine diamond ore. Type `#stop` to stop. For more, read [the usage page](USAGE.md) and/or watch this [tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa) From 5e724c1e3af7e67466664548694fa2bfaac5145a Mon Sep 17 00:00:00 2001 From: leijurv Date: Tue, 13 Jun 2023 21:31:10 -0700 Subject: [PATCH 091/405] making these clickable was a mistake --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index c135ebdf8..5fefcdf47 100644 --- a/README.md +++ b/README.md @@ -4,16 +4,16 @@

- Minecraft - Minecraft - Minecraft - Minecraft - Minecraft - Minecraft - Minecraft - Minecraft - Minecraft - Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft

From 6a80b0d4ffea38131462557e67f56c0d2ca42701 Mon Sep 17 00:00:00 2001 From: leijurv Date: Tue, 13 Jun 2023 21:31:49 -0700 Subject: [PATCH 092/405] forgot github markdown is stupid --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 5fefcdf47..11fed3581 100644 --- a/README.md +++ b/README.md @@ -4,16 +4,16 @@

- Minecraft - Minecraft - Minecraft - Minecraft - Minecraft - Minecraft - Minecraft - Minecraft - Minecraft - Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft

From 54f0a3c14c63cc58f1188daaa329d660c898b6c9 Mon Sep 17 00:00:00 2001 From: leijurv Date: Tue, 13 Jun 2023 21:32:21 -0700 Subject: [PATCH 093/405] marginally better --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 11fed3581..c6a90ff93 100644 --- a/README.md +++ b/README.md @@ -4,16 +4,16 @@

- Minecraft - Minecraft - Minecraft - Minecraft - Minecraft - Minecraft - Minecraft - Minecraft - Minecraft - Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft

From b03d31e99013be1283f7701c1ced02afcd012105 Mon Sep 17 00:00:00 2001 From: leijurv Date: Tue, 13 Jun 2023 21:32:57 -0700 Subject: [PATCH 094/405] will github let me do this --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c6a90ff93..bbb386a74 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ Baritone is the pathfinding system used in [Impact](https://impactclient.net/) s [**Baritone Discord Server**](http://discord.gg/s6fRBAUpmr) **Quick download links:** - +

| Forge | Fabric | |---------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------| | [1.12.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.2.17/baritone-api-forge-1.2.17.jar) | | @@ -67,7 +67,7 @@ Baritone is the pathfinding system used in [Impact](https://impactclient.net/) s | [1.19.3 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-forge-1.9.1.jar) | [1.19.3 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-fabric-1.9.1.jar) | | [1.19.4 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-forge-1.9.3.jar) | [1.19.4 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-fabric-1.9.3.jar) | | [1.20.1 Forge](https://github.com/cabaletta/baritone/releases/download/v1.10.1/baritone-api-forge-1.10.1.jar) | [1.20.1 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.10.1/baritone-api-fabric-1.10.1.jar) | - +

**How to immediately get started:** Type `#goto 1000 500` in chat to go to x=1000 z=500. Type `#mine diamond_ore` to mine diamond ore. Type `#stop` to stop. For more, read [the usage page](USAGE.md) and/or watch this [tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa) For other versions of Minecraft or more complicated situations or for development, see [Installation & setup](SETUP.md). Also consider just installing [Impact](https://impactclient.net/), which comes with Baritone and is easier to install than wrangling with version JSONs and zips. For 1.16.5, [click here](https://www.youtube.com/watch?v=_4eVJ9Qz2J8) and see description. Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it. There's a [showcase video](https://youtu.be/CZkLXWo4Fg4) made by @Adovin#6313 on Baritone which I recommend. From 3662b3fdf18e4acba7cf9022f1143367f4737887 Mon Sep 17 00:00:00 2001 From: leijurv Date: Tue, 13 Jun 2023 21:33:12 -0700 Subject: [PATCH 095/405] nope --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bbb386a74..c6a90ff93 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ Baritone is the pathfinding system used in [Impact](https://impactclient.net/) s [**Baritone Discord Server**](http://discord.gg/s6fRBAUpmr) **Quick download links:** -

+ | Forge | Fabric | |---------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------| | [1.12.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.2.17/baritone-api-forge-1.2.17.jar) | | @@ -67,7 +67,7 @@ Baritone is the pathfinding system used in [Impact](https://impactclient.net/) s | [1.19.3 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-forge-1.9.1.jar) | [1.19.3 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-fabric-1.9.1.jar) | | [1.19.4 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-forge-1.9.3.jar) | [1.19.4 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-fabric-1.9.3.jar) | | [1.20.1 Forge](https://github.com/cabaletta/baritone/releases/download/v1.10.1/baritone-api-forge-1.10.1.jar) | [1.20.1 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.10.1/baritone-api-fabric-1.10.1.jar) | -

+ **How to immediately get started:** Type `#goto 1000 500` in chat to go to x=1000 z=500. Type `#mine diamond_ore` to mine diamond ore. Type `#stop` to stop. For more, read [the usage page](USAGE.md) and/or watch this [tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa) For other versions of Minecraft or more complicated situations or for development, see [Installation & setup](SETUP.md). Also consider just installing [Impact](https://impactclient.net/), which comes with Baritone and is easier to install than wrangling with version JSONs and zips. For 1.16.5, [click here](https://www.youtube.com/watch?v=_4eVJ9Qz2J8) and see description. Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it. There's a [showcase video](https://youtu.be/CZkLXWo4Fg4) made by @Adovin#6313 on Baritone which I recommend. From 75d47bb1104be9ca2a8045ec52068e926bb613a7 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 14 Jun 2023 01:53:29 -0500 Subject: [PATCH 096/405] Fix all usages of `Helper.mc` --- .../api/command/datatypes/RelativeFile.java | 9 ++- .../baritone/api/utils/IPlayerContext.java | 2 + src/main/java/baritone/Baritone.java | 27 ++++++--- src/main/java/baritone/BaritoneProvider.java | 2 +- .../command/ExampleBaritoneControl.java | 11 ++-- .../command/defaults/ComeCommand.java | 9 +-- .../defaults/ExploreFilterCommand.java | 4 +- .../command/defaults/RenderCommand.java | 4 +- .../baritone/command/defaults/SelCommand.java | 6 +- .../command/defaults/SurfaceCommand.java | 2 +- src/main/java/baritone/utils/IRenderer.java | 6 +- .../java/baritone/utils/PathRenderer.java | 59 +++++++++++-------- .../utils/player/BaritonePlayerContext.java | 9 +++ 13 files changed, 91 insertions(+), 59 deletions(-) diff --git a/src/api/java/baritone/api/command/datatypes/RelativeFile.java b/src/api/java/baritone/api/command/datatypes/RelativeFile.java index 0bc3604ab..ec605c048 100644 --- a/src/api/java/baritone/api/command/datatypes/RelativeFile.java +++ b/src/api/java/baritone/api/command/datatypes/RelativeFile.java @@ -19,6 +19,8 @@ package baritone.api.command.datatypes; import baritone.api.command.argument.IArgConsumer; import baritone.api.command.exception.CommandException; +import baritone.api.utils.Helper; +import net.minecraft.client.Minecraft; import java.io.File; import java.io.IOException; @@ -93,8 +95,13 @@ public enum RelativeFile implements IDatatypePost { .filter(s -> !s.contains(" ")); } + @Deprecated public static File gameDir() { - File gameDir = HELPER.mc.gameDir.getAbsoluteFile(); + return gameDir(Helper.mc); + } + + public static File gameDir(Minecraft mc) { + File gameDir = mc.gameDir.getAbsoluteFile(); if (gameDir.getName().equals(".")) { return gameDir.getParentFile(); } diff --git a/src/api/java/baritone/api/utils/IPlayerContext.java b/src/api/java/baritone/api/utils/IPlayerContext.java index 525f73ddc..14ca69fb9 100644 --- a/src/api/java/baritone/api/utils/IPlayerContext.java +++ b/src/api/java/baritone/api/utils/IPlayerContext.java @@ -75,6 +75,8 @@ public interface IPlayerContext { return new Vec3d(player().posX, player().posY + player().getEyeHeight(), player().posZ); } + BetterBlockPos viewerPos(); + default Rotation playerRotations() { return new Rotation(player().rotationYaw, player().rotationPitch); } diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index 637af2e3b..e85b57ce4 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -42,6 +42,7 @@ import java.util.concurrent.Executor; import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.function.Function; /** * @author Brady @@ -100,11 +101,11 @@ public class Baritone implements IBaritone { this.playerContext = new BaritonePlayerContext(this, mc); { - this.registerBehavior(pathingBehavior = new PathingBehavior(this)); - this.registerBehavior(lookBehavior = new LookBehavior(this)); - this.registerBehavior(inventoryBehavior = new InventoryBehavior(this)); - this.registerBehavior(inputOverrideHandler = new InputOverrideHandler(this)); - this.registerBehavior(waypointBehavior = new WaypointBehavior(this)); + pathingBehavior = this.registerBehavior(PathingBehavior::new); + lookBehavior = this.registerBehavior(LookBehavior::new); + inventoryBehavior = this.registerBehavior(InventoryBehavior::new); + inputOverrideHandler = this.registerBehavior(InputOverrideHandler::new); + waypointBehavior = this.registerBehavior(WaypointBehavior::new); } this.pathingControlManager = new PathingControlManager(this); @@ -125,15 +126,21 @@ public class Baritone implements IBaritone { this.commandManager = new CommandManager(this); } + public void registerBehavior(Behavior behavior) { + this.gameEventHandler.registerEventListener(behavior); + } + + public T registerBehavior(Function constructor) { + final T behavior = constructor.apply(this); + this.registerBehavior(behavior); + return behavior; + } + @Override public PathingControlManager getPathingControlManager() { return this.pathingControlManager; } - public void registerBehavior(Behavior behavior) { - this.gameEventHandler.registerEventListener(behavior); - } - @Override public InputOverrideHandler getInputOverrideHandler() { return this.inputOverrideHandler; @@ -173,6 +180,7 @@ public class Baritone implements IBaritone { return this.lookBehavior; } + @Override public ExploreProcess getExploreProcess() { return this.exploreProcess; } @@ -182,6 +190,7 @@ public class Baritone implements IBaritone { return this.mineProcess; } + @Override public FarmProcess getFarmProcess() { return this.farmProcess; } diff --git a/src/main/java/baritone/BaritoneProvider.java b/src/main/java/baritone/BaritoneProvider.java index b7c2403d2..a0621af93 100644 --- a/src/main/java/baritone/BaritoneProvider.java +++ b/src/main/java/baritone/BaritoneProvider.java @@ -45,7 +45,7 @@ public final class BaritoneProvider implements IBaritoneProvider { this.all = Collections.singletonList(this.primary); // Setup chat control, just for the primary instance - new ExampleBaritoneControl(this.primary); + this.primary.registerBehavior(ExampleBaritoneControl::new); } @Override diff --git a/src/main/java/baritone/command/ExampleBaritoneControl.java b/src/main/java/baritone/command/ExampleBaritoneControl.java index 28ced07f4..1a7b69644 100644 --- a/src/main/java/baritone/command/ExampleBaritoneControl.java +++ b/src/main/java/baritone/command/ExampleBaritoneControl.java @@ -17,8 +17,8 @@ package baritone.command; +import baritone.Baritone; import baritone.api.BaritoneAPI; -import baritone.api.IBaritone; import baritone.api.Settings; import baritone.api.command.argument.ICommandArgument; import baritone.api.command.exception.CommandNotEnoughArgumentsException; @@ -30,6 +30,7 @@ import baritone.api.event.events.TabCompleteEvent; import baritone.api.event.listener.AbstractGameEventListener; import baritone.api.utils.Helper; import baritone.api.utils.SettingsUtil; +import baritone.behavior.Behavior; import baritone.command.argument.ArgConsumer; import baritone.command.argument.CommandArguments; import baritone.command.manager.CommandManager; @@ -49,14 +50,14 @@ import java.util.stream.Stream; import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX; -public class ExampleBaritoneControl implements Helper, AbstractGameEventListener { +public class ExampleBaritoneControl extends Behavior implements Helper { private static final Settings settings = BaritoneAPI.getSettings(); private final ICommandManager manager; - public ExampleBaritoneControl(IBaritone baritone) { + public ExampleBaritoneControl(Baritone baritone) { + super(baritone); this.manager = baritone.getCommandManager(); - baritone.getGameEventHandler().registerEventListener(this); } @Override @@ -100,7 +101,7 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener return false; } else if (msg.trim().equalsIgnoreCase("orderpizza")) { try { - ((IGuiScreen) mc.currentScreen).openLink(new URI("https://www.dominos.com/en/pages/order/")); + ((IGuiScreen) ctx.minecraft().currentScreen).openLink(new URI("https://www.dominos.com/en/pages/order/")); } catch (NullPointerException | URISyntaxException ignored) {} return false; } diff --git a/src/main/java/baritone/command/defaults/ComeCommand.java b/src/main/java/baritone/command/defaults/ComeCommand.java index 5d3e3b829..b111ee1de 100644 --- a/src/main/java/baritone/command/defaults/ComeCommand.java +++ b/src/main/java/baritone/command/defaults/ComeCommand.java @@ -21,10 +21,7 @@ import baritone.api.IBaritone; import baritone.api.command.Command; import baritone.api.command.argument.IArgConsumer; import baritone.api.command.exception.CommandException; -import baritone.api.command.exception.CommandInvalidStateException; import baritone.api.pathing.goals.GoalBlock; -import net.minecraft.entity.Entity; -import net.minecraft.util.math.BlockPos; import java.util.Arrays; import java.util.List; @@ -39,11 +36,7 @@ public class ComeCommand extends Command { @Override public void execute(String label, IArgConsumer args) throws CommandException { args.requireMax(0); - Entity entity = mc.getRenderViewEntity(); - if (entity == null) { - throw new CommandInvalidStateException("render view entity is null"); - } - baritone.getCustomGoalProcess().setGoalAndPath(new GoalBlock(new BlockPos(entity))); + baritone.getCustomGoalProcess().setGoalAndPath(new GoalBlock(ctx.viewerPos())); logDirect("Coming"); } diff --git a/src/main/java/baritone/command/defaults/ExploreFilterCommand.java b/src/main/java/baritone/command/defaults/ExploreFilterCommand.java index c2057551f..6f306a966 100644 --- a/src/main/java/baritone/command/defaults/ExploreFilterCommand.java +++ b/src/main/java/baritone/command/defaults/ExploreFilterCommand.java @@ -41,7 +41,7 @@ public class ExploreFilterCommand extends Command { @Override public void execute(String label, IArgConsumer args) throws CommandException { args.requireMax(2); - File file = args.getDatatypePost(RelativeFile.INSTANCE, mc.gameDir.getAbsoluteFile().getParentFile()); + File file = args.getDatatypePost(RelativeFile.INSTANCE, ctx.minecraft().gameDir.getAbsoluteFile().getParentFile()); boolean invert = false; if (args.hasAny()) { if (args.getString().equalsIgnoreCase("invert")) { @@ -65,7 +65,7 @@ public class ExploreFilterCommand extends Command { @Override public Stream tabComplete(String label, IArgConsumer args) throws CommandException { if (args.hasExactlyOne()) { - return RelativeFile.tabComplete(args, RelativeFile.gameDir()); + return RelativeFile.tabComplete(args, RelativeFile.gameDir(ctx.minecraft())); } return Stream.empty(); } diff --git a/src/main/java/baritone/command/defaults/RenderCommand.java b/src/main/java/baritone/command/defaults/RenderCommand.java index cc9803d16..ab4a9dbcd 100644 --- a/src/main/java/baritone/command/defaults/RenderCommand.java +++ b/src/main/java/baritone/command/defaults/RenderCommand.java @@ -37,8 +37,8 @@ public class RenderCommand extends Command { public void execute(String label, IArgConsumer args) throws CommandException { args.requireMax(0); BetterBlockPos origin = ctx.playerFeet(); - int renderDistance = (mc.gameSettings.renderDistanceChunks + 1) * 16; - mc.renderGlobal.markBlockRangeForRenderUpdate( + int renderDistance = (ctx.minecraft().gameSettings.renderDistanceChunks + 1) * 16; + ctx.minecraft().renderGlobal.markBlockRangeForRenderUpdate( origin.x - renderDistance, 0, origin.z - renderDistance, diff --git a/src/main/java/baritone/command/defaults/SelCommand.java b/src/main/java/baritone/command/defaults/SelCommand.java index 9abe417ac..78035aa4e 100644 --- a/src/main/java/baritone/command/defaults/SelCommand.java +++ b/src/main/java/baritone/command/defaults/SelCommand.java @@ -92,7 +92,7 @@ public class SelCommand extends Command { if (action == Action.POS2 && pos1 == null) { throw new CommandInvalidStateException("Set pos1 first before using pos2"); } - BetterBlockPos playerPos = mc.getRenderViewEntity() != null ? BetterBlockPos.from(new BlockPos(mc.getRenderViewEntity())) : ctx.playerFeet(); + BetterBlockPos playerPos = ctx.viewerPos(); BetterBlockPos pos = args.hasAny() ? args.getDatatypePost(RelativeBlockPos.INSTANCE, playerPos) : playerPos; args.requireMax(0); if (action == Action.POS1) { @@ -198,7 +198,7 @@ public class SelCommand extends Command { baritone.getBuilderProcess().build("Fill", composite, origin); logDirect("Filling now"); } else if (action == Action.COPY) { - BetterBlockPos playerPos = mc.getRenderViewEntity() != null ? BetterBlockPos.from(new BlockPos(mc.getRenderViewEntity())) : ctx.playerFeet(); + BetterBlockPos playerPos = ctx.viewerPos(); BetterBlockPos pos = args.hasAny() ? args.getDatatypePost(RelativeBlockPos.INSTANCE, playerPos) : playerPos; args.requireMax(0); ISelection[] selections = manager.getSelections(); @@ -239,7 +239,7 @@ public class SelCommand extends Command { clipboardOffset = origin.subtract(pos); logDirect("Selection copied"); } else if (action == Action.PASTE) { - BetterBlockPos playerPos = mc.getRenderViewEntity() != null ? BetterBlockPos.from(new BlockPos(mc.getRenderViewEntity())) : ctx.playerFeet(); + BetterBlockPos playerPos = ctx.viewerPos(); BetterBlockPos pos = args.hasAny() ? args.getDatatypePost(RelativeBlockPos.INSTANCE, playerPos) : playerPos; args.requireMax(0); if (clipboard == null) { diff --git a/src/main/java/baritone/command/defaults/SurfaceCommand.java b/src/main/java/baritone/command/defaults/SurfaceCommand.java index 5d914aded..9ab22bdc2 100644 --- a/src/main/java/baritone/command/defaults/SurfaceCommand.java +++ b/src/main/java/baritone/command/defaults/SurfaceCommand.java @@ -54,7 +54,7 @@ public class SurfaceCommand extends Command { for (int currentIteratedY = startingYPos; currentIteratedY < worldHeight; currentIteratedY++) { final BetterBlockPos newPos = new BetterBlockPos(playerPos.getX(), currentIteratedY, playerPos.getZ()); - if (!(mc.world.getBlockState(newPos).getBlock() instanceof BlockAir) && newPos.getY() > playerPos.getY()) { + if (!(ctx.world().getBlockState(newPos).getBlock() instanceof BlockAir) && newPos.getY() > playerPos.getY()) { Goal goal = new GoalBlock(newPos.up()); logDirect(String.format("Going to: %s", goal.toString())); baritone.getCustomGoalProcess().setGoalAndPath(goal); diff --git a/src/main/java/baritone/utils/IRenderer.java b/src/main/java/baritone/utils/IRenderer.java index 26a7cf1ad..2134bcb99 100644 --- a/src/main/java/baritone/utils/IRenderer.java +++ b/src/main/java/baritone/utils/IRenderer.java @@ -19,11 +19,12 @@ package baritone.utils; import baritone.api.BaritoneAPI; import baritone.api.Settings; -import baritone.api.utils.Helper; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.util.math.AxisAlignedBB; @@ -35,7 +36,8 @@ public interface IRenderer { Tessellator tessellator = Tessellator.getInstance(); BufferBuilder buffer = tessellator.getBuffer(); - RenderManager renderManager = Helper.mc.getRenderManager(); + RenderManager renderManager = Minecraft.getMinecraft().getRenderManager(); + TextureManager textureManager = Minecraft.getMinecraft().getTextureManager(); Settings settings = BaritoneAPI.getSettings(); float[] color = new float[] {1.0F, 1.0F, 1.0F, 255.0F}; diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index deec261d4..65bf6269c 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -22,7 +22,7 @@ import baritone.api.event.events.RenderEvent; import baritone.api.pathing.calc.IPath; import baritone.api.pathing.goals.*; import baritone.api.utils.BetterBlockPos; -import baritone.api.utils.Helper; +import baritone.api.utils.IPlayerContext; import baritone.api.utils.interfaces.IGoalRenderPos; import baritone.behavior.PathingBehavior; import baritone.pathing.path.PathExecutor; @@ -52,31 +52,40 @@ public final class PathRenderer implements IRenderer { private PathRenderer() {} public static void render(RenderEvent event, PathingBehavior behavior) { - float partialTicks = event.getPartialTicks(); - Goal goal = behavior.getGoal(); - if (Helper.mc.currentScreen instanceof GuiClick) { - ((GuiClick) Helper.mc.currentScreen).onRender(); + final IPlayerContext ctx = behavior.ctx; + if (ctx.world() == null) { + return; + } + if (ctx.minecraft().currentScreen instanceof GuiClick) { + ((GuiClick) ctx.minecraft().currentScreen).onRender(); } - int thisPlayerDimension = behavior.baritone.getPlayerContext().world().provider.getDimensionType().getId(); - int currentRenderViewDimension = BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().world().provider.getDimensionType().getId(); + final float partialTicks = event.getPartialTicks(); + final Goal goal = behavior.getGoal(); + + final int thisPlayerDimension = ctx.world().provider.getDimensionType().getId(); + final int currentRenderViewDimension = BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().world().provider.getDimensionType().getId(); if (thisPlayerDimension != currentRenderViewDimension) { // this is a path for a bot in a different dimension, don't render it return; } - Entity renderView = Helper.mc.getRenderViewEntity(); - - if (renderView.world != BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().world()) { - System.out.println("I have no idea what's going on"); - System.out.println("The primary baritone is in a different world than the render view entity"); - System.out.println("Not rendering the path"); - return; - } + // TODO: This is goofy 💀 (pr/deprecateHelperMc) + // renderView isn't even needed for drawGoal since it's only used to + // calculate GoalYLevel x/z bounds, and ends up just cancelling itself + // out because of viewerPosX/Y/Z. I just changed it to center around the + // actual player so the goal box doesn't follow the camera in freecam. +// Entity renderView = Helper.mc.getRenderViewEntity(); +// if (renderView.world != BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().world()) { +// System.out.println("I have no idea what's going on"); +// System.out.println("The primary baritone is in a different world than the render view entity"); +// System.out.println("Not rendering the path"); +// return; +// } if (goal != null && settings.renderGoal.value) { - drawGoal(renderView, goal, partialTicks, settings.colorGoalBox.value); + drawGoal(ctx.player(), goal, partialTicks, settings.colorGoalBox.value); } if (!settings.renderPath.value) { @@ -86,9 +95,9 @@ public final class PathRenderer implements IRenderer { PathExecutor current = behavior.getCurrent(); // this should prevent most race conditions? PathExecutor next = behavior.getNext(); // like, now it's not possible for current!=null to be true, then suddenly false because of another thread if (current != null && settings.renderSelectionBoxes.value) { - drawManySelectionBoxes(renderView, current.toBreak(), settings.colorBlocksToBreak.value); - drawManySelectionBoxes(renderView, current.toPlace(), settings.colorBlocksToPlace.value); - drawManySelectionBoxes(renderView, current.toWalkInto(), settings.colorBlocksToWalkInto.value); + drawManySelectionBoxes(ctx.player(), current.toBreak(), settings.colorBlocksToBreak.value); + drawManySelectionBoxes(ctx.player(), current.toPlace(), settings.colorBlocksToPlace.value); + drawManySelectionBoxes(ctx.player(), current.toWalkInto(), settings.colorBlocksToWalkInto.value); } //drawManySelectionBoxes(player, Collections.singletonList(behavior.pathStart()), partialTicks, Color.WHITE); @@ -111,12 +120,12 @@ public final class PathRenderer implements IRenderer { currentlyRunning.pathToMostRecentNodeConsidered().ifPresent(mr -> { drawPath(mr, 0, settings.colorMostRecentConsidered.value, settings.fadePath.value, 10, 20); - drawManySelectionBoxes(renderView, Collections.singletonList(mr.getDest()), settings.colorMostRecentConsidered.value); + drawManySelectionBoxes(ctx.player(), Collections.singletonList(mr.getDest()), settings.colorMostRecentConsidered.value); }); }); } - public static void drawPath(IPath path, int startIndex, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0) { + private static void drawPath(IPath path, int startIndex, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0) { IRenderer.startLines(color, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); int fadeStart = fadeStart0 + startIndex; @@ -159,7 +168,7 @@ public final class PathRenderer implements IRenderer { IRenderer.endLines(settings.renderPathIgnoreDepth.value); } - public static void emitLine(double x1, double y1, double z1, double x2, double y2, double z2) { + private static void emitLine(double x1, double y1, double z1, double x2, double y2, double z2) { double vpX = renderManager.viewerPosX; double vpY = renderManager.viewerPosY; double vpZ = renderManager.viewerPosZ; @@ -202,11 +211,11 @@ public final class PathRenderer implements IRenderer { IRenderer.endLines(settings.renderSelectionBoxesIgnoreDepth.value); } - public static void drawGoal(Entity player, Goal goal, float partialTicks, Color color) { + private static void drawGoal(Entity player, Goal goal, float partialTicks, Color color) { drawGoal(player, goal, partialTicks, color, true); } - public static void drawGoal(Entity player, Goal goal, float partialTicks, Color color, boolean setupRender) { + private static void drawGoal(Entity player, Goal goal, float partialTicks, Color color, boolean setupRender) { double renderPosX = renderManager.viewerPosX; double renderPosY = renderManager.viewerPosY; double renderPosZ = renderManager.viewerPosZ; @@ -245,7 +254,7 @@ public final class PathRenderer implements IRenderer { if (settings.renderGoalXZBeacon.value) { glPushAttrib(GL_LIGHTING_BIT); - Helper.mc.getTextureManager().bindTexture(TileEntityBeaconRenderer.TEXTURE_BEACON_BEAM); + textureManager.bindTexture(TileEntityBeaconRenderer.TEXTURE_BEACON_BEAM); if (settings.renderGoalIgnoreDepth.value) { GlStateManager.disableDepth(); diff --git a/src/main/java/baritone/utils/player/BaritonePlayerContext.java b/src/main/java/baritone/utils/player/BaritonePlayerContext.java index 601d2bb72..7c7fe13f6 100644 --- a/src/main/java/baritone/utils/player/BaritonePlayerContext.java +++ b/src/main/java/baritone/utils/player/BaritonePlayerContext.java @@ -22,7 +22,10 @@ import baritone.api.cache.IWorldData; import baritone.api.utils.*; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; /** @@ -68,6 +71,12 @@ public final class BaritonePlayerContext implements IPlayerContext { return this.baritone.getWorldProvider().getCurrentWorld(); } + @Override + public BetterBlockPos viewerPos() { + final Entity entity = this.mc.getRenderViewEntity(); + return entity == null ? this.playerFeet() : BetterBlockPos.from(new BlockPos(entity)); + } + @Override public Rotation playerRotations() { return this.baritone.getLookBehavior().getEffectiveRotation().orElseGet(IPlayerContext.super::playerRotations); From 2db2d8be59f8510028576c5640cd4f61ba7ebe20 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 14 Jun 2023 02:00:10 -0500 Subject: [PATCH 097/405] Steal `BaritoneList` from `bot-system` --- src/main/java/baritone/BaritoneProvider.java | 24 ++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/main/java/baritone/BaritoneProvider.java b/src/main/java/baritone/BaritoneProvider.java index a0621af93..4593fefbc 100644 --- a/src/main/java/baritone/BaritoneProvider.java +++ b/src/main/java/baritone/BaritoneProvider.java @@ -28,7 +28,7 @@ import baritone.command.ExampleBaritoneControl; import baritone.utils.schematic.SchematicSystem; import net.minecraft.client.Minecraft; -import java.util.Collections; +import java.util.AbstractList; import java.util.List; /** @@ -42,7 +42,7 @@ public final class BaritoneProvider implements IBaritoneProvider { { this.primary = new Baritone(Minecraft.getMinecraft()); - this.all = Collections.singletonList(this.primary); + this.all = this.new BaritoneList(); // Setup chat control, just for the primary instance this.primary.registerBehavior(ExampleBaritoneControl::new); @@ -50,12 +50,12 @@ public final class BaritoneProvider implements IBaritoneProvider { @Override public IBaritone getPrimaryBaritone() { - return primary; + return this.primary; } @Override public List getAllBaritones() { - return all; + return this.all; } @Override @@ -72,4 +72,20 @@ public final class BaritoneProvider implements IBaritoneProvider { public ISchematicSystem getSchematicSystem() { return SchematicSystem.INSTANCE; } + + private final class BaritoneList extends AbstractList { + + @Override + public int size() { + return 1; + } + + @Override + public IBaritone get(int index) { + if (index == 0) { + return BaritoneProvider.this.primary; + } + throw new IndexOutOfBoundsException(); + } + } } From 5b39c0dd969bcedc44fb864647f9713550316e98 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 14 Jun 2023 12:18:50 -0500 Subject: [PATCH 098/405] Remove `getMinecraft()` from `BlockStateInterface` --- .../java/baritone/api/process/IBuilderProcess.java | 1 + .../java/baritone/behavior/PathingBehavior.java | 1 - .../pathing/movement/CalculationContext.java | 4 ++-- .../java/baritone/utils/BlockStateInterface.java | 14 ++++---------- .../utils/BlockStateInterfaceAccessWrapper.java | 6 ++++-- .../utils/player/BaritonePlayerContext.java | 1 - 6 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/api/java/baritone/api/process/IBuilderProcess.java b/src/api/java/baritone/api/process/IBuilderProcess.java index c63113cdd..29d8968a7 100644 --- a/src/api/java/baritone/api/process/IBuilderProcess.java +++ b/src/api/java/baritone/api/process/IBuilderProcess.java @@ -51,6 +51,7 @@ public interface IBuilderProcess extends IBaritoneProcess { */ boolean build(String name, File schematic, Vec3i origin); + @Deprecated default boolean build(String schematicFile, BlockPos origin) { File file = new File(new File(Minecraft.getMinecraft().gameDir, "schematics"), schematicFile); return build(schematicFile, file, origin); diff --git a/src/main/java/baritone/behavior/PathingBehavior.java b/src/main/java/baritone/behavior/PathingBehavior.java index f5433fe8d..31a884622 100644 --- a/src/main/java/baritone/behavior/PathingBehavior.java +++ b/src/main/java/baritone/behavior/PathingBehavior.java @@ -36,7 +36,6 @@ import baritone.pathing.path.PathExecutor; import baritone.utils.PathRenderer; import baritone.utils.PathingCommandContext; import baritone.utils.pathing.Favoring; -import net.minecraft.client.settings.GameSettings; import net.minecraft.util.math.BlockPos; import java.util.ArrayList; diff --git a/src/main/java/baritone/pathing/movement/CalculationContext.java b/src/main/java/baritone/pathing/movement/CalculationContext.java index 177435ef1..129f00e20 100644 --- a/src/main/java/baritone/pathing/movement/CalculationContext.java +++ b/src/main/java/baritone/pathing/movement/CalculationContext.java @@ -91,8 +91,8 @@ public class CalculationContext { this.baritone = baritone; EntityPlayerSP player = baritone.getPlayerContext().player(); this.world = baritone.getPlayerContext().world(); - this.worldData = (WorldData) baritone.getWorldProvider().getCurrentWorld(); - this.bsi = new BlockStateInterface(world, worldData, forUseOnAnotherThread); + this.worldData = (WorldData) baritone.getPlayerContext().worldData(); + this.bsi = new BlockStateInterface(baritone.getPlayerContext(), forUseOnAnotherThread); this.toolSet = new ToolSet(player); this.hasThrowaway = Baritone.settings().allowPlace.value && ((Baritone) baritone).getInventoryBehavior().hasGenericThrowaway(); this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.value && InventoryPlayer.isHotbar(player.inventory.getSlotFor(STACK_BUCKET_WATER)) && !world.provider.isNether(); diff --git a/src/main/java/baritone/utils/BlockStateInterface.java b/src/main/java/baritone/utils/BlockStateInterface.java index f451c2f1d..1d6dcaf79 100644 --- a/src/main/java/baritone/utils/BlockStateInterface.java +++ b/src/main/java/baritone/utils/BlockStateInterface.java @@ -27,7 +27,6 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; -import net.minecraft.client.Minecraft; import net.minecraft.init.Blocks; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkPos; @@ -44,7 +43,6 @@ public class BlockStateInterface { private final Long2ObjectMap loadedChunks; private final WorldData worldData; - protected final IBlockAccess world; public final BlockPos.MutableBlockPos isPassableBlockPos; public final IBlockAccess access; public final BetterWorldBorder worldBorder; @@ -61,13 +59,9 @@ public class BlockStateInterface { } public BlockStateInterface(IPlayerContext ctx, boolean copyLoadedChunks) { - this(ctx.world(), (WorldData) ctx.worldData(), copyLoadedChunks); - } - - public BlockStateInterface(World world, WorldData worldData, boolean copyLoadedChunks) { - this.world = world; + final World world = ctx.world(); this.worldBorder = new BetterWorldBorder(world.getWorldBorder()); - this.worldData = worldData; + this.worldData = (WorldData) ctx.worldData(); Long2ObjectMap worldLoaded = ((IChunkProviderClient) world.getChunkProvider()).loadedChunks(); if (copyLoadedChunks) { this.loadedChunks = new Long2ObjectOpenHashMap<>(worldLoaded); // make a copy that we can safely access from another thread @@ -75,11 +69,11 @@ public class BlockStateInterface { this.loadedChunks = worldLoaded; // this will only be used on the main thread } this.useTheRealWorld = !Baritone.settings().pathThroughCachedOnly.value; - if (!Minecraft.getMinecraft().isCallingFromMinecraftThread()) { + if (!ctx.minecraft().isCallingFromMinecraftThread()) { throw new IllegalStateException(); } this.isPassableBlockPos = new BlockPos.MutableBlockPos(); - this.access = new BlockStateInterfaceAccessWrapper(this); + this.access = new BlockStateInterfaceAccessWrapper(this, world); } public boolean worldContainsLoadedChunk(int blockX, int blockZ) { diff --git a/src/main/java/baritone/utils/BlockStateInterfaceAccessWrapper.java b/src/main/java/baritone/utils/BlockStateInterfaceAccessWrapper.java index 6dded1dd5..7ebde5f23 100644 --- a/src/main/java/baritone/utils/BlockStateInterfaceAccessWrapper.java +++ b/src/main/java/baritone/utils/BlockStateInterfaceAccessWrapper.java @@ -37,9 +37,11 @@ import javax.annotation.Nullable; public final class BlockStateInterfaceAccessWrapper implements IBlockAccess { private final BlockStateInterface bsi; + private final IBlockAccess world; - BlockStateInterfaceAccessWrapper(BlockStateInterface bsi) { + BlockStateInterfaceAccessWrapper(BlockStateInterface bsi, IBlockAccess world) { this.bsi = bsi; + this.world = world; } @Nullable @@ -76,6 +78,6 @@ public final class BlockStateInterfaceAccessWrapper implements IBlockAccess { @Override public WorldType getWorldType() { - return this.bsi.world.getWorldType(); + return this.world.getWorldType(); } } diff --git a/src/main/java/baritone/utils/player/BaritonePlayerContext.java b/src/main/java/baritone/utils/player/BaritonePlayerContext.java index 7c7fe13f6..282d3d8b6 100644 --- a/src/main/java/baritone/utils/player/BaritonePlayerContext.java +++ b/src/main/java/baritone/utils/player/BaritonePlayerContext.java @@ -25,7 +25,6 @@ import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.entity.Entity; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; /** From ae66004b80b69d802d507a4812995583d9525d34 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 14 Jun 2023 13:52:27 -0500 Subject: [PATCH 099/405] Custom registration of `Baritone` instances from `Minecraft` --- .../java/baritone/api/IBaritoneProvider.java | 40 ++++++++++++++-- src/main/java/baritone/BaritoneProvider.java | 48 +++++++++---------- 2 files changed, 60 insertions(+), 28 deletions(-) diff --git a/src/api/java/baritone/api/IBaritoneProvider.java b/src/api/java/baritone/api/IBaritoneProvider.java index 84a8abbbd..55d208e03 100644 --- a/src/api/java/baritone/api/IBaritoneProvider.java +++ b/src/api/java/baritone/api/IBaritoneProvider.java @@ -21,6 +21,7 @@ import baritone.api.cache.IWorldScanner; import baritone.api.command.ICommand; import baritone.api.command.ICommandSystem; import baritone.api.schematic.ISchematicSystem; +import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; import java.util.List; @@ -52,15 +53,13 @@ public interface IBaritoneProvider { List getAllBaritones(); /** - * Provides the {@link IBaritone} instance for a given {@link EntityPlayerSP}. This will likely be - * replaced with or be overloaded in addition to {@code #getBaritoneForUser(IBaritoneUser)} when - * {@code bot-system} is merged into {@code master}. + * Provides the {@link IBaritone} instance for a given {@link EntityPlayerSP}. * * @param player The player * @return The {@link IBaritone} instance. */ default IBaritone getBaritoneForPlayer(EntityPlayerSP player) { - for (IBaritone baritone : getAllBaritones()) { + for (IBaritone baritone : this.getAllBaritones()) { if (Objects.equals(player, baritone.getPlayerContext().player())) { return baritone; } @@ -68,6 +67,39 @@ public interface IBaritoneProvider { return null; } + /** + * Provides the {@link IBaritone} instance for a given {@link Minecraft}. + * + * @param minecraft The minecraft + * @return The {@link IBaritone} instance. + */ + default IBaritone getBaritoneForMinecraft(Minecraft minecraft) { + for (IBaritone baritone : this.getAllBaritones()) { + if (Objects.equals(minecraft, baritone.getPlayerContext().minecraft())) { + return baritone; + } + } + return null; + } + + /** + * Creates and registers a new {@link IBaritone} instance using the specified {@link Minecraft}. The existing + * instance is returned if already registered. + * + * @param minecraft The minecraft + * @return The {@link IBaritone} instance + */ + IBaritone createBaritone(Minecraft minecraft); + + /** + * Destroys and removes the specified {@link IBaritone} instance. If the specified instance is the + * {@link #getPrimaryBaritone() primary baritone}, this operation has no effect and will return {@code false}. + * + * @param baritone The baritone instance to remove + * @return Whether the baritone instance was removed + */ + boolean destroyBaritone(IBaritone baritone); + /** * Returns the {@link IWorldScanner} instance. This is not a type returned by * {@link IBaritone} implementation, because it is not linked with {@link IBaritone}. diff --git a/src/main/java/baritone/BaritoneProvider.java b/src/main/java/baritone/BaritoneProvider.java index 4593fefbc..b96cf03f7 100644 --- a/src/main/java/baritone/BaritoneProvider.java +++ b/src/main/java/baritone/BaritoneProvider.java @@ -28,8 +28,9 @@ import baritone.command.ExampleBaritoneControl; import baritone.utils.schematic.SchematicSystem; import net.minecraft.client.Minecraft; -import java.util.AbstractList; +import java.util.Collections; import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; /** * @author Brady @@ -37,25 +38,40 @@ import java.util.List; */ public final class BaritoneProvider implements IBaritoneProvider { - private final Baritone primary; private final List all; + private final List allView; - { - this.primary = new Baritone(Minecraft.getMinecraft()); - this.all = this.new BaritoneList(); + public BaritoneProvider() { + this.all = new CopyOnWriteArrayList<>(); + this.allView = Collections.unmodifiableList(this.all); // Setup chat control, just for the primary instance - this.primary.registerBehavior(ExampleBaritoneControl::new); + final Baritone primary = (Baritone) this.createBaritone(Minecraft.getMinecraft()); + primary.registerBehavior(ExampleBaritoneControl::new); } @Override public IBaritone getPrimaryBaritone() { - return this.primary; + return this.all.get(0); } @Override public List getAllBaritones() { - return this.all; + return this.allView; + } + + @Override + public synchronized IBaritone createBaritone(Minecraft minecraft) { + IBaritone baritone = this.getBaritoneForMinecraft(minecraft); + if (baritone == null) { + this.all.add(baritone = new Baritone(minecraft)); + } + return baritone; + } + + @Override + public synchronized boolean destroyBaritone(IBaritone baritone) { + return baritone != this.getPrimaryBaritone() && this.all.remove(baritone); } @Override @@ -72,20 +88,4 @@ public final class BaritoneProvider implements IBaritoneProvider { public ISchematicSystem getSchematicSystem() { return SchematicSystem.INSTANCE; } - - private final class BaritoneList extends AbstractList { - - @Override - public int size() { - return 1; - } - - @Override - public IBaritone get(int index) { - if (index == 0) { - return BaritoneProvider.this.primary; - } - throw new IndexOutOfBoundsException(); - } - } } From 8534e1ba552135f83924c7a66550ff4f46d88459 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 14 Jun 2023 14:04:34 -0500 Subject: [PATCH 100/405] =?UTF-8?q?=F0=9F=92=9A=20appease=20codacy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/baritone/Baritone.java | 42 ++++++++++++++++------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index e85b57ce4..776e646af 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -20,7 +20,9 @@ package baritone; import baritone.api.BaritoneAPI; import baritone.api.IBaritone; import baritone.api.Settings; +import baritone.api.behavior.IBehavior; import baritone.api.event.listener.IEventBus; +import baritone.api.process.IBaritoneProcess; import baritone.api.utils.IPlayerContext; import baritone.behavior.*; import baritone.cache.WorldProvider; @@ -64,7 +66,6 @@ public class Baritone implements IBaritone { private final PathingBehavior pathingBehavior; private final LookBehavior lookBehavior; private final InventoryBehavior inventoryBehavior; - private final WaypointBehavior waypointBehavior; private final InputOverrideHandler inputOverrideHandler; private final FollowProcess followProcess; @@ -73,7 +74,6 @@ public class Baritone implements IBaritone { private final CustomGoalProcess customGoalProcess; private final BuilderProcess builderProcess; private final ExploreProcess exploreProcess; - private final BackfillProcess backfillProcess; private final FarmProcess farmProcess; private final InventoryPauserProcess inventoryPauserProcess; @@ -101,24 +101,24 @@ public class Baritone implements IBaritone { this.playerContext = new BaritonePlayerContext(this, mc); { - pathingBehavior = this.registerBehavior(PathingBehavior::new); - lookBehavior = this.registerBehavior(LookBehavior::new); - inventoryBehavior = this.registerBehavior(InventoryBehavior::new); - inputOverrideHandler = this.registerBehavior(InputOverrideHandler::new); - waypointBehavior = this.registerBehavior(WaypointBehavior::new); + this.pathingBehavior = this.registerBehavior(PathingBehavior::new); + this.lookBehavior = this.registerBehavior(LookBehavior::new); + this.inventoryBehavior = this.registerBehavior(InventoryBehavior::new); + this.inputOverrideHandler = this.registerBehavior(InputOverrideHandler::new); + this.registerBehavior(WaypointBehavior::new); } this.pathingControlManager = new PathingControlManager(this); { - this.pathingControlManager.registerProcess(followProcess = new FollowProcess(this)); - this.pathingControlManager.registerProcess(mineProcess = new MineProcess(this)); - this.pathingControlManager.registerProcess(customGoalProcess = new CustomGoalProcess(this)); // very high iq - this.pathingControlManager.registerProcess(getToBlockProcess = new GetToBlockProcess(this)); - this.pathingControlManager.registerProcess(builderProcess = new BuilderProcess(this)); - this.pathingControlManager.registerProcess(exploreProcess = new ExploreProcess(this)); - this.pathingControlManager.registerProcess(backfillProcess = new BackfillProcess(this)); - this.pathingControlManager.registerProcess(farmProcess = new FarmProcess(this)); - this.pathingControlManager.registerProcess(inventoryPauserProcess = new InventoryPauserProcess(this)); + this.followProcess = this.registerProcess(FollowProcess::new); + this.mineProcess = this.registerProcess(MineProcess::new); + this.customGoalProcess = this.registerProcess(CustomGoalProcess::new); // very high iq + this.getToBlockProcess = this.registerProcess(GetToBlockProcess::new); + this.builderProcess = this.registerProcess(BuilderProcess::new); + this.exploreProcess = this.registerProcess(ExploreProcess::new); + this.farmProcess = this.registerProcess(FarmProcess::new); + this.inventoryPauserProcess = this.registerProcess(InventoryPauserProcess::new); + this.registerProcess(BackfillProcess::new); } this.worldProvider = new WorldProvider(this); @@ -126,16 +126,22 @@ public class Baritone implements IBaritone { this.commandManager = new CommandManager(this); } - public void registerBehavior(Behavior behavior) { + public void registerBehavior(IBehavior behavior) { this.gameEventHandler.registerEventListener(behavior); } - public T registerBehavior(Function constructor) { + public T registerBehavior(Function constructor) { final T behavior = constructor.apply(this); this.registerBehavior(behavior); return behavior; } + public T registerProcess(Function constructor) { + final T behavior = constructor.apply(this); + this.pathingControlManager.registerProcess(behavior); + return behavior; + } + @Override public PathingControlManager getPathingControlManager() { return this.pathingControlManager; From ea9245ad26379a9daccae6907e132abca2d71311 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 14 Jun 2023 14:23:24 -0500 Subject: [PATCH 101/405] missed that :weary: --- src/api/java/baritone/api/utils/Helper.java | 3 ++- src/api/java/baritone/api/utils/SettingsUtil.java | 5 ++--- src/main/java/baritone/command/defaults/BuildCommand.java | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/api/java/baritone/api/utils/Helper.java b/src/api/java/baritone/api/utils/Helper.java index e49744b4f..b99074ae0 100755 --- a/src/api/java/baritone/api/utils/Helper.java +++ b/src/api/java/baritone/api/utils/Helper.java @@ -42,7 +42,8 @@ public interface Helper { Helper HELPER = new Helper() {}; /** - * Instance of the game + * The main game instance returned by {@link Minecraft#getMinecraft()}. + * Deprecated since {@link IPlayerContext#minecraft()} should be used instead (In the majority of cases). */ @Deprecated Minecraft mc = Minecraft.getMinecraft(); diff --git a/src/api/java/baritone/api/utils/SettingsUtil.java b/src/api/java/baritone/api/utils/SettingsUtil.java index 0b9c64737..efc080cf5 100644 --- a/src/api/java/baritone/api/utils/SettingsUtil.java +++ b/src/api/java/baritone/api/utils/SettingsUtil.java @@ -20,6 +20,7 @@ package baritone.api.utils; import baritone.api.BaritoneAPI; import baritone.api.Settings; import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; import net.minecraft.item.Item; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.Vec3i; @@ -44,8 +45,6 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; -import static net.minecraft.client.Minecraft.getMinecraft; - public class SettingsUtil { public static final String SETTINGS_DEFAULT_NAME = "settings.txt"; @@ -105,7 +104,7 @@ public class SettingsUtil { } private static Path settingsByName(String name) { - return getMinecraft().gameDir.toPath().resolve("baritone").resolve(name); + return Minecraft.getMinecraft().gameDir.toPath().resolve("baritone").resolve(name); } public static List modifiedSettings(Settings settings) { diff --git a/src/main/java/baritone/command/defaults/BuildCommand.java b/src/main/java/baritone/command/defaults/BuildCommand.java index 724582865..12f287955 100644 --- a/src/main/java/baritone/command/defaults/BuildCommand.java +++ b/src/main/java/baritone/command/defaults/BuildCommand.java @@ -26,7 +26,6 @@ import baritone.api.command.datatypes.RelativeFile; import baritone.api.command.exception.CommandException; import baritone.api.command.exception.CommandInvalidStateException; import baritone.api.utils.BetterBlockPos; -import net.minecraft.client.Minecraft; import org.apache.commons.io.FilenameUtils; import java.io.File; @@ -36,10 +35,11 @@ import java.util.stream.Stream; public class BuildCommand extends Command { - private static final File schematicsDir = new File(Minecraft.getMinecraft().gameDir, "schematics"); + private final File schematicsDir; public BuildCommand(IBaritone baritone) { super(baritone, "build"); + this.schematicsDir = new File(baritone.getPlayerContext().minecraft().gameDir, "schematics"); } @Override From 9672bd2c6d83bc9ae24ea607650e84804fd68c06 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 14 Jun 2023 16:08:34 -0500 Subject: [PATCH 102/405] Fix compile --- src/main/java/baritone/utils/PathRenderer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index 13a14f6dc..bec8937a4 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -108,14 +108,14 @@ public final class PathRenderer implements IRenderer { drawPath(Elytra.path.subList(Math.max(behavior.baritone.elytra.playerNear - 30, 0), Math.min(behavior.baritone.elytra.playerNear + 30, Elytra.path.size())), 0, Color.RED, false, 0, 0); if (behavior.baritone.elytra.goal != null) { - drawDankLitGoalBox(renderView, new GoalBlock(behavior.baritone.elytra.goal), partialTicks, Color.GREEN); + drawGoal(renderView, new GoalBlock(behavior.baritone.elytra.goal), partialTicks, Color.GREEN); } if (!behavior.baritone.elytra.lines.isEmpty() && Baritone.settings().renderRaytraces.value) { IRenderer.startLines(Color.BLUE, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); boolean orig = settings.renderPathAsLine.value; settings.renderPathAsLine.value = true; for (Pair line : behavior.baritone.elytra.lines) { - drawLine(line.first().x, line.first().y, line.first().z, line.second().x, line.second().y, line.second().z); + emitLine(line.first().x, line.first().y, line.first().z, line.second().x, line.second().y, line.second().z); tessellator.draw(); } settings.renderPathAsLine.value = orig; From bde0c620ad6270cbd363140ab6be8aa49370644d Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 14 Jun 2023 16:11:11 -0500 Subject: [PATCH 103/405] Allow freeLook when using elytra --- .../api/event/events/RotationMoveEvent.java | 38 ++++++++- .../launch/mixins/MixinEntityLivingBase.java | 85 +++++++++++++++---- .../launch/mixins/MixinEntityPlayerSP.java | 16 ---- .../launch/mixins/MixinMinecraft.java | 15 ++++ src/main/java/baritone/Elytra.java | 6 +- .../java/baritone/behavior/LookBehavior.java | 1 + 6 files changed, 121 insertions(+), 40 deletions(-) diff --git a/src/api/java/baritone/api/event/events/RotationMoveEvent.java b/src/api/java/baritone/api/event/events/RotationMoveEvent.java index 109061c7e..a2ab17ed6 100644 --- a/src/api/java/baritone/api/event/events/RotationMoveEvent.java +++ b/src/api/java/baritone/api/event/events/RotationMoveEvent.java @@ -17,6 +17,7 @@ package baritone.api.event.events; +import baritone.api.utils.Rotation; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; @@ -31,14 +32,27 @@ public final class RotationMoveEvent { */ private final Type type; + private final Rotation original; + /** * The yaw rotation */ private float yaw; - public RotationMoveEvent(Type type, float yaw) { + /** + * The pitch rotation + */ + private float pitch; + + public RotationMoveEvent(Type type, float yaw, float pitch) { this.type = type; + this.original = new Rotation(yaw, pitch); this.yaw = yaw; + this.pitch = pitch; + } + + public Rotation getOriginal() { + return this.original; } /** @@ -46,21 +60,37 @@ public final class RotationMoveEvent { * * @param yaw Yaw rotation */ - public final void setYaw(float yaw) { + public void setYaw(float yaw) { this.yaw = yaw; } /** * @return The yaw rotation */ - public final float getYaw() { + public float getYaw() { return this.yaw; } + /** + * Set the pitch movement rotation + * + * @param pitch Pitch rotation + */ + public void setPitch(float pitch) { + this.pitch = pitch; + } + + /** + * @return The pitch rotation + */ + public float getPitch() { + return pitch; + } + /** * @return The type of the event */ - public final Type getType() { + public Type getType() { return this.type; } diff --git a/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java b/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java index 0fd2436c9..f8544dd2f 100644 --- a/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java +++ b/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java @@ -25,11 +25,14 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import java.util.Optional; + import static org.spongepowered.asm.lib.Opcodes.GETFIELD; /** @@ -42,11 +45,14 @@ public abstract class MixinEntityLivingBase extends Entity { /** * Event called to override the movement direction when jumping */ + @Unique private RotationMoveEvent jumpRotationEvent; - public MixinEntityLivingBase(World worldIn, RotationMoveEvent jumpRotationEvent) { + @Unique + private RotationMoveEvent elytraRotationEvent; + + public MixinEntityLivingBase(World worldIn) { super(worldIn); - this.jumpRotationEvent = jumpRotationEvent; } @Inject( @@ -54,14 +60,10 @@ public abstract class MixinEntityLivingBase extends Entity { at = @At("HEAD") ) private void preMoveRelative(CallbackInfo ci) { - // noinspection ConstantConditions - if (EntityPlayerSP.class.isInstance(this)) { - IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this); - if (baritone != null) { - this.jumpRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.JUMP, this.rotationYaw); - baritone.getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent); - } - } + this.getBaritone().ifPresent(baritone -> { + this.jumpRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.JUMP, this.rotationYaw, this.rotationPitch); + baritone.getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent); + }); } @Redirect( @@ -79,6 +81,38 @@ public abstract class MixinEntityLivingBase extends Entity { return self.rotationYaw; } + @Inject( + method = "travel", + at = @At( + value = "INVOKE", + target = "net/minecraft/entity/EntityLivingBase.getLookVec()Lnet/minecraft/util/math/Vec3d;" + ) + ) + private void onPreElytraMove(float strafe, float vertical, float forward, CallbackInfo ci) { + this.getBaritone().ifPresent(baritone -> { + this.elytraRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw, this.rotationPitch); + baritone.getGameEventHandler().onPlayerRotationMove(this.elytraRotationEvent); + this.rotationYaw = this.elytraRotationEvent.getYaw(); + this.rotationPitch = this.elytraRotationEvent.getPitch(); + }); + } + + @Inject( + method = "travel", + at = @At( + value = "INVOKE", + target = "net/minecraft/entity/EntityLivingBase.move(Lnet/minecraft/entity/MoverType;DDD)V", + shift = At.Shift.AFTER + ) + ) + private void onPostElytraMove(float strafe, float vertical, float forward, CallbackInfo ci) { + if (this.elytraRotationEvent != null) { + this.rotationYaw = this.elytraRotationEvent.getOriginal().getYaw(); + this.rotationPitch = this.elytraRotationEvent.getOriginal().getPitch(); + this.elytraRotationEvent = null; + } + } + @Redirect( method = "travel", at = @At( @@ -86,17 +120,32 @@ public abstract class MixinEntityLivingBase extends Entity { target = "net/minecraft/entity/EntityLivingBase.moveRelative(FFFF)V" ) ) - private void travel(EntityLivingBase self, float strafe, float up, float forward, float friction) { - // noinspection ConstantConditions - if (!EntityPlayerSP.class.isInstance(this) || BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this) == null) { + private void onMoveRelative(EntityLivingBase self, float strafe, float up, float forward, float friction) { + Optional baritone = this.getBaritone(); + if (!baritone.isPresent()) { moveRelative(strafe, up, forward, friction); return; } - RotationMoveEvent motionUpdateRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw); - BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerRotationMove(motionUpdateRotationEvent); - float originalYaw = this.rotationYaw; - this.rotationYaw = motionUpdateRotationEvent.getYaw(); + + RotationMoveEvent event = new RotationMoveEvent(RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw, this.rotationPitch); + baritone.get().getGameEventHandler().onPlayerRotationMove(event); + + this.rotationYaw = event.getYaw(); + this.rotationPitch = event.getPitch(); + this.moveRelative(strafe, up, forward, friction); - this.rotationYaw = originalYaw; + + this.rotationYaw = event.getOriginal().getYaw(); + this.rotationPitch = event.getOriginal().getPitch(); + } + + @Unique + private Optional getBaritone() { + // noinspection ConstantConditions + if (EntityPlayerSP.class.isInstance(this)) { + return Optional.ofNullable(BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this)); + } else { + return Optional.empty(); + } } } diff --git a/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java b/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java index 7c1225b9b..3f34c0e77 100644 --- a/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java +++ b/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java @@ -73,22 +73,6 @@ public class MixinEntityPlayerSP { } } - @Inject( - method = "onUpdate", - at = @At( - value = "INVOKE", - target = "net/minecraft/client/entity/EntityPlayerSP.onUpdateWalkingPlayer()V", - shift = At.Shift.BY, - by = 2 - ) - ) - private void onPostUpdate(CallbackInfo ci) { - IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this); - if (baritone != null) { - baritone.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.POST)); - } - } - @Redirect( method = "onLivingUpdate", at = @At( diff --git a/src/launch/java/baritone/launch/mixins/MixinMinecraft.java b/src/launch/java/baritone/launch/mixins/MixinMinecraft.java index 097c72905..edc1e3fcc 100644 --- a/src/launch/java/baritone/launch/mixins/MixinMinecraft.java +++ b/src/launch/java/baritone/launch/mixins/MixinMinecraft.java @@ -20,6 +20,7 @@ package baritone.launch.mixins; import baritone.api.BaritoneAPI; import baritone.api.IBaritone; import baritone.api.event.events.BlockInteractEvent; +import baritone.api.event.events.PlayerUpdateEvent; import baritone.api.event.events.TickEvent; import baritone.api.event.events.WorldEvent; import baritone.api.event.events.type.EventState; @@ -84,7 +85,21 @@ public class MixinMinecraft { baritone.getGameEventHandler().onTick(tickProvider.apply(EventState.PRE, type)); } + } + @Inject( + method = "runTick", + at = @At( + value = "INVOKE", + target = "net/minecraft/client/multiplayer/WorldClient.updateEntities()V", + shift = At.Shift.AFTER + ) + ) + private void postUpdateEntities(CallbackInfo ci) { + IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(this.player); + if (baritone != null) { + baritone.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.POST)); + } } @Inject( diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index 2f724c692..35ea70b95 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -264,17 +264,19 @@ public class Elytra extends Behavior implements Helper { } if (requireClear ? isClear(start, dest) : clearView(start, dest)) { Rotation rot = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()); - ctx.player().rotationYaw = rot.getYaw(); +// ctx.player().rotationYaw = rot.getYaw(); long a = System.currentTimeMillis(); Float pitch = solvePitch(dest.subtract(start), steps, relaxation == 2); if (pitch == null) { + baritone.getLookBehavior().updateTarget(new Rotation(rot.getYaw(), ctx.playerRotations().getPitch()), false); continue; } long b = System.currentTimeMillis(); - ctx.player().rotationPitch = pitch; +// ctx.player().rotationPitch = pitch; System.out.println("Solved pitch in " + (b - a) + " total time " + (b - t)); goingTo = i; goal = path.get(i).add(0, dy, 0); + baritone.getLookBehavior().updateTarget(new Rotation(rot.getYaw(), pitch), false); return; } } diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index 99e496e6f..d9a06b086 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -149,6 +149,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior { public void onPlayerRotationMove(RotationMoveEvent event) { if (this.target != null) { event.setYaw(this.target.rotation.getYaw()); + event.setPitch(this.target.rotation.getPitch()); } } From 91bf7d726b30add13deaf14094a15b58f93c8b70 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 14 Jun 2023 16:32:56 -0500 Subject: [PATCH 104/405] Un-scuff and add setting --- src/api/java/baritone/api/Settings.java | 1 + .../java/baritone/launch/mixins/MixinMinecraft.java | 2 ++ src/main/java/baritone/Elytra.java | 4 +--- src/main/java/baritone/behavior/LookBehavior.java | 12 ++++++++---- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 30506fd08..f5cf3c77a 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -53,6 +53,7 @@ public final class Settings { public final Setting elytraFireworkSpeed = new Setting<>(0.6); public final Setting wasteFireworks = new Setting<>(false); public final Setting renderRaytraces = new Setting<>(false); + public final Setting elytraFreeLook = new Setting<>(false); /** * Allow Baritone to break blocks diff --git a/src/launch/java/baritone/launch/mixins/MixinMinecraft.java b/src/launch/java/baritone/launch/mixins/MixinMinecraft.java index edc1e3fcc..19d4741ca 100644 --- a/src/launch/java/baritone/launch/mixins/MixinMinecraft.java +++ b/src/launch/java/baritone/launch/mixins/MixinMinecraft.java @@ -98,6 +98,8 @@ public class MixinMinecraft { private void postUpdateEntities(CallbackInfo ci) { IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(this.player); if (baritone != null) { + // Intentionally call this after all entities have been updated. That way, any modification to rotations + // can be recognized by other entity code. (Fireworks and Pigs, for example) baritone.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.POST)); } } diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index 35ea70b95..b8a05010b 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -48,7 +48,7 @@ public class Elytra extends Behavior implements Helper { static { try { - DataInputStream in = new DataInputStream(new FileInputStream(new File("/Users/leijurv/Dropbox/nether-pathfinder/build/test"))); + DataInputStream in = new DataInputStream(new FileInputStream(new File("E:/Brady/Documents/Java/baritone/test"))); int count = in.readInt(); System.out.println("Count: " + count); for (int i = 0; i < count; i++) { @@ -264,7 +264,6 @@ public class Elytra extends Behavior implements Helper { } if (requireClear ? isClear(start, dest) : clearView(start, dest)) { Rotation rot = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()); -// ctx.player().rotationYaw = rot.getYaw(); long a = System.currentTimeMillis(); Float pitch = solvePitch(dest.subtract(start), steps, relaxation == 2); if (pitch == null) { @@ -272,7 +271,6 @@ public class Elytra extends Behavior implements Helper { continue; } long b = System.currentTimeMillis(); -// ctx.player().rotationPitch = pitch; System.out.println("Solved pitch in " + (b - a) + " total time " + (b - t)); goingTo = i; goal = path.get(i).add(0, dy, 0); diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index d9a06b086..1b85ac7e3 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -56,7 +56,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior { @Override public void updateTarget(Rotation rotation, boolean blockInteract) { - this.target = new Target(rotation, blockInteract); + this.target = new Target(rotation, Target.Mode.resolve(ctx, blockInteract)); } @Override @@ -186,9 +186,9 @@ public final class LookBehavior extends Behavior implements ILookBehavior { public final Rotation rotation; public final Mode mode; - public Target(Rotation rotation, boolean blockInteract) { + public Target(Rotation rotation, Mode mode) { this.rotation = rotation; - this.mode = Mode.resolve(blockInteract); + this.mode = mode; } enum Mode { @@ -207,12 +207,16 @@ public final class LookBehavior extends Behavior implements ILookBehavior { */ NONE; - static Mode resolve(boolean blockInteract) { + static Mode resolve(IPlayerContext ctx, boolean blockInteract) { final Settings settings = Baritone.settings(); final boolean antiCheat = settings.antiCheatCompatibility.value; final boolean blockFreeLook = settings.blockFreeLook.value; final boolean freeLook = settings.freeLook.value; + if (ctx.player().isElytraFlying()) { + return settings.elytraFreeLook.value ? SERVER : CLIENT; + } + if (!freeLook && !blockFreeLook) return CLIENT; if (!blockFreeLook && blockInteract) return CLIENT; From 06d11c187417374103a6e4b0ed162e1dfbfe4083 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 14 Jun 2023 16:59:03 -0500 Subject: [PATCH 105/405] Revert file path --- src/main/java/baritone/Elytra.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index b8a05010b..6d12e9f0d 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -48,7 +48,7 @@ public class Elytra extends Behavior implements Helper { static { try { - DataInputStream in = new DataInputStream(new FileInputStream(new File("E:/Brady/Documents/Java/baritone/test"))); + DataInputStream in = new DataInputStream(new FileInputStream(new File("/Users/leijurv/Dropbox/nether-pathfinder/build/test"))); int count = in.readInt(); System.out.println("Count: " + count); for (int i = 0; i < count; i++) { From f14caa3778c580877ea73d742339b67262ff4d70 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 14 Jun 2023 17:32:47 -0500 Subject: [PATCH 106/405] Fix cringe shift by injector --- .../java/baritone/launch/mixins/MixinEntityPlayerSP.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java b/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java index 7c1225b9b..4f6031d78 100644 --- a/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java +++ b/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java @@ -61,9 +61,8 @@ public class MixinEntityPlayerSP { method = "onUpdate", at = @At( value = "INVOKE", - target = "net/minecraft/client/entity/EntityPlayerSP.isRiding()Z", - shift = At.Shift.BY, - by = -3 + target = "net/minecraft/client/entity/AbstractClientPlayer.onUpdate()V", + shift = At.Shift.AFTER ) ) private void onPreUpdate(CallbackInfo ci) { From 26a2945696d83227ebbc429ee1900a435eb21482 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 14 Jun 2023 19:13:07 -0500 Subject: [PATCH 107/405] remove comment --- src/main/java/baritone/utils/PathRenderer.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index 65bf6269c..b3abc8cd2 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -71,19 +71,6 @@ public final class PathRenderer implements IRenderer { return; } - // TODO: This is goofy 💀 (pr/deprecateHelperMc) - // renderView isn't even needed for drawGoal since it's only used to - // calculate GoalYLevel x/z bounds, and ends up just cancelling itself - // out because of viewerPosX/Y/Z. I just changed it to center around the - // actual player so the goal box doesn't follow the camera in freecam. -// Entity renderView = Helper.mc.getRenderViewEntity(); -// if (renderView.world != BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().world()) { -// System.out.println("I have no idea what's going on"); -// System.out.println("The primary baritone is in a different world than the render view entity"); -// System.out.println("Not rendering the path"); -// return; -// } - if (goal != null && settings.renderGoal.value) { drawGoal(ctx.player(), goal, partialTicks, settings.colorGoalBox.value); } From 8df67786415d5f0eb8f4fb6802bf0b8a385d20c9 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 15 Jun 2023 00:32:26 -0700 Subject: [PATCH 108/405] sort of integrated nether pathfinder --- build.gradle | 18 +++--- src/main/java/baritone/Elytra.java | 28 +++------ .../command/defaults/DefaultCommands.java | 3 +- .../command/defaults/ElytraCommand.java | 61 +++++++++++++++++++ .../java/baritone/utils/PathRenderer.java | 3 +- 5 files changed, 84 insertions(+), 29 deletions(-) create mode 100644 src/main/java/baritone/command/defaults/ElytraCommand.java diff --git a/build.gradle b/build.gradle index 0ce05058c..7909911be 100755 --- a/build.gradle +++ b/build.gradle @@ -100,7 +100,9 @@ dependencies { exclude module: 'commons-io' exclude module: 'log4j-core' } + runtime launchCompile('dev.babbaj:nether-pathfinder:1.3') testImplementation 'junit:junit:4.12' + implementation 'dev.babbaj:nether-pathfinder:1.3' } mixin { @@ -153,16 +155,16 @@ install { def jarSAForgeName = String.format("%s-standalone-forge-%s", rootProject.name, version.toString()) artifacts { - archives file("$buildDir/libs/"+jarApiName+".jar") - archives file("$buildDir/libs/"+jarApiForgeName+".jar") - archives file("$buildDir/libs/"+jarSAName+".jar") - archives file("$buildDir/libs/"+jarSAForgeName+".jar") + archives file("$buildDir/libs/" + jarApiName + ".jar") + archives file("$buildDir/libs/" + jarApiForgeName + ".jar") + archives file("$buildDir/libs/" + jarSAName + ".jar") + archives file("$buildDir/libs/" + jarSAForgeName + ".jar") } repositories.mavenInstaller { - addFilter('api') { artifact, file -> artifact.name == "baritone-api" } - addFilter('api-forge') { artifact, file -> artifact.name == "baritone-api-forge" } - addFilter('standalone') { artifact, file -> artifact.name == "baritone-standalone" } - addFilter('standalone-forge') { artifact, file -> artifact.name == "baritone-standalone-forge" } + addFilter('api') { artifact, file -> artifact.name == "baritone-api" } + addFilter('api-forge') { artifact, file -> artifact.name == "baritone-api-forge" } + addFilter('standalone') { artifact, file -> artifact.name == "baritone-standalone" } + addFilter('standalone-forge') { artifact, file -> artifact.name == "baritone-standalone-forge" } } } diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index 2f724c692..5a8cae634 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -25,6 +25,7 @@ import baritone.api.utils.RotationUtils; import baritone.behavior.Behavior; import baritone.utils.BlockStateInterface; import com.mojang.realmsclient.util.Pair; +import dev.babbaj.pathfinder.NetherPathfinder; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.item.EntityFireworkRocket; @@ -36,28 +37,16 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Vec3d; -import java.io.DataInputStream; -import java.io.File; -import java.io.FileInputStream; import java.util.*; +import java.util.stream.Collectors; public class Elytra extends Behavior implements Helper { - public static List path = new ArrayList<>(); + public List path = new ArrayList<>(); - static { - - try { - DataInputStream in = new DataInputStream(new FileInputStream(new File("/Users/leijurv/Dropbox/nether-pathfinder/build/test"))); - int count = in.readInt(); - System.out.println("Count: " + count); - for (int i = 0; i < count; i++) { - path.add(new BetterBlockPos((int) in.readDouble(), (int) in.readDouble(), (int) in.readDouble())); - } - removeBacktracks(); - } catch (Exception e) { - throw new RuntimeException(e); - } + public void path(BlockPos destination) { + path = Arrays.stream(NetherPathfinder.pathFind(146008555100680L, false, false, ctx.playerFeet().x, ctx.playerFeet().y, ctx.playerFeet().z, destination.getX(), destination.getY(), destination.getZ())).mapToObj(BlockPos::fromLong).map(BetterBlockPos::new).collect(Collectors.toList()); + removeBacktracks(); } public int playerNear; @@ -211,6 +200,9 @@ public class Elytra extends Behavior implements Helper { if (event.getType() == TickEvent.Type.OUT) { return; } + if (path.isEmpty()) { + return; + } fixNearPlayer(); baritone.getInputOverrideHandler().clearAllKeys(); lines.clear(); @@ -425,7 +417,7 @@ public class Elytra extends Behavior implements Helper { //System.out.println(playerNear); } - public static void removeBacktracks() { + public void removeBacktracks() { Map positionFirstSeen = new HashMap<>(); for (int i = 0; i < path.size(); i++) { BetterBlockPos pos = path.get(i); diff --git a/src/main/java/baritone/command/defaults/DefaultCommands.java b/src/main/java/baritone/command/defaults/DefaultCommands.java index 901fda713..b8e3c924b 100644 --- a/src/main/java/baritone/command/defaults/DefaultCommands.java +++ b/src/main/java/baritone/command/defaults/DefaultCommands.java @@ -66,7 +66,8 @@ public final class DefaultCommands { new WaypointsCommand(baritone), new CommandAlias(baritone, "sethome", "Sets your home waypoint", "waypoints save home"), new CommandAlias(baritone, "home", "Path to your home waypoint", "waypoints goto home"), - new SelCommand(baritone) + new SelCommand(baritone), + new ElytraCommand(baritone) )); ExecutionControlCommands prc = new ExecutionControlCommands(baritone); commands.add(prc.pauseCommand); diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java new file mode 100644 index 000000000..2d2e3f0ee --- /dev/null +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -0,0 +1,61 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.command.defaults; + +import baritone.Baritone; +import baritone.api.IBaritone; +import baritone.api.command.Command; +import baritone.api.command.argument.IArgConsumer; +import baritone.api.command.exception.CommandException; +import baritone.api.pathing.goals.GoalXZ; +import baritone.api.process.ICustomGoalProcess; +import net.minecraft.util.math.BlockPos; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; + +public class ElytraCommand extends Command { + + public ElytraCommand(IBaritone baritone) { + super(baritone, "elytra"); + } + + @Override + public void execute(String label, IArgConsumer args) throws CommandException { + ICustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess(); + args.requireMax(0); + GoalXZ goal = (GoalXZ) customGoalProcess.getGoal(); + ((Baritone) baritone).elytra.path(new BlockPos(goal.getX(), 64, goal.getZ())); + } + + @Override + public Stream tabComplete(String label, IArgConsumer args) throws CommandException { + return Stream.empty(); + } + + @Override + public String getShortDesc() { + return "elytra time"; + } + + @Override + public List getLongDesc() { + return Arrays.asList(); + } +} diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index bec8937a4..df0d5b0ca 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -18,7 +18,6 @@ package baritone.utils; import baritone.Baritone; -import baritone.Elytra; import baritone.api.BaritoneAPI; import baritone.api.event.events.RenderEvent; import baritone.api.pathing.goals.*; @@ -106,7 +105,7 @@ public final class PathRenderer implements IRenderer { drawPath(next.getPath().positions(), 0, settings.colorNextPath.value, settings.fadePath.value, 10, 20); } - drawPath(Elytra.path.subList(Math.max(behavior.baritone.elytra.playerNear - 30, 0), Math.min(behavior.baritone.elytra.playerNear + 30, Elytra.path.size())), 0, Color.RED, false, 0, 0); + drawPath(behavior.baritone.elytra.path.subList(Math.max(behavior.baritone.elytra.playerNear - 30, 0), Math.min(behavior.baritone.elytra.playerNear + 30, behavior.baritone.elytra.path.size())), 0, Color.RED, false, 0, 0); if (behavior.baritone.elytra.goal != null) { drawGoal(renderView, new GoalBlock(behavior.baritone.elytra.goal), partialTicks, Color.GREEN); } From fe8ec19b6d8e321a08d0300be5b7a25ab4be7226 Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 15 Jun 2023 22:07:44 -0500 Subject: [PATCH 109/405] Fix `renderRaytraces` crash --- src/main/java/baritone/utils/PathRenderer.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index df0d5b0ca..15ae73696 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -115,7 +115,6 @@ public final class PathRenderer implements IRenderer { settings.renderPathAsLine.value = true; for (Pair line : behavior.baritone.elytra.lines) { emitLine(line.first().x, line.first().y, line.first().z, line.second().x, line.second().y, line.second().z); - tessellator.draw(); } settings.renderPathAsLine.value = orig; IRenderer.endLines(settings.renderPathIgnoreDepth.value); From a9e9cd978df262403c3a7571ca15187aa0a21bbe Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 15 Jun 2023 22:59:01 -0500 Subject: [PATCH 110/405] cancel lol --- src/main/java/baritone/Elytra.java | 8 ++++++++ .../command/defaults/ExecutionControlCommands.java | 2 ++ .../baritone/command/defaults/ForceCancelCommand.java | 2 ++ 3 files changed, 12 insertions(+) diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index 082344f6c..f2d28b0f2 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -54,6 +54,14 @@ public class Elytra extends Behavior implements Helper { public int sinceFirework; public BlockPos goal; + public void cancel() { + this.path.clear(); + this.goal = null; + this.playerNear = 0; + this.goingTo = 0; + this.sinceFirework = 0; + } + private void pathfindAroundObstacles() { outer: while (true) { diff --git a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java index 6f6293ccd..66b2d156d 100644 --- a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java +++ b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java @@ -17,6 +17,7 @@ package baritone.command.defaults; +import baritone.Baritone; import baritone.api.IBaritone; import baritone.api.command.Command; import baritone.api.command.argument.IArgConsumer; @@ -180,6 +181,7 @@ public class ExecutionControlCommands { paused[0] = false; } baritone.getPathingBehavior().cancelEverything(); + ((Baritone) baritone).elytra.cancel(); logDirect("ok canceled"); } diff --git a/src/main/java/baritone/command/defaults/ForceCancelCommand.java b/src/main/java/baritone/command/defaults/ForceCancelCommand.java index 513d61bcb..3a54ce69e 100644 --- a/src/main/java/baritone/command/defaults/ForceCancelCommand.java +++ b/src/main/java/baritone/command/defaults/ForceCancelCommand.java @@ -17,6 +17,7 @@ package baritone.command.defaults; +import baritone.Baritone; import baritone.api.IBaritone; import baritone.api.behavior.IPathingBehavior; import baritone.api.command.Command; @@ -39,6 +40,7 @@ public class ForceCancelCommand extends Command { IPathingBehavior pathingBehavior = baritone.getPathingBehavior(); pathingBehavior.cancelEverything(); pathingBehavior.forceCancel(); + ((Baritone) baritone).elytra.cancel(); logDirect("ok force canceled"); } From e01093eb9aa19cff9bed1094f0f9305a82310de3 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 15 Jun 2023 20:59:08 -0700 Subject: [PATCH 111/405] build with pathfinder --- .../baritone/gradle/task/ProguardTask.java | 30 +++++++++++-------- .../baritone/gradle/util/Determinizer.java | 15 ++++++---- scripts/proguard.pro | 2 +- src/main/java/baritone/Elytra.java | 2 ++ 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java b/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java index 1789435f7..1c329ee2c 100644 --- a/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java +++ b/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java @@ -68,17 +68,18 @@ public class ProguardTask extends BaritoneGradleTask { private List requiredLibraries; private File mixin; + private File pathfinder; @TaskAction protected void exec() throws Exception { super.verifyArtifacts(); // "Haha brady why don't you make separate tasks" - processArtifact(); downloadProguard(); extractProguard(); generateConfigs(); acquireDependencies(); + processArtifact(); proguardApi(); proguardStandalone(); cleanup(); @@ -89,7 +90,7 @@ public class ProguardTask extends BaritoneGradleTask { Files.delete(this.artifactUnoptimizedPath); } - Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString(), Optional.empty()); + Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString(), Arrays.asList(pathfinder), false); } private void downloadProguard() throws Exception { @@ -114,8 +115,7 @@ public class ProguardTask extends BaritoneGradleTask { try { path = findJavaPathByGradleConfig(); if (path != null) return path; - } - catch (Exception ex) { + } catch (Exception ex) { System.err.println("Unable to find java by javaCompile options"); ex.printStackTrace(); } @@ -123,8 +123,7 @@ public class ProguardTask extends BaritoneGradleTask { try { path = findJavaByJavaHome(); if (path != null) return path; - } - catch(Exception ex) { + } catch (Exception ex) { System.err.println("Unable to find java by JAVA_HOME"); ex.printStackTrace(); } @@ -132,7 +131,7 @@ public class ProguardTask extends BaritoneGradleTask { path = findJavaByGradleCurrentRuntime(); if (path != null) return path; - + throw new Exception("Unable to find java to determine ProGuard libraryjars. Please specify forkOptions.executable in javaCompile," + " JAVA_HOME environment variable, or make sure to run Gradle with the correct JDK (a v1.8 only)"); } @@ -281,6 +280,9 @@ public class ProguardTask extends BaritoneGradleTask { if (lib.contains("mixin")) { mixin = file; } + if (lib.contains("nether-pathfinder")) { + pathfinder = file; + } Files.copy(file.toPath(), getTemporaryFile("tempLibraries/" + lib + ".jar"), REPLACE_EXISTING); } } @@ -288,6 +290,9 @@ public class ProguardTask extends BaritoneGradleTask { if (mixin == null) { throw new IllegalStateException("Unable to find mixin jar"); } + if (pathfinder == null) { + throw new IllegalStateException("Unable to find pathfinder jar"); + } } // a bunch of epic stuff to get the path to the cached jar @@ -375,14 +380,14 @@ public class ProguardTask extends BaritoneGradleTask { private void proguardApi() throws Exception { runProguard(getTemporaryFile(PROGUARD_API_CONFIG)); - Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString(), Optional.empty()); - Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeApiPath.toString(), Optional.of(mixin)); + Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString(), Arrays.asList(pathfinder), false); + Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeApiPath.toString(), Arrays.asList(pathfinder, mixin), true); } private void proguardStandalone() throws Exception { runProguard(getTemporaryFile(PROGUARD_STANDALONE_CONFIG)); - Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString(), Optional.empty()); - Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeStandalonePath.toString(), Optional.of(mixin)); + Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString(), Arrays.asList(pathfinder), false); + Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeStandalonePath.toString(), Arrays.asList(pathfinder, mixin), true); } private void cleanup() { @@ -409,7 +414,7 @@ public class ProguardTask extends BaritoneGradleTask { Path workingDirectory = getTemporaryFile(""); Path proguardJar = workingDirectory.relativize(getTemporaryFile(PROGUARD_JAR)); config = workingDirectory.relativize(config); - + // Honestly, if you still have spaces in your path at this point, you're SOL. Process p = new ProcessBuilder("java", "-jar", proguardJar.toString(), "@" + config.toString()) @@ -423,6 +428,7 @@ public class ProguardTask extends BaritoneGradleTask { // Halt the current thread until the process is complete, if the exit code isn't 0, throw an exception int exitCode = p.waitFor(); if (exitCode != 0) { + Thread.sleep(1000); throw new IllegalStateException("Proguard exited with code " + exitCode); } } diff --git a/buildSrc/src/main/java/baritone/gradle/util/Determinizer.java b/buildSrc/src/main/java/baritone/gradle/util/Determinizer.java index d9f475a5c..40d17ef03 100644 --- a/buildSrc/src/main/java/baritone/gradle/util/Determinizer.java +++ b/buildSrc/src/main/java/baritone/gradle/util/Determinizer.java @@ -22,7 +22,10 @@ import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; import java.io.*; -import java.util.*; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.JarOutputStream; @@ -36,10 +39,11 @@ import java.util.stream.Collectors; */ public class Determinizer { - public static void determinize(String inputPath, String outputPath, Optional toInclude) throws IOException { + public static void determinize(String inputPath, String outputPath, List toInclude, boolean doForgeReplacementOfMetaInf) throws IOException { System.out.println("Running Determinizer"); System.out.println(" Input path: " + inputPath); System.out.println(" Output path: " + outputPath); + System.out.println(" Shade: " + toInclude); try ( JarFile jarFile = new JarFile(new File(inputPath)); @@ -63,7 +67,7 @@ public class Determinizer { if (entry.getName().endsWith(".refmap.json")) { JsonObject object = new JsonParser().parse(new InputStreamReader(jarFile.getInputStream(entry))).getAsJsonObject(); jos.write(writeSorted(object).getBytes()); - } else if (entry.getName().equals("META-INF/MANIFEST.MF") && toInclude.isPresent()) { // only replace for forge jar + } else if (entry.getName().equals("META-INF/MANIFEST.MF") && doForgeReplacementOfMetaInf) { // only replace for forge jar ByteArrayOutputStream cancer = new ByteArrayOutputStream(); copy(jarFile.getInputStream(entry), cancer); String manifest = new String(cancer.toByteArray()); @@ -76,8 +80,8 @@ public class Determinizer { copy(jarFile.getInputStream(entry), jos); } } - if (toInclude.isPresent()) { - try (JarFile mixin = new JarFile(toInclude.get())) { + for (File file : toInclude) { + try (JarFile mixin = new JarFile(file)) { for (JarEntry entry : mixin.stream().sorted(Comparator.comparing(JarEntry::getName)).collect(Collectors.toList())) { if (entry.getName().startsWith("META-INF") && !entry.getName().startsWith("META-INF/services")) { continue; @@ -89,6 +93,7 @@ public class Determinizer { } jos.finish(); } + System.out.println("Done with determinizer"); } private static void copy(InputStream is, OutputStream os) throws IOException { diff --git a/scripts/proguard.pro b/scripts/proguard.pro index cc3130081..858494778 100644 --- a/scripts/proguard.pro +++ b/scripts/proguard.pro @@ -94,7 +94,7 @@ -libraryjars 'tempLibraries/mixin-0.7.11-SNAPSHOT.jar' -libraryjars 'tempLibraries/launchwrapper-1.11.jar' # TODO why does only 1.11.jar exist? - +-libraryjars 'tempLibraries/nether-pathfinder-.jar' # Keep - Applications. Keep all application classes, along with their 'main' diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index f2d28b0f2..caa819fb4 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -45,6 +45,8 @@ public class Elytra extends Behavior implements Helper { public List path = new ArrayList<>(); public void path(BlockPos destination) { + playerNear = 0; + goingTo = 0; path = Arrays.stream(NetherPathfinder.pathFind(146008555100680L, false, false, ctx.playerFeet().x, ctx.playerFeet().y, ctx.playerFeet().z, destination.getX(), destination.getY(), destination.getZ())).mapToObj(BlockPos::fromLong).map(BetterBlockPos::new).collect(Collectors.toList()); removeBacktracks(); } From ef4cdfd646eda11108b1b408c0987b70b36f1802 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Fri, 16 Jun 2023 19:22:37 +0200 Subject: [PATCH 112/405] Fix render bug caused by color bug fix --- src/main/java/baritone/utils/GuiClick.java | 2 +- src/main/java/baritone/utils/IRenderer.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/utils/GuiClick.java b/src/main/java/baritone/utils/GuiClick.java index 1716d74b6..72d436928 100644 --- a/src/main/java/baritone/utils/GuiClick.java +++ b/src/main/java/baritone/utils/GuiClick.java @@ -119,7 +119,7 @@ public class GuiClick extends GuiScreen { if (clickStart != null && !clickStart.equals(currentMouseOver)) { GlStateManager.enableBlend(); GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); - GlStateManager.color(Color.RED.getColorComponents(null)[0], Color.RED.getColorComponents(null)[1], Color.RED.getColorComponents(null)[2], 0.4F); + IRenderer.glColor(Color.RED, 0.4F); GlStateManager.glLineWidth(Baritone.settings().pathRenderLineWidthPixels.value); GlStateManager.disableTexture2D(); GlStateManager.depthMask(false); diff --git a/src/main/java/baritone/utils/IRenderer.java b/src/main/java/baritone/utils/IRenderer.java index 2134bcb99..680d7e380 100644 --- a/src/main/java/baritone/utils/IRenderer.java +++ b/src/main/java/baritone/utils/IRenderer.java @@ -116,7 +116,7 @@ public interface IRenderer { } static void drawAABB(AxisAlignedBB aabb) { - buffer.begin(GL_LINES, DefaultVertexFormats.POSITION); + buffer.begin(GL_LINES, DefaultVertexFormats.POSITION_COLOR); emitAABB(aabb); tessellator.draw(); } From f1bf1e8663724b3cb9dc0d40ce2b06807b2ff2aa Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Sat, 17 Jun 2023 00:36:35 +0200 Subject: [PATCH 113/405] Use IRenderer setup methods --- src/main/java/baritone/utils/GuiClick.java | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/main/java/baritone/utils/GuiClick.java b/src/main/java/baritone/utils/GuiClick.java index 72d436928..c378aca53 100644 --- a/src/main/java/baritone/utils/GuiClick.java +++ b/src/main/java/baritone/utils/GuiClick.java @@ -117,21 +117,11 @@ public class GuiClick extends GuiScreen { // drawSingleSelectionBox WHEN? PathRenderer.drawManySelectionBoxes(e, Collections.singletonList(currentMouseOver), Color.CYAN); if (clickStart != null && !clickStart.equals(currentMouseOver)) { - GlStateManager.enableBlend(); - GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); - IRenderer.glColor(Color.RED, 0.4F); - GlStateManager.glLineWidth(Baritone.settings().pathRenderLineWidthPixels.value); - GlStateManager.disableTexture2D(); - GlStateManager.depthMask(false); - GlStateManager.disableDepth(); + IRenderer.startLines(Color.RED, Baritone.settings().pathRenderLineWidthPixels.value, true); BetterBlockPos a = new BetterBlockPos(currentMouseOver); BetterBlockPos b = new BetterBlockPos(clickStart); - IRenderer.drawAABB(new AxisAlignedBB(Math.min(a.x, b.x), Math.min(a.y, b.y), Math.min(a.z, b.z), Math.max(a.x, b.x) + 1, Math.max(a.y, b.y) + 1, Math.max(a.z, b.z) + 1)); - GlStateManager.enableDepth(); - - GlStateManager.depthMask(true); - GlStateManager.enableTexture2D(); - GlStateManager.disableBlend(); + IRenderer.emitAABB(new AxisAlignedBB(Math.min(a.x, b.x), Math.min(a.y, b.y), Math.min(a.z, b.z), Math.max(a.x, b.x) + 1, Math.max(a.y, b.y) + 1, Math.max(a.z, b.z) + 1)); + IRenderer.endLines(true); } } } From e00e0032b49ac2f0c29f3cf3f6e70ec1ceaccd01 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Sat, 17 Jun 2023 01:40:19 +0200 Subject: [PATCH 114/405] Actually use stack hashes --- .../api/utils/BlockOptionalMetaLookup.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/api/java/baritone/api/utils/BlockOptionalMetaLookup.java b/src/api/java/baritone/api/utils/BlockOptionalMetaLookup.java index 6d236e90e..6479854bc 100644 --- a/src/api/java/baritone/api/utils/BlockOptionalMetaLookup.java +++ b/src/api/java/baritone/api/utils/BlockOptionalMetaLookup.java @@ -17,6 +17,7 @@ package baritone.api.utils; +import baritone.api.utils.accessor.IItemStack; import com.google.common.collect.ImmutableSet; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; @@ -29,8 +30,9 @@ import java.util.Set; import java.util.stream.Stream; public class BlockOptionalMetaLookup { - private final Set blockSet; - private final Set blockStateSet; + private final ImmutableSet blockSet; + private final ImmutableSet blockStateSet; + private final ImmutableSet stackHashes; private final BlockOptionalMeta[] boms; public BlockOptionalMetaLookup(BlockOptionalMeta... boms) { @@ -45,6 +47,7 @@ public class BlockOptionalMetaLookup { } this.blockSet = ImmutableSet.copyOf(blocks); this.blockStateSet = ImmutableSet.copyOf(blockStates); + this.stackHashes = ImmutableSet.copyOf(stacks); } public BlockOptionalMetaLookup(Block... blocks) { @@ -75,13 +78,9 @@ public class BlockOptionalMetaLookup { } public boolean has(ItemStack stack) { - for (BlockOptionalMeta bom : boms) { - if (bom.matches(stack)) { - return true; - } - } - - return false; + int hash = ((IItemStack) (Object) stack).getBaritoneHash(); + return stackHashes.contains(hash) + || stackHashes.contains(hash - stack.getItemDamage()); } public List blocks() { From 8c124163483755aa2ad350e2822558077a51590d Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 16 Jun 2023 18:59:57 -0500 Subject: [PATCH 115/405] Use new nether-pathfinder API Doesn't stitch segments, just partially functional --- build.gradle | 9 +++- src/main/java/baritone/Elytra.java | 44 +++++++++++++++++-- .../command/defaults/ElytraCommand.java | 2 +- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index 7909911be..8e952df73 100755 --- a/build.gradle +++ b/build.gradle @@ -88,6 +88,11 @@ repositories { name = 'impactdevelopment-repo' url = 'https://impactdevelopment.github.io/maven/' } + + maven { + name = 'babbaj-repo' + url = 'https://babbaj.github.io/maven/' + } } dependencies { @@ -100,9 +105,9 @@ dependencies { exclude module: 'commons-io' exclude module: 'log4j-core' } - runtime launchCompile('dev.babbaj:nether-pathfinder:1.3') + runtime launchCompile('dev.babbaj:nether-pathfinder:0.2') testImplementation 'junit:junit:4.12' - implementation 'dev.babbaj:nether-pathfinder:1.3' + implementation 'dev.babbaj:nether-pathfinder:0.2' } mixin { diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index caa819fb4..69fee5450 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -26,6 +26,7 @@ import baritone.behavior.Behavior; import baritone.utils.BlockStateInterface; import com.mojang.realmsclient.util.Pair; import dev.babbaj.pathfinder.NetherPathfinder; +import dev.babbaj.pathfinder.PathSegment; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.item.EntityFireworkRocket; @@ -44,13 +45,48 @@ public class Elytra extends Behavior implements Helper { public List path = new ArrayList<>(); - public void path(BlockPos destination) { - playerNear = 0; - goingTo = 0; - path = Arrays.stream(NetherPathfinder.pathFind(146008555100680L, false, false, ctx.playerFeet().x, ctx.playerFeet().y, ctx.playerFeet().z, destination.getX(), destination.getY(), destination.getZ())).mapToObj(BlockPos::fromLong).map(BetterBlockPos::new).collect(Collectors.toList()); + private long context; + private Long seed; + + public void path(long seed, BlockPos destination) { + this.setupContext(seed); + + this.playerNear = 0; + this.goingTo = 0; + + final PathSegment segment = NetherPathfinder.pathFind( + this.context, + ctx.playerFeet().x, ctx.playerFeet().y, ctx.playerFeet().z, + destination.getX(), destination.getY(), destination.getZ() + ); + + this.path = Arrays.stream(segment.packed) + .mapToObj(BlockPos::fromLong) + .map(BetterBlockPos::new) + .collect(Collectors.toList()); + + if (!segment.finished) { + logDirect("segment not finished. path incomplete"); + } + removeBacktracks(); } + private void setupContext(long seed) { + if (!Objects.equals(this.seed, seed)) { + this.freeContext(); + this.context = NetherPathfinder.newContext(seed); + } + this.seed = seed; + } + + private void freeContext() { + if (this.context != 0) { + NetherPathfinder.freeContext(this.context); + } + this.context = 0; + } + public int playerNear; public int goingTo; public int sinceFirework; diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index 2d2e3f0ee..99ddaa8e4 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -41,7 +41,7 @@ public class ElytraCommand extends Command { ICustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess(); args.requireMax(0); GoalXZ goal = (GoalXZ) customGoalProcess.getGoal(); - ((Baritone) baritone).elytra.path(new BlockPos(goal.getX(), 64, goal.getZ())); + ((Baritone) baritone).elytra.path(146008555100680L, new BlockPos(goal.getX(), 64, goal.getZ())); } @Override From 53a0069704b115657bfd470940d443544c61ca03 Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 16 Jun 2023 19:54:37 -0500 Subject: [PATCH 116/405] Remove Java pathfinder in preparation for `insertChunkData` --- src/main/java/baritone/Elytra.java | 166 ++++------------------------- 1 file changed, 18 insertions(+), 148 deletions(-) diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index 69fee5450..77a09f369 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -48,6 +48,16 @@ public class Elytra extends Behavior implements Helper { private long context; private Long seed; + public int playerNear; + public int goingTo; + public int sinceFirework; + public BlockPos goal; + public List> lines = new ArrayList<>(); + + protected Elytra(Baritone baritone) { + super(baritone); + } + public void path(long seed, BlockPos destination) { this.setupContext(seed); @@ -87,11 +97,6 @@ public class Elytra extends Behavior implements Helper { this.context = 0; } - public int playerNear; - public int goingTo; - public int sinceFirework; - public BlockPos goal; - public void cancel() { this.path.clear(); this.goal = null; @@ -100,147 +105,10 @@ public class Elytra extends Behavior implements Helper { this.sinceFirework = 0; } - private void pathfindAroundObstacles() { - outer: - while (true) { - int rangeStartIncl = playerNear; - int rangeEndExcl = playerNear; - while (rangeEndExcl < path.size() && ctx.world().isBlockLoaded(path.get(rangeEndExcl), false)) { - rangeEndExcl++; - } - if (rangeStartIncl >= rangeEndExcl) { - // not loaded yet? - return; - } - if (!passable(ctx.world().getBlockState(path.get(rangeStartIncl)))) { - // we're in a wall - return; // previous iterations of this function SHOULD have fixed this by now :rage_cat: - } - for (int i = rangeStartIncl; i < rangeEndExcl - 1; i++) { - if (!clearView(pathAt(i), pathAt(i + 1))) { - // obstacle. where do we return to pathing? - // find the next valid segment - for (int j = i + 1; j < rangeEndExcl - 1; j++) { - if (clearView(pathAt(j), pathAt(j + 1))) { - // found it - // path from i to j - List newPath = simplePathfind(path.get(i), path.get(j)); - if (newPath == null) { - logDirect("no path"); - return; - } - path.subList(i + 1, j).clear(); - for (int k = newPath.size() - 1; k >= 0; k--) { - path.add(i + 1, newPath.get(k)); - } - logDirect("replaced path starting at " + path.get(i)); - removeBacktracks(); - break outer; // eventually "continue outer" - } - } - } - } - break; - } - } - - private int manhattanDist(BlockPos start, BlockPos dest) { - return Math.abs(start.getX() - dest.getX()) + Math.abs(start.getY() - dest.getY()) + Math.abs(start.getZ() - dest.getZ()); - } - - private class SearchNode { - BetterBlockPos pos; - int dist; - int heuristic; - SearchNode prev; - boolean canceled; - - public SearchNode(BetterBlockPos pos, int dist, int heuristic, SearchNode prev) { - this.pos = pos; - this.dist = dist; - this.heuristic = heuristic; - this.prev = prev; - } - } - - private List simplePathfind(BetterBlockPos start, BetterBlockPos dest) { - Map map = new HashMap<>(); - PriorityQueue queue = new PriorityQueue<>(Comparator.comparingInt(node -> node.dist + node.heuristic)); - SearchNode origin = new SearchNode(start, 0, manhattanDist(start, dest) * 10, null); - map.put(start, origin); - queue.add(origin); - int count = 0; - while (!queue.isEmpty()) { - if (count++ > 10000) { - logDirect("oopsie"); - return null; - } - SearchNode node = queue.poll(); - if (node.canceled) { - continue; - } - if (node.pos.equals(dest)) { - List path = new ArrayList<>(); - while (node != null) { - path.add(node.pos); - node = node.prev; - } - Collections.reverse(path); - return simplify(path); - } - BetterBlockPos[] adjs = new BetterBlockPos[]{node.pos.up(), node.pos.down(), node.pos.north(), node.pos.south(), node.pos.east(), node.pos.west()}; - boolean nearAWall = false; - for (BetterBlockPos adj : adjs) { - if (!passable(ctx.world().getBlockState(adj))) { - nearAWall = true; - break; - } - } - for (BetterBlockPos adj : adjs) { - if (!passable(ctx.world().getBlockState(adj))) { - continue; - } - int cost = node.dist + (nearAWall ? 11 : 10); - if (map.containsKey(adj)) { - if (map.get(adj).dist <= cost) { - continue; - } - map.get(adj).canceled = true; - } - map.put(adj, new SearchNode(adj, cost, manhattanDist(adj, dest) * 10, node)); - queue.add(map.get(adj)); - } - } - return null; - } - - private List simplify(List path) { - List simplified = new ArrayList<>(path); - for (int i = 0; i < simplified.size() - 2; i++) { - BlockPos dir = simplified.get(i + 1).subtract(simplified.get(i)); - while (i + 2 < simplified.size()) { - if (simplified.get(i + 2).subtract(simplified.get(i + 1)).equals(dir)) { - simplified.remove(i + 1); - } else { - break; - } - } - } - return simplified; - } - private Vec3d pathAt(int i) { return new Vec3d(path.get(i).x + 0.5, path.get(i).y + 0.5, path.get(i).z + 0.5); } - - public List> lines = new ArrayList<>(); - - protected Elytra(Baritone baritone) { - super(baritone); - } - - @Override public void onTick(TickEvent event) { if (event.getType() == TickEvent.Type.OUT) { @@ -252,7 +120,6 @@ public class Elytra extends Behavior implements Helper { fixNearPlayer(); baritone.getInputOverrideHandler().clearAllKeys(); lines.clear(); - pathfindAroundObstacles(); if (ctx.player().isElytraFlying()) { if (ctx.player().collidedHorizontally) { logDirect("hbonk"); @@ -323,7 +190,9 @@ public class Elytra extends Behavior implements Helper { } private boolean firework() { - return ctx.world().loadedEntityList.stream().anyMatch(x -> (x instanceof EntityFireworkRocket) && ((EntityFireworkRocket) x).isAttachedToEntity()); + // TODO: Validate that the EntityFireworkRocket is attached to ctx.player() + return ctx.world().loadedEntityList.stream() + .anyMatch(x -> (x instanceof EntityFireworkRocket) && ((EntityFireworkRocket) x).isAttachedToEntity()); } private boolean isClear(Vec3d start, Vec3d dest) { @@ -390,7 +259,7 @@ public class Elytra extends Behavior implements Helper { return state.getMaterial() == Material.AIR; } - public static Vec3d step(Vec3d motion, float rotationPitch, float rotationYaw, boolean firework) { + private static Vec3d step(Vec3d motion, float rotationPitch, float rotationYaw, boolean firework) { double motionX = motion.x; double motionY = motion.y; double motionZ = motion.z; @@ -438,7 +307,7 @@ public class Elytra extends Behavior implements Helper { return new Vec3d(motionX, motionY, motionZ); } - public void fixNearPlayer() { + private void fixNearPlayer() { BetterBlockPos pos = ctx.playerFeet(); for (int i = playerNear; i >= Math.max(playerNear - 1000, 0); i -= 10) { if (path.get(i).distanceSq(pos) < path.get(playerNear).distanceSq(pos)) { @@ -463,7 +332,7 @@ public class Elytra extends Behavior implements Helper { //System.out.println(playerNear); } - public void removeBacktracks() { + private void removeBacktracks() { Map positionFirstSeen = new HashMap<>(); for (int i = 0; i < path.size(); i++) { BetterBlockPos pos = path.get(i); @@ -479,7 +348,8 @@ public class Elytra extends Behavior implements Helper { } } - public RayTraceResult rayTraceBlocks(Vec3d start, Vec3d end) { + // TODO: Use the optimized version from builder-2 + private RayTraceResult rayTraceBlocks(Vec3d start, Vec3d end) { int x1 = MathHelper.floor(end.x); int y1 = MathHelper.floor(end.y); int z1 = MathHelper.floor(end.z); From 5b39eb5041e60f0aad6cf6284836ab78954864ae Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 16 Jun 2023 20:38:29 -0500 Subject: [PATCH 117/405] clean up --- src/main/java/baritone/Elytra.java | 139 +++++++++++++++-------------- 1 file changed, 74 insertions(+), 65 deletions(-) diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index 77a09f369..5b748403e 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -43,16 +43,18 @@ import java.util.stream.Collectors; public class Elytra extends Behavior implements Helper { + // Used exclusively for PathRenderer + public List> lines = new ArrayList<>(); + public BlockPos goal; + public List path = new ArrayList<>(); private long context; private Long seed; public int playerNear; - public int goingTo; - public int sinceFirework; - public BlockPos goal; - public List> lines = new ArrayList<>(); + private int goingTo; + private int sinceFirework; protected Elytra(Baritone baritone) { super(baritone); @@ -117,79 +119,83 @@ public class Elytra extends Behavior implements Helper { if (path.isEmpty()) { return; } + fixNearPlayer(); - baritone.getInputOverrideHandler().clearAllKeys(); + baritone.getInputOverrideHandler().clearAllKeys(); // FIXME: This breaks the regular path-finder lines.clear(); - if (ctx.player().isElytraFlying()) { - if (ctx.player().collidedHorizontally) { - logDirect("hbonk"); - } - if (ctx.player().collidedVertically) { - logDirect("vbonk"); - } - Vec3d start = ctx.playerFeetAsVec(); - boolean firework = firework(); - sinceFirework++; - if (!firework - && sinceFirework > 10 - && (Baritone.settings().wasteFireworks.value || ctx.player().posY < path.get(goingTo).y + 5) // don't firework if trying to descend - && (ctx.player().posY < path.get(goingTo).y - 5 || ctx.playerFeetAsVec().distanceTo(new Vec3d(path.get(goingTo).x + 0.5, ctx.player().posY, path.get(goingTo).z + 0.5)) > 5) // UGH!!!!!!! - && new Vec3d(ctx.player().motionX, ctx.player().posY < path.get(goingTo).y ? Math.max(0, ctx.player().motionY) : ctx.player().motionY, ctx.player().motionZ).length() < Baritone.settings().elytraFireworkSpeed.value // ignore y component if we are BOTH below where we want to be AND descending - ) { - logDirect("firework"); - ctx.playerController().processRightClick(ctx.player(), ctx.world(), EnumHand.MAIN_HAND); - sinceFirework = 0; - } - long t = System.currentTimeMillis(); - for (int relaxation = 0; relaxation < 3; relaxation++) { // try for a strict solution first, then relax more and more (if we're in a corner or near some blocks, it will have to relax its constraints a bit) - int[] heights = firework ? new int[]{20, 10, 5, 0} : new int[]{0}; // attempt to gain height, if we can, so as not to waste the boost - boolean requireClear = relaxation == 0; - int steps = relaxation < 2 ? firework ? 5 : Baritone.settings().elytraSimulationTicks.value : 3; - int lookahead = relaxation == 0 ? 2 : 3; // ideally this would be expressed as a distance in blocks, rather than a number of voxel steps - //int minStep = Math.max(0, playerNear - relaxation); - int minStep = playerNear; - for (int i = Math.min(playerNear + 20, path.size() - 1); i >= minStep; i--) { - for (int dy : heights) { - Vec3d dest = pathAt(i).add(0, dy, 0); - if (dy != 0) { - if (i + lookahead >= path.size()) { + + if (!ctx.player().isElytraFlying()) { + return; + } + if (ctx.player().collidedHorizontally) { + logDirect("hbonk"); + } + if (ctx.player().collidedVertically) { + logDirect("vbonk"); + } + + Vec3d start = ctx.playerFeetAsVec(); + boolean firework = isFireworkActive(); + sinceFirework++; + if (!firework + && sinceFirework > 10 + && (Baritone.settings().wasteFireworks.value || ctx.player().posY < path.get(goingTo).y + 5) // don't firework if trying to descend + && (ctx.player().posY < path.get(goingTo).y - 5 || start.distanceTo(new Vec3d(path.get(goingTo).x + 0.5, ctx.player().posY, path.get(goingTo).z + 0.5)) > 5) // UGH!!!!!!! + && new Vec3d(ctx.player().motionX, ctx.player().posY < path.get(goingTo).y ? Math.max(0, ctx.player().motionY) : ctx.player().motionY, ctx.player().motionZ).length() < Baritone.settings().elytraFireworkSpeed.value // ignore y component if we are BOTH below where we want to be AND descending + ) { + logDirect("firework"); + ctx.playerController().processRightClick(ctx.player(), ctx.world(), EnumHand.MAIN_HAND); + sinceFirework = 0; + } + final long t = System.currentTimeMillis(); + for (int relaxation = 0; relaxation < 3; relaxation++) { // try for a strict solution first, then relax more and more (if we're in a corner or near some blocks, it will have to relax its constraints a bit) + int[] heights = firework ? new int[]{20, 10, 5, 0} : new int[]{0}; // attempt to gain height, if we can, so as not to waste the boost + boolean requireClear = relaxation == 0; + int steps = relaxation < 2 ? firework ? 5 : Baritone.settings().elytraSimulationTicks.value : 3; + int lookahead = relaxation == 0 ? 2 : 3; // ideally this would be expressed as a distance in blocks, rather than a number of voxel steps + //int minStep = Math.max(0, playerNear - relaxation); + int minStep = playerNear; + for (int i = Math.min(playerNear + 20, path.size() - 1); i >= minStep; i--) { + for (int dy : heights) { + Vec3d dest = pathAt(i).add(0, dy, 0); + if (dy != 0) { + if (i + lookahead >= path.size()) { + continue; + } + if (start.distanceTo(dest) < 40) { + if (!clearView(dest, pathAt(i + lookahead).add(0, dy, 0)) || !clearView(dest, pathAt(i + lookahead))) { + // aka: don't go upwards if doing so would prevent us from being able to see the next position **OR** the modified next position continue; } - if (start.distanceTo(dest) < 40) { - if (!clearView(dest, pathAt(i + lookahead).add(0, dy, 0)) || !clearView(dest, pathAt(i + lookahead))) { - // aka: don't go upwards if doing so would prevent us from being able to see the next position **OR** the modified next position - continue; - } - } else { - // but if it's far away, allow gaining altitude if we could lose it again by the time we get there - if (!clearView(dest, pathAt(i))) { - continue; - } - } - } - if (requireClear ? isClear(start, dest) : clearView(start, dest)) { - Rotation rot = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()); - long a = System.currentTimeMillis(); - Float pitch = solvePitch(dest.subtract(start), steps, relaxation == 2); - if (pitch == null) { - baritone.getLookBehavior().updateTarget(new Rotation(rot.getYaw(), ctx.playerRotations().getPitch()), false); + } else { + // but if it's far away, allow gaining altitude if we could lose it again by the time we get there + if (!clearView(dest, pathAt(i))) { continue; } - long b = System.currentTimeMillis(); - System.out.println("Solved pitch in " + (b - a) + " total time " + (b - t)); - goingTo = i; - goal = path.get(i).add(0, dy, 0); - baritone.getLookBehavior().updateTarget(new Rotation(rot.getYaw(), pitch), false); - return; } } + if (requireClear ? isClear(start, dest) : clearView(start, dest)) { + Rotation rot = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()); + long a = System.currentTimeMillis(); + Float pitch = solvePitch(dest.subtract(start), steps, relaxation == 2); + if (pitch == null) { + baritone.getLookBehavior().updateTarget(new Rotation(rot.getYaw(), ctx.playerRotations().getPitch()), false); + continue; + } + long b = System.currentTimeMillis(); + System.out.println("Solved pitch in " + (b - a) + " total time " + (b - t)); + goingTo = i; + goal = path.get(i).add(0, dy, 0); + baritone.getLookBehavior().updateTarget(new Rotation(rot.getYaw(), pitch), false); + return; + } } } - logDirect("no pitch solution, probably gonna crash in a few ticks LOL!!!"); } + logDirect("no pitch solution, probably gonna crash in a few ticks LOL!!!"); } - private boolean firework() { + private boolean isFireworkActive() { // TODO: Validate that the EntityFireworkRocket is attached to ctx.player() return ctx.world().loadedEntityList.stream() .anyMatch(x -> (x instanceof EntityFireworkRocket) && ((EntityFireworkRocket) x).isAttachedToEntity()); @@ -218,7 +224,7 @@ public class Elytra extends Behavior implements Helper { goalDirection = goalDirection.normalize(); Rotation good = RotationUtils.calcRotationFromVec3d(new Vec3d(0, 0, 0), goalDirection, ctx.playerRotations()); // lazy lol - boolean firework = firework(); + boolean firework = isFireworkActive(); Float bestPitch = null; double bestDot = Double.NEGATIVE_INFINITY; Vec3d motion = new Vec3d(ctx.player().motionX, ctx.player().motionY, ctx.player().motionZ); @@ -268,11 +274,14 @@ public class Elytra extends Behavior implements Helper { float pitchBase = -MathHelper.cos(-rotationPitch * 0.017453292F); float pitchHeight = MathHelper.sin(-rotationPitch * 0.017453292F); Vec3d lookDirection = new Vec3d(flatX * pitchBase, pitchHeight, flatZ * pitchBase); + if (firework) { + // See EntityFireworkRocket motionX += lookDirection.x * 0.1 + (lookDirection.x * 1.5 - motionX) * 0.5; motionY += lookDirection.y * 0.1 + (lookDirection.y * 1.5 - motionY) * 0.5; motionZ += lookDirection.z * 0.1 + (lookDirection.z * 1.5 - motionZ) * 0.5; } + float pitchRadians = rotationPitch * 0.017453292F; double pitchBase2 = Math.sqrt(lookDirection.x * lookDirection.x + lookDirection.z * lookDirection.z); double flatMotion = Math.sqrt(motionX * motionX + motionZ * motionZ); From 800cb2e747a487fb7cb035764fc7cffb308dc562 Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 16 Jun 2023 20:53:53 -0500 Subject: [PATCH 118/405] Replace sublist troll in PathRenderer with `visiblePath` --- src/main/java/baritone/Elytra.java | 49 ++++++++++++------- .../java/baritone/utils/PathRenderer.java | 2 +- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index 5b748403e..e8e83c5b7 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -44,20 +44,25 @@ import java.util.stream.Collectors; public class Elytra extends Behavior implements Helper { // Used exclusively for PathRenderer - public List> lines = new ArrayList<>(); + public List> lines; public BlockPos goal; + public List visiblePath; - public List path = new ArrayList<>(); - + // NetherPathfinder stuff private long context; private Long seed; + // yay! + private List path; public int playerNear; private int goingTo; private int sinceFirework; protected Elytra(Baritone baritone) { super(baritone); + this.lines = new ArrayList<>(); + this.visiblePath = Collections.emptyList(); + this.path = new ArrayList<>(); } public void path(long seed, BlockPos destination) { @@ -100,6 +105,7 @@ public class Elytra extends Behavior implements Helper { } public void cancel() { + this.visiblePath = Collections.emptyList(); this.path.clear(); this.goal = null; this.playerNear = 0; @@ -120,7 +126,12 @@ public class Elytra extends Behavior implements Helper { return; } - fixNearPlayer(); + playerNear = fixNearPlayer(playerNear); + visiblePath = path.subList( + Math.max(playerNear - 30, 0), + Math.min(playerNear + 30, path.size()) + ); + baritone.getInputOverrideHandler().clearAllKeys(); // FIXME: This breaks the regular path-finder lines.clear(); @@ -316,29 +327,29 @@ public class Elytra extends Behavior implements Helper { return new Vec3d(motionX, motionY, motionZ); } - private void fixNearPlayer() { - BetterBlockPos pos = ctx.playerFeet(); - for (int i = playerNear; i >= Math.max(playerNear - 1000, 0); i -= 10) { - if (path.get(i).distanceSq(pos) < path.get(playerNear).distanceSq(pos)) { - playerNear = i; // intentional: this changes the bound of the loop + private int fixNearPlayer(int index) { + final BetterBlockPos pos = ctx.playerFeet(); + for (int i = index; i >= Math.max(index - 1000, 0); i -= 10) { + if (path.get(i).distanceSq(pos) < path.get(index).distanceSq(pos)) { + index = i; // intentional: this changes the bound of the loop } } - for (int i = playerNear; i < Math.min(playerNear + 1000, path.size()); i += 10) { - if (path.get(i).distanceSq(pos) < path.get(playerNear).distanceSq(pos)) { - playerNear = i; // intentional: this changes the bound of the loop + for (int i = index; i < Math.min(index + 1000, path.size()); i += 10) { + if (path.get(i).distanceSq(pos) < path.get(index).distanceSq(pos)) { + index = i; // intentional: this changes the bound of the loop } } - for (int i = playerNear; i >= Math.max(playerNear - 50, 0); i--) { - if (path.get(i).distanceSq(pos) < path.get(playerNear).distanceSq(pos)) { - playerNear = i; // intentional: this changes the bound of the loop + for (int i = index; i >= Math.max(index - 50, 0); i--) { + if (path.get(i).distanceSq(pos) < path.get(index).distanceSq(pos)) { + index = i; // intentional: this changes the bound of the loop } } - for (int i = playerNear; i < Math.min(playerNear + 50, path.size()); i++) { - if (path.get(i).distanceSq(pos) < path.get(playerNear).distanceSq(pos)) { - playerNear = i; // intentional: this changes the bound of the loop + for (int i = index; i < Math.min(index + 50, path.size()); i++) { + if (path.get(i).distanceSq(pos) < path.get(index).distanceSq(pos)) { + index = i; // intentional: this changes the bound of the loop } } - //System.out.println(playerNear); + return index; } private void removeBacktracks() { diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index 15ae73696..934375c4c 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -105,7 +105,7 @@ public final class PathRenderer implements IRenderer { drawPath(next.getPath().positions(), 0, settings.colorNextPath.value, settings.fadePath.value, 10, 20); } - drawPath(behavior.baritone.elytra.path.subList(Math.max(behavior.baritone.elytra.playerNear - 30, 0), Math.min(behavior.baritone.elytra.playerNear + 30, behavior.baritone.elytra.path.size())), 0, Color.RED, false, 0, 0); + drawPath(behavior.baritone.elytra.visiblePath, 0, Color.RED, false, 0, 0); if (behavior.baritone.elytra.goal != null) { drawGoal(renderView, new GoalBlock(behavior.baritone.elytra.goal), partialTicks, Color.GREEN); } From cb7c2d71710caa43a352675e566b43374eb2ed55 Mon Sep 17 00:00:00 2001 From: 0x22 <0x22@futureclient.net> Date: Fri, 16 Jun 2023 21:59:06 -0400 Subject: [PATCH 119/405] 1.12.2 build script overhaul. - Updated to ForgeGradle 4.0, MixinGradle 0.7 and Gradle 6.9.4 - Added a hack to run the game on arm64 on Mac OS X natively. --- .gitignore | 2 + build.gradle | 138 +++++++---- buildSrc/build.gradle | 4 +- .../baritone/gradle/task/ProguardTask.java | 228 +++++++----------- .../baritone/gradle/util/MappingType.java | 29 --- .../baritone/gradle/util/ReobfWrapper.java | 63 ----- gradle/wrapper/gradle-wrapper.jar | Bin 54706 -> 59536 bytes gradle/wrapper/gradle-wrapper.properties | 3 +- gradlew | 55 +++-- gradlew.bat | 43 ++-- hacks.gradle | 161 +++++++++++++ scripts/proguard.pro | 2 +- 12 files changed, 406 insertions(+), 322 deletions(-) delete mode 100644 buildSrc/src/main/java/baritone/gradle/util/MappingType.java delete mode 100644 buildSrc/src/main/java/baritone/gradle/util/ReobfWrapper.java create mode 100644 hacks.gradle diff --git a/.gitignore b/.gitignore index d4c25ad90..5b420a0e4 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,5 @@ baritone_Client.launch .vscode/launch.json +libs/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar +libs/java-objc-bridge-1.1.jar diff --git a/build.gradle b/build.gradle index 8e952df73..70f8a7adf 100755 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,7 @@ buildscript { repositories { maven { name = 'forge' - url = 'http://files.minecraftforge.net/maven' + url = 'https://files.minecraftforge.net/maven' } maven { name = 'SpongePowered' @@ -32,18 +32,19 @@ buildscript { } dependencies { - classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT' - classpath 'org.spongepowered:mixingradle:0.6-SNAPSHOT' + classpath 'net.minecraftforge.gradle:ForgeGradle:4.+' // TODO: 5.+. `doHackyStuff` relies on 4.x internals. + classpath 'org.spongepowered:mixingradle:0.7-SNAPSHOT' } } - import baritone.gradle.task.CreateDistTask import baritone.gradle.task.ProguardTask apply plugin: 'java' -apply plugin: 'maven' -apply plugin: 'net.minecraftforge.gradle.tweaker-client' +apply plugin: 'maven-publish' +apply plugin: 'net.minecraftforge.gradle' +apply from: 'hacks.gradle' +ext.doHackyStuff(Class.forName('net.minecraftforge.gradle.mcp.task.GenerateSRG')) // TODO: fg 5.0 - `ext.doHackyStuff(Class.forName('net.minecraftforge.gradle.mcp.tasks.GenerateSRG'))` apply plugin: 'org.spongepowered.mixin' sourceCompatibility = targetCompatibility = '1.8' @@ -53,8 +54,19 @@ compileJava { } sourceSets { + api { + compileClasspath += main.compileClasspath + } + main { + compileClasspath += api.output + } + test { + compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output + runtimeClasspath += main.compileClasspath + main.runtimeClasspath + main.output + } launch { compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output + runtimeClasspath += main.compileClasspath + main.runtimeClasspath + main.output } schematica_api { @@ -67,13 +79,26 @@ sourceSets { } minecraft { - version = '1.12.2' - mappings = 'stable_39' - tweakClass = 'baritone.launch.BaritoneTweaker' - runDir = 'run' + mappings channel: 'stable', version: '39-1.12' + runs { + def nativesOutput = extractNatives.output // TODO: fg 5.0 - `def nativesOutput = extractNatives.output.get()` + println("[Baritoe] Detected natives: ${nativesOutput}") + client { + workingDirectory project.file('run') + source sourceSets.launch - // The sources jar should use SRG names not MCP to ensure compatibility with all mappings - makeObfSourceJar = true + main 'net.minecraft.launchwrapper.Launch' + + args '--gameDir', '.' + args '--version', '1.12.2' + args '--assetsDir', downloadAssets.output + args '--assetIndex', '{asset_index}' + args '--accessToken', 'INVALID' + + args '--tweakClass', 'baritone.launch.BaritoneTweaker' + jvmArgs "-Dorg.lwjgl.librarypath=${nativesOutput}" + } + } } repositories { @@ -95,23 +120,66 @@ repositories { } } -dependencies { - runtime launchCompile('com.github.ImpactDevelopment:SimpleTweaker:1.2') - runtime launchCompile('org.spongepowered:mixin:0.7.11-SNAPSHOT') { - // Mixin includes a lot of dependencies that are too up-to-date - exclude module: 'launchwrapper' - exclude module: 'guava' - exclude module: 'gson' - exclude module: 'commons-io' - exclude module: 'log4j-core' +// fix forge gradle 4+ bug with 1.12.2 +afterEvaluate { + configurations.minecraft { + exclude group: 'net.minecraftforge', module: 'mergetool' } - runtime launchCompile('dev.babbaj:nether-pathfinder:0.2') +} + +// lwjgl2 hack for running game on arm64 mac os +afterEvaluate { + def os = org.gradle.internal.os.OperatingSystem.current() + if (os.isMacOsX()) { + def arch = System.getProperty("os.arch").toLowerCase() + println("Detected Mac OS X running on ${arch}") + if (arch == "aarch64") { + println("Configurating aarch64 dependencies.") + + configurations.minecraft { + exclude group: 'ca.weblite', module: 'java-objc-bridge' + } + + dependencies { + // https://github.com/MinecraftMachina/lwjgl/releases/download/2.9.4-20150209-mmachina.2/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar + minecraft files("libs/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar") // TODO: use prism launcher maven + // https://github.com/MinecraftMachina/Java-Objective-C-Bridge/releases/download/1.1.0-mmachina.1/java-objc-bridge-1.1.jar + minecraft files("libs/java-objc-bridge-1.1.jar") // TODO: use prism launcher maven + minecraft(group: 'net.java.dev.jna', name: 'jna') { + version { + strictly '5.12.1' + } + } + } + } + } +} + +dependencies { + minecraft group: 'net.minecraft', name: 'joined', version: '1.12.2' + implementation(group: 'net.minecraft', name: 'launchwrapper', version: '1.12') { + transitive = false + } + + def asmVersion = '9.5' + implementation group: 'org.ow2.asm', name: 'asm', version: asmVersion + implementation group: 'org.ow2.asm', name: 'asm-tree', version: asmVersion + implementation group: 'org.ow2.asm', name: 'asm-commons', version: asmVersion + implementation group: 'org.ow2.asm', name: 'asm-analysis', version: asmVersion + implementation group: 'org.ow2.asm', name: 'asm-util', version: asmVersion + + launchImplementation('com.github.ImpactDevelopment:SimpleTweaker:1.2') + launchImplementation('org.spongepowered:mixin:0.7.11-SNAPSHOT') { + // Mixin includes a lot of dependencies that are too up-to-date + transitive = false + } + launchAnnotationProcessor 'org.spongepowered:mixin:0.8.4-SNAPSHOT:processor' + launchImplementation('dev.babbaj:nether-pathfinder:0.2') testImplementation 'junit:junit:4.12' implementation 'dev.babbaj:nether-pathfinder:0.2' } mixin { - defaultObfuscationEnv searge add sourceSets.launch, 'mixins.baritone.refmap.json' } @@ -137,7 +205,7 @@ jar { manifest { attributes( 'MixinConfigs': 'mixins.baritone.json', - + 'TweakClass': 'baritone.launch.BaritoneTweaker', 'Implementation-Title': 'Baritone', 'Implementation-Version': version ) @@ -152,25 +220,3 @@ task proguard(type: ProguardTask) { task createDist(type: CreateDistTask, dependsOn: proguard) build.finalizedBy(createDist) - -install { - def jarApiName = String.format("%s-api-%s", rootProject.name, version.toString()) - def jarApiForgeName = String.format("%s-api-forge-%s", rootProject.name, version.toString()) - def jarSAName = String.format("%s-standalone-%s", rootProject.name, version.toString()) - def jarSAForgeName = String.format("%s-standalone-forge-%s", rootProject.name, version.toString()) - - artifacts { - archives file("$buildDir/libs/" + jarApiName + ".jar") - archives file("$buildDir/libs/" + jarApiForgeName + ".jar") - archives file("$buildDir/libs/" + jarSAName + ".jar") - archives file("$buildDir/libs/" + jarSAForgeName + ".jar") - } - repositories.mavenInstaller { - addFilter('api') { artifact, file -> artifact.name == "baritone-api" } - addFilter('api-forge') { artifact, file -> artifact.name == "baritone-api-forge" } - addFilter('standalone') { artifact, file -> artifact.name == "baritone-standalone" } - addFilter('standalone-forge') { artifact, file -> artifact.name == "baritone-standalone-forge" } - } -} - -install.dependsOn(build) diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 2ac49af0f..8ab0f7014 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -20,6 +20,6 @@ repositories { } dependencies { - compile group: 'com.google.code.gson', name: 'gson', version: '2.8.5' - compile group: 'commons-io', name: 'commons-io', version: '2.6' + implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.5' + implementation group: 'commons-io', name: 'commons-io', version: '2.6' } \ No newline at end of file diff --git a/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java b/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java index 1c329ee2c..435eabcf3 100644 --- a/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java +++ b/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java @@ -18,39 +18,33 @@ package baritone.gradle.task; import baritone.gradle.util.Determinizer; -import baritone.gradle.util.MappingType; -import baritone.gradle.util.ReobfWrapper; import org.apache.commons.io.IOUtils; -import org.gradle.api.JavaVersion; -import org.gradle.api.NamedDomainObjectContainer; +import org.gradle.api.Project; import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.Dependency; -import org.gradle.api.internal.file.IdentityFileResolver; -import org.gradle.api.internal.plugins.DefaultConvention; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.TaskAction; import org.gradle.api.tasks.TaskCollection; import org.gradle.api.tasks.compile.ForkOptions; import org.gradle.api.tasks.compile.JavaCompile; -import org.gradle.internal.Pair; import org.gradle.internal.jvm.Jvm; -import org.gradle.internal.jvm.inspection.DefaultJvmVersionDetector; -import org.gradle.process.internal.DefaultExecActionFactory; + +import java.io.File; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.Objects; import java.io.*; -import java.lang.reflect.Field; import java.net.URL; import java.nio.file.Files; -import java.nio.file.Path; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; -import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; -import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; - /** * @author Brady * @since 10/11/2018 @@ -138,23 +132,16 @@ public class ProguardTask extends BaritoneGradleTask { private String findJavaByGradleCurrentRuntime() { String path = Jvm.current().getJavaExecutable().getAbsolutePath(); - - if (this.validateJavaVersion(path)) { - System.out.println("Using Gradle's runtime Java for ProGuard"); - return path; - } - return null; + System.out.println("Using Gradle's runtime Java for ProGuard"); + return path; } private String findJavaByJavaHome() { final String javaHomeEnv = System.getenv("JAVA_HOME"); if (javaHomeEnv != null) { - String path = Jvm.forHome(new File(javaHomeEnv)).getJavaExecutable().getAbsolutePath(); - if (this.validateJavaVersion(path)) { - System.out.println("Detected Java path by JAVA_HOME"); - return path; - } + System.out.println("Detected Java path by JAVA_HOME"); + return path; } return null; } @@ -170,19 +157,11 @@ public class ProguardTask extends BaritoneGradleTask { if (javacPath != null) { File javacFile = new File(javacPath); if (javacFile.exists()) { - File[] maybeJava = javacFile.getParentFile().listFiles(new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return name.equals("java"); - } - }); - + File[] maybeJava = javacFile.getParentFile().listFiles((dir, name) -> name.equals("java")); if (maybeJava != null && maybeJava.length > 0) { String path = maybeJava[0].getAbsolutePath(); - if (this.validateJavaVersion(path)) { - System.out.println("Detected Java path by forkOptions"); - return path; - } + System.out.println("Detected Java path by forkOptions"); + return path; } } } @@ -190,21 +169,8 @@ public class ProguardTask extends BaritoneGradleTask { return null; } - private boolean validateJavaVersion(String java) { - final JavaVersion javaVersion = new DefaultJvmVersionDetector(new DefaultExecActionFactory(new IdentityFileResolver())).getJavaVersion(java); - - if (!javaVersion.getMajorVersion().equals("8")) { - System.out.println("Failed to validate Java version " + javaVersion.toString() + " [" + java + "] for ProGuard libraryjars"); - // throw new RuntimeException("Java version incorrect: " + javaVersion.getMajorVersion() + " for " + java); - return false; - } - - System.out.println("Validated Java version " + javaVersion.toString() + " [" + java + "] for ProGuard libraryjars"); - return true; - } - private void generateConfigs() throws Exception { - Files.copy(getRelativeFile(PROGUARD_CONFIG_TEMPLATE), getTemporaryFile(PROGUARD_CONFIG_DEST), REPLACE_EXISTING); + Files.copy(getRelativeFile(PROGUARD_CONFIG_TEMPLATE), getTemporaryFile(PROGUARD_CONFIG_DEST), StandardCopyOption.REPLACE_EXISTING); // Setup the template that will be used to derive the API and Standalone configs List template = Files.readAllLines(getTemporaryFile(PROGUARD_CONFIG_DEST)); @@ -236,14 +202,37 @@ public class ProguardTask extends BaritoneGradleTask { }); } - private void acquireDependencies() throws Exception { + private static final class Pair { + public final A a; + public final B b; + private Pair(final A a, final B b) { + this.a = a; + this.b = b; + } + + @Override + public String toString() { + return "Pair{" + + "a=" + this.a + + ", " + + "b=" + this.b + + '}'; + } + } + + private void acquireDependencies() throws Exception { // Create a map of all of the dependencies that we are able to access in this project // Likely a better way to do this, I just pair the dependency with the first valid configuration Map> dependencyLookupMap = new HashMap<>(); - getProject().getConfigurations().stream().filter(Configuration::isCanBeResolved).forEach(config -> - config.getAllDependencies().forEach(dependency -> - dependencyLookupMap.putIfAbsent(dependency.getName() + "-" + dependency.getVersion(), Pair.of(config, dependency)))); + Map files = new HashMap<>(); + getProject().getConfigurations().stream().filter(Configuration::isCanBeResolved).forEach(config -> { + for (File file : config.getFiles()) { + files.put(file.getName(), file); + } + config.getAllDependencies().forEach(dependency -> + dependencyLookupMap.putIfAbsent(dependency.getName() + "-" + dependency.getVersion(), new Pair<>(config, dependency))); + }); // Create the directory if it doesn't already exist Path tempLibraries = getTemporaryFile(TEMP_LIBRARY_DIR); @@ -258,7 +247,7 @@ public class ProguardTask extends BaritoneGradleTask { Path cachedJar = getMinecraftJar(); Path inTempDir = getTemporaryFile("tempLibraries/minecraft.jar"); // TODO: maybe try not to copy every time - Files.copy(cachedJar, inTempDir, REPLACE_EXISTING); + Files.copy(cachedJar, inTempDir, StandardCopyOption.REPLACE_EXISTING); continue; } @@ -270,20 +259,21 @@ public class ProguardTask extends BaritoneGradleTask { pair = entry.getValue(); } } - - // The pair must be non-null - Objects.requireNonNull(pair); - // Find the library jar file, and copy it to tempLibraries - for (File file : pair.getLeft().files(pair.getRight())) { - if (file.getName().startsWith(lib)) { - if (lib.contains("mixin")) { - mixin = file; + if (pair == null) { + File libFile = files.get(lib + ".jar"); + if (libFile == null) { + libFile = files.values().stream().filter(file -> file.getName().startsWith(lib)).findFirst().orElse(null); + if (libFile == null) { + throw new IllegalStateException(lib); } - if (lib.contains("nether-pathfinder")) { - pathfinder = file; + } + copyTempLib(lib, libFile); + } else { + for (File file : pair.a.files(pair.b)) { + if (file.getName().startsWith(lib)) { + copyTempLib(lib, file); } - Files.copy(file.toPath(), getTemporaryFile("tempLibraries/" + lib + ".jar"), REPLACE_EXISTING); } } } @@ -295,87 +285,39 @@ public class ProguardTask extends BaritoneGradleTask { } } + private void copyTempLib(String lib, File libFile) throws IOException { + if (lib.contains("mixin")) { + mixin = libFile; + } + if (lib.contains("nether-pathfinder")) { + pathfinder = libFile; + } + Files.copy(libFile.toPath(), getTemporaryFile("tempLibraries/" + lib + ".jar"), StandardCopyOption.REPLACE_EXISTING); + } + // a bunch of epic stuff to get the path to the cached jar private Path getMinecraftJar() throws Exception { - MappingType mappingType; - try { - mappingType = getMappingType(); - } catch (Exception e) { - System.err.println("Failed to get mapping type, assuming NOTCH."); - mappingType = MappingType.NOTCH; - } - - String suffix; - switch (mappingType) { - case NOTCH: - suffix = ""; - break; - case SEARGE: - suffix = "-srgBin"; - break; - case CUSTOM: - throw new IllegalStateException("Custom mappings not supported!"); - default: - throw new IllegalStateException("Unknown mapping type: " + mappingType); - } - - DefaultConvention convention = (DefaultConvention) this.getProject().getConvention(); - Object extension = convention.getAsMap().get("minecraft"); - Objects.requireNonNull(extension); - - // for some reason cant use Class.forName - Class class_baseExtension = extension.getClass().getSuperclass().getSuperclass().getSuperclass(); // <-- cursed - Field f_replacer = class_baseExtension.getDeclaredField("replacer"); - f_replacer.setAccessible(true); - Object replacer = f_replacer.get(extension); - Class class_replacementProvider = replacer.getClass(); - Field replacement_replaceMap = class_replacementProvider.getDeclaredField("replaceMap"); - replacement_replaceMap.setAccessible(true); - - Map replacements = (Map) replacement_replaceMap.get(replacer); - String cacheDir = replacements.get("CACHE_DIR").toString() + "/net/minecraft"; - String mcVersion = replacements.get("MC_VERSION").toString(); - String mcpInsert = replacements.get("MAPPING_CHANNEL").toString() + "/" + replacements.get("MAPPING_VERSION").toString(); - String fullJarName = "minecraft-" + mcVersion + suffix + ".jar"; - - String baseDir = String.format("%s/minecraft/%s/", cacheDir, mcVersion); - - String jarPath; - if (mappingType == MappingType.SEARGE) { - jarPath = String.format("%s/%s/%s", baseDir, mcpInsert, fullJarName); - } else { - jarPath = baseDir + fullJarName; - } - jarPath = jarPath - .replace("/", File.separator) - .replace("\\", File.separator); // hecking regex - - return new File(jarPath).toPath(); + return getObfuscatedMinecraftJar(getProject(), false); // always notch jar for now. } - // throws IllegalStateException if mapping type is ambiguous or it fails to find it - private MappingType getMappingType() { - // if it fails to find this then its probably a forgegradle version problem - Set reobf = (NamedDomainObjectContainer) this.getProject().getExtensions().getByName("reobf"); + private static Path getObfuscatedMinecraftJar(final Project project, final boolean srg) throws Exception { + final Object extension = Objects.requireNonNull(project.getExtensions().findByName("minecraft"), "Unable to find Minecraft extension."); - List mappingTypes = getUsedMappingTypes(reobf); - long mappingTypesUsed = mappingTypes.size(); - if (mappingTypesUsed == 0) { - throw new IllegalStateException("Failed to find mapping type (no jar task?)"); - } - if (mappingTypesUsed > 1) { - throw new IllegalStateException("Ambiguous mapping type (multiple jars with different mapping types?)"); - } + final Class mcpRepoClass = mcpRepoClass(extension.getClass().getClassLoader()); + final Field mcpRepoInstanceField = mcpRepoClass.getDeclaredField("INSTANCE"); + mcpRepoInstanceField.setAccessible(true); + final Method findMethod = mcpRepoClass.getDeclaredMethod(srg ? "findSrg" : "findRaw", String.class, String.class); + findMethod.setAccessible(true); - return mappingTypes.get(0); + final Object mcpRepo = mcpRepoInstanceField.get(null); + final String mcpVersion = (String) Objects.requireNonNull(project.getExtensions().getExtraProperties().get("MCP_VERSION"), "Extra property \"MCP_VERSION\" not found"); + return ((File) findMethod.invoke(mcpRepo, "joined", mcpVersion)).toPath(); } - private List getUsedMappingTypes(Set reobf) { - return reobf.stream() - .map(ReobfWrapper::new) - .map(ReobfWrapper::getMappingType) - .distinct() - .collect(Collectors.toList()); + private static Class mcpRepoClass(final ClassLoader loader) throws Exception { + final Method forName0 = Class.class.getDeclaredMethod("forName0", String.class, boolean.class, ClassLoader.class, Class.class); + forName0.setAccessible(true); + return (Class) forName0.invoke(null, "net.minecraftforge.gradle.mcp.MCPRepo", true, loader, null); } private void proguardApi() throws Exception { @@ -400,10 +342,18 @@ public class ProguardTask extends BaritoneGradleTask { this.url = url; } + public String getUrl() { + return url; + } + public void setExtract(String extract) { this.extract = extract; } + public String getExtract() { + return extract; + } + private void runProguard(Path config) throws Exception { // Delete the existing proguard output file. Proguard probably handles this already, but why not do it ourselves if (Files.exists(this.proguardOut)) { diff --git a/buildSrc/src/main/java/baritone/gradle/util/MappingType.java b/buildSrc/src/main/java/baritone/gradle/util/MappingType.java deleted file mode 100644 index a3be9b49f..000000000 --- a/buildSrc/src/main/java/baritone/gradle/util/MappingType.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of Baritone. - * - * Baritone is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Baritone is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Baritone. If not, see . - */ - -package baritone.gradle.util; - -/** - * All credits go to AsmLibGradle and its contributors. - * - * @see Original Source - */ -public enum MappingType { - SEARGE, - NOTCH, - CUSTOM // forgegradle -} diff --git a/buildSrc/src/main/java/baritone/gradle/util/ReobfWrapper.java b/buildSrc/src/main/java/baritone/gradle/util/ReobfWrapper.java deleted file mode 100644 index f752cd946..000000000 --- a/buildSrc/src/main/java/baritone/gradle/util/ReobfWrapper.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of Baritone. - * - * Baritone is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Baritone is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Baritone. If not, see . - */ - -package baritone.gradle.util; - -import java.lang.reflect.Field; -import java.util.Objects; - -/** - * All credits go to AsmLibGradle and its contributors. - * - * @see Original Source - */ -public class ReobfWrapper { - - private final Object instance; - private final Class type; - - public ReobfWrapper(Object instance) { - this.instance = instance; - Objects.requireNonNull(instance); - this.type = instance.getClass(); - } - - public String getName() { - try { - Field nameField = type.getDeclaredField("name"); - nameField.setAccessible(true); - return (String) nameField.get(this.instance); - } catch (ReflectiveOperationException ex) { - throw new IllegalStateException(ex); - } - } - - public MappingType getMappingType() { - try { - Field enumField = type.getDeclaredField("mappingType"); - enumField.setAccessible(true); - Enum aEnum = (Enum) enumField.get(this.instance); - MappingType mappingType = MappingType.values()[aEnum.ordinal()]; - if (!aEnum.name().equals(mappingType.name())) { - throw new IllegalStateException("ForgeGradle ReobfMappingType is not equivalent to MappingType (version error?)"); - } - return mappingType; - } catch (ReflectiveOperationException ex) { - throw new IllegalStateException(ex); - } - } -} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 4c5670a158b8953b61fd441194873cac2c99930d..7454180f2ae8848c63b8b4dea2cb829da983f2fa 100755 GIT binary patch literal 59536 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 QuEJmfE|#`Dqx|px0L@K;Y5)KL literal 54706 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 599a02b7a..c51cbf173 100755 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Tue Jul 31 21:56:56 PDT 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.4-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip diff --git a/gradlew b/gradlew index cccdd3d51..744e882ed 100755 --- a/gradlew +++ b/gradlew @@ -1,5 +1,21 @@ #!/usr/bin/env sh +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + ############################################################################## ## ## Gradle start up script for UN*X @@ -28,7 +44,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" @@ -56,7 +72,7 @@ case "`uname`" in Darwin* ) darwin=true ;; - MINGW* ) + MSYS* | MINGW* ) msys=true ;; NONSTOP* ) @@ -66,6 +82,7 @@ esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then @@ -109,10 +126,11 @@ if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath @@ -138,19 +156,19 @@ if $cygwin ; then else eval `echo args$i`="\"$arg\"" fi - i=$((i+1)) + i=`expr $i + 1` done case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi @@ -159,14 +177,9 @@ save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } -APP_ARGS=$(save "$@") +APP_ARGS=`save "$@"` # Collect all arguments for the java command, following the shell quoting and substitution rules eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index f9553162f..107acd32c 100755 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -35,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -45,28 +64,14 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/hacks.gradle b/hacks.gradle new file mode 100644 index 000000000..821a4d02e --- /dev/null +++ b/hacks.gradle @@ -0,0 +1,161 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +ext.doHackyStuff = { final Class clazz -> + def withExtension = { final File file, final String extension -> + def i = file.getName().lastIndexOf('.') + def name = file.getName().substring(0, i) + return new File(file.getParent(), "$name.$extension") + } + + // https://github.com/MinecraftForge/ForgeGradle/blob/6639464b29b0923187eee0a609e546ba9f1b998b/src/patcher/java/net/minecraftforge/gradle/patcher/PatcherPlugin.java#L545 + // https://github.com/MinecraftForge/ForgeGradle/blob/6639464b29b0923187eee0a609e546ba9f1b998b/src/userdev/java/net/minecraftforge/gradle/userdev/UserDevPlugin.java#L149 + // create createMcp2Obf task + this.tasks.register('createMcpToObf', clazz) + .configure { task -> + task.setNotch(true) + task.setReverse(true) + } + afterEvaluate { + def createMcp2Obf = this.tasks.getByName('createMcpToObf') + def createMcp2Srg = this.tasks.getByName('createMcpToSrg') + + // configure createMcp2Obf task + if (createMcp2Obf.getSrg() == null) { + createMcp2Obf.setSrg(createMcp2Srg.getSrg()) + createMcp2Obf.setMappings(createMcp2Srg.getMappings()) + createMcp2Obf.dependsOn(createMcp2Srg) + } + + def createSrgCopyTask = { final Task tsrgTask -> + def srgCopyTask = this.tasks.register("${tsrgTask.name}Srg", tsrgTask.getClass()) + tsrgTask.getDependsOn().forEach({ dep -> + srgCopyTask.get().dependsOn(dep) + }) + // https://github.com/MinecraftForge/ForgeGradle/blob/6639464b29b0923187eee0a609e546ba9f1b998b/src/mcp/java/net/minecraftforge/gradle/mcp/task/GenerateSRG.java#L39 + srgCopyTask.configure { task -> + task.setSrg(tsrgTask.getSrg()) + task.setMappings(tsrgTask.getMappings()) + // https://github.com/MinecraftForge/SrgUtils/blob/bb2ca35bb8d349a122ef512dedd24f54f7cd0bdf/src/main/java/net/minecraftforge/srgutils/IMappingFile.java#L44 + task.setFormat('SRG') + task.setNotch(tsrgTask.getNotch()) + task.setReverse(tsrgTask.getReverse()) + task.setOutput(withExtension(tsrgTask.getOutput(), 'srg')) + } + return srgCopyTask + } + def createMcp2ObfSrgCopyTask = createSrgCopyTask(createMcp2Obf) + createMcp2Obf.dependsOn(createMcp2ObfSrgCopyTask) + def createMcp2SrgSrgCopyTask = createSrgCopyTask(createMcp2Srg) + createMcp2Srg.dependsOn(createMcp2SrgSrgCopyTask) + + this.sourceSets.forEach({ set -> + def compileTask = this.project.tasks[set.compileJavaTaskName] + if (!(compileTask instanceof JavaCompile)) { + println("[Baritoe] Non-java compile task for ${set} of type ${compileTask}") + return + } + compileTask.dependsOn(createMcp2Obf) + compileTask.doFirst { + // inject legacy notch srg file + def createMcp2ObfSrgCopy = createMcp2ObfSrgCopyTask.get() + def reobfNotchSrgFileArgument = "-AreobfNotchSrgFile=${createMcp2ObfSrgCopy.output.canonicalPath}" + compileTask.options.compilerArgs += reobfNotchSrgFileArgument + println("[Baritoe] Injecting compiler argument: ${reobfNotchSrgFileArgument}") + + // inject legacy notch srg out file + def outTSrgFileArgument = '-AoutTsrgFile=' + def compilerArgsIterator = compileTask.options.compilerArgs.listIterator() + while (compilerArgsIterator.hasNext()) { + def compilerArg = compilerArgsIterator.next() + if (compilerArg.startsWith(outTSrgFileArgument)) { + def argumentFileValue = new File(compilerArg.substring(outTSrgFileArgument.length(), compilerArg.length())) + def outNotchSrgFile = withExtension(argumentFileValue, 'notch.srg') + def outNotchSrgFileArgument = "-AoutNotchSrgFile=${outNotchSrgFile.canonicalPath}" + println("[Baritoe] Injecting compiler argument: ${outNotchSrgFileArgument}") + compilerArgsIterator.add(outNotchSrgFileArgument) + } + } + } + }) + + // register reobf jars + def reobfExtension = this.project.getExtensions().getByName('reobf') + if (!reobfExtension) { + throw new IllegalStateException("Could not find \"reobf\" extension") + } + def reobfNotchJar = reobfExtension.create(jar.getName()) + reobfNotchJar.dependsOn(createMcp2Obf) + reobfNotchJar.setMappings(createMcp2Obf.getOutput()) + + // even more horrible hack :) for outNotchSrgFile injection + reobfNotchJar.doFirst { + // https://github.com/MinecraftForge/ForgeGradle/blob/6639464b29b0923187eee0a609e546ba9f1b998b/src/userdev/java/net/minecraftforge/gradle/userdev/tasks/RenameJar.java#L96 + def extraMappings = reobfNotchJar.getExtraMappings() + println("[Baritoe] Extra mappings: ${extraMappings}") + def copy = new ArrayList<>() + extraMappings.forEach { extraMapping -> + copy.add(withExtension(extraMapping, 'notch.srg')) + } + println("[Baritoe] New extra mappings: ${copy}") + reobfNotchJar.setExtraMappings(copy) + } + } +} + +// TODO: In-complete fg 5.0 port. Currently doesn't handle mixin notch srg mapping hack. +//ext.doHackyStuff = { final Class clazz -> +// afterEvaluate { +// def createMcp2Srg = this.tasks.getByName('createMcpToSrg') +// def createMcpToObf = this.tasks.register('createMcpToObf', clazz) +// createMcpToObf.configure { task -> +// task.setNotch(true) +// task.setReverse(true) +// task.getSrg().set(createMcp2Srg.getSrg().get()) +// task.getMappings().set(createMcp2Srg.getMappings().get()) +// task.dependsOn(createMcp2Srg) +// } +// reobf { +// jar { +// dependsOn(createMcpToObf) +// getMappings().set(createMcpToObf.get().getOutput().get()) +// } +// } +// this.sourceSets.forEach({ set -> +// def compileTask = this.project.tasks[set.compileJavaTaskName] +// if (!(compileTask instanceof JavaCompile)) { +// println("[Baritoe] Non-java compile task for ${set} of type ${compileTask}") +// return +// } +// compileTask.dependsOn(createMcpToObf) +// compileTask.doFirst { +// def reobfTSrgFile = '-AreobfTsrgFile=' +// def compilerArgsIterator = compileTask.options.compilerArgs.listIterator() +// while (compilerArgsIterator.hasNext()) { +// def compilerArg = compilerArgsIterator.next() +// if (compilerArg.startsWith(reobfTSrgFile)) { +// compilerArgsIterator.remove() +// def toInject = "-AreobfTsrgFile=${createMcpToObf.get().output.get().asFile.canonicalPath}" +// compilerArgsIterator.add(toInject) +// println("[Baritoe] Injecting compiler argument: ${toInject}") +// } +// } +// println("[Baritoe] Compiler arguments: ${compileTask.options.compilerArgs}") +// } +// }) +// } +//} \ No newline at end of file diff --git a/scripts/proguard.pro b/scripts/proguard.pro index 858494778..d493f60de 100644 --- a/scripts/proguard.pro +++ b/scripts/proguard.pro @@ -92,7 +92,7 @@ -libraryjars 'tempLibraries/text2speech-1.10.3.jar' -libraryjars 'tempLibraries/mixin-0.7.11-SNAPSHOT.jar' --libraryjars 'tempLibraries/launchwrapper-1.11.jar' # TODO why does only 1.11.jar exist? +-libraryjars 'tempLibraries/launchwrapper-1.12.jar' -libraryjars 'tempLibraries/nether-pathfinder-.jar' From b72bbfce5e4eb28ded8b4bb9003d468d9baa47e6 Mon Sep 17 00:00:00 2001 From: 0x22 <0x22@futureclient.net> Date: Fri, 16 Jun 2023 22:36:58 -0400 Subject: [PATCH 120/405] make all json deterministic --- .../src/main/java/baritone/gradle/util/Determinizer.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/buildSrc/src/main/java/baritone/gradle/util/Determinizer.java b/buildSrc/src/main/java/baritone/gradle/util/Determinizer.java index 40d17ef03..35c1fe40a 100644 --- a/buildSrc/src/main/java/baritone/gradle/util/Determinizer.java +++ b/buildSrc/src/main/java/baritone/gradle/util/Determinizer.java @@ -64,9 +64,9 @@ public class Determinizer { JarEntry clone = new JarEntry(entry.getName()); clone.setTime(42069); jos.putNextEntry(clone); - if (entry.getName().endsWith(".refmap.json")) { - JsonObject object = new JsonParser().parse(new InputStreamReader(jarFile.getInputStream(entry))).getAsJsonObject(); - jos.write(writeSorted(object).getBytes()); + if (entry.getName().endsWith(".json")) { + JsonElement json = new JsonParser().parse(new InputStreamReader(jarFile.getInputStream(entry))); + jos.write(writeSorted(json).getBytes()); } else if (entry.getName().equals("META-INF/MANIFEST.MF") && doForgeReplacementOfMetaInf) { // only replace for forge jar ByteArrayOutputStream cancer = new ByteArrayOutputStream(); copy(jarFile.getInputStream(entry), cancer); @@ -104,7 +104,7 @@ public class Determinizer { } } - private static String writeSorted(JsonObject in) throws IOException { + private static String writeSorted(JsonElement in) throws IOException { StringWriter writer = new StringWriter(); JsonWriter jw = new JsonWriter(writer); ORDERED_JSON_WRITER.write(jw, in); From 071e6164fef3fff38e7316641f723e46eb31827a Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 16 Jun 2023 21:55:08 -0500 Subject: [PATCH 121/405] Fix nether-pathfinder on Windows --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 8e952df73..e9c0c24cd 100755 --- a/build.gradle +++ b/build.gradle @@ -105,9 +105,9 @@ dependencies { exclude module: 'commons-io' exclude module: 'log4j-core' } - runtime launchCompile('dev.babbaj:nether-pathfinder:0.2') + runtime launchCompile('dev.babbaj:nether-pathfinder:0.4') testImplementation 'junit:junit:4.12' - implementation 'dev.babbaj:nether-pathfinder:0.2' + implementation 'dev.babbaj:nether-pathfinder:0.4' } mixin { From f798ff26f696e0825ad4d94d2856cc14bd0deb51 Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 16 Jun 2023 22:31:53 -0500 Subject: [PATCH 122/405] fixed seed --- src/main/java/baritone/Elytra.java | 74 ++++++++++++------- .../command/defaults/ElytraCommand.java | 2 +- .../java/baritone/utils/PathRenderer.java | 4 +- 3 files changed, 51 insertions(+), 29 deletions(-) diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index e8e83c5b7..affe8e5e6 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -18,10 +18,7 @@ package baritone; import baritone.api.event.events.TickEvent; -import baritone.api.utils.BetterBlockPos; -import baritone.api.utils.Helper; -import baritone.api.utils.Rotation; -import baritone.api.utils.RotationUtils; +import baritone.api.utils.*; import baritone.behavior.Behavior; import baritone.utils.BlockStateInterface; import com.mojang.realmsclient.util.Pair; @@ -37,20 +34,24 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Vec3d; +import net.minecraft.world.chunk.BlockStateContainer; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.storage.ExtendedBlockStorage; import java.util.*; import java.util.stream.Collectors; public class Elytra extends Behavior implements Helper { + private static final long NETHER_SEED = 146008555100680L; + // Used exclusively for PathRenderer public List> lines; - public BlockPos goal; + public BlockPos aimPos; public List visiblePath; // NetherPathfinder stuff private long context; - private Long seed; // yay! private List path; @@ -60,28 +61,34 @@ public class Elytra extends Behavior implements Helper { protected Elytra(Baritone baritone) { super(baritone); + // lol + this.context = NetherPathfinder.newContext(NETHER_SEED); + this.lines = new ArrayList<>(); this.visiblePath = Collections.emptyList(); this.path = new ArrayList<>(); } - public void path(long seed, BlockPos destination) { - this.setupContext(seed); - + public void path(BlockPos destination) { this.playerNear = 0; this.goingTo = 0; + long start = System.currentTimeMillis(); final PathSegment segment = NetherPathfinder.pathFind( this.context, ctx.playerFeet().x, ctx.playerFeet().y, ctx.playerFeet().z, destination.getX(), destination.getY(), destination.getZ() ); + long end = System.currentTimeMillis(); this.path = Arrays.stream(segment.packed) .mapToObj(BlockPos::fromLong) .map(BetterBlockPos::new) .collect(Collectors.toList()); + final int distance = (int) Math.sqrt(this.path.get(0).distanceSq(this.path.get(this.path.size() - 1))); + logDirect(String.format("Computed path in %dms. (%d blocks)", end - start, distance)); + if (!segment.finished) { logDirect("segment not finished. path incomplete"); } @@ -89,25 +96,10 @@ public class Elytra extends Behavior implements Helper { removeBacktracks(); } - private void setupContext(long seed) { - if (!Objects.equals(this.seed, seed)) { - this.freeContext(); - this.context = NetherPathfinder.newContext(seed); - } - this.seed = seed; - } - - private void freeContext() { - if (this.context != 0) { - NetherPathfinder.freeContext(this.context); - } - this.context = 0; - } - public void cancel() { this.visiblePath = Collections.emptyList(); this.path.clear(); - this.goal = null; + this.aimPos = null; this.playerNear = 0; this.goingTo = 0; this.sinceFirework = 0; @@ -196,7 +188,7 @@ public class Elytra extends Behavior implements Helper { long b = System.currentTimeMillis(); System.out.println("Solved pitch in " + (b - a) + " total time " + (b - t)); goingTo = i; - goal = path.get(i).add(0, dy, 0); + aimPos = path.get(i).add(0, dy, 0); baritone.getLookBehavior().updateTarget(new Rotation(rot.getYaw(), pitch), false); return; } @@ -368,6 +360,36 @@ public class Elytra extends Behavior implements Helper { } } + private static boolean[] pack(Chunk chunk) { + try { + boolean[] packed = new boolean[16 * 16 * 128]; + ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray(); + for (int y0 = 0; y0 < 8; y0++) { + ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0]; + if (extendedblockstorage == null) { + continue; + } + BlockStateContainer bsc = extendedblockstorage.getData(); + int yReal = y0 << 4; + for (int y1 = 0; y1 < 16; y1++) { + int y = y1 | yReal; + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { + IBlockState state = bsc.get(x, y1, z); + if (state.getBlock() != Blocks.AIR) { // instanceof BlockAir in 1.13+ + packed[x + (z << 4) + (y << 8)] = true; + } + } + } + } + } + return packed; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + // TODO: Use the optimized version from builder-2 private RayTraceResult rayTraceBlocks(Vec3d start, Vec3d end) { int x1 = MathHelper.floor(end.x); diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index 99ddaa8e4..2d2e3f0ee 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -41,7 +41,7 @@ public class ElytraCommand extends Command { ICustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess(); args.requireMax(0); GoalXZ goal = (GoalXZ) customGoalProcess.getGoal(); - ((Baritone) baritone).elytra.path(146008555100680L, new BlockPos(goal.getX(), 64, goal.getZ())); + ((Baritone) baritone).elytra.path(new BlockPos(goal.getX(), 64, goal.getZ())); } @Override diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index 934375c4c..a4c412298 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -106,8 +106,8 @@ public final class PathRenderer implements IRenderer { } drawPath(behavior.baritone.elytra.visiblePath, 0, Color.RED, false, 0, 0); - if (behavior.baritone.elytra.goal != null) { - drawGoal(renderView, new GoalBlock(behavior.baritone.elytra.goal), partialTicks, Color.GREEN); + if (behavior.baritone.elytra.aimPos != null) { + drawGoal(renderView, new GoalBlock(behavior.baritone.elytra.aimPos), partialTicks, Color.GREEN); } if (!behavior.baritone.elytra.lines.isEmpty() && Baritone.settings().renderRaytraces.value) { IRenderer.startLines(Color.BLUE, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); From dc53c7939312507418debde09822dcdbfb7b36eb Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 16 Jun 2023 21:35:56 -0700 Subject: [PATCH 123/405] gaming --- build.gradle | 7 +- src/main/java/baritone/Elytra.java | 129 +++++++++++++++++++++++------ 2 files changed, 106 insertions(+), 30 deletions(-) diff --git a/build.gradle b/build.gradle index e6f3e1134..6f5ca491a 100755 --- a/build.gradle +++ b/build.gradle @@ -142,7 +142,8 @@ afterEvaluate { dependencies { // https://github.com/MinecraftMachina/lwjgl/releases/download/2.9.4-20150209-mmachina.2/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar - minecraft files("libs/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar") // TODO: use prism launcher maven + minecraft files("libs/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar") + // TODO: use prism launcher maven // https://github.com/MinecraftMachina/Java-Objective-C-Bridge/releases/download/1.1.0-mmachina.1/java-objc-bridge-1.1.jar minecraft files("libs/java-objc-bridge-1.1.jar") // TODO: use prism launcher maven minecraft(group: 'net.java.dev.jna', name: 'jna') { @@ -174,9 +175,9 @@ dependencies { transitive = false } launchAnnotationProcessor 'org.spongepowered:mixin:0.8.4-SNAPSHOT:processor' - launchImplementation('dev.babbaj:nether-pathfinder:0.4') + launchImplementation('dev.babbaj:nether-pathfinder:0.6') testImplementation 'junit:junit:4.12' - implementation 'dev.babbaj:nether-pathfinder:0.4' + implementation 'dev.babbaj:nether-pathfinder:0.6' } mixin { diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index affe8e5e6..97e4a0b43 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -17,8 +17,13 @@ package baritone; +import baritone.api.event.events.ChunkEvent; import baritone.api.event.events.TickEvent; -import baritone.api.utils.*; +import baritone.api.event.events.type.EventState; +import baritone.api.utils.BetterBlockPos; +import baritone.api.utils.Helper; +import baritone.api.utils.Rotation; +import baritone.api.utils.RotationUtils; import baritone.behavior.Behavior; import baritone.utils.BlockStateInterface; import com.mojang.realmsclient.util.Pair; @@ -39,6 +44,8 @@ import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.storage.ExtendedBlockStorage; import java.util.*; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; import java.util.stream.Collectors; public class Elytra extends Behavior implements Helper { @@ -69,31 +76,93 @@ public class Elytra extends Behavior implements Helper { this.path = new ArrayList<>(); } - public void path(BlockPos destination) { - this.playerNear = 0; - this.goingTo = 0; + private final Executor packer = Executors.newSingleThreadExecutor(); - long start = System.currentTimeMillis(); - final PathSegment segment = NetherPathfinder.pathFind( - this.context, - ctx.playerFeet().x, ctx.playerFeet().y, ctx.playerFeet().z, - destination.getX(), destination.getY(), destination.getZ() - ); - long end = System.currentTimeMillis(); - - this.path = Arrays.stream(segment.packed) - .mapToObj(BlockPos::fromLong) - .map(BetterBlockPos::new) - .collect(Collectors.toList()); - - final int distance = (int) Math.sqrt(this.path.get(0).distanceSq(this.path.get(this.path.size() - 1))); - logDirect(String.format("Computed path in %dms. (%d blocks)", end - start, distance)); - - if (!segment.finished) { - logDirect("segment not finished. path incomplete"); + @Override + public final void onChunkEvent(ChunkEvent event) { + if (event.getState() == EventState.POST && (event.getType() == ChunkEvent.Type.POPULATE_FULL || event.getType() == ChunkEvent.Type.POPULATE_PARTIAL)) { + Chunk chunk = ctx.world().getChunk(event.getX(), event.getZ()); + packer.execute(() -> { + NetherPathfinder.insertChunkData(context, event.getX(), event.getZ(), pack(chunk)); + }); } + } - removeBacktracks(); + boolean recalculating; + + private void pathfindAroundObstacles() { + if (recalculating) { + return; + } + outer: + while (true) { + int rangeStartIncl = playerNear; + int rangeEndExcl = playerNear; + while (rangeEndExcl < path.size() && ctx.world().isBlockLoaded(path.get(rangeEndExcl), false)) { + rangeEndExcl++; + } + if (rangeStartIncl >= rangeEndExcl) { + // not loaded yet? + return; + } + if (!passable(ctx.world().getBlockState(path.get(rangeStartIncl)))) { + // we're in a wall + return; // previous iterations of this function SHOULD have fixed this by now :rage_cat: + } + for (int i = rangeStartIncl; i < rangeEndExcl - 1; i++) { + if (!clearView(pathAt(i), pathAt(i + 1))) { + // obstacle. where do we return to pathing? + // find the next valid segment + for (int j = i + 1; j < rangeEndExcl - 1; j++) { + if (clearView(pathAt(j), pathAt(j + 1))) { + // found it + // we want to replace the path from i to j + List afterSplice = path.subList(j + 1, path.size()); + recalculating = true; + path(path.get(j + 1), afterSplice); + break outer; + } + } + } + } + break; + } + } + + public void path(BlockPos destination) { + path(destination, new ArrayList<>()); + } + + public void path(BlockPos destination, List andThen) { + packer.execute(() -> { + long start = System.currentTimeMillis(); + final PathSegment segment = NetherPathfinder.pathFind( + this.context, + ctx.playerFeet().x, ctx.playerFeet().y, ctx.playerFeet().z, + destination.getX(), destination.getY(), destination.getZ() + ); + long end = System.currentTimeMillis(); + + ctx.minecraft().addScheduledTask(() -> { + this.path = Arrays.stream(segment.packed) + .mapToObj(BlockPos::fromLong) + .map(BetterBlockPos::new) + .collect(Collectors.toList()); + final int distance = (int) Math.sqrt(this.path.get(0).distanceSq(this.path.get(this.path.size() - 1))); + logDirect(String.format("Computed path in %dms. (%d blocks)", end - start, distance)); + + if (!segment.finished) { + logDirect("segment not finished. path incomplete"); + } + this.path.addAll(andThen); + if (!andThen.isEmpty()) { + recalculating = false; + } + this.playerNear = 0; + this.goingTo = 0; + removeBacktracks(); + }); + }); } public void cancel() { @@ -127,6 +196,8 @@ public class Elytra extends Behavior implements Helper { baritone.getInputOverrideHandler().clearAllKeys(); // FIXME: This breaks the regular path-finder lines.clear(); + pathfindAroundObstacles(); + if (!ctx.player().isElytraFlying()) { return; } @@ -361,9 +432,11 @@ public class Elytra extends Behavior implements Helper { } private static boolean[] pack(Chunk chunk) { + //System.out.println(chunk); try { boolean[] packed = new boolean[16 * 16 * 128]; ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray(); + int count = 0; for (int y0 = 0; y0 < 8; y0++) { ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0]; if (extendedblockstorage == null) { @@ -376,17 +449,19 @@ public class Elytra extends Behavior implements Helper { for (int z = 0; z < 16; z++) { for (int x = 0; x < 16; x++) { IBlockState state = bsc.get(x, y1, z); - if (state.getBlock() != Blocks.AIR) { // instanceof BlockAir in 1.13+ + if (!passable(state)) { packed[x + (z << 4) + (y << 8)] = true; + count++; } } } } } + //System.out.println("breakpoint " + count); return packed; } catch (Exception e) { e.printStackTrace(); - return null; + throw new RuntimeException(e); } } @@ -401,7 +476,7 @@ public class Elytra extends Behavior implements Helper { BlockPos blockpos = new BlockPos(x2, y2, z2); IBlockState iblockstate = ctx.world().getBlockState(blockpos); if (!passable(iblockstate)) { - return Blocks.DIRT.getDefaultState().collisionRayTrace(ctx.world(), blockpos, start, end); + return Blocks.SPONGE.getDefaultState().collisionRayTrace(ctx.world(), blockpos, start, end); } int steps = 200; while (steps-- >= 0) { @@ -479,7 +554,7 @@ public class Elytra extends Behavior implements Helper { blockpos = new BlockPos(x2, y2, z2); IBlockState iblockstate1 = ctx.world().getBlockState(blockpos); if (!passable(iblockstate1)) { - return Blocks.DIRT.getDefaultState().collisionRayTrace(ctx.world(), blockpos, start, end); + return Blocks.NETHERRACK.getDefaultState().collisionRayTrace(ctx.world(), blockpos, start, end); } } return null; From 1f303e69b0d246689ccbf96afbc3963092274058 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 16 Jun 2023 22:21:52 -0700 Subject: [PATCH 124/405] cut at render distance --- build.gradle | 4 ++-- src/main/java/baritone/Elytra.java | 17 ++++++----------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/build.gradle b/build.gradle index 6f5ca491a..a389ae08f 100755 --- a/build.gradle +++ b/build.gradle @@ -175,9 +175,9 @@ dependencies { transitive = false } launchAnnotationProcessor 'org.spongepowered:mixin:0.8.4-SNAPSHOT:processor' - launchImplementation('dev.babbaj:nether-pathfinder:0.6') + launchImplementation('dev.babbaj:nether-pathfinder:0.8') testImplementation 'junit:junit:4.12' - implementation 'dev.babbaj:nether-pathfinder:0.6' + implementation 'dev.babbaj:nether-pathfinder:0.8' } mixin { diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index 97e4a0b43..1af15edda 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -83,6 +83,7 @@ public class Elytra extends Behavior implements Helper { if (event.getState() == EventState.POST && (event.getType() == ChunkEvent.Type.POPULATE_FULL || event.getType() == ChunkEvent.Type.POPULATE_PARTIAL)) { Chunk chunk = ctx.world().getChunk(event.getX(), event.getZ()); packer.execute(() -> { + System.out.println("meow"); NetherPathfinder.insertChunkData(context, event.getX(), event.getZ(), pack(chunk)); }); } @@ -113,16 +114,10 @@ public class Elytra extends Behavior implements Helper { if (!clearView(pathAt(i), pathAt(i + 1))) { // obstacle. where do we return to pathing? // find the next valid segment - for (int j = i + 1; j < rangeEndExcl - 1; j++) { - if (clearView(pathAt(j), pathAt(j + 1))) { - // found it - // we want to replace the path from i to j - List afterSplice = path.subList(j + 1, path.size()); - recalculating = true; - path(path.get(j + 1), afterSplice); - break outer; - } - } + List afterSplice = path.subList(rangeEndExcl - 1, path.size()); + recalculating = true; + path(path.get(rangeEndExcl - 1), afterSplice); + break outer; } } break; @@ -457,7 +452,7 @@ public class Elytra extends Behavior implements Helper { } } } - //System.out.println("breakpoint " + count); + System.out.println("breakpoint " + count); return packed; } catch (Exception e) { e.printStackTrace(); From 157e4db7c5aab54236c551b5ba33a9062018feff Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 16 Jun 2023 22:39:50 -0700 Subject: [PATCH 125/405] fireworks hack --- src/main/java/baritone/Elytra.java | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index 1af15edda..75d90dc6f 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -206,17 +206,8 @@ public class Elytra extends Behavior implements Helper { Vec3d start = ctx.playerFeetAsVec(); boolean firework = isFireworkActive(); sinceFirework++; - if (!firework - && sinceFirework > 10 - && (Baritone.settings().wasteFireworks.value || ctx.player().posY < path.get(goingTo).y + 5) // don't firework if trying to descend - && (ctx.player().posY < path.get(goingTo).y - 5 || start.distanceTo(new Vec3d(path.get(goingTo).x + 0.5, ctx.player().posY, path.get(goingTo).z + 0.5)) > 5) // UGH!!!!!!! - && new Vec3d(ctx.player().motionX, ctx.player().posY < path.get(goingTo).y ? Math.max(0, ctx.player().motionY) : ctx.player().motionY, ctx.player().motionZ).length() < Baritone.settings().elytraFireworkSpeed.value // ignore y component if we are BOTH below where we want to be AND descending - ) { - logDirect("firework"); - ctx.playerController().processRightClick(ctx.player(), ctx.world(), EnumHand.MAIN_HAND); - sinceFirework = 0; - } final long t = System.currentTimeMillis(); + outermost: for (int relaxation = 0; relaxation < 3; relaxation++) { // try for a strict solution first, then relax more and more (if we're in a corner or near some blocks, it will have to relax its constraints a bit) int[] heights = firework ? new int[]{20, 10, 5, 0} : new int[]{0}; // attempt to gain height, if we can, so as not to waste the boost boolean requireClear = relaxation == 0; @@ -256,12 +247,26 @@ public class Elytra extends Behavior implements Helper { goingTo = i; aimPos = path.get(i).add(0, dy, 0); baritone.getLookBehavior().updateTarget(new Rotation(rot.getYaw(), pitch), false); - return; + break outermost; } } } + if (relaxation == 2) { + logDirect("no pitch solution, probably gonna crash in a few ticks LOL!!!"); + return; + } + } + + if (!firework + && sinceFirework > 10 + && (Baritone.settings().wasteFireworks.value || ctx.player().posY < path.get(goingTo).y + 5) // don't firework if trying to descend + && (ctx.player().posY < path.get(goingTo).y - 5 || start.distanceTo(new Vec3d(path.get(goingTo).x + 0.5, ctx.player().posY, path.get(goingTo).z + 0.5)) > 5) // UGH!!!!!!! + && new Vec3d(ctx.player().motionX, ctx.player().posY < path.get(goingTo).y ? Math.max(0, ctx.player().motionY) : ctx.player().motionY, ctx.player().motionZ).length() < Baritone.settings().elytraFireworkSpeed.value // ignore y component if we are BOTH below where we want to be AND descending + ) { + logDirect("firework"); + ctx.playerController().processRightClick(ctx.player(), ctx.world(), EnumHand.MAIN_HAND); + sinceFirework = 0; } - logDirect("no pitch solution, probably gonna crash in a few ticks LOL!!!"); } private boolean isFireworkActive() { From c5475498ca655a854874770d24a4eba79b2f6cbd Mon Sep 17 00:00:00 2001 From: Brady Date: Sat, 17 Jun 2023 01:39:21 -0500 Subject: [PATCH 126/405] so cute --- .../baritone/api/event/events/ChunkEvent.java | 6 +- src/main/java/baritone/Elytra.java | 116 +++++++++++------- 2 files changed, 78 insertions(+), 44 deletions(-) diff --git a/src/api/java/baritone/api/event/events/ChunkEvent.java b/src/api/java/baritone/api/event/events/ChunkEvent.java index f27475bce..a7b5d96f0 100644 --- a/src/api/java/baritone/api/event/events/ChunkEvent.java +++ b/src/api/java/baritone/api/event/events/ChunkEvent.java @@ -106,6 +106,10 @@ public final class ChunkEvent { *

* And it's a partial chunk */ - POPULATE_PARTIAL + POPULATE_PARTIAL; + + public final boolean isPopulate() { + return this == POPULATE_FULL || this == POPULATE_PARTIAL; + } } } diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index 75d90dc6f..e63682e11 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -44,9 +44,9 @@ import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.storage.ExtendedBlockStorage; import java.util.*; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; +import java.util.concurrent.*; import java.util.stream.Collectors; +import java.util.stream.Stream; public class Elytra extends Behavior implements Helper { @@ -57,10 +57,8 @@ public class Elytra extends Behavior implements Helper { public BlockPos aimPos; public List visiblePath; - // NetherPathfinder stuff - private long context; - - // yay! + // :sunglasses: + private final Context context; private List path; public int playerNear; private int goingTo; @@ -68,31 +66,67 @@ public class Elytra extends Behavior implements Helper { protected Elytra(Baritone baritone) { super(baritone); - // lol - this.context = NetherPathfinder.newContext(NETHER_SEED); - + this.context = new Context(NETHER_SEED); this.lines = new ArrayList<>(); this.visiblePath = Collections.emptyList(); this.path = new ArrayList<>(); } - private final Executor packer = Executors.newSingleThreadExecutor(); + private static final class Context { + + private final long context; + private final long seed; + private final ExecutorService executor; + + public Context(long seed) { + this.context = NetherPathfinder.newContext(seed); + this.seed = seed; + this.executor = Executors.newSingleThreadExecutor(); + } + + public void queueForPacking(Chunk chunk) { + this.executor.submit(() -> NetherPathfinder.insertChunkData(this.context, chunk.x, chunk.z, pack(chunk))); + } + + public CompletableFuture pathFindAsync(final BlockPos src, final BlockPos dst) { + return CompletableFuture.supplyAsync(() -> + NetherPathfinder.pathFind( + this.context, + src.getX(), src.getY(), src.getZ(), + dst.getX(), dst.getY(), dst.getZ() + ), this.executor); + } + + public void destroy() { + // Ignore anything that was queued up, just shutdown the executor + this.executor.shutdownNow(); + + try { + while (!this.executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) {} + } catch (InterruptedException e) { + e.printStackTrace(); + } + + NetherPathfinder.freeContext(this.context); + } + + public long getSeed() { + return this.seed; + } + } @Override public final void onChunkEvent(ChunkEvent event) { - if (event.getState() == EventState.POST && (event.getType() == ChunkEvent.Type.POPULATE_FULL || event.getType() == ChunkEvent.Type.POPULATE_PARTIAL)) { - Chunk chunk = ctx.world().getChunk(event.getX(), event.getZ()); - packer.execute(() -> { - System.out.println("meow"); - NetherPathfinder.insertChunkData(context, event.getX(), event.getZ(), pack(chunk)); - }); + if (event.getState() == EventState.POST && event.getType().isPopulate()) { + final Chunk chunk = ctx.world().getChunk(event.getX(), event.getZ()); + this.context.queueForPacking(chunk); } } boolean recalculating; private void pathfindAroundObstacles() { - if (recalculating) { + if (this.recalculating) { return; } outer: @@ -115,7 +149,6 @@ public class Elytra extends Behavior implements Helper { // obstacle. where do we return to pathing? // find the next valid segment List afterSplice = path.subList(rangeEndExcl - 1, path.size()); - recalculating = true; path(path.get(rangeEndExcl - 1), afterSplice); break outer; } @@ -125,36 +158,33 @@ public class Elytra extends Behavior implements Helper { } public void path(BlockPos destination) { - path(destination, new ArrayList<>()); + path(destination, Collections.emptyList()); } public void path(BlockPos destination, List andThen) { - packer.execute(() -> { - long start = System.currentTimeMillis(); - final PathSegment segment = NetherPathfinder.pathFind( - this.context, - ctx.playerFeet().x, ctx.playerFeet().y, ctx.playerFeet().z, - destination.getX(), destination.getY(), destination.getZ() - ); - long end = System.currentTimeMillis(); + final boolean isRecalc = !andThen.isEmpty(); + this.recalculating = isRecalc; + + this.context.pathFindAsync(ctx.playerFeet(), destination).thenAccept(segment -> { + Stream newPath = Arrays.stream(segment.packed) + .mapToObj(BlockPos::fromLong) + .map(BetterBlockPos::new); + + List joined = Stream.concat(newPath, andThen.stream()).collect(Collectors.toList()); ctx.minecraft().addScheduledTask(() -> { - this.path = Arrays.stream(segment.packed) - .mapToObj(BlockPos::fromLong) - .map(BetterBlockPos::new) - .collect(Collectors.toList()); - final int distance = (int) Math.sqrt(this.path.get(0).distanceSq(this.path.get(this.path.size() - 1))); - logDirect(String.format("Computed path in %dms. (%d blocks)", end - start, distance)); - - if (!segment.finished) { - logDirect("segment not finished. path incomplete"); - } - this.path.addAll(andThen); - if (!andThen.isEmpty()) { - recalculating = false; - } + this.path = joined; this.playerNear = 0; this.goingTo = 0; + + final int distance = (int) Math.sqrt(this.path.get(0).distanceSq(this.path.get(segment.packed.length - 1))); + + if (isRecalc) { + this.recalculating = false; + logDirect(String.format("Recalculated segment (%d blocks)", distance)); + } else { + logDirect(String.format("Computed path (%d blocks)", distance)); + } removeBacktracks(); }); }); @@ -182,7 +212,7 @@ public class Elytra extends Behavior implements Helper { return; } - playerNear = fixNearPlayer(playerNear); + playerNear = calculateNear(playerNear); visiblePath = path.subList( Math.max(playerNear - 30, 0), Math.min(playerNear + 30, path.size()) @@ -390,7 +420,7 @@ public class Elytra extends Behavior implements Helper { return new Vec3d(motionX, motionY, motionZ); } - private int fixNearPlayer(int index) { + private int calculateNear(int index) { final BetterBlockPos pos = ctx.playerFeet(); for (int i = index; i >= Math.max(index - 1000, 0); i -= 10) { if (path.get(i).distanceSq(pos) < path.get(index).distanceSq(pos)) { From 424f27c7986567168cc50b6caf7b5388d8bd13cf Mon Sep 17 00:00:00 2001 From: Brady Date: Sat, 17 Jun 2023 01:41:17 -0500 Subject: [PATCH 127/405] remove debug msg --- src/main/java/baritone/Elytra.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index e63682e11..2f9aa223c 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -462,11 +462,9 @@ public class Elytra extends Behavior implements Helper { } private static boolean[] pack(Chunk chunk) { - //System.out.println(chunk); try { boolean[] packed = new boolean[16 * 16 * 128]; ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray(); - int count = 0; for (int y0 = 0; y0 < 8; y0++) { ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0]; if (extendedblockstorage == null) { @@ -481,13 +479,11 @@ public class Elytra extends Behavior implements Helper { IBlockState state = bsc.get(x, y1, z); if (!passable(state)) { packed[x + (z << 4) + (y << 8)] = true; - count++; } } } } } - System.out.println("breakpoint " + count); return packed; } catch (Exception e) { e.printStackTrace(); From 97e91ed680e581498666ff80d35a74923e36cdf1 Mon Sep 17 00:00:00 2001 From: Brady Date: Sat, 17 Jun 2023 01:42:49 -0500 Subject: [PATCH 128/405] one var --- src/main/java/baritone/Elytra.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/Elytra.java index 2f9aa223c..57f0f7cf4 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/Elytra.java @@ -166,11 +166,12 @@ public class Elytra extends Behavior implements Helper { this.recalculating = isRecalc; this.context.pathFindAsync(ctx.playerFeet(), destination).thenAccept(segment -> { - Stream newPath = Arrays.stream(segment.packed) - .mapToObj(BlockPos::fromLong) - .map(BetterBlockPos::new); - - List joined = Stream.concat(newPath, andThen.stream()).collect(Collectors.toList()); + final List joined = Stream.concat( + Arrays.stream(segment.packed) + .mapToObj(BlockPos::fromLong) + .map(BetterBlockPos::new), + andThen.stream() + ).collect(Collectors.toList()); ctx.minecraft().addScheduledTask(() -> { this.path = joined; From a67889ab4266b2fed6168a3813db8e33bd4832e1 Mon Sep 17 00:00:00 2001 From: Brady Date: Sat, 17 Jun 2023 01:55:07 -0500 Subject: [PATCH 129/405] refactoring --- src/main/java/baritone/Baritone.java | 8 ++++++-- .../{Elytra.java => behavior/ElytraBehavior.java} | 8 ++++---- .../baritone/command/defaults/ElytraCommand.java | 2 +- .../command/defaults/ExecutionControlCommands.java | 2 +- .../command/defaults/ForceCancelCommand.java | 2 +- src/main/java/baritone/utils/PathRenderer.java | 13 ++++++++----- 6 files changed, 21 insertions(+), 14 deletions(-) rename src/main/java/baritone/{Elytra.java => behavior/ElytraBehavior.java} (99%) diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index 6199d03f5..457b49a45 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -64,7 +64,7 @@ public class Baritone implements IBaritone { private final GameEventHandler gameEventHandler; private final PathingBehavior pathingBehavior; - public final Elytra elytra; + private final ElytraBehavior elytraBehavior; private final LookBehavior lookBehavior; private final InventoryBehavior inventoryBehavior; private final InputOverrideHandler inputOverrideHandler; @@ -103,7 +103,7 @@ public class Baritone implements IBaritone { { this.pathingBehavior = this.registerBehavior(PathingBehavior::new); - this.elytra = this.registerBehavior(Elytra::new); + this.elytraBehavior = this.registerBehavior(ElytraBehavior::new); this.lookBehavior = this.registerBehavior(LookBehavior::new); this.inventoryBehavior = this.registerBehavior(InventoryBehavior::new); this.inputOverrideHandler = this.registerBehavior(InputOverrideHandler::new); @@ -232,6 +232,10 @@ public class Baritone implements IBaritone { return this.commandManager; } + public ElytraBehavior getElytraBehavior() { + return this.elytraBehavior; + } + @Override public void openClick() { new Thread(() -> { diff --git a/src/main/java/baritone/Elytra.java b/src/main/java/baritone/behavior/ElytraBehavior.java similarity index 99% rename from src/main/java/baritone/Elytra.java rename to src/main/java/baritone/behavior/ElytraBehavior.java index 57f0f7cf4..473fd7f8b 100644 --- a/src/main/java/baritone/Elytra.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -15,8 +15,9 @@ * along with Baritone. If not, see . */ -package baritone; +package baritone.behavior; +import baritone.Baritone; import baritone.api.event.events.ChunkEvent; import baritone.api.event.events.TickEvent; import baritone.api.event.events.type.EventState; @@ -24,7 +25,6 @@ import baritone.api.utils.BetterBlockPos; import baritone.api.utils.Helper; import baritone.api.utils.Rotation; import baritone.api.utils.RotationUtils; -import baritone.behavior.Behavior; import baritone.utils.BlockStateInterface; import com.mojang.realmsclient.util.Pair; import dev.babbaj.pathfinder.NetherPathfinder; @@ -48,7 +48,7 @@ import java.util.concurrent.*; import java.util.stream.Collectors; import java.util.stream.Stream; -public class Elytra extends Behavior implements Helper { +public final class ElytraBehavior extends Behavior implements Helper { private static final long NETHER_SEED = 146008555100680L; @@ -64,7 +64,7 @@ public class Elytra extends Behavior implements Helper { private int goingTo; private int sinceFirework; - protected Elytra(Baritone baritone) { + public ElytraBehavior(Baritone baritone) { super(baritone); this.context = new Context(NETHER_SEED); this.lines = new ArrayList<>(); diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index 2d2e3f0ee..47db0e33e 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -41,7 +41,7 @@ public class ElytraCommand extends Command { ICustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess(); args.requireMax(0); GoalXZ goal = (GoalXZ) customGoalProcess.getGoal(); - ((Baritone) baritone).elytra.path(new BlockPos(goal.getX(), 64, goal.getZ())); + ((Baritone) baritone).getElytraBehavior().path(new BlockPos(goal.getX(), 64, goal.getZ())); } @Override diff --git a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java index 66b2d156d..ef566bb8d 100644 --- a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java +++ b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java @@ -181,7 +181,7 @@ public class ExecutionControlCommands { paused[0] = false; } baritone.getPathingBehavior().cancelEverything(); - ((Baritone) baritone).elytra.cancel(); + ((Baritone) baritone).getElytraBehavior().cancel(); logDirect("ok canceled"); } diff --git a/src/main/java/baritone/command/defaults/ForceCancelCommand.java b/src/main/java/baritone/command/defaults/ForceCancelCommand.java index 3a54ce69e..60ccdab01 100644 --- a/src/main/java/baritone/command/defaults/ForceCancelCommand.java +++ b/src/main/java/baritone/command/defaults/ForceCancelCommand.java @@ -40,7 +40,7 @@ public class ForceCancelCommand extends Command { IPathingBehavior pathingBehavior = baritone.getPathingBehavior(); pathingBehavior.cancelEverything(); pathingBehavior.forceCancel(); - ((Baritone) baritone).elytra.cancel(); + ((Baritone) baritone).getElytraBehavior().cancel(); logDirect("ok force canceled"); } diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index 491d7906e..fa8925042 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -24,6 +24,7 @@ import baritone.api.pathing.goals.*; import baritone.api.utils.BetterBlockPos; import baritone.api.utils.IPlayerContext; import baritone.api.utils.interfaces.IGoalRenderPos; +import baritone.behavior.ElytraBehavior; import baritone.behavior.PathingBehavior; import baritone.pathing.path.PathExecutor; import com.mojang.realmsclient.util.Pair; @@ -101,15 +102,17 @@ public final class PathRenderer implements IRenderer { drawPath(next.getPath().positions(), 0, settings.colorNextPath.value, settings.fadePath.value, 10, 20); } - drawPath(behavior.baritone.elytra.visiblePath, 0, Color.RED, false, 0, 0); - if (behavior.baritone.elytra.aimPos != null) { - drawGoal(ctx.player(), new GoalBlock(behavior.baritone.elytra.aimPos), partialTicks, Color.GREEN); + final ElytraBehavior elytra = behavior.baritone.getElytraBehavior(); + + drawPath(elytra.visiblePath, 0, Color.RED, false, 0, 0); + if (elytra.aimPos != null) { + drawGoal(ctx.player(), new GoalBlock(elytra.aimPos), partialTicks, Color.GREEN); } - if (!behavior.baritone.elytra.lines.isEmpty() && Baritone.settings().renderRaytraces.value) { + if (!elytra.lines.isEmpty() && Baritone.settings().renderRaytraces.value) { IRenderer.startLines(Color.BLUE, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); boolean orig = settings.renderPathAsLine.value; settings.renderPathAsLine.value = true; - for (Pair line : behavior.baritone.elytra.lines) { + for (Pair line : elytra.lines) { emitLine(line.first().x, line.first().y, line.first().z, line.second().x, line.second().y, line.second().z); } settings.renderPathAsLine.value = orig; From 395706edc9ebfb54ba8d3127397408c4354beae1 Mon Sep 17 00:00:00 2001 From: Brady Date: Sat, 17 Jun 2023 02:02:26 -0500 Subject: [PATCH 130/405] move context wrapper to new class --- .../baritone/behavior/ElytraBehavior.java | 90 ++------------- .../elytra/NetherPathfinderContext.java | 109 ++++++++++++++++++ 2 files changed, 117 insertions(+), 82 deletions(-) create mode 100644 src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 473fd7f8b..bd430b9e5 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -25,10 +25,9 @@ import baritone.api.utils.BetterBlockPos; import baritone.api.utils.Helper; import baritone.api.utils.Rotation; import baritone.api.utils.RotationUtils; +import baritone.behavior.elytra.NetherPathfinderContext; import baritone.utils.BlockStateInterface; import com.mojang.realmsclient.util.Pair; -import dev.babbaj.pathfinder.NetherPathfinder; -import dev.babbaj.pathfinder.PathSegment; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.item.EntityFireworkRocket; @@ -39,17 +38,17 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Vec3d; -import net.minecraft.world.chunk.BlockStateContainer; import net.minecraft.world.chunk.Chunk; -import net.minecraft.world.chunk.storage.ExtendedBlockStorage; import java.util.*; -import java.util.concurrent.*; import java.util.stream.Collectors; import java.util.stream.Stream; public final class ElytraBehavior extends Behavior implements Helper { + /** + * 2b2t seed + */ private static final long NETHER_SEED = 146008555100680L; // Used exclusively for PathRenderer @@ -58,7 +57,7 @@ public final class ElytraBehavior extends Behavior implements Helper { public List visiblePath; // :sunglasses: - private final Context context; + private final NetherPathfinderContext context; private List path; public int playerNear; private int goingTo; @@ -66,57 +65,14 @@ public final class ElytraBehavior extends Behavior implements Helper { public ElytraBehavior(Baritone baritone) { super(baritone); - this.context = new Context(NETHER_SEED); + this.context = new NetherPathfinderContext(NETHER_SEED); this.lines = new ArrayList<>(); this.visiblePath = Collections.emptyList(); this.path = new ArrayList<>(); } - private static final class Context { - - private final long context; - private final long seed; - private final ExecutorService executor; - - public Context(long seed) { - this.context = NetherPathfinder.newContext(seed); - this.seed = seed; - this.executor = Executors.newSingleThreadExecutor(); - } - - public void queueForPacking(Chunk chunk) { - this.executor.submit(() -> NetherPathfinder.insertChunkData(this.context, chunk.x, chunk.z, pack(chunk))); - } - - public CompletableFuture pathFindAsync(final BlockPos src, final BlockPos dst) { - return CompletableFuture.supplyAsync(() -> - NetherPathfinder.pathFind( - this.context, - src.getX(), src.getY(), src.getZ(), - dst.getX(), dst.getY(), dst.getZ() - ), this.executor); - } - - public void destroy() { - // Ignore anything that was queued up, just shutdown the executor - this.executor.shutdownNow(); - - try { - while (!this.executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) {} - } catch (InterruptedException e) { - e.printStackTrace(); - } - - NetherPathfinder.freeContext(this.context); - } - - public long getSeed() { - return this.seed; - } - } - @Override - public final void onChunkEvent(ChunkEvent event) { + public void onChunkEvent(ChunkEvent event) { if (event.getState() == EventState.POST && event.getType().isPopulate()) { final Chunk chunk = ctx.world().getChunk(event.getX(), event.getZ()); this.context.queueForPacking(chunk); @@ -366,7 +322,7 @@ public final class ElytraBehavior extends Behavior implements Helper { return bestPitch; } - private static boolean passable(IBlockState state) { + public static boolean passable(IBlockState state) { return state.getMaterial() == Material.AIR; } @@ -462,36 +418,6 @@ public final class ElytraBehavior extends Behavior implements Helper { } } - private static boolean[] pack(Chunk chunk) { - try { - boolean[] packed = new boolean[16 * 16 * 128]; - ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray(); - for (int y0 = 0; y0 < 8; y0++) { - ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0]; - if (extendedblockstorage == null) { - continue; - } - BlockStateContainer bsc = extendedblockstorage.getData(); - int yReal = y0 << 4; - for (int y1 = 0; y1 < 16; y1++) { - int y = y1 | yReal; - for (int z = 0; z < 16; z++) { - for (int x = 0; x < 16; x++) { - IBlockState state = bsc.get(x, y1, z); - if (!passable(state)) { - packed[x + (z << 4) + (y << 8)] = true; - } - } - } - } - } - return packed; - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - // TODO: Use the optimized version from builder-2 private RayTraceResult rayTraceBlocks(Vec3d start, Vec3d end) { int x1 = MathHelper.floor(end.x); diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java new file mode 100644 index 000000000..33a8569f7 --- /dev/null +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -0,0 +1,109 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.behavior.elytra; + +import dev.babbaj.pathfinder.NetherPathfinder; +import dev.babbaj.pathfinder.PathSegment; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.chunk.BlockStateContainer; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.storage.ExtendedBlockStorage; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import static baritone.behavior.ElytraBehavior.passable; + +/** + * @author Brady + */ +public final class NetherPathfinderContext { + + private final long context; + private final long seed; + private final ExecutorService executor; + + public NetherPathfinderContext(long seed) { + this.context = NetherPathfinder.newContext(seed); + this.seed = seed; + this.executor = Executors.newSingleThreadExecutor(); + } + + public void queueForPacking(Chunk chunk) { + this.executor.submit(() -> NetherPathfinder.insertChunkData(this.context, chunk.x, chunk.z, pack(chunk))); + } + + public CompletableFuture pathFindAsync(final BlockPos src, final BlockPos dst) { + return CompletableFuture.supplyAsync(() -> + NetherPathfinder.pathFind( + this.context, + src.getX(), src.getY(), src.getZ(), + dst.getX(), dst.getY(), dst.getZ() + ), this.executor); + } + + public void destroy() { + // Ignore anything that was queued up, just shutdown the executor + this.executor.shutdownNow(); + + try { + while (!this.executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) {} + } catch (InterruptedException e) { + e.printStackTrace(); + } + + NetherPathfinder.freeContext(this.context); + } + + public long getSeed() { + return this.seed; + } + + private static boolean[] pack(Chunk chunk) { + try { + boolean[] packed = new boolean[16 * 16 * 128]; + ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray(); + for (int y0 = 0; y0 < 8; y0++) { + ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0]; + if (extendedblockstorage == null) { + continue; + } + BlockStateContainer bsc = extendedblockstorage.getData(); + int yReal = y0 << 4; + for (int y1 = 0; y1 < 16; y1++) { + int y = y1 | yReal; + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { + IBlockState state = bsc.get(x, y1, z); + if (!passable(state)) { + packed[x + (z << 4) + (y << 8)] = true; + } + } + } + } + } + return packed; + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } +} From 0290b344dc7e9ccdf548bb2b44c28c49d33ed84a Mon Sep 17 00:00:00 2001 From: Brady Date: Sat, 17 Jun 2023 02:33:43 -0500 Subject: [PATCH 131/405] Cancel before shutting down executor --- .../baritone/behavior/elytra/NetherPathfinderContext.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index 33a8569f7..0fb1983f9 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -60,7 +60,12 @@ public final class NetherPathfinderContext { ), this.executor); } + public void cancel() { + NetherPathfinder.cancel(this.context); + } + public void destroy() { + this.cancel(); // Ignore anything that was queued up, just shutdown the executor this.executor.shutdownNow(); From d1a6de06e20ec677d902fd4234dfa7eb9422792d Mon Sep 17 00:00:00 2001 From: Brady Date: Sat, 17 Jun 2023 14:15:57 -0500 Subject: [PATCH 132/405] =?UTF-8?q?=F0=9F=98=BC=20`PathManager`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../baritone/behavior/ElytraBehavior.java | 366 +++++++++++------- .../behavior/elytra/UnpackedSegment.java | 65 ++++ 2 files changed, 299 insertions(+), 132 deletions(-) create mode 100644 src/main/java/baritone/behavior/elytra/UnpackedSegment.java diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index bd430b9e5..2226f5b1b 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -26,6 +26,7 @@ import baritone.api.utils.Helper; import baritone.api.utils.Rotation; import baritone.api.utils.RotationUtils; import baritone.behavior.elytra.NetherPathfinderContext; +import baritone.behavior.elytra.UnpackedSegment; import baritone.utils.BlockStateInterface; import com.mojang.realmsclient.util.Pair; import net.minecraft.block.material.Material; @@ -41,8 +42,8 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.world.chunk.Chunk; import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; +import java.util.concurrent.CompletableFuture; +import java.util.function.UnaryOperator; public final class ElytraBehavior extends Behavior implements Helper { @@ -58,9 +59,7 @@ public final class ElytraBehavior extends Behavior implements Helper { // :sunglasses: private final NetherPathfinderContext context; - private List path; - public int playerNear; - private int goingTo; + private final PathManager pathManager; private int sinceFirework; public ElytraBehavior(Baritone baritone) { @@ -68,7 +67,217 @@ public final class ElytraBehavior extends Behavior implements Helper { this.context = new NetherPathfinderContext(NETHER_SEED); this.lines = new ArrayList<>(); this.visiblePath = Collections.emptyList(); - this.path = new ArrayList<>(); + this.pathManager = new PathManager(); + } + + private final class PathManager { + + private BlockPos destination; + private List path; + private boolean completePath; + + private int playerNear; + private int goingTo; + + private boolean recalculating; + + public PathManager() { + // lol imagine initializing fields normally + this.clear(); + } + + public void tick() { + // Recalculate closest path node + this.playerNear = this.calculateNear(this.playerNear); + + // Obstacles are more important than an incomplete path, handle those first. + this.pathfindAroundObstacles(); + this.attemptNextSegment(); + } + + public void pathToDestination(BlockPos destination) { + this.destination = destination; + this.path0(ctx.playerFeet(), destination, UnaryOperator.identity()) + .thenRun(() -> { + final int distance = (int) this.pathAt(0).distanceTo(this.pathAt(this.path.size() - 1)); + if (this.completePath) { + logDirect(String.format("Computed path (%d blocks)", distance)); + } else { + logDirect(String.format("Computed segment (Next %d blocks)", distance)); + } + }); + } + + public void recalcSegment(final int upToIncl) { + if (this.recalculating) { + return; + } + + this.recalculating = true; + final List after = this.path.subList(upToIncl, this.path.size()); + final boolean complete = this.completePath; + + this.path0(ctx.playerFeet(), this.path.get(upToIncl), segment -> segment.append(after.stream(), complete)) + .thenRun(() -> { + this.recalculating = false; + final int recompute = this.path.size() - after.size() - 1; + final int distance = (int) this.pathAt(0).distanceTo(this.pathAt(recompute)); + logDirect(String.format("Recomputed segment (Next %d blocks)", distance)); + }); + } + + public void nextSegment(final int afterIncl) { + if (this.recalculating) { + return; + } + + this.recalculating = true; + final List before = this.path.subList(0, afterIncl + 1); + + this.path0(this.path.get(afterIncl), this.destination, segment -> segment.prepend(before.stream())) + .thenRun(() -> { + this.recalculating = false; + final int recompute = this.path.size() - before.size() - 1; + final int distance = (int) this.pathAt(0).distanceTo(this.pathAt(recompute)); + + if (this.completePath) { + logDirect(String.format("Computed path (%d blocks)", distance)); + } else { + logDirect(String.format("Computed next segment (Next %d blocks)", distance)); + } + }); + } + + private Vec3d pathAt(int i) { + return new Vec3d( + this.path.get(i).x + 0.5, + this.path.get(i).y + 0.5, + this.path.get(i).z + 0.5 + ); + } + + public void clear() { + this.path = Collections.emptyList(); + this.playerNear = 0; + this.goingTo = 0; + this.completePath = true; + } + + private void setPath(final UnpackedSegment segment) { + this.path = segment.collect(); + this.removeBacktracks(); + this.playerNear = 0; + this.goingTo = 0; + this.completePath = segment.isFinished(); + } + + public List getPath() { + return this.path; + } + + public int getNear() { + return this.playerNear; + } + + public void setGoingTo(int index) { + this.goingTo = index; + } + + public BetterBlockPos goingTo() { + return this.path.get(this.goingTo); + } + + // mickey resigned + private CompletableFuture path0(BlockPos src, BlockPos dst, UnaryOperator operator) { + return ElytraBehavior.this.context.pathFindAsync(src, dst) + .thenApply(UnpackedSegment::from) + .thenApply(operator) + .thenAcceptAsync(this::setPath, ctx.minecraft()::addScheduledTask); + } + + private void pathfindAroundObstacles() { + if (this.recalculating) { + return; + } + + outer: + while (true) { + int rangeStartIncl = playerNear; + int rangeEndExcl = playerNear; + while (rangeEndExcl < path.size() && ctx.world().isBlockLoaded(path.get(rangeEndExcl), false)) { + rangeEndExcl++; + } + if (rangeStartIncl >= rangeEndExcl) { + // not loaded yet? + return; + } + if (!passable(ctx.world().getBlockState(path.get(rangeStartIncl)))) { + // we're in a wall + return; // previous iterations of this function SHOULD have fixed this by now :rage_cat: + } + for (int i = rangeStartIncl; i < rangeEndExcl - 1; i++) { + if (!clearView(pathAt(i), pathAt(i + 1))) { + // obstacle. where do we return to pathing? + // find the next valid segment + this.recalcSegment(rangeEndExcl - 1); + break outer; + } + } + break; + } + } + + private void attemptNextSegment() { + if (this.recalculating) { + return; + } + + final int last = this.path.size() - 1; + if (!this.completePath && ctx.world().isBlockLoaded(this.path.get(last), false)) { + this.nextSegment(last); + } + } + + private int calculateNear(int index) { + final BetterBlockPos pos = ctx.playerFeet(); + for (int i = index; i >= Math.max(index - 1000, 0); i -= 10) { + if (path.get(i).distanceSq(pos) < path.get(index).distanceSq(pos)) { + index = i; // intentional: this changes the bound of the loop + } + } + for (int i = index; i < Math.min(index + 1000, path.size()); i += 10) { + if (path.get(i).distanceSq(pos) < path.get(index).distanceSq(pos)) { + index = i; // intentional: this changes the bound of the loop + } + } + for (int i = index; i >= Math.max(index - 50, 0); i--) { + if (path.get(i).distanceSq(pos) < path.get(index).distanceSq(pos)) { + index = i; // intentional: this changes the bound of the loop + } + } + for (int i = index; i < Math.min(index + 50, path.size()); i++) { + if (path.get(i).distanceSq(pos) < path.get(index).distanceSq(pos)) { + index = i; // intentional: this changes the bound of the loop + } + } + return index; + } + + private void removeBacktracks() { + Map positionFirstSeen = new HashMap<>(); + for (int i = 0; i < this.path.size(); i++) { + BetterBlockPos pos = this.path.get(i); + if (positionFirstSeen.containsKey(pos)) { + int j = positionFirstSeen.get(pos); + while (i > j) { + this.path.remove(i); + i--; + } + } else { + positionFirstSeen.put(pos, i); + } + } + } } @Override @@ -79,106 +288,38 @@ public final class ElytraBehavior extends Behavior implements Helper { } } - boolean recalculating; - - private void pathfindAroundObstacles() { - if (this.recalculating) { - return; - } - outer: - while (true) { - int rangeStartIncl = playerNear; - int rangeEndExcl = playerNear; - while (rangeEndExcl < path.size() && ctx.world().isBlockLoaded(path.get(rangeEndExcl), false)) { - rangeEndExcl++; - } - if (rangeStartIncl >= rangeEndExcl) { - // not loaded yet? - return; - } - if (!passable(ctx.world().getBlockState(path.get(rangeStartIncl)))) { - // we're in a wall - return; // previous iterations of this function SHOULD have fixed this by now :rage_cat: - } - for (int i = rangeStartIncl; i < rangeEndExcl - 1; i++) { - if (!clearView(pathAt(i), pathAt(i + 1))) { - // obstacle. where do we return to pathing? - // find the next valid segment - List afterSplice = path.subList(rangeEndExcl - 1, path.size()); - path(path.get(rangeEndExcl - 1), afterSplice); - break outer; - } - } - break; - } - } - public void path(BlockPos destination) { - path(destination, Collections.emptyList()); - } - - public void path(BlockPos destination, List andThen) { - final boolean isRecalc = !andThen.isEmpty(); - this.recalculating = isRecalc; - - this.context.pathFindAsync(ctx.playerFeet(), destination).thenAccept(segment -> { - final List joined = Stream.concat( - Arrays.stream(segment.packed) - .mapToObj(BlockPos::fromLong) - .map(BetterBlockPos::new), - andThen.stream() - ).collect(Collectors.toList()); - - ctx.minecraft().addScheduledTask(() -> { - this.path = joined; - this.playerNear = 0; - this.goingTo = 0; - - final int distance = (int) Math.sqrt(this.path.get(0).distanceSq(this.path.get(segment.packed.length - 1))); - - if (isRecalc) { - this.recalculating = false; - logDirect(String.format("Recalculated segment (%d blocks)", distance)); - } else { - logDirect(String.format("Computed path (%d blocks)", distance)); - } - removeBacktracks(); - }); - }); + this.pathManager.pathToDestination(destination); } public void cancel() { this.visiblePath = Collections.emptyList(); - this.path.clear(); + this.pathManager.clear(); this.aimPos = null; - this.playerNear = 0; - this.goingTo = 0; this.sinceFirework = 0; } - private Vec3d pathAt(int i) { - return new Vec3d(path.get(i).x + 0.5, path.get(i).y + 0.5, path.get(i).z + 0.5); - } - @Override public void onTick(TickEvent event) { if (event.getType() == TickEvent.Type.OUT) { return; } + this.lines.clear(); + + final List path = this.pathManager.getPath(); if (path.isEmpty()) { return; } - playerNear = calculateNear(playerNear); - visiblePath = path.subList( + this.pathManager.tick(); + + final int playerNear = this.pathManager.getNear(); + this.visiblePath = path.subList( Math.max(playerNear - 30, 0), Math.min(playerNear + 30, path.size()) ); baritone.getInputOverrideHandler().clearAllKeys(); // FIXME: This breaks the regular path-finder - lines.clear(); - - pathfindAroundObstacles(); if (!ctx.player().isElytraFlying()) { return; @@ -204,19 +345,19 @@ public final class ElytraBehavior extends Behavior implements Helper { int minStep = playerNear; for (int i = Math.min(playerNear + 20, path.size() - 1); i >= minStep; i--) { for (int dy : heights) { - Vec3d dest = pathAt(i).add(0, dy, 0); + Vec3d dest = this.pathManager.pathAt(i).add(0, dy, 0); if (dy != 0) { if (i + lookahead >= path.size()) { continue; } if (start.distanceTo(dest) < 40) { - if (!clearView(dest, pathAt(i + lookahead).add(0, dy, 0)) || !clearView(dest, pathAt(i + lookahead))) { + if (!clearView(dest, this.pathManager.pathAt(i + lookahead).add(0, dy, 0)) || !clearView(dest, this.pathManager.pathAt(i + lookahead))) { // aka: don't go upwards if doing so would prevent us from being able to see the next position **OR** the modified next position continue; } } else { // but if it's far away, allow gaining altitude if we could lose it again by the time we get there - if (!clearView(dest, pathAt(i))) { + if (!clearView(dest, this.pathManager.pathAt(i))) { continue; } } @@ -231,8 +372,8 @@ public final class ElytraBehavior extends Behavior implements Helper { } long b = System.currentTimeMillis(); System.out.println("Solved pitch in " + (b - a) + " total time " + (b - t)); - goingTo = i; - aimPos = path.get(i).add(0, dy, 0); + this.pathManager.setGoingTo(i); + this.aimPos = path.get(i).add(0, dy, 0); baritone.getLookBehavior().updateTarget(new Rotation(rot.getYaw(), pitch), false); break outermost; } @@ -244,11 +385,13 @@ public final class ElytraBehavior extends Behavior implements Helper { } } + final BetterBlockPos goingTo = this.pathManager.goingTo(); + if (!firework && sinceFirework > 10 - && (Baritone.settings().wasteFireworks.value || ctx.player().posY < path.get(goingTo).y + 5) // don't firework if trying to descend - && (ctx.player().posY < path.get(goingTo).y - 5 || start.distanceTo(new Vec3d(path.get(goingTo).x + 0.5, ctx.player().posY, path.get(goingTo).z + 0.5)) > 5) // UGH!!!!!!! - && new Vec3d(ctx.player().motionX, ctx.player().posY < path.get(goingTo).y ? Math.max(0, ctx.player().motionY) : ctx.player().motionY, ctx.player().motionZ).length() < Baritone.settings().elytraFireworkSpeed.value // ignore y component if we are BOTH below where we want to be AND descending + && (Baritone.settings().wasteFireworks.value || ctx.player().posY < goingTo.y + 5) // don't firework if trying to descend + && (ctx.player().posY < goingTo.y - 5 || start.distanceTo(new Vec3d(goingTo.x + 0.5, ctx.player().posY, goingTo.z + 0.5)) > 5) // UGH!!!!!!! + && new Vec3d(ctx.player().motionX, ctx.player().posY < goingTo.y ? Math.max(0, ctx.player().motionY) : ctx.player().motionY, ctx.player().motionZ).length() < Baritone.settings().elytraFireworkSpeed.value // ignore y component if we are BOTH below where we want to be AND descending ) { logDirect("firework"); ctx.playerController().processRightClick(ctx.player(), ctx.world(), EnumHand.MAIN_HAND); @@ -377,47 +520,6 @@ public final class ElytraBehavior extends Behavior implements Helper { return new Vec3d(motionX, motionY, motionZ); } - private int calculateNear(int index) { - final BetterBlockPos pos = ctx.playerFeet(); - for (int i = index; i >= Math.max(index - 1000, 0); i -= 10) { - if (path.get(i).distanceSq(pos) < path.get(index).distanceSq(pos)) { - index = i; // intentional: this changes the bound of the loop - } - } - for (int i = index; i < Math.min(index + 1000, path.size()); i += 10) { - if (path.get(i).distanceSq(pos) < path.get(index).distanceSq(pos)) { - index = i; // intentional: this changes the bound of the loop - } - } - for (int i = index; i >= Math.max(index - 50, 0); i--) { - if (path.get(i).distanceSq(pos) < path.get(index).distanceSq(pos)) { - index = i; // intentional: this changes the bound of the loop - } - } - for (int i = index; i < Math.min(index + 50, path.size()); i++) { - if (path.get(i).distanceSq(pos) < path.get(index).distanceSq(pos)) { - index = i; // intentional: this changes the bound of the loop - } - } - return index; - } - - private void removeBacktracks() { - Map positionFirstSeen = new HashMap<>(); - for (int i = 0; i < path.size(); i++) { - BetterBlockPos pos = path.get(i); - if (positionFirstSeen.containsKey(pos)) { - int j = positionFirstSeen.get(pos); - while (i > j) { - path.remove(i); - i--; - } - } else { - positionFirstSeen.put(pos, i); - } - } - } - // TODO: Use the optimized version from builder-2 private RayTraceResult rayTraceBlocks(Vec3d start, Vec3d end) { int x1 = MathHelper.floor(end.x); diff --git a/src/main/java/baritone/behavior/elytra/UnpackedSegment.java b/src/main/java/baritone/behavior/elytra/UnpackedSegment.java new file mode 100644 index 000000000..7798113da --- /dev/null +++ b/src/main/java/baritone/behavior/elytra/UnpackedSegment.java @@ -0,0 +1,65 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.behavior.elytra; + +import baritone.api.utils.BetterBlockPos; +import dev.babbaj.pathfinder.PathSegment; +import net.minecraft.util.math.BlockPos; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @author Brady + */ +public final class UnpackedSegment { + + private final Stream path; + private final boolean finished; + + public UnpackedSegment(Stream path, boolean finished) { + this.path = path; + this.finished = finished; + } + + public UnpackedSegment append(Stream other, boolean otherFinished) { + // The new segment is only finished if the one getting added on is + return new UnpackedSegment(Stream.concat(this.path, other), otherFinished); + } + + public UnpackedSegment prepend(Stream other) { + return new UnpackedSegment(Stream.concat(other, this.path), this.finished); + } + + public List collect() { + return this.path.collect(Collectors.toList()); + } + + public boolean isFinished() { + return this.finished; + } + + public static UnpackedSegment from(final PathSegment segment) { + return new UnpackedSegment( + Arrays.stream(segment.packed).mapToObj(BlockPos::fromLong).map(BetterBlockPos::new), + segment.finished + ); + } +} From 4c2984a9a0201ecd791ff4df82911e0de923cd09 Mon Sep 17 00:00:00 2001 From: Brady Date: Sat, 17 Jun 2023 14:21:32 -0500 Subject: [PATCH 133/405] Consistent `path` prefix for methods --- src/main/java/baritone/behavior/ElytraBehavior.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 2226f5b1b..3109a6dcc 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -108,7 +108,7 @@ public final class ElytraBehavior extends Behavior implements Helper { }); } - public void recalcSegment(final int upToIncl) { + public void pathRecalcSegment(final int upToIncl) { if (this.recalculating) { return; } @@ -126,7 +126,7 @@ public final class ElytraBehavior extends Behavior implements Helper { }); } - public void nextSegment(final int afterIncl) { + public void pathNextSegment(final int afterIncl) { if (this.recalculating) { return; } @@ -219,7 +219,7 @@ public final class ElytraBehavior extends Behavior implements Helper { if (!clearView(pathAt(i), pathAt(i + 1))) { // obstacle. where do we return to pathing? // find the next valid segment - this.recalcSegment(rangeEndExcl - 1); + this.pathRecalcSegment(rangeEndExcl - 1); break outer; } } @@ -234,7 +234,7 @@ public final class ElytraBehavior extends Behavior implements Helper { final int last = this.path.size() - 1; if (!this.completePath && ctx.world().isBlockLoaded(this.path.get(last), false)) { - this.nextSegment(last); + this.pathNextSegment(last); } } From 64a5ceabd8b1d4552435c0fc447e9b6ca3d9f59a Mon Sep 17 00:00:00 2001 From: Brady Date: Sat, 17 Jun 2023 15:35:26 -0500 Subject: [PATCH 134/405] Fix the regular pathfinder issue --- src/main/java/baritone/behavior/ElytraBehavior.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 3109a6dcc..214a0d1fd 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -319,11 +319,12 @@ public final class ElytraBehavior extends Behavior implements Helper { Math.min(playerNear + 30, path.size()) ); - baritone.getInputOverrideHandler().clearAllKeys(); // FIXME: This breaks the regular path-finder - if (!ctx.player().isElytraFlying()) { return; } + + baritone.getInputOverrideHandler().clearAllKeys(); + if (ctx.player().collidedHorizontally) { logDirect("hbonk"); } From 91609f4ebfc6598efda86316b60d00cca548d8b3 Mon Sep 17 00:00:00 2001 From: Brady Date: Sat, 17 Jun 2023 19:36:29 -0500 Subject: [PATCH 135/405] Use player bounding box in isClear --- .../baritone/behavior/ElytraBehavior.java | 46 +++++++++++++------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 214a0d1fd..3e5dde199 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -35,10 +35,7 @@ import net.minecraft.entity.item.EntityFireworkRocket; import net.minecraft.init.Blocks; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.*; import net.minecraft.world.chunk.Chunk; import java.util.*; @@ -339,7 +336,6 @@ public final class ElytraBehavior extends Behavior implements Helper { outermost: for (int relaxation = 0; relaxation < 3; relaxation++) { // try for a strict solution first, then relax more and more (if we're in a corner or near some blocks, it will have to relax its constraints a bit) int[] heights = firework ? new int[]{20, 10, 5, 0} : new int[]{0}; // attempt to gain height, if we can, so as not to waste the boost - boolean requireClear = relaxation == 0; int steps = relaxation < 2 ? firework ? 5 : Baritone.settings().elytraSimulationTicks.value : 3; int lookahead = relaxation == 0 ? 2 : 3; // ideally this would be expressed as a distance in blocks, rather than a number of voxel steps //int minStep = Math.max(0, playerNear - relaxation); @@ -363,7 +359,12 @@ public final class ElytraBehavior extends Behavior implements Helper { } } } - if (requireClear ? isClear(start, dest) : clearView(start, dest)) { + + // 1.0 -> 0.25 -> none + final Double grow = relaxation == 2 ? null + : relaxation == 0 ? 1.0d : 0.25d; + + if (isClear(start, dest, grow)) { Rotation rot = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()); long a = System.currentTimeMillis(); Float pitch = solvePitch(dest.subtract(start), steps, relaxation == 2); @@ -406,13 +407,32 @@ public final class ElytraBehavior extends Behavior implements Helper { .anyMatch(x -> (x instanceof EntityFireworkRocket) && ((EntityFireworkRocket) x).isAttachedToEntity()); } - private boolean isClear(Vec3d start, Vec3d dest) { - Vec3d perpendicular = dest.subtract(start).crossProduct(new Vec3d(0, 1, 0)).normalize(); - return clearView(start, dest) - && clearView(start.add(0, 2, 0), dest.add(0, 2, 0)) - && clearView(start.add(0, -2, 0), dest.add(0, -2, 0)) - && clearView(start.add(perpendicular), dest.add(perpendicular)) - && clearView(start.subtract(perpendicular), dest.subtract(perpendicular)); + private boolean isClear(final Vec3d start, final Vec3d dest, final Double growAmount) { + if (!clearView(start, dest)) { + return false; + } + if (growAmount == null) { + return true; + } + + final AxisAlignedBB bb = ctx.player().getEntityBoundingBox().grow(growAmount); + final Vec3d[] corners = new Vec3d[] { + new Vec3d(bb.minX, bb.minY, bb.minZ), + new Vec3d(bb.minX, bb.minY, bb.maxZ), + new Vec3d(bb.minX, bb.maxY, bb.minZ), + new Vec3d(bb.minX, bb.maxY, bb.maxZ), + new Vec3d(bb.maxX, bb.minY, bb.minZ), + new Vec3d(bb.maxX, bb.minY, bb.maxZ), + new Vec3d(bb.maxX, bb.maxY, bb.minZ), + new Vec3d(bb.maxX, bb.maxY, bb.maxZ), + }; + + for (final Vec3d corner : corners) { + if (!clearView(corner, dest.add(corner.subtract(start)))) { + return false; + } + } + return true; } private boolean clearView(Vec3d start, Vec3d dest) { From fcf8cd35d24a2b85630c9c10ceeec09360986f7f Mon Sep 17 00:00:00 2001 From: Brady Date: Sat, 17 Jun 2023 19:58:19 -0500 Subject: [PATCH 136/405] Handle exception to ensure `recalculating` is reset --- .../baritone/behavior/ElytraBehavior.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 3e5dde199..94033d60a 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -95,7 +95,11 @@ public final class ElytraBehavior extends Behavior implements Helper { public void pathToDestination(BlockPos destination) { this.destination = destination; this.path0(ctx.playerFeet(), destination, UnaryOperator.identity()) - .thenRun(() -> { + .whenComplete((__, ex) -> { + if (ex != null) { + logDirect("Failed to compute path to destination"); + return; + } final int distance = (int) this.pathAt(0).distanceTo(this.pathAt(this.path.size() - 1)); if (this.completePath) { logDirect(String.format("Computed path (%d blocks)", distance)); @@ -115,8 +119,12 @@ public final class ElytraBehavior extends Behavior implements Helper { final boolean complete = this.completePath; this.path0(ctx.playerFeet(), this.path.get(upToIncl), segment -> segment.append(after.stream(), complete)) - .thenRun(() -> { + .whenComplete((__, ex) -> { this.recalculating = false; + if (ex != null) { + logDirect("Failed to recompute segment"); + return; + } final int recompute = this.path.size() - after.size() - 1; final int distance = (int) this.pathAt(0).distanceTo(this.pathAt(recompute)); logDirect(String.format("Recomputed segment (Next %d blocks)", distance)); @@ -132,8 +140,13 @@ public final class ElytraBehavior extends Behavior implements Helper { final List before = this.path.subList(0, afterIncl + 1); this.path0(this.path.get(afterIncl), this.destination, segment -> segment.prepend(before.stream())) - .thenRun(() -> { + .whenComplete((__, ex) -> { this.recalculating = false; + if (ex != null) { + logDirect("Failed to compute next segment"); + return; + } + final int recompute = this.path.size() - before.size() - 1; final int distance = (int) this.pathAt(0).distanceTo(this.pathAt(recompute)); From fef7ba47010072af6bae29a204b60b00eca08296 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sat, 17 Jun 2023 20:03:30 -0700 Subject: [PATCH 137/405] tweaks --- build.gradle | 4 ++-- src/main/java/baritone/behavior/ElytraBehavior.java | 12 ++++++------ .../behavior/elytra/NetherPathfinderContext.java | 3 ++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/build.gradle b/build.gradle index a389ae08f..6d0ba4f1a 100755 --- a/build.gradle +++ b/build.gradle @@ -175,9 +175,9 @@ dependencies { transitive = false } launchAnnotationProcessor 'org.spongepowered:mixin:0.8.4-SNAPSHOT:processor' - launchImplementation('dev.babbaj:nether-pathfinder:0.8') + launchImplementation('dev.babbaj:nether-pathfinder:0.12') testImplementation 'junit:junit:4.12' - implementation 'dev.babbaj:nether-pathfinder:0.8' + implementation 'dev.babbaj:nether-pathfinder:0.12' } mixin { diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 94033d60a..e745ad53c 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -160,9 +160,9 @@ public final class ElytraBehavior extends Behavior implements Helper { private Vec3d pathAt(int i) { return new Vec3d( - this.path.get(i).x + 0.5, - this.path.get(i).y + 0.5, - this.path.get(i).z + 0.5 + this.path.get(i).x, + this.path.get(i).y, + this.path.get(i).z ); } @@ -326,7 +326,7 @@ public final class ElytraBehavior extends Behavior implements Helper { final int playerNear = this.pathManager.getNear(); this.visiblePath = path.subList( Math.max(playerNear - 30, 0), - Math.min(playerNear + 30, path.size()) + Math.min(playerNear + 100, path.size()) ); if (!ctx.player().isElytraFlying()) { @@ -429,7 +429,7 @@ public final class ElytraBehavior extends Behavior implements Helper { } final AxisAlignedBB bb = ctx.player().getEntityBoundingBox().grow(growAmount); - final Vec3d[] corners = new Vec3d[] { + final Vec3d[] corners = new Vec3d[]{ new Vec3d(bb.minX, bb.minY, bb.minZ), new Vec3d(bb.minX, bb.minY, bb.maxZ), new Vec3d(bb.minX, bb.maxY, bb.minZ), @@ -479,7 +479,7 @@ public final class ElytraBehavior extends Behavior implements Helper { totalMotion = totalMotion.add(stepped); Vec3d actualPosition = ctx.playerFeetAsVec().add(totalMotion); for (int x = MathHelper.floor(Math.min(actualPosition.x, actualPositionPrevTick.x) - 0.31); x <= Math.max(actualPosition.x, actualPositionPrevTick.x) + 0.31; x++) { - for (int y = MathHelper.floor(Math.min(actualPosition.y, actualPositionPrevTick.y) - 0.2); y <= Math.max(actualPosition.y, actualPositionPrevTick.y) + 0.8; y++) { + for (int y = MathHelper.floor(Math.min(actualPosition.y, actualPositionPrevTick.y) - 0.2); y <= Math.max(actualPosition.y, actualPositionPrevTick.y) + 1; y++) { for (int z = MathHelper.floor(Math.min(actualPosition.z, actualPositionPrevTick.z) - 0.31); z <= Math.max(actualPosition.z, actualPositionPrevTick.z) + 0.31; z++) { if (!passable(bsi.get0(x, y, z))) { continue outer; diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index 0fb1983f9..1c512b9c2 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -56,7 +56,8 @@ public final class NetherPathfinderContext { NetherPathfinder.pathFind( this.context, src.getX(), src.getY(), src.getZ(), - dst.getX(), dst.getY(), dst.getZ() + dst.getX(), dst.getY(), dst.getZ(), + true ), this.executor); } From 94027d17f2b6ec55558e7ec75f19857d5bac4e41 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sat, 17 Jun 2023 20:12:05 -0700 Subject: [PATCH 138/405] gaming --- .../gradle/task/BaritoneGradleTask.java | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/buildSrc/src/main/java/baritone/gradle/task/BaritoneGradleTask.java b/buildSrc/src/main/java/baritone/gradle/task/BaritoneGradleTask.java index 7e26dac11..a542278aa 100644 --- a/buildSrc/src/main/java/baritone/gradle/task/BaritoneGradleTask.java +++ b/buildSrc/src/main/java/baritone/gradle/task/BaritoneGradleTask.java @@ -32,21 +32,21 @@ import java.nio.file.Paths; class BaritoneGradleTask extends DefaultTask { protected static final String - PROGUARD_ZIP = "proguard.zip", - PROGUARD_JAR = "proguard.jar", - PROGUARD_CONFIG_TEMPLATE = "scripts/proguard.pro", - PROGUARD_CONFIG_DEST = "template.pro", - PROGUARD_API_CONFIG = "api.pro", - PROGUARD_STANDALONE_CONFIG = "standalone.pro", - PROGUARD_EXPORT_PATH = "proguard_out.jar", + PROGUARD_ZIP = "proguard.zip", + PROGUARD_JAR = "proguard.jar", + PROGUARD_CONFIG_TEMPLATE = "scripts/proguard.pro", + PROGUARD_CONFIG_DEST = "template.pro", + PROGUARD_API_CONFIG = "api.pro", + PROGUARD_STANDALONE_CONFIG = "standalone.pro", + PROGUARD_EXPORT_PATH = "proguard_out.jar", - TEMP_LIBRARY_DIR = "tempLibraries/", + TEMP_LIBRARY_DIR = "tempLibraries/", - ARTIFACT_STANDARD = "%s-%s.jar", - ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar", - ARTIFACT_API = "%s-api-%s.jar", - ARTIFACT_STANDALONE = "%s-standalone-%s.jar", - ARTIFACT_FORGE_API = "%s-api-forge-%s.jar", + ARTIFACT_STANDARD = "%s-%s.jar", + ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar", + ARTIFACT_API = "%s-api-%s.jar", + ARTIFACT_STANDALONE = "%s-standalone-%s.jar", + ARTIFACT_FORGE_API = "%s-api-forge-%s.jar", ARTIFACT_FORGE_STANDALONE = "%s-standalone-forge-%s.jar"; protected String artifactName, artifactVersion; @@ -56,17 +56,17 @@ class BaritoneGradleTask extends DefaultTask { this.artifactName = getProject().getName(); this.artifactVersion = getProject().getVersion().toString(); - this.artifactPath = this.getBuildFile(formatVersion(ARTIFACT_STANDARD)); - this.artifactUnoptimizedPath = this.getBuildFile(formatVersion(ARTIFACT_UNOPTIMIZED)); - this.artifactApiPath = this.getBuildFile(formatVersion(ARTIFACT_API)); - this.artifactStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_STANDALONE)); - this.artifactForgeApiPath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_API)); + this.artifactPath = this.getBuildFile(formatVersion(ARTIFACT_STANDARD)); + this.artifactUnoptimizedPath = this.getBuildFile(formatVersion(ARTIFACT_UNOPTIMIZED)); + this.artifactApiPath = this.getBuildFile(formatVersion(ARTIFACT_API)); + this.artifactStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_STANDALONE)); + this.artifactForgeApiPath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_API)); this.artifactForgeStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_STANDALONE)); this.proguardOut = this.getTemporaryFile(PROGUARD_EXPORT_PATH); if (!Files.exists(this.artifactPath)) { - throw new IllegalStateException("Artifact not found! Run build first!"); + throw new IllegalStateException("Artifact not found! Run build first! " + this.artifactPath); } } @@ -82,7 +82,7 @@ class BaritoneGradleTask extends DefaultTask { } protected Path getRelativeFile(String file) { - return Paths.get(new File(file).getAbsolutePath()); + return Paths.get(this.getProject().file(file).getAbsolutePath()); } protected Path getTemporaryFile(String file) { From 76c5c1155f7b237d1d1dae6c5cc593949a2b998d Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sun, 18 Jun 2023 00:51:07 -0400 Subject: [PATCH 139/405] Fix ElytraCommand throwing exception for invalid goals --- .../baritone/behavior/ElytraBehavior.java | 4 +-- .../elytra/NetherPathfinderContext.java | 4 +-- .../command/defaults/ElytraCommand.java | 29 +++++++++++++++++-- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index e745ad53c..d4608a705 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -386,7 +386,7 @@ public final class ElytraBehavior extends Behavior implements Helper { continue; } long b = System.currentTimeMillis(); - System.out.println("Solved pitch in " + (b - a) + " total time " + (b - t)); + //System.out.println("Solved pitch in " + (b - a) + " total time " + (b - t)); this.pathManager.setGoingTo(i); this.aimPos = path.get(i).add(0, dy, 0); baritone.getLookBehavior().updateTarget(new Rotation(rot.getYaw(), pitch), false); @@ -648,4 +648,4 @@ public final class ElytraBehavior extends Behavior implements Helper { } return null; } -} +} \ No newline at end of file diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index 1c512b9c2..2d407375a 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -100,7 +100,7 @@ public final class NetherPathfinderContext { for (int x = 0; x < 16; x++) { IBlockState state = bsc.get(x, y1, z); if (!passable(state)) { - packed[x + (z << 4) + (y << 8)] = true; + packed[x | (z << 4) | (y << 8)] = true; } } } @@ -112,4 +112,4 @@ public final class NetherPathfinderContext { throw new RuntimeException(e); } } -} +} \ No newline at end of file diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index 47db0e33e..1c9ee7882 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -22,6 +22,9 @@ import baritone.api.IBaritone; import baritone.api.command.Command; 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 net.minecraft.util.math.BlockPos; @@ -40,8 +43,28 @@ public class ElytraCommand extends Command { public void execute(String label, IArgConsumer args) throws CommandException { ICustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess(); args.requireMax(0); - GoalXZ goal = (GoalXZ) customGoalProcess.getGoal(); - ((Baritone) baritone).getElytraBehavior().path(new BlockPos(goal.getX(), 64, goal.getZ())); + Goal iGoal = customGoalProcess.getGoal(); + 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"); + } + ((Baritone) baritone).getElytraBehavior().path(new BlockPos(x, y, z)); } @Override @@ -58,4 +81,4 @@ public class ElytraCommand extends Command { public List getLongDesc() { return Arrays.asList(); } -} +} \ No newline at end of file From da31a643b393e607fe26aa8aa70562ea9925bccb Mon Sep 17 00:00:00 2001 From: Brady Date: Sat, 17 Jun 2023 20:16:26 -0500 Subject: [PATCH 140/405] unscuff --- .../baritone/behavior/ElytraBehavior.java | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index d4608a705..75ceb6b5b 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -95,17 +95,19 @@ public final class ElytraBehavior extends Behavior implements Helper { public void pathToDestination(BlockPos destination) { this.destination = destination; this.path0(ctx.playerFeet(), destination, UnaryOperator.identity()) - .whenComplete((__, ex) -> { - if (ex != null) { - logDirect("Failed to compute path to destination"); - return; - } + .thenRun(() -> { final int distance = (int) this.pathAt(0).distanceTo(this.pathAt(this.path.size() - 1)); if (this.completePath) { logDirect(String.format("Computed path (%d blocks)", distance)); } else { logDirect(String.format("Computed segment (Next %d blocks)", distance)); } + }) + .whenComplete((result, ex) -> { + this.recalculating = false; + if (ex != null) { + logDirect("Failed to compute path to destination"); + } }); } @@ -119,15 +121,16 @@ public final class ElytraBehavior extends Behavior implements Helper { final boolean complete = this.completePath; this.path0(ctx.playerFeet(), this.path.get(upToIncl), segment -> segment.append(after.stream(), complete)) - .whenComplete((__, ex) -> { - this.recalculating = false; - if (ex != null) { - logDirect("Failed to recompute segment"); - return; - } + .thenRun(() -> { final int recompute = this.path.size() - after.size() - 1; final int distance = (int) this.pathAt(0).distanceTo(this.pathAt(recompute)); logDirect(String.format("Recomputed segment (Next %d blocks)", distance)); + }) + .whenComplete((result, ex) -> { + this.recalculating = false; + if (ex != null) { + logDirect("Failed to recompute segment"); + } }); } @@ -140,13 +143,7 @@ public final class ElytraBehavior extends Behavior implements Helper { final List before = this.path.subList(0, afterIncl + 1); this.path0(this.path.get(afterIncl), this.destination, segment -> segment.prepend(before.stream())) - .whenComplete((__, ex) -> { - this.recalculating = false; - if (ex != null) { - logDirect("Failed to compute next segment"); - return; - } - + .thenRun(() -> { final int recompute = this.path.size() - before.size() - 1; final int distance = (int) this.pathAt(0).distanceTo(this.pathAt(recompute)); @@ -155,6 +152,12 @@ public final class ElytraBehavior extends Behavior implements Helper { } else { logDirect(String.format("Computed next segment (Next %d blocks)", distance)); } + }) + .whenComplete((result, ex) -> { + this.recalculating = false; + if (ex != null) { + logDirect("Failed to compute next segment"); + } }); } From 688bbb83c8dbe484b2b5285636b4a6b141ea2e4c Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 18 Jun 2023 00:11:40 -0500 Subject: [PATCH 141/405] Rename `wasteFireworks` to `conserveFireworks` and invert --- src/api/java/baritone/api/Settings.java | 2 +- .../java/baritone/behavior/ElytraBehavior.java | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index f5cf3c77a..24e54c136 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -51,7 +51,7 @@ public final class Settings { public final Setting elytraSimulationTicks = new Setting<>(20); public final Setting elytraPitchRange = new Setting<>(25); public final Setting elytraFireworkSpeed = new Setting<>(0.6); - public final Setting wasteFireworks = new Setting<>(false); + public final Setting conserveFireworks = new Setting<>(true); public final Setting renderRaytraces = new Setting<>(false); public final Setting elytraFreeLook = new Setting<>(false); diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 75ceb6b5b..9945d0b31 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -345,10 +345,10 @@ public final class ElytraBehavior extends Behavior implements Helper { logDirect("vbonk"); } - Vec3d start = ctx.playerFeetAsVec(); - boolean firework = isFireworkActive(); - sinceFirework++; - final long t = System.currentTimeMillis(); + final Vec3d start = ctx.playerFeetAsVec(); + final boolean firework = isFireworkActive(); + this.sinceFirework++; + outermost: for (int relaxation = 0; relaxation < 3; relaxation++) { // try for a strict solution first, then relax more and more (if we're in a corner or near some blocks, it will have to relax its constraints a bit) int[] heights = firework ? new int[]{20, 10, 5, 0} : new int[]{0}; // attempt to gain height, if we can, so as not to waste the boost @@ -382,14 +382,11 @@ public final class ElytraBehavior extends Behavior implements Helper { if (isClear(start, dest, grow)) { Rotation rot = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()); - long a = System.currentTimeMillis(); Float pitch = solvePitch(dest.subtract(start), steps, relaxation == 2); if (pitch == null) { baritone.getLookBehavior().updateTarget(new Rotation(rot.getYaw(), ctx.playerRotations().getPitch()), false); continue; } - long b = System.currentTimeMillis(); - //System.out.println("Solved pitch in " + (b - a) + " total time " + (b - t)); this.pathManager.setGoingTo(i); this.aimPos = path.get(i).add(0, dy, 0); baritone.getLookBehavior().updateTarget(new Rotation(rot.getYaw(), pitch), false); @@ -404,10 +401,11 @@ public final class ElytraBehavior extends Behavior implements Helper { } final BetterBlockPos goingTo = this.pathManager.goingTo(); + final boolean useOnDescend = !Baritone.settings().conserveFireworks.value || ctx.player().posY < goingTo.y + 5; if (!firework && sinceFirework > 10 - && (Baritone.settings().wasteFireworks.value || ctx.player().posY < goingTo.y + 5) // don't firework if trying to descend + && useOnDescend && (ctx.player().posY < goingTo.y - 5 || start.distanceTo(new Vec3d(goingTo.x + 0.5, ctx.player().posY, goingTo.z + 0.5)) > 5) // UGH!!!!!!! && new Vec3d(ctx.player().motionX, ctx.player().posY < goingTo.y ? Math.max(0, ctx.player().motionY) : ctx.player().motionY, ctx.player().motionZ).length() < Baritone.settings().elytraFireworkSpeed.value // ignore y component if we are BOTH below where we want to be AND descending ) { From d66b8f1dd8b5c96f741ae016868b689501441aef Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 18 Jun 2023 00:13:55 -0500 Subject: [PATCH 142/405] Extract `currentSpeed` into variable --- src/main/java/baritone/behavior/ElytraBehavior.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 9945d0b31..8fdcb34f6 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -402,12 +402,18 @@ public final class ElytraBehavior extends Behavior implements Helper { final BetterBlockPos goingTo = this.pathManager.goingTo(); final boolean useOnDescend = !Baritone.settings().conserveFireworks.value || ctx.player().posY < goingTo.y + 5; + final double currentSpeed = new Vec3d( + ctx.player().motionX, + // ignore y component if we are BOTH below where we want to be AND descending + ctx.player().posY < goingTo.y ? Math.max(0, ctx.player().motionY) : ctx.player().motionY, + ctx.player().motionZ + ).length(); if (!firework && sinceFirework > 10 && useOnDescend && (ctx.player().posY < goingTo.y - 5 || start.distanceTo(new Vec3d(goingTo.x + 0.5, ctx.player().posY, goingTo.z + 0.5)) > 5) // UGH!!!!!!! - && new Vec3d(ctx.player().motionX, ctx.player().posY < goingTo.y ? Math.max(0, ctx.player().motionY) : ctx.player().motionY, ctx.player().motionZ).length() < Baritone.settings().elytraFireworkSpeed.value // ignore y component if we are BOTH below where we want to be AND descending + && currentSpeed < Baritone.settings().elytraFireworkSpeed.value ) { logDirect("firework"); ctx.playerController().processRightClick(ctx.player(), ctx.world(), EnumHand.MAIN_HAND); From d4e6a84ec96ce5d2043d2a1d5b4ee5d4cee113c3 Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 18 Jun 2023 10:57:13 -0500 Subject: [PATCH 143/405] Remove usage of realms Pair class --- src/api/java/baritone/api/utils/Pair.java | 59 +++++++++++++++++++ .../baritone/behavior/ElytraBehavior.java | 14 ++--- .../java/baritone/utils/PathRenderer.java | 2 +- 3 files changed, 65 insertions(+), 10 deletions(-) create mode 100644 src/api/java/baritone/api/utils/Pair.java diff --git a/src/api/java/baritone/api/utils/Pair.java b/src/api/java/baritone/api/utils/Pair.java new file mode 100644 index 000000000..ca7259520 --- /dev/null +++ b/src/api/java/baritone/api/utils/Pair.java @@ -0,0 +1,59 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.api.utils; + +import java.util.Objects; + +/** + * @author Brady + */ +public final class Pair { + + private final A a; + private final B b; + + public Pair(A a, B b) { + this.a = a; + this.b = b; + } + + public A first() { + return this.a; + } + + public B second() { + return this.b; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || o.getClass() != Pair.class) { + return false; + } + Pair pair = (Pair) o; + return Objects.equals(this.a, pair.a) && Objects.equals(this.b, pair.b); + } + + @Override + public int hashCode() { + return 31 * Objects.hashCode(this.a) + Objects.hashCode(this.b); + } +} diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 8fdcb34f6..6ace0a4e1 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -21,14 +21,10 @@ import baritone.Baritone; import baritone.api.event.events.ChunkEvent; import baritone.api.event.events.TickEvent; import baritone.api.event.events.type.EventState; -import baritone.api.utils.BetterBlockPos; -import baritone.api.utils.Helper; -import baritone.api.utils.Rotation; -import baritone.api.utils.RotationUtils; +import baritone.api.utils.*; import baritone.behavior.elytra.NetherPathfinderContext; import baritone.behavior.elytra.UnpackedSegment; import baritone.utils.BlockStateInterface; -import com.mojang.realmsclient.util.Pair; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.item.EntityFireworkRocket; @@ -381,15 +377,15 @@ public final class ElytraBehavior extends Behavior implements Helper { : relaxation == 0 ? 1.0d : 0.25d; if (isClear(start, dest, grow)) { - Rotation rot = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()); + float yaw = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()).getYaw(); Float pitch = solvePitch(dest.subtract(start), steps, relaxation == 2); if (pitch == null) { - baritone.getLookBehavior().updateTarget(new Rotation(rot.getYaw(), ctx.playerRotations().getPitch()), false); + baritone.getLookBehavior().updateTarget(new Rotation(yaw, ctx.playerRotations().getPitch()), false); continue; } this.pathManager.setGoingTo(i); this.aimPos = path.get(i).add(0, dy, 0); - baritone.getLookBehavior().updateTarget(new Rotation(rot.getYaw(), pitch), false); + baritone.getLookBehavior().updateTarget(new Rotation(yaw, pitch), false); break outermost; } } @@ -456,7 +452,7 @@ public final class ElytraBehavior extends Behavior implements Helper { } private boolean clearView(Vec3d start, Vec3d dest) { - lines.add(Pair.of(start, dest)); + lines.add(new Pair<>(start, dest)); RayTraceResult result = rayTraceBlocks(start, dest); return result == null || result.typeOfHit == RayTraceResult.Type.MISS; } diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index fa8925042..7274f5dbc 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -23,11 +23,11 @@ import baritone.api.event.events.RenderEvent; import baritone.api.pathing.goals.*; import baritone.api.utils.BetterBlockPos; import baritone.api.utils.IPlayerContext; +import baritone.api.utils.Pair; import baritone.api.utils.interfaces.IGoalRenderPos; import baritone.behavior.ElytraBehavior; import baritone.behavior.PathingBehavior; import baritone.pathing.path.PathExecutor; -import com.mojang.realmsclient.util.Pair; import net.minecraft.block.state.IBlockState; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.tileentity.TileEntityBeaconRenderer; From aec683d80f027a61a64e315366d06b6b5f847b89 Mon Sep 17 00:00:00 2001 From: 0x22 <0x22@futureclient.net> Date: Sun, 18 Jun 2023 12:21:01 -0400 Subject: [PATCH 144/405] fast raytrace --- .../baritone/behavior/ElytraBehavior.java | 196 ++++++++++-------- 1 file changed, 107 insertions(+), 89 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 6ace0a4e1..3d396b5e1 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -28,10 +28,9 @@ import baritone.utils.BlockStateInterface; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.item.EntityFireworkRocket; -import net.minecraft.init.Blocks; -import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.math.*; +import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; import java.util.*; @@ -453,8 +452,7 @@ public final class ElytraBehavior extends Behavior implements Helper { private boolean clearView(Vec3d start, Vec3d dest) { lines.add(new Pair<>(start, dest)); - RayTraceResult result = rayTraceBlocks(start, dest); - return result == null || result.typeOfHit == RayTraceResult.Type.MISS; + return !rayTraceBlocks(ctx.world(), start.x, start.y, start.z, dest.x, dest.y, dest.z); } private Float solvePitch(Vec3d goalDirection, int steps, boolean desperate) { @@ -557,98 +555,118 @@ public final class ElytraBehavior extends Behavior implements Helper { return new Vec3d(motionX, motionY, motionZ); } - // TODO: Use the optimized version from builder-2 - private RayTraceResult rayTraceBlocks(Vec3d start, Vec3d end) { - int x1 = MathHelper.floor(end.x); - int y1 = MathHelper.floor(end.y); - int z1 = MathHelper.floor(end.z); - int x2 = MathHelper.floor(start.x); - int y2 = MathHelper.floor(start.y); - int z2 = MathHelper.floor(start.z); - BlockPos blockpos = new BlockPos(x2, y2, z2); - IBlockState iblockstate = ctx.world().getBlockState(blockpos); - if (!passable(iblockstate)) { - return Blocks.SPONGE.getDefaultState().collisionRayTrace(ctx.world(), blockpos, start, end); + private final BlockPos.MutableBlockPos mutableRaytraceBlockPos = new BlockPos.MutableBlockPos(); + + private boolean rayTraceBlocks(final World world, + final double startX, final double startY, final double startZ, + final double endX, final double endY, final double endZ) { + int voxelCurrX = fastFloor(startX); + int voxelCurrY = fastFloor(startY); + int voxelCurrZ = fastFloor(startZ); + + Chunk prevChunk; + IBlockState currentState = (prevChunk = cachedChunk(world, this.mutableRaytraceBlockPos.setPos(voxelCurrX, voxelCurrY, voxelCurrZ), null)).getBlockState(this.mutableRaytraceBlockPos); + + // This is true if player is standing inside of block. + if (!passable(currentState)) { + return true; } - int steps = 200; + + final int voxelEndX = fastFloor(endX); + final int voxelEndY = fastFloor(endY); + final int voxelEndZ = fastFloor(endZ); + double currPosX = startX; + double currPosY = startY; + double currPosZ = startZ; + + int steps = 200; // TODO: should we lower the max steps? while (steps-- >= 0) { - if (Double.isNaN(start.x) || Double.isNaN(start.y) || Double.isNaN(start.z)) { - return null; + if (voxelCurrX == voxelEndX && voxelCurrY == voxelEndY && voxelCurrZ == voxelEndZ) { + return false; } - if (x2 == x1 && y2 == y1 && z2 == z1) { - return null; + + final double distanceFromStartToEndX = endX - currPosX; + final double distanceFromStartToEndY = endY - currPosY; + final double distanceFromStartToEndZ = endZ - currPosZ; + + double nextIntegerX; + double nextIntegerY; + double nextIntegerZ; + // potentially more based branchless impl? + nextIntegerX = voxelCurrX + ((voxelCurrX - voxelEndX) >>> 31); // if voxelEnd > voxelIn, then voxelIn-voxelEnd will be negative, meaning the sign bit is 1 + nextIntegerY = voxelCurrY + ((voxelCurrY - voxelEndY) >>> 31); // if we do an unsigned right shift by 31, that sign bit becomes the LSB + nextIntegerZ = voxelCurrZ + ((voxelCurrZ - voxelEndZ) >>> 31); // therefore, this increments nextInteger iff EndX>inX, otherwise it leaves it alone + // remember: don't have to worry about the case when voxelEnd == voxelIn, because nextInteger value wont be used + + // these just have to be strictly greater than 1, might as well just go up to the next int + double fracIfSkipX = 2.0D; + double fracIfSkipY = 2.0D; + double fracIfSkipZ = 2.0D; + + // reminder to future self: don't "branchlessify" this, it's MUCH slower (pretty obviously, floating point div is much worse than a branch mispredict, but integer increment (like the other two removed branches) are cheap enough to be worth doing either way) + if (voxelEndX != voxelCurrX) { + fracIfSkipX = (nextIntegerX - currPosX) / distanceFromStartToEndX; } - boolean hitX = true; - boolean hitY = true; - boolean hitZ = true; - double nextX = 999.0D; - double nextY = 999.0D; - double nextZ = 999.0D; - if (x1 > x2) { - nextX = (double) x2 + 1.0D; - } else if (x1 < x2) { - nextX = (double) x2 + 0.0D; + if (voxelEndY != voxelCurrY) { + fracIfSkipY = (nextIntegerY - currPosY) / distanceFromStartToEndY; + } + if (voxelEndZ != voxelCurrZ) { + fracIfSkipZ = (nextIntegerZ - currPosZ) / distanceFromStartToEndZ; + } + + if (fracIfSkipX < fracIfSkipY && fracIfSkipX < fracIfSkipZ) { + // note: voxelEndX == voxelInX is impossible because allowSkip would be set to false in that case, meaning that the elapsed distance would stay at default + currPosX = nextIntegerX; + currPosY += distanceFromStartToEndY * fracIfSkipX; + currPosZ += distanceFromStartToEndZ * fracIfSkipX; + // tested: faster to paste this 3 times with only one of the subtractions in each + final int xFloorOffset = (voxelEndX - voxelCurrX) >>> 31; + voxelCurrX = (fastFloor(currPosX) - xFloorOffset); + voxelCurrY = (fastFloor(currPosY)); + voxelCurrZ = (fastFloor(currPosZ)); + } else if (fracIfSkipY < fracIfSkipZ) { + currPosX += distanceFromStartToEndX * fracIfSkipY; + currPosY = nextIntegerY; + currPosZ += distanceFromStartToEndZ * fracIfSkipY; + // tested: faster to paste this 3 times with only one of the subtractions in each + final int yFloorOffset = (voxelEndY - voxelCurrY) >>> 31; + voxelCurrX = (fastFloor(currPosX)); + voxelCurrY = (fastFloor(currPosY) - yFloorOffset); + voxelCurrZ = (fastFloor(currPosZ)); } else { - hitX = false; + currPosX += distanceFromStartToEndX * fracIfSkipZ; + currPosY += distanceFromStartToEndY * fracIfSkipZ; + currPosZ = nextIntegerZ; + // tested: faster to paste this 3 times with only one of the subtractions in each + final int zFloorOffset = (voxelEndZ - voxelCurrZ) >>> 31; + voxelCurrX = (fastFloor(currPosX)); + voxelCurrY = (fastFloor(currPosY)); + voxelCurrZ = (fastFloor(currPosZ) - zFloorOffset); } - if (y1 > y2) { - nextY = (double) y2 + 1.0D; - } else if (y1 < y2) { - nextY = (double) y2 + 0.0D; - } else { - hitY = false; - } - if (z1 > z2) { - nextZ = (double) z2 + 1.0D; - } else if (z1 < z2) { - nextZ = (double) z2 + 0.0D; - } else { - hitZ = false; - } - double stepX = 999.0D; - double stepY = 999.0D; - double stepZ = 999.0D; - double dirX = end.x - start.x; - double dirY = end.y - start.y; - double dirZ = end.z - start.z; - if (hitX) { - stepX = (nextX - start.x) / dirX; - } - if (hitY) { - stepY = (nextY - start.y) / dirY; - } - if (hitZ) { - stepZ = (nextZ - start.z) / dirZ; - } - if (stepX == -0.0D) { - stepX = -1.0E-4D; - } - if (stepY == -0.0D) { - stepY = -1.0E-4D; - } - if (stepZ == -0.0D) { - stepZ = -1.0E-4D; - } - EnumFacing dir; - if (stepX < stepY && stepX < stepZ) { - dir = x1 > x2 ? EnumFacing.WEST : EnumFacing.EAST; - start = new Vec3d(nextX, start.y + dirY * stepX, start.z + dirZ * stepX); - } else if (stepY < stepZ) { - dir = y1 > y2 ? EnumFacing.DOWN : EnumFacing.UP; - start = new Vec3d(start.x + dirX * stepY, nextY, start.z + dirZ * stepY); - } else { - dir = z1 > z2 ? EnumFacing.NORTH : EnumFacing.SOUTH; - start = new Vec3d(start.x + dirX * stepZ, start.y + dirY * stepZ, nextZ); - } - x2 = MathHelper.floor(start.x) - (dir == EnumFacing.EAST ? 1 : 0); - y2 = MathHelper.floor(start.y) - (dir == EnumFacing.UP ? 1 : 0); - z2 = MathHelper.floor(start.z) - (dir == EnumFacing.SOUTH ? 1 : 0); - blockpos = new BlockPos(x2, y2, z2); - IBlockState iblockstate1 = ctx.world().getBlockState(blockpos); - if (!passable(iblockstate1)) { - return Blocks.NETHERRACK.getDefaultState().collisionRayTrace(ctx.world(), blockpos, start, end); + + currentState = (prevChunk = cachedChunk(world, this.mutableRaytraceBlockPos.setPos(voxelCurrX, voxelCurrY, voxelCurrZ), prevChunk)).getBlockState(this.mutableRaytraceBlockPos); + if (!passable(currentState)) { + return true; } } - return null; + return false; + } + + private static final double FLOOR_DOUBLE_D = 1_073_741_824.0; + private static final int FLOOR_DOUBLE_I = 1_073_741_824; + + private static int fastFloor(final double v) { + return ((int) (v + FLOOR_DOUBLE_D)) - FLOOR_DOUBLE_I; + } + + private static Chunk cachedChunk(final World world, + final BlockPos pos, + final Chunk prevLookup) { + final int chunkX = pos.getX() >> 4; + final int chunkZ = pos.getZ() >> 4; + if (prevLookup != null && prevLookup.x == chunkX && prevLookup.z == chunkZ) { + return prevLookup; + } + return world.getChunk(chunkX, chunkZ); } } \ No newline at end of file From 6aeb73b5bd30f74a8f39271e2cd0b4fc96ec3f22 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Sun, 18 Jun 2023 19:18:46 +0200 Subject: [PATCH 145/405] Fix `CylinderMask` with horizontal alignment --- .../api/schematic/mask/shape/CylinderMask.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/api/java/baritone/api/schematic/mask/shape/CylinderMask.java b/src/api/java/baritone/api/schematic/mask/shape/CylinderMask.java index 71b0d43c9..790a9a05d 100644 --- a/src/api/java/baritone/api/schematic/mask/shape/CylinderMask.java +++ b/src/api/java/baritone/api/schematic/mask/shape/CylinderMask.java @@ -35,8 +35,8 @@ public final class CylinderMask extends AbstractMask implements StaticMask { public CylinderMask(int widthX, int heightY, int lengthZ, boolean filled, EnumFacing.Axis alignment) { super(widthX, heightY, lengthZ); - this.centerA = this.getA(widthX, heightY) / 2.0; - this.centerB = this.getB(heightY, lengthZ) / 2.0; + this.centerA = this.getA(widthX, heightY, alignment) / 2.0; + this.centerB = this.getB(heightY, lengthZ, alignment) / 2.0; this.radiusSqA = (this.centerA - 1) * (this.centerA - 1); this.radiusSqB = (this.centerB - 1) * (this.centerB - 1); this.filled = filled; @@ -45,8 +45,8 @@ public final class CylinderMask extends AbstractMask implements StaticMask { @Override public boolean partOfMask(int x, int y, int z) { - double da = Math.abs((this.getA(x, y) + 0.5) - this.centerA); - double db = Math.abs((this.getB(y, z) + 0.5) - this.centerB); + double da = Math.abs((this.getA(x, y, this.alignment) + 0.5) - this.centerA); + double db = Math.abs((this.getB(y, z, this.alignment) + 0.5) - this.centerB); if (this.outside(da, db)) { return false; } @@ -59,11 +59,11 @@ public final class CylinderMask extends AbstractMask implements StaticMask { return da * da / this.radiusSqA + db * db / this.radiusSqB > 1; } - private int getA(int x, int y) { - return this.alignment == EnumFacing.Axis.X ? y : x; + private static int getA(int x, int y, EnumFacing.Axis alignment) { + return alignment == EnumFacing.Axis.X ? y : x; } - private int getB(int y, int z) { - return this.alignment == EnumFacing.Axis.Z ? y : z; + private static int getB(int y, int z, EnumFacing.Axis alignment) { + return alignment == EnumFacing.Axis.Z ? y : z; } } From 68901695cae0aa5b8d40ce6cf07b9e88cfe5efed Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 18 Jun 2023 13:23:41 -0500 Subject: [PATCH 146/405] Add experimental takeoff feature --- src/api/java/baritone/api/Settings.java | 1 + .../baritone/behavior/ElytraBehavior.java | 37 ++++++++++++++----- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 24e54c136..9180c6ad7 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -54,6 +54,7 @@ public final class Settings { public final Setting conserveFireworks = new Setting<>(true); public final Setting renderRaytraces = new Setting<>(false); public final Setting elytraFreeLook = new Setting<>(false); + public final Setting experimentalTakeoff = new Setting<>(false); /** * Allow Baritone to break blocks diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 3d396b5e1..fa15e1678 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -342,6 +342,7 @@ public final class ElytraBehavior extends Behavior implements Helper { final Vec3d start = ctx.playerFeetAsVec(); final boolean firework = isFireworkActive(); + boolean forceUseFirework = false; this.sinceFirework++; outermost: @@ -376,15 +377,18 @@ public final class ElytraBehavior extends Behavior implements Helper { : relaxation == 0 ? 1.0d : 0.25d; if (isClear(start, dest, grow)) { - float yaw = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()).getYaw(); - Float pitch = solvePitch(dest.subtract(start), steps, relaxation == 2); - if (pitch == null) { + final float yaw = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()).getYaw(); + + final Pair pitch = this.solvePitch(dest.subtract(start), steps, relaxation, firework); + if (pitch.first() == null) { baritone.getLookBehavior().updateTarget(new Rotation(yaw, ctx.playerRotations().getPitch()), false); continue; } + forceUseFirework = pitch.second(); + this.pathManager.setGoingTo(i); this.aimPos = path.get(i).add(0, dy, 0); - baritone.getLookBehavior().updateTarget(new Rotation(yaw, pitch), false); + baritone.getLookBehavior().updateTarget(new Rotation(yaw, pitch.first()), false); break outermost; } } @@ -404,13 +408,13 @@ public final class ElytraBehavior extends Behavior implements Helper { ctx.player().motionZ ).length(); - if (!firework + if (forceUseFirework || (!firework && sinceFirework > 10 && useOnDescend && (ctx.player().posY < goingTo.y - 5 || start.distanceTo(new Vec3d(goingTo.x + 0.5, ctx.player().posY, goingTo.z + 0.5)) > 5) // UGH!!!!!!! - && currentSpeed < Baritone.settings().elytraFireworkSpeed.value + && currentSpeed < Baritone.settings().elytraFireworkSpeed.value) ) { - logDirect("firework"); + logDirect("firework" + (forceUseFirework ? " takeoff" : "")); ctx.playerController().processRightClick(ctx.player(), ctx.world(), EnumHand.MAIN_HAND); sinceFirework = 0; } @@ -455,7 +459,23 @@ public final class ElytraBehavior extends Behavior implements Helper { return !rayTraceBlocks(ctx.world(), start.x, start.y, start.z, dest.x, dest.y, dest.z); } - private Float solvePitch(Vec3d goalDirection, int steps, boolean desperate) { + private Pair solvePitch(Vec3d goalDirection, int steps, int relaxation, boolean currentlyBoosted) { + final Float pitch = this.solvePitch(goalDirection, steps, relaxation == 2, currentlyBoosted); + if (pitch != null) { + return new Pair<>(pitch, false); + } + + if (Baritone.settings().experimentalTakeoff.value && relaxation > 0) { + final Float usingFirework = this.solvePitch(goalDirection, steps, relaxation == 2, true); + if (usingFirework != null) { + return new Pair<>(usingFirework, true); + } + } + + return new Pair<>(null, false); + } + + private Float solvePitch(Vec3d goalDirection, int steps, boolean desperate, boolean firework) { // we are at a certain velocity, but we have a target velocity // what pitch would get us closest to our target velocity? // yaw is easy so we only care about pitch @@ -463,7 +483,6 @@ public final class ElytraBehavior extends Behavior implements Helper { goalDirection = goalDirection.normalize(); Rotation good = RotationUtils.calcRotationFromVec3d(new Vec3d(0, 0, 0), goalDirection, ctx.playerRotations()); // lazy lol - boolean firework = isFireworkActive(); Float bestPitch = null; double bestDot = Double.NEGATIVE_INFINITY; Vec3d motion = new Vec3d(ctx.player().motionX, ctx.player().motionY, ctx.player().motionZ); From 5fd915ab8acf41ed379f9f05431ff24a39b96f32 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Sun, 18 Jun 2023 19:50:58 +0200 Subject: [PATCH 147/405] Tab complete the file argument for `#settings load` --- src/main/java/baritone/command/defaults/SetCommand.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/baritone/command/defaults/SetCommand.java b/src/main/java/baritone/command/defaults/SetCommand.java index dd6f1204b..4325cd625 100644 --- a/src/main/java/baritone/command/defaults/SetCommand.java +++ b/src/main/java/baritone/command/defaults/SetCommand.java @@ -22,12 +22,14 @@ import baritone.api.IBaritone; import baritone.api.Settings; import baritone.api.command.Command; import baritone.api.command.argument.IArgConsumer; +import baritone.api.command.datatypes.RelativeFile; import baritone.api.command.exception.CommandException; import baritone.api.command.exception.CommandInvalidStateException; import baritone.api.command.exception.CommandInvalidTypeException; import baritone.api.command.helpers.Paginator; import baritone.api.command.helpers.TabCompleteHelper; import baritone.api.utils.SettingsUtil; +import net.minecraft.client.Minecraft; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextFormatting; @@ -221,6 +223,9 @@ public class SetCommand extends Command { .addToggleableSettings() .filterPrefix(args.getString()) .stream(); + } else if (Arrays.asList("ld", "load").contains(arg.toLowerCase(Locale.US))) { + // settings always use the directory of the main Minecraft instance + return RelativeFile.tabComplete(args, Minecraft.getMinecraft().gameDir.toPath().resolve("baritone").toFile()); } Settings.Setting setting = Baritone.settings().byLowerName.get(arg.toLowerCase(Locale.US)); if (setting != null) { From 8dc32ae03c9866df9d7c6957290c018ad6b66d69 Mon Sep 17 00:00:00 2001 From: rfresh2 <89827146+rfresh2@users.noreply.github.com> Date: Sat, 17 Jun 2023 22:24:10 -0700 Subject: [PATCH 148/405] firework inv management + pause/resume --- src/api/java/baritone/api/IBaritone.java | 7 ++ src/api/java/baritone/api/Settings.java | 8 ++ .../api/behavior/IElytraBehavior.java | 35 ++++++++ .../mixins/MixinEntityFireworkRocket.java | 35 ++++++++ src/launch/resources/mixins.baritone.json | 3 +- src/main/java/baritone/Baritone.java | 1 + .../baritone/behavior/ElytraBehavior.java | 89 +++++++++++++++++-- .../baritone/behavior/InventoryBehavior.java | 16 ++++ .../command/defaults/ElytraCommand.java | 2 +- .../defaults/ExecutionControlCommands.java | 2 + .../utils/accessor/IEntityFireworkRocket.java | 24 +++++ 11 files changed, 215 insertions(+), 7 deletions(-) create mode 100644 src/api/java/baritone/api/behavior/IElytraBehavior.java create mode 100644 src/launch/java/baritone/launch/mixins/MixinEntityFireworkRocket.java create mode 100644 src/main/java/baritone/utils/accessor/IEntityFireworkRocket.java diff --git a/src/api/java/baritone/api/IBaritone.java b/src/api/java/baritone/api/IBaritone.java index 0cc73b0d1..0913a8c43 100644 --- a/src/api/java/baritone/api/IBaritone.java +++ b/src/api/java/baritone/api/IBaritone.java @@ -17,6 +17,7 @@ package baritone.api; +import baritone.api.behavior.IElytraBehavior; import baritone.api.behavior.ILookBehavior; import baritone.api.behavior.IPathingBehavior; import baritone.api.cache.IWorldProvider; @@ -40,6 +41,12 @@ public interface IBaritone { */ IPathingBehavior getPathingBehavior(); + /** + * @return The {@link IElytraBehavior} instance + * @see IElytraBehavior + */ + IElytraBehavior getElytraBehavior(); + /** * @return The {@link ILookBehavior} instance * @see ILookBehavior diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 9180c6ad7..116df04e0 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -50,6 +50,14 @@ public final class Settings { public final Setting elytraSimulationTicks = new Setting<>(20); public final Setting elytraPitchRange = new Setting<>(25); + /** + * Allow users to control firework usage instead of Baritone. e.g. with their own client modules. + */ + public final Setting elytraUseFireworks = new Setting<>(true); + /** + * Allow Baritone to manage fireworks in the inventory and hotbar + */ + public final Setting elytraInventory = new Setting<>(true); public final Setting elytraFireworkSpeed = new Setting<>(0.6); public final Setting conserveFireworks = new Setting<>(true); public final Setting renderRaytraces = new Setting<>(false); diff --git a/src/api/java/baritone/api/behavior/IElytraBehavior.java b/src/api/java/baritone/api/behavior/IElytraBehavior.java new file mode 100644 index 000000000..dc44eacda --- /dev/null +++ b/src/api/java/baritone/api/behavior/IElytraBehavior.java @@ -0,0 +1,35 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.api.behavior; + +public interface IElytraBehavior extends IBehavior { + /** + * Pause the current {@link IElytraBehavior} if it is pathing. + */ + void pause(); + + /** + * Resume the current {@link IElytraBehavior} if it is paused. + */ + void resume(); + + /** + * Returns true if the current {@link IElytraBehavior} is actively pathing and not paused. + */ + boolean isActive(); +} diff --git a/src/launch/java/baritone/launch/mixins/MixinEntityFireworkRocket.java b/src/launch/java/baritone/launch/mixins/MixinEntityFireworkRocket.java new file mode 100644 index 000000000..274e979a0 --- /dev/null +++ b/src/launch/java/baritone/launch/mixins/MixinEntityFireworkRocket.java @@ -0,0 +1,35 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.launch.mixins; + +import baritone.utils.accessor.IEntityFireworkRocket; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.item.EntityFireworkRocket; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(EntityFireworkRocket.class) +public abstract class MixinEntityFireworkRocket implements IEntityFireworkRocket { + @Shadow + private EntityLivingBase boostedEntity; + + @Override + public EntityLivingBase getBoostedEntity() { + return boostedEntity; + } +} diff --git a/src/launch/resources/mixins.baritone.json b/src/launch/resources/mixins.baritone.json index 982736635..5c221de58 100644 --- a/src/launch/resources/mixins.baritone.json +++ b/src/launch/resources/mixins.baritone.json @@ -16,6 +16,7 @@ "MixinChunkProviderServer", "MixinChunkRenderContainer", "MixinChunkRenderWorker", + "MixinEntityFireworkRocket", "MixinEntityLivingBase", "MixinEntityPlayerSP", "MixinEntityRenderer", @@ -34,4 +35,4 @@ "MixinVboRenderList", "MixinWorldClient" ] -} \ No newline at end of file +} diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index 457b49a45..05e1992c9 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -232,6 +232,7 @@ public class Baritone implements IBaritone { return this.commandManager; } + @Override public ElytraBehavior getElytraBehavior() { return this.elytraBehavior; } diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index fa15e1678..3da503066 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -18,6 +18,7 @@ package baritone.behavior; import baritone.Baritone; +import baritone.api.behavior.IElytraBehavior; import baritone.api.event.events.ChunkEvent; import baritone.api.event.events.TickEvent; import baritone.api.event.events.type.EventState; @@ -25,11 +26,19 @@ import baritone.api.utils.*; import baritone.behavior.elytra.NetherPathfinderContext; import baritone.behavior.elytra.UnpackedSegment; import baritone.utils.BlockStateInterface; +import baritone.utils.accessor.IEntityFireworkRocket; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.item.EntityFireworkRocket; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumHand; -import net.minecraft.util.math.*; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; @@ -37,7 +46,7 @@ import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.function.UnaryOperator; -public final class ElytraBehavior extends Behavior implements Helper { +public final class ElytraBehavior extends Behavior implements IElytraBehavior, Helper { /** * 2b2t seed @@ -53,6 +62,7 @@ public final class ElytraBehavior extends Behavior implements Helper { private final NetherPathfinderContext context; private final PathManager pathManager; private int sinceFirework; + private boolean pawsed = false; public ElytraBehavior(Baritone baritone) { super(baritone); @@ -297,6 +307,7 @@ public final class ElytraBehavior extends Behavior implements Helper { } public void path(BlockPos destination) { + pawsed = false; this.pathManager.pathToDestination(destination); } @@ -305,6 +316,23 @@ public final class ElytraBehavior extends Behavior implements Helper { this.pathManager.clear(); this.aimPos = null; this.sinceFirework = 0; + pawsed = false; + } + + public boolean isActive() { + return !this.pathManager.getPath().isEmpty() && !isPaused(); + } + + public void pause() { + this.pawsed = true; + } + + public void resume() { + this.pawsed = false; + } + + public boolean isPaused() { + return this.pawsed; } @Override @@ -312,6 +340,7 @@ public final class ElytraBehavior extends Behavior implements Helper { if (event.getType() == TickEvent.Type.OUT) { return; } + if (isPaused()) return; this.lines.clear(); final List path = this.pathManager.getPath(); @@ -410,20 +439,69 @@ public final class ElytraBehavior extends Behavior implements Helper { if (forceUseFirework || (!firework && sinceFirework > 10 + && Baritone.settings().elytraUseFireworks.value && useOnDescend && (ctx.player().posY < goingTo.y - 5 || start.distanceTo(new Vec3d(goingTo.x + 0.5, ctx.player().posY, goingTo.z + 0.5)) > 5) // UGH!!!!!!! && currentSpeed < Baritone.settings().elytraFireworkSpeed.value) ) { + if (Baritone.settings().elytraInventory.value) { + final int firstFireworksInHotbar = firstFireworksInHotbar(); + if (firstFireworksInHotbar == -1) { + if (!swapToFireworksInInventory()) { + logDirect("no fireworks"); + return; + } + } else { + ctx.player().inventory.currentItem = firstFireworksInHotbar; + } + } logDirect("firework" + (forceUseFirework ? " takeoff" : "")); ctx.playerController().processRightClick(ctx.player(), ctx.world(), EnumHand.MAIN_HAND); sinceFirework = 0; } } + private boolean swapToFireworksInInventory() { + final int i = firstFireworksInInventory(); + if (i != -1) { + baritone.getInventoryBehavior().attemptToPutOnHotbar(i, (slot) -> slot != 7); + ctx.player().inventory.currentItem = 7; + return true; + } + return false; + } + + private int firstFireworksInInventory() { + final NonNullList invy = ctx.player().inventory.mainInventory; + for (int i = 0; i < invy.size(); i++) { + if (isBoostingFireworks(invy.get(i))) { + return i; + } + } + return -1; + } + + private int firstFireworksInHotbar() { + final NonNullList invy = ctx.player().inventory.mainInventory; + for (int i = 0; i < 9; i++) { + if (isBoostingFireworks(invy.get(i))) { + return i; + } + } + return -1; + } + + private boolean isBoostingFireworks(final ItemStack itemStack) { + final NBTTagCompound subCompound = itemStack.getSubCompound("Fireworks"); + return itemStack.getItem() == Items.FIREWORKS + && subCompound != null + && subCompound.hasKey("Flight"); + } + private boolean isFireworkActive() { - // TODO: Validate that the EntityFireworkRocket is attached to ctx.player() return ctx.world().loadedEntityList.stream() - .anyMatch(x -> (x instanceof EntityFireworkRocket) && ((EntityFireworkRocket) x).isAttachedToEntity()); + .filter(x -> x instanceof EntityFireworkRocket) + .anyMatch(x -> Objects.equals(((IEntityFireworkRocket) x).getBoostedEntity(), ctx.player())); } private boolean isClear(final Vec3d start, final Vec3d dest, final Double growAmount) { @@ -688,4 +766,5 @@ public final class ElytraBehavior extends Behavior implements Helper { } return world.getChunk(chunkX, chunkZ); } -} \ No newline at end of file +} + diff --git a/src/main/java/baritone/behavior/InventoryBehavior.java b/src/main/java/baritone/behavior/InventoryBehavior.java index 93dc200cc..5c351adce 100644 --- a/src/main/java/baritone/behavior/InventoryBehavior.java +++ b/src/main/java/baritone/behavior/InventoryBehavior.java @@ -25,8 +25,10 @@ import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.init.Blocks; +import net.minecraft.init.Items; import net.minecraft.inventory.ClickType; import net.minecraft.item.*; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; import net.minecraft.util.NonNullList; @@ -150,6 +152,20 @@ public final class InventoryBehavior extends Behavior implements Helper { return bestInd; } + private int firstFireworks() { + final NonNullList invy = ctx.player().inventory.mainInventory; + for (int i = 0; i < invy.size(); i++) { + final ItemStack itemStack = invy.get(i); + final NBTTagCompound subCompound = itemStack.getSubCompound("Fireworks"); + if (itemStack.getItem() == Items.FIREWORKS + && subCompound != null + && subCompound.hasKey("Flight")) { + return i; + } + } + return -1; + } + public boolean hasGenericThrowaway() { for (Item item : Baritone.settings().acceptableThrowawayItems.value) { if (throwaway(false, stack -> item.equals(stack.getItem()))) { diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index 1c9ee7882..7c101fd3b 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -81,4 +81,4 @@ public class ElytraCommand extends Command { public List getLongDesc() { return Arrays.asList(); } -} \ No newline at end of file +} diff --git a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java index ef566bb8d..6ca324ad7 100644 --- a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java +++ b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java @@ -89,6 +89,7 @@ public class ExecutionControlCommands { throw new CommandInvalidStateException("Already paused"); } paused[0] = true; + baritone.getElytraBehavior().pause(); logDirect("Paused"); } @@ -123,6 +124,7 @@ public class ExecutionControlCommands { throw new CommandInvalidStateException("Not paused"); } paused[0] = false; + baritone.getElytraBehavior().resume(); logDirect("Resumed"); } diff --git a/src/main/java/baritone/utils/accessor/IEntityFireworkRocket.java b/src/main/java/baritone/utils/accessor/IEntityFireworkRocket.java new file mode 100644 index 000000000..86c96acd9 --- /dev/null +++ b/src/main/java/baritone/utils/accessor/IEntityFireworkRocket.java @@ -0,0 +1,24 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.utils.accessor; + +import net.minecraft.entity.EntityLivingBase; + +public interface IEntityFireworkRocket { + EntityLivingBase getBoostedEntity(); +} From 1dbfc9abe39a71063cbcbefa946f3b8cd149feee Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 18 Jun 2023 19:57:29 -0500 Subject: [PATCH 149/405] optimize block lookups and move goingTo to local --- .../baritone/behavior/ElytraBehavior.java | 59 ++++++------------- 1 file changed, 17 insertions(+), 42 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index fa15e1678..c2ef38425 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -30,7 +30,6 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.entity.item.EntityFireworkRocket; import net.minecraft.util.EnumHand; import net.minecraft.util.math.*; -import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; import java.util.*; @@ -69,7 +68,6 @@ public final class ElytraBehavior extends Behavior implements Helper { private boolean completePath; private int playerNear; - private int goingTo; private boolean recalculating; @@ -167,7 +165,6 @@ public final class ElytraBehavior extends Behavior implements Helper { public void clear() { this.path = Collections.emptyList(); this.playerNear = 0; - this.goingTo = 0; this.completePath = true; } @@ -175,7 +172,6 @@ public final class ElytraBehavior extends Behavior implements Helper { this.path = segment.collect(); this.removeBacktracks(); this.playerNear = 0; - this.goingTo = 0; this.completePath = segment.isFinished(); } @@ -187,14 +183,6 @@ public final class ElytraBehavior extends Behavior implements Helper { return this.playerNear; } - public void setGoingTo(int index) { - this.goingTo = index; - } - - public BetterBlockPos goingTo() { - return this.path.get(this.goingTo); - } - // mickey resigned private CompletableFuture path0(BlockPos src, BlockPos dst, UnaryOperator operator) { return ElytraBehavior.this.context.pathFindAsync(src, dst) @@ -319,6 +307,7 @@ public final class ElytraBehavior extends Behavior implements Helper { return; } + this.bsi = new BlockStateInterface(ctx); this.pathManager.tick(); final int playerNear = this.pathManager.getNear(); @@ -342,6 +331,7 @@ public final class ElytraBehavior extends Behavior implements Helper { final Vec3d start = ctx.playerFeetAsVec(); final boolean firework = isFireworkActive(); + BetterBlockPos goingTo = null; boolean forceUseFirework = false; this.sinceFirework++; @@ -354,7 +344,8 @@ public final class ElytraBehavior extends Behavior implements Helper { int minStep = playerNear; for (int i = Math.min(playerNear + 20, path.size() - 1); i >= minStep; i--) { for (int dy : heights) { - Vec3d dest = this.pathManager.pathAt(i).add(0, dy, 0); + final BetterBlockPos pos = path.get(i); + Vec3d dest = new Vec3d(pos).add(0, dy, 0); if (dy != 0) { if (i + lookahead >= path.size()) { continue; @@ -385,9 +376,8 @@ public final class ElytraBehavior extends Behavior implements Helper { continue; } forceUseFirework = pitch.second(); - - this.pathManager.setGoingTo(i); - this.aimPos = path.get(i).add(0, dy, 0); + goingTo = pos; + this.aimPos = goingTo.add(0, dy, 0); baritone.getLookBehavior().updateTarget(new Rotation(yaw, pitch.first()), false); break outermost; } @@ -399,7 +389,6 @@ public final class ElytraBehavior extends Behavior implements Helper { } } - final BetterBlockPos goingTo = this.pathManager.goingTo(); final boolean useOnDescend = !Baritone.settings().conserveFireworks.value || ctx.player().posY < goingTo.y + 5; final double currentSpeed = new Vec3d( ctx.player().motionX, @@ -456,7 +445,7 @@ public final class ElytraBehavior extends Behavior implements Helper { private boolean clearView(Vec3d start, Vec3d dest) { lines.add(new Pair<>(start, dest)); - return !rayTraceBlocks(ctx.world(), start.x, start.y, start.z, dest.x, dest.y, dest.z); + return !rayTraceBlocks(start.x, start.y, start.z, dest.x, dest.y, dest.z); } private Pair solvePitch(Vec3d goalDirection, int steps, int relaxation, boolean currentlyBoosted) { @@ -486,7 +475,6 @@ public final class ElytraBehavior extends Behavior implements Helper { Float bestPitch = null; double bestDot = Double.NEGATIVE_INFINITY; Vec3d motion = new Vec3d(ctx.player().motionX, ctx.player().motionY, ctx.player().motionZ); - BlockStateInterface bsi = new BlockStateInterface(ctx); float minPitch = desperate ? -90 : Math.max(good.getPitch() - Baritone.settings().elytraPitchRange.value, -89); float maxPitch = desperate ? 90 : Math.min(good.getPitch() + Baritone.settings().elytraPitchRange.value, 89); outer: @@ -501,7 +489,7 @@ public final class ElytraBehavior extends Behavior implements Helper { for (int x = MathHelper.floor(Math.min(actualPosition.x, actualPositionPrevTick.x) - 0.31); x <= Math.max(actualPosition.x, actualPositionPrevTick.x) + 0.31; x++) { for (int y = MathHelper.floor(Math.min(actualPosition.y, actualPositionPrevTick.y) - 0.2); y <= Math.max(actualPosition.y, actualPositionPrevTick.y) + 1; y++) { for (int z = MathHelper.floor(Math.min(actualPosition.z, actualPositionPrevTick.z) - 0.31); z <= Math.max(actualPosition.z, actualPositionPrevTick.z) + 0.31; z++) { - if (!passable(bsi.get0(x, y, z))) { + if (!this.passable(x, y, z)) { continue outer; } } @@ -519,6 +507,12 @@ public final class ElytraBehavior extends Behavior implements Helper { return bestPitch; } + private BlockStateInterface bsi; + + public boolean passable(int x, int y, int z) { + return passable(this.bsi.get0(x, y, z)); + } + public static boolean passable(IBlockState state) { return state.getMaterial() == Material.AIR; } @@ -574,20 +568,13 @@ public final class ElytraBehavior extends Behavior implements Helper { return new Vec3d(motionX, motionY, motionZ); } - private final BlockPos.MutableBlockPos mutableRaytraceBlockPos = new BlockPos.MutableBlockPos(); - - private boolean rayTraceBlocks(final World world, - final double startX, final double startY, final double startZ, + private boolean rayTraceBlocks(final double startX, final double startY, final double startZ, final double endX, final double endY, final double endZ) { int voxelCurrX = fastFloor(startX); int voxelCurrY = fastFloor(startY); int voxelCurrZ = fastFloor(startZ); - Chunk prevChunk; - IBlockState currentState = (prevChunk = cachedChunk(world, this.mutableRaytraceBlockPos.setPos(voxelCurrX, voxelCurrY, voxelCurrZ), null)).getBlockState(this.mutableRaytraceBlockPos); - - // This is true if player is standing inside of block. - if (!passable(currentState)) { + if (!this.passable(voxelCurrX, voxelCurrY, voxelCurrZ)) { return true; } @@ -663,8 +650,7 @@ public final class ElytraBehavior extends Behavior implements Helper { voxelCurrZ = (fastFloor(currPosZ) - zFloorOffset); } - currentState = (prevChunk = cachedChunk(world, this.mutableRaytraceBlockPos.setPos(voxelCurrX, voxelCurrY, voxelCurrZ), prevChunk)).getBlockState(this.mutableRaytraceBlockPos); - if (!passable(currentState)) { + if (!this.passable(voxelCurrX, voxelCurrY, voxelCurrZ)) { return true; } } @@ -677,15 +663,4 @@ public final class ElytraBehavior extends Behavior implements Helper { private static int fastFloor(final double v) { return ((int) (v + FLOOR_DOUBLE_D)) - FLOOR_DOUBLE_I; } - - private static Chunk cachedChunk(final World world, - final BlockPos pos, - final Chunk prevLookup) { - final int chunkX = pos.getX() >> 4; - final int chunkZ = pos.getZ() >> 4; - if (prevLookup != null && prevLookup.x == chunkX && prevLookup.z == chunkZ) { - return prevLookup; - } - return world.getChunk(chunkX, chunkZ); - } } \ No newline at end of file From 812be14375df960cc0495fcd62acc30698db0fa6 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 18 Jun 2023 18:06:32 -0700 Subject: [PATCH 150/405] debug --- .../baritone/behavior/ElytraBehavior.java | 129 +++++++++++++++++- .../java/baritone/utils/PathRenderer.java | 14 +- 2 files changed, 134 insertions(+), 9 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index c2ef38425..d0fd210eb 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -28,8 +28,12 @@ import baritone.utils.BlockStateInterface; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.item.EntityFireworkRocket; +import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; -import net.minecraft.util.math.*; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.chunk.Chunk; import java.util.*; @@ -44,7 +48,8 @@ public final class ElytraBehavior extends Behavior implements Helper { private static final long NETHER_SEED = 146008555100680L; // Used exclusively for PathRenderer - public List> lines; + public List> clearLines; + public List> blockedLines; public BlockPos aimPos; public List visiblePath; @@ -56,7 +61,8 @@ public final class ElytraBehavior extends Behavior implements Helper { public ElytraBehavior(Baritone baritone) { super(baritone); this.context = new NetherPathfinderContext(NETHER_SEED); - this.lines = new ArrayList<>(); + this.clearLines = new ArrayList<>(); + this.blockedLines = new ArrayList<>(); this.visiblePath = Collections.emptyList(); this.pathManager = new PathManager(); } @@ -300,7 +306,8 @@ public final class ElytraBehavior extends Behavior implements Helper { if (event.getType() == TickEvent.Type.OUT) { return; } - this.lines.clear(); + this.clearLines.clear(); + this.blockedLines.clear(); final List path = this.pathManager.getPath(); if (path.isEmpty()) { @@ -376,8 +383,12 @@ public final class ElytraBehavior extends Behavior implements Helper { continue; } forceUseFirework = pitch.second(); + logDirect("final dy " + dy); + logDirect("i " + i); + logDirect("playerNear " + playerNear); + logDirect("relaxation " + relaxation); goingTo = pos; - this.aimPos = goingTo.add(0, dy, 0); + this.aimPos = path.get(i).add(0, dy, 0); baritone.getLookBehavior().updateTarget(new Rotation(yaw, pitch.first()), false); break outermost; } @@ -444,8 +455,18 @@ public final class ElytraBehavior extends Behavior implements Helper { } private boolean clearView(Vec3d start, Vec3d dest) { - lines.add(new Pair<>(start, dest)); - return !rayTraceBlocks(start.x, start.y, start.z, dest.x, dest.y, dest.z); + boolean oxy = !rayTraceBlocks(start.x, start.y, start.z, dest.x, dest.y, dest.z); + boolean meow = !rayTraceBlocks(start, dest); + if (oxy != meow) { + logDirect(start + " " + dest + " " + oxy + " " + meow); + } + if (oxy) { + clearLines.add(new Pair<>(start, dest)); + return true; + } else { + blockedLines.add(new Pair<>(start, dest)); + return false; + } } private Pair solvePitch(Vec3d goalDirection, int steps, int relaxation, boolean currentlyBoosted) { @@ -663,4 +684,98 @@ public final class ElytraBehavior extends Behavior implements Helper { private static int fastFloor(final double v) { return ((int) (v + FLOOR_DOUBLE_D)) - FLOOR_DOUBLE_I; } + + private boolean rayTraceBlocks(Vec3d start, Vec3d end) { + int x1 = MathHelper.floor(end.x); + int y1 = MathHelper.floor(end.y); + int z1 = MathHelper.floor(end.z); + int x2 = MathHelper.floor(start.x); + int y2 = MathHelper.floor(start.y); + int z2 = MathHelper.floor(start.z); + BlockPos blockpos = new BlockPos(x2, y2, z2); + IBlockState iblockstate = ctx.world().getBlockState(blockpos); + if (!passable(iblockstate)) { + return true; + } + int steps = 200; + while (steps-- >= 0) { + if (Double.isNaN(start.x) || Double.isNaN(start.y) || Double.isNaN(start.z)) { + return false; + } + if (x2 == x1 && y2 == y1 && z2 == z1) { + return false; + } + boolean hitX = true; + boolean hitY = true; + boolean hitZ = true; + double nextX = 999.0D; + double nextY = 999.0D; + double nextZ = 999.0D; + if (x1 > x2) { + nextX = (double) x2 + 1.0D; + } else if (x1 < x2) { + nextX = (double) x2 + 0.0D; + } else { + hitX = false; + } + if (y1 > y2) { + nextY = (double) y2 + 1.0D; + } else if (y1 < y2) { + nextY = (double) y2 + 0.0D; + } else { + hitY = false; + } + if (z1 > z2) { + nextZ = (double) z2 + 1.0D; + } else if (z1 < z2) { + nextZ = (double) z2 + 0.0D; + } else { + hitZ = false; + } + double stepX = 999.0D; + double stepY = 999.0D; + double stepZ = 999.0D; + double dirX = end.x - start.x; + double dirY = end.y - start.y; + double dirZ = end.z - start.z; + if (hitX) { + stepX = (nextX - start.x) / dirX; + } + if (hitY) { + stepY = (nextY - start.y) / dirY; + } + if (hitZ) { + stepZ = (nextZ - start.z) / dirZ; + } + if (stepX == -0.0D) { + stepX = -1.0E-4D; + } + if (stepY == -0.0D) { + stepY = -1.0E-4D; + } + if (stepZ == -0.0D) { + stepZ = -1.0E-4D; + } + EnumFacing dir; + if (stepX < stepY && stepX < stepZ) { + dir = x1 > x2 ? EnumFacing.WEST : EnumFacing.EAST; + start = new Vec3d(nextX, start.y + dirY * stepX, start.z + dirZ * stepX); + } else if (stepY < stepZ) { + dir = y1 > y2 ? EnumFacing.DOWN : EnumFacing.UP; + start = new Vec3d(start.x + dirX * stepY, nextY, start.z + dirZ * stepY); + } else { + dir = z1 > z2 ? EnumFacing.NORTH : EnumFacing.SOUTH; + start = new Vec3d(start.x + dirX * stepZ, start.y + dirY * stepZ, nextZ); + } + x2 = MathHelper.floor(start.x) - (dir == EnumFacing.EAST ? 1 : 0); + y2 = MathHelper.floor(start.y) - (dir == EnumFacing.UP ? 1 : 0); + z2 = MathHelper.floor(start.z) - (dir == EnumFacing.SOUTH ? 1 : 0); + blockpos = new BlockPos(x2, y2, z2); + IBlockState iblockstate1 = ctx.world().getBlockState(blockpos); + if (!passable(iblockstate1)) { + return true; + } + } + return false; + } } \ No newline at end of file diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index 7274f5dbc..d608d4a2b 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -108,11 +108,21 @@ public final class PathRenderer implements IRenderer { if (elytra.aimPos != null) { drawGoal(ctx.player(), new GoalBlock(elytra.aimPos), partialTicks, Color.GREEN); } - if (!elytra.lines.isEmpty() && Baritone.settings().renderRaytraces.value) { + if (!elytra.clearLines.isEmpty() && Baritone.settings().renderRaytraces.value) { + IRenderer.startLines(Color.GREEN, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); + boolean orig = settings.renderPathAsLine.value; + settings.renderPathAsLine.value = true; + for (Pair line : elytra.clearLines) { + emitLine(line.first().x, line.first().y, line.first().z, line.second().x, line.second().y, line.second().z); + } + settings.renderPathAsLine.value = orig; + IRenderer.endLines(settings.renderPathIgnoreDepth.value); + } + if (!elytra.blockedLines.isEmpty() && Baritone.settings().renderRaytraces.value) { IRenderer.startLines(Color.BLUE, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); boolean orig = settings.renderPathAsLine.value; settings.renderPathAsLine.value = true; - for (Pair line : elytra.lines) { + for (Pair line : elytra.blockedLines) { emitLine(line.first().x, line.first().y, line.first().z, line.second().x, line.second().y, line.second().z); } settings.renderPathAsLine.value = orig; From a236031435d3c6d8c528c583da08df7372929cf7 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 18 Jun 2023 18:09:45 -0700 Subject: [PATCH 151/405] fix raytracer --- src/main/java/baritone/behavior/ElytraBehavior.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index d0fd210eb..3d3d4843c 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -455,7 +455,7 @@ public final class ElytraBehavior extends Behavior implements Helper { } private boolean clearView(Vec3d start, Vec3d dest) { - boolean oxy = !rayTraceBlocks(start.x, start.y, start.z, dest.x, dest.y, dest.z); + boolean oxy = !rayTraceBlocks(start.x + 0.0001 * Math.random(), start.y + 0.0001 * Math.random(), start.z + 0.0001 * Math.random(), dest.x + 0.0001 * Math.random(), dest.y + 0.0001 * Math.random(), dest.z + 0.0001 * Math.random()); boolean meow = !rayTraceBlocks(start, dest); if (oxy != meow) { logDirect(start + " " + dest + " " + oxy + " " + meow); From efae476bc028f04dbe01d9b99e4adfaeade003c1 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 18 Jun 2023 18:16:13 -0700 Subject: [PATCH 152/405] solved --- src/main/java/baritone/behavior/ElytraBehavior.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 3d3d4843c..97dc24102 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -162,9 +162,9 @@ public final class ElytraBehavior extends Behavior implements Helper { private Vec3d pathAt(int i) { return new Vec3d( - this.path.get(i).x, - this.path.get(i).y, - this.path.get(i).z + this.path.get(i).x + 0.000123, + this.path.get(i).y + 0.000456, + this.path.get(i).z + 0.000789 ); } @@ -351,8 +351,7 @@ public final class ElytraBehavior extends Behavior implements Helper { int minStep = playerNear; for (int i = Math.min(playerNear + 20, path.size() - 1); i >= minStep; i--) { for (int dy : heights) { - final BetterBlockPos pos = path.get(i); - Vec3d dest = new Vec3d(pos).add(0, dy, 0); + Vec3d dest = this.pathManager.pathAt(i).add(0, dy, 0); if (dy != 0) { if (i + lookahead >= path.size()) { continue; @@ -387,7 +386,7 @@ public final class ElytraBehavior extends Behavior implements Helper { logDirect("i " + i); logDirect("playerNear " + playerNear); logDirect("relaxation " + relaxation); - goingTo = pos; + goingTo = path.get(i); this.aimPos = path.get(i).add(0, dy, 0); baritone.getLookBehavior().updateTarget(new Rotation(yaw, pitch.first()), false); break outermost; @@ -455,7 +454,7 @@ public final class ElytraBehavior extends Behavior implements Helper { } private boolean clearView(Vec3d start, Vec3d dest) { - boolean oxy = !rayTraceBlocks(start.x + 0.0001 * Math.random(), start.y + 0.0001 * Math.random(), start.z + 0.0001 * Math.random(), dest.x + 0.0001 * Math.random(), dest.y + 0.0001 * Math.random(), dest.z + 0.0001 * Math.random()); + boolean oxy = !rayTraceBlocks(start.x, start.y, start.z, dest.x, dest.y, dest.z); boolean meow = !rayTraceBlocks(start, dest); if (oxy != meow) { logDirect(start + " " + dest + " " + oxy + " " + meow); From 1837b66bb5153e14ad46cc7269fb3e6c70367bd0 Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 18 Jun 2023 21:24:13 -0500 Subject: [PATCH 153/405] Add `BlockChangeEvent` Moves the cache repack on block change functionality into `GameEventHandler` --- .../java/baritone/api/IBaritoneProvider.java | 17 +++ .../api/event/events/BlockChangeEvent.java | 49 +++++++ .../baritone/api/event/events/ChunkEvent.java | 15 +- .../listener/AbstractGameEventListener.java | 3 + .../event/listener/IGameEventListener.java | 7 + .../mixins/MixinNetHandlerPlayClient.java | 128 +++++++----------- .../java/baritone/event/GameEventHandler.java | 30 +++- 7 files changed, 164 insertions(+), 85 deletions(-) create mode 100644 src/api/java/baritone/api/event/events/BlockChangeEvent.java diff --git a/src/api/java/baritone/api/IBaritoneProvider.java b/src/api/java/baritone/api/IBaritoneProvider.java index 55d208e03..cf816b40f 100644 --- a/src/api/java/baritone/api/IBaritoneProvider.java +++ b/src/api/java/baritone/api/IBaritoneProvider.java @@ -23,6 +23,7 @@ import baritone.api.command.ICommandSystem; import baritone.api.schematic.ISchematicSystem; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.client.network.NetHandlerPlayClient; import java.util.List; import java.util.Objects; @@ -82,6 +83,22 @@ public interface IBaritoneProvider { return null; } + /** + * Provides the {@link IBaritone} instance for the player with the specified connection. + * + * @param connection The connection + * @return The {@link IBaritone} instance. + */ + default IBaritone getBaritoneForConnection(NetHandlerPlayClient connection) { + for (IBaritone baritone : this.getAllBaritones()) { + final EntityPlayerSP player = baritone.getPlayerContext().player(); + if (player != null && player.connection == connection) { + return baritone; + } + } + return null; + } + /** * Creates and registers a new {@link IBaritone} instance using the specified {@link Minecraft}. The existing * instance is returned if already registered. diff --git a/src/api/java/baritone/api/event/events/BlockChangeEvent.java b/src/api/java/baritone/api/event/events/BlockChangeEvent.java new file mode 100644 index 000000000..152c435ae --- /dev/null +++ b/src/api/java/baritone/api/event/events/BlockChangeEvent.java @@ -0,0 +1,49 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.api.event.events; + +import baritone.api.utils.Pair; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; + +import java.util.Collections; +import java.util.List; +import java.util.Set; + +/** + * @author Brady + */ +public final class BlockChangeEvent { + + private final Set affectedChunks; + private final List> blocks; + + public BlockChangeEvent(ChunkPos pos, List> blocks) { + this.affectedChunks = Collections.singleton(pos); + this.blocks = blocks; + } + + public Set getAffectedChunks() { + return this.affectedChunks; + } + + public List> getBlocks() { + return this.blocks; + } +} diff --git a/src/api/java/baritone/api/event/events/ChunkEvent.java b/src/api/java/baritone/api/event/events/ChunkEvent.java index a7b5d96f0..bb22a47b1 100644 --- a/src/api/java/baritone/api/event/events/ChunkEvent.java +++ b/src/api/java/baritone/api/event/events/ChunkEvent.java @@ -57,31 +57,38 @@ public final class ChunkEvent { /** * @return The state of the event */ - public final EventState getState() { + public EventState getState() { return this.state; } /** * @return The type of chunk event that occurred; */ - public final Type getType() { + public Type getType() { return this.type; } /** * @return The Chunk X position. */ - public final int getX() { + public int getX() { return this.x; } /** * @return The Chunk Z position. */ - public final int getZ() { + public int getZ() { return this.z; } + /** + * @return {@code true} if the event was fired after a chunk population + */ + public boolean isPostPopulate() { + return this.state == EventState.POST && this.type.isPopulate(); + } + public enum Type { /** diff --git a/src/api/java/baritone/api/event/listener/AbstractGameEventListener.java b/src/api/java/baritone/api/event/listener/AbstractGameEventListener.java index 9eac8de46..64ae0c16e 100644 --- a/src/api/java/baritone/api/event/listener/AbstractGameEventListener.java +++ b/src/api/java/baritone/api/event/listener/AbstractGameEventListener.java @@ -45,6 +45,9 @@ public interface AbstractGameEventListener extends IGameEventListener { @Override default void onChunkEvent(ChunkEvent event) {} + @Override + default void onBlockChange(BlockChangeEvent event) {} + @Override default void onRenderPass(RenderEvent event) {} diff --git a/src/api/java/baritone/api/event/listener/IGameEventListener.java b/src/api/java/baritone/api/event/listener/IGameEventListener.java index b074e978b..71e9521ad 100644 --- a/src/api/java/baritone/api/event/listener/IGameEventListener.java +++ b/src/api/java/baritone/api/event/listener/IGameEventListener.java @@ -72,6 +72,13 @@ public interface IGameEventListener { */ void onChunkEvent(ChunkEvent event); + /** + * Runs after a single or multi block change packet is received and processed. + * + * @param event The event + */ + void onBlockChange(BlockChangeEvent event); + /** * Runs once per world render pass. Two passes are made when {@link GameSettings#anaglyph} is on. *

diff --git a/src/launch/java/baritone/launch/mixins/MixinNetHandlerPlayClient.java b/src/launch/java/baritone/launch/mixins/MixinNetHandlerPlayClient.java index f1c1f7972..cdbeffc6c 100644 --- a/src/launch/java/baritone/launch/mixins/MixinNetHandlerPlayClient.java +++ b/src/launch/java/baritone/launch/mixins/MixinNetHandlerPlayClient.java @@ -17,24 +17,29 @@ package baritone.launch.mixins; -import baritone.Baritone; import baritone.api.BaritoneAPI; import baritone.api.IBaritone; +import baritone.api.event.events.BlockChangeEvent; import baritone.api.event.events.ChunkEvent; import baritone.api.event.events.type.EventState; -import baritone.cache.CachedChunk; -import net.minecraft.client.entity.EntityPlayerSP; +import baritone.api.utils.Pair; +import net.minecraft.block.state.IBlockState; import net.minecraft.client.network.NetHandlerPlayClient; import net.minecraft.network.play.server.SPacketBlockChange; import net.minecraft.network.play.server.SPacketChunkData; import net.minecraft.network.play.server.SPacketCombatEvent; import net.minecraft.network.play.server.SPacketMultiBlockChange; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkPos; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import java.util.Arrays; +import java.util.Collections; +import java.util.stream.Collectors; + /** * @author Brady * @since 8/3/2018 @@ -50,19 +55,18 @@ public class MixinNetHandlerPlayClient { ) ) private void preRead(SPacketChunkData packetIn, CallbackInfo ci) { - for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) { - EntityPlayerSP player = ibaritone.getPlayerContext().player(); - if (player != null && player.connection == (NetHandlerPlayClient) (Object) this) { - ibaritone.getGameEventHandler().onChunkEvent( - new ChunkEvent( - EventState.PRE, - packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL, - packetIn.getChunkX(), - packetIn.getChunkZ() - ) - ); - } + IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this); + if (baritone == null) { + return; } + baritone.getGameEventHandler().onChunkEvent( + new ChunkEvent( + EventState.PRE, + packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL, + packetIn.getChunkX(), + packetIn.getChunkZ() + ) + ); } @Inject( @@ -70,19 +74,18 @@ public class MixinNetHandlerPlayClient { at = @At("RETURN") ) private void postHandleChunkData(SPacketChunkData packetIn, CallbackInfo ci) { - for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) { - EntityPlayerSP player = ibaritone.getPlayerContext().player(); - if (player != null && player.connection == (NetHandlerPlayClient) (Object) this) { - ibaritone.getGameEventHandler().onChunkEvent( - new ChunkEvent( - EventState.POST, - packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL, - packetIn.getChunkX(), - packetIn.getChunkZ() - ) - ); - } + IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this); + if (baritone == null) { + return; } + baritone.getGameEventHandler().onChunkEvent( + new ChunkEvent( + EventState.POST, + packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL, + packetIn.getChunkX(), + packetIn.getChunkZ() + ) + ); } @Inject( @@ -90,25 +93,14 @@ public class MixinNetHandlerPlayClient { at = @At("RETURN") ) private void postHandleBlockChange(SPacketBlockChange packetIn, CallbackInfo ci) { - if (!Baritone.settings().repackOnAnyBlockChange.value) { + IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this); + if (baritone == null) { return; } - if (!CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(packetIn.getBlockState().getBlock())) { - return; - } - for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) { - EntityPlayerSP player = ibaritone.getPlayerContext().player(); - if (player != null && player.connection == (NetHandlerPlayClient) (Object) this) { - ibaritone.getGameEventHandler().onChunkEvent( - new ChunkEvent( - EventState.POST, - ChunkEvent.Type.POPULATE_FULL, - packetIn.getBlockPosition().getX() >> 4, - packetIn.getBlockPosition().getZ() >> 4 - ) - ); - } - } + + final ChunkPos pos = new ChunkPos(packetIn.getBlockPosition().getX() >> 4, packetIn.getBlockPosition().getZ() >> 4); + final Pair changed = new Pair<>(packetIn.getBlockPosition(), packetIn.getBlockState()); + baritone.getGameEventHandler().onBlockChange(new BlockChangeEvent(pos, Collections.singletonList(changed))); } @Inject( @@ -116,35 +108,20 @@ public class MixinNetHandlerPlayClient { at = @At("RETURN") ) private void postHandleMultiBlockChange(SPacketMultiBlockChange packetIn, CallbackInfo ci) { - if (!Baritone.settings().repackOnAnyBlockChange.value) { + IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this); + if (baritone == null) { return; } - if (packetIn.getChangedBlocks().length == 0) { - return; - } - https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.15 - { - for (SPacketMultiBlockChange.BlockUpdateData update : packetIn.getChangedBlocks()) { - if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(update.getBlockState().getBlock())) { - break https; - } - } - return; - } - ChunkPos pos = new ChunkPos(packetIn.getChangedBlocks()[0].getPos()); - for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) { - EntityPlayerSP player = ibaritone.getPlayerContext().player(); - if (player != null && player.connection == (NetHandlerPlayClient) (Object) this) { - ibaritone.getGameEventHandler().onChunkEvent( - new ChunkEvent( - EventState.POST, - ChunkEvent.Type.POPULATE_FULL, - pos.x, - pos.z - ) - ); - } - } + + // All blocks have the same ChunkPos + final ChunkPos pos = new ChunkPos(packetIn.getChangedBlocks()[0].getPos()); + + baritone.getGameEventHandler().onBlockChange(new BlockChangeEvent( + pos, + Arrays.stream(packetIn.getChangedBlocks()) + .map(data -> new Pair<>(data.getPos(), data.getBlockState())) + .collect(Collectors.toList()) + )); } @Inject( @@ -155,11 +132,10 @@ public class MixinNetHandlerPlayClient { ) ) private void onPlayerDeath(SPacketCombatEvent packetIn, CallbackInfo ci) { - for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) { - EntityPlayerSP player = ibaritone.getPlayerContext().player(); - if (player != null && player.connection == (NetHandlerPlayClient) (Object) this) { - ibaritone.getGameEventHandler().onPlayerDeath(); - } + IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this); + if (baritone == null) { + return; } + baritone.getGameEventHandler().onPlayerDeath(); } } diff --git a/src/main/java/baritone/event/GameEventHandler.java b/src/main/java/baritone/event/GameEventHandler.java index 0b46eb5e1..ceb05e739 100644 --- a/src/main/java/baritone/event/GameEventHandler.java +++ b/src/main/java/baritone/event/GameEventHandler.java @@ -23,8 +23,11 @@ import baritone.api.event.events.type.EventState; import baritone.api.event.listener.IEventBus; import baritone.api.event.listener.IGameEventListener; import baritone.api.utils.Helper; +import baritone.api.utils.Pair; +import baritone.cache.CachedChunk; import baritone.cache.WorldProvider; import baritone.utils.BlockStateInterface; +import net.minecraft.block.state.IBlockState; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; @@ -75,13 +78,10 @@ public final class GameEventHandler implements IEventBus, Helper { } @Override - public final void onChunkEvent(ChunkEvent event) { + public void onChunkEvent(ChunkEvent event) { EventState state = event.getState(); ChunkEvent.Type type = event.getType(); - boolean isPostPopulate = state == EventState.POST - && (type == ChunkEvent.Type.POPULATE_FULL || type == ChunkEvent.Type.POPULATE_PARTIAL); - World world = baritone.getPlayerContext().world(); // Whenever the server sends us to another dimension, chunks are unloaded @@ -91,7 +91,7 @@ public final class GameEventHandler implements IEventBus, Helper { && type == ChunkEvent.Type.UNLOAD && world.getChunkProvider().isChunkGeneratedAt(event.getX(), event.getZ()); - if (isPostPopulate || isPreUnload) { + if (event.isPostPopulate() || isPreUnload) { baritone.getWorldProvider().ifWorldLoaded(worldData -> { Chunk chunk = world.getChunk(event.getX(), event.getZ()); worldData.getCachedWorld().queueForPacking(chunk); @@ -102,6 +102,26 @@ public final class GameEventHandler implements IEventBus, Helper { listeners.forEach(l -> l.onChunkEvent(event)); } + @Override + public void onBlockChange(BlockChangeEvent event) { + if (Baritone.settings().repackOnAnyBlockChange.value) { + final boolean keepingTrackOf = event.getBlocks().stream() + .map(Pair::second).map(IBlockState::getBlock) + .anyMatch(CachedChunk.BLOCKS_TO_KEEP_TRACK_OF::contains); + + if (keepingTrackOf) { + baritone.getWorldProvider().ifWorldLoaded(worldData -> { + final World world = baritone.getPlayerContext().world(); + event.getAffectedChunks().stream() + .map(pos -> world.getChunk(pos.x, pos.z)) + .forEach(worldData.getCachedWorld()::queueForPacking); + }); + } + } + + listeners.forEach(l -> l.onBlockChange(event)); + } + @Override public final void onRenderPass(RenderEvent event) { listeners.forEach(l -> l.onRenderPass(event)); From 9808f62fe4c004fd865970b4a1cfdf8f2cbadfe7 Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 18 Jun 2023 21:25:00 -0500 Subject: [PATCH 154/405] Send chunks to nether-pathfinder on `BlockUpdateEvent` --- .../java/baritone/behavior/ElytraBehavior.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 97dc24102..6260b42bf 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -18,9 +18,9 @@ package baritone.behavior; import baritone.Baritone; +import baritone.api.event.events.BlockChangeEvent; import baritone.api.event.events.ChunkEvent; import baritone.api.event.events.TickEvent; -import baritone.api.event.events.type.EventState; import baritone.api.utils.*; import baritone.behavior.elytra.NetherPathfinderContext; import baritone.behavior.elytra.UnpackedSegment; @@ -284,12 +284,19 @@ public final class ElytraBehavior extends Behavior implements Helper { @Override public void onChunkEvent(ChunkEvent event) { - if (event.getState() == EventState.POST && event.getType().isPopulate()) { + if (event.isPostPopulate()) { final Chunk chunk = ctx.world().getChunk(event.getX(), event.getZ()); this.context.queueForPacking(chunk); } } + @Override + public void onBlockChange(BlockChangeEvent event) { + event.getAffectedChunks().stream() + .map(pos -> ctx.world().getChunk(pos.x, pos.z)) + .forEach(this.context::queueForPacking); + } + public void path(BlockPos destination) { this.pathManager.pathToDestination(destination); } @@ -382,10 +389,6 @@ public final class ElytraBehavior extends Behavior implements Helper { continue; } forceUseFirework = pitch.second(); - logDirect("final dy " + dy); - logDirect("i " + i); - logDirect("playerNear " + playerNear); - logDirect("relaxation " + relaxation); goingTo = path.get(i); this.aimPos = path.get(i).add(0, dy, 0); baritone.getLookBehavior().updateTarget(new Rotation(yaw, pitch.first()), false); From 6c8f2698d697c3ffaca7022f29644c6317435494 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 18 Jun 2023 19:31:51 -0700 Subject: [PATCH 155/405] cherry pick remainWithExistingLookDirection from fork --- src/api/java/baritone/api/Settings.java | 6 ++++++ src/api/java/baritone/api/utils/RotationUtils.java | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index bcd3eaa63..824dfd7e2 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -729,6 +729,12 @@ public final class Settings { */ public final Setting blockFreeLook = new Setting<>(false); + /** + * When true, the player will remain with its existing look direction as often as possible. + * Although, in some cases this can get it stuck, hence this setting to disable that behavior. + */ + public final Setting remainWithExistingLookDirection = new Setting<>(true); + /** * Will cause some minor behavioral differences to ensure that Baritone works on anticheats. *

diff --git a/src/api/java/baritone/api/utils/RotationUtils.java b/src/api/java/baritone/api/utils/RotationUtils.java index 1991ab878..b3b67d9ca 100644 --- a/src/api/java/baritone/api/utils/RotationUtils.java +++ b/src/api/java/baritone/api/utils/RotationUtils.java @@ -161,7 +161,7 @@ public final class RotationUtils { } public static Optional reachable(IPlayerContext ctx, BlockPos pos, double blockReachDistance, boolean wouldSneak) { - if (ctx.isLookingAt(pos)) { + if (BaritoneAPI.getSettings().remainWithExistingLookDirection.value && ctx.isLookingAt(pos)) { /* * why add 0.0001? * to indicate that we actually have a desired pitch From 7a8f8e8d47b8703c588d11e96771fe158f314f45 Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 18 Jun 2023 21:42:04 -0500 Subject: [PATCH 156/405] fix noob error from resolving merge conflicts --- src/main/java/baritone/behavior/ElytraBehavior.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 200ca48cb..77f414776 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -340,7 +340,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return; } if (isPaused()) return; - this.lines.clear(); this.clearLines.clear(); this.blockedLines.clear(); From 0886f176b3280e0bbb902c265c3d3e4ef160b488 Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 18 Jun 2023 21:46:03 -0500 Subject: [PATCH 157/405] Make elytra API changes --- .../api/behavior/IElytraBehavior.java | 17 ++++++------- .../baritone/behavior/ElytraBehavior.java | 25 ++++++------------- .../command/defaults/ElytraCommand.java | 2 +- .../defaults/ExecutionControlCommands.java | 2 -- 4 files changed, 15 insertions(+), 31 deletions(-) diff --git a/src/api/java/baritone/api/behavior/IElytraBehavior.java b/src/api/java/baritone/api/behavior/IElytraBehavior.java index dc44eacda..3c3b91466 100644 --- a/src/api/java/baritone/api/behavior/IElytraBehavior.java +++ b/src/api/java/baritone/api/behavior/IElytraBehavior.java @@ -17,19 +17,16 @@ package baritone.api.behavior; +import net.minecraft.util.math.BlockPos; + public interface IElytraBehavior extends IBehavior { - /** - * Pause the current {@link IElytraBehavior} if it is pathing. - */ - void pause(); + + void pathTo(BlockPos destination); + + void cancel(); /** - * Resume the current {@link IElytraBehavior} if it is paused. - */ - void resume(); - - /** - * Returns true if the current {@link IElytraBehavior} is actively pathing and not paused. + * Returns {@code true} if the current {@link IElytraBehavior} is actively pathing. */ boolean isActive(); } diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 77f414776..12723a001 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -64,7 +64,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private final NetherPathfinderContext context; private final PathManager pathManager; private int sinceFirework; - private boolean pawsed = false; public ElytraBehavior(Baritone baritone) { super(baritone); @@ -180,6 +179,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.path = Collections.emptyList(); this.playerNear = 0; this.completePath = true; + this.destination = null; } private void setPath(final UnpackedSegment segment) { @@ -305,33 +305,22 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H .forEach(this.context::queueForPacking); } - public void path(BlockPos destination) { - pawsed = false; + @Override + public void pathTo(BlockPos destination) { this.pathManager.pathToDestination(destination); } + @Override public void cancel() { this.visiblePath = Collections.emptyList(); this.pathManager.clear(); this.aimPos = null; this.sinceFirework = 0; - pawsed = false; } + @Override public boolean isActive() { - return !this.pathManager.getPath().isEmpty() && !isPaused(); - } - - public void pause() { - this.pawsed = true; - } - - public void resume() { - this.pawsed = false; - } - - public boolean isPaused() { - return this.pawsed; + return !this.pathManager.getPath().isEmpty(); } @Override @@ -339,7 +328,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H if (event.getType() == TickEvent.Type.OUT) { return; } - if (isPaused()) return; + this.clearLines.clear(); this.blockedLines.clear(); diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index 7c101fd3b..f96901b9b 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -64,7 +64,7 @@ public class ElytraCommand extends Command { if (y <= 0 || y >= 128) { throw new CommandInvalidStateException("The y of the goal is not between 0 and 128"); } - ((Baritone) baritone).getElytraBehavior().path(new BlockPos(x, y, z)); + ((Baritone) baritone).getElytraBehavior().pathTo(new BlockPos(x, y, z)); } @Override diff --git a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java index 6ca324ad7..ef566bb8d 100644 --- a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java +++ b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java @@ -89,7 +89,6 @@ public class ExecutionControlCommands { throw new CommandInvalidStateException("Already paused"); } paused[0] = true; - baritone.getElytraBehavior().pause(); logDirect("Paused"); } @@ -124,7 +123,6 @@ public class ExecutionControlCommands { throw new CommandInvalidStateException("Not paused"); } paused[0] = false; - baritone.getElytraBehavior().resume(); logDirect("Resumed"); } From 1257a0128cdcd95637b33c75c9baccd34ceac216 Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 18 Jun 2023 21:46:56 -0500 Subject: [PATCH 158/405] Remove unnecessary `Baritone` casts --- src/main/java/baritone/command/defaults/ElytraCommand.java | 2 +- .../baritone/command/defaults/ExecutionControlCommands.java | 2 +- src/main/java/baritone/command/defaults/ForceCancelCommand.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index f96901b9b..3414c7bb3 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -64,7 +64,7 @@ public class ElytraCommand extends Command { if (y <= 0 || y >= 128) { throw new CommandInvalidStateException("The y of the goal is not between 0 and 128"); } - ((Baritone) baritone).getElytraBehavior().pathTo(new BlockPos(x, y, z)); + baritone.getElytraBehavior().pathTo(new BlockPos(x, y, z)); } @Override diff --git a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java index ef566bb8d..e7f7c9497 100644 --- a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java +++ b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java @@ -181,7 +181,7 @@ public class ExecutionControlCommands { paused[0] = false; } baritone.getPathingBehavior().cancelEverything(); - ((Baritone) baritone).getElytraBehavior().cancel(); + baritone.getElytraBehavior().cancel(); logDirect("ok canceled"); } diff --git a/src/main/java/baritone/command/defaults/ForceCancelCommand.java b/src/main/java/baritone/command/defaults/ForceCancelCommand.java index 60ccdab01..bc6dbd0a4 100644 --- a/src/main/java/baritone/command/defaults/ForceCancelCommand.java +++ b/src/main/java/baritone/command/defaults/ForceCancelCommand.java @@ -40,7 +40,7 @@ public class ForceCancelCommand extends Command { IPathingBehavior pathingBehavior = baritone.getPathingBehavior(); pathingBehavior.cancelEverything(); pathingBehavior.forceCancel(); - ((Baritone) baritone).getElytraBehavior().cancel(); + baritone.getElytraBehavior().cancel(); logDirect("ok force canceled"); } From 1da7ab2c2229373d1f4ba1bcb0cb70248961eb7e Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 18 Jun 2023 23:58:20 -0500 Subject: [PATCH 159/405] Fix raytracer rendering --- src/main/java/baritone/utils/PathRenderer.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index d608d4a2b..5898ce643 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -110,22 +110,16 @@ public final class PathRenderer implements IRenderer { } if (!elytra.clearLines.isEmpty() && Baritone.settings().renderRaytraces.value) { IRenderer.startLines(Color.GREEN, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); - boolean orig = settings.renderPathAsLine.value; - settings.renderPathAsLine.value = true; for (Pair line : elytra.clearLines) { emitLine(line.first().x, line.first().y, line.first().z, line.second().x, line.second().y, line.second().z); } - settings.renderPathAsLine.value = orig; IRenderer.endLines(settings.renderPathIgnoreDepth.value); } if (!elytra.blockedLines.isEmpty() && Baritone.settings().renderRaytraces.value) { IRenderer.startLines(Color.BLUE, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); - boolean orig = settings.renderPathAsLine.value; - settings.renderPathAsLine.value = true; for (Pair line : elytra.blockedLines) { emitLine(line.first().x, line.first().y, line.first().z, line.second().x, line.second().y, line.second().z); } - settings.renderPathAsLine.value = orig; IRenderer.endLines(settings.renderPathIgnoreDepth.value); } @@ -179,13 +173,21 @@ public final class PathRenderer implements IRenderer { IRenderer.glColor(color, alpha); } - emitLine(start.x, start.y, start.z, end.x, end.y, end.z); + emitPathLine(start.x, start.y, start.z, end.x, end.y, end.z); } IRenderer.endLines(settings.renderPathIgnoreDepth.value); } private static void emitLine(double x1, double y1, double z1, double x2, double y2, double z2) { + double vpX = renderManager.viewerPosX; + double vpY = renderManager.viewerPosY; + double vpZ = renderManager.viewerPosZ; + buffer.pos(x1 - vpX, y1 - vpY, z1 - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(x2 - vpX, y2 - vpY, z2 - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + } + + private static void emitPathLine(double x1, double y1, double z1, double x2, double y2, double z2) { double vpX = renderManager.viewerPosX; double vpY = renderManager.viewerPosY; double vpZ = renderManager.viewerPosZ; From 67efb7a5b676dbcf7afe59dede5155ab3dbbd821 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 19 Jun 2023 00:34:22 -0500 Subject: [PATCH 160/405] Add `experimentalRaytrace` setting for native raytrace Update `nether-pathfinder` to 0.15 --- build.gradle | 4 +- src/api/java/baritone/api/Settings.java | 3 + .../baritone/behavior/ElytraBehavior.java | 57 +++++++++++++++---- .../elytra/NetherPathfinderContext.java | 23 +++++++- 4 files changed, 74 insertions(+), 13 deletions(-) diff --git a/build.gradle b/build.gradle index 6d0ba4f1a..c3ef73c32 100755 --- a/build.gradle +++ b/build.gradle @@ -175,9 +175,9 @@ dependencies { transitive = false } launchAnnotationProcessor 'org.spongepowered:mixin:0.8.4-SNAPSHOT:processor' - launchImplementation('dev.babbaj:nether-pathfinder:0.12') + launchImplementation('dev.babbaj:nether-pathfinder:0.15') testImplementation 'junit:junit:4.12' - implementation 'dev.babbaj:nether-pathfinder:0.12' + implementation 'dev.babbaj:nether-pathfinder:0.15' } mixin { diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 116df04e0..3f46c24d9 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -62,7 +62,10 @@ public final class Settings { public final Setting conserveFireworks = new Setting<>(true); public final Setting renderRaytraces = new Setting<>(false); public final Setting elytraFreeLook = new Setting<>(false); + + // Experimental Elytra Settings public final Setting experimentalTakeoff = new Setting<>(false); + public final Setting experimentalRaytrace = new Setting<>(false); /** * Allow Baritone to break blocks diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 12723a001..2a6c3c0c8 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -40,7 +40,6 @@ import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; -import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; import java.util.*; @@ -169,9 +168,9 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private Vec3d pathAt(int i) { return new Vec3d( - this.path.get(i).x + 0.000123, - this.path.get(i).y + 0.000456, - this.path.get(i).z + 0.000789 + this.path.get(i).x, + this.path.get(i).y, + this.path.get(i).z ); } @@ -502,6 +501,44 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } final AxisAlignedBB bb = ctx.player().getEntityBoundingBox().grow(growAmount); + + if (Baritone.settings().experimentalRaytrace.value) { + final double ox = dest.x - start.x; + final double oy = dest.y - start.y; + final double oz = dest.z - start.z; + + final double[] src = new double[] { + bb.minX, bb.minY, bb.minZ, + bb.minX, bb.minY, bb.maxZ, + bb.minX, bb.maxY, bb.minZ, + bb.minX, bb.maxY, bb.maxZ, + bb.maxX, bb.minY, bb.minZ, + bb.maxX, bb.minY, bb.maxZ, + bb.maxX, bb.maxY, bb.minZ, + bb.maxX, bb.maxY, bb.maxZ, + }; + final double[] dst = new double[] { + bb.minX + ox, bb.minY + oy, bb.minZ + oz, + bb.minX + ox, bb.minY + oy, bb.maxZ + oz, + bb.minX + ox, bb.maxY + oy, bb.minZ + oz, + bb.minX + ox, bb.maxY + oy, bb.maxZ + oz, + bb.maxX + ox, bb.minY + oy, bb.minZ + oz, + bb.maxX + ox, bb.minY + oy, bb.maxZ + oz, + bb.maxX + ox, bb.maxY + oy, bb.minZ + oz, + bb.maxX + ox, bb.maxY + oy, bb.maxZ + oz, + }; + + // Batch together all 8 traces + final boolean[] hitOut = new boolean[8]; + this.context.raytrace(src, dst, hitOut); + for (boolean hit : hitOut) { + if (hit) { + return false; + } + } + return true; + } + final Vec3d[] corners = new Vec3d[]{ new Vec3d(bb.minX, bb.minY, bb.minZ), new Vec3d(bb.minX, bb.minY, bb.maxZ), @@ -522,12 +559,12 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } private boolean clearView(Vec3d start, Vec3d dest) { - boolean oxy = !rayTraceBlocks(start.x, start.y, start.z, dest.x, dest.y, dest.z); - boolean meow = !rayTraceBlocks(start, dest); - if (oxy != meow) { - logDirect(start + " " + dest + " " + oxy + " " + meow); - } - if (oxy) { + boolean clear = !(Baritone.settings().experimentalRaytrace.value + ? this.context.raytrace(start.x, start.y, start.z, dest.x, dest.y, dest.z) + : this.rayTraceBlocks(start.x, start.y, start.z, dest.x, dest.y, dest.z) // ox method + ); + + if (clear) { clearLines.add(new Pair<>(start, dest)); return true; } else { diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index 2d407375a..0a833ab5d 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -21,6 +21,7 @@ import dev.babbaj.pathfinder.NetherPathfinder; import dev.babbaj.pathfinder.PathSegment; import net.minecraft.block.state.IBlockState; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.chunk.BlockStateContainer; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.storage.ExtendedBlockStorage; @@ -57,10 +58,30 @@ public final class NetherPathfinderContext { this.context, src.getX(), src.getY(), src.getZ(), dst.getX(), dst.getY(), dst.getZ(), - true + true, + 10000 ), this.executor); } + public boolean raytrace(final double startX, final double startY, final double startZ, + final double endX, final double endY, final double endZ) { + final boolean[] hitOut = new boolean[1]; + NetherPathfinder.raytrace( + this.context, + true, + 1, + new double[] { startX, startY, startZ }, + new double[] { endX, endY, endZ }, + hitOut, + null + ); + return hitOut[0]; + } + + public void raytrace(final double[] src, final double[] dst, final boolean[] hitOut) { + NetherPathfinder.raytrace(this.context, true, hitOut.length, src, dst, hitOut, null); + } + public void cancel() { NetherPathfinder.cancel(this.context); } From 2b259d6dee9bbb60b683f8ee74786b4482d38cc2 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 18 Jun 2023 23:09:43 -0700 Subject: [PATCH 161/405] cuter debug --- .../baritone/behavior/ElytraBehavior.java | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 2a6c3c0c8..484d2d341 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -99,13 +99,14 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H public void pathToDestination(BlockPos destination) { this.destination = destination; + final long start = System.nanoTime(); this.path0(ctx.playerFeet(), destination, UnaryOperator.identity()) .thenRun(() -> { - final int distance = (int) this.pathAt(0).distanceTo(this.pathAt(this.path.size() - 1)); + final double distance = this.pathAt(0).distanceTo(this.pathAt(this.path.size() - 1)); if (this.completePath) { - logDirect(String.format("Computed path (%d blocks)", distance)); + logDirect(String.format("Computed path (%.1f blocks in %.4f seconds)", distance, (System.nanoTime() - start) / 1e9d)); } else { - logDirect(String.format("Computed segment (Next %d blocks)", distance)); + logDirect(String.format("Computed segment (Next %.1f blocks in %.4f seconds)", distance, (System.nanoTime() - start) / 1e9d)); } }) .whenComplete((result, ex) -> { @@ -116,7 +117,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H }); } - public void pathRecalcSegment(final int upToIncl) { + public void pathRecalcSegment(final int blockedAt, final int upToIncl) { if (this.recalculating) { return; } @@ -124,12 +125,14 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.recalculating = true; final List after = this.path.subList(upToIncl, this.path.size()); final boolean complete = this.completePath; + final BetterBlockPos blockage = this.path.get(blockedAt); + final long start = System.nanoTime(); this.path0(ctx.playerFeet(), this.path.get(upToIncl), segment -> segment.append(after.stream(), complete)) .thenRun(() -> { final int recompute = this.path.size() - after.size() - 1; - final int distance = (int) this.pathAt(0).distanceTo(this.pathAt(recompute)); - logDirect(String.format("Recomputed segment (Next %d blocks)", distance)); + final double distance = this.pathAt(0).distanceTo(this.pathAt(recompute)); // in spirit same as ctx.playerFeet().distanceTo(this.path.get(upToIncl)), but, thread safe (those could have changed in the meantime) + logDirect(String.format("Recalculated segment around path blockage near %s %s %s (next %.1f blocks in %.4f seconds)", SettingsUtil.maybeCensor(blockage.x), SettingsUtil.maybeCensor(blockage.y), SettingsUtil.maybeCensor(blockage.z), distance, (System.nanoTime() - start) / 1e9d)); }) .whenComplete((result, ex) -> { this.recalculating = false; @@ -146,16 +149,17 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.recalculating = true; final List before = this.path.subList(0, afterIncl + 1); + final long start = System.nanoTime(); this.path0(this.path.get(afterIncl), this.destination, segment -> segment.prepend(before.stream())) .thenRun(() -> { final int recompute = this.path.size() - before.size() - 1; - final int distance = (int) this.pathAt(0).distanceTo(this.pathAt(recompute)); + final double distance = this.pathAt(0).distanceTo(this.pathAt(recompute)); if (this.completePath) { - logDirect(String.format("Computed path (%d blocks)", distance)); + logDirect(String.format("Computed path (%.1f blocks in %.4f seconds)", distance, (System.nanoTime() - start) / 1e9d)); } else { - logDirect(String.format("Computed next segment (Next %d blocks)", distance)); + logDirect(String.format("Computed segment (Next %.1f blocks in %.4f seconds)", distance, (System.nanoTime() - start) / 1e9d)); } }) .whenComplete((result, ex) -> { @@ -228,7 +232,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H if (!clearView(pathAt(i), pathAt(i + 1))) { // obstacle. where do we return to pathing? // find the next valid segment - this.pathRecalcSegment(rangeEndExcl - 1); + this.pathRecalcSegment(i, rangeEndExcl - 1); break outer; } } @@ -443,7 +447,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H ctx.player().inventory.currentItem = firstFireworksInHotbar; } } - logDirect("firework" + (forceUseFirework ? " takeoff" : "")); + logDirect("attempting to use firework" + (forceUseFirework ? " takeoff" : "")); ctx.playerController().processRightClick(ctx.player(), ctx.world(), EnumHand.MAIN_HAND); sinceFirework = 0; } @@ -507,7 +511,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final double oy = dest.y - start.y; final double oz = dest.z - start.z; - final double[] src = new double[] { + final double[] src = new double[]{ bb.minX, bb.minY, bb.minZ, bb.minX, bb.minY, bb.maxZ, bb.minX, bb.maxY, bb.minZ, @@ -517,7 +521,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H bb.maxX, bb.maxY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ, }; - final double[] dst = new double[] { + final double[] dst = new double[]{ bb.minX + ox, bb.minY + oy, bb.minZ + oz, bb.minX + ox, bb.minY + oy, bb.maxZ + oz, bb.minX + ox, bb.maxY + oy, bb.minZ + oz, From a32ac59ec1842050f09c5e6fe190e4b23be30e2f Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Mon, 19 Jun 2023 12:44:32 +0200 Subject: [PATCH 162/405] prevent went off with a bang --- src/main/java/baritone/behavior/ElytraBehavior.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 484d2d341..28628e68f 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -487,7 +487,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final NBTTagCompound subCompound = itemStack.getSubCompound("Fireworks"); return itemStack.getItem() == Items.FIREWORKS && subCompound != null - && subCompound.hasKey("Flight"); + && subCompound.hasKey("Flight") + && !subCompound.hasKey("Explosions"); } private boolean isFireworkActive() { From 9e10faa4c56da5af29226b344e8a0bb8ec807845 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 19 Jun 2023 12:32:25 -0500 Subject: [PATCH 163/405] Elytra inventory modifications - Use `throwaway` to switch items - Remove inventory settings - Prioritizes boost fireworks, but works without - Avoids explosion fireworks --- src/api/java/baritone/api/Settings.java | 8 --- .../baritone/behavior/ElytraBehavior.java | 61 +++++-------------- 2 files changed, 16 insertions(+), 53 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 3f46c24d9..23f138eeb 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -50,14 +50,6 @@ public final class Settings { public final Setting elytraSimulationTicks = new Setting<>(20); public final Setting elytraPitchRange = new Setting<>(25); - /** - * Allow users to control firework usage instead of Baritone. e.g. with their own client modules. - */ - public final Setting elytraUseFireworks = new Setting<>(true); - /** - * Allow Baritone to manage fireworks in the inventory and hotbar - */ - public final Setting elytraInventory = new Setting<>(true); public final Setting elytraFireworkSpeed = new Setting<>(0.6); public final Setting conserveFireworks = new Setting<>(true); public final Setting renderRaytraces = new Setting<>(false); diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 28628e68f..3ff824474 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -431,21 +431,16 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H if (forceUseFirework || (!firework && sinceFirework > 10 - && Baritone.settings().elytraUseFireworks.value && useOnDescend && (ctx.player().posY < goingTo.y - 5 || start.distanceTo(new Vec3d(goingTo.x + 0.5, ctx.player().posY, goingTo.z + 0.5)) > 5) // UGH!!!!!!! && currentSpeed < Baritone.settings().elytraFireworkSpeed.value) ) { - if (Baritone.settings().elytraInventory.value) { - final int firstFireworksInHotbar = firstFireworksInHotbar(); - if (firstFireworksInHotbar == -1) { - if (!swapToFireworksInInventory()) { - logDirect("no fireworks"); - return; - } - } else { - ctx.player().inventory.currentItem = firstFireworksInHotbar; - } + // Prioritize boosting fireworks over regular ones + // TODO: Take the minimum boost time into account? + if (!baritone.getInventoryBehavior().throwaway(true, ElytraBehavior::isBoostingFireworks) && + !baritone.getInventoryBehavior().throwaway(true, ElytraBehavior::isFireworks)) { + logDirect("no fireworks"); + return; } logDirect("attempting to use firework" + (forceUseFirework ? " takeoff" : "")); ctx.playerController().processRightClick(ctx.player(), ctx.world(), EnumHand.MAIN_HAND); @@ -453,42 +448,18 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } - private boolean swapToFireworksInInventory() { - final int i = firstFireworksInInventory(); - if (i != -1) { - baritone.getInventoryBehavior().attemptToPutOnHotbar(i, (slot) -> slot != 7); - ctx.player().inventory.currentItem = 7; - return true; + private static boolean isFireworks(final ItemStack itemStack) { + if (itemStack.getItem() != Items.FIREWORKS) { + return false; } - return false; - } - - private int firstFireworksInInventory() { - final NonNullList invy = ctx.player().inventory.mainInventory; - for (int i = 0; i < invy.size(); i++) { - if (isBoostingFireworks(invy.get(i))) { - return i; - } - } - return -1; - } - - private int firstFireworksInHotbar() { - final NonNullList invy = ctx.player().inventory.mainInventory; - for (int i = 0; i < 9; i++) { - if (isBoostingFireworks(invy.get(i))) { - return i; - } - } - return -1; - } - - private boolean isBoostingFireworks(final ItemStack itemStack) { + // If it has NBT data, make sure it won't cause us to explode. final NBTTagCompound subCompound = itemStack.getSubCompound("Fireworks"); - return itemStack.getItem() == Items.FIREWORKS - && subCompound != null - && subCompound.hasKey("Flight") - && !subCompound.hasKey("Explosions"); + return subCompound == null || !subCompound.hasKey("Explosions"); + } + + private static boolean isBoostingFireworks(final ItemStack itemStack) { + final NBTTagCompound subCompound = itemStack.getSubCompound("Fireworks"); + return isFireworks(itemStack) && subCompound != null && subCompound.hasKey("Flight"); } private boolean isFireworkActive() { From 6741dff12b241cb451735aae934295b69be867aa Mon Sep 17 00:00:00 2001 From: 0x22 <0x22@futureclient.net> Date: Mon, 19 Jun 2023 14:17:54 -0400 Subject: [PATCH 164/405] replaced (PI / 180) constants, RotationUtils calcVec3dFromRotation->calcLookDirectionFromRotation and named local variables. --- .../java/baritone/api/utils/RayTraceUtils.java | 2 +- .../java/baritone/api/utils/RotationUtils.java | 17 ++++++++++++----- .../java/baritone/behavior/ElytraBehavior.java | 10 +++++----- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/api/java/baritone/api/utils/RayTraceUtils.java b/src/api/java/baritone/api/utils/RayTraceUtils.java index 4f763e392..d80f84e5e 100644 --- a/src/api/java/baritone/api/utils/RayTraceUtils.java +++ b/src/api/java/baritone/api/utils/RayTraceUtils.java @@ -50,7 +50,7 @@ public final class RayTraceUtils { } else { start = entity.getPositionEyes(1.0F); // do whatever is correct } - Vec3d direction = RotationUtils.calcVec3dFromRotation(rotation); + Vec3d direction = RotationUtils.calcLookDirectionFromRotation(rotation); Vec3d end = start.add( direction.x * blockReachDistance, direction.y * blockReachDistance, diff --git a/src/api/java/baritone/api/utils/RotationUtils.java b/src/api/java/baritone/api/utils/RotationUtils.java index 1991ab878..4ebb22dd5 100644 --- a/src/api/java/baritone/api/utils/RotationUtils.java +++ b/src/api/java/baritone/api/utils/RotationUtils.java @@ -37,11 +37,13 @@ public final class RotationUtils { * Constant that a degree value is multiplied by to get the equivalent radian value */ public static final double DEG_TO_RAD = Math.PI / 180.0; + public static final float DEG_TO_RAD_F = (float) DEG_TO_RAD; /** * Constant that a radian value is multiplied by to get the equivalent degree value */ public static final double RAD_TO_DEG = 180.0 / Math.PI; + public static final float RAD_TO_DEG_F = (float) RAD_TO_DEG; /** * Offsets from the root block position to the center of each side. @@ -122,12 +124,17 @@ public final class RotationUtils { * @param rotation The input rotation * @return Look vector for the rotation */ + public static Vec3d calcLookDirectionFromRotation(Rotation rotation) { + float flatZ = MathHelper.cos((-rotation.getYaw() * DEG_TO_RAD_F) - (float) Math.PI); + float flatX = MathHelper.sin((-rotation.getYaw() * DEG_TO_RAD_F) - (float) Math.PI); + float pitchBase = -MathHelper.cos(-rotation.getPitch() * DEG_TO_RAD_F); + float pitchHeight = MathHelper.sin(-rotation.getPitch() * DEG_TO_RAD_F); + return new Vec3d(flatX * pitchBase, pitchHeight, flatZ * pitchBase); + } + + @Deprecated public static Vec3d calcVec3dFromRotation(Rotation rotation) { - float f = MathHelper.cos(-rotation.getYaw() * (float) DEG_TO_RAD - (float) Math.PI); - float f1 = MathHelper.sin(-rotation.getYaw() * (float) DEG_TO_RAD - (float) Math.PI); - float f2 = -MathHelper.cos(-rotation.getPitch() * (float) DEG_TO_RAD); - float f3 = MathHelper.sin(-rotation.getPitch() * (float) DEG_TO_RAD); - return new Vec3d((double) (f1 * f2), (double) f3, (double) (f * f2)); + return calcLookDirectionFromRotation(rotation); } /** diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 3ff824474..11512b7b1 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -622,10 +622,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H double motionX = motion.x; double motionY = motion.y; double motionZ = motion.z; - float flatZ = MathHelper.cos(-rotationYaw * 0.017453292F - (float) Math.PI); // 0.174... is Math.PI / 180 - float flatX = MathHelper.sin(-rotationYaw * 0.017453292F - (float) Math.PI); - float pitchBase = -MathHelper.cos(-rotationPitch * 0.017453292F); - float pitchHeight = MathHelper.sin(-rotationPitch * 0.017453292F); + float flatZ = MathHelper.cos((-rotationYaw * RotationUtils.DEG_TO_RAD_F) - (float) Math.PI); + float flatX = MathHelper.sin((-rotationYaw * RotationUtils.DEG_TO_RAD_F) - (float) Math.PI); + float pitchBase = -MathHelper.cos(-rotationPitch * RotationUtils.DEG_TO_RAD_F); + float pitchHeight = MathHelper.sin(-rotationPitch * RotationUtils.DEG_TO_RAD_F); Vec3d lookDirection = new Vec3d(flatX * pitchBase, pitchHeight, flatZ * pitchBase); if (firework) { @@ -635,7 +635,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H motionZ += lookDirection.z * 0.1 + (lookDirection.z * 1.5 - motionZ) * 0.5; } - float pitchRadians = rotationPitch * 0.017453292F; + float pitchRadians = rotationPitch * RotationUtils.DEG_TO_RAD_F; double pitchBase2 = Math.sqrt(lookDirection.x * lookDirection.x + lookDirection.z * lookDirection.z); double flatMotion = Math.sqrt(motionX * motionX + motionZ * motionZ); double thisIsAlwaysOne = lookDirection.length(); From 8d3b0c8f0772366c189f02d52ac126528f8379a5 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 19 Jun 2023 14:10:41 -0500 Subject: [PATCH 165/405] Always enforce `sinceFirework` --- src/main/java/baritone/behavior/ElytraBehavior.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 11512b7b1..b885b842c 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -429,11 +429,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H ctx.player().motionZ ).length(); - if (forceUseFirework || (!firework - && sinceFirework > 10 + if (sinceFirework > 10 && (forceUseFirework || (!firework && useOnDescend && (ctx.player().posY < goingTo.y - 5 || start.distanceTo(new Vec3d(goingTo.x + 0.5, ctx.player().posY, goingTo.z + 0.5)) > 5) // UGH!!!!!!! - && currentSpeed < Baritone.settings().elytraFireworkSpeed.value) + && currentSpeed < Baritone.settings().elytraFireworkSpeed.value)) ) { // Prioritize boosting fireworks over regular ones // TODO: Take the minimum boost time into account? From 7d17ace15df27ede1c28df456eb4e0bb3f144332 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 19 Jun 2023 15:15:29 -0500 Subject: [PATCH 166/405] Reset recalculating flag on `clear` --- src/main/java/baritone/behavior/ElytraBehavior.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index b885b842c..4db310346 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -182,6 +182,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.path = Collections.emptyList(); this.playerNear = 0; this.completePath = true; + this.recalculating = false; this.destination = null; } From c6a66240453c5a9c2744061e734fb2818fe41a1f Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 19 Jun 2023 15:16:11 -0500 Subject: [PATCH 167/405] Reorder fields --- src/main/java/baritone/behavior/ElytraBehavior.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 4db310346..74e05edad 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -78,10 +78,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private BlockPos destination; private List path; private boolean completePath; - - private int playerNear; - private boolean recalculating; + private int playerNear; public PathManager() { // lol imagine initializing fields normally @@ -179,11 +177,11 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } public void clear() { + this.destination = null; this.path = Collections.emptyList(); - this.playerNear = 0; this.completePath = true; this.recalculating = false; - this.destination = null; + this.playerNear = 0; } private void setPath(final UnpackedSegment segment) { From 90f401a06746c89c37aa7c78489a8ee013dc8e29 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 19 Jun 2023 15:19:32 -0500 Subject: [PATCH 168/405] Remove legacy raytracing methods --- src/api/java/baritone/api/Settings.java | 1 - .../baritone/behavior/ElytraBehavior.java | 270 ++---------------- 2 files changed, 28 insertions(+), 243 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 23f138eeb..3cfef2ffc 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -57,7 +57,6 @@ public final class Settings { // Experimental Elytra Settings public final Setting experimentalTakeoff = new Setting<>(false); - public final Setting experimentalRaytrace = new Setting<>(false); /** * Allow Baritone to break blocks diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 74e05edad..5a8614edc 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -476,56 +476,36 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final AxisAlignedBB bb = ctx.player().getEntityBoundingBox().grow(growAmount); - if (Baritone.settings().experimentalRaytrace.value) { - final double ox = dest.x - start.x; - final double oy = dest.y - start.y; - final double oz = dest.z - start.z; + final double ox = dest.x - start.x; + final double oy = dest.y - start.y; + final double oz = dest.z - start.z; - final double[] src = new double[]{ - bb.minX, bb.minY, bb.minZ, - bb.minX, bb.minY, bb.maxZ, - bb.minX, bb.maxY, bb.minZ, - bb.minX, bb.maxY, bb.maxZ, - bb.maxX, bb.minY, bb.minZ, - bb.maxX, bb.minY, bb.maxZ, - bb.maxX, bb.maxY, bb.minZ, - bb.maxX, bb.maxY, bb.maxZ, - }; - final double[] dst = new double[]{ - bb.minX + ox, bb.minY + oy, bb.minZ + oz, - bb.minX + ox, bb.minY + oy, bb.maxZ + oz, - bb.minX + ox, bb.maxY + oy, bb.minZ + oz, - bb.minX + ox, bb.maxY + oy, bb.maxZ + oz, - bb.maxX + ox, bb.minY + oy, bb.minZ + oz, - bb.maxX + ox, bb.minY + oy, bb.maxZ + oz, - bb.maxX + ox, bb.maxY + oy, bb.minZ + oz, - bb.maxX + ox, bb.maxY + oy, bb.maxZ + oz, - }; - - // Batch together all 8 traces - final boolean[] hitOut = new boolean[8]; - this.context.raytrace(src, dst, hitOut); - for (boolean hit : hitOut) { - if (hit) { - return false; - } - } - return true; - } - - final Vec3d[] corners = new Vec3d[]{ - new Vec3d(bb.minX, bb.minY, bb.minZ), - new Vec3d(bb.minX, bb.minY, bb.maxZ), - new Vec3d(bb.minX, bb.maxY, bb.minZ), - new Vec3d(bb.minX, bb.maxY, bb.maxZ), - new Vec3d(bb.maxX, bb.minY, bb.minZ), - new Vec3d(bb.maxX, bb.minY, bb.maxZ), - new Vec3d(bb.maxX, bb.maxY, bb.minZ), - new Vec3d(bb.maxX, bb.maxY, bb.maxZ), + final double[] src = new double[]{ + bb.minX, bb.minY, bb.minZ, + bb.minX, bb.minY, bb.maxZ, + bb.minX, bb.maxY, bb.minZ, + bb.minX, bb.maxY, bb.maxZ, + bb.maxX, bb.minY, bb.minZ, + bb.maxX, bb.minY, bb.maxZ, + bb.maxX, bb.maxY, bb.minZ, + bb.maxX, bb.maxY, bb.maxZ, + }; + final double[] dst = new double[]{ + bb.minX + ox, bb.minY + oy, bb.minZ + oz, + bb.minX + ox, bb.minY + oy, bb.maxZ + oz, + bb.minX + ox, bb.maxY + oy, bb.minZ + oz, + bb.minX + ox, bb.maxY + oy, bb.maxZ + oz, + bb.maxX + ox, bb.minY + oy, bb.minZ + oz, + bb.maxX + ox, bb.minY + oy, bb.maxZ + oz, + bb.maxX + ox, bb.maxY + oy, bb.minZ + oz, + bb.maxX + ox, bb.maxY + oy, bb.maxZ + oz, }; - for (final Vec3d corner : corners) { - if (!clearView(corner, dest.add(corner.subtract(start)))) { + // Batch together all 8 traces + final boolean[] hitOut = new boolean[8]; + this.context.raytrace(src, dst, hitOut); + for (boolean hit : hitOut) { + if (hit) { return false; } } @@ -533,11 +513,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } private boolean clearView(Vec3d start, Vec3d dest) { - boolean clear = !(Baritone.settings().experimentalRaytrace.value - ? this.context.raytrace(start.x, start.y, start.z, dest.x, dest.y, dest.z) - : this.rayTraceBlocks(start.x, start.y, start.z, dest.x, dest.y, dest.z) // ox method - ); - + boolean clear = !this.context.raytrace(start.x, start.y, start.z, dest.x, dest.y, dest.z); if (clear) { clearLines.add(new Pair<>(start, dest)); return true; @@ -666,195 +642,5 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return new Vec3d(motionX, motionY, motionZ); } - - private boolean rayTraceBlocks(final double startX, final double startY, final double startZ, - final double endX, final double endY, final double endZ) { - int voxelCurrX = fastFloor(startX); - int voxelCurrY = fastFloor(startY); - int voxelCurrZ = fastFloor(startZ); - - if (!this.passable(voxelCurrX, voxelCurrY, voxelCurrZ)) { - return true; - } - - final int voxelEndX = fastFloor(endX); - final int voxelEndY = fastFloor(endY); - final int voxelEndZ = fastFloor(endZ); - double currPosX = startX; - double currPosY = startY; - double currPosZ = startZ; - - int steps = 200; // TODO: should we lower the max steps? - while (steps-- >= 0) { - if (voxelCurrX == voxelEndX && voxelCurrY == voxelEndY && voxelCurrZ == voxelEndZ) { - return false; - } - - final double distanceFromStartToEndX = endX - currPosX; - final double distanceFromStartToEndY = endY - currPosY; - final double distanceFromStartToEndZ = endZ - currPosZ; - - double nextIntegerX; - double nextIntegerY; - double nextIntegerZ; - // potentially more based branchless impl? - nextIntegerX = voxelCurrX + ((voxelCurrX - voxelEndX) >>> 31); // if voxelEnd > voxelIn, then voxelIn-voxelEnd will be negative, meaning the sign bit is 1 - nextIntegerY = voxelCurrY + ((voxelCurrY - voxelEndY) >>> 31); // if we do an unsigned right shift by 31, that sign bit becomes the LSB - nextIntegerZ = voxelCurrZ + ((voxelCurrZ - voxelEndZ) >>> 31); // therefore, this increments nextInteger iff EndX>inX, otherwise it leaves it alone - // remember: don't have to worry about the case when voxelEnd == voxelIn, because nextInteger value wont be used - - // these just have to be strictly greater than 1, might as well just go up to the next int - double fracIfSkipX = 2.0D; - double fracIfSkipY = 2.0D; - double fracIfSkipZ = 2.0D; - - // reminder to future self: don't "branchlessify" this, it's MUCH slower (pretty obviously, floating point div is much worse than a branch mispredict, but integer increment (like the other two removed branches) are cheap enough to be worth doing either way) - if (voxelEndX != voxelCurrX) { - fracIfSkipX = (nextIntegerX - currPosX) / distanceFromStartToEndX; - } - if (voxelEndY != voxelCurrY) { - fracIfSkipY = (nextIntegerY - currPosY) / distanceFromStartToEndY; - } - if (voxelEndZ != voxelCurrZ) { - fracIfSkipZ = (nextIntegerZ - currPosZ) / distanceFromStartToEndZ; - } - - if (fracIfSkipX < fracIfSkipY && fracIfSkipX < fracIfSkipZ) { - // note: voxelEndX == voxelInX is impossible because allowSkip would be set to false in that case, meaning that the elapsed distance would stay at default - currPosX = nextIntegerX; - currPosY += distanceFromStartToEndY * fracIfSkipX; - currPosZ += distanceFromStartToEndZ * fracIfSkipX; - // tested: faster to paste this 3 times with only one of the subtractions in each - final int xFloorOffset = (voxelEndX - voxelCurrX) >>> 31; - voxelCurrX = (fastFloor(currPosX) - xFloorOffset); - voxelCurrY = (fastFloor(currPosY)); - voxelCurrZ = (fastFloor(currPosZ)); - } else if (fracIfSkipY < fracIfSkipZ) { - currPosX += distanceFromStartToEndX * fracIfSkipY; - currPosY = nextIntegerY; - currPosZ += distanceFromStartToEndZ * fracIfSkipY; - // tested: faster to paste this 3 times with only one of the subtractions in each - final int yFloorOffset = (voxelEndY - voxelCurrY) >>> 31; - voxelCurrX = (fastFloor(currPosX)); - voxelCurrY = (fastFloor(currPosY) - yFloorOffset); - voxelCurrZ = (fastFloor(currPosZ)); - } else { - currPosX += distanceFromStartToEndX * fracIfSkipZ; - currPosY += distanceFromStartToEndY * fracIfSkipZ; - currPosZ = nextIntegerZ; - // tested: faster to paste this 3 times with only one of the subtractions in each - final int zFloorOffset = (voxelEndZ - voxelCurrZ) >>> 31; - voxelCurrX = (fastFloor(currPosX)); - voxelCurrY = (fastFloor(currPosY)); - voxelCurrZ = (fastFloor(currPosZ) - zFloorOffset); - } - - if (!this.passable(voxelCurrX, voxelCurrY, voxelCurrZ)) { - return true; - } - } - return false; - } - - private static final double FLOOR_DOUBLE_D = 1_073_741_824.0; - private static final int FLOOR_DOUBLE_I = 1_073_741_824; - - private static int fastFloor(final double v) { - return ((int) (v + FLOOR_DOUBLE_D)) - FLOOR_DOUBLE_I; - } - - private boolean rayTraceBlocks(Vec3d start, Vec3d end) { - int x1 = MathHelper.floor(end.x); - int y1 = MathHelper.floor(end.y); - int z1 = MathHelper.floor(end.z); - int x2 = MathHelper.floor(start.x); - int y2 = MathHelper.floor(start.y); - int z2 = MathHelper.floor(start.z); - BlockPos blockpos = new BlockPos(x2, y2, z2); - IBlockState iblockstate = ctx.world().getBlockState(blockpos); - if (!passable(iblockstate)) { - return true; - } - int steps = 200; - while (steps-- >= 0) { - if (Double.isNaN(start.x) || Double.isNaN(start.y) || Double.isNaN(start.z)) { - return false; - } - if (x2 == x1 && y2 == y1 && z2 == z1) { - return false; - } - boolean hitX = true; - boolean hitY = true; - boolean hitZ = true; - double nextX = 999.0D; - double nextY = 999.0D; - double nextZ = 999.0D; - if (x1 > x2) { - nextX = (double) x2 + 1.0D; - } else if (x1 < x2) { - nextX = (double) x2 + 0.0D; - } else { - hitX = false; - } - if (y1 > y2) { - nextY = (double) y2 + 1.0D; - } else if (y1 < y2) { - nextY = (double) y2 + 0.0D; - } else { - hitY = false; - } - if (z1 > z2) { - nextZ = (double) z2 + 1.0D; - } else if (z1 < z2) { - nextZ = (double) z2 + 0.0D; - } else { - hitZ = false; - } - double stepX = 999.0D; - double stepY = 999.0D; - double stepZ = 999.0D; - double dirX = end.x - start.x; - double dirY = end.y - start.y; - double dirZ = end.z - start.z; - if (hitX) { - stepX = (nextX - start.x) / dirX; - } - if (hitY) { - stepY = (nextY - start.y) / dirY; - } - if (hitZ) { - stepZ = (nextZ - start.z) / dirZ; - } - if (stepX == -0.0D) { - stepX = -1.0E-4D; - } - if (stepY == -0.0D) { - stepY = -1.0E-4D; - } - if (stepZ == -0.0D) { - stepZ = -1.0E-4D; - } - EnumFacing dir; - if (stepX < stepY && stepX < stepZ) { - dir = x1 > x2 ? EnumFacing.WEST : EnumFacing.EAST; - start = new Vec3d(nextX, start.y + dirY * stepX, start.z + dirZ * stepX); - } else if (stepY < stepZ) { - dir = y1 > y2 ? EnumFacing.DOWN : EnumFacing.UP; - start = new Vec3d(start.x + dirX * stepY, nextY, start.z + dirZ * stepY); - } else { - dir = z1 > z2 ? EnumFacing.NORTH : EnumFacing.SOUTH; - start = new Vec3d(start.x + dirX * stepZ, start.y + dirY * stepZ, nextZ); - } - x2 = MathHelper.floor(start.x) - (dir == EnumFacing.EAST ? 1 : 0); - y2 = MathHelper.floor(start.y) - (dir == EnumFacing.UP ? 1 : 0); - z2 = MathHelper.floor(start.z) - (dir == EnumFacing.SOUTH ? 1 : 0); - blockpos = new BlockPos(x2, y2, z2); - IBlockState iblockstate1 = ctx.world().getBlockState(blockpos); - if (!passable(iblockstate1)) { - return true; - } - } - return false; - } } From 82156250df4cf43a3f33c07579d53964aca22da2 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 19 Jun 2023 15:20:04 -0500 Subject: [PATCH 169/405] Update `nether-pathfinder` to 0.16 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index c3ef73c32..95abfec6a 100755 --- a/build.gradle +++ b/build.gradle @@ -175,9 +175,9 @@ dependencies { transitive = false } launchAnnotationProcessor 'org.spongepowered:mixin:0.8.4-SNAPSHOT:processor' - launchImplementation('dev.babbaj:nether-pathfinder:0.15') + launchImplementation('dev.babbaj:nether-pathfinder:0.16') testImplementation 'junit:junit:4.12' - implementation 'dev.babbaj:nether-pathfinder:0.15' + implementation 'dev.babbaj:nether-pathfinder:0.16' } mixin { From 959b4cddbd400cb256a6d53c297a6d67154f6c5f Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 19 Jun 2023 15:29:30 -0500 Subject: [PATCH 170/405] Remove unneeded `while (true)` --- .../baritone/behavior/ElytraBehavior.java | 43 ++++++++----------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 5a8614edc..a0502d930 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -63,6 +63,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private final NetherPathfinderContext context; private final PathManager pathManager; private int sinceFirework; + private BlockStateInterface bsi; public ElytraBehavior(Baritone baritone) { super(baritone); @@ -212,30 +213,26 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return; } - outer: - while (true) { - int rangeStartIncl = playerNear; - int rangeEndExcl = playerNear; - while (rangeEndExcl < path.size() && ctx.world().isBlockLoaded(path.get(rangeEndExcl), false)) { - rangeEndExcl++; - } - if (rangeStartIncl >= rangeEndExcl) { - // not loaded yet? + int rangeStartIncl = playerNear; + int rangeEndExcl = playerNear; + while (rangeEndExcl < path.size() && ctx.world().isBlockLoaded(path.get(rangeEndExcl), false)) { + rangeEndExcl++; + } + if (rangeStartIncl >= rangeEndExcl) { + // not loaded yet? + return; + } + if (!passable(ctx.world().getBlockState(path.get(rangeStartIncl)))) { + // we're in a wall + return; // previous iterations of this function SHOULD have fixed this by now :rage_cat: + } + for (int i = rangeStartIncl; i < rangeEndExcl - 1; i++) { + if (!clearView(pathAt(i), pathAt(i + 1))) { + // obstacle. where do we return to pathing? + // find the next valid segment + this.pathRecalcSegment(i, rangeEndExcl - 1); return; } - if (!passable(ctx.world().getBlockState(path.get(rangeStartIncl)))) { - // we're in a wall - return; // previous iterations of this function SHOULD have fixed this by now :rage_cat: - } - for (int i = rangeStartIncl; i < rangeEndExcl - 1; i++) { - if (!clearView(pathAt(i), pathAt(i + 1))) { - // obstacle. where do we return to pathing? - // find the next valid segment - this.pathRecalcSegment(i, rangeEndExcl - 1); - break outer; - } - } - break; } } @@ -582,8 +579,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return bestPitch; } - private BlockStateInterface bsi; - public boolean passable(int x, int y, int z) { return passable(this.bsi.get0(x, y, z)); } From 1de2d5596594f3684e6e42b2279eb6c2c6ad42ee Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Mon, 19 Jun 2023 23:05:46 +0200 Subject: [PATCH 171/405] Tab complete block properties --- .../api/command/datatypes/BlockById.java | 122 +++++++++++++++++- 1 file changed, 116 insertions(+), 6 deletions(-) diff --git a/src/api/java/baritone/api/command/datatypes/BlockById.java b/src/api/java/baritone/api/command/datatypes/BlockById.java index 3702725e3..8df3e0658 100644 --- a/src/api/java/baritone/api/command/datatypes/BlockById.java +++ b/src/api/java/baritone/api/command/datatypes/BlockById.java @@ -19,15 +19,28 @@ package baritone.api.command.datatypes; import baritone.api.command.exception.CommandException; import baritone.api.command.helpers.TabCompleteHelper; + import net.minecraft.block.Block; +import net.minecraft.block.properties.IProperty; import net.minecraft.init.Blocks; import net.minecraft.util.ResourceLocation; +import java.util.Set; +import java.util.regex.Pattern; +import java.util.stream.Collectors; import java.util.stream.Stream; public enum BlockById implements IDatatypeFor { INSTANCE; + /** + * Matches (domain:)?name([(property=value)*])? but the input can be truncated at any position. + * domain and name are [a-z0-9_.-]+ and [a-z0-9/_.-]+ because that's what mc 1.13+ accepts. + * property and value use the same format as domain. + */ + // Good luck reading this. + private static Pattern PATTERN = Pattern.compile("(?:[a-z0-9_.-]+:)?(?:[a-z0-9/_.-]+(?:\\[(?:(?:[a-z0-9_.-]+=[a-z0-9_.-]+,)*(?:[a-z0-9_.-]+(?:=(?:[a-z0-9_.-]+(?:\\])?)?)?)?|\\])?)?)?"); + @Override public Block get(IDatatypeContext ctx) throws CommandException { ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString()); @@ -40,14 +53,111 @@ public enum BlockById implements IDatatypeFor { @Override public Stream tabComplete(IDatatypeContext ctx) throws CommandException { + String arg = ctx.getConsumer().getString(); + + if (!PATTERN.matcher(arg).matches()) { + // Invalid format; we can't complete this. + return Stream.empty(); + } + + if (arg.endsWith("]")) { + // We are already done. + return Stream.empty(); + } + + if (!arg.contains("[")) { + // no properties so we are completing the block id + return new TabCompleteHelper() + .append( + Block.REGISTRY.getKeys() + .stream() + .map(Object::toString) + ) + .filterPrefixNamespaced(arg) + .sortAlphabetically() + .stream(); + } + + // destructuring assignment? Please? + String blockId, properties; + { + String[] parts = splitLast(arg, '['); + blockId = parts[0]; + properties = parts[1]; + } + + Block block = Block.REGISTRY.getObject(new ResourceLocation(blockId)); + if (block == null) { + // This block doesn't exist so there's no properties to complete. + return Stream.empty(); + } + + String leadingProperties, lastProperty; + { + String[] parts = splitLast(properties, ','); + leadingProperties = parts[0]; + lastProperty = parts[1]; + } + + if (!lastProperty.contains("=")) { + // The last property-value pair doesn't have a value yet so we are completing its name + Set usedProps = Stream.of(leadingProperties.split(",")) + .map(pair -> pair.split("=")[0]) + .collect(Collectors.toSet()); + + String prefix = arg.substring(0, arg.length() - lastProperty.length()); + return new TabCompleteHelper() + .append( + block.getBlockState() + .getProperties() + .stream() + .map(IProperty::getName) + ) + .filter(prop -> !usedProps.contains(prop)) + .filterPrefix(lastProperty) + .sortAlphabetically() + .map(prop -> prefix + prop) + .stream(); + } + + String lastName, lastValue; + { + String[] parts = splitLast(lastProperty, '='); + lastName = parts[0]; + lastValue = parts[1]; + } + + // We are completing the value of a property + String prefix = arg.substring(0, arg.length() - lastValue.length()); + + IProperty property = block.getBlockState().getProperty(lastName); + if (property == null) { + // The property does not exist so there's no values to complete + return Stream.empty(); + } + return new TabCompleteHelper() - .append( - Block.REGISTRY.getKeys() - .stream() - .map(Object::toString) - ) - .filterPrefixNamespaced(ctx.getConsumer().getString()) + .append(getValues(property)) + .filterPrefix(lastValue) .sortAlphabetically() + .map(val -> prefix + val) .stream(); } + + /** + * Always returns exactly two strings. + * If the separator is not found the FIRST returned string is empty. + */ + private static String[] splitLast(String string, char chr) { + int idx = string.lastIndexOf(chr); + if (idx == -1) { + return new String[]{"", string}; + } + return new String[]{string.substring(0, idx), string.substring(idx + 1)}; + } + + // this shouldn't need to be a separate method? + private static > Stream getValues(IProperty property) { + return property.getAllowedValues().stream().map(property::getName); + } } From e43200865cbdb305d11c913aae3cb90ea48ae4ab Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Mon, 19 Jun 2023 23:44:22 +0200 Subject: [PATCH 172/405] Move this to the right place --- .../api/command/datatypes/BlockById.java | 122 +----------------- .../datatypes/ForBlockOptionalMeta.java | 120 ++++++++++++++++- 2 files changed, 124 insertions(+), 118 deletions(-) diff --git a/src/api/java/baritone/api/command/datatypes/BlockById.java b/src/api/java/baritone/api/command/datatypes/BlockById.java index 8df3e0658..3702725e3 100644 --- a/src/api/java/baritone/api/command/datatypes/BlockById.java +++ b/src/api/java/baritone/api/command/datatypes/BlockById.java @@ -19,28 +19,15 @@ package baritone.api.command.datatypes; import baritone.api.command.exception.CommandException; import baritone.api.command.helpers.TabCompleteHelper; - import net.minecraft.block.Block; -import net.minecraft.block.properties.IProperty; import net.minecraft.init.Blocks; import net.minecraft.util.ResourceLocation; -import java.util.Set; -import java.util.regex.Pattern; -import java.util.stream.Collectors; import java.util.stream.Stream; public enum BlockById implements IDatatypeFor { INSTANCE; - /** - * Matches (domain:)?name([(property=value)*])? but the input can be truncated at any position. - * domain and name are [a-z0-9_.-]+ and [a-z0-9/_.-]+ because that's what mc 1.13+ accepts. - * property and value use the same format as domain. - */ - // Good luck reading this. - private static Pattern PATTERN = Pattern.compile("(?:[a-z0-9_.-]+:)?(?:[a-z0-9/_.-]+(?:\\[(?:(?:[a-z0-9_.-]+=[a-z0-9_.-]+,)*(?:[a-z0-9_.-]+(?:=(?:[a-z0-9_.-]+(?:\\])?)?)?)?|\\])?)?)?"); - @Override public Block get(IDatatypeContext ctx) throws CommandException { ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString()); @@ -53,111 +40,14 @@ public enum BlockById implements IDatatypeFor { @Override public Stream tabComplete(IDatatypeContext ctx) throws CommandException { - String arg = ctx.getConsumer().getString(); - - if (!PATTERN.matcher(arg).matches()) { - // Invalid format; we can't complete this. - return Stream.empty(); - } - - if (arg.endsWith("]")) { - // We are already done. - return Stream.empty(); - } - - if (!arg.contains("[")) { - // no properties so we are completing the block id - return new TabCompleteHelper() - .append( - Block.REGISTRY.getKeys() - .stream() - .map(Object::toString) - ) - .filterPrefixNamespaced(arg) - .sortAlphabetically() - .stream(); - } - - // destructuring assignment? Please? - String blockId, properties; - { - String[] parts = splitLast(arg, '['); - blockId = parts[0]; - properties = parts[1]; - } - - Block block = Block.REGISTRY.getObject(new ResourceLocation(blockId)); - if (block == null) { - // This block doesn't exist so there's no properties to complete. - return Stream.empty(); - } - - String leadingProperties, lastProperty; - { - String[] parts = splitLast(properties, ','); - leadingProperties = parts[0]; - lastProperty = parts[1]; - } - - if (!lastProperty.contains("=")) { - // The last property-value pair doesn't have a value yet so we are completing its name - Set usedProps = Stream.of(leadingProperties.split(",")) - .map(pair -> pair.split("=")[0]) - .collect(Collectors.toSet()); - - String prefix = arg.substring(0, arg.length() - lastProperty.length()); - return new TabCompleteHelper() - .append( - block.getBlockState() - .getProperties() - .stream() - .map(IProperty::getName) - ) - .filter(prop -> !usedProps.contains(prop)) - .filterPrefix(lastProperty) - .sortAlphabetically() - .map(prop -> prefix + prop) - .stream(); - } - - String lastName, lastValue; - { - String[] parts = splitLast(lastProperty, '='); - lastName = parts[0]; - lastValue = parts[1]; - } - - // We are completing the value of a property - String prefix = arg.substring(0, arg.length() - lastValue.length()); - - IProperty property = block.getBlockState().getProperty(lastName); - if (property == null) { - // The property does not exist so there's no values to complete - return Stream.empty(); - } - return new TabCompleteHelper() - .append(getValues(property)) - .filterPrefix(lastValue) + .append( + Block.REGISTRY.getKeys() + .stream() + .map(Object::toString) + ) + .filterPrefixNamespaced(ctx.getConsumer().getString()) .sortAlphabetically() - .map(val -> prefix + val) .stream(); } - - /** - * Always returns exactly two strings. - * If the separator is not found the FIRST returned string is empty. - */ - private static String[] splitLast(String string, char chr) { - int idx = string.lastIndexOf(chr); - if (idx == -1) { - return new String[]{"", string}; - } - return new String[]{string.substring(0, idx), string.substring(idx + 1)}; - } - - // this shouldn't need to be a separate method? - private static > Stream getValues(IProperty property) { - return property.getAllowedValues().stream().map(property::getName); - } } diff --git a/src/api/java/baritone/api/command/datatypes/ForBlockOptionalMeta.java b/src/api/java/baritone/api/command/datatypes/ForBlockOptionalMeta.java index 978450a23..079ec03fd 100644 --- a/src/api/java/baritone/api/command/datatypes/ForBlockOptionalMeta.java +++ b/src/api/java/baritone/api/command/datatypes/ForBlockOptionalMeta.java @@ -18,20 +18,136 @@ package baritone.api.command.datatypes; import baritone.api.command.exception.CommandException; +import baritone.api.command.helpers.TabCompleteHelper; import baritone.api.utils.BlockOptionalMeta; +import net.minecraft.block.Block; +import net.minecraft.block.properties.IProperty; +import net.minecraft.util.ResourceLocation; +import java.util.Set; +import java.util.regex.Pattern; +import java.util.stream.Collectors; import java.util.stream.Stream; public enum ForBlockOptionalMeta implements IDatatypeFor { INSTANCE; + /** + * Matches (domain:)?name([(property=value)*])? but the input can be truncated at any position. + * domain and name are [a-z0-9_.-]+ and [a-z0-9/_.-]+ because that's what mc 1.13+ accepts. + * property and value use the same format as domain. + */ + // Good luck reading this. + private static Pattern PATTERN = Pattern.compile("(?:[a-z0-9_.-]+:)?(?:[a-z0-9/_.-]+(?:\\[(?:(?:[a-z0-9_.-]+=[a-z0-9_.-]+,)*(?:[a-z0-9_.-]+(?:=(?:[a-z0-9_.-]+(?:\\])?)?)?)?|\\])?)?)?"); + @Override public BlockOptionalMeta get(IDatatypeContext ctx) throws CommandException { return new BlockOptionalMeta(ctx.getConsumer().getString()); } @Override - public Stream tabComplete(IDatatypeContext ctx) { - return ctx.getConsumer().tabCompleteDatatype(BlockById.INSTANCE); + public Stream tabComplete(IDatatypeContext ctx) throws CommandException { + String arg = ctx.getConsumer().peekString(); + + if (!PATTERN.matcher(arg).matches()) { + // Invalid format; we can't complete this. + ctx.getConsumer().getString(); + return Stream.empty(); + } + + if (arg.endsWith("]")) { + // We are already done. + ctx.getConsumer().getString(); + return Stream.empty(); + } + + if (!arg.contains("[")) { + // no properties so we are completing the block id + return ctx.getConsumer().tabCompleteDatatype(BlockById.INSTANCE); + } + + ctx.getConsumer().getString(); + + // destructuring assignment? Please? + String blockId, properties; + { + String[] parts = splitLast(arg, '['); + blockId = parts[0]; + properties = parts[1]; + } + + Block block = Block.REGISTRY.getObject(new ResourceLocation(blockId)); + if (block == null) { + // This block doesn't exist so there's no properties to complete. + return Stream.empty(); + } + + String leadingProperties, lastProperty; + { + String[] parts = splitLast(properties, ','); + leadingProperties = parts[0]; + lastProperty = parts[1]; + } + + if (!lastProperty.contains("=")) { + // The last property-value pair doesn't have a value yet so we are completing its name + Set usedProps = Stream.of(leadingProperties.split(",")) + .map(pair -> pair.split("=")[0]) + .collect(Collectors.toSet()); + + String prefix = arg.substring(0, arg.length() - lastProperty.length()); + return new TabCompleteHelper() + .append( + block.getBlockState() + .getProperties() + .stream() + .map(IProperty::getName) + ) + .filter(prop -> !usedProps.contains(prop)) + .filterPrefix(lastProperty) + .sortAlphabetically() + .map(prop -> prefix + prop) + .stream(); + } + + String lastName, lastValue; + { + String[] parts = splitLast(lastProperty, '='); + lastName = parts[0]; + lastValue = parts[1]; + } + + // We are completing the value of a property + String prefix = arg.substring(0, arg.length() - lastValue.length()); + + IProperty property = block.getBlockState().getProperty(lastName); + if (property == null) { + // The property does not exist so there's no values to complete + return Stream.empty(); + } + + return new TabCompleteHelper() + .append(getValues(property)) + .filterPrefix(lastValue) + .sortAlphabetically() + .map(val -> prefix + val) + .stream(); + } + + /** + * Always returns exactly two strings. + * If the separator is not found the FIRST returned string is empty. + */ + private static String[] splitLast(String string, char chr) { + int idx = string.lastIndexOf(chr); + if (idx == -1) { + return new String[]{"", string}; + } + return new String[]{string.substring(0, idx), string.substring(idx + 1)}; + } + + // this shouldn't need to be a separate method? + private static > Stream getValues(IProperty property) { + return property.getAllowedValues().stream().map(property::getName); } } From f55f7f19b4bb6ad6d36bdaeabe0eb6bcc6b84748 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Mon, 19 Jun 2023 23:50:42 +0200 Subject: [PATCH 173/405] Tab complete the datatype which will be parsed --- src/main/java/baritone/command/defaults/GotoCommand.java | 3 +-- src/main/java/baritone/command/defaults/MineCommand.java | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/baritone/command/defaults/GotoCommand.java b/src/main/java/baritone/command/defaults/GotoCommand.java index 333d7fa57..fc43026bb 100644 --- a/src/main/java/baritone/command/defaults/GotoCommand.java +++ b/src/main/java/baritone/command/defaults/GotoCommand.java @@ -20,7 +20,6 @@ package baritone.command.defaults; import baritone.api.IBaritone; import baritone.api.command.Command; import baritone.api.command.argument.IArgConsumer; -import baritone.api.command.datatypes.BlockById; import baritone.api.command.datatypes.ForBlockOptionalMeta; import baritone.api.command.datatypes.RelativeCoordinate; import baritone.api.command.datatypes.RelativeGoal; @@ -61,7 +60,7 @@ public class GotoCommand extends Command { public Stream tabComplete(String label, IArgConsumer args) throws CommandException { // since it's either a goal or a block, I don't think we can tab complete properly? // so just tab complete for the block variant - return args.tabCompleteDatatype(BlockById.INSTANCE); + return args.tabCompleteDatatype(ForBlockOptionalMeta.INSTANCE); } @Override diff --git a/src/main/java/baritone/command/defaults/MineCommand.java b/src/main/java/baritone/command/defaults/MineCommand.java index 1ab5c3321..52e9e0e67 100644 --- a/src/main/java/baritone/command/defaults/MineCommand.java +++ b/src/main/java/baritone/command/defaults/MineCommand.java @@ -21,7 +21,6 @@ import baritone.api.BaritoneAPI; import baritone.api.IBaritone; import baritone.api.command.Command; import baritone.api.command.argument.IArgConsumer; -import baritone.api.command.datatypes.BlockById; import baritone.api.command.datatypes.ForBlockOptionalMeta; import baritone.api.command.exception.CommandException; import baritone.api.utils.BlockOptionalMeta; @@ -53,7 +52,7 @@ public class MineCommand extends Command { @Override public Stream tabComplete(String label, IArgConsumer args) { - return args.tabCompleteDatatype(BlockById.INSTANCE); + return args.tabCompleteDatatype(ForBlockOptionalMeta.INSTANCE); } @Override From e57a84ded4b0af83b8388c9dfad016782d14b70f Mon Sep 17 00:00:00 2001 From: Babbaj Date: Mon, 19 Jun 2023 17:58:06 -0400 Subject: [PATCH 174/405] use legacy raytrace with ignore liquid to get out of lava --- .../baritone/behavior/ElytraBehavior.java | 236 ++++++++++++++++-- .../elytra/NetherPathfinderContext.java | 4 +- 2 files changed, 219 insertions(+), 21 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index a0502d930..1bf098132 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -222,12 +222,12 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // not loaded yet? return; } - if (!passable(ctx.world().getBlockState(path.get(rangeStartIncl)))) { + if (!passable(ctx.world().getBlockState(path.get(rangeStartIncl)), false)) { // we're in a wall return; // previous iterations of this function SHOULD have fixed this by now :rage_cat: } for (int i = rangeStartIncl; i < rangeEndExcl - 1; i++) { - if (!clearView(pathAt(i), pathAt(i + 1))) { + if (!clearView(pathAt(i), pathAt(i + 1), false)) { // obstacle. where do we return to pathing? // find the next valid segment this.pathRecalcSegment(i, rangeEndExcl - 1); @@ -363,6 +363,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H BetterBlockPos goingTo = null; boolean forceUseFirework = false; this.sinceFirework++; + final boolean isInLava = ctx.player().isInLava(); outermost: for (int relaxation = 0; relaxation < 3; relaxation++) { // try for a strict solution first, then relax more and more (if we're in a corner or near some blocks, it will have to relax its constraints a bit) @@ -379,13 +380,13 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H continue; } if (start.distanceTo(dest) < 40) { - if (!clearView(dest, this.pathManager.pathAt(i + lookahead).add(0, dy, 0)) || !clearView(dest, this.pathManager.pathAt(i + lookahead))) { + if (!clearView(dest, this.pathManager.pathAt(i + lookahead).add(0, dy, 0), false) || !clearView(dest, this.pathManager.pathAt(i + lookahead), false)) { // aka: don't go upwards if doing so would prevent us from being able to see the next position **OR** the modified next position continue; } } else { // but if it's far away, allow gaining altitude if we could lose it again by the time we get there - if (!clearView(dest, this.pathManager.pathAt(i))) { + if (!clearView(dest, this.pathManager.pathAt(i), false)) { continue; } } @@ -395,10 +396,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final Double grow = relaxation == 2 ? null : relaxation == 0 ? 1.0d : 0.25d; - if (isClear(start, dest, grow)) { + if (isClear(start, dest, grow, isInLava)) { final float yaw = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()).getYaw(); - final Pair pitch = this.solvePitch(dest.subtract(start), steps, relaxation, firework); + final Pair pitch = this.solvePitch(dest.subtract(start), steps, relaxation, firework, isInLava); if (pitch.first() == null) { baritone.getLookBehavior().updateTarget(new Rotation(yaw, ctx.playerRotations().getPitch()), false); continue; @@ -463,8 +464,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H .anyMatch(x -> Objects.equals(((IEntityFireworkRocket) x).getBoostedEntity(), ctx.player())); } - private boolean isClear(final Vec3d start, final Vec3d dest, final Double growAmount) { - if (!clearView(start, dest)) { + private boolean isClear(final Vec3d start, final Vec3d dest, final Double growAmount, boolean ignoreLava) { + if (!clearView(start, dest, ignoreLava)) { return false; } if (growAmount == null) { @@ -509,8 +510,14 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return true; } - private boolean clearView(Vec3d start, Vec3d dest) { - boolean clear = !this.context.raytrace(start.x, start.y, start.z, dest.x, dest.y, dest.z); + private boolean clearView(Vec3d start, Vec3d dest, boolean ignoreLava) { + final boolean clear; + if (!ignoreLava) { + clear = !this.context.raytrace(start.x, start.y, start.z, dest.x, dest.y, dest.z); + } else { + clear = !rayTraceBlocks(start.x, start.y, start.z, dest.x, dest.y, dest.z, true); + } + if (clear) { clearLines.add(new Pair<>(start, dest)); return true; @@ -520,14 +527,14 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } - private Pair solvePitch(Vec3d goalDirection, int steps, int relaxation, boolean currentlyBoosted) { - final Float pitch = this.solvePitch(goalDirection, steps, relaxation == 2, currentlyBoosted); + private Pair solvePitch(Vec3d goalDirection, int steps, int relaxation, boolean currentlyBoosted, boolean ignoreLava) { + final Float pitch = this.solvePitch(goalDirection, steps, relaxation == 2, currentlyBoosted, ignoreLava); if (pitch != null) { return new Pair<>(pitch, false); } if (Baritone.settings().experimentalTakeoff.value && relaxation > 0) { - final Float usingFirework = this.solvePitch(goalDirection, steps, relaxation == 2, true); + final Float usingFirework = this.solvePitch(goalDirection, steps, relaxation == 2, true, ignoreLava); if (usingFirework != null) { return new Pair<>(usingFirework, true); } @@ -536,7 +543,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return new Pair<>(null, false); } - private Float solvePitch(Vec3d goalDirection, int steps, boolean desperate, boolean firework) { + private Float solvePitch(Vec3d goalDirection, int steps, boolean desperate, boolean firework, boolean ignoreLava) { // we are at a certain velocity, but we have a target velocity // what pitch would get us closest to our target velocity? // yaw is easy so we only care about pitch @@ -561,7 +568,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H for (int x = MathHelper.floor(Math.min(actualPosition.x, actualPositionPrevTick.x) - 0.31); x <= Math.max(actualPosition.x, actualPositionPrevTick.x) + 0.31; x++) { for (int y = MathHelper.floor(Math.min(actualPosition.y, actualPositionPrevTick.y) - 0.2); y <= Math.max(actualPosition.y, actualPositionPrevTick.y) + 1; y++) { for (int z = MathHelper.floor(Math.min(actualPosition.z, actualPositionPrevTick.z) - 0.31); z <= Math.max(actualPosition.z, actualPositionPrevTick.z) + 0.31; z++) { - if (!this.passable(x, y, z)) { + if (!this.passable(x, y, z, ignoreLava)) { continue outer; } } @@ -579,12 +586,13 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return bestPitch; } - public boolean passable(int x, int y, int z) { - return passable(this.bsi.get0(x, y, z)); + public boolean passable(int x, int y, int z, boolean ignoreLava) { + return passable(this.bsi.get0(x, y, z), ignoreLava); } - public static boolean passable(IBlockState state) { - return state.getMaterial() == Material.AIR; + public static boolean passable(IBlockState state, boolean ignoreLava) { + Material mat = state.getMaterial(); + return mat == Material.AIR || (ignoreLava && mat == Material.LAVA); } private static Vec3d step(Vec3d motion, float rotationPitch, float rotationYaw, boolean firework) { @@ -637,5 +645,195 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return new Vec3d(motionX, motionY, motionZ); } + + private boolean rayTraceBlocks(final double startX, final double startY, final double startZ, + final double endX, final double endY, final double endZ, boolean ignoreLava) { + int voxelCurrX = fastFloor(startX); + int voxelCurrY = fastFloor(startY); + int voxelCurrZ = fastFloor(startZ); + + if (!this.passable(voxelCurrX, voxelCurrY, voxelCurrZ, ignoreLava)) { + return true; + } + + final int voxelEndX = fastFloor(endX); + final int voxelEndY = fastFloor(endY); + final int voxelEndZ = fastFloor(endZ); + double currPosX = startX; + double currPosY = startY; + double currPosZ = startZ; + + int steps = 200; // TODO: should we lower the max steps? + while (steps-- >= 0) { + if (voxelCurrX == voxelEndX && voxelCurrY == voxelEndY && voxelCurrZ == voxelEndZ) { + return false; + } + + final double distanceFromStartToEndX = endX - currPosX; + final double distanceFromStartToEndY = endY - currPosY; + final double distanceFromStartToEndZ = endZ - currPosZ; + + double nextIntegerX; + double nextIntegerY; + double nextIntegerZ; + // potentially more based branchless impl? + nextIntegerX = voxelCurrX + ((voxelCurrX - voxelEndX) >>> 31); // if voxelEnd > voxelIn, then voxelIn-voxelEnd will be negative, meaning the sign bit is 1 + nextIntegerY = voxelCurrY + ((voxelCurrY - voxelEndY) >>> 31); // if we do an unsigned right shift by 31, that sign bit becomes the LSB + nextIntegerZ = voxelCurrZ + ((voxelCurrZ - voxelEndZ) >>> 31); // therefore, this increments nextInteger iff EndX>inX, otherwise it leaves it alone + // remember: don't have to worry about the case when voxelEnd == voxelIn, because nextInteger value wont be used + + // these just have to be strictly greater than 1, might as well just go up to the next int + double fracIfSkipX = 2.0D; + double fracIfSkipY = 2.0D; + double fracIfSkipZ = 2.0D; + + // reminder to future self: don't "branchlessify" this, it's MUCH slower (pretty obviously, floating point div is much worse than a branch mispredict, but integer increment (like the other two removed branches) are cheap enough to be worth doing either way) + if (voxelEndX != voxelCurrX) { + fracIfSkipX = (nextIntegerX - currPosX) / distanceFromStartToEndX; + } + if (voxelEndY != voxelCurrY) { + fracIfSkipY = (nextIntegerY - currPosY) / distanceFromStartToEndY; + } + if (voxelEndZ != voxelCurrZ) { + fracIfSkipZ = (nextIntegerZ - currPosZ) / distanceFromStartToEndZ; + } + + if (fracIfSkipX < fracIfSkipY && fracIfSkipX < fracIfSkipZ) { + // note: voxelEndX == voxelInX is impossible because allowSkip would be set to false in that case, meaning that the elapsed distance would stay at default + currPosX = nextIntegerX; + currPosY += distanceFromStartToEndY * fracIfSkipX; + currPosZ += distanceFromStartToEndZ * fracIfSkipX; + // tested: faster to paste this 3 times with only one of the subtractions in each + final int xFloorOffset = (voxelEndX - voxelCurrX) >>> 31; + voxelCurrX = (fastFloor(currPosX) - xFloorOffset); + voxelCurrY = (fastFloor(currPosY)); + voxelCurrZ = (fastFloor(currPosZ)); + } else if (fracIfSkipY < fracIfSkipZ) { + currPosX += distanceFromStartToEndX * fracIfSkipY; + currPosY = nextIntegerY; + currPosZ += distanceFromStartToEndZ * fracIfSkipY; + // tested: faster to paste this 3 times with only one of the subtractions in each + final int yFloorOffset = (voxelEndY - voxelCurrY) >>> 31; + voxelCurrX = (fastFloor(currPosX)); + voxelCurrY = (fastFloor(currPosY) - yFloorOffset); + voxelCurrZ = (fastFloor(currPosZ)); + } else { + currPosX += distanceFromStartToEndX * fracIfSkipZ; + currPosY += distanceFromStartToEndY * fracIfSkipZ; + currPosZ = nextIntegerZ; + // tested: faster to paste this 3 times with only one of the subtractions in each + final int zFloorOffset = (voxelEndZ - voxelCurrZ) >>> 31; + voxelCurrX = (fastFloor(currPosX)); + voxelCurrY = (fastFloor(currPosY)); + voxelCurrZ = (fastFloor(currPosZ) - zFloorOffset); + } + + if (!this.passable(voxelCurrX, voxelCurrY, voxelCurrZ, ignoreLava)) { + return true; + } + } + return false; + } + + private static final double FLOOR_DOUBLE_D = 1_073_741_824.0; + private static final int FLOOR_DOUBLE_I = 1_073_741_824; + + private static int fastFloor(final double v) { + return ((int) (v + FLOOR_DOUBLE_D)) - FLOOR_DOUBLE_I; + } + + private boolean rayTraceBlocks(Vec3d start, Vec3d end, boolean ignoreLava) { + int x1 = MathHelper.floor(end.x); + int y1 = MathHelper.floor(end.y); + int z1 = MathHelper.floor(end.z); + int x2 = MathHelper.floor(start.x); + int y2 = MathHelper.floor(start.y); + int z2 = MathHelper.floor(start.z); + BlockPos blockpos = new BlockPos(x2, y2, z2); + IBlockState iblockstate = ctx.world().getBlockState(blockpos); + if (!passable(iblockstate, ignoreLava)) { + return true; + } + int steps = 200; + while (steps-- >= 0) { + if (Double.isNaN(start.x) || Double.isNaN(start.y) || Double.isNaN(start.z)) { + return false; + } + if (x2 == x1 && y2 == y1 && z2 == z1) { + return false; + } + boolean hitX = true; + boolean hitY = true; + boolean hitZ = true; + double nextX = 999.0D; + double nextY = 999.0D; + double nextZ = 999.0D; + if (x1 > x2) { + nextX = (double) x2 + 1.0D; + } else if (x1 < x2) { + nextX = (double) x2 + 0.0D; + } else { + hitX = false; + } + if (y1 > y2) { + nextY = (double) y2 + 1.0D; + } else if (y1 < y2) { + nextY = (double) y2 + 0.0D; + } else { + hitY = false; + } + if (z1 > z2) { + nextZ = (double) z2 + 1.0D; + } else if (z1 < z2) { + nextZ = (double) z2 + 0.0D; + } else { + hitZ = false; + } + double stepX = 999.0D; + double stepY = 999.0D; + double stepZ = 999.0D; + double dirX = end.x - start.x; + double dirY = end.y - start.y; + double dirZ = end.z - start.z; + if (hitX) { + stepX = (nextX - start.x) / dirX; + } + if (hitY) { + stepY = (nextY - start.y) / dirY; + } + if (hitZ) { + stepZ = (nextZ - start.z) / dirZ; + } + if (stepX == -0.0D) { + stepX = -1.0E-4D; + } + if (stepY == -0.0D) { + stepY = -1.0E-4D; + } + if (stepZ == -0.0D) { + stepZ = -1.0E-4D; + } + EnumFacing dir; + if (stepX < stepY && stepX < stepZ) { + dir = x1 > x2 ? EnumFacing.WEST : EnumFacing.EAST; + start = new Vec3d(nextX, start.y + dirY * stepX, start.z + dirZ * stepX); + } else if (stepY < stepZ) { + dir = y1 > y2 ? EnumFacing.DOWN : EnumFacing.UP; + start = new Vec3d(start.x + dirX * stepY, nextY, start.z + dirZ * stepY); + } else { + dir = z1 > z2 ? EnumFacing.NORTH : EnumFacing.SOUTH; + start = new Vec3d(start.x + dirX * stepZ, start.y + dirY * stepZ, nextZ); + } + x2 = MathHelper.floor(start.x) - (dir == EnumFacing.EAST ? 1 : 0); + y2 = MathHelper.floor(start.y) - (dir == EnumFacing.UP ? 1 : 0); + z2 = MathHelper.floor(start.z) - (dir == EnumFacing.SOUTH ? 1 : 0); + blockpos = new BlockPos(x2, y2, z2); + IBlockState iblockstate1 = ctx.world().getBlockState(blockpos); + if (!passable(iblockstate1, ignoreLava)) { + return true; + } + } + return false; + } } diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index 0a833ab5d..bdee1a037 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -120,7 +120,7 @@ public final class NetherPathfinderContext { for (int z = 0; z < 16; z++) { for (int x = 0; x < 16; x++) { IBlockState state = bsc.get(x, y1, z); - if (!passable(state)) { + if (!passable(state, false)) { packed[x | (z << 4) | (y << 8)] = true; } } @@ -133,4 +133,4 @@ public final class NetherPathfinderContext { throw new RuntimeException(e); } } -} \ No newline at end of file +} From 13742df877ac734eb393df5d8a2dcd6336b3bdb5 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Tue, 20 Jun 2023 00:00:52 +0200 Subject: [PATCH 175/405] Complete the last argument, not the first one --- src/main/java/baritone/command/defaults/MineCommand.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/baritone/command/defaults/MineCommand.java b/src/main/java/baritone/command/defaults/MineCommand.java index 52e9e0e67..0f0f9bcb1 100644 --- a/src/main/java/baritone/command/defaults/MineCommand.java +++ b/src/main/java/baritone/command/defaults/MineCommand.java @@ -51,7 +51,11 @@ public class MineCommand extends Command { } @Override - public Stream tabComplete(String label, IArgConsumer args) { + public Stream tabComplete(String label, IArgConsumer args) throws CommandException { + args.getAsOrDefault(Integer.class, 0); + while (args.has(2)) { + args.getDatatypeFor(ForBlockOptionalMeta.INSTANCE); + } return args.tabCompleteDatatype(ForBlockOptionalMeta.INSTANCE); } From 84777c2437cb72a028a9f59148187a5c503807c0 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Tue, 20 Jun 2023 00:01:33 +0200 Subject: [PATCH 176/405] Don't complete more than what's supported --- src/main/java/baritone/command/defaults/GotoCommand.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/baritone/command/defaults/GotoCommand.java b/src/main/java/baritone/command/defaults/GotoCommand.java index fc43026bb..c64d7fa00 100644 --- a/src/main/java/baritone/command/defaults/GotoCommand.java +++ b/src/main/java/baritone/command/defaults/GotoCommand.java @@ -60,6 +60,7 @@ public class GotoCommand extends Command { public Stream tabComplete(String label, IArgConsumer args) throws CommandException { // since it's either a goal or a block, I don't think we can tab complete properly? // so just tab complete for the block variant + args.requireMax(1); return args.tabCompleteDatatype(ForBlockOptionalMeta.INSTANCE); } From b111fd2f3ef610dfebc5c3b41e1d4021ff829213 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Tue, 20 Jun 2023 00:02:56 +0200 Subject: [PATCH 177/405] Don't construct malformed `ResourceLocation`s Later mc versions throw an exception when you construct a malformed `ResourceLocation`. --- .../baritone/api/command/datatypes/BlockById.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/api/java/baritone/api/command/datatypes/BlockById.java b/src/api/java/baritone/api/command/datatypes/BlockById.java index 3702725e3..0efb738ca 100644 --- a/src/api/java/baritone/api/command/datatypes/BlockById.java +++ b/src/api/java/baritone/api/command/datatypes/BlockById.java @@ -23,11 +23,17 @@ import net.minecraft.block.Block; import net.minecraft.init.Blocks; import net.minecraft.util.ResourceLocation; +import java.util.regex.Pattern; import java.util.stream.Stream; public enum BlockById implements IDatatypeFor { INSTANCE; + /** + * Matches (domain:)?name? where domain and name are [a-z0-9_.-]+ and [a-z0-9/_.-]+ respectively. + */ + private static Pattern PATTERN = Pattern.compile("(?:[a-z0-9_.-]+:)?[a-z0-9/_.-]*"); + @Override public Block get(IDatatypeContext ctx) throws CommandException { ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString()); @@ -40,13 +46,19 @@ public enum BlockById implements IDatatypeFor { @Override public Stream tabComplete(IDatatypeContext ctx) throws CommandException { + String arg = ctx.getConsumer().getString(); + + if (!PATTERN.matcher(arg).matches()) { + return Stream.empty(); + } + return new TabCompleteHelper() .append( Block.REGISTRY.getKeys() .stream() .map(Object::toString) ) - .filterPrefixNamespaced(ctx.getConsumer().getString()) + .filterPrefixNamespaced(arg) .sortAlphabetically() .stream(); } From 5f709eef9c0099b7d28b4e11ca46219c8350afde Mon Sep 17 00:00:00 2001 From: Babbaj Date: Mon, 19 Jun 2023 18:26:00 -0400 Subject: [PATCH 178/405] use world raytrace --- .../baritone/behavior/ElytraBehavior.java | 197 +----------------- 1 file changed, 2 insertions(+), 195 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 1bf098132..f2e22248b 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -36,10 +36,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.NonNullList; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.*; import net.minecraft.world.chunk.Chunk; import java.util.*; @@ -515,7 +512,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H if (!ignoreLava) { clear = !this.context.raytrace(start.x, start.y, start.z, dest.x, dest.y, dest.z); } else { - clear = !rayTraceBlocks(start.x, start.y, start.z, dest.x, dest.y, dest.z, true); + clear = ctx.world().rayTraceBlocks(start, dest, false, false, false) == null; } if (clear) { @@ -645,195 +642,5 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return new Vec3d(motionX, motionY, motionZ); } - - private boolean rayTraceBlocks(final double startX, final double startY, final double startZ, - final double endX, final double endY, final double endZ, boolean ignoreLava) { - int voxelCurrX = fastFloor(startX); - int voxelCurrY = fastFloor(startY); - int voxelCurrZ = fastFloor(startZ); - - if (!this.passable(voxelCurrX, voxelCurrY, voxelCurrZ, ignoreLava)) { - return true; - } - - final int voxelEndX = fastFloor(endX); - final int voxelEndY = fastFloor(endY); - final int voxelEndZ = fastFloor(endZ); - double currPosX = startX; - double currPosY = startY; - double currPosZ = startZ; - - int steps = 200; // TODO: should we lower the max steps? - while (steps-- >= 0) { - if (voxelCurrX == voxelEndX && voxelCurrY == voxelEndY && voxelCurrZ == voxelEndZ) { - return false; - } - - final double distanceFromStartToEndX = endX - currPosX; - final double distanceFromStartToEndY = endY - currPosY; - final double distanceFromStartToEndZ = endZ - currPosZ; - - double nextIntegerX; - double nextIntegerY; - double nextIntegerZ; - // potentially more based branchless impl? - nextIntegerX = voxelCurrX + ((voxelCurrX - voxelEndX) >>> 31); // if voxelEnd > voxelIn, then voxelIn-voxelEnd will be negative, meaning the sign bit is 1 - nextIntegerY = voxelCurrY + ((voxelCurrY - voxelEndY) >>> 31); // if we do an unsigned right shift by 31, that sign bit becomes the LSB - nextIntegerZ = voxelCurrZ + ((voxelCurrZ - voxelEndZ) >>> 31); // therefore, this increments nextInteger iff EndX>inX, otherwise it leaves it alone - // remember: don't have to worry about the case when voxelEnd == voxelIn, because nextInteger value wont be used - - // these just have to be strictly greater than 1, might as well just go up to the next int - double fracIfSkipX = 2.0D; - double fracIfSkipY = 2.0D; - double fracIfSkipZ = 2.0D; - - // reminder to future self: don't "branchlessify" this, it's MUCH slower (pretty obviously, floating point div is much worse than a branch mispredict, but integer increment (like the other two removed branches) are cheap enough to be worth doing either way) - if (voxelEndX != voxelCurrX) { - fracIfSkipX = (nextIntegerX - currPosX) / distanceFromStartToEndX; - } - if (voxelEndY != voxelCurrY) { - fracIfSkipY = (nextIntegerY - currPosY) / distanceFromStartToEndY; - } - if (voxelEndZ != voxelCurrZ) { - fracIfSkipZ = (nextIntegerZ - currPosZ) / distanceFromStartToEndZ; - } - - if (fracIfSkipX < fracIfSkipY && fracIfSkipX < fracIfSkipZ) { - // note: voxelEndX == voxelInX is impossible because allowSkip would be set to false in that case, meaning that the elapsed distance would stay at default - currPosX = nextIntegerX; - currPosY += distanceFromStartToEndY * fracIfSkipX; - currPosZ += distanceFromStartToEndZ * fracIfSkipX; - // tested: faster to paste this 3 times with only one of the subtractions in each - final int xFloorOffset = (voxelEndX - voxelCurrX) >>> 31; - voxelCurrX = (fastFloor(currPosX) - xFloorOffset); - voxelCurrY = (fastFloor(currPosY)); - voxelCurrZ = (fastFloor(currPosZ)); - } else if (fracIfSkipY < fracIfSkipZ) { - currPosX += distanceFromStartToEndX * fracIfSkipY; - currPosY = nextIntegerY; - currPosZ += distanceFromStartToEndZ * fracIfSkipY; - // tested: faster to paste this 3 times with only one of the subtractions in each - final int yFloorOffset = (voxelEndY - voxelCurrY) >>> 31; - voxelCurrX = (fastFloor(currPosX)); - voxelCurrY = (fastFloor(currPosY) - yFloorOffset); - voxelCurrZ = (fastFloor(currPosZ)); - } else { - currPosX += distanceFromStartToEndX * fracIfSkipZ; - currPosY += distanceFromStartToEndY * fracIfSkipZ; - currPosZ = nextIntegerZ; - // tested: faster to paste this 3 times with only one of the subtractions in each - final int zFloorOffset = (voxelEndZ - voxelCurrZ) >>> 31; - voxelCurrX = (fastFloor(currPosX)); - voxelCurrY = (fastFloor(currPosY)); - voxelCurrZ = (fastFloor(currPosZ) - zFloorOffset); - } - - if (!this.passable(voxelCurrX, voxelCurrY, voxelCurrZ, ignoreLava)) { - return true; - } - } - return false; - } - - private static final double FLOOR_DOUBLE_D = 1_073_741_824.0; - private static final int FLOOR_DOUBLE_I = 1_073_741_824; - - private static int fastFloor(final double v) { - return ((int) (v + FLOOR_DOUBLE_D)) - FLOOR_DOUBLE_I; - } - - private boolean rayTraceBlocks(Vec3d start, Vec3d end, boolean ignoreLava) { - int x1 = MathHelper.floor(end.x); - int y1 = MathHelper.floor(end.y); - int z1 = MathHelper.floor(end.z); - int x2 = MathHelper.floor(start.x); - int y2 = MathHelper.floor(start.y); - int z2 = MathHelper.floor(start.z); - BlockPos blockpos = new BlockPos(x2, y2, z2); - IBlockState iblockstate = ctx.world().getBlockState(blockpos); - if (!passable(iblockstate, ignoreLava)) { - return true; - } - int steps = 200; - while (steps-- >= 0) { - if (Double.isNaN(start.x) || Double.isNaN(start.y) || Double.isNaN(start.z)) { - return false; - } - if (x2 == x1 && y2 == y1 && z2 == z1) { - return false; - } - boolean hitX = true; - boolean hitY = true; - boolean hitZ = true; - double nextX = 999.0D; - double nextY = 999.0D; - double nextZ = 999.0D; - if (x1 > x2) { - nextX = (double) x2 + 1.0D; - } else if (x1 < x2) { - nextX = (double) x2 + 0.0D; - } else { - hitX = false; - } - if (y1 > y2) { - nextY = (double) y2 + 1.0D; - } else if (y1 < y2) { - nextY = (double) y2 + 0.0D; - } else { - hitY = false; - } - if (z1 > z2) { - nextZ = (double) z2 + 1.0D; - } else if (z1 < z2) { - nextZ = (double) z2 + 0.0D; - } else { - hitZ = false; - } - double stepX = 999.0D; - double stepY = 999.0D; - double stepZ = 999.0D; - double dirX = end.x - start.x; - double dirY = end.y - start.y; - double dirZ = end.z - start.z; - if (hitX) { - stepX = (nextX - start.x) / dirX; - } - if (hitY) { - stepY = (nextY - start.y) / dirY; - } - if (hitZ) { - stepZ = (nextZ - start.z) / dirZ; - } - if (stepX == -0.0D) { - stepX = -1.0E-4D; - } - if (stepY == -0.0D) { - stepY = -1.0E-4D; - } - if (stepZ == -0.0D) { - stepZ = -1.0E-4D; - } - EnumFacing dir; - if (stepX < stepY && stepX < stepZ) { - dir = x1 > x2 ? EnumFacing.WEST : EnumFacing.EAST; - start = new Vec3d(nextX, start.y + dirY * stepX, start.z + dirZ * stepX); - } else if (stepY < stepZ) { - dir = y1 > y2 ? EnumFacing.DOWN : EnumFacing.UP; - start = new Vec3d(start.x + dirX * stepY, nextY, start.z + dirZ * stepY); - } else { - dir = z1 > z2 ? EnumFacing.NORTH : EnumFacing.SOUTH; - start = new Vec3d(start.x + dirX * stepZ, start.y + dirY * stepZ, nextZ); - } - x2 = MathHelper.floor(start.x) - (dir == EnumFacing.EAST ? 1 : 0); - y2 = MathHelper.floor(start.y) - (dir == EnumFacing.UP ? 1 : 0); - z2 = MathHelper.floor(start.z) - (dir == EnumFacing.SOUTH ? 1 : 0); - blockpos = new BlockPos(x2, y2, z2); - IBlockState iblockstate1 = ctx.world().getBlockState(blockpos); - if (!passable(iblockstate1, ignoreLava)) { - return true; - } - } - return false; - } } From f7a20a3acf49fb1c4b6a9553d1b9d02d2bfd2e49 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Tue, 20 Jun 2023 01:32:18 +0200 Subject: [PATCH 179/405] Don't swallow random exceptions, don't bother with CommandExceptions --- src/main/java/baritone/command/argument/ArgConsumer.java | 2 ++ src/main/java/baritone/command/manager/CommandManager.java | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/baritone/command/argument/ArgConsumer.java b/src/main/java/baritone/command/argument/ArgConsumer.java index 4a80681dd..42ac1e5a0 100644 --- a/src/main/java/baritone/command/argument/ArgConsumer.java +++ b/src/main/java/baritone/command/argument/ArgConsumer.java @@ -373,6 +373,8 @@ public class ArgConsumer implements IArgConsumer { public Stream tabCompleteDatatype(T datatype) { try { return datatype.tabComplete(this.context); + } catch (CommandException ignored) { + // NOP } catch (Exception e) { e.printStackTrace(); } diff --git a/src/main/java/baritone/command/manager/CommandManager.java b/src/main/java/baritone/command/manager/CommandManager.java index e7d24eb33..26f369df9 100644 --- a/src/main/java/baritone/command/manager/CommandManager.java +++ b/src/main/java/baritone/command/manager/CommandManager.java @@ -151,9 +151,12 @@ public class CommandManager implements ICommandManager { private Stream tabComplete() { try { return this.command.tabComplete(this.label, this.args); + } catch (CommandException ignored) { + // NOP } catch (Throwable t) { - return Stream.empty(); + t.printStackTrace(); } + return Stream.empty(); } } } From 31c9072970685e1a16ee191a8a94d8429c694634 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Tue, 20 Jun 2023 01:36:09 +0200 Subject: [PATCH 180/405] Forgot to git add --- src/main/java/baritone/command/manager/CommandManager.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/baritone/command/manager/CommandManager.java b/src/main/java/baritone/command/manager/CommandManager.java index 26f369df9..35cad4541 100644 --- a/src/main/java/baritone/command/manager/CommandManager.java +++ b/src/main/java/baritone/command/manager/CommandManager.java @@ -21,6 +21,7 @@ import baritone.Baritone; import baritone.api.IBaritone; import baritone.api.command.ICommand; import baritone.api.command.argument.ICommandArgument; +import baritone.api.command.exception.CommandException; import baritone.api.command.exception.CommandUnhandledException; import baritone.api.command.exception.ICommandException; import baritone.api.command.helpers.TabCompleteHelper; From d87d1ab9b55cee52abeb18b702b32573fd384006 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Tue, 20 Jun 2023 02:00:08 +0200 Subject: [PATCH 181/405] Don't call `partOfMask` out of bounds --- .../mask/operator/BinaryOperatorMask.java | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/api/java/baritone/api/schematic/mask/operator/BinaryOperatorMask.java b/src/api/java/baritone/api/schematic/mask/operator/BinaryOperatorMask.java index e591c7873..bcce96651 100644 --- a/src/api/java/baritone/api/schematic/mask/operator/BinaryOperatorMask.java +++ b/src/api/java/baritone/api/schematic/mask/operator/BinaryOperatorMask.java @@ -33,7 +33,7 @@ public final class BinaryOperatorMask extends AbstractMask { private final BooleanBinaryOperator operator; public BinaryOperatorMask(Mask a, Mask b, BooleanBinaryOperator operator) { - super(a.widthX(), a.heightY(), a.lengthZ()); + super(Math.max(a.widthX(), b.widthX()), Math.max(a.heightY(), b.heightY()), Math.max(a.lengthZ(), b.lengthZ())); this.a = a; this.b = b; this.operator = operator; @@ -42,11 +42,15 @@ public final class BinaryOperatorMask extends AbstractMask { @Override public boolean partOfMask(int x, int y, int z, IBlockState currentState) { return this.operator.applyAsBoolean( - this.a.partOfMask(x, y, z, currentState), - this.b.partOfMask(x, y, z, currentState) + partOfMask(a, x, y, z, currentState), + partOfMask(b, x, y, z, currentState) ); } + private static boolean partOfMask(Mask mask, int x, int y, int z, IBlockState currentState) { + return x < mask.widthX() && y < mask.heightY() && z < mask.lengthZ() && mask.partOfMask(x, y, z, currentState); + } + public static final class Static extends AbstractMask implements StaticMask { private final StaticMask a; @@ -54,7 +58,7 @@ public final class BinaryOperatorMask extends AbstractMask { private final BooleanBinaryOperator operator; public Static(StaticMask a, StaticMask b, BooleanBinaryOperator operator) { - super(a.widthX(), a.heightY(), a.lengthZ()); + super(Math.max(a.widthX(), b.widthX()), Math.max(a.heightY(), b.heightY()), Math.max(a.lengthZ(), b.lengthZ())); this.a = a; this.b = b; this.operator = operator; @@ -63,9 +67,13 @@ public final class BinaryOperatorMask extends AbstractMask { @Override public boolean partOfMask(int x, int y, int z) { return this.operator.applyAsBoolean( - this.a.partOfMask(x, y, z), - this.b.partOfMask(x, y, z) + partOfMask(a, x, y, z), + partOfMask(b, x, y, z) ); } + + private static boolean partOfMask(StaticMask mask, int x, int y, int z) { + return x < mask.widthX() && y < mask.heightY() && z < mask.lengthZ() && mask.partOfMask(x, y, z); + } } } From 30278a1c5254713e135c8a2a2bbf302b0fc4a2f1 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Tue, 20 Jun 2023 02:44:29 +0200 Subject: [PATCH 182/405] Implement `hashCode` for goals --- .../baritone/api/pathing/goals/GoalAxis.java | 5 ++++ .../baritone/api/pathing/goals/GoalBlock.java | 6 +++++ .../api/pathing/goals/GoalComposite.java | 5 ++++ .../api/pathing/goals/GoalGetToBlock.java | 6 +++++ .../api/pathing/goals/GoalInverted.java | 5 ++++ .../baritone/api/pathing/goals/GoalNear.java | 6 +++++ .../api/pathing/goals/GoalRunAway.java | 8 ++++++ .../pathing/goals/GoalStrictDirection.java | 9 +++++++ .../api/pathing/goals/GoalTwoBlocks.java | 6 +++++ .../baritone/api/pathing/goals/GoalXZ.java | 8 ++++++ .../api/pathing/goals/GoalYLevel.java | 5 ++++ .../java/baritone/process/BuilderProcess.java | 26 +++++++++++++++++++ .../java/baritone/process/MineProcess.java | 5 ++++ 13 files changed, 100 insertions(+) diff --git a/src/api/java/baritone/api/pathing/goals/GoalAxis.java b/src/api/java/baritone/api/pathing/goals/GoalAxis.java index ad8fb892e..6e2f84e7a 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalAxis.java +++ b/src/api/java/baritone/api/pathing/goals/GoalAxis.java @@ -47,6 +47,11 @@ public class GoalAxis implements Goal { return o.getClass() == GoalAxis.class; } + @Override + public int hashCode() { + return 201385781; + } + @Override public String toString() { return "GoalAxis"; diff --git a/src/api/java/baritone/api/pathing/goals/GoalBlock.java b/src/api/java/baritone/api/pathing/goals/GoalBlock.java index d76fdc7af..24faa9b34 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalBlock.java +++ b/src/api/java/baritone/api/pathing/goals/GoalBlock.java @@ -17,6 +17,7 @@ package baritone.api.pathing.goals; +import baritone.api.utils.BetterBlockPos; import baritone.api.utils.SettingsUtil; import baritone.api.utils.interfaces.IGoalRenderPos; import net.minecraft.util.math.BlockPos; @@ -81,6 +82,11 @@ public class GoalBlock implements Goal, IGoalRenderPos { && z == goal.z; } + @Override + public int hashCode() { + return (int) BetterBlockPos.longHash(x, y, z) * 905165533; + } + @Override public String toString() { return String.format( diff --git a/src/api/java/baritone/api/pathing/goals/GoalComposite.java b/src/api/java/baritone/api/pathing/goals/GoalComposite.java index d64f8e33e..8e13a86e4 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalComposite.java +++ b/src/api/java/baritone/api/pathing/goals/GoalComposite.java @@ -80,6 +80,11 @@ public class GoalComposite implements Goal { return Arrays.equals(goals, goal.goals); } + @Override + public int hashCode() { + return Arrays.hashCode(goals); + } + @Override public String toString() { return "GoalComposite" + Arrays.toString(goals); diff --git a/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java b/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java index b5caafa48..b8934a480 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java +++ b/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java @@ -17,6 +17,7 @@ package baritone.api.pathing.goals; +import baritone.api.utils.BetterBlockPos; import baritone.api.utils.SettingsUtil; import baritone.api.utils.interfaces.IGoalRenderPos; import net.minecraft.util.math.BlockPos; @@ -75,6 +76,11 @@ public class GoalGetToBlock implements Goal, IGoalRenderPos { && z == goal.z; } + @Override + public int hashCode() { + return (int) BetterBlockPos.longHash(x, y, z) * -49639096; + } + @Override public String toString() { return String.format( diff --git a/src/api/java/baritone/api/pathing/goals/GoalInverted.java b/src/api/java/baritone/api/pathing/goals/GoalInverted.java index e559088ef..4a3f75315 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalInverted.java +++ b/src/api/java/baritone/api/pathing/goals/GoalInverted.java @@ -65,6 +65,11 @@ public class GoalInverted implements Goal { return Objects.equals(origin, goal.origin); } + @Override + public int hashCode() { + return origin.hashCode() * 495796690; + } + @Override public String toString() { return String.format("GoalInverted{%s}", origin.toString()); diff --git a/src/api/java/baritone/api/pathing/goals/GoalNear.java b/src/api/java/baritone/api/pathing/goals/GoalNear.java index 166138ff4..e211c0194 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalNear.java +++ b/src/api/java/baritone/api/pathing/goals/GoalNear.java @@ -17,6 +17,7 @@ package baritone.api.pathing.goals; +import baritone.api.utils.BetterBlockPos; import baritone.api.utils.SettingsUtil; import baritone.api.utils.interfaces.IGoalRenderPos; import it.unimi.dsi.fastutil.doubles.DoubleIterator; @@ -102,6 +103,11 @@ public class GoalNear implements Goal, IGoalRenderPos { && rangeSq == goal.rangeSq; } + @Override + public int hashCode() { + return (int) BetterBlockPos.longHash(x, y, z) + rangeSq; + } + @Override public String toString() { return String.format( diff --git a/src/api/java/baritone/api/pathing/goals/GoalRunAway.java b/src/api/java/baritone/api/pathing/goals/GoalRunAway.java index 166ad5a98..1e65d30f7 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalRunAway.java +++ b/src/api/java/baritone/api/pathing/goals/GoalRunAway.java @@ -140,6 +140,14 @@ public class GoalRunAway implements Goal { && Objects.equals(maintainY, goal.maintainY); } + @Override + public int hashCode() { + int hash = Arrays.hashCode(from); + hash = hash * 1196803141 + distanceSq; + hash = hash * -2053788840 + maintainY; + return hash; + } + @Override public String toString() { if (maintainY != null) { diff --git a/src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java b/src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java index b8e4b43b2..b6bf16b33 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java +++ b/src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java @@ -17,6 +17,7 @@ package baritone.api.pathing.goals; +import baritone.api.utils.BetterBlockPos; import baritone.api.utils.SettingsUtil; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; @@ -86,6 +87,14 @@ public class GoalStrictDirection implements Goal { && dz == goal.dz; } + @Override + public int hashCode() { + int hash = (int) BetterBlockPos.longHash(x, y, z); + hash = hash * 630627507 + dx; + hash = hash * -283028380 + dz; + return hash; + } + @Override public String toString() { return String.format( diff --git a/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java b/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java index d6fff33a2..475d6e972 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java +++ b/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java @@ -17,6 +17,7 @@ package baritone.api.pathing.goals; +import baritone.api.utils.BetterBlockPos; import baritone.api.utils.SettingsUtil; import baritone.api.utils.interfaces.IGoalRenderPos; import net.minecraft.util.math.BlockPos; @@ -87,6 +88,11 @@ public class GoalTwoBlocks implements Goal, IGoalRenderPos { && z == goal.z; } + @Override + public int hashCode() { + return (int) BetterBlockPos.longHash(x, y, z) * 516508351; + } + @Override public String toString() { return String.format( diff --git a/src/api/java/baritone/api/pathing/goals/GoalXZ.java b/src/api/java/baritone/api/pathing/goals/GoalXZ.java index 2c551d395..1c7535b38 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalXZ.java +++ b/src/api/java/baritone/api/pathing/goals/GoalXZ.java @@ -77,6 +77,14 @@ public class GoalXZ implements Goal { return x == goal.x && z == goal.z; } + @Override + public int hashCode() { + int hash = 1791873246; + hash = hash * 222601791 + x; + hash = hash * -1331679453 + z; + return hash; + } + @Override public String toString() { return String.format( diff --git a/src/api/java/baritone/api/pathing/goals/GoalYLevel.java b/src/api/java/baritone/api/pathing/goals/GoalYLevel.java index 37745e8de..442906ad1 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalYLevel.java +++ b/src/api/java/baritone/api/pathing/goals/GoalYLevel.java @@ -71,6 +71,11 @@ public class GoalYLevel implements Goal, ActionCosts { return level == goal.level; } + @Override + public int hashCode() { + return level * 1271009915; + } + @Override public String toString() { return String.format( diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index ac12471a3..62f865899 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -775,6 +775,14 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil && Objects.equals(fallback, goal.fallback); } + @Override + public int hashCode() { + int hash = -1701079641; + hash = hash * 1196141026 + primary.hashCode(); + hash = hash * -80327868 + fallback.hashCode(); + return hash; + } + @Override public String toString() { return "JankyComposite Primary: " + primary + " Fallback: " + fallback; @@ -806,6 +814,11 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil SettingsUtil.maybeCensor(z) ); } + + @Override + public int hashCode() { + return super.hashCode() * 1636324008; + } } private Goal placementGoal(BlockPos pos, BuilderCalculationContext bcc) { @@ -883,6 +896,14 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil && Objects.equals(no, goal.no); } + @Override + public int hashCode() { + int hash = 806368046; + hash = hash * 1730799370 + (int) BetterBlockPos.longHash(no.getX(), no.getY(), no.getZ()); + hash = hash * 260592149 + (allowSameLevel ? -1314802005 : 1565710265); + return hash; + } + @Override public String toString() { return String.format( @@ -906,6 +927,11 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil return this.y * 100 + super.heuristic(x, y, z); } + @Override + public int hashCode() { + return super.hashCode() * 1910811835; + } + @Override public String toString() { return String.format( diff --git a/src/main/java/baritone/process/MineProcess.java b/src/main/java/baritone/process/MineProcess.java index 777b48197..8cd1a6cae 100644 --- a/src/main/java/baritone/process/MineProcess.java +++ b/src/main/java/baritone/process/MineProcess.java @@ -325,6 +325,11 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro return super.equals(o); } + @Override + public int hashCode() { + return super.hashCode() * 393857768; + } + @Override public String toString() { return String.format( From 41d730fb04f1058d8bab6e57b3d04cd77926b577 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Tue, 20 Jun 2023 03:20:44 +0200 Subject: [PATCH 183/405] Forgot to include target pos --- src/main/java/baritone/process/BuilderProcess.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index 62f865899..bd14d09a7 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -899,6 +899,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil @Override public int hashCode() { int hash = 806368046; + hash = hash * 1412661222 + super.hashCode(); hash = hash * 1730799370 + (int) BetterBlockPos.longHash(no.getX(), no.getY(), no.getZ()); hash = hash * 260592149 + (allowSameLevel ? -1314802005 : 1565710265); return hash; From cd1c07deef082149a210dd345f0d8f6dae564183 Mon Sep 17 00:00:00 2001 From: 0x22 <0x22@futureclient.net> Date: Mon, 19 Jun 2023 22:22:57 -0400 Subject: [PATCH 184/405] added elytraFireworkSetbackUseDelay setting. --- src/api/java/baritone/api/Settings.java | 1 + .../baritone/behavior/ElytraBehavior.java | 33 ++++++++++++++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 3cfef2ffc..aa2a4a957 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -51,6 +51,7 @@ public final class Settings { public final Setting elytraSimulationTicks = new Setting<>(20); public final Setting elytraPitchRange = new Setting<>(25); public final Setting elytraFireworkSpeed = new Setting<>(0.6); + public final Setting elytraFireworkSetbackUseDelay = new Setting<>(15L); public final Setting conserveFireworks = new Setting<>(true); public final Setting renderRaytraces = new Setting<>(false); public final Setting elytraFreeLook = new Setting<>(false); diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index f2e22248b..0b50bb804 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -21,6 +21,7 @@ import baritone.Baritone; import baritone.api.behavior.IElytraBehavior; import baritone.api.event.events.BlockChangeEvent; import baritone.api.event.events.ChunkEvent; +import baritone.api.event.events.PacketEvent; import baritone.api.event.events.TickEvent; import baritone.api.utils.*; import baritone.behavior.elytra.NetherPathfinderContext; @@ -33,9 +34,8 @@ import net.minecraft.entity.item.EntityFireworkRocket; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.EnumFacing; +import net.minecraft.network.play.server.SPacketPlayerPosLook; import net.minecraft.util.EnumHand; -import net.minecraft.util.NonNullList; import net.minecraft.util.math.*; import net.minecraft.world.chunk.Chunk; @@ -50,6 +50,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H */ private static final long NETHER_SEED = 146008555100680L; + private static final long MS_IN_NANOS = 1_000_000L; + private static final long TICK_IN_MS = 50L; + private static final long TICK_IN_NANOS = TICK_IN_MS * MS_IN_NANOS; + // Used exclusively for PathRenderer public List> clearLines; public List> blockedLines; @@ -62,6 +66,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private int sinceFirework; private BlockStateInterface bsi; + private long lastSetBack = Long.MIN_VALUE; + public ElytraBehavior(Baritone baritone) { super(baritone); this.context = new NetherPathfinderContext(NETHER_SEED); @@ -301,6 +307,13 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H .forEach(this.context::queueForPacking); } + @Override + public void onReceivePacket(PacketEvent event) { + if (event.getPacket() instanceof SPacketPlayerPosLook) { + this.lastSetBack = System.nanoTime(); + } + } + @Override public void pathTo(BlockPos destination) { this.pathManager.pathToDestination(destination); @@ -312,6 +325,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.pathManager.clear(); this.aimPos = null; this.sinceFirework = 0; + this.lastSetBack = Long.MIN_VALUE; } @Override @@ -415,18 +429,29 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } + this.tickUseFireworks(start, firework, goingTo, forceUseFirework); + } + + private void tickUseFireworks(final Vec3d start, final boolean firework, final BetterBlockPos goingTo, final boolean forceUseFirework) { + final long now = System.nanoTime(); + final long timeSinceLastSetback = now - this.lastSetBack; + if (timeSinceLastSetback < Baritone.settings().elytraFireworkSetbackUseDelay.value * TICK_IN_NANOS) { + logDebug("waiting for elytraFireworkSetbackUseDelay: " + (timeSinceLastSetback / TICK_IN_NANOS)); + return; + } final boolean useOnDescend = !Baritone.settings().conserveFireworks.value || ctx.player().posY < goingTo.y + 5; final double currentSpeed = new Vec3d( ctx.player().motionX, // ignore y component if we are BOTH below where we want to be AND descending ctx.player().posY < goingTo.y ? Math.max(0, ctx.player().motionY) : ctx.player().motionY, ctx.player().motionZ - ).length(); + ).lengthSquared(); + final double elytraFireworkSpeed = Baritone.settings().elytraFireworkSpeed.value; if (sinceFirework > 10 && (forceUseFirework || (!firework && useOnDescend && (ctx.player().posY < goingTo.y - 5 || start.distanceTo(new Vec3d(goingTo.x + 0.5, ctx.player().posY, goingTo.z + 0.5)) > 5) // UGH!!!!!!! - && currentSpeed < Baritone.settings().elytraFireworkSpeed.value)) + && currentSpeed < elytraFireworkSpeed * elytraFireworkSpeed)) ) { // Prioritize boosting fireworks over regular ones // TODO: Take the minimum boost time into account? From 753b1cf1c365161e2eff25234ff59c38d44e3c6c Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 19 Jun 2023 21:36:09 -0500 Subject: [PATCH 185/405] Interpolate path positions - Update `nether-pathfinder` to 0.17 - Utilize new batched visibility raytracing to efficiently trace bounding box paths --- build.gradle | 4 +- .../baritone/behavior/ElytraBehavior.java | 80 ++++++++++--------- .../elytra/NetherPathfinderContext.java | 22 ++++- 3 files changed, 65 insertions(+), 41 deletions(-) diff --git a/build.gradle b/build.gradle index 95abfec6a..7608c07ad 100755 --- a/build.gradle +++ b/build.gradle @@ -175,9 +175,9 @@ dependencies { transitive = false } launchAnnotationProcessor 'org.spongepowered:mixin:0.8.4-SNAPSHOT:processor' - launchImplementation('dev.babbaj:nether-pathfinder:0.16') + launchImplementation('dev.babbaj:nether-pathfinder:0.17') testImplementation 'junit:junit:4.12' - implementation 'dev.babbaj:nether-pathfinder:0.16' + implementation 'dev.babbaj:nether-pathfinder:0.17' } mixin { diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 0b50bb804..9331e3945 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -379,47 +379,59 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H outermost: for (int relaxation = 0; relaxation < 3; relaxation++) { // try for a strict solution first, then relax more and more (if we're in a corner or near some blocks, it will have to relax its constraints a bit) int[] heights = firework ? new int[]{20, 10, 5, 0} : new int[]{0}; // attempt to gain height, if we can, so as not to waste the boost + float[] interps = new float[] {1.0f, 0.75f, 0.5f, 0.25f}; int steps = relaxation < 2 ? firework ? 5 : Baritone.settings().elytraSimulationTicks.value : 3; int lookahead = relaxation == 0 ? 2 : 3; // ideally this would be expressed as a distance in blocks, rather than a number of voxel steps //int minStep = Math.max(0, playerNear - relaxation); int minStep = playerNear; for (int i = Math.min(playerNear + 20, path.size() - 1); i >= minStep; i--) { for (int dy : heights) { - Vec3d dest = this.pathManager.pathAt(i).add(0, dy, 0); - if (dy != 0) { - if (i + lookahead >= path.size()) { - continue; - } - if (start.distanceTo(dest) < 40) { - if (!clearView(dest, this.pathManager.pathAt(i + lookahead).add(0, dy, 0), false) || !clearView(dest, this.pathManager.pathAt(i + lookahead), false)) { - // aka: don't go upwards if doing so would prevent us from being able to see the next position **OR** the modified next position - continue; - } + for (float interp : interps) { + Vec3d dest; + if (interp == 1 || i == minStep) { + dest = this.pathManager.pathAt(i); } else { - // but if it's far away, allow gaining altitude if we could lose it again by the time we get there - if (!clearView(dest, this.pathManager.pathAt(i), false)) { + dest = this.pathManager.pathAt(i).scale(interp) + .add(this.pathManager.pathAt(i - 1).scale(1.0d - interp)); + } + + dest = dest.add(0, dy, 0); + if (dy != 0) { + if (i + lookahead >= path.size()) { continue; } + if (start.distanceTo(dest) < 40) { + if (!clearView(dest, this.pathManager.pathAt(i + lookahead).add(0, dy, 0), false) + || !clearView(dest, this.pathManager.pathAt(i + lookahead), false)) { + // aka: don't go upwards if doing so would prevent us from being able to see the next position **OR** the modified next position + continue; + } + } else { + // but if it's far away, allow gaining altitude if we could lose it again by the time we get there + if (!clearView(dest, this.pathManager.pathAt(i), false)) { + continue; + } + } } - } - // 1.0 -> 0.25 -> none - final Double grow = relaxation == 2 ? null - : relaxation == 0 ? 1.0d : 0.25d; + // 1.0 -> 0.25 -> none + final Double grow = relaxation == 2 ? null + : relaxation == 0 ? 1.0d : 0.25d; - if (isClear(start, dest, grow, isInLava)) { - final float yaw = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()).getYaw(); + if (isClear(start, dest, grow, isInLava)) { + final float yaw = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()).getYaw(); - final Pair pitch = this.solvePitch(dest.subtract(start), steps, relaxation, firework, isInLava); - if (pitch.first() == null) { - baritone.getLookBehavior().updateTarget(new Rotation(yaw, ctx.playerRotations().getPitch()), false); - continue; + final Pair pitch = this.solvePitch(dest.subtract(start), steps, relaxation, firework, isInLava); + if (pitch.first() == null) { + baritone.getLookBehavior().updateTarget(new Rotation(yaw, ctx.playerRotations().getPitch()), false); + continue; + } + forceUseFirework = pitch.second(); + goingTo = new BetterBlockPos(dest.x, dest.y, dest.z); + this.aimPos = goingTo; + baritone.getLookBehavior().updateTarget(new Rotation(yaw, pitch.first()), false); + break outermost; } - forceUseFirework = pitch.second(); - goingTo = path.get(i); - this.aimPos = path.get(i).add(0, dy, 0); - baritone.getLookBehavior().updateTarget(new Rotation(yaw, pitch.first()), false); - break outermost; } } } @@ -520,22 +532,14 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H bb.maxX + ox, bb.maxY + oy, bb.minZ + oz, bb.maxX + ox, bb.maxY + oy, bb.maxZ + oz, }; - - // Batch together all 8 traces - final boolean[] hitOut = new boolean[8]; - this.context.raytrace(src, dst, hitOut); - for (boolean hit : hitOut) { - if (hit) { - return false; - } - } - return true; + return this.context.raytrace(8, src, dst, NetherPathfinderContext.Visibility.ALL); } private boolean clearView(Vec3d start, Vec3d dest, boolean ignoreLava) { final boolean clear; if (!ignoreLava) { - clear = !this.context.raytrace(start.x, start.y, start.z, dest.x, dest.y, dest.z); + // if start == dest then the cpp raytracer dies + clear = start.equals(dest) || !this.context.raytrace(start.x, start.y, start.z, dest.x, dest.y, dest.z); } else { clear = ctx.world().rayTraceBlocks(start, dest, false, false, false) == null; } diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index bdee1a037..7c30a51b1 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -21,7 +21,6 @@ import dev.babbaj.pathfinder.NetherPathfinder; import dev.babbaj.pathfinder.PathSegment; import net.minecraft.block.state.IBlockState; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; import net.minecraft.world.chunk.BlockStateContainer; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.storage.ExtendedBlockStorage; @@ -82,6 +81,18 @@ public final class NetherPathfinderContext { NetherPathfinder.raytrace(this.context, true, hitOut.length, src, dst, hitOut, null); } + public boolean raytrace(final int count, final double[] src, final double[] dst, int visibility) { + switch (visibility) { + case Visibility.ALL: + return NetherPathfinder.isVisibleMulti(this.context, true, count, src, dst, false); + case Visibility.NONE: + return !NetherPathfinder.isVisibleMulti(this.context, true, count, src, dst, true); + case Visibility.ANY: + return NetherPathfinder.isVisibleMulti(this.context, true, count, src, dst, true); + } + throw new IllegalArgumentException("lol"); + } + public void cancel() { NetherPathfinder.cancel(this.context); } @@ -133,4 +144,13 @@ public final class NetherPathfinderContext { throw new RuntimeException(e); } } + + public static final class Visibility { + + private Visibility() {} + + public static final int ALL = 0; + public static final int NONE = 1; + public static final int ANY = 2; + } } From ee0a6c2523d1abf09ea415064a8a4dbc4c097dd9 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 19 Jun 2023 21:45:52 -0500 Subject: [PATCH 186/405] Use new single trace `isVisible` api --- .../baritone/behavior/ElytraBehavior.java | 2 +- .../elytra/NetherPathfinderContext.java | 30 +++++++++---------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 9331e3945..94abdd64d 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -539,7 +539,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final boolean clear; if (!ignoreLava) { // if start == dest then the cpp raytracer dies - clear = start.equals(dest) || !this.context.raytrace(start.x, start.y, start.z, dest.x, dest.y, dest.z); + clear = start.equals(dest) || this.context.raytrace(start.x, start.y, start.z, dest.x, dest.y, dest.z); } else { clear = ctx.world().rayTraceBlocks(start, dest, false, false, false) == null; } diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index 7c30a51b1..befb5163a 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -62,26 +62,24 @@ public final class NetherPathfinderContext { ), this.executor); } + /** + * Performs a raytrace from the given start position to the given end position, returning {@code true} if there is + * visibility between the two points. + * + * @param startX The start X coordinate + * @param startY The start Y coordinate + * @param startZ The start Z coordinate + * @param endX The end X coordinate + * @param endY The end Y coordinate + * @param endZ The end Z coordinate + * @return {@code true} if there is visibility between the points + */ public boolean raytrace(final double startX, final double startY, final double startZ, final double endX, final double endY, final double endZ) { - final boolean[] hitOut = new boolean[1]; - NetherPathfinder.raytrace( - this.context, - true, - 1, - new double[] { startX, startY, startZ }, - new double[] { endX, endY, endZ }, - hitOut, - null - ); - return hitOut[0]; + return NetherPathfinder.isVisible(this.context, true, startX, startY, startZ, endX, endY, endZ); } - public void raytrace(final double[] src, final double[] dst, final boolean[] hitOut) { - NetherPathfinder.raytrace(this.context, true, hitOut.length, src, dst, hitOut, null); - } - - public boolean raytrace(final int count, final double[] src, final double[] dst, int visibility) { + public boolean raytrace(final int count, final double[] src, final double[] dst, final int visibility) { switch (visibility) { case Visibility.ALL: return NetherPathfinder.isVisibleMulti(this.context, true, count, src, dst, false); From 5d7655fbdf5313eea8a7d505a9890c6712989e16 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 19 Jun 2023 22:52:27 -0500 Subject: [PATCH 187/405] Fix silly 0x integer wraparound trolle --- src/main/java/baritone/behavior/ElytraBehavior.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 94abdd64d..6d8b2cb3b 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -84,6 +84,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private boolean completePath; private boolean recalculating; private int playerNear; + private int maxPlayerNear; public PathManager() { // lol imagine initializing fields normally @@ -92,6 +93,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H public void tick() { // Recalculate closest path node + final int prevMax = this.maxPlayerNear; this.playerNear = this.calculateNear(this.playerNear); // Obstacles are more important than an incomplete path, handle those first. @@ -446,9 +448,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private void tickUseFireworks(final Vec3d start, final boolean firework, final BetterBlockPos goingTo, final boolean forceUseFirework) { final long now = System.nanoTime(); - final long timeSinceLastSetback = now - this.lastSetBack; - if (timeSinceLastSetback < Baritone.settings().elytraFireworkSetbackUseDelay.value * TICK_IN_NANOS) { - logDebug("waiting for elytraFireworkSetbackUseDelay: " + (timeSinceLastSetback / TICK_IN_NANOS)); + final long waitUntil = this.lastSetBack + Baritone.settings().elytraFireworkSetbackUseDelay.value * TICK_IN_NANOS; + final long remaining = waitUntil - now; + if (remaining < 0) { + logDebug("waiting for elytraFireworkSetbackUseDelay: " + (remaining / TICK_IN_NANOS)); return; } final boolean useOnDescend = !Baritone.settings().conserveFireworks.value || ctx.player().posY < goingTo.y + 5; From 14ff90ccf14f3cea388db711a73d2ed95f91620d Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 19 Jun 2023 23:12:46 -0500 Subject: [PATCH 188/405] remaining ticks mojang incident --- src/api/java/baritone/api/Settings.java | 2 +- .../baritone/behavior/ElytraBehavior.java | 36 ++++++++++--------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index aa2a4a957..be959ef12 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -51,7 +51,7 @@ public final class Settings { public final Setting elytraSimulationTicks = new Setting<>(20); public final Setting elytraPitchRange = new Setting<>(25); public final Setting elytraFireworkSpeed = new Setting<>(0.6); - public final Setting elytraFireworkSetbackUseDelay = new Setting<>(15L); + public final Setting elytraFireworkSetbackUseDelay = new Setting<>(15); public final Setting conserveFireworks = new Setting<>(true); public final Setting renderRaytraces = new Setting<>(false); public final Setting elytraFreeLook = new Setting<>(false); diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 6d8b2cb3b..1973e1bd4 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -63,11 +63,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // :sunglasses: private final NetherPathfinderContext context; private final PathManager pathManager; - private int sinceFirework; + private int remainingFireworkTicks; + private int remainingSetBackTicks; private BlockStateInterface bsi; - private long lastSetBack = Long.MIN_VALUE; - public ElytraBehavior(Baritone baritone) { super(baritone); this.context = new NetherPathfinderContext(NETHER_SEED); @@ -84,7 +83,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private boolean completePath; private boolean recalculating; private int playerNear; - private int maxPlayerNear; public PathManager() { // lol imagine initializing fields normally @@ -93,7 +91,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H public void tick() { // Recalculate closest path node - final int prevMax = this.maxPlayerNear; this.playerNear = this.calculateNear(this.playerNear); // Obstacles are more important than an incomplete path, handle those first. @@ -312,7 +309,9 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H @Override public void onReceivePacket(PacketEvent event) { if (event.getPacket() instanceof SPacketPlayerPosLook) { - this.lastSetBack = System.nanoTime(); + ctx.minecraft().addScheduledTask(() -> { + this.remainingSetBackTicks = Baritone.settings().elytraFireworkSetbackUseDelay.value; + }); } } @@ -326,8 +325,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.visiblePath = Collections.emptyList(); this.pathManager.clear(); this.aimPos = null; - this.sinceFirework = 0; - this.lastSetBack = Long.MIN_VALUE; + this.remainingFireworkTicks = 0; + this.remainingSetBackTicks = 0; } @Override @@ -341,6 +340,14 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return; } + // Certified mojang employee incident + if (this.remainingFireworkTicks > 0) { + this.remainingFireworkTicks--; + } + if (this.remainingSetBackTicks > 0) { + this.remainingSetBackTicks--; + } + this.clearLines.clear(); this.blockedLines.clear(); @@ -375,7 +382,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final boolean firework = isFireworkActive(); BetterBlockPos goingTo = null; boolean forceUseFirework = false; - this.sinceFirework++; + final boolean isInLava = ctx.player().isInLava(); outermost: @@ -447,11 +454,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } private void tickUseFireworks(final Vec3d start, final boolean firework, final BetterBlockPos goingTo, final boolean forceUseFirework) { - final long now = System.nanoTime(); - final long waitUntil = this.lastSetBack + Baritone.settings().elytraFireworkSetbackUseDelay.value * TICK_IN_NANOS; - final long remaining = waitUntil - now; - if (remaining < 0) { - logDebug("waiting for elytraFireworkSetbackUseDelay: " + (remaining / TICK_IN_NANOS)); + if (this.remainingSetBackTicks > 0) { + logDebug("waiting for elytraFireworkSetbackUseDelay: " + this.remainingSetBackTicks); return; } final boolean useOnDescend = !Baritone.settings().conserveFireworks.value || ctx.player().posY < goingTo.y + 5; @@ -463,7 +467,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H ).lengthSquared(); final double elytraFireworkSpeed = Baritone.settings().elytraFireworkSpeed.value; - if (sinceFirework > 10 && (forceUseFirework || (!firework + if (this.remainingFireworkTicks <= 0 && (forceUseFirework || (!firework && useOnDescend && (ctx.player().posY < goingTo.y - 5 || start.distanceTo(new Vec3d(goingTo.x + 0.5, ctx.player().posY, goingTo.z + 0.5)) > 5) // UGH!!!!!!! && currentSpeed < elytraFireworkSpeed * elytraFireworkSpeed)) @@ -477,7 +481,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } logDirect("attempting to use firework" + (forceUseFirework ? " takeoff" : "")); ctx.playerController().processRightClick(ctx.player(), ctx.world(), EnumHand.MAIN_HAND); - sinceFirework = 0; + this.remainingFireworkTicks = 10; } } From 6c6b44ee65d8752acaee9db53d5a7822b00c0ccb Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 20 Jun 2023 13:43:14 -0500 Subject: [PATCH 189/405] Recalculate path if stuck --- .../baritone/behavior/ElytraBehavior.java | 59 ++++++++++++++----- 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 1973e1bd4..f04fed343 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -50,10 +50,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H */ private static final long NETHER_SEED = 146008555100680L; - private static final long MS_IN_NANOS = 1_000_000L; - private static final long TICK_IN_MS = 50L; - private static final long TICK_IN_NANOS = TICK_IN_MS * MS_IN_NANOS; - // Used exclusively for PathRenderer public List> clearLines; public List> blockedLines; @@ -82,6 +78,9 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private List path; private boolean completePath; private boolean recalculating; + + private int maxPlayerNear; + private int ticksNearUnchanged; private int playerNear; public PathManager() { @@ -91,7 +90,15 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H public void tick() { // Recalculate closest path node + final int prevMaxNear = this.maxPlayerNear; this.playerNear = this.calculateNear(this.playerNear); + this.maxPlayerNear = Math.max(this.maxPlayerNear, this.playerNear); + + if (this.maxPlayerNear == prevMaxNear) { + this.ticksNearUnchanged++; + } else { + this.ticksNearUnchanged = 0; + } // Obstacles are more important than an incomplete path, handle those first. this.pathfindAroundObstacles(); @@ -118,23 +125,16 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H }); } - public void pathRecalcSegment(final int blockedAt, final int upToIncl) { + public CompletableFuture pathRecalcSegment(final int upToIncl) { if (this.recalculating) { - return; + throw new IllegalStateException("already recalculating"); } this.recalculating = true; final List after = this.path.subList(upToIncl, this.path.size()); final boolean complete = this.completePath; - final BetterBlockPos blockage = this.path.get(blockedAt); - final long start = System.nanoTime(); - this.path0(ctx.playerFeet(), this.path.get(upToIncl), segment -> segment.append(after.stream(), complete)) - .thenRun(() -> { - final int recompute = this.path.size() - after.size() - 1; - final double distance = this.pathAt(0).distanceTo(this.pathAt(recompute)); // in spirit same as ctx.playerFeet().distanceTo(this.path.get(upToIncl)), but, thread safe (those could have changed in the meantime) - logDirect(String.format("Recalculated segment around path blockage near %s %s %s (next %.1f blocks in %.4f seconds)", SettingsUtil.maybeCensor(blockage.x), SettingsUtil.maybeCensor(blockage.y), SettingsUtil.maybeCensor(blockage.z), distance, (System.nanoTime() - start) / 1e9d)); - }) + return this.path0(ctx.playerFeet(), this.path.get(upToIncl), segment -> segment.append(after.stream(), complete)) .whenComplete((result, ex) -> { this.recalculating = false; if (ex != null) { @@ -185,13 +185,17 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.completePath = true; this.recalculating = false; this.playerNear = 0; + this.ticksNearUnchanged = 0; + this.maxPlayerNear = 0; } private void setPath(final UnpackedSegment segment) { this.path = segment.collect(); this.removeBacktracks(); - this.playerNear = 0; this.completePath = segment.isFinished(); + this.playerNear = 0; + this.ticksNearUnchanged = 0; + this.maxPlayerNear = 0; } public List getPath() { @@ -228,11 +232,34 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // we're in a wall return; // previous iterations of this function SHOULD have fixed this by now :rage_cat: } + + if (this.ticksNearUnchanged > 100) { + this.pathRecalcSegment(rangeEndExcl - 1) + .thenRun(() -> { + logDirect("Recalculating segment, no progress in last 100 ticks"); + }); + this.ticksNearUnchanged = 0; + return; + } + for (int i = rangeStartIncl; i < rangeEndExcl - 1; i++) { if (!clearView(pathAt(i), pathAt(i + 1), false)) { // obstacle. where do we return to pathing? // find the next valid segment - this.pathRecalcSegment(i, rangeEndExcl - 1); + final BetterBlockPos blockage = this.path.get(i); + final double distance = Math.sqrt(ctx.playerFeet().distanceSq(this.path.get(rangeEndExcl - 1))); + + final long start = System.nanoTime(); + this.pathRecalcSegment(rangeEndExcl - 1) + .thenRun(() -> { + logDirect(String.format("Recalculated segment around path blockage near %s %s %s (next %.1f blocks in %.4f seconds)", + SettingsUtil.maybeCensor(blockage.x), + SettingsUtil.maybeCensor(blockage.y), + SettingsUtil.maybeCensor(blockage.z), + distance, + (System.nanoTime() - start) / 1e9d + )); + }); return; } } From 0ecabdd04714e68ac27e080e9c7831b3547e767c Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 20 Jun 2023 13:43:42 -0500 Subject: [PATCH 190/405] Update `nether-pathfinder` to 0.18 --- build.gradle | 4 ++-- .../baritone/behavior/elytra/NetherPathfinderContext.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 7608c07ad..41a495f4f 100755 --- a/build.gradle +++ b/build.gradle @@ -175,9 +175,9 @@ dependencies { transitive = false } launchAnnotationProcessor 'org.spongepowered:mixin:0.8.4-SNAPSHOT:processor' - launchImplementation('dev.babbaj:nether-pathfinder:0.17') + launchImplementation('dev.babbaj:nether-pathfinder:0.18') testImplementation 'junit:junit:4.12' - implementation 'dev.babbaj:nether-pathfinder:0.17' + implementation 'dev.babbaj:nether-pathfinder:0.18' } mixin { diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index befb5163a..f269cd33b 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -82,11 +82,11 @@ public final class NetherPathfinderContext { public boolean raytrace(final int count, final double[] src, final double[] dst, final int visibility) { switch (visibility) { case Visibility.ALL: - return NetherPathfinder.isVisibleMulti(this.context, true, count, src, dst, false); + return NetherPathfinder.isVisibleMulti(this.context, true, count, src, dst, false) == -1; case Visibility.NONE: - return !NetherPathfinder.isVisibleMulti(this.context, true, count, src, dst, true); + return NetherPathfinder.isVisibleMulti(this.context, true, count, src, dst, true) == -1; case Visibility.ANY: - return NetherPathfinder.isVisibleMulti(this.context, true, count, src, dst, true); + return NetherPathfinder.isVisibleMulti(this.context, true, count, src, dst, true) != -1; } throw new IllegalArgumentException("lol"); } From 7d22a71507215c2e9ae3099c7dc1fe3c8145e692 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 20 Jun 2023 13:50:26 -0500 Subject: [PATCH 191/405] Only count unchanged ticks when using elytra --- src/main/java/baritone/behavior/ElytraBehavior.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index f04fed343..f54b66d6c 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -94,7 +94,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.playerNear = this.calculateNear(this.playerNear); this.maxPlayerNear = Math.max(this.maxPlayerNear, this.playerNear); - if (this.maxPlayerNear == prevMaxNear) { + if (this.maxPlayerNear == prevMaxNear && ctx.player().isElytraFlying()) { this.ticksNearUnchanged++; } else { this.ticksNearUnchanged = 0; From c057081f07a0079289e16b53764f2567b1fd14bf Mon Sep 17 00:00:00 2001 From: Babbaj Date: Tue, 20 Jun 2023 15:48:12 -0400 Subject: [PATCH 192/405] fix 0.5 offset in elytra path rendering --- .../java/baritone/utils/PathRenderer.java | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index 5898ce643..0b08a1f32 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -104,7 +104,7 @@ public final class PathRenderer implements IRenderer { final ElytraBehavior elytra = behavior.baritone.getElytraBehavior(); - drawPath(elytra.visiblePath, 0, Color.RED, false, 0, 0); + drawPath(elytra.visiblePath, 0, Color.RED, false, 0, 0, 0.0D); if (elytra.aimPos != null) { drawGoal(ctx.player(), new GoalBlock(elytra.aimPos), partialTicks, Color.GREEN); } @@ -138,6 +138,10 @@ public final class PathRenderer implements IRenderer { } private static void drawPath(List positions, int startIndex, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0) { + drawPath(positions, startIndex, color, fadeOut, fadeStart0, fadeEnd0, 0.5D); + } + + private static void drawPath(List positions, int startIndex, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0, double offset) { IRenderer.startLines(color, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); int fadeStart = fadeStart0 + startIndex; @@ -173,7 +177,7 @@ public final class PathRenderer implements IRenderer { IRenderer.glColor(color, alpha); } - emitPathLine(start.x, start.y, start.z, end.x, end.y, end.z); + emitPathLine(start.x, start.y, start.z, end.x, end.y, end.z, offset); } IRenderer.endLines(settings.renderPathIgnoreDepth.value); @@ -187,24 +191,25 @@ public final class PathRenderer implements IRenderer { buffer.pos(x2 - vpX, y2 - vpY, z2 - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); } - private static void emitPathLine(double x1, double y1, double z1, double x2, double y2, double z2) { + private static void emitPathLine(double x1, double y1, double z1, double x2, double y2, double z2, double offset) { + final double extraOffset = offset + 0.03D; double vpX = renderManager.viewerPosX; double vpY = renderManager.viewerPosY; double vpZ = renderManager.viewerPosZ; boolean renderPathAsFrickinThingy = !settings.renderPathAsLine.value; - buffer.pos(x1 + 0.5D - vpX, y1 + 0.5D - vpY, z1 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.pos(x2 + 0.5D - vpX, y2 + 0.5D - vpY, z2 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(x1 + offset - vpX, y1 + offset - vpY, z1 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(x2 + offset - vpX, y2 + offset - vpY, z2 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); if (renderPathAsFrickinThingy) { - buffer.pos(x2 + 0.5D - vpX, y2 + 0.5D - vpY, z2 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.pos(x2 + 0.5D - vpX, y2 + 0.53D - vpY, z2 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(x2 + offset - vpX, y2 + offset - vpY, z2 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(x2 + offset - vpX, y2 + extraOffset - vpY, z2 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.pos(x2 + 0.5D - vpX, y2 + 0.53D - vpY, z2 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.pos(x1 + 0.5D - vpX, y1 + 0.53D - vpY, z1 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(x2 + offset - vpX, y2 + extraOffset - vpY, z2 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(x1 + offset - vpX, y1 + extraOffset - vpY, z1 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.pos(x1 + 0.5D - vpX, y1 + 0.53D - vpY, z1 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.pos(x1 + 0.5D - vpX, y1 + 0.5D - vpY, z1 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(x1 + offset - vpX, y1 + extraOffset - vpY, z1 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(x1 + offset - vpX, y1 + offset - vpY, z1 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); } } From 0aad3470d9785002aa876648f37b99842c404871 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 20 Jun 2023 15:05:59 -0500 Subject: [PATCH 193/405] Differ between no pitch solution and no solution at all --- .../baritone/behavior/ElytraBehavior.java | 41 ++++++++++++++----- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index f54b66d6c..e3d0164b8 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -408,9 +408,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final Vec3d start = ctx.playerFeetAsVec(); final boolean firework = isFireworkActive(); BetterBlockPos goingTo = null; - boolean forceUseFirework = false; - final boolean isInLava = ctx.player().isInLava(); + Solution solution = null; outermost: for (int relaxation = 0; relaxation < 3; relaxation++) { // try for a strict solution first, then relax more and more (if we're in a corner or near some blocks, it will have to relax its constraints a bit) @@ -459,25 +458,34 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final Pair pitch = this.solvePitch(dest.subtract(start), steps, relaxation, firework, isInLava); if (pitch.first() == null) { - baritone.getLookBehavior().updateTarget(new Rotation(yaw, ctx.playerRotations().getPitch()), false); + solution = new Solution(new Rotation(yaw, ctx.playerRotations().getPitch()), false, false); continue; } - forceUseFirework = pitch.second(); goingTo = new BetterBlockPos(dest.x, dest.y, dest.z); this.aimPos = goingTo; - baritone.getLookBehavior().updateTarget(new Rotation(yaw, pitch.first()), false); + + // A solution was found with yaw AND pitch, break out of the loop to use it + solution = new Solution(new Rotation(yaw, pitch.first()), true, pitch.second()); break outermost; } } } } - if (relaxation == 2) { - logDirect("no pitch solution, probably gonna crash in a few ticks LOL!!!"); - return; - } } - this.tickUseFireworks(start, firework, goingTo, forceUseFirework); + if (solution == null) { + logDirect("no solution"); + return; + } + + baritone.getLookBehavior().updateTarget(solution.rotation, false); + + if (!solution.solvedPitch) { + logDirect("no pitch solution, probably gonna crash in a few ticks LOL!!!"); + return; + } + + this.tickUseFireworks(start, firework, goingTo, solution.forceUseFirework); } private void tickUseFireworks(final Vec3d start, final boolean firework, final BetterBlockPos goingTo, final boolean forceUseFirework) { @@ -512,6 +520,19 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } + private static final class Solution { + + public final Rotation rotation; + public final boolean solvedPitch; + public final boolean forceUseFirework; + + public Solution(Rotation rotation, boolean solvedPitch, boolean forceUseFirework) { + this.rotation = rotation; + this.solvedPitch = solvedPitch; + this.forceUseFirework = forceUseFirework; + } + } + private static boolean isFireworks(final ItemStack itemStack) { if (itemStack.getItem() != Items.FIREWORKS) { return false; From e3c82831583611cce3ba8df9fbe06e4533c73f69 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 20 Jun 2023 15:15:02 -0500 Subject: [PATCH 194/405] Move solver into separate method --- .../baritone/behavior/ElytraBehavior.java | 57 ++++++++++--------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index e3d0164b8..1be445b2c 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -406,16 +406,32 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } final Vec3d start = ctx.playerFeetAsVec(); - final boolean firework = isFireworkActive(); - BetterBlockPos goingTo = null; + final boolean currentlyBoosted = this.isFireworkActive(); + + final Solution solution = this.solveAngles(path, playerNear, start, currentlyBoosted); + if (solution == null) { + logDirect("no solution"); + return; + } + + baritone.getLookBehavior().updateTarget(solution.rotation, false); + + if (!solution.solvedPitch) { + logDirect("no pitch solution, probably gonna crash in a few ticks LOL!!!"); + return; + } + + this.tickUseFireworks(start, currentlyBoosted, solution.goingTo, solution.forceUseFirework); + } + + private Solution solveAngles(final List path, final int playerNear, final Vec3d start, final boolean currentlyBoosted) { final boolean isInLava = ctx.player().isInLava(); Solution solution = null; - outermost: for (int relaxation = 0; relaxation < 3; relaxation++) { // try for a strict solution first, then relax more and more (if we're in a corner or near some blocks, it will have to relax its constraints a bit) - int[] heights = firework ? new int[]{20, 10, 5, 0} : new int[]{0}; // attempt to gain height, if we can, so as not to waste the boost + int[] heights = currentlyBoosted ? new int[]{20, 10, 5, 0} : new int[]{0}; // attempt to gain height, if we can, so as not to waste the boost float[] interps = new float[] {1.0f, 0.75f, 0.5f, 0.25f}; - int steps = relaxation < 2 ? firework ? 5 : Baritone.settings().elytraSimulationTicks.value : 3; + int steps = relaxation < 2 ? currentlyBoosted ? 5 : Baritone.settings().elytraSimulationTicks.value : 3; int lookahead = relaxation == 0 ? 2 : 3; // ideally this would be expressed as a distance in blocks, rather than a number of voxel steps //int minStep = Math.max(0, playerNear - relaxation); int minStep = playerNear; @@ -456,36 +472,23 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H if (isClear(start, dest, grow, isInLava)) { final float yaw = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()).getYaw(); - final Pair pitch = this.solvePitch(dest.subtract(start), steps, relaxation, firework, isInLava); + final Pair pitch = this.solvePitch(dest.subtract(start), steps, relaxation, currentlyBoosted, isInLava); if (pitch.first() == null) { - solution = new Solution(new Rotation(yaw, ctx.playerRotations().getPitch()), false, false); + solution = new Solution(new Rotation(yaw, ctx.playerRotations().getPitch()), null, false, false); continue; } - goingTo = new BetterBlockPos(dest.x, dest.y, dest.z); + + final BetterBlockPos goingTo = new BetterBlockPos(dest.x, dest.y, dest.z); this.aimPos = goingTo; - // A solution was found with yaw AND pitch, break out of the loop to use it - solution = new Solution(new Rotation(yaw, pitch.first()), true, pitch.second()); - break outermost; + // A solution was found with yaw AND pitch, so just immediately return it. + return new Solution(new Rotation(yaw, pitch.first()), goingTo, true, pitch.second()); } } } } } - - if (solution == null) { - logDirect("no solution"); - return; - } - - baritone.getLookBehavior().updateTarget(solution.rotation, false); - - if (!solution.solvedPitch) { - logDirect("no pitch solution, probably gonna crash in a few ticks LOL!!!"); - return; - } - - this.tickUseFireworks(start, firework, goingTo, solution.forceUseFirework); + return solution; } private void tickUseFireworks(final Vec3d start, final boolean firework, final BetterBlockPos goingTo, final boolean forceUseFirework) { @@ -523,11 +526,13 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private static final class Solution { public final Rotation rotation; + public final BetterBlockPos goingTo; public final boolean solvedPitch; public final boolean forceUseFirework; - public Solution(Rotation rotation, boolean solvedPitch, boolean forceUseFirework) { + public Solution(Rotation rotation, BetterBlockPos goingTo, boolean solvedPitch, boolean forceUseFirework) { this.rotation = rotation; + this.goingTo = goingTo; this.solvedPitch = solvedPitch; this.forceUseFirework = forceUseFirework; } From 4076263afa5cbbbb3e5aa6d43e8eae4cf9f21c4f Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 20 Jun 2023 17:00:42 -0500 Subject: [PATCH 195/405] Un-scuff PRE TickEvent injector --- .../java/baritone/launch/mixins/MixinMinecraft.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/launch/java/baritone/launch/mixins/MixinMinecraft.java b/src/launch/java/baritone/launch/mixins/MixinMinecraft.java index 19d4741ca..ddd17e8d5 100644 --- a/src/launch/java/baritone/launch/mixins/MixinMinecraft.java +++ b/src/launch/java/baritone/launch/mixins/MixinMinecraft.java @@ -38,6 +38,7 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.Slice; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @@ -69,9 +70,15 @@ public class MixinMinecraft { value = "FIELD", opcode = Opcodes.GETFIELD, target = "net/minecraft/client/Minecraft.currentScreen:Lnet/minecraft/client/gui/GuiScreen;", - ordinal = 5, - shift = At.Shift.BY, - by = -3 + ordinal = 0, + shift = At.Shift.BEFORE + ), + slice = @Slice( + from = @At( + value = "FIELD", + opcode = Opcodes.PUTFIELD, + target = "net/minecraft/client/Minecraft.leftClickCounter:I" + ) ) ) private void runTick(CallbackInfo ci) { From 2a82f6048a25c966098c127770fcb52c9ee21279 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 20 Jun 2023 17:18:30 -0500 Subject: [PATCH 196/405] Implement POST TickEvent with new `onPostTick` callback --- .../baritone/api/event/events/TickEvent.java | 9 ++++++ .../listener/AbstractGameEventListener.java | 3 ++ .../event/listener/IGameEventListener.java | 8 +++++ .../launch/mixins/MixinMinecraft.java | 30 ++++++++++++++++--- .../java/baritone/event/GameEventHandler.java | 5 ++++ 5 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/api/java/baritone/api/event/events/TickEvent.java b/src/api/java/baritone/api/event/events/TickEvent.java index 5c484ae49..405ad3c49 100644 --- a/src/api/java/baritone/api/event/events/TickEvent.java +++ b/src/api/java/baritone/api/event/events/TickEvent.java @@ -18,9 +18,18 @@ package baritone.api.event.events; import baritone.api.event.events.type.EventState; +import net.minecraft.client.Minecraft; import java.util.function.BiFunction; +/** + * Called on and after each game tick of the primary {@link Minecraft} instance and dispatched to all Baritone + * instances. + *

+ * When {@link #state} is {@link EventState#PRE}, the event is being called just prior to when the current in-game + * screen is ticked. When {@link #state} is {@link EventState#POST}, the event is being called at the very end + * of the {@link Minecraft#runTick()} method. + */ public final class TickEvent { private static int overallTickCount; diff --git a/src/api/java/baritone/api/event/listener/AbstractGameEventListener.java b/src/api/java/baritone/api/event/listener/AbstractGameEventListener.java index 64ae0c16e..54aabe387 100644 --- a/src/api/java/baritone/api/event/listener/AbstractGameEventListener.java +++ b/src/api/java/baritone/api/event/listener/AbstractGameEventListener.java @@ -33,6 +33,9 @@ public interface AbstractGameEventListener extends IGameEventListener { @Override default void onTick(TickEvent event) {} + @Override + default void onPostTick(TickEvent event) {} + @Override default void onPlayerUpdate(PlayerUpdateEvent event) {} diff --git a/src/api/java/baritone/api/event/listener/IGameEventListener.java b/src/api/java/baritone/api/event/listener/IGameEventListener.java index 71e9521ad..22466ce52 100644 --- a/src/api/java/baritone/api/event/listener/IGameEventListener.java +++ b/src/api/java/baritone/api/event/listener/IGameEventListener.java @@ -41,6 +41,14 @@ public interface IGameEventListener { */ void onTick(TickEvent event); + /** + * Run once per game tick after the tick is completed + * + * @param event The event + * @see Minecraft#runTick() + */ + void onPostTick(TickEvent event); + /** * Run once per game tick from before and after the player rotation is sent to the server. * diff --git a/src/launch/java/baritone/launch/mixins/MixinMinecraft.java b/src/launch/java/baritone/launch/mixins/MixinMinecraft.java index ddd17e8d5..13bc2cdf2 100644 --- a/src/launch/java/baritone/launch/mixins/MixinMinecraft.java +++ b/src/launch/java/baritone/launch/mixins/MixinMinecraft.java @@ -35,6 +35,7 @@ import net.minecraft.util.math.BlockPos; import org.spongepowered.asm.lib.Opcodes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; @@ -53,9 +54,13 @@ public class MixinMinecraft { @Shadow public EntityPlayerSP player; + @Shadow public WorldClient world; + @Unique + private BiFunction tickProvider; + @Inject( method = "init", at = @At("RETURN") @@ -82,18 +87,35 @@ public class MixinMinecraft { ) ) private void runTick(CallbackInfo ci) { - final BiFunction tickProvider = TickEvent.createNextProvider(); + this.tickProvider = TickEvent.createNextProvider(); for (IBaritone baritone : BaritoneAPI.getProvider().getAllBaritones()) { - TickEvent.Type type = baritone.getPlayerContext().player() != null && baritone.getPlayerContext().world() != null ? TickEvent.Type.IN : TickEvent.Type.OUT; - - baritone.getGameEventHandler().onTick(tickProvider.apply(EventState.PRE, type)); + baritone.getGameEventHandler().onTick(this.tickProvider.apply(EventState.PRE, type)); } } + @Inject( + method = "runTick", + at = @At("RETURN") + ) + private void postRunTick() { + if (this.tickProvider == null) { + return; + } + + for (IBaritone baritone : BaritoneAPI.getProvider().getAllBaritones()) { + TickEvent.Type type = baritone.getPlayerContext().player() != null && baritone.getPlayerContext().world() != null + ? TickEvent.Type.IN + : TickEvent.Type.OUT; + baritone.getGameEventHandler().onPostTick(this.tickProvider.apply(EventState.POST, type)); + } + + this.tickProvider = null; + } + @Inject( method = "runTick", at = @At( diff --git a/src/main/java/baritone/event/GameEventHandler.java b/src/main/java/baritone/event/GameEventHandler.java index ceb05e739..d26f2de24 100644 --- a/src/main/java/baritone/event/GameEventHandler.java +++ b/src/main/java/baritone/event/GameEventHandler.java @@ -62,6 +62,11 @@ public final class GameEventHandler implements IEventBus, Helper { listeners.forEach(l -> l.onTick(event)); } + @Override + public void onPostTick(TickEvent event) { + listeners.forEach(l -> l.onPostTick(event)); + } + @Override public final void onPlayerUpdate(PlayerUpdateEvent event) { listeners.forEach(l -> l.onPlayerUpdate(event)); From 57a17e907ea79b944ec253628434ac08e9408cac Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 20 Jun 2023 17:30:38 -0500 Subject: [PATCH 197/405] Add missing `CallbackInfo` --- src/launch/java/baritone/launch/mixins/MixinMinecraft.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/launch/java/baritone/launch/mixins/MixinMinecraft.java b/src/launch/java/baritone/launch/mixins/MixinMinecraft.java index 13bc2cdf2..543ed3280 100644 --- a/src/launch/java/baritone/launch/mixins/MixinMinecraft.java +++ b/src/launch/java/baritone/launch/mixins/MixinMinecraft.java @@ -101,7 +101,7 @@ public class MixinMinecraft { method = "runTick", at = @At("RETURN") ) - private void postRunTick() { + private void postRunTick(CallbackInfo ci) { if (this.tickProvider == null) { return; } From 1d092a71652f5cd7be3c1a169a3ba2b2ddee847a Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 20 Jun 2023 20:09:53 -0500 Subject: [PATCH 198/405] Compute angles on another thread between ticks --- .../baritone/api/utils/BetterBlockPos.java | 14 ++ .../baritone/behavior/ElytraBehavior.java | 167 +++++++++++++----- .../elytra/NetherPathfinderContext.java | 5 +- 3 files changed, 140 insertions(+), 46 deletions(-) diff --git a/src/api/java/baritone/api/utils/BetterBlockPos.java b/src/api/java/baritone/api/utils/BetterBlockPos.java index a9b02445b..01e53402e 100644 --- a/src/api/java/baritone/api/utils/BetterBlockPos.java +++ b/src/api/java/baritone/api/utils/BetterBlockPos.java @@ -202,6 +202,20 @@ public final class BetterBlockPos extends BlockPos { return amt == 0 ? this : new BetterBlockPos(x - amt, y, z); } + public double distanceSq(final BetterBlockPos to) { + double dx = (double) this.x - to.x; + double dy = (double) this.y - to.y; + double dz = (double) this.z - to.z; + return dx * dx + dy * dy + dz * dz; + } + + public double distanceTo(final BetterBlockPos to) { + double dx = (double) this.x - to.x; + double dy = (double) this.y - to.y; + double dz = (double) this.z - to.z; + return Math.sqrt(dx * dx + dy * dy + dz * dz); + } + @Override @Nonnull public String toString() { diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 1be445b2c..59ff847d7 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -19,10 +19,7 @@ package baritone.behavior; import baritone.Baritone; import baritone.api.behavior.IElytraBehavior; -import baritone.api.event.events.BlockChangeEvent; -import baritone.api.event.events.ChunkEvent; -import baritone.api.event.events.PacketEvent; -import baritone.api.event.events.TickEvent; +import baritone.api.event.events.*; import baritone.api.utils.*; import baritone.behavior.elytra.NetherPathfinderContext; import baritone.behavior.elytra.UnpackedSegment; @@ -41,6 +38,8 @@ import net.minecraft.world.chunk.Chunk; import java.util.*; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Future; +import java.util.function.IntFunction; import java.util.function.UnaryOperator; public final class ElytraBehavior extends Behavior implements IElytraBehavior, Helper { @@ -63,13 +62,16 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private int remainingSetBackTicks; private BlockStateInterface bsi; + private Future solver; + private boolean solveNextTick; + public ElytraBehavior(Baritone baritone) { super(baritone); this.context = new NetherPathfinderContext(NETHER_SEED); this.clearLines = new ArrayList<>(); this.blockedLines = new ArrayList<>(); this.visiblePath = Collections.emptyList(); - this.pathManager = new PathManager(); + this.pathManager = this.new PathManager(); } private final class PathManager { @@ -90,11 +92,11 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H public void tick() { // Recalculate closest path node + this.updatePlayerNear(); final int prevMaxNear = this.maxPlayerNear; - this.playerNear = this.calculateNear(this.playerNear); this.maxPlayerNear = Math.max(this.maxPlayerNear, this.playerNear); - if (this.maxPlayerNear == prevMaxNear && ctx.player().isElytraFlying()) { + if (this.maxPlayerNear == prevMaxNear) { this.ticksNearUnchanged++; } else { this.ticksNearUnchanged = 0; @@ -247,7 +249,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // obstacle. where do we return to pathing? // find the next valid segment final BetterBlockPos blockage = this.path.get(i); - final double distance = Math.sqrt(ctx.playerFeet().distanceSq(this.path.get(rangeEndExcl - 1))); + final double distance = ctx.playerFeet().distanceTo(this.path.get(rangeEndExcl - 1)); final long start = System.nanoTime(); this.pathRecalcSegment(rangeEndExcl - 1) @@ -276,7 +278,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } - private int calculateNear(int index) { + public void updatePlayerNear() { + int index = this.playerNear; final BetterBlockPos pos = ctx.playerFeet(); for (int i = index; i >= Math.max(index - 1000, 0); i -= 10) { if (path.get(i).distanceSq(pos) < path.get(index).distanceSq(pos)) { @@ -298,7 +301,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H index = i; // intentional: this changes the bound of the loop } } - return index; + this.playerNear = index; } private void removeBacktracks() { @@ -367,6 +370,18 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return; } + // Fetch the previous solution, regardless of if it's going to be used + Solution solution = null; + if (this.solver != null) { + try { + solution = this.solver.get(); + } catch (Exception ignored) { + // it doesn't matter if get() fails since the solution can just be recalculated synchronously + } finally { + this.solver = null; + } + } + // Certified mojang employee incident if (this.remainingFireworkTicks > 0) { this.remainingFireworkTicks--; @@ -379,7 +394,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.blockedLines.clear(); final List path = this.pathManager.getPath(); - if (path.isEmpty()) { + if (path.isEmpty() || !ctx.player().isElytraFlying()) { return; } @@ -392,10 +407,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H Math.min(playerNear + 100, path.size()) ); - if (!ctx.player().isElytraFlying()) { - return; - } - baritone.getInputOverrideHandler().clearAllKeys(); if (ctx.player().collidedHorizontally) { @@ -405,10 +416,14 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H logDirect("vbonk"); } - final Vec3d start = ctx.playerFeetAsVec(); - final boolean currentlyBoosted = this.isFireworkActive(); + final SolverContext solverContext = this.new SolverContext(); + this.solveNextTick = true; + + // If there's no previously calculated solution to use, or the context used at the end of last tick doesn't match this tick + if (solution == null || !solution.context.equals(solverContext)) { + solution = this.solveAngles(solverContext); + } - final Solution solution = this.solveAngles(path, playerNear, start, currentlyBoosted); if (solution == null) { logDirect("no solution"); return; @@ -419,12 +434,43 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H if (!solution.solvedPitch) { logDirect("no pitch solution, probably gonna crash in a few ticks LOL!!!"); return; + } else { + this.aimPos = solution.goingTo; } - this.tickUseFireworks(start, currentlyBoosted, solution.goingTo, solution.forceUseFirework); + this.tickUseFireworks( + solution.context.start, + solution.context.currentlyBoosted, + solution.goingTo, + solution.forceUseFirework + ); } - private Solution solveAngles(final List path, final int playerNear, final Vec3d start, final boolean currentlyBoosted) { + @Override + public void onPostTick(TickEvent event) { + if (event.getType() == TickEvent.Type.IN && this.solveNextTick) { + // We're at the end of the tick, the player's position likely updated and the closest path node could've + // changed. Updating it now will avoid unnecessary recalculation on the main thread. + this.pathManager.updatePlayerNear(); + + final SolverContext context = this.new SolverContext(); + this.solver = CompletableFuture.supplyAsync(() -> this.solveAngles(context)); + this.solveNextTick = false; + } + } + + private Solution solveAngles(final SolverContext context) { + final List path = context.path; + final int playerNear = context.playerNear; + final Vec3d start = context.start; + final boolean currentlyBoosted = context.currentlyBoosted; + + final IntFunction pathAt = (i) -> new Vec3d( + path.get(i).x, + path.get(i).y, + path.get(i).z + ); + final boolean isInLava = ctx.player().isInLava(); Solution solution = null; @@ -440,10 +486,9 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H for (float interp : interps) { Vec3d dest; if (interp == 1 || i == minStep) { - dest = this.pathManager.pathAt(i); + dest = pathAt.apply(i); } else { - dest = this.pathManager.pathAt(i).scale(interp) - .add(this.pathManager.pathAt(i - 1).scale(1.0d - interp)); + dest = pathAt.apply(i).scale(interp).add(pathAt.apply(i - 1).scale(1.0d - interp)); } dest = dest.add(0, dy, 0); @@ -452,14 +497,14 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H continue; } if (start.distanceTo(dest) < 40) { - if (!clearView(dest, this.pathManager.pathAt(i + lookahead).add(0, dy, 0), false) - || !clearView(dest, this.pathManager.pathAt(i + lookahead), false)) { + if (!clearView(dest, pathAt.apply(i + lookahead).add(0, dy, 0), false) + || !clearView(dest, pathAt.apply(i + lookahead), false)) { // aka: don't go upwards if doing so would prevent us from being able to see the next position **OR** the modified next position continue; } } else { // but if it's far away, allow gaining altitude if we could lose it again by the time we get there - if (!clearView(dest, this.pathManager.pathAt(i), false)) { + if (!clearView(dest, pathAt.apply(i), false)) { continue; } } @@ -474,15 +519,18 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final Pair pitch = this.solvePitch(dest.subtract(start), steps, relaxation, currentlyBoosted, isInLava); if (pitch.first() == null) { - solution = new Solution(new Rotation(yaw, ctx.playerRotations().getPitch()), null, false, false); + solution = new Solution(context, new Rotation(yaw, ctx.playerRotations().getPitch()), null, false, false); continue; } - final BetterBlockPos goingTo = new BetterBlockPos(dest.x, dest.y, dest.z); - this.aimPos = goingTo; - // A solution was found with yaw AND pitch, so just immediately return it. - return new Solution(new Rotation(yaw, pitch.first()), goingTo, true, pitch.second()); + return new Solution( + context, + new Rotation(yaw, pitch.first()), + new BetterBlockPos(dest.x, dest.y, dest.z), + true, + pitch.second() + ); } } } @@ -523,14 +571,47 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } + private final class SolverContext { + + public final List path; + public final int playerNear; + public final Vec3d start; + public final boolean currentlyBoosted; + + public SolverContext() { + this.path = ElytraBehavior.this.pathManager.getPath(); + this.playerNear = ElytraBehavior.this.pathManager.getNear(); + this.start = ElytraBehavior.this.ctx.playerFeetAsVec(); + this.currentlyBoosted = ElytraBehavior.this.isFireworkActive(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || o.getClass() != SolverContext.class) { + return false; + } + + SolverContext other = (SolverContext) o; + return this.path == other.path // Contents aren't modified, just compare by reference + && this.playerNear == other.playerNear + && Objects.equals(this.start, other.start) + && this.currentlyBoosted == other.currentlyBoosted; + } + } + private static final class Solution { + public final SolverContext context; public final Rotation rotation; public final BetterBlockPos goingTo; public final boolean solvedPitch; public final boolean forceUseFirework; - public Solution(Rotation rotation, BetterBlockPos goingTo, boolean solvedPitch, boolean forceUseFirework) { + public Solution(SolverContext context, Rotation rotation, BetterBlockPos goingTo, boolean solvedPitch, boolean forceUseFirework) { + this.context = context; this.rotation = rotation; this.goingTo = goingTo; this.solvedPitch = solvedPitch; @@ -605,10 +686,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } if (clear) { - clearLines.add(new Pair<>(start, dest)); + this.clearLines.add(new Pair<>(start, dest)); return true; } else { - blockedLines.add(new Pair<>(start, dest)); + this.blockedLines.add(new Pair<>(start, dest)); return false; } } @@ -672,15 +753,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return bestPitch; } - public boolean passable(int x, int y, int z, boolean ignoreLava) { - return passable(this.bsi.get0(x, y, z), ignoreLava); - } - - public static boolean passable(IBlockState state, boolean ignoreLava) { - Material mat = state.getMaterial(); - return mat == Material.AIR || (ignoreLava && mat == Material.LAVA); - } - private static Vec3d step(Vec3d motion, float rotationPitch, float rotationYaw, boolean firework) { double motionX = motion.x; double motionY = motion.y; @@ -731,5 +803,14 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return new Vec3d(motionX, motionY, motionZ); } + + private boolean passable(int x, int y, int z, boolean ignoreLava) { + return passable(this.bsi.get0(x, y, z), ignoreLava); + } + + private static boolean passable(IBlockState state, boolean ignoreLava) { + Material mat = state.getMaterial(); + return mat == Material.AIR || (ignoreLava && mat == Material.LAVA); + } } diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index f269cd33b..8dcd87274 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -19,6 +19,7 @@ package baritone.behavior.elytra; import dev.babbaj.pathfinder.NetherPathfinder; import dev.babbaj.pathfinder.PathSegment; +import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.world.chunk.BlockStateContainer; @@ -30,8 +31,6 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; -import static baritone.behavior.ElytraBehavior.passable; - /** * @author Brady */ @@ -129,7 +128,7 @@ public final class NetherPathfinderContext { for (int z = 0; z < 16; z++) { for (int x = 0; x < 16; x++) { IBlockState state = bsc.get(x, y1, z); - if (!passable(state, false)) { + if (state.getMaterial() != Material.AIR) { packed[x | (z << 4) | (y << 8)] = true; } } From 7a12ef530c3a56dce284b996e054d88df75f9af5 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 20 Jun 2023 20:11:34 -0500 Subject: [PATCH 199/405] Cancel solver on behavior cancel --- src/main/java/baritone/behavior/ElytraBehavior.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 59ff847d7..77c426c69 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -357,6 +357,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.aimPos = null; this.remainingFireworkTicks = 0; this.remainingSetBackTicks = 0; + this.solver.cancel(true); + this.solver = null; } @Override From fa158c6e67d7ccfe43a93e3721e969e75c3598a6 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 20 Jun 2023 20:18:56 -0500 Subject: [PATCH 200/405] Remove unnecessary conversions to Vec3d --- src/main/java/baritone/behavior/ElytraBehavior.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 77c426c69..7bcedea59 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -112,7 +112,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final long start = System.nanoTime(); this.path0(ctx.playerFeet(), destination, UnaryOperator.identity()) .thenRun(() -> { - final double distance = this.pathAt(0).distanceTo(this.pathAt(this.path.size() - 1)); + final double distance = this.path.get(0).distanceTo(this.path.get(this.path.size() - 1)); if (this.completePath) { logDirect(String.format("Computed path (%.1f blocks in %.4f seconds)", distance, (System.nanoTime() - start) / 1e9d)); } else { @@ -157,7 +157,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.path0(this.path.get(afterIncl), this.destination, segment -> segment.prepend(before.stream())) .thenRun(() -> { final int recompute = this.path.size() - before.size() - 1; - final double distance = this.pathAt(0).distanceTo(this.pathAt(recompute)); + final double distance = this.path.get(0).distanceTo(this.path.get(recompute)); if (this.completePath) { logDirect(String.format("Computed path (%.1f blocks in %.4f seconds)", distance, (System.nanoTime() - start) / 1e9d)); From 141a48a15e56446f91b7ff2c9410c2b5b005cc52 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 20 Jun 2023 20:30:10 -0500 Subject: [PATCH 201/405] Some refactoring, more precise `goingTo` --- .../baritone/behavior/ElytraBehavior.java | 57 +++++++++---------- .../elytra/NetherPathfinderContext.java | 13 +++++ 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 7bcedea59..328ee6818 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -437,13 +437,13 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H logDirect("no pitch solution, probably gonna crash in a few ticks LOL!!!"); return; } else { - this.aimPos = solution.goingTo; + this.aimPos = new BetterBlockPos(solution.goingTo.x, solution.goingTo.y, solution.goingTo.z); } this.tickUseFireworks( solution.context.start, - solution.context.currentlyBoosted, solution.goingTo, + solution.context.isBoosted, solution.forceUseFirework ); } @@ -465,7 +465,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final List path = context.path; final int playerNear = context.playerNear; final Vec3d start = context.start; - final boolean currentlyBoosted = context.currentlyBoosted; + final boolean isBoosted = context.isBoosted; final IntFunction pathAt = (i) -> new Vec3d( path.get(i).x, @@ -477,9 +477,9 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H Solution solution = null; for (int relaxation = 0; relaxation < 3; relaxation++) { // try for a strict solution first, then relax more and more (if we're in a corner or near some blocks, it will have to relax its constraints a bit) - int[] heights = currentlyBoosted ? new int[]{20, 10, 5, 0} : new int[]{0}; // attempt to gain height, if we can, so as not to waste the boost + int[] heights = isBoosted ? new int[]{20, 10, 5, 0} : new int[]{0}; // attempt to gain height, if we can, so as not to waste the boost float[] interps = new float[] {1.0f, 0.75f, 0.5f, 0.25f}; - int steps = relaxation < 2 ? currentlyBoosted ? 5 : Baritone.settings().elytraSimulationTicks.value : 3; + int steps = relaxation < 2 ? isBoosted ? 5 : Baritone.settings().elytraSimulationTicks.value : 3; int lookahead = relaxation == 0 ? 2 : 3; // ideally this would be expressed as a distance in blocks, rather than a number of voxel steps //int minStep = Math.max(0, playerNear - relaxation); int minStep = playerNear; @@ -499,14 +499,14 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H continue; } if (start.distanceTo(dest) < 40) { - if (!clearView(dest, pathAt.apply(i + lookahead).add(0, dy, 0), false) - || !clearView(dest, pathAt.apply(i + lookahead), false)) { + if (!this.clearView(dest, pathAt.apply(i + lookahead).add(0, dy, 0), false) + || !this.clearView(dest, pathAt.apply(i + lookahead), false)) { // aka: don't go upwards if doing so would prevent us from being able to see the next position **OR** the modified next position continue; } } else { // but if it's far away, allow gaining altitude if we could lose it again by the time we get there - if (!clearView(dest, pathAt.apply(i), false)) { + if (!this.clearView(dest, pathAt.apply(i), false)) { continue; } } @@ -516,23 +516,18 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final Double grow = relaxation == 2 ? null : relaxation == 0 ? 1.0d : 0.25d; - if (isClear(start, dest, grow, isInLava)) { + if (this.isClear(start, dest, grow, isInLava)) { + // Yaw is trivial, just calculate the rotation required to face the destination final float yaw = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()).getYaw(); - final Pair pitch = this.solvePitch(dest.subtract(start), steps, relaxation, currentlyBoosted, isInLava); + final Pair pitch = this.solvePitch(dest.subtract(start), steps, relaxation, isBoosted, isInLava); if (pitch.first() == null) { solution = new Solution(context, new Rotation(yaw, ctx.playerRotations().getPitch()), null, false, false); continue; } // A solution was found with yaw AND pitch, so just immediately return it. - return new Solution( - context, - new Rotation(yaw, pitch.first()), - new BetterBlockPos(dest.x, dest.y, dest.z), - true, - pitch.second() - ); + return new Solution(context, new Rotation(yaw, pitch.first()), dest, true, pitch.second()); } } } @@ -541,7 +536,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return solution; } - private void tickUseFireworks(final Vec3d start, final boolean firework, final BetterBlockPos goingTo, final boolean forceUseFirework) { + private void tickUseFireworks(final Vec3d start, final Vec3d goingTo, final boolean isBoosted, final boolean forceUseFirework) { if (this.remainingSetBackTicks > 0) { logDebug("waiting for elytraFireworkSetbackUseDelay: " + this.remainingSetBackTicks); return; @@ -555,7 +550,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H ).lengthSquared(); final double elytraFireworkSpeed = Baritone.settings().elytraFireworkSpeed.value; - if (this.remainingFireworkTicks <= 0 && (forceUseFirework || (!firework + if (this.remainingFireworkTicks <= 0 && (forceUseFirework || (!isBoosted && useOnDescend && (ctx.player().posY < goingTo.y - 5 || start.distanceTo(new Vec3d(goingTo.x + 0.5, ctx.player().posY, goingTo.z + 0.5)) > 5) // UGH!!!!!!! && currentSpeed < elytraFireworkSpeed * elytraFireworkSpeed)) @@ -578,13 +573,13 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H public final List path; public final int playerNear; public final Vec3d start; - public final boolean currentlyBoosted; + public final boolean isBoosted; public SolverContext() { - this.path = ElytraBehavior.this.pathManager.getPath(); - this.playerNear = ElytraBehavior.this.pathManager.getNear(); - this.start = ElytraBehavior.this.ctx.playerFeetAsVec(); - this.currentlyBoosted = ElytraBehavior.this.isFireworkActive(); + this.path = ElytraBehavior.this.pathManager.getPath(); + this.playerNear = ElytraBehavior.this.pathManager.getNear(); + this.start = ElytraBehavior.this.ctx.playerFeetAsVec(); + this.isBoosted = ElytraBehavior.this.isFireworkActive(); } @Override @@ -600,7 +595,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return this.path == other.path // Contents aren't modified, just compare by reference && this.playerNear == other.playerNear && Objects.equals(this.start, other.start) - && this.currentlyBoosted == other.currentlyBoosted; + && this.isBoosted == other.isBoosted; } } @@ -608,11 +603,11 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H public final SolverContext context; public final Rotation rotation; - public final BetterBlockPos goingTo; + public final Vec3d goingTo; public final boolean solvedPitch; public final boolean forceUseFirework; - public Solution(SolverContext context, Rotation rotation, BetterBlockPos goingTo, boolean solvedPitch, boolean forceUseFirework) { + public Solution(SolverContext context, Rotation rotation, Vec3d goingTo, boolean solvedPitch, boolean forceUseFirework) { this.context = context; this.rotation = rotation; this.goingTo = goingTo; @@ -642,7 +637,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } private boolean isClear(final Vec3d start, final Vec3d dest, final Double growAmount, boolean ignoreLava) { - if (!clearView(start, dest, ignoreLava)) { + if (!this.clearView(start, dest, ignoreLava)) { return false; } if (growAmount == null) { @@ -682,7 +677,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final boolean clear; if (!ignoreLava) { // if start == dest then the cpp raytracer dies - clear = start.equals(dest) || this.context.raytrace(start.x, start.y, start.z, dest.x, dest.y, dest.z); + clear = start.equals(dest) || this.context.raytrace(start, dest); } else { clear = ctx.world().rayTraceBlocks(start, dest, false, false, false) == null; } @@ -696,8 +691,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } - private Pair solvePitch(Vec3d goalDirection, int steps, int relaxation, boolean currentlyBoosted, boolean ignoreLava) { - final Float pitch = this.solvePitch(goalDirection, steps, relaxation == 2, currentlyBoosted, ignoreLava); + private Pair solvePitch(Vec3d goalDirection, int steps, int relaxation, boolean isBoosted, boolean ignoreLava) { + final Float pitch = this.solvePitch(goalDirection, steps, relaxation == 2, isBoosted, ignoreLava); if (pitch != null) { return new Pair<>(pitch, false); } diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index 8dcd87274..da3753bf3 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -22,6 +22,7 @@ import dev.babbaj.pathfinder.PathSegment; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.chunk.BlockStateContainer; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.storage.ExtendedBlockStorage; @@ -78,6 +79,18 @@ public final class NetherPathfinderContext { return NetherPathfinder.isVisible(this.context, true, startX, startY, startZ, endX, endY, endZ); } + /** + * Performs a raytrace from the given start position to the given end position, returning {@code true} if there is + * visibility between the two points. + * + * @param start The starting point + * @param end The ending point + * @return {@code true} if there is visibility between the points + */ + public boolean raytrace(final Vec3d start, final Vec3d end) { + return NetherPathfinder.isVisible(this.context, true, start.x, start.y, start.z, end.x, end.y, end.z); + } + public boolean raytrace(final int count, final double[] src, final double[] dst, final int visibility) { switch (visibility) { case Visibility.ALL: From e76f79214e4fb19b1cbbc3331ae92d31b6cd3b14 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 20 Jun 2023 21:07:21 -0500 Subject: [PATCH 202/405] Replace `pathAt` with `NetherPath` --- .../baritone/behavior/ElytraBehavior.java | 50 ++++++---------- .../baritone/behavior/elytra/NetherPath.java | 58 +++++++++++++++++++ .../behavior/elytra/UnpackedSegment.java | 5 +- 3 files changed, 79 insertions(+), 34 deletions(-) create mode 100644 src/main/java/baritone/behavior/elytra/NetherPath.java diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 328ee6818..4494a54aa 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -22,6 +22,7 @@ import baritone.api.behavior.IElytraBehavior; import baritone.api.event.events.*; import baritone.api.utils.*; import baritone.behavior.elytra.NetherPathfinderContext; +import baritone.behavior.elytra.NetherPath; import baritone.behavior.elytra.UnpackedSegment; import baritone.utils.BlockStateInterface; import baritone.utils.accessor.IEntityFireworkRocket; @@ -39,7 +40,6 @@ import net.minecraft.world.chunk.Chunk; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; -import java.util.function.IntFunction; import java.util.function.UnaryOperator; public final class ElytraBehavior extends Behavior implements IElytraBehavior, Helper { @@ -77,7 +77,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private final class PathManager { private BlockPos destination; - private List path; + private NetherPath path; private boolean completePath; private boolean recalculating; @@ -173,17 +173,9 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H }); } - private Vec3d pathAt(int i) { - return new Vec3d( - this.path.get(i).x, - this.path.get(i).y, - this.path.get(i).z - ); - } - public void clear() { this.destination = null; - this.path = Collections.emptyList(); + this.path = NetherPath.emptyPath(); this.completePath = true; this.recalculating = false; this.playerNear = 0; @@ -200,7 +192,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.maxPlayerNear = 0; } - public List getPath() { + public NetherPath getPath() { return this.path; } @@ -245,7 +237,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } for (int i = rangeStartIncl; i < rangeEndExcl - 1; i++) { - if (!clearView(pathAt(i), pathAt(i + 1), false)) { + if (!ElytraBehavior.this.clearView(this.path.getVec(i), this.path.getVec(i + 1), false)) { // obstacle. where do we return to pathing? // find the next valid segment final BetterBlockPos blockage = this.path.get(i); @@ -392,8 +384,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.remainingSetBackTicks--; } + // Reset rendered elements this.clearLines.clear(); this.blockedLines.clear(); + this.aimPos = null; final List path = this.pathManager.getPath(); if (path.isEmpty() || !ctx.player().isElytraFlying()) { @@ -462,17 +456,11 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } private Solution solveAngles(final SolverContext context) { - final List path = context.path; + final NetherPath path = context.path; final int playerNear = context.playerNear; final Vec3d start = context.start; final boolean isBoosted = context.isBoosted; - final IntFunction pathAt = (i) -> new Vec3d( - path.get(i).x, - path.get(i).y, - path.get(i).z - ); - final boolean isInLava = ctx.player().isInLava(); Solution solution = null; @@ -488,9 +476,9 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H for (float interp : interps) { Vec3d dest; if (interp == 1 || i == minStep) { - dest = pathAt.apply(i); + dest = path.getVec(i); } else { - dest = pathAt.apply(i).scale(interp).add(pathAt.apply(i - 1).scale(1.0d - interp)); + dest = path.getVec(i).scale(interp).add(path.getVec(i - 1).scale(1.0d - interp)); } dest = dest.add(0, dy, 0); @@ -499,24 +487,24 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H continue; } if (start.distanceTo(dest) < 40) { - if (!this.clearView(dest, pathAt.apply(i + lookahead).add(0, dy, 0), false) - || !this.clearView(dest, pathAt.apply(i + lookahead), false)) { + if (!this.clearView(dest, path.getVec(i + lookahead).add(0, dy, 0), false) + || !this.clearView(dest, path.getVec(i + lookahead), false)) { // aka: don't go upwards if doing so would prevent us from being able to see the next position **OR** the modified next position continue; } } else { // but if it's far away, allow gaining altitude if we could lose it again by the time we get there - if (!this.clearView(dest, pathAt.apply(i), false)) { + if (!this.clearView(dest, path.getVec(i), false)) { continue; } } } // 1.0 -> 0.25 -> none - final Double grow = relaxation == 2 ? null + final Double growth = relaxation == 2 ? null : relaxation == 0 ? 1.0d : 0.25d; - if (this.isClear(start, dest, grow, isInLava)) { + if (this.isHitboxClear(start, dest, growth, isInLava)) { // Yaw is trivial, just calculate the rotation required to face the destination final float yaw = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()).getYaw(); @@ -570,7 +558,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private final class SolverContext { - public final List path; + public final NetherPath path; public final int playerNear; public final Vec3d start; public final boolean isBoosted; @@ -636,7 +624,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H .anyMatch(x -> Objects.equals(((IEntityFireworkRocket) x).getBoostedEntity(), ctx.player())); } - private boolean isClear(final Vec3d start, final Vec3d dest, final Double growAmount, boolean ignoreLava) { + private boolean isHitboxClear(final Vec3d start, final Vec3d dest, final Double growAmount, boolean ignoreLava) { if (!this.clearView(start, dest, ignoreLava)) { return false; } @@ -713,7 +701,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // yaw is easy so we only care about pitch goalDirection = goalDirection.normalize(); - Rotation good = RotationUtils.calcRotationFromVec3d(new Vec3d(0, 0, 0), goalDirection, ctx.playerRotations()); // lazy lol + Rotation good = RotationUtils.calcRotationFromVec3d(Vec3d.ZERO, goalDirection, ctx.playerRotations()); // lazy lol Float bestPitch = null; double bestDot = Double.NEGATIVE_INFINITY; @@ -723,7 +711,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H outer: for (float pitch = minPitch; pitch <= maxPitch; pitch++) { Vec3d stepped = motion; - Vec3d totalMotion = new Vec3d(0, 0, 0); + Vec3d totalMotion = Vec3d.ZERO; for (int i = 0; i < steps; i++) { stepped = step(stepped, pitch, good.getYaw(), firework); Vec3d actualPositionPrevTick = ctx.playerFeetAsVec().add(totalMotion); diff --git a/src/main/java/baritone/behavior/elytra/NetherPath.java b/src/main/java/baritone/behavior/elytra/NetherPath.java new file mode 100644 index 000000000..e90075b87 --- /dev/null +++ b/src/main/java/baritone/behavior/elytra/NetherPath.java @@ -0,0 +1,58 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.behavior.elytra; + +import baritone.api.utils.BetterBlockPos; +import net.minecraft.util.math.Vec3d; + +import java.util.AbstractList; +import java.util.Collections; +import java.util.List; + +/** + * @author Brady + */ +public final class NetherPath extends AbstractList { + + private static final NetherPath EMPTY_PATH = new NetherPath(Collections.emptyList()); + + private final List backing; + + NetherPath(List backing) { + this.backing = backing; + } + + @Override + public BetterBlockPos get(int index) { + return this.backing.get(index); + } + + @Override + public int size() { + return this.backing.size(); + } + + public Vec3d getVec(int index) { + final BetterBlockPos pos = this.get(index); + return new Vec3d(pos.x, pos.y, pos.z); + } + + public static NetherPath emptyPath() { + return EMPTY_PATH; + } +} diff --git a/src/main/java/baritone/behavior/elytra/UnpackedSegment.java b/src/main/java/baritone/behavior/elytra/UnpackedSegment.java index 7798113da..8771aaabd 100644 --- a/src/main/java/baritone/behavior/elytra/UnpackedSegment.java +++ b/src/main/java/baritone/behavior/elytra/UnpackedSegment.java @@ -22,7 +22,6 @@ import dev.babbaj.pathfinder.PathSegment; import net.minecraft.util.math.BlockPos; import java.util.Arrays; -import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -48,8 +47,8 @@ public final class UnpackedSegment { return new UnpackedSegment(Stream.concat(other, this.path), this.finished); } - public List collect() { - return this.path.collect(Collectors.toList()); + public NetherPath collect() { + return new NetherPath(this.path.collect(Collectors.toList())); } public boolean isFinished() { From bd7a57f7aabbb1eb599044b47e720dc3ded2e349 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 20 Jun 2023 21:27:54 -0500 Subject: [PATCH 203/405] We do a little trolling --- .../baritone/behavior/ElytraBehavior.java | 19 +--------------- .../behavior/elytra/UnpackedSegment.java | 22 ++++++++++++++++++- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 4494a54aa..aab8be41d 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -185,7 +185,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private void setPath(final UnpackedSegment segment) { this.path = segment.collect(); - this.removeBacktracks(); this.completePath = segment.isFinished(); this.playerNear = 0; this.ticksNearUnchanged = 0; @@ -295,22 +294,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } this.playerNear = index; } - - private void removeBacktracks() { - Map positionFirstSeen = new HashMap<>(); - for (int i = 0; i < this.path.size(); i++) { - BetterBlockPos pos = this.path.get(i); - if (positionFirstSeen.containsKey(pos)) { - int j = positionFirstSeen.get(pos); - while (i > j) { - this.path.remove(i); - i--; - } - } else { - positionFirstSeen.put(pos, i); - } - } - } } @Override @@ -466,7 +449,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H for (int relaxation = 0; relaxation < 3; relaxation++) { // try for a strict solution first, then relax more and more (if we're in a corner or near some blocks, it will have to relax its constraints a bit) int[] heights = isBoosted ? new int[]{20, 10, 5, 0} : new int[]{0}; // attempt to gain height, if we can, so as not to waste the boost - float[] interps = new float[] {1.0f, 0.75f, 0.5f, 0.25f}; + float[] interps = new float[] {1.0f}; int steps = relaxation < 2 ? isBoosted ? 5 : Baritone.settings().elytraSimulationTicks.value : 3; int lookahead = relaxation == 0 ? 2 : 3; // ideally this would be expressed as a distance in blocks, rather than a number of voxel steps //int minStep = Math.max(0, playerNear - relaxation); diff --git a/src/main/java/baritone/behavior/elytra/UnpackedSegment.java b/src/main/java/baritone/behavior/elytra/UnpackedSegment.java index 8771aaabd..22fa4f82d 100644 --- a/src/main/java/baritone/behavior/elytra/UnpackedSegment.java +++ b/src/main/java/baritone/behavior/elytra/UnpackedSegment.java @@ -22,6 +22,9 @@ import dev.babbaj.pathfinder.PathSegment; import net.minecraft.util.math.BlockPos; import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -48,7 +51,24 @@ public final class UnpackedSegment { } public NetherPath collect() { - return new NetherPath(this.path.collect(Collectors.toList())); + final List path = this.path.collect(Collectors.toList()); + + // Remove backtracks + final Map positionFirstSeen = new HashMap<>(); + for (int i = 0; i < path.size(); i++) { + BetterBlockPos pos = path.get(i); + if (positionFirstSeen.containsKey(pos)) { + int j = positionFirstSeen.get(pos); + while (i > j) { + path.remove(i); + i--; + } + } else { + positionFirstSeen.put(pos, i); + } + } + + return new NetherPath(path); } public boolean isFinished() { From 2eb912835a2e98c452726a689c07901359a67381 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 20 Jun 2023 21:28:30 -0500 Subject: [PATCH 204/405] Restore interp values --- src/main/java/baritone/behavior/ElytraBehavior.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index aab8be41d..15d4f5f09 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -449,7 +449,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H for (int relaxation = 0; relaxation < 3; relaxation++) { // try for a strict solution first, then relax more and more (if we're in a corner or near some blocks, it will have to relax its constraints a bit) int[] heights = isBoosted ? new int[]{20, 10, 5, 0} : new int[]{0}; // attempt to gain height, if we can, so as not to waste the boost - float[] interps = new float[] {1.0f}; + float[] interps = new float[] {1.0f, 0.75f, 0.5f, 0.25f}; int steps = relaxation < 2 ? isBoosted ? 5 : Baritone.settings().elytraSimulationTicks.value : 3; int lookahead = relaxation == 0 ? 2 : 3; // ideally this would be expressed as a distance in blocks, rather than a number of voxel steps //int minStep = Math.max(0, playerNear - relaxation); From 699e8bdea6b545842f234e3360b30db76c223b7d Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 20 Jun 2023 22:36:27 -0500 Subject: [PATCH 205/405] troll concurrency fix for rn --- src/main/java/baritone/behavior/ElytraBehavior.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 15d4f5f09..6f585d30c 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -39,6 +39,7 @@ import net.minecraft.world.chunk.Chunk; import java.util.*; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Future; import java.util.function.UnaryOperator; @@ -68,8 +69,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H public ElytraBehavior(Baritone baritone) { super(baritone); this.context = new NetherPathfinderContext(NETHER_SEED); - this.clearLines = new ArrayList<>(); - this.blockedLines = new ArrayList<>(); + this.clearLines = new CopyOnWriteArrayList<>(); + this.blockedLines = new CopyOnWriteArrayList<>(); this.visiblePath = Collections.emptyList(); this.pathManager = this.new PathManager(); } From defa6399e2bcf0f722dfc5890779ba1e9a100bf6 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 20 Jun 2023 23:01:07 -0500 Subject: [PATCH 206/405] Tweak hitbox constraints --- src/main/java/baritone/behavior/ElytraBehavior.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 6f585d30c..eb6e2c4b0 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -486,7 +486,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // 1.0 -> 0.25 -> none final Double growth = relaxation == 2 ? null - : relaxation == 0 ? 1.0d : 0.25d; + : relaxation == 0 ? 0.5d : 0.25d; if (this.isHitboxClear(start, dest, growth, isInLava)) { // Yaw is trivial, just calculate the rotation required to face the destination From d42bfcfa53fc4d27f46cae301b35a7d6f97c0612 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 20 Jun 2023 23:15:45 -0500 Subject: [PATCH 207/405] Fix NPE --- src/main/java/baritone/behavior/ElytraBehavior.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index eb6e2c4b0..5f3e92838 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -333,8 +333,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.aimPos = null; this.remainingFireworkTicks = 0; this.remainingSetBackTicks = 0; - this.solver.cancel(true); - this.solver = null; + if (this.solver != null) { + this.solver.cancel(true); + this.solver = null; + } } @Override From cfd9a690528508d6427fc068e426dceeff01943d Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 21 Jun 2023 00:21:37 -0500 Subject: [PATCH 208/405] Revert how PathManager tick works --- src/main/java/baritone/behavior/ElytraBehavior.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 5f3e92838..14a15706e 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -97,7 +97,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final int prevMaxNear = this.maxPlayerNear; this.maxPlayerNear = Math.max(this.maxPlayerNear, this.playerNear); - if (this.maxPlayerNear == prevMaxNear) { + if (this.maxPlayerNear == prevMaxNear && ctx.player().isElytraFlying()) { this.ticksNearUnchanged++; } else { this.ticksNearUnchanged = 0; @@ -376,7 +376,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.aimPos = null; final List path = this.pathManager.getPath(); - if (path.isEmpty() || !ctx.player().isElytraFlying()) { + if (path.isEmpty()) { return; } @@ -389,6 +389,9 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H Math.min(playerNear + 100, path.size()) ); + if (!ctx.player().isElytraFlying()) { + return; + } baritone.getInputOverrideHandler().clearAllKeys(); if (ctx.player().collidedHorizontally) { From 877fd25608202596336af3ead8d19d2349c47394 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 21 Jun 2023 00:52:43 -0500 Subject: [PATCH 209/405] Distinguish unexpected exceptions in path calc --- .../exception/CommandUnhandledException.java | 7 +---- src/api/java/baritone/api/utils/Helper.java | 7 +++++ .../baritone/behavior/ElytraBehavior.java | 19 ++++++++++--- .../elytra/NetherPathfinderContext.java | 21 ++++++++------ .../elytra/PathCalculationException.java | 28 +++++++++++++++++++ 5 files changed, 64 insertions(+), 18 deletions(-) create mode 100644 src/main/java/baritone/behavior/elytra/PathCalculationException.java diff --git a/src/api/java/baritone/api/command/exception/CommandUnhandledException.java b/src/api/java/baritone/api/command/exception/CommandUnhandledException.java index 5dce59313..a1f826262 100644 --- a/src/api/java/baritone/api/command/exception/CommandUnhandledException.java +++ b/src/api/java/baritone/api/command/exception/CommandUnhandledException.java @@ -19,7 +19,6 @@ package baritone.api.command.exception; import baritone.api.command.ICommand; import baritone.api.command.argument.ICommandArgument; -import net.minecraft.util.text.TextFormatting; import java.util.List; @@ -37,10 +36,6 @@ public class CommandUnhandledException extends RuntimeException implements IComm @Override public void handle(ICommand command, List args) { - HELPER.logDirect("An unhandled exception occurred. " + - "The error is in your game's log, please report this at https://github.com/cabaletta/baritone/issues", - TextFormatting.RED); - - this.printStackTrace(); + HELPER.logUnhandledException(this); } } diff --git a/src/api/java/baritone/api/utils/Helper.java b/src/api/java/baritone/api/utils/Helper.java index b99074ae0..d604e0006 100755 --- a/src/api/java/baritone/api/utils/Helper.java +++ b/src/api/java/baritone/api/utils/Helper.java @@ -230,4 +230,11 @@ public interface Helper { default void logDirect(String message) { logDirect(message, BaritoneAPI.getSettings().logAsToast.value); } + + default void logUnhandledException(final Throwable exception) { + HELPER.logDirect("An unhandled exception occurred. " + + "The error is in your game's log, please report this at https://github.com/cabaletta/baritone/issues", + TextFormatting.RED); + exception.printStackTrace(); + } } diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 14a15706e..193c95227 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -23,6 +23,7 @@ import baritone.api.event.events.*; import baritone.api.utils.*; import baritone.behavior.elytra.NetherPathfinderContext; import baritone.behavior.elytra.NetherPath; +import baritone.behavior.elytra.PathCalculationException; import baritone.behavior.elytra.UnpackedSegment; import baritone.utils.BlockStateInterface; import baritone.utils.accessor.IEntityFireworkRocket; @@ -108,7 +109,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.attemptNextSegment(); } - public void pathToDestination(BlockPos destination) { + public void pathToDestination(final BlockPos destination) { this.destination = destination; final long start = System.nanoTime(); this.path0(ctx.playerFeet(), destination, UnaryOperator.identity()) @@ -123,7 +124,11 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H .whenComplete((result, ex) -> { this.recalculating = false; if (ex != null) { - logDirect("Failed to compute path to destination"); + if (ex instanceof PathCalculationException) { + logDirect("Failed to compute path to destination"); + } else { + logUnhandledException(ex); + } } }); } @@ -141,7 +146,11 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H .whenComplete((result, ex) -> { this.recalculating = false; if (ex != null) { - logDirect("Failed to recompute segment"); + if (ex instanceof PathCalculationException) { + logDirect("Failed to recompute segment"); + } else { + logUnhandledException(ex); + } } }); } @@ -168,8 +177,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H }) .whenComplete((result, ex) -> { this.recalculating = false; - if (ex != null) { + if (ex instanceof PathCalculationException) { logDirect("Failed to compute next segment"); + } else { + logUnhandledException(ex); } }); } diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index da3753bf3..d82372a99 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -52,14 +52,19 @@ public final class NetherPathfinderContext { } public CompletableFuture pathFindAsync(final BlockPos src, final BlockPos dst) { - return CompletableFuture.supplyAsync(() -> - NetherPathfinder.pathFind( - this.context, - src.getX(), src.getY(), src.getZ(), - dst.getX(), dst.getY(), dst.getZ(), - true, - 10000 - ), this.executor); + return CompletableFuture.supplyAsync(() -> { + final PathSegment segment = NetherPathfinder.pathFind( + this.context, + src.getX(), src.getY(), src.getZ(), + dst.getX(), dst.getY(), dst.getZ(), + true, + 10000 + ); + if (segment == null) { + throw new PathCalculationException("Path calculation failed"); + } + return segment; + }, this.executor); } /** diff --git a/src/main/java/baritone/behavior/elytra/PathCalculationException.java b/src/main/java/baritone/behavior/elytra/PathCalculationException.java new file mode 100644 index 000000000..73ce82faf --- /dev/null +++ b/src/main/java/baritone/behavior/elytra/PathCalculationException.java @@ -0,0 +1,28 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.behavior.elytra; + +/** + * @author Brady + */ +public final class PathCalculationException extends RuntimeException { + + public PathCalculationException(final String message) { + super(message); + } +} From 367ce5fa177cb6806937f37983932076bcd38172 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 14 Jun 2023 16:11:11 -0500 Subject: [PATCH 210/405] cherry pick Allow freeLook when using elytra --- .../api/event/events/RotationMoveEvent.java | 38 ++++++++- .../launch/mixins/MixinEntityLivingBase.java | 85 +++++++++++++++---- .../launch/mixins/MixinEntityPlayerSP.java | 16 ---- .../launch/mixins/MixinMinecraft.java | 15 ++++ .../java/baritone/behavior/LookBehavior.java | 1 + 5 files changed, 117 insertions(+), 38 deletions(-) diff --git a/src/api/java/baritone/api/event/events/RotationMoveEvent.java b/src/api/java/baritone/api/event/events/RotationMoveEvent.java index 109061c7e..a2ab17ed6 100644 --- a/src/api/java/baritone/api/event/events/RotationMoveEvent.java +++ b/src/api/java/baritone/api/event/events/RotationMoveEvent.java @@ -17,6 +17,7 @@ package baritone.api.event.events; +import baritone.api.utils.Rotation; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; @@ -31,14 +32,27 @@ public final class RotationMoveEvent { */ private final Type type; + private final Rotation original; + /** * The yaw rotation */ private float yaw; - public RotationMoveEvent(Type type, float yaw) { + /** + * The pitch rotation + */ + private float pitch; + + public RotationMoveEvent(Type type, float yaw, float pitch) { this.type = type; + this.original = new Rotation(yaw, pitch); this.yaw = yaw; + this.pitch = pitch; + } + + public Rotation getOriginal() { + return this.original; } /** @@ -46,21 +60,37 @@ public final class RotationMoveEvent { * * @param yaw Yaw rotation */ - public final void setYaw(float yaw) { + public void setYaw(float yaw) { this.yaw = yaw; } /** * @return The yaw rotation */ - public final float getYaw() { + public float getYaw() { return this.yaw; } + /** + * Set the pitch movement rotation + * + * @param pitch Pitch rotation + */ + public void setPitch(float pitch) { + this.pitch = pitch; + } + + /** + * @return The pitch rotation + */ + public float getPitch() { + return pitch; + } + /** * @return The type of the event */ - public final Type getType() { + public Type getType() { return this.type; } diff --git a/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java b/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java index 0fd2436c9..f8544dd2f 100644 --- a/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java +++ b/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java @@ -25,11 +25,14 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import java.util.Optional; + import static org.spongepowered.asm.lib.Opcodes.GETFIELD; /** @@ -42,11 +45,14 @@ public abstract class MixinEntityLivingBase extends Entity { /** * Event called to override the movement direction when jumping */ + @Unique private RotationMoveEvent jumpRotationEvent; - public MixinEntityLivingBase(World worldIn, RotationMoveEvent jumpRotationEvent) { + @Unique + private RotationMoveEvent elytraRotationEvent; + + public MixinEntityLivingBase(World worldIn) { super(worldIn); - this.jumpRotationEvent = jumpRotationEvent; } @Inject( @@ -54,14 +60,10 @@ public abstract class MixinEntityLivingBase extends Entity { at = @At("HEAD") ) private void preMoveRelative(CallbackInfo ci) { - // noinspection ConstantConditions - if (EntityPlayerSP.class.isInstance(this)) { - IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this); - if (baritone != null) { - this.jumpRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.JUMP, this.rotationYaw); - baritone.getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent); - } - } + this.getBaritone().ifPresent(baritone -> { + this.jumpRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.JUMP, this.rotationYaw, this.rotationPitch); + baritone.getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent); + }); } @Redirect( @@ -79,6 +81,38 @@ public abstract class MixinEntityLivingBase extends Entity { return self.rotationYaw; } + @Inject( + method = "travel", + at = @At( + value = "INVOKE", + target = "net/minecraft/entity/EntityLivingBase.getLookVec()Lnet/minecraft/util/math/Vec3d;" + ) + ) + private void onPreElytraMove(float strafe, float vertical, float forward, CallbackInfo ci) { + this.getBaritone().ifPresent(baritone -> { + this.elytraRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw, this.rotationPitch); + baritone.getGameEventHandler().onPlayerRotationMove(this.elytraRotationEvent); + this.rotationYaw = this.elytraRotationEvent.getYaw(); + this.rotationPitch = this.elytraRotationEvent.getPitch(); + }); + } + + @Inject( + method = "travel", + at = @At( + value = "INVOKE", + target = "net/minecraft/entity/EntityLivingBase.move(Lnet/minecraft/entity/MoverType;DDD)V", + shift = At.Shift.AFTER + ) + ) + private void onPostElytraMove(float strafe, float vertical, float forward, CallbackInfo ci) { + if (this.elytraRotationEvent != null) { + this.rotationYaw = this.elytraRotationEvent.getOriginal().getYaw(); + this.rotationPitch = this.elytraRotationEvent.getOriginal().getPitch(); + this.elytraRotationEvent = null; + } + } + @Redirect( method = "travel", at = @At( @@ -86,17 +120,32 @@ public abstract class MixinEntityLivingBase extends Entity { target = "net/minecraft/entity/EntityLivingBase.moveRelative(FFFF)V" ) ) - private void travel(EntityLivingBase self, float strafe, float up, float forward, float friction) { - // noinspection ConstantConditions - if (!EntityPlayerSP.class.isInstance(this) || BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this) == null) { + private void onMoveRelative(EntityLivingBase self, float strafe, float up, float forward, float friction) { + Optional baritone = this.getBaritone(); + if (!baritone.isPresent()) { moveRelative(strafe, up, forward, friction); return; } - RotationMoveEvent motionUpdateRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw); - BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerRotationMove(motionUpdateRotationEvent); - float originalYaw = this.rotationYaw; - this.rotationYaw = motionUpdateRotationEvent.getYaw(); + + RotationMoveEvent event = new RotationMoveEvent(RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw, this.rotationPitch); + baritone.get().getGameEventHandler().onPlayerRotationMove(event); + + this.rotationYaw = event.getYaw(); + this.rotationPitch = event.getPitch(); + this.moveRelative(strafe, up, forward, friction); - this.rotationYaw = originalYaw; + + this.rotationYaw = event.getOriginal().getYaw(); + this.rotationPitch = event.getOriginal().getPitch(); + } + + @Unique + private Optional getBaritone() { + // noinspection ConstantConditions + if (EntityPlayerSP.class.isInstance(this)) { + return Optional.ofNullable(BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this)); + } else { + return Optional.empty(); + } } } diff --git a/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java b/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java index 4f6031d78..281ff96f5 100644 --- a/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java +++ b/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java @@ -72,22 +72,6 @@ public class MixinEntityPlayerSP { } } - @Inject( - method = "onUpdate", - at = @At( - value = "INVOKE", - target = "net/minecraft/client/entity/EntityPlayerSP.onUpdateWalkingPlayer()V", - shift = At.Shift.BY, - by = 2 - ) - ) - private void onPostUpdate(CallbackInfo ci) { - IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this); - if (baritone != null) { - baritone.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.POST)); - } - } - @Redirect( method = "onLivingUpdate", at = @At( diff --git a/src/launch/java/baritone/launch/mixins/MixinMinecraft.java b/src/launch/java/baritone/launch/mixins/MixinMinecraft.java index 097c72905..edc1e3fcc 100644 --- a/src/launch/java/baritone/launch/mixins/MixinMinecraft.java +++ b/src/launch/java/baritone/launch/mixins/MixinMinecraft.java @@ -20,6 +20,7 @@ package baritone.launch.mixins; import baritone.api.BaritoneAPI; import baritone.api.IBaritone; import baritone.api.event.events.BlockInteractEvent; +import baritone.api.event.events.PlayerUpdateEvent; import baritone.api.event.events.TickEvent; import baritone.api.event.events.WorldEvent; import baritone.api.event.events.type.EventState; @@ -84,7 +85,21 @@ public class MixinMinecraft { baritone.getGameEventHandler().onTick(tickProvider.apply(EventState.PRE, type)); } + } + @Inject( + method = "runTick", + at = @At( + value = "INVOKE", + target = "net/minecraft/client/multiplayer/WorldClient.updateEntities()V", + shift = At.Shift.AFTER + ) + ) + private void postUpdateEntities(CallbackInfo ci) { + IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(this.player); + if (baritone != null) { + baritone.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.POST)); + } } @Inject( diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index 67aa45e39..d3c514ac2 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -149,6 +149,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior { public void onPlayerRotationMove(RotationMoveEvent event) { if (this.target != null) { event.setYaw(this.target.rotation.getYaw()); + event.setPitch(this.target.rotation.getPitch()); } } From a5ca664a6a84014cc623eb74325c2f41026c88ee Mon Sep 17 00:00:00 2001 From: Mike <44955015+jdbool@users.noreply.github.com> Date: Wed, 21 Jun 2023 15:14:54 -0700 Subject: [PATCH 211/405] Add useMessageTag setting --- src/api/java/baritone/api/Settings.java | 8 +++++- src/api/java/baritone/api/utils/Helper.java | 28 ++++++++++++++++++--- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index c815d89d3..ae8cb07fd 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -21,6 +21,7 @@ import baritone.api.utils.NotificationHelper; import baritone.api.utils.SettingsUtil; import baritone.api.utils.TypeUtils; import baritone.api.utils.gui.BaritoneToast; +import net.minecraft.client.GuiMessageTag; import net.minecraft.client.Minecraft; import net.minecraft.core.Vec3i; import net.minecraft.network.chat.Component; @@ -772,6 +773,11 @@ public final class Settings { */ public final Setting shortBaritonePrefix = new Setting<>(false); + /** + * Use a modern message tag instead of a prefix when logging to chat + */ + public final Setting useMessageTag = new Setting<>(false); + /** * Echo commands to chat when they are run */ @@ -1141,7 +1147,7 @@ public final class Settings { * via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting * {@link Setting#value}; */ - public final Setting> logger = new Setting<>(msg -> Minecraft.getInstance().gui.getChat().addMessage(msg)); + public final Setting> logger = new Setting<>((msg, tag) -> Minecraft.getInstance().gui.getChat().addMessage(msg, null, tag)); /** * The function that is called when Baritone will send a desktop notification. This function can be added to diff --git a/src/api/java/baritone/api/utils/Helper.java b/src/api/java/baritone/api/utils/Helper.java index 7e3c44607..f0709c1cc 100755 --- a/src/api/java/baritone/api/utils/Helper.java +++ b/src/api/java/baritone/api/utils/Helper.java @@ -18,8 +18,10 @@ package baritone.api.utils; import baritone.api.BaritoneAPI; +import baritone.api.Settings; import baritone.api.utils.gui.BaritoneToast; import net.minecraft.ChatFormatting; +import net.minecraft.client.GuiMessageTag; import net.minecraft.client.Minecraft; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; @@ -48,6 +50,11 @@ public interface Helper { */ Minecraft mc = Minecraft.getInstance(); + /** + * The tag to assign to chat messages when {@link Settings#useMessageTag} is {@code true}. + */ + GuiMessageTag MESSAGE_TAG = new GuiMessageTag(0xFF55FF, null, Component.literal("Baritone message."), "Baritone"); + static Component getPrefix() { // Inner text component final Calendar now = Calendar.getInstance(); @@ -156,20 +163,33 @@ public interface Helper { * Send components to chat with the [Baritone] prefix * * @param logAsToast Whether to log as a toast notification + * @param useMessageTag Whether to use a message tag instead of a prefix * @param components The components to send */ - default void logDirect(boolean logAsToast, Component... components) { + default void logDirect(boolean logAsToast, boolean useMessageTag, Component... components) { MutableComponent component = Component.literal(""); - component.append(getPrefix()); - component.append(Component.literal(" ")); + if (!logAsToast && !useMessageTag) { + component.append(getPrefix()); + component.append(Component.literal(" ")); + } Arrays.asList(components).forEach(component::append); if (logAsToast) { logToast(getPrefix(), component); } else { - mc.execute(() -> BaritoneAPI.getSettings().logger.value.accept(component)); + mc.execute(() -> BaritoneAPI.getSettings().logger.value.accept(component, useMessageTag ? MESSAGE_TAG : null)); } } + /** + * Send components to chat with the [Baritone] prefix + * + * @param logAsToast Whether to log as a toast notification + * @param components The components to send + */ + default void logDirect(boolean logAsToast, Component... components) { + logDirect(logAsToast, BaritoneAPI.getSettings().useMessageTag.value, components); + } + /** * Send components to chat with the [Baritone] prefix * From 7e426bd2e8ad15ba571b9775fdf779fc09390318 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 21 Jun 2023 17:35:47 -0500 Subject: [PATCH 212/405] AimProcessor API --- .../baritone/api/behavior/ILookBehavior.java | 19 +- .../api/behavior/look/IAimProcessor.java | 44 ++++ .../java/baritone/behavior/LookBehavior.java | 188 +++++++++++++----- .../behavior/look/ForkableRandom.java | 85 ++++++++ 4 files changed, 283 insertions(+), 53 deletions(-) create mode 100644 src/api/java/baritone/api/behavior/look/IAimProcessor.java create mode 100644 src/main/java/baritone/behavior/look/ForkableRandom.java diff --git a/src/api/java/baritone/api/behavior/ILookBehavior.java b/src/api/java/baritone/api/behavior/ILookBehavior.java index 218e8b59a..eb7c992b8 100644 --- a/src/api/java/baritone/api/behavior/ILookBehavior.java +++ b/src/api/java/baritone/api/behavior/ILookBehavior.java @@ -17,6 +17,8 @@ package baritone.api.behavior; +import baritone.api.Settings; +import baritone.api.behavior.look.IAimProcessor; import baritone.api.utils.Rotation; /** @@ -27,10 +29,25 @@ public interface ILookBehavior extends IBehavior { /** * Updates the current {@link ILookBehavior} target to target the specified rotations on the next tick. If any sort - * of block interaction is required, {@code blockInteract} should be {@code true}. + * of block interaction is required, {@code blockInteract} should be {@code true}. It is not guaranteed that the + * rotations set by the caller will be the exact rotations expressed by the client (This is due to settings like + * {@link Settings#randomLooking}). If the rotations produced by this behavior are required, then the + * {@link #getAimProcessor() aim processor} should be used. * * @param rotation The target rotations * @param blockInteract Whether the target rotations are needed for a block interaction */ void updateTarget(Rotation rotation, boolean blockInteract); + + /** + * The aim processor instance for this {@link ILookBehavior}, which is responsible for applying additional, deterministic + * transformations to the target rotation set by {@link #updateTarget}. Whenever {@link IAimProcessor#nextRotation(Rotation)} + * is called on the instance returned by this method, the returned value always reflects what would happen in the + * upcoming tick. In other words, it is a pure function, and no internal state changes. If simulation of the + * rotation states beyond the next tick is required, then a {@link IAimProcessor#fork(int) fork} should be created. + * + * @return The aim processor + * @see IAimProcessor#fork(int) + */ + IAimProcessor getAimProcessor(); } diff --git a/src/api/java/baritone/api/behavior/look/IAimProcessor.java b/src/api/java/baritone/api/behavior/look/IAimProcessor.java new file mode 100644 index 000000000..72a4c681d --- /dev/null +++ b/src/api/java/baritone/api/behavior/look/IAimProcessor.java @@ -0,0 +1,44 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.api.behavior.look; + +import baritone.api.utils.Rotation; + +/** + * @author Brady + */ +public interface IAimProcessor { + + /** + * Returns the actual rotation that will be used when the desired rotation is requested. This is not guaranteed to + * return the same value for a given input. + * + * @param desired The desired rotation to set + * @return The actual rotation + */ + Rotation nextRotation(Rotation desired); + + /** + * Returns a copy of this {@link IAimProcessor} which has its own internal state and updates on each call to + * {@link #nextRotation(Rotation)}. + * + * @param ticksAdvanced The number of ticks to advance ahead of time + * @return The forked processor + */ + IAimProcessor fork(int ticksAdvanced); +} diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index d3c514ac2..aeb694181 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -20,13 +20,11 @@ package baritone.behavior; import baritone.Baritone; import baritone.api.Settings; import baritone.api.behavior.ILookBehavior; -import baritone.api.event.events.PacketEvent; -import baritone.api.event.events.PlayerUpdateEvent; -import baritone.api.event.events.RotationMoveEvent; -import baritone.api.event.events.WorldEvent; -import baritone.api.utils.Helper; +import baritone.api.behavior.look.IAimProcessor; +import baritone.api.event.events.*; import baritone.api.utils.IPlayerContext; import baritone.api.utils.Rotation; +import baritone.behavior.look.ForkableRandom; import net.minecraft.network.play.client.CPacketPlayer; import java.util.Optional; @@ -44,14 +42,17 @@ public final class LookBehavior extends Behavior implements ILookBehavior { private Rotation serverRotation; /** - * The last player rotation. Used when free looking + * The last player rotation. Used to restore the player's angle when using free look. * * @see Settings#freeLook */ private Rotation prevRotation; + private final AimProcessor processor; + public LookBehavior(Baritone baritone) { super(baritone); + this.processor = new AimProcessor(baritone.getPlayerContext()); } @Override @@ -59,6 +60,19 @@ public final class LookBehavior extends Behavior implements ILookBehavior { this.target = new Target(rotation, blockInteract); } + @Override + public IAimProcessor getAimProcessor() { + return this.processor; + } + + @Override + public void onTick(TickEvent event) { + if (event.getType() == TickEvent.Type.IN) { + // Unlike forked AimProcessors, the root one needs to be manually updated each game tick + this.processor.tick(); + } + } + @Override public void onPlayerUpdate(PlayerUpdateEvent event) { if (this.target == null) { @@ -67,34 +81,16 @@ public final class LookBehavior extends Behavior implements ILookBehavior { switch (event.getState()) { case PRE: { if (this.target.mode == Target.Mode.NONE) { + // Just return for PRE, we still want to set target to null on POST return; } if (this.target.mode == Target.Mode.SERVER) { this.prevRotation = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch); } - final float oldYaw = ctx.playerRotations().getYaw(); - final float oldPitch = ctx.playerRotations().getPitch(); - - float desiredYaw = this.target.rotation.getYaw(); - float desiredPitch = this.target.rotation.getPitch(); - - // In other words, the target doesn't care about the pitch, so it used playerRotations().getPitch() - // and it's safe to adjust it to a normal level - if (desiredPitch == oldPitch) { - desiredPitch = nudgeToLevel(desiredPitch); - } - - desiredYaw += (Math.random() - 0.5) * Baritone.settings().randomLooking.value; - desiredPitch += (Math.random() - 0.5) * Baritone.settings().randomLooking.value; - - ctx.player().rotationYaw = calculateMouseMove(oldYaw, desiredYaw); - ctx.player().rotationPitch = calculateMouseMove(oldPitch, desiredPitch); - - if (this.target.mode == Target.Mode.CLIENT) { - // The target can be invalidated now since it won't be needed for RotationMoveEvent - this.target = null; - } + final Rotation actual = this.processor.nextRotation(this.target.rotation); + ctx.player().rotationYaw = actual.getYaw(); + ctx.player().rotationPitch = actual.getPitch(); break; } case POST: { @@ -133,7 +129,8 @@ public final class LookBehavior extends Behavior implements ILookBehavior { public void pig() { if (this.target != null) { - ctx.player().rotationYaw = this.target.rotation.getYaw(); + final Rotation actual = this.processor.nextRotation(this.target.rotation); + ctx.player().rotationYaw = actual.getYaw(); } } @@ -148,37 +145,124 @@ public final class LookBehavior extends Behavior implements ILookBehavior { @Override public void onPlayerRotationMove(RotationMoveEvent event) { if (this.target != null) { - event.setYaw(this.target.rotation.getYaw()); - event.setPitch(this.target.rotation.getPitch()); + final Rotation actual = this.target.rotation; + event.setYaw(actual.getYaw()); + event.setPitch(actual.getPitch()); } } - /** - * Nudges the player's pitch to a regular level. (Between {@code -20} and {@code 10}, increments are by {@code 1}) - */ - private static float nudgeToLevel(float pitch) { - if (pitch < -20) { - return pitch + 1; - } else if (pitch > 10) { - return pitch - 1; + private static final class AimProcessor extends AbstractAimProcessor { + + public AimProcessor(final IPlayerContext ctx) { + super(ctx); + } + + @Override + protected Rotation getPrevRotation() { + // Implementation will use LookBehavior.serverRotation + return ctx.playerRotations(); } - return pitch; } - private float calculateMouseMove(float current, float target) { - final float delta = target - current; - final int deltaPx = angleToMouse(delta); - return current + mouseToAngle(deltaPx); - } + private static abstract class AbstractAimProcessor implements IAimProcessor { - private int angleToMouse(float angleDelta) { - final float minAngleChange = mouseToAngle(1); - return Math.round(angleDelta / minAngleChange); - } + protected final IPlayerContext ctx; + private final ForkableRandom rand; + private double randomYawOffset; + private double randomPitchOffset; - private float mouseToAngle(int mouseDelta) { - final float f = ctx.minecraft().gameSettings.mouseSensitivity * 0.6f + 0.2f; - return mouseDelta * f * f * f * 8.0f * 0.15f; + public AbstractAimProcessor(IPlayerContext ctx) { + this.ctx = ctx; + this.rand = new ForkableRandom(); + } + + private AbstractAimProcessor(final AbstractAimProcessor source) { + this.ctx = source.ctx; + this.rand = source.rand.fork(); + this.randomYawOffset = source.randomYawOffset; + this.randomPitchOffset = source.randomPitchOffset; + } + + public void tick() { + this.randomYawOffset = (this.rand.nextDouble() - 0.5) * Baritone.settings().randomLooking.value; + this.randomPitchOffset = (this.rand.nextDouble() - 0.5) * Baritone.settings().randomLooking.value; + } + + @Override + public Rotation nextRotation(final Rotation rotation) { + final Rotation prev = this.getPrevRotation(); + + float desiredYaw = rotation.getYaw(); + float desiredPitch = rotation.getPitch(); + + // In other words, the target doesn't care about the pitch, so it used playerRotations().getPitch() + // and it's safe to adjust it to a normal level + if (desiredPitch == prev.getPitch()) { + desiredPitch = nudgeToLevel(desiredPitch); + } + + desiredYaw += this.randomYawOffset; + desiredPitch += this.randomPitchOffset; + + return new Rotation( + this.calculateMouseMove(prev.getYaw(), desiredYaw), + this.calculateMouseMove(prev.getPitch(), desiredPitch) + ); + } + + @Override + public final IAimProcessor fork(final int ticksAdvanced) { + final AbstractAimProcessor fork = new AbstractAimProcessor(this) { + + private Rotation prev = AbstractAimProcessor.this.getPrevRotation(); + + @Override + public Rotation nextRotation(Rotation rotation) { + final Rotation actual = super.nextRotation(rotation); + this.tick(); + return (this.prev = actual); + } + + @Override + protected Rotation getPrevRotation() { + return this.prev; + } + }; + for (int i = 0; i < ticksAdvanced; i++) { + fork.tick(); + } + return fork; + } + + protected abstract Rotation getPrevRotation(); + + /** + * Nudges the player's pitch to a regular level. (Between {@code -20} and {@code 10}, increments are by {@code 1}) + */ + private float nudgeToLevel(float pitch) { + if (pitch < -20) { + return pitch + 1; + } else if (pitch > 10) { + return pitch - 1; + } + return pitch; + } + + private float calculateMouseMove(float current, float target) { + final float delta = target - current; + final int deltaPx = angleToMouse(delta); + return current + mouseToAngle(deltaPx); + } + + private int angleToMouse(float angleDelta) { + final float minAngleChange = mouseToAngle(1); + return Math.round(angleDelta / minAngleChange); + } + + private float mouseToAngle(int mouseDelta) { + final float f = ctx.minecraft().gameSettings.mouseSensitivity * 0.6f + 0.2f; + return mouseDelta * f * f * f * 8.0f * 0.15f; + } } private static class Target { diff --git a/src/main/java/baritone/behavior/look/ForkableRandom.java b/src/main/java/baritone/behavior/look/ForkableRandom.java new file mode 100644 index 000000000..5f5f942d2 --- /dev/null +++ b/src/main/java/baritone/behavior/look/ForkableRandom.java @@ -0,0 +1,85 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.behavior.look; + +import java.util.Arrays; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.LongSupplier; + +/** + * Implementation of Xoroshiro256++ + *

+ * Extended to produce random double-precision floating point numbers, and allow copies to be spawned via {@link #fork}, + * which share the same internal state as the source object. + * + * @author Brady + */ +public final class ForkableRandom { + + private static final double DOUBLE_UNIT = 0x1.0p-53; + + private final long[] s; + + public ForkableRandom() { + this(System.nanoTime() ^ System.currentTimeMillis()); + } + + public ForkableRandom(long seedIn) { + final AtomicLong seed = new AtomicLong(seedIn); + final LongSupplier splitmix64 = () -> { + long z = seed.addAndGet(0x9e3779b97f4a7c15L); + z = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L; + z = (z ^ (z >>> 27)) * 0x94d049bb133111ebL; + return z ^ (z >>> 31); + }; + this.s = new long[] { + splitmix64.getAsLong(), + splitmix64.getAsLong(), + splitmix64.getAsLong(), + splitmix64.getAsLong() + }; + } + + private ForkableRandom(long[] s) { + this.s = s; + } + + public double nextDouble() { + return (this.next() >>> 11) * DOUBLE_UNIT; + } + + public long next() { + final long result = rotl(this.s[0] + this.s[3], 23) + this.s[0]; + final long t = this.s[1] << 17; + this.s[2] ^= this.s[0]; + this.s[3] ^= this.s[1]; + this.s[1] ^= this.s[2]; + this.s[0] ^= this.s[3]; + this.s[2] ^= t; + this.s[3] = rotl(this.s[3], 45); + return result; + } + + public ForkableRandom fork() { + return new ForkableRandom(Arrays.copyOf(this.s, 4)); + } + + private static long rotl(long x, int k) { + return (x << k) | (x >>> (64 - k)); + } +} From 0682e6370713961c31a56871bc32b924120556f3 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 21 Jun 2023 17:39:04 -0500 Subject: [PATCH 213/405] Apply processor to RotationMoveEvent --- src/main/java/baritone/behavior/LookBehavior.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index aeb694181..57dfd206c 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -145,7 +145,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior { @Override public void onPlayerRotationMove(RotationMoveEvent event) { if (this.target != null) { - final Rotation actual = this.target.rotation; + final Rotation actual = this.processor.nextRotation(this.target.rotation); event.setYaw(actual.getYaw()); event.setPitch(actual.getPitch()); } From 0aff31b7685008adf23f7251e328b74c05570ebc Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 21 Jun 2023 18:59:44 -0500 Subject: [PATCH 214/405] Perfect elytra simulation --- src/main/java/baritone/behavior/ElytraBehavior.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 193c95227..a0839f100 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -713,7 +713,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H Vec3d stepped = motion; Vec3d totalMotion = Vec3d.ZERO; for (int i = 0; i < steps; i++) { - stepped = step(stepped, pitch, good.getYaw(), firework); + stepped = step(stepped, pitch, good.getYaw(), firework && i > 0); Vec3d actualPositionPrevTick = ctx.playerFeetAsVec().add(totalMotion); totalMotion = totalMotion.add(stepped); Vec3d actualPosition = ctx.playerFeetAsVec().add(totalMotion); @@ -781,9 +781,9 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H motionX += (lookDirection.x / pitchBase2 * flatMotion - motionX) * 0.1; motionZ += (lookDirection.z / pitchBase2 * flatMotion - motionZ) * 0.1; } - motionX *= 0.99; - motionY *= 0.98; - motionZ *= 0.99; + motionX *= 0.99f; + motionY *= 0.98f; + motionZ *= 0.99f; //System.out.println(motionX + " " + motionY + " " + motionZ); return new Vec3d(motionX, motionY, motionZ); From 7ef4307ab7977432beae24c4965bcb2e573e6d00 Mon Sep 17 00:00:00 2001 From: Mike <44955015+jdbool@users.noreply.github.com> Date: Wed, 21 Jun 2023 18:25:24 -0700 Subject: [PATCH 215/405] Clean up useMessageTag --- src/api/java/baritone/api/Settings.java | 6 +++++- src/api/java/baritone/api/utils/Helper.java | 17 +++-------------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index ae8cb07fd..2b7ebc288 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -17,6 +17,7 @@ package baritone.api; +import baritone.api.utils.Helper; import baritone.api.utils.NotificationHelper; import baritone.api.utils.SettingsUtil; import baritone.api.utils.TypeUtils; @@ -1147,7 +1148,10 @@ public final class Settings { * via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting * {@link Setting#value}; */ - public final Setting> logger = new Setting<>((msg, tag) -> Minecraft.getInstance().gui.getChat().addMessage(msg, null, tag)); + public final Setting> logger = new Setting<>((msg) -> { + final GuiMessageTag tag = useMessageTag.value ? Helper.MESSAGE_TAG : null; + Minecraft.getInstance().gui.getChat().addMessage(msg, null, tag); + }); /** * The function that is called when Baritone will send a desktop notification. This function can be added to diff --git a/src/api/java/baritone/api/utils/Helper.java b/src/api/java/baritone/api/utils/Helper.java index f0709c1cc..63ced2496 100755 --- a/src/api/java/baritone/api/utils/Helper.java +++ b/src/api/java/baritone/api/utils/Helper.java @@ -163,12 +163,11 @@ public interface Helper { * Send components to chat with the [Baritone] prefix * * @param logAsToast Whether to log as a toast notification - * @param useMessageTag Whether to use a message tag instead of a prefix * @param components The components to send */ - default void logDirect(boolean logAsToast, boolean useMessageTag, Component... components) { + default void logDirect(boolean logAsToast, Component... components) { MutableComponent component = Component.literal(""); - if (!logAsToast && !useMessageTag) { + if (!logAsToast && !BaritoneAPI.getSettings().useMessageTag.value) { component.append(getPrefix()); component.append(Component.literal(" ")); } @@ -176,20 +175,10 @@ public interface Helper { if (logAsToast) { logToast(getPrefix(), component); } else { - mc.execute(() -> BaritoneAPI.getSettings().logger.value.accept(component, useMessageTag ? MESSAGE_TAG : null)); + mc.execute(() -> BaritoneAPI.getSettings().logger.value.accept(component)); } } - /** - * Send components to chat with the [Baritone] prefix - * - * @param logAsToast Whether to log as a toast notification - * @param components The components to send - */ - default void logDirect(boolean logAsToast, Component... components) { - logDirect(logAsToast, BaritoneAPI.getSettings().useMessageTag.value, components); - } - /** * Send components to chat with the [Baritone] prefix * From 4776fa18765a9b56d9abea493117f2e119fd5abf Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 21 Jun 2023 21:19:12 -0500 Subject: [PATCH 216/405] Don't update `playerNear` on an empty path --- src/main/java/baritone/behavior/ElytraBehavior.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index a0839f100..b63d81a33 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -282,6 +282,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } public void updatePlayerNear() { + if (this.path.isEmpty()) { + return; + } + int index = this.playerNear; final BetterBlockPos pos = ctx.playerFeet(); for (int i = index; i >= Math.max(index - 1000, 0); i -= 10) { From 47dc0f9b941a6d9c8643cc9a03986998a6940498 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 21 Jun 2023 21:30:04 -0500 Subject: [PATCH 217/405] Add missing exception null check to async completed callback --- src/main/java/baritone/behavior/ElytraBehavior.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index b63d81a33..a6fd769d0 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -177,10 +177,12 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H }) .whenComplete((result, ex) -> { this.recalculating = false; - if (ex instanceof PathCalculationException) { - logDirect("Failed to compute next segment"); - } else { - logUnhandledException(ex); + if (ex != null) { + if (ex instanceof PathCalculationException) { + logDirect("Failed to compute next segment"); + } else { + logUnhandledException(ex); + } } }); } From 535fd17a42b6b9a110c28ac298e5ac9e1e3379f4 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Thu, 22 Jun 2023 08:30:25 -0400 Subject: [PATCH 218/405] simplify null check --- src/main/java/baritone/behavior/ElytraBehavior.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index a6fd769d0..da2b4f41b 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -123,12 +123,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H }) .whenComplete((result, ex) -> { this.recalculating = false; - if (ex != null) { - if (ex instanceof PathCalculationException) { - logDirect("Failed to compute path to destination"); - } else { - logUnhandledException(ex); - } + if (ex instanceof PathCalculationException) { + logDirect("Failed to compute path to destination"); + } else if (ex != null) { + logUnhandledException(ex); } }); } From b366b1b1d1aa79185389c5541b3451c436c6179d Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 22 Jun 2023 11:40:45 -0500 Subject: [PATCH 219/405] Fix other null checks --- .../baritone/behavior/ElytraBehavior.java | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index da2b4f41b..5e370fa28 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -143,12 +143,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return this.path0(ctx.playerFeet(), this.path.get(upToIncl), segment -> segment.append(after.stream(), complete)) .whenComplete((result, ex) -> { this.recalculating = false; - if (ex != null) { - if (ex instanceof PathCalculationException) { - logDirect("Failed to recompute segment"); - } else { - logUnhandledException(ex); - } + if (ex instanceof PathCalculationException) { + logDirect("Failed to recompute segment"); + } else if (ex != null) { + logUnhandledException(ex); } }); } @@ -175,12 +173,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H }) .whenComplete((result, ex) -> { this.recalculating = false; - if (ex != null) { - if (ex instanceof PathCalculationException) { - logDirect("Failed to compute next segment"); - } else { - logUnhandledException(ex); - } + if (ex instanceof PathCalculationException) { + logDirect("Failed to compute next segment"); + } else if (ex != null) { + logUnhandledException(ex); } }); } From f4a99253f44f727dbff097c92c28796d4860b830 Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 22 Jun 2023 12:08:30 -0500 Subject: [PATCH 220/405] Prevent head bonks --- src/main/java/baritone/behavior/ElytraBehavior.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 5e370fa28..89acee39f 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -628,6 +628,11 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H if (!this.clearView(start, dest, ignoreLava)) { return false; } + // Prevent head bonks + // Even though the player's hitbox is supposed to be 0.6 tall, there's no way it's actually that short + if (!this.clearView(start.add(0, 1.6, 0), dest, ignoreLava)) { + return false; + } if (growAmount == null) { return true; } From 9cf5538058579470f87ccb6a009f99b1681aa0b2 Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 22 Jun 2023 12:50:06 -0500 Subject: [PATCH 221/405] Improve stepper collision detection --- .../baritone/behavior/ElytraBehavior.java | 45 ++++++++++++------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 89acee39f..5f25119a7 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -628,7 +628,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H if (!this.clearView(start, dest, ignoreLava)) { return false; } - // Prevent head bonks + // Avoid head bonks // Even though the player's hitbox is supposed to be 0.6 tall, there's no way it's actually that short if (!this.clearView(start.add(0, 1.6, 0), dest, ignoreLava)) { return false; @@ -684,14 +684,14 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } - private Pair solvePitch(Vec3d goalDirection, int steps, int relaxation, boolean isBoosted, boolean ignoreLava) { - final Float pitch = this.solvePitch(goalDirection, steps, relaxation == 2, isBoosted, ignoreLava); + private Pair solvePitch(Vec3d goalDelta, int steps, int relaxation, boolean isBoosted, boolean ignoreLava) { + final Float pitch = this.solvePitch(goalDelta, steps, relaxation == 2, isBoosted, ignoreLava); if (pitch != null) { return new Pair<>(pitch, false); } if (Baritone.settings().experimentalTakeoff.value && relaxation > 0) { - final Float usingFirework = this.solvePitch(goalDirection, steps, relaxation == 2, true, ignoreLava); + final Float usingFirework = this.solvePitch(goalDelta, steps, relaxation == 2, true, ignoreLava); if (usingFirework != null) { return new Pair<>(usingFirework, true); } @@ -700,37 +700,48 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return new Pair<>(null, false); } - private Float solvePitch(Vec3d goalDirection, int steps, boolean desperate, boolean firework, boolean ignoreLava) { + private Float solvePitch(Vec3d goalDelta, int steps, boolean desperate, boolean firework, boolean ignoreLava) { // we are at a certain velocity, but we have a target velocity // what pitch would get us closest to our target velocity? // yaw is easy so we only care about pitch - goalDirection = goalDirection.normalize(); + final Vec3d goalDirection = goalDelta.normalize(); Rotation good = RotationUtils.calcRotationFromVec3d(Vec3d.ZERO, goalDirection, ctx.playerRotations()); // lazy lol Float bestPitch = null; double bestDot = Double.NEGATIVE_INFINITY; - Vec3d motion = new Vec3d(ctx.player().motionX, ctx.player().motionY, ctx.player().motionZ); - float minPitch = desperate ? -90 : Math.max(good.getPitch() - Baritone.settings().elytraPitchRange.value, -89); - float maxPitch = desperate ? 90 : Math.min(good.getPitch() + Baritone.settings().elytraPitchRange.value, 89); + + final Vec3d initialMotion = new Vec3d(ctx.player().motionX, ctx.player().motionY, ctx.player().motionZ); + final AxisAlignedBB initialBB = ctx.player().getEntityBoundingBox(); + final float minPitch = desperate ? -90 : Math.max(good.getPitch() - Baritone.settings().elytraPitchRange.value, -89); + final float maxPitch = desperate ? 90 : Math.min(good.getPitch() + Baritone.settings().elytraPitchRange.value, 89); + outer: for (float pitch = minPitch; pitch <= maxPitch; pitch++) { - Vec3d stepped = motion; + Vec3d motion = initialMotion; + AxisAlignedBB hitbox = initialBB; Vec3d totalMotion = Vec3d.ZERO; for (int i = 0; i < steps; i++) { - stepped = step(stepped, pitch, good.getYaw(), firework && i > 0); - Vec3d actualPositionPrevTick = ctx.playerFeetAsVec().add(totalMotion); - totalMotion = totalMotion.add(stepped); - Vec3d actualPosition = ctx.playerFeetAsVec().add(totalMotion); - for (int x = MathHelper.floor(Math.min(actualPosition.x, actualPositionPrevTick.x) - 0.31); x <= Math.max(actualPosition.x, actualPositionPrevTick.x) + 0.31; x++) { - for (int y = MathHelper.floor(Math.min(actualPosition.y, actualPositionPrevTick.y) - 0.2); y <= Math.max(actualPosition.y, actualPositionPrevTick.y) + 1; y++) { - for (int z = MathHelper.floor(Math.min(actualPosition.z, actualPositionPrevTick.z) - 0.31); z <= Math.max(actualPosition.z, actualPositionPrevTick.z) + 0.31; z++) { + motion = step(motion, pitch, good.getYaw(), firework && i > 0); + + final AxisAlignedBB inMotion = hitbox.expand(motion.x, motion.y, motion.z) + // Additional padding for safety + .grow(0.01, 0.01, 0.01) + // Expand 0.4 up and 0.2 down for head bonk avoidance + .expand(0, 0.4, 0).expand(0, -0.2, 0); + + for (int x = MathHelper.floor(inMotion.minX); x < MathHelper.ceil(inMotion.maxX); x++) { + for (int y = MathHelper.floor(inMotion.minY); y < MathHelper.ceil(inMotion.maxY); y++) { + for (int z = MathHelper.floor(inMotion.minZ); z < MathHelper.ceil(inMotion.maxZ); z++) { if (!this.passable(x, y, z, ignoreLava)) { continue outer; } } } } + + hitbox = hitbox.offset(motion.x, motion.y, motion.z); + totalMotion = totalMotion.add(motion); } double directionalGoodness = goalDirection.dotProduct(totalMotion.normalize()); // tried to incorporate a "speedGoodness" but it kept making it do stupid stuff (aka always losing altitude) From 90434b3178516fe92c4dbe9538bc432e95a1bf15 Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 22 Jun 2023 12:54:30 -0500 Subject: [PATCH 222/405] A bit more flexibility --- src/main/java/baritone/behavior/ElytraBehavior.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 5f25119a7..77c2d9f00 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -630,7 +630,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } // Avoid head bonks // Even though the player's hitbox is supposed to be 0.6 tall, there's no way it's actually that short - if (!this.clearView(start.add(0, 1.6, 0), dest, ignoreLava)) { + if (!this.clearView(start.add(0, 1, 0), dest, ignoreLava)) { return false; } if (growAmount == null) { From bce2c74a8e3cab5b14986c3f01084a587fc21af4 Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 22 Jun 2023 18:07:11 -0500 Subject: [PATCH 223/405] NO MORE CONCUSSIONS! --- .../baritone/behavior/ElytraBehavior.java | 80 ++++++++++++++----- 1 file changed, 60 insertions(+), 20 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 77c2d9f00..041813d4c 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -123,10 +123,13 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H }) .whenComplete((result, ex) -> { this.recalculating = false; - if (ex instanceof PathCalculationException) { - logDirect("Failed to compute path to destination"); - } else if (ex != null) { - logUnhandledException(ex); + if (ex != null) { + final Throwable cause = ex.getCause(); + if (cause instanceof PathCalculationException) { + logDirect("Failed to compute path to destination"); + } else { + logUnhandledException(cause); + } } }); } @@ -143,10 +146,13 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return this.path0(ctx.playerFeet(), this.path.get(upToIncl), segment -> segment.append(after.stream(), complete)) .whenComplete((result, ex) -> { this.recalculating = false; - if (ex instanceof PathCalculationException) { - logDirect("Failed to recompute segment"); - } else if (ex != null) { - logUnhandledException(ex); + if (ex != null) { + final Throwable cause = ex.getCause(); + if (cause instanceof PathCalculationException) { + logDirect("Failed to recompute segment"); + } else { + logUnhandledException(cause); + } } }); } @@ -173,10 +179,13 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H }) .whenComplete((result, ex) -> { this.recalculating = false; - if (ex instanceof PathCalculationException) { - logDirect("Failed to compute next segment"); - } else if (ex != null) { - logUnhandledException(ex); + if (ex != null) { + final Throwable cause = ex.getCause(); + if (cause instanceof PathCalculationException) { + logDirect("Failed to compute next segment"); + } else { + logUnhandledException(cause); + } } }); } @@ -628,11 +637,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H if (!this.clearView(start, dest, ignoreLava)) { return false; } - // Avoid head bonks - // Even though the player's hitbox is supposed to be 0.6 tall, there's no way it's actually that short - if (!this.clearView(start.add(0, 1, 0), dest, ignoreLava)) { - return false; - } if (growAmount == null) { return true; } @@ -722,13 +726,14 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H AxisAlignedBB hitbox = initialBB; Vec3d totalMotion = Vec3d.ZERO; for (int i = 0; i < steps; i++) { + if (MC_1_12_Collision_Fix.bonk(ctx, hitbox)) { + continue outer; + } motion = step(motion, pitch, good.getYaw(), firework && i > 0); final AxisAlignedBB inMotion = hitbox.expand(motion.x, motion.y, motion.z) // Additional padding for safety - .grow(0.01, 0.01, 0.01) - // Expand 0.4 up and 0.2 down for head bonk avoidance - .expand(0, 0.4, 0).expand(0, -0.2, 0); + .grow(0.01, 0.01, 0.01); for (int x = MathHelper.floor(inMotion.minX); x < MathHelper.ceil(inMotion.maxX); x++) { for (int y = MathHelper.floor(inMotion.minY); y < MathHelper.ceil(inMotion.maxY); y++) { @@ -813,5 +818,40 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H Material mat = state.getMaterial(); return mat == Material.AIR || (ignoreLava && mat == Material.LAVA); } + + /** + * Minecraft 1.12's pushOutOfBlocks logic doesn't account for players being able to fit under single block spaces, + * so whenever the edge of a ceiling is encountered while elytra flying it tries to push the player out. + */ + private static final class MC_1_12_Collision_Fix { + + public static boolean bonk(final IPlayerContext ctx, final AxisAlignedBB aabb) { + final Vec3d center = aabb.getCenter(); + final double width = (double) ctx.player().width * 0.35D; + final double x = center.x; + final double y = aabb.minY + 0.5D; + final double z = center.z; + + return pushOutOfBlocks(ctx, x - width, y, z + width) + || pushOutOfBlocks(ctx, x - width, y, z - width) + || pushOutOfBlocks(ctx, x + width, y, z - width) + || pushOutOfBlocks(ctx, x + width, y, z + width); + } + + private static boolean pushOutOfBlocks(final IPlayerContext ctx, final double x, final double y, final double z) { + final BlockPos pos = new BlockPos(x, y, z); + if (isOpenBlockSpace(ctx, pos)) { + return false; + } + return isOpenBlockSpace(ctx, pos.west()) + || isOpenBlockSpace(ctx, pos.east()) + || isOpenBlockSpace(ctx, pos.north()) + || isOpenBlockSpace(ctx, pos.south()); + } + + private static boolean isOpenBlockSpace(IPlayerContext ctx, BlockPos pos) { + return !ctx.world().getBlockState(pos).isNormalCube() && !ctx.world().getBlockState(pos.up()).isNormalCube(); + } + } } From 878a32228a09eed651fde46b1203d974ebfb3506 Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 22 Jun 2023 18:22:40 -0500 Subject: [PATCH 224/405] Add avoidance setting --- src/api/java/baritone/api/Settings.java | 1 + src/main/java/baritone/behavior/ElytraBehavior.java | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index be959ef12..71a2d996b 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -52,6 +52,7 @@ public final class Settings { public final Setting elytraPitchRange = new Setting<>(25); public final Setting elytraFireworkSpeed = new Setting<>(0.6); public final Setting elytraFireworkSetbackUseDelay = new Setting<>(15); + public final Setting elytraMinimumAvoidance = new Setting<>(0.2); public final Setting conserveFireworks = new Setting<>(true); public final Setting renderRaytraces = new Setting<>(false); public final Setting elytraFreeLook = new Setting<>(false); diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 041813d4c..345da254d 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -509,9 +509,9 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } - // 1.0 -> 0.25 -> none + final double minAvoidance = Baritone.settings().elytraMinimumAvoidance.value; final Double growth = relaxation == 2 ? null - : relaxation == 0 ? 0.5d : 0.25d; + : relaxation == 0 ? 2 * minAvoidance : minAvoidance; if (this.isHitboxClear(start, dest, growth, isInLava)) { // Yaw is trivial, just calculate the rotation required to face the destination From bfae100cb91b28ab41a4378997cbbc32d85f5217 Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 22 Jun 2023 20:35:22 -0500 Subject: [PATCH 225/405] Create `ITickableAimProcessor` --- .../baritone/api/behavior/ILookBehavior.java | 9 ++-- .../api/behavior/look/IAimProcessor.java | 15 +++--- .../behavior/look/ITickableAimProcessor.java | 47 +++++++++++++++++ .../java/baritone/behavior/LookBehavior.java | 51 +++++++++++-------- 4 files changed, 88 insertions(+), 34 deletions(-) create mode 100644 src/api/java/baritone/api/behavior/look/ITickableAimProcessor.java diff --git a/src/api/java/baritone/api/behavior/ILookBehavior.java b/src/api/java/baritone/api/behavior/ILookBehavior.java index eb7c992b8..d78e7f8b3 100644 --- a/src/api/java/baritone/api/behavior/ILookBehavior.java +++ b/src/api/java/baritone/api/behavior/ILookBehavior.java @@ -40,14 +40,11 @@ public interface ILookBehavior extends IBehavior { void updateTarget(Rotation rotation, boolean blockInteract); /** - * The aim processor instance for this {@link ILookBehavior}, which is responsible for applying additional, deterministic - * transformations to the target rotation set by {@link #updateTarget}. Whenever {@link IAimProcessor#nextRotation(Rotation)} - * is called on the instance returned by this method, the returned value always reflects what would happen in the - * upcoming tick. In other words, it is a pure function, and no internal state changes. If simulation of the - * rotation states beyond the next tick is required, then a {@link IAimProcessor#fork(int) fork} should be created. + * The aim processor instance for this {@link ILookBehavior}, which is responsible for applying additional, + * deterministic transformations to the target rotation set by {@link #updateTarget}. * * @return The aim processor - * @see IAimProcessor#fork(int) + * @see IAimProcessor#fork */ IAimProcessor getAimProcessor(); } diff --git a/src/api/java/baritone/api/behavior/look/IAimProcessor.java b/src/api/java/baritone/api/behavior/look/IAimProcessor.java index 72a4c681d..c7c60f413 100644 --- a/src/api/java/baritone/api/behavior/look/IAimProcessor.java +++ b/src/api/java/baritone/api/behavior/look/IAimProcessor.java @@ -25,20 +25,21 @@ import baritone.api.utils.Rotation; public interface IAimProcessor { /** - * Returns the actual rotation that will be used when the desired rotation is requested. This is not guaranteed to - * return the same value for a given input. + * Returns the actual rotation that will be used when the desired rotation is requested. The returned rotation + * always reflects what would happen in the upcoming tick. In other words, it is a pure function, and no internal + * state changes. If simulation of the rotation states beyond the next tick is required, then a + * {@link IAimProcessor#fork fork} should be created. * * @param desired The desired rotation to set * @return The actual rotation */ - Rotation nextRotation(Rotation desired); + Rotation peekRotation(Rotation desired); /** - * Returns a copy of this {@link IAimProcessor} which has its own internal state and updates on each call to - * {@link #nextRotation(Rotation)}. + * Returns a copy of this {@link IAimProcessor} which has its own internal state and is manually tickable. * - * @param ticksAdvanced The number of ticks to advance ahead of time * @return The forked processor + * @see ITickableAimProcessor */ - IAimProcessor fork(int ticksAdvanced); + ITickableAimProcessor fork(); } diff --git a/src/api/java/baritone/api/behavior/look/ITickableAimProcessor.java b/src/api/java/baritone/api/behavior/look/ITickableAimProcessor.java new file mode 100644 index 000000000..e0a07ae57 --- /dev/null +++ b/src/api/java/baritone/api/behavior/look/ITickableAimProcessor.java @@ -0,0 +1,47 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.api.behavior.look; + +import baritone.api.utils.Rotation; + +/** + * @author Brady + */ +public interface ITickableAimProcessor extends IAimProcessor { + + /** + * Advances the internal state of this aim processor by a single tick. + */ + void tick(); + + /** + * Calls {@link #tick()} the specified number of times. + * + * @param ticks The number of calls + */ + void advance(int ticks); + + /** + * Returns the actual rotation as provided by {@link #peekRotation(Rotation)}, and then automatically advances the + * internal state by one {@link #tick() tick}. + * + * @param rotation The desired rotation to set + * @return The actual rotation + */ + Rotation nextRotation(Rotation rotation); +} diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index 57dfd206c..4ea0274d7 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -21,6 +21,7 @@ import baritone.Baritone; import baritone.api.Settings; import baritone.api.behavior.ILookBehavior; import baritone.api.behavior.look.IAimProcessor; +import baritone.api.behavior.look.ITickableAimProcessor; import baritone.api.event.events.*; import baritone.api.utils.IPlayerContext; import baritone.api.utils.Rotation; @@ -68,7 +69,6 @@ public final class LookBehavior extends Behavior implements ILookBehavior { @Override public void onTick(TickEvent event) { if (event.getType() == TickEvent.Type.IN) { - // Unlike forked AimProcessors, the root one needs to be manually updated each game tick this.processor.tick(); } } @@ -88,7 +88,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior { this.prevRotation = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch); } - final Rotation actual = this.processor.nextRotation(this.target.rotation); + final Rotation actual = this.processor.peekRotation(this.target.rotation); ctx.player().rotationYaw = actual.getYaw(); ctx.player().rotationPitch = actual.getPitch(); break; @@ -129,7 +129,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior { public void pig() { if (this.target != null) { - final Rotation actual = this.processor.nextRotation(this.target.rotation); + final Rotation actual = this.processor.peekRotation(this.target.rotation); ctx.player().rotationYaw = actual.getYaw(); } } @@ -145,7 +145,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior { @Override public void onPlayerRotationMove(RotationMoveEvent event) { if (this.target != null) { - final Rotation actual = this.processor.nextRotation(this.target.rotation); + final Rotation actual = this.processor.peekRotation(this.target.rotation); event.setYaw(actual.getYaw()); event.setPitch(actual.getPitch()); } @@ -164,7 +164,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior { } } - private static abstract class AbstractAimProcessor implements IAimProcessor { + private static abstract class AbstractAimProcessor implements ITickableAimProcessor { protected final IPlayerContext ctx; private final ForkableRandom rand; @@ -183,13 +183,8 @@ public final class LookBehavior extends Behavior implements ILookBehavior { this.randomPitchOffset = source.randomPitchOffset; } - public void tick() { - this.randomYawOffset = (this.rand.nextDouble() - 0.5) * Baritone.settings().randomLooking.value; - this.randomPitchOffset = (this.rand.nextDouble() - 0.5) * Baritone.settings().randomLooking.value; - } - @Override - public Rotation nextRotation(final Rotation rotation) { + public final Rotation peekRotation(final Rotation rotation) { final Rotation prev = this.getPrevRotation(); float desiredYaw = rotation.getYaw(); @@ -211,16 +206,34 @@ public final class LookBehavior extends Behavior implements ILookBehavior { } @Override - public final IAimProcessor fork(final int ticksAdvanced) { - final AbstractAimProcessor fork = new AbstractAimProcessor(this) { + public final void tick() { + this.randomYawOffset = (this.rand.nextDouble() - 0.5) * Baritone.settings().randomLooking.value; + this.randomPitchOffset = (this.rand.nextDouble() - 0.5) * Baritone.settings().randomLooking.value; + } + + @Override + public final void advance(int ticks) { + for (int i = 0; i < ticks; i++) { + this.tick(); + } + } + + @Override + public Rotation nextRotation(final Rotation rotation) { + final Rotation actual = this.peekRotation(rotation); + this.tick(); + return actual; + } + + @Override + public final ITickableAimProcessor fork() { + return new AbstractAimProcessor(this) { private Rotation prev = AbstractAimProcessor.this.getPrevRotation(); @Override - public Rotation nextRotation(Rotation rotation) { - final Rotation actual = super.nextRotation(rotation); - this.tick(); - return (this.prev = actual); + public Rotation nextRotation(final Rotation rotation) { + return (this.prev = super.nextRotation(rotation)); } @Override @@ -228,10 +241,6 @@ public final class LookBehavior extends Behavior implements ILookBehavior { return this.prev; } }; - for (int i = 0; i < ticksAdvanced; i++) { - fork.tick(); - } - return fork; } protected abstract Rotation getPrevRotation(); From c9a18caf492f6ccba6cb04223573e9aeb41da7cd Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 22 Jun 2023 20:38:00 -0500 Subject: [PATCH 226/405] Register `LookBehavior` first Since there's no event priority system, this is necessary to ensure anything else listening to the PRE `TickEvent` can accurately simulate rotations. --- src/main/java/baritone/Baritone.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index 776e646af..957421970 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -101,8 +101,8 @@ public class Baritone implements IBaritone { this.playerContext = new BaritonePlayerContext(this, mc); { - this.pathingBehavior = this.registerBehavior(PathingBehavior::new); this.lookBehavior = this.registerBehavior(LookBehavior::new); + this.pathingBehavior = this.registerBehavior(PathingBehavior::new); this.inventoryBehavior = this.registerBehavior(InventoryBehavior::new); this.inputOverrideHandler = this.registerBehavior(InputOverrideHandler::new); this.registerBehavior(WaypointBehavior::new); From e3a1ac85cce9605f99f2d0db97f7a852ca768f30 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Fri, 23 Jun 2023 02:28:52 +0200 Subject: [PATCH 227/405] Fix waiting for impossible rotations --- src/api/java/baritone/api/utils/RotationUtils.java | 3 ++- src/main/java/baritone/pathing/movement/MovementHelper.java | 3 ++- src/main/java/baritone/process/BuilderProcess.java | 5 +++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/api/java/baritone/api/utils/RotationUtils.java b/src/api/java/baritone/api/utils/RotationUtils.java index b3b67d9ca..9fc65df9f 100644 --- a/src/api/java/baritone/api/utils/RotationUtils.java +++ b/src/api/java/baritone/api/utils/RotationUtils.java @@ -217,7 +217,8 @@ public final class RotationUtils { public static Optional reachableOffset(IPlayerContext ctx, BlockPos pos, Vec3d offsetPos, double blockReachDistance, boolean wouldSneak) { Vec3d eyes = wouldSneak ? RayTraceUtils.inferSneakingEyePosition(ctx.player()) : ctx.player().getPositionEyes(1.0F); Rotation rotation = calcRotationFromVec3d(eyes, offsetPos, ctx.playerRotations()); - RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rotation, blockReachDistance, wouldSneak); + Rotation actualRotation = BaritoneAPI.getProvider().getBaritoneForPlayer(ctx.player()).getLookBehavior().getAimProcessor().peekRotation(rotation); + RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), actualRotation, blockReachDistance, wouldSneak); //System.out.println(result); if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) { if (result.getBlockPos().equals(pos)) { diff --git a/src/main/java/baritone/pathing/movement/MovementHelper.java b/src/main/java/baritone/pathing/movement/MovementHelper.java index b14b2d69c..881bb6f15 100644 --- a/src/main/java/baritone/pathing/movement/MovementHelper.java +++ b/src/main/java/baritone/pathing/movement/MovementHelper.java @@ -684,7 +684,8 @@ public interface MovementHelper extends ActionCosts, Helper { double faceY = (placeAt.getY() + against1.getY() + 0.5D) * 0.5D; double faceZ = (placeAt.getZ() + against1.getZ() + 1.0D) * 0.5D; Rotation place = RotationUtils.calcRotationFromVec3d(wouldSneak ? RayTraceUtils.inferSneakingEyePosition(ctx.player()) : ctx.playerHead(), new Vec3d(faceX, faceY, faceZ), ctx.playerRotations()); - RayTraceResult res = RayTraceUtils.rayTraceTowards(ctx.player(), place, ctx.playerController().getBlockReachDistance(), wouldSneak); + Rotation actual = baritone.getLookBehavior().getAimProcessor().peekRotation(place); + RayTraceResult res = RayTraceUtils.rayTraceTowards(ctx.player(), actual, ctx.playerController().getBlockReachDistance(), wouldSneak); if (res != null && res.typeOfHit == RayTraceResult.Type.BLOCK && res.getBlockPos().equals(against1) && res.getBlockPos().offset(res.sideHit).equals(placeAt)) { state.setTarget(new MovementState.MovementTarget(place, true)); found = true; diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index bd14d09a7..60066971e 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -351,9 +351,10 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil double placeY = placeAgainstPos.y + aabb.minY * placementMultiplier.y + aabb.maxY * (1 - placementMultiplier.y); double placeZ = placeAgainstPos.z + aabb.minZ * placementMultiplier.z + aabb.maxZ * (1 - placementMultiplier.z); Rotation rot = RotationUtils.calcRotationFromVec3d(RayTraceUtils.inferSneakingEyePosition(ctx.player()), new Vec3d(placeX, placeY, placeZ), ctx.playerRotations()); - RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot, ctx.playerController().getBlockReachDistance(), true); + Rotation actualRot = baritone.getLookBehavior().getAimProcessor().peekRotation(rot); + RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), actualRot, ctx.playerController().getBlockReachDistance(), true); if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK && result.getBlockPos().equals(placeAgainstPos) && result.sideHit == against.getOpposite()) { - OptionalInt hotbar = hasAnyItemThatWouldPlace(toPlace, result, rot); + OptionalInt hotbar = hasAnyItemThatWouldPlace(toPlace, result, actualRot); if (hotbar.isPresent()) { return Optional.of(new Placement(hotbar.getAsInt(), placeAgainstPos, against.getOpposite(), rot)); } From c10903be6985d553d623b590088b3943cfe98d92 Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 23 Jun 2023 16:17:59 -0700 Subject: [PATCH 228/405] Remove `firstFireworks` from `InventoryBehavior` --- .../java/baritone/behavior/InventoryBehavior.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/main/java/baritone/behavior/InventoryBehavior.java b/src/main/java/baritone/behavior/InventoryBehavior.java index 5c351adce..1ab31eb53 100644 --- a/src/main/java/baritone/behavior/InventoryBehavior.java +++ b/src/main/java/baritone/behavior/InventoryBehavior.java @@ -152,20 +152,6 @@ public final class InventoryBehavior extends Behavior implements Helper { return bestInd; } - private int firstFireworks() { - final NonNullList invy = ctx.player().inventory.mainInventory; - for (int i = 0; i < invy.size(); i++) { - final ItemStack itemStack = invy.get(i); - final NBTTagCompound subCompound = itemStack.getSubCompound("Fireworks"); - if (itemStack.getItem() == Items.FIREWORKS - && subCompound != null - && subCompound.hasKey("Flight")) { - return i; - } - } - return -1; - } - public boolean hasGenericThrowaway() { for (Item item : Baritone.settings().acceptableThrowawayItems.value) { if (throwaway(false, stack -> item.equals(stack.getItem()))) { From f56e0569a2878fff0828f9041d6c9736d1d0ec58 Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 23 Jun 2023 16:30:10 -0700 Subject: [PATCH 229/405] Add `minimumBoostTicks` --- .../baritone/behavior/ElytraBehavior.java | 40 +++++++++++++++---- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 345da254d..e2c87c2c7 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -60,7 +60,19 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // :sunglasses: private final NetherPathfinderContext context; private final PathManager pathManager; + + /** + * Remaining cool-down ticks between firework usage + */ private int remainingFireworkTicks; + + /** + * The most recent minimum number of firework boost ticks, equivalent to {@code 10 * (1 + Flight)} + *

+ * Updated every time a firework is automatically used + */ + private int minimumBoostTicks; + private int remainingSetBackTicks; private BlockStateInterface bsi; @@ -561,6 +573,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } logDirect("attempting to use firework" + (forceUseFirework ? " takeoff" : "")); ctx.playerController().processRightClick(ctx.player(), ctx.world(), EnumHand.MAIN_HAND); + this.minimumBoostTicks = 10 * (1 + getFireworkBoost(ctx.player().getHeldItemMainhand()).orElse(0)); this.remainingFireworkTicks = 10; } } @@ -576,7 +589,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.path = ElytraBehavior.this.pathManager.getPath(); this.playerNear = ElytraBehavior.this.pathManager.getNear(); this.start = ElytraBehavior.this.ctx.playerFeetAsVec(); - this.isBoosted = ElytraBehavior.this.isFireworkActive(); + this.isBoosted = ElytraBehavior.this.getAttachedFirework().isPresent(); } @Override @@ -618,19 +631,30 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return false; } // If it has NBT data, make sure it won't cause us to explode. - final NBTTagCompound subCompound = itemStack.getSubCompound("Fireworks"); - return subCompound == null || !subCompound.hasKey("Explosions"); + final NBTTagCompound compound = itemStack.getSubCompound("Fireworks"); + return compound == null || !compound.hasKey("Explosions"); } private static boolean isBoostingFireworks(final ItemStack itemStack) { - final NBTTagCompound subCompound = itemStack.getSubCompound("Fireworks"); - return isFireworks(itemStack) && subCompound != null && subCompound.hasKey("Flight"); + return getFireworkBoost(itemStack).isPresent(); } - private boolean isFireworkActive() { + private static OptionalInt getFireworkBoost(final ItemStack itemStack) { + if (isFireworks(itemStack)) { + final NBTTagCompound compound = itemStack.getSubCompound("Fireworks"); + if (compound != null && compound.hasKey("Flight")) { + return OptionalInt.of(compound.getByte("Flight")); + } + } + return OptionalInt.empty(); + } + + private Optional getAttachedFirework() { return ctx.world().loadedEntityList.stream() - .filter(x -> x instanceof EntityFireworkRocket) - .anyMatch(x -> Objects.equals(((IEntityFireworkRocket) x).getBoostedEntity(), ctx.player())); + .filter(x -> x instanceof EntityFireworkRocket) + .filter(x -> Objects.equals(((IEntityFireworkRocket) x).getBoostedEntity(), ctx.player())) + .map(x -> (EntityFireworkRocket) x) + .findFirst(); } private boolean isHitboxClear(final Vec3d start, final Vec3d dest, final Double growAmount, boolean ignoreLava) { From 2ccd464a4989013609b6d293a3167b1cc854b83d Mon Sep 17 00:00:00 2001 From: Brady Date: Sat, 24 Jun 2023 21:44:08 -0700 Subject: [PATCH 230/405] Utilize aim processor API for correct elytra simulation --- .../baritone/api/utils/IPlayerContext.java | 4 ++ .../baritone/behavior/ElytraBehavior.java | 43 +++++++++++++------ 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/api/java/baritone/api/utils/IPlayerContext.java b/src/api/java/baritone/api/utils/IPlayerContext.java index 14ca69fb9..8edd8f648 100644 --- a/src/api/java/baritone/api/utils/IPlayerContext.java +++ b/src/api/java/baritone/api/utils/IPlayerContext.java @@ -75,6 +75,10 @@ public interface IPlayerContext { return new Vec3d(player().posX, player().posY + player().getEyeHeight(), player().posZ); } + default Vec3d playerMotion() { + return new Vec3d(player().motionX, player().motionY, player().motionZ); + } + BetterBlockPos viewerPos(); default Rotation playerRotations() { diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index e2c87c2c7..d3e1c76f7 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -19,6 +19,8 @@ package baritone.behavior; import baritone.Baritone; import baritone.api.behavior.IElytraBehavior; +import baritone.api.behavior.look.IAimProcessor; +import baritone.api.behavior.look.ITickableAimProcessor; import baritone.api.event.events.*; import baritone.api.utils.*; import baritone.behavior.elytra.NetherPathfinderContext; @@ -433,7 +435,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H logDirect("vbonk"); } - final SolverContext solverContext = this.new SolverContext(); + final SolverContext solverContext = this.new SolverContext(false); this.solveNextTick = true; // If there's no previously calculated solution to use, or the context used at the end of last tick doesn't match this tick @@ -470,7 +472,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // changed. Updating it now will avoid unnecessary recalculation on the main thread. this.pathManager.updatePlayerNear(); - final SolverContext context = this.new SolverContext(); + final SolverContext context = this.new SolverContext(true); this.solver = CompletableFuture.supplyAsync(() -> this.solveAngles(context)); this.solveNextTick = false; } @@ -529,7 +531,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // Yaw is trivial, just calculate the rotation required to face the destination final float yaw = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()).getYaw(); - final Pair pitch = this.solvePitch(dest.subtract(start), steps, relaxation, isBoosted, isInLava); + final Pair pitch = this.solvePitch(context, dest.subtract(start), steps, relaxation, isInLava); if (pitch.first() == null) { solution = new Solution(context, new Rotation(yaw, ctx.playerRotations().getPitch()), null, false, false); continue; @@ -584,12 +586,20 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H public final int playerNear; public final Vec3d start; public final boolean isBoosted; + public final IAimProcessor aimProcessor; - public SolverContext() { + public SolverContext(boolean async) { this.path = ElytraBehavior.this.pathManager.getPath(); this.playerNear = ElytraBehavior.this.pathManager.getNear(); this.start = ElytraBehavior.this.ctx.playerFeetAsVec(); this.isBoosted = ElytraBehavior.this.getAttachedFirework().isPresent(); + + ITickableAimProcessor aim = ElytraBehavior.this.baritone.getLookBehavior().getAimProcessor().fork(); + if (async) { + // async computation is done at the end of a tick, advance by 1 to prepare for the next tick + aim.advance(1); + } + this.aimProcessor = aim; } @Override @@ -712,14 +722,14 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } - private Pair solvePitch(Vec3d goalDelta, int steps, int relaxation, boolean isBoosted, boolean ignoreLava) { - final Float pitch = this.solvePitch(goalDelta, steps, relaxation == 2, isBoosted, ignoreLava); + private Pair solvePitch(SolverContext context, Vec3d goalDelta, int steps, int relaxation, boolean ignoreLava) { + final Float pitch = this.solvePitch(context, goalDelta, steps, relaxation == 2, context.isBoosted, ignoreLava); if (pitch != null) { return new Pair<>(pitch, false); } if (Baritone.settings().experimentalTakeoff.value && relaxation > 0) { - final Float usingFirework = this.solvePitch(goalDelta, steps, relaxation == 2, true, ignoreLava); + final Float usingFirework = this.solvePitch(context, goalDelta, steps, relaxation == 2, true, ignoreLava); if (usingFirework != null) { return new Pair<>(usingFirework, true); } @@ -728,32 +738,39 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return new Pair<>(null, false); } - private Float solvePitch(Vec3d goalDelta, int steps, boolean desperate, boolean firework, boolean ignoreLava) { + private Float solvePitch(SolverContext context, Vec3d goalDelta, int steps, boolean desperate, boolean firework, boolean ignoreLava) { // we are at a certain velocity, but we have a target velocity // what pitch would get us closest to our target velocity? // yaw is easy so we only care about pitch final Vec3d goalDirection = goalDelta.normalize(); - Rotation good = RotationUtils.calcRotationFromVec3d(Vec3d.ZERO, goalDirection, ctx.playerRotations()); // lazy lol + final float goodPitch = RotationUtils.calcRotationFromVec3d(Vec3d.ZERO, goalDirection, ctx.playerRotations()).getPitch(); Float bestPitch = null; double bestDot = Double.NEGATIVE_INFINITY; - final Vec3d initialMotion = new Vec3d(ctx.player().motionX, ctx.player().motionY, ctx.player().motionZ); + final Vec3d initialMotion = ctx.playerMotion(); final AxisAlignedBB initialBB = ctx.player().getEntityBoundingBox(); - final float minPitch = desperate ? -90 : Math.max(good.getPitch() - Baritone.settings().elytraPitchRange.value, -89); - final float maxPitch = desperate ? 90 : Math.min(good.getPitch() + Baritone.settings().elytraPitchRange.value, 89); + final float minPitch = desperate ? -90 : Math.max(goodPitch - Baritone.settings().elytraPitchRange.value, -89); + final float maxPitch = desperate ? 90 : Math.min(goodPitch + Baritone.settings().elytraPitchRange.value, 89); outer: for (float pitch = minPitch; pitch <= maxPitch; pitch++) { + final ITickableAimProcessor aimProcessor = context.aimProcessor.fork(); + Vec3d delta = goalDelta; Vec3d motion = initialMotion; AxisAlignedBB hitbox = initialBB; Vec3d totalMotion = Vec3d.ZERO; + for (int i = 0; i < steps; i++) { if (MC_1_12_Collision_Fix.bonk(ctx, hitbox)) { continue outer; } - motion = step(motion, pitch, good.getYaw(), firework && i > 0); + final Rotation rotation = aimProcessor.nextRotation( + RotationUtils.calcRotationFromVec3d(Vec3d.ZERO, delta, ctx.playerRotations()).withPitch(pitch) + ); + motion = step(motion, rotation.getPitch(), rotation.getYaw(), firework && i > 0); + delta = delta.subtract(motion); final AxisAlignedBB inMotion = hitbox.expand(motion.x, motion.y, motion.z) // Additional padding for safety From 15f4253b3db96b8c31ef088f4c4f7305c5ed8b0a Mon Sep 17 00:00:00 2001 From: Brady Date: Sat, 24 Jun 2023 21:48:44 -0700 Subject: [PATCH 231/405] Clamp pitch to normal range --- src/main/java/baritone/behavior/LookBehavior.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index 4ea0274d7..d438e8f85 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -202,7 +202,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior { return new Rotation( this.calculateMouseMove(prev.getYaw(), desiredYaw), this.calculateMouseMove(prev.getPitch(), desiredPitch) - ); + ).clamp(); } @Override From 615266ed963a47ac1c7c6a4363d36ec229a36034 Mon Sep 17 00:00:00 2001 From: Brady Date: Sat, 24 Jun 2023 21:57:00 -0700 Subject: [PATCH 232/405] Replace manual calculation with util method --- .../java/baritone/behavior/ElytraBehavior.java | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index d3e1c76f7..642def293 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -769,12 +769,11 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final Rotation rotation = aimProcessor.nextRotation( RotationUtils.calcRotationFromVec3d(Vec3d.ZERO, delta, ctx.playerRotations()).withPitch(pitch) ); - motion = step(motion, rotation.getPitch(), rotation.getYaw(), firework && i > 0); + motion = step(motion, rotation, firework && i > 0); delta = delta.subtract(motion); - final AxisAlignedBB inMotion = hitbox.expand(motion.x, motion.y, motion.z) - // Additional padding for safety - .grow(0.01, 0.01, 0.01); + // Collision box while the player is in motion, with additional padding for safety + final AxisAlignedBB inMotion = hitbox.expand(motion.x, motion.y, motion.z).grow(0.01); for (int x = MathHelper.floor(inMotion.minX); x < MathHelper.ceil(inMotion.maxX); x++) { for (int y = MathHelper.floor(inMotion.minY); y < MathHelper.ceil(inMotion.maxY); y++) { @@ -800,15 +799,11 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return bestPitch; } - private static Vec3d step(Vec3d motion, float rotationPitch, float rotationYaw, boolean firework) { + private static Vec3d step(final Vec3d motion, final Rotation rotation, final boolean firework) { double motionX = motion.x; double motionY = motion.y; double motionZ = motion.z; - float flatZ = MathHelper.cos((-rotationYaw * RotationUtils.DEG_TO_RAD_F) - (float) Math.PI); - float flatX = MathHelper.sin((-rotationYaw * RotationUtils.DEG_TO_RAD_F) - (float) Math.PI); - float pitchBase = -MathHelper.cos(-rotationPitch * RotationUtils.DEG_TO_RAD_F); - float pitchHeight = MathHelper.sin(-rotationPitch * RotationUtils.DEG_TO_RAD_F); - Vec3d lookDirection = new Vec3d(flatX * pitchBase, pitchHeight, flatZ * pitchBase); + final Vec3d lookDirection = RotationUtils.calcLookDirectionFromRotation(rotation); if (firework) { // See EntityFireworkRocket @@ -817,7 +812,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H motionZ += lookDirection.z * 0.1 + (lookDirection.z * 1.5 - motionZ) * 0.5; } - float pitchRadians = rotationPitch * RotationUtils.DEG_TO_RAD_F; + float pitchRadians = rotation.getPitch() * RotationUtils.DEG_TO_RAD_F; double pitchBase2 = Math.sqrt(lookDirection.x * lookDirection.x + lookDirection.z * lookDirection.z); double flatMotion = Math.sqrt(motionX * motionX + motionZ * motionZ); double thisIsAlwaysOne = lookDirection.length(); From 32b7c8265077a2b25873ddb0750d2d74a63f02fd Mon Sep 17 00:00:00 2001 From: Brady Date: Sat, 24 Jun 2023 22:11:08 -0700 Subject: [PATCH 233/405] Add `renderHitboxRaytraces` setting --- src/api/java/baritone/api/Settings.java | 1 + .../java/baritone/behavior/ElytraBehavior.java | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 1b39c3cab..48d1c85d2 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -55,6 +55,7 @@ public final class Settings { public final Setting elytraMinimumAvoidance = new Setting<>(0.2); public final Setting conserveFireworks = new Setting<>(true); public final Setting renderRaytraces = new Setting<>(false); + public final Setting renderHitboxRaytraces = new Setting<>(false); public final Setting elytraFreeLook = new Setting<>(false); // Experimental Elytra Settings diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 642def293..af353896f 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -701,6 +701,21 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H bb.maxX + ox, bb.maxY + oy, bb.minZ + oz, bb.maxX + ox, bb.maxY + oy, bb.maxZ + oz, }; + + // Use non-batching method without early failure + if (Baritone.settings().renderHitboxRaytraces.value) { + boolean clear = true; + for (int i = 0; i < 8; i++) { + final Vec3d s = new Vec3d(src[i * 3], src[i * 3 + 1], src[i * 3 + 2]); + final Vec3d d = new Vec3d(dst[i * 3], dst[i * 3 + 1], dst[i * 3 + 2]); + // Don't forward ignoreLava since the batch call doesn't care about it + if (!this.clearView(s, d, false)) { + clear = false; + } + } + return clear; + } + return this.context.raytrace(8, src, dst, NetherPathfinderContext.Visibility.ALL); } From a1a3d93dc1e3a04db2c1c4c707353c2090e22bdc Mon Sep 17 00:00:00 2001 From: Brady Date: Sat, 24 Jun 2023 22:27:38 -0700 Subject: [PATCH 234/405] Add `renderElytraSimulation` setting --- src/api/java/baritone/api/Settings.java | 1 + src/main/java/baritone/behavior/ElytraBehavior.java | 10 ++++++++++ src/main/java/baritone/utils/PathRenderer.java | 11 +++++++++++ 3 files changed, 22 insertions(+) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 48d1c85d2..960759fa2 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -56,6 +56,7 @@ public final class Settings { public final Setting conserveFireworks = new Setting<>(true); public final Setting renderRaytraces = new Setting<>(false); public final Setting renderHitboxRaytraces = new Setting<>(false); + public final Setting renderElytraSimulation = new Setting<>(false); public final Setting elytraFreeLook = new Setting<>(false); // Experimental Elytra Settings diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index af353896f..cb0355832 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -56,6 +56,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // Used exclusively for PathRenderer public List> clearLines; public List> blockedLines; + public List simulationLine; public BlockPos aimPos; public List visiblePath; @@ -407,6 +408,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // Reset rendered elements this.clearLines.clear(); this.blockedLines.clear(); + this.simulationLine = null; this.aimPos = null; final List path = this.pathManager.getPath(); @@ -763,6 +765,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H Float bestPitch = null; double bestDot = Double.NEGATIVE_INFINITY; + List bestLine = null; final Vec3d initialMotion = ctx.playerMotion(); final AxisAlignedBB initialBB = ctx.player().getEntityBoundingBox(); @@ -776,6 +779,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H Vec3d motion = initialMotion; AxisAlignedBB hitbox = initialBB; Vec3d totalMotion = Vec3d.ZERO; + List line = new ArrayList<>(); + line.add(totalMotion); for (int i = 0; i < steps; i++) { if (MC_1_12_Collision_Fix.bonk(ctx, hitbox)) { @@ -802,6 +807,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H hitbox = hitbox.offset(motion.x, motion.y, motion.z); totalMotion = totalMotion.add(motion); + line.add(totalMotion); } double directionalGoodness = goalDirection.dotProduct(totalMotion.normalize()); // tried to incorporate a "speedGoodness" but it kept making it do stupid stuff (aka always losing altitude) @@ -809,8 +815,12 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H if (goodness > bestDot) { bestDot = goodness; bestPitch = pitch; + bestLine = line; } } + if (bestLine != null) { + this.simulationLine = bestLine; + } return bestPitch; } diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index 0b08a1f32..da2f69e7b 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -122,6 +122,17 @@ public final class PathRenderer implements IRenderer { } IRenderer.endLines(settings.renderPathIgnoreDepth.value); } + if (elytra.simulationLine != null && Baritone.settings().renderElytraSimulation.value) { + IRenderer.startLines(new Color(0x36CCDC), settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); + for (int i = 0; i < elytra.simulationLine.size() - 1; i++) { + Vec3d src = elytra.simulationLine.get(i); + Vec3d dst = elytra.simulationLine.get(i + 1); + // Center line on viewer pos + buffer.pos(src.x, src.y, src.z).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(dst.x, dst.y, dst.z).color(color[0], color[1], color[2], color[3]).endVertex(); + } + IRenderer.endLines(settings.renderPathIgnoreDepth.value); + } // If there is a path calculation currently running, render the path calculation process From 1902e6c1f351caabe8035879f59a7c77dc6efdc1 Mon Sep 17 00:00:00 2001 From: Brady Date: Sat, 24 Jun 2023 22:37:21 -0700 Subject: [PATCH 235/405] Reset `minimumBoostTicks` to 0 when not boosted --- src/main/java/baritone/behavior/ElytraBehavior.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index cb0355832..2ceea192a 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -550,6 +550,9 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } private void tickUseFireworks(final Vec3d start, final Vec3d goingTo, final boolean isBoosted, final boolean forceUseFirework) { + if (!isBoosted) { + this.minimumBoostTicks = 0; + } if (this.remainingSetBackTicks > 0) { logDebug("waiting for elytraFireworkSetbackUseDelay: " + this.remainingSetBackTicks); return; From 9d1addd114ebc33c87aef59c13ce716a489caf2f Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 25 Jun 2023 15:28:06 -0700 Subject: [PATCH 236/405] Add `smoothLook` setting --- src/api/java/baritone/api/Settings.java | 1 + src/main/java/baritone/behavior/LookBehavior.java | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 960759fa2..5ec5b6ed4 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -58,6 +58,7 @@ public final class Settings { public final Setting renderHitboxRaytraces = new Setting<>(false); public final Setting renderElytraSimulation = new Setting<>(false); public final Setting elytraFreeLook = new Setting<>(false); + public final Setting smoothLook = new Setting<>(false); // Experimental Elytra Settings public final Setting experimentalTakeoff = new Setting<>(false); diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index 9dd379771..f59d1be83 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -26,6 +26,7 @@ import baritone.api.event.events.*; import baritone.api.utils.IPlayerContext; import baritone.api.utils.Rotation; import baritone.behavior.look.ForkableRandom; +import com.google.common.collect.EvictingQueue; import net.minecraft.network.play.client.CPacketPlayer; import java.util.Optional; @@ -51,9 +52,12 @@ public final class LookBehavior extends Behavior implements ILookBehavior { private final AimProcessor processor; + private final EvictingQueue smoothYawBuffer; + public LookBehavior(Baritone baritone) { super(baritone); this.processor = new AimProcessor(baritone.getPlayerContext()); + this.smoothYawBuffer = EvictingQueue.create(10); } @Override @@ -96,8 +100,14 @@ public final class LookBehavior extends Behavior implements ILookBehavior { case POST: { // Reset the player's rotations back to their original values if (this.prevRotation != null) { - ctx.player().rotationYaw = this.prevRotation.getYaw(); - ctx.player().rotationPitch = this.prevRotation.getPitch(); + if (Baritone.settings().smoothLook.value) { + ctx.player().rotationYaw = (float) this.smoothYawBuffer.stream() + .mapToDouble(d -> d).average().orElseGet(this.prevRotation::getYaw); + ctx.player().rotationPitch = this.prevRotation.getPitch(); + } else { + ctx.player().rotationYaw = this.prevRotation.getYaw(); + ctx.player().rotationPitch = this.prevRotation.getPitch(); + } this.prevRotation = null; } // The target is done being used for this game tick, so it can be invalidated From 9bd085644504897f05ef52ffb3401ed8aef5ea3d Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 25 Jun 2023 15:32:02 -0700 Subject: [PATCH 237/405] lol --- src/main/java/baritone/behavior/LookBehavior.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index f59d1be83..93ea561b5 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -101,6 +101,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior { // Reset the player's rotations back to their original values if (this.prevRotation != null) { if (Baritone.settings().smoothLook.value) { + this.smoothYawBuffer.add(this.target.rotation.getYaw()); ctx.player().rotationYaw = (float) this.smoothYawBuffer.stream() .mapToDouble(d -> d).average().orElseGet(this.prevRotation::getYaw); ctx.player().rotationPitch = this.prevRotation.getPitch(); From 0981114b782f8de1d978f3372a16d8d64dad4271 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 26 Jun 2023 13:55:18 -0500 Subject: [PATCH 238/405] Create `FireworkBoost` class for additional boost context Also initialize `boostedEntity` in `EntityFireworkRocket` if `null` since it's lazily initialized in `onUpdate()` --- .../baritone/launch/mixins/MixinEntity.java | 37 +++++++++++ .../mixins/MixinEntityFireworkRocket.java | 21 +++++- src/launch/resources/mixins.baritone.json | 1 + .../baritone/behavior/ElytraBehavior.java | 64 ++++++++++++++++--- .../utils/accessor/IEntityFireworkRocket.java | 1 + 5 files changed, 112 insertions(+), 12 deletions(-) create mode 100644 src/launch/java/baritone/launch/mixins/MixinEntity.java diff --git a/src/launch/java/baritone/launch/mixins/MixinEntity.java b/src/launch/java/baritone/launch/mixins/MixinEntity.java new file mode 100644 index 000000000..a611507b8 --- /dev/null +++ b/src/launch/java/baritone/launch/mixins/MixinEntity.java @@ -0,0 +1,37 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.launch.mixins; + +import net.minecraft.entity.Entity; +import net.minecraft.network.datasync.EntityDataManager; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +/** + * @author Brady + */ +@Mixin(Entity.class) +public abstract class MixinEntity { + + @Shadow + public World world; + + @Shadow + protected EntityDataManager dataManager; +} diff --git a/src/launch/java/baritone/launch/mixins/MixinEntityFireworkRocket.java b/src/launch/java/baritone/launch/mixins/MixinEntityFireworkRocket.java index 274e979a0..559ae0d54 100644 --- a/src/launch/java/baritone/launch/mixins/MixinEntityFireworkRocket.java +++ b/src/launch/java/baritone/launch/mixins/MixinEntityFireworkRocket.java @@ -18,18 +18,35 @@ package baritone.launch.mixins; import baritone.utils.accessor.IEntityFireworkRocket; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.item.EntityFireworkRocket; +import net.minecraft.network.datasync.DataParameter; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @Mixin(EntityFireworkRocket.class) -public abstract class MixinEntityFireworkRocket implements IEntityFireworkRocket { +public abstract class MixinEntityFireworkRocket extends MixinEntity implements IEntityFireworkRocket { + + @Shadow + @Final + private static DataParameter BOOSTED_ENTITY_ID; + @Shadow private EntityLivingBase boostedEntity; + @Shadow + public abstract boolean isAttachedToEntity(); + @Override public EntityLivingBase getBoostedEntity() { - return boostedEntity; + if (this.isAttachedToEntity() && this.boostedEntity == null) { + final Entity entity = this.world.getEntityByID(this.dataManager.get(BOOSTED_ENTITY_ID)); + if (entity instanceof EntityLivingBase) { + this.boostedEntity = (EntityLivingBase) entity; + } + } + return this.boostedEntity; } } diff --git a/src/launch/resources/mixins.baritone.json b/src/launch/resources/mixins.baritone.json index 5c221de58..cbade3329 100644 --- a/src/launch/resources/mixins.baritone.json +++ b/src/launch/resources/mixins.baritone.json @@ -16,6 +16,7 @@ "MixinChunkProviderServer", "MixinChunkRenderContainer", "MixinChunkRenderWorker", + "MixinEntity", "MixinEntityFireworkRocket", "MixinEntityLivingBase", "MixinEntityPlayerSP", diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 2ceea192a..922d824de 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -462,7 +462,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.tickUseFireworks( solution.context.start, solution.goingTo, - solution.context.isBoosted, + solution.context.boost.isBoosted(), solution.forceUseFirework ); } @@ -484,15 +484,14 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final NetherPath path = context.path; final int playerNear = context.playerNear; final Vec3d start = context.start; - final boolean isBoosted = context.isBoosted; final boolean isInLava = ctx.player().isInLava(); Solution solution = null; for (int relaxation = 0; relaxation < 3; relaxation++) { // try for a strict solution first, then relax more and more (if we're in a corner or near some blocks, it will have to relax its constraints a bit) - int[] heights = isBoosted ? new int[]{20, 10, 5, 0} : new int[]{0}; // attempt to gain height, if we can, so as not to waste the boost + int[] heights = context.boost.isBoosted() ? new int[]{20, 10, 5, 0} : new int[]{0}; // attempt to gain height, if we can, so as not to waste the boost float[] interps = new float[] {1.0f, 0.75f, 0.5f, 0.25f}; - int steps = relaxation < 2 ? isBoosted ? 5 : Baritone.settings().elytraSimulationTicks.value : 3; + int steps = relaxation < 2 ? context.boost.isBoosted() ? 5 : Baritone.settings().elytraSimulationTicks.value : 3; int lookahead = relaxation == 0 ? 2 : 3; // ideally this would be expressed as a distance in blocks, rather than a number of voxel steps //int minStep = Math.max(0, playerNear - relaxation); int minStep = playerNear; @@ -590,14 +589,17 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H public final NetherPath path; public final int playerNear; public final Vec3d start; - public final boolean isBoosted; + public final FireworkBoost boost; public final IAimProcessor aimProcessor; public SolverContext(boolean async) { this.path = ElytraBehavior.this.pathManager.getPath(); this.playerNear = ElytraBehavior.this.pathManager.getNear(); this.start = ElytraBehavior.this.ctx.playerFeetAsVec(); - this.isBoosted = ElytraBehavior.this.getAttachedFirework().isPresent(); + this.boost = new FireworkBoost( + ElytraBehavior.this.getAttachedFirework().orElse(null), + ElytraBehavior.this.minimumBoostTicks + ); ITickableAimProcessor aim = ElytraBehavior.this.baritone.getLookBehavior().getAimProcessor().fork(); if (async) { @@ -620,7 +622,49 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return this.path == other.path // Contents aren't modified, just compare by reference && this.playerNear == other.playerNear && Objects.equals(this.start, other.start) - && this.isBoosted == other.isBoosted; + && Objects.equals(this.boost, other.boost); + } + } + + private static final class FireworkBoost { + + private final EntityFireworkRocket firework; + private final int minimumBoostTicks; + private final int maximumBoostTicks; + + public FireworkBoost(final EntityFireworkRocket firework, final int minimumBoostTicks) { + this.firework = firework; + + // this.lifetime = 10 * i + this.rand.nextInt(6) + this.rand.nextInt(7); + this.minimumBoostTicks = minimumBoostTicks; + this.maximumBoostTicks = minimumBoostTicks + 11; + } + + public boolean isBoosted() { + return this.firework != null; + } + + public int getGuaranteedBoostTicks() { + return this.isBoosted() ? Math.max(0, this.minimumBoostTicks - this.firework.ticksExisted) : 0; + } + + public int getMaximumBoostTicks() { + return this.isBoosted() ? Math.max(0, this.maximumBoostTicks - this.firework.ticksExisted) : 0; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || o.getClass() != FireworkBoost.class) { + return false; + } + + FireworkBoost other = (FireworkBoost) o; + return Objects.equals(this.firework, other.firework) + && this.minimumBoostTicks == other.minimumBoostTicks + && this.maximumBoostTicks == other.maximumBoostTicks; } } @@ -743,7 +787,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } private Pair solvePitch(SolverContext context, Vec3d goalDelta, int steps, int relaxation, boolean ignoreLava) { - final Float pitch = this.solvePitch(context, goalDelta, steps, relaxation == 2, context.isBoosted, ignoreLava); + final Float pitch = this.solvePitch(context, goalDelta, steps, relaxation == 2, context.boost.isBoosted(), ignoreLava); if (pitch != null) { return new Pair<>(pitch, false); } @@ -827,13 +871,13 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return bestPitch; } - private static Vec3d step(final Vec3d motion, final Rotation rotation, final boolean firework) { + private static Vec3d step(final Vec3d motion, final Rotation rotation, final boolean applyFireworkBoost) { double motionX = motion.x; double motionY = motion.y; double motionZ = motion.z; final Vec3d lookDirection = RotationUtils.calcLookDirectionFromRotation(rotation); - if (firework) { + if (applyFireworkBoost) { // See EntityFireworkRocket motionX += lookDirection.x * 0.1 + (lookDirection.x * 1.5 - motionX) * 0.5; motionY += lookDirection.y * 0.1 + (lookDirection.y * 1.5 - motionY) * 0.5; diff --git a/src/main/java/baritone/utils/accessor/IEntityFireworkRocket.java b/src/main/java/baritone/utils/accessor/IEntityFireworkRocket.java index 86c96acd9..1b22d1ffd 100644 --- a/src/main/java/baritone/utils/accessor/IEntityFireworkRocket.java +++ b/src/main/java/baritone/utils/accessor/IEntityFireworkRocket.java @@ -20,5 +20,6 @@ package baritone.utils.accessor; import net.minecraft.entity.EntityLivingBase; public interface IEntityFireworkRocket { + EntityLivingBase getBoostedEntity(); } From d244a3904036ece828534e5aa8b30babfc038f03 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 26 Jun 2023 13:57:24 -0500 Subject: [PATCH 239/405] Make `MixinEntityLivingBase` extend `MixinEntity` --- .../java/baritone/launch/mixins/MixinEntity.java | 9 +++++++++ .../baritone/launch/mixins/MixinEntityLivingBase.java | 10 ++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/launch/java/baritone/launch/mixins/MixinEntity.java b/src/launch/java/baritone/launch/mixins/MixinEntity.java index a611507b8..c4f99acbd 100644 --- a/src/launch/java/baritone/launch/mixins/MixinEntity.java +++ b/src/launch/java/baritone/launch/mixins/MixinEntity.java @@ -34,4 +34,13 @@ public abstract class MixinEntity { @Shadow protected EntityDataManager dataManager; + + @Shadow + public float rotationPitch; + + @Shadow + public float rotationYaw; + + @Shadow + public abstract void moveRelative(float strafe, float up, float forward, float friction); } diff --git a/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java b/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java index f8544dd2f..db2faa940 100644 --- a/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java +++ b/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java @@ -21,9 +21,7 @@ import baritone.api.BaritoneAPI; import baritone.api.IBaritone; import baritone.api.event.events.RotationMoveEvent; import net.minecraft.client.entity.EntityPlayerSP; -import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; @@ -40,7 +38,7 @@ import static org.spongepowered.asm.lib.Opcodes.GETFIELD; * @since 9/10/2018 */ @Mixin(EntityLivingBase.class) -public abstract class MixinEntityLivingBase extends Entity { +public abstract class MixinEntityLivingBase extends MixinEntity { /** * Event called to override the movement direction when jumping @@ -51,10 +49,6 @@ public abstract class MixinEntityLivingBase extends Entity { @Unique private RotationMoveEvent elytraRotationEvent; - public MixinEntityLivingBase(World worldIn) { - super(worldIn); - } - @Inject( method = "jump", at = @At("HEAD") @@ -123,7 +117,7 @@ public abstract class MixinEntityLivingBase extends Entity { private void onMoveRelative(EntityLivingBase self, float strafe, float up, float forward, float friction) { Optional baritone = this.getBaritone(); if (!baritone.isPresent()) { - moveRelative(strafe, up, forward, friction); + this.moveRelative(strafe, up, forward, friction); return; } From c18715b8d7a27470e2b3c345f5bbb97faae4ac99 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 26 Jun 2023 14:00:38 -0500 Subject: [PATCH 240/405] Reset `minimumBoostTicks` to 0 earlier --- src/main/java/baritone/behavior/ElytraBehavior.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 922d824de..22359a3da 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -404,6 +404,9 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H if (this.remainingSetBackTicks > 0) { this.remainingSetBackTicks--; } + if (!this.getAttachedFirework().isPresent()) { + this.minimumBoostTicks = 0; + } // Reset rendered elements this.clearLines.clear(); @@ -549,9 +552,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } private void tickUseFireworks(final Vec3d start, final Vec3d goingTo, final boolean isBoosted, final boolean forceUseFirework) { - if (!isBoosted) { - this.minimumBoostTicks = 0; - } if (this.remainingSetBackTicks > 0) { logDebug("waiting for elytraFireworkSetbackUseDelay: " + this.remainingSetBackTicks); return; From 0b5a310f1835f841e2b445b5f778eca06b265598 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 26 Jun 2023 15:35:40 -0500 Subject: [PATCH 241/405] Move firework boost calculation into `solvePitch` --- .../baritone/behavior/ElytraBehavior.java | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 22359a3da..e1a134725 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -69,6 +69,11 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H */ private int remainingFireworkTicks; + /** + * Remaining cool-down ticks after the player's position and rotation are reset by the server + */ + private int remainingSetBackTicks; + /** * The most recent minimum number of firework boost ticks, equivalent to {@code 10 * (1 + Flight)} *

@@ -76,7 +81,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H */ private int minimumBoostTicks; - private int remainingSetBackTicks; private BlockStateInterface bsi; private Future solver; @@ -836,7 +840,9 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final Rotation rotation = aimProcessor.nextRotation( RotationUtils.calcRotationFromVec3d(Vec3d.ZERO, delta, ctx.playerRotations()).withPitch(pitch) ); - motion = step(motion, rotation, firework && i > 0); + final Vec3d lookDirection = RotationUtils.calcLookDirectionFromRotation(rotation); + + motion = step(motion, lookDirection, rotation.getPitch()); delta = delta.subtract(motion); // Collision box while the player is in motion, with additional padding for safety @@ -855,6 +861,15 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H hitbox = hitbox.offset(motion.x, motion.y, motion.z); totalMotion = totalMotion.add(motion); line.add(totalMotion); + + if (firework) { + // See EntityFireworkRocket + motion = motion.add( + lookDirection.x * 0.1 + (lookDirection.x * 1.5 - motion.x) * 0.5, + lookDirection.y * 0.1 + (lookDirection.y * 1.5 - motion.y) * 0.5, + lookDirection.z * 0.1 + (lookDirection.z * 1.5 - motion.z) * 0.5 + ); + } } double directionalGoodness = goalDirection.dotProduct(totalMotion.normalize()); // tried to incorporate a "speedGoodness" but it kept making it do stupid stuff (aka always losing altitude) @@ -871,20 +886,12 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return bestPitch; } - private static Vec3d step(final Vec3d motion, final Rotation rotation, final boolean applyFireworkBoost) { + private static Vec3d step(final Vec3d motion, final Vec3d lookDirection, final float pitch) { double motionX = motion.x; double motionY = motion.y; double motionZ = motion.z; - final Vec3d lookDirection = RotationUtils.calcLookDirectionFromRotation(rotation); - if (applyFireworkBoost) { - // See EntityFireworkRocket - motionX += lookDirection.x * 0.1 + (lookDirection.x * 1.5 - motionX) * 0.5; - motionY += lookDirection.y * 0.1 + (lookDirection.y * 1.5 - motionY) * 0.5; - motionZ += lookDirection.z * 0.1 + (lookDirection.z * 1.5 - motionZ) * 0.5; - } - - float pitchRadians = rotation.getPitch() * RotationUtils.DEG_TO_RAD_F; + float pitchRadians = pitch * RotationUtils.DEG_TO_RAD_F; double pitchBase2 = Math.sqrt(lookDirection.x * lookDirection.x + lookDirection.z * lookDirection.z); double flatMotion = Math.sqrt(motionX * motionX + motionZ * motionZ); double thisIsAlwaysOne = lookDirection.length(); @@ -962,4 +969,3 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } } - From f0148a625e790e155884d2a8ddb2a992c98a4cf4 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 26 Jun 2023 16:04:05 -0500 Subject: [PATCH 242/405] Move `steps` into `solvePitch` --- src/main/java/baritone/behavior/ElytraBehavior.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index e1a134725..7deea42b9 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -498,7 +498,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H for (int relaxation = 0; relaxation < 3; relaxation++) { // try for a strict solution first, then relax more and more (if we're in a corner or near some blocks, it will have to relax its constraints a bit) int[] heights = context.boost.isBoosted() ? new int[]{20, 10, 5, 0} : new int[]{0}; // attempt to gain height, if we can, so as not to waste the boost float[] interps = new float[] {1.0f, 0.75f, 0.5f, 0.25f}; - int steps = relaxation < 2 ? context.boost.isBoosted() ? 5 : Baritone.settings().elytraSimulationTicks.value : 3; int lookahead = relaxation == 0 ? 2 : 3; // ideally this would be expressed as a distance in blocks, rather than a number of voxel steps //int minStep = Math.max(0, playerNear - relaxation); int minStep = playerNear; @@ -539,7 +538,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // Yaw is trivial, just calculate the rotation required to face the destination final float yaw = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()).getYaw(); - final Pair pitch = this.solvePitch(context, dest.subtract(start), steps, relaxation, isInLava); + final Pair pitch = this.solvePitch(context, dest.subtract(start), relaxation, isInLava); if (pitch.first() == null) { solution = new Solution(context, new Rotation(yaw, ctx.playerRotations().getPitch()), null, false, false); continue; @@ -790,7 +789,9 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } - private Pair solvePitch(SolverContext context, Vec3d goalDelta, int steps, int relaxation, boolean ignoreLava) { + private Pair solvePitch(SolverContext context, Vec3d goalDelta, int relaxation, boolean ignoreLava) { + final int steps = relaxation < 2 ? context.boost.isBoosted() ? 5 : Baritone.settings().elytraSimulationTicks.value : 3; + final Float pitch = this.solvePitch(context, goalDelta, steps, relaxation == 2, context.boost.isBoosted(), ignoreLava); if (pitch != null) { return new Pair<>(pitch, false); From db0bfbe7229df54260d3dda30995d33552672c95 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 26 Jun 2023 16:12:56 -0500 Subject: [PATCH 243/405] Move elytra simulation into new method --- .../baritone/behavior/ElytraBehavior.java | 107 +++++++++--------- 1 file changed, 54 insertions(+), 53 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 7deea42b9..ef8134c2a 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -807,7 +807,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return new Pair<>(null, false); } - private Float solvePitch(SolverContext context, Vec3d goalDelta, int steps, boolean desperate, boolean firework, boolean ignoreLava) { + private Float solvePitch(final SolverContext context, final Vec3d goalDelta, final int steps, + final boolean desperate, final boolean firework, final boolean ignoreLava) { // we are at a certain velocity, but we have a target velocity // what pitch would get us closest to our target velocity? // yaw is easy so we only care about pitch @@ -819,66 +820,18 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H double bestDot = Double.NEGATIVE_INFINITY; List bestLine = null; - final Vec3d initialMotion = ctx.playerMotion(); - final AxisAlignedBB initialBB = ctx.player().getEntityBoundingBox(); final float minPitch = desperate ? -90 : Math.max(goodPitch - Baritone.settings().elytraPitchRange.value, -89); final float maxPitch = desperate ? 90 : Math.min(goodPitch + Baritone.settings().elytraPitchRange.value, 89); - outer: for (float pitch = minPitch; pitch <= maxPitch; pitch++) { - final ITickableAimProcessor aimProcessor = context.aimProcessor.fork(); - Vec3d delta = goalDelta; - Vec3d motion = initialMotion; - AxisAlignedBB hitbox = initialBB; - Vec3d totalMotion = Vec3d.ZERO; - List line = new ArrayList<>(); - line.add(totalMotion); - - for (int i = 0; i < steps; i++) { - if (MC_1_12_Collision_Fix.bonk(ctx, hitbox)) { - continue outer; - } - final Rotation rotation = aimProcessor.nextRotation( - RotationUtils.calcRotationFromVec3d(Vec3d.ZERO, delta, ctx.playerRotations()).withPitch(pitch) - ); - final Vec3d lookDirection = RotationUtils.calcLookDirectionFromRotation(rotation); - - motion = step(motion, lookDirection, rotation.getPitch()); - delta = delta.subtract(motion); - - // Collision box while the player is in motion, with additional padding for safety - final AxisAlignedBB inMotion = hitbox.expand(motion.x, motion.y, motion.z).grow(0.01); - - for (int x = MathHelper.floor(inMotion.minX); x < MathHelper.ceil(inMotion.maxX); x++) { - for (int y = MathHelper.floor(inMotion.minY); y < MathHelper.ceil(inMotion.maxY); y++) { - for (int z = MathHelper.floor(inMotion.minZ); z < MathHelper.ceil(inMotion.maxZ); z++) { - if (!this.passable(x, y, z, ignoreLava)) { - continue outer; - } - } - } - } - - hitbox = hitbox.offset(motion.x, motion.y, motion.z); - totalMotion = totalMotion.add(motion); - line.add(totalMotion); - - if (firework) { - // See EntityFireworkRocket - motion = motion.add( - lookDirection.x * 0.1 + (lookDirection.x * 1.5 - motion.x) * 0.5, - lookDirection.y * 0.1 + (lookDirection.y * 1.5 - motion.y) * 0.5, - lookDirection.z * 0.1 + (lookDirection.z * 1.5 - motion.z) * 0.5 - ); - } + Vec3d totalMotion = this.simulate(context.aimProcessor.fork(), goalDelta, pitch, steps, firework, ignoreLava); + if (totalMotion == null) { + continue; } - double directionalGoodness = goalDirection.dotProduct(totalMotion.normalize()); - // tried to incorporate a "speedGoodness" but it kept making it do stupid stuff (aka always losing altitude) - double goodness = directionalGoodness; + double goodness = goalDirection.dotProduct(totalMotion.normalize()); if (goodness > bestDot) { bestDot = goodness; bestPitch = pitch; - bestLine = line; } } if (bestLine != null) { @@ -887,6 +840,54 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return bestPitch; } + private Vec3d simulate(final ITickableAimProcessor aimProcessor, final Vec3d goalDelta, final float pitch, + final int ticks, final boolean firework, final boolean ignoreLava) { + Vec3d delta = goalDelta; + Vec3d motion = ctx.playerMotion(); + AxisAlignedBB hitbox = ctx.player().getEntityBoundingBox(); + Vec3d totalMotion = Vec3d.ZERO; + + for (int i = 0; i < ticks; i++) { + if (MC_1_12_Collision_Fix.bonk(ctx, hitbox)) { + return null; + } + final Rotation rotation = aimProcessor.nextRotation( + RotationUtils.calcRotationFromVec3d(Vec3d.ZERO, delta, ctx.playerRotations()).withPitch(pitch) + ); + final Vec3d lookDirection = RotationUtils.calcLookDirectionFromRotation(rotation); + + motion = step(motion, lookDirection, rotation.getPitch()); + delta = delta.subtract(motion); + + // Collision box while the player is in motion, with additional padding for safety + final AxisAlignedBB inMotion = hitbox.expand(motion.x, motion.y, motion.z).grow(0.01); + + for (int x = MathHelper.floor(inMotion.minX); x < MathHelper.ceil(inMotion.maxX); x++) { + for (int y = MathHelper.floor(inMotion.minY); y < MathHelper.ceil(inMotion.maxY); y++) { + for (int z = MathHelper.floor(inMotion.minZ); z < MathHelper.ceil(inMotion.maxZ); z++) { + if (!this.passable(x, y, z, ignoreLava)) { + return null; + } + } + } + } + + hitbox = hitbox.offset(motion.x, motion.y, motion.z); + totalMotion = totalMotion.add(motion); + + if (firework) { + // See EntityFireworkRocket + motion = motion.add( + lookDirection.x * 0.1 + (lookDirection.x * 1.5 - motion.x) * 0.5, + lookDirection.y * 0.1 + (lookDirection.y * 1.5 - motion.y) * 0.5, + lookDirection.z * 0.1 + (lookDirection.z * 1.5 - motion.z) * 0.5 + ); + } + } + + return totalMotion; + } + private static Vec3d step(final Vec3d motion, final Vec3d lookDirection, final float pitch) { double motionX = motion.x; double motionY = motion.y; From 452b2c278b0fe17f84b31803af1e55d24d6b2cc8 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 26 Jun 2023 16:21:15 -0500 Subject: [PATCH 244/405] Fix `renderElytraSimulation` --- .../baritone/behavior/ElytraBehavior.java | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index ef8134c2a..c60f920a9 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -824,14 +824,23 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final float maxPitch = desperate ? 90 : Math.min(goodPitch + Baritone.settings().elytraPitchRange.value, 89); for (float pitch = minPitch; pitch <= maxPitch; pitch++) { - Vec3d totalMotion = this.simulate(context.aimProcessor.fork(), goalDelta, pitch, steps, firework, ignoreLava); - if (totalMotion == null) { + final List displacement = this.simulate( + context.aimProcessor.fork(), + goalDelta, + pitch, + steps, + firework ? Integer.MAX_VALUE : 0, + ignoreLava + ); + if (displacement == null) { continue; } - double goodness = goalDirection.dotProduct(totalMotion.normalize()); + final Vec3d result = displacement.get(displacement.size() - 1); + double goodness = goalDirection.dotProduct(result.normalize()); if (goodness > bestDot) { bestDot = goodness; bestPitch = pitch; + bestLine = displacement; } } if (bestLine != null) { @@ -840,12 +849,13 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return bestPitch; } - private Vec3d simulate(final ITickableAimProcessor aimProcessor, final Vec3d goalDelta, final float pitch, - final int ticks, final boolean firework, final boolean ignoreLava) { + private List simulate(final ITickableAimProcessor aimProcessor, final Vec3d goalDelta, final float pitch, + final int ticks, int ticksBoosted, final boolean ignoreLava) { Vec3d delta = goalDelta; Vec3d motion = ctx.playerMotion(); AxisAlignedBB hitbox = ctx.player().getEntityBoundingBox(); - Vec3d totalMotion = Vec3d.ZERO; + List displacement = new ArrayList<>(); + displacement.add(Vec3d.ZERO); for (int i = 0; i < ticks; i++) { if (MC_1_12_Collision_Fix.bonk(ctx, hitbox)) { @@ -872,10 +882,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } - hitbox = hitbox.offset(motion.x, motion.y, motion.z); - totalMotion = totalMotion.add(motion); + hitbox = hitbox.offset(motion); + displacement.add(displacement.get(displacement.size() - 1).add(motion)); - if (firework) { + if (ticksBoosted-- > 0) { // See EntityFireworkRocket motion = motion.add( lookDirection.x * 0.1 + (lookDirection.x * 1.5 - motion.x) * 0.5, @@ -885,7 +895,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } - return totalMotion; + return displacement; } private static Vec3d step(final Vec3d motion, final Vec3d lookDirection, final float pitch) { From 3e94cac56768042ab9d39a409fdbe9d5c98929af Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 26 Jun 2023 16:25:21 -0500 Subject: [PATCH 245/405] clarity --- src/main/java/baritone/behavior/ElytraBehavior.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index c60f920a9..3f056d7e6 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -789,16 +789,18 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } - private Pair solvePitch(SolverContext context, Vec3d goalDelta, int relaxation, boolean ignoreLava) { - final int steps = relaxation < 2 ? context.boost.isBoosted() ? 5 : Baritone.settings().elytraSimulationTicks.value : 3; + private Pair solvePitch(final SolverContext context, final Vec3d goalDelta, + final int relaxation, final boolean ignoreLava) { + final boolean desperate = relaxation == 2; + final int steps = desperate ? 3 : context.boost.isBoosted() ? 5 : Baritone.settings().elytraSimulationTicks.value; - final Float pitch = this.solvePitch(context, goalDelta, steps, relaxation == 2, context.boost.isBoosted(), ignoreLava); + final Float pitch = this.solvePitch(context, goalDelta, steps, desperate, context.boost.isBoosted(), ignoreLava); if (pitch != null) { return new Pair<>(pitch, false); } if (Baritone.settings().experimentalTakeoff.value && relaxation > 0) { - final Float usingFirework = this.solvePitch(context, goalDelta, steps, relaxation == 2, true, ignoreLava); + final Float usingFirework = this.solvePitch(context, goalDelta, steps, desperate, true, ignoreLava); if (usingFirework != null) { return new Pair<>(usingFirework, true); } From 04a5a1a620ffeb3b6a92ed9eed504a58f3e45f7d Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 26 Jun 2023 16:58:29 -0500 Subject: [PATCH 246/405] Replace `bool firework` with `ticksBoosted` in `solvePitch` --- .../java/baritone/behavior/ElytraBehavior.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 3f056d7e6..6a7e98f83 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -792,15 +792,17 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private Pair solvePitch(final SolverContext context, final Vec3d goalDelta, final int relaxation, final boolean ignoreLava) { final boolean desperate = relaxation == 2; - final int steps = desperate ? 3 : context.boost.isBoosted() ? 5 : Baritone.settings().elytraSimulationTicks.value; + final int ticks = desperate ? 3 : context.boost.isBoosted() ? 5 : Baritone.settings().elytraSimulationTicks.value; + final int ticksBoosted = context.boost.isBoosted() ? ticks : 0; - final Float pitch = this.solvePitch(context, goalDelta, steps, desperate, context.boost.isBoosted(), ignoreLava); + final Float pitch = this.solvePitch(context, goalDelta, ticks, ticksBoosted, desperate, ignoreLava); if (pitch != null) { return new Pair<>(pitch, false); } if (Baritone.settings().experimentalTakeoff.value && relaxation > 0) { - final Float usingFirework = this.solvePitch(context, goalDelta, steps, desperate, true, ignoreLava); + // Simulate as if we were boosted for the entire duration + final Float usingFirework = this.solvePitch(context, goalDelta, ticks, ticks, desperate, ignoreLava); if (usingFirework != null) { return new Pair<>(usingFirework, true); } @@ -809,8 +811,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return new Pair<>(null, false); } - private Float solvePitch(final SolverContext context, final Vec3d goalDelta, final int steps, - final boolean desperate, final boolean firework, final boolean ignoreLava) { + private Float solvePitch(final SolverContext context, final Vec3d goalDelta, final int ticks, + final int ticksBoosted, final boolean desperate, final boolean ignoreLava) { // we are at a certain velocity, but we have a target velocity // what pitch would get us closest to our target velocity? // yaw is easy so we only care about pitch @@ -830,8 +832,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H context.aimProcessor.fork(), goalDelta, pitch, - steps, - firework ? Integer.MAX_VALUE : 0, + ticks, + ticksBoosted, ignoreLava ); if (displacement == null) { From 02fc62f1c474b14553cc803eb912c519a8a1fd42 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 26 Jun 2023 18:37:06 -0500 Subject: [PATCH 247/405] Stop simulation when goal reached --- src/main/java/baritone/behavior/ElytraBehavior.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 6a7e98f83..abfad1ed9 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -854,7 +854,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } private List simulate(final ITickableAimProcessor aimProcessor, final Vec3d goalDelta, final float pitch, - final int ticks, int ticksBoosted, final boolean ignoreLava) { + final int ticks, int ticksBoosted, final boolean ignoreLava) { Vec3d delta = goalDelta; Vec3d motion = ctx.playerMotion(); AxisAlignedBB hitbox = ctx.player().getEntityBoundingBox(); @@ -865,6 +865,9 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H if (MC_1_12_Collision_Fix.bonk(ctx, hitbox)) { return null; } + if (delta.lengthSquared() < 1) { + break; + } final Rotation rotation = aimProcessor.nextRotation( RotationUtils.calcRotationFromVec3d(Vec3d.ZERO, delta, ctx.playerRotations()).withPitch(pitch) ); From 4ccaf681c5aae01e76892f340f0debc290327a11 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 27 Jun 2023 02:54:53 -0500 Subject: [PATCH 248/405] Somewhat functional `elytraAutoJump`, but mostly scuffed --- src/api/java/baritone/api/Settings.java | 1 + src/main/java/baritone/Baritone.java | 1 + .../baritone/behavior/ElytraBehavior.java | 177 +++++++++++++++++- 3 files changed, 171 insertions(+), 8 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 5ec5b6ed4..0842ac10a 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -58,6 +58,7 @@ public final class Settings { public final Setting renderHitboxRaytraces = new Setting<>(false); public final Setting renderElytraSimulation = new Setting<>(false); public final Setting elytraFreeLook = new Setting<>(false); +` public final Setting elytraAutoJump = new Setting<>(false); public final Setting smoothLook = new Setting<>(false); // Experimental Elytra Settings diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index 5723cc422..dcbad33f5 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -121,6 +121,7 @@ public class Baritone implements IBaritone { this.farmProcess = this.registerProcess(FarmProcess::new); this.inventoryPauserProcess = this.registerProcess(InventoryPauserProcess::new); this.registerProcess(BackfillProcess::new); + this.registerProcess(__ -> this.elytraBehavior.new ElytraProcess()); // pain } this.worldProvider = new WorldProvider(this); diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index abfad1ed9..1720cf24e 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -22,11 +22,19 @@ import baritone.api.behavior.IElytraBehavior; import baritone.api.behavior.look.IAimProcessor; import baritone.api.behavior.look.ITickableAimProcessor; import baritone.api.event.events.*; +import baritone.api.pathing.goals.Goal; +import baritone.api.pathing.goals.GoalGetToBlock; +import baritone.api.process.IBaritoneProcess; +import baritone.api.process.PathingCommand; +import baritone.api.process.PathingCommandType; import baritone.api.utils.*; +import baritone.api.utils.input.Input; +import baritone.api.utils.interfaces.IGoalRenderPos; import baritone.behavior.elytra.NetherPathfinderContext; import baritone.behavior.elytra.NetherPath; import baritone.behavior.elytra.PathCalculationException; import baritone.behavior.elytra.UnpackedSegment; +import baritone.cache.FasterWorldScanner; import baritone.utils.BlockStateInterface; import baritone.utils.accessor.IEntityFireworkRocket; import net.minecraft.block.material.Material; @@ -82,6 +90,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private int minimumBoostTicks; private BlockStateInterface bsi; + private BlockPos destination; private Future solver; private boolean solveNextTick; @@ -97,7 +106,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private final class PathManager { - private BlockPos destination; private NetherPath path; private boolean completePath; private boolean recalculating; @@ -128,10 +136,13 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.attemptNextSegment(); } - public void pathToDestination(final BlockPos destination) { - this.destination = destination; + public void pathToDestination() { + this.pathToDestination(ctx.playerFeet()); + } + + public void pathToDestination(final BlockPos from) { final long start = System.nanoTime(); - this.path0(ctx.playerFeet(), destination, UnaryOperator.identity()) + this.path0(from, ElytraBehavior.this.destination, UnaryOperator.identity()) .thenRun(() -> { final double distance = this.path.get(0).distanceTo(this.path.get(this.path.size() - 1)); if (this.completePath) { @@ -185,7 +196,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final List before = this.path.subList(0, afterIncl + 1); final long start = System.nanoTime(); - this.path0(this.path.get(afterIncl), this.destination, segment -> segment.prepend(before.stream())) + this.path0(this.path.get(afterIncl), ElytraBehavior.this.destination, segment -> segment.prepend(before.stream())) .thenRun(() -> { final int recompute = this.path.size() - before.size() - 1; final double distance = this.path.get(0).distanceTo(this.path.get(recompute)); @@ -210,7 +221,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } public void clear() { - this.destination = null; this.path = NetherPath.emptyPath(); this.completePath = true; this.recalculating = false; @@ -362,11 +372,15 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H @Override public void pathTo(BlockPos destination) { - this.pathManager.pathToDestination(destination); + this.destination = destination; + if (!Baritone.settings().elytraAutoJump.value || ctx.player().isElytraFlying()) { + this.pathManager.pathToDestination(); + } } @Override public void cancel() { + this.destination = null; this.visiblePath = Collections.emptyList(); this.pathManager.clear(); this.aimPos = null; @@ -435,7 +449,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H if (!ctx.player().isElytraFlying()) { return; } - baritone.getInputOverrideHandler().clearAllKeys(); if (ctx.player().collidedHorizontally) { logDirect("hbonk"); @@ -987,4 +1000,152 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return !ctx.world().getBlockState(pos).isNormalCube() && !ctx.world().getBlockState(pos.up()).isNormalCube(); } } + + public final class ElytraProcess implements IBaritoneProcess { + + private State state; + private Goal goal; + + @Override + public boolean isActive() { + return ElytraBehavior.this.destination != null; + } + + @Override + public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { + if (calcFailed) { + onLostControl(); + logDirect("Failed to get to jump off spot, canceling"); + return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); + } + + if (ctx.player().isElytraFlying()) { + this.state = State.FLYING; + this.goal = null; + baritone.getInputOverrideHandler().clearAllKeys(); + return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); + } + + if (!Baritone.settings().elytraAutoJump.value) { + return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); + } + + // We were flying, but we're not anymore, reset the state + if (this.state == State.FLYING) { + this.state = State.GET_TO_JUMP; + } + + if (this.state == State.GET_TO_JUMP) { + if (this.goal == null) { + final BlockPos jumpOff = this.findJumpOffSpot(); + if (jumpOff == null) { + onLostControl(); + logDirect("Couldn't find a suitable spot to jump off of, canceling"); + return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); + } + this.goal = new GoalGetToBlock(jumpOff); + ElytraBehavior.this.pathManager.pathToDestination(jumpOff.add(0, -4, 0)); + } + if (this.goal.isInGoal(ctx.playerFeet())) { + this.state = State.START_FLYING; + } else { + return new PathingCommand(this.goal, PathingCommandType.SET_GOAL_AND_PATH); + } + } + + if (this.state == State.START_FLYING && isSafeToCancel && !ElytraBehavior.this.pathManager.getPath().isEmpty()) { + baritone.getLookBehavior().updateTarget(RotationUtils.calcRotationFromVec3d( + ctx.playerHead(), + VecUtils.getBlockPosCenter(((IGoalRenderPos) this.goal).getGoalPos()), + ctx.playerRotations() + ), false); + baritone.getInputOverrideHandler().setInputForceState(Input.MOVE_FORWARD, true); + if (ctx.player().fallDistance > 0.0f) { + baritone.getInputOverrideHandler().setInputForceState(Input.JUMP, true); + } + } + return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); + } + + @Override + public boolean isTemporary() { + return false; + } + + @Override + public void onLostControl() { + this.goal = null; + this.state = State.GET_TO_JUMP; + ElytraBehavior.this.cancel(); + } + + @Override + public double priority() { + return 10; + } + + @Override + public String displayName0() { + return "Elytra"; + } + + // ok... now this.. is disgusting + // TODO: make less scuffed + private BlockPos findJumpOffSpot() { + BlockPos best = null; + final BetterBlockPos feet = ctx.playerFeet(); + final List nearby = FasterWorldScanner.getChunkRange(feet.x >> 4, feet.z >> 4, 3); + for (ChunkPos pos : nearby) { + final Chunk chunk = ctx.world().getChunk(pos.x, pos.z); + int[][] obstruction = new int[16][16]; + for (int y0 = 0; y0 < 8; y0++) { + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { + int y = feet.y - y0; + if (chunk.getBlockState(x, y, z).getMaterial() != Material.AIR) { + if (obstruction[x][z] == 0 || obstruction[x][z] > y0 + 1) { + obstruction[x][z] = y0 + 1; + } + } + } + } + } + for (int x = 0; x < 16; x++) { + for (int z = 0; z < 16; z++) { + if (obstruction[x][z] != 0) { + continue; + } + + final int[] adjacent = new int[4]; + if (x > 0) adjacent[0] = obstruction[x - 1][z]; + if (z > 0) adjacent[1] = obstruction[x][z - 1]; + if (x < 15) adjacent[2] = obstruction[x + 1][z]; + if (z < 15) adjacent[3] = obstruction[x][z + 1]; + final OptionalInt minLevel = Arrays.stream(adjacent).filter(i -> i != 0).min(); + + if (minLevel.isPresent() && minLevel.getAsInt() <= 4) { + final int yActual = feet.y - minLevel.getAsInt() + 2; // lol + // The target spot itself is clear + if (chunk.getBlockState(x, yActual, z).getMaterial() != Material.AIR + || chunk.getBlockState(x, yActual + 1, z).getMaterial() != Material.AIR) { + continue; + } + // lessgooo + final BlockPos target = new BlockPos(chunk.x << 4 | x, yActual, chunk.z << 4 | z); + if (best == null || target.distanceSq(feet) < best.distanceSq(feet)) { + best = target; + } + } + } + } + } + return best; + } + } + + private enum State { + GET_TO_JUMP, + START_FLYING, + FLYING + } } From ff12832a216c1c7b74375601e2bb16fa19cb8fd8 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 27 Jun 2023 12:30:41 -0500 Subject: [PATCH 249/405] whoops --- src/api/java/baritone/api/Settings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 0842ac10a..47643245d 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -58,7 +58,7 @@ public final class Settings { public final Setting renderHitboxRaytraces = new Setting<>(false); public final Setting renderElytraSimulation = new Setting<>(false); public final Setting elytraFreeLook = new Setting<>(false); -` public final Setting elytraAutoJump = new Setting<>(false); + public final Setting elytraAutoJump = new Setting<>(false); public final Setting smoothLook = new Setting<>(false); // Experimental Elytra Settings From 3b31387092a7fa6e05ad3b025d2e8c6e00eecb53 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 27 Jun 2023 13:02:01 -0500 Subject: [PATCH 250/405] Render simulation line from player pos --- .../java/baritone/utils/PathRenderer.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index da2f69e7b..d09567914 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -111,25 +111,28 @@ public final class PathRenderer implements IRenderer { if (!elytra.clearLines.isEmpty() && Baritone.settings().renderRaytraces.value) { IRenderer.startLines(Color.GREEN, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); for (Pair line : elytra.clearLines) { - emitLine(line.first().x, line.first().y, line.first().z, line.second().x, line.second().y, line.second().z); + emitLine(line.first(), line.second()); } IRenderer.endLines(settings.renderPathIgnoreDepth.value); } if (!elytra.blockedLines.isEmpty() && Baritone.settings().renderRaytraces.value) { IRenderer.startLines(Color.BLUE, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); for (Pair line : elytra.blockedLines) { - emitLine(line.first().x, line.first().y, line.first().z, line.second().x, line.second().y, line.second().z); + emitLine(line.first(), line.second()); } IRenderer.endLines(settings.renderPathIgnoreDepth.value); } if (elytra.simulationLine != null && Baritone.settings().renderElytraSimulation.value) { IRenderer.startLines(new Color(0x36CCDC), settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); + final Vec3d offset = new Vec3d( + ctx.player().prevPosX + (ctx.player().posX - ctx.player().prevPosX) * partialTicks, + ctx.player().prevPosY + (ctx.player().posY - ctx.player().prevPosY) * partialTicks, + ctx.player().prevPosZ + (ctx.player().posZ - ctx.player().prevPosZ) * partialTicks + ); for (int i = 0; i < elytra.simulationLine.size() - 1; i++) { - Vec3d src = elytra.simulationLine.get(i); - Vec3d dst = elytra.simulationLine.get(i + 1); - // Center line on viewer pos - buffer.pos(src.x, src.y, src.z).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.pos(dst.x, dst.y, dst.z).color(color[0], color[1], color[2], color[3]).endVertex(); + final Vec3d src = elytra.simulationLine.get(i).add(offset); + final Vec3d dst = elytra.simulationLine.get(i + 1).add(offset); + emitLine(src, dst); } IRenderer.endLines(settings.renderPathIgnoreDepth.value); } @@ -194,6 +197,10 @@ public final class PathRenderer implements IRenderer { IRenderer.endLines(settings.renderPathIgnoreDepth.value); } + private static void emitLine(Vec3d start, Vec3d end) { + emitLine(start.x, start.y, start.z, end.x, end.y, end.z); + } + private static void emitLine(double x1, double y1, double z1, double x2, double y2, double z2) { double vpX = renderManager.viewerPosX; double vpY = renderManager.viewerPosY; From c48de3286025e54fb813f6133f0993c13c3a560d Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 27 Jun 2023 16:31:08 -0500 Subject: [PATCH 251/405] `PitchResult` --- .../baritone/behavior/ElytraBehavior.java | 45 +++++++++++-------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 1720cf24e..048a00e12 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -684,6 +684,19 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } + private static final class PitchResult { + + public final float pitch; + public final double dot; + public final List steps; + + public PitchResult(float pitch, double dot, List steps) { + this.pitch = pitch; + this.dot = dot; + this.steps = steps; + } + } + private static final class Solution { public final SolverContext context; @@ -808,24 +821,24 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final int ticks = desperate ? 3 : context.boost.isBoosted() ? 5 : Baritone.settings().elytraSimulationTicks.value; final int ticksBoosted = context.boost.isBoosted() ? ticks : 0; - final Float pitch = this.solvePitch(context, goalDelta, ticks, ticksBoosted, desperate, ignoreLava); + final PitchResult pitch = this.solvePitch(context, goalDelta, ticks, ticksBoosted, desperate, ignoreLava); if (pitch != null) { - return new Pair<>(pitch, false); + return new Pair<>(pitch.pitch, false); } if (Baritone.settings().experimentalTakeoff.value && relaxation > 0) { // Simulate as if we were boosted for the entire duration - final Float usingFirework = this.solvePitch(context, goalDelta, ticks, ticks, desperate, ignoreLava); + final PitchResult usingFirework = this.solvePitch(context, goalDelta, ticks, ticks, desperate, ignoreLava); if (usingFirework != null) { - return new Pair<>(usingFirework, true); + return new Pair<>(usingFirework.pitch, true); } } return new Pair<>(null, false); } - private Float solvePitch(final SolverContext context, final Vec3d goalDelta, final int ticks, - final int ticksBoosted, final boolean desperate, final boolean ignoreLava) { + private PitchResult solvePitch(final SolverContext context, final Vec3d goalDelta, final int ticks, + final int ticksBoosted, final boolean desperate, final boolean ignoreLava) { // we are at a certain velocity, but we have a target velocity // what pitch would get us closest to our target velocity? // yaw is easy so we only care about pitch @@ -833,9 +846,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final Vec3d goalDirection = goalDelta.normalize(); final float goodPitch = RotationUtils.calcRotationFromVec3d(Vec3d.ZERO, goalDirection, ctx.playerRotations()).getPitch(); - Float bestPitch = null; - double bestDot = Double.NEGATIVE_INFINITY; - List bestLine = null; + PitchResult result = null; final float minPitch = desperate ? -90 : Math.max(goodPitch - Baritone.settings().elytraPitchRange.value, -89); final float maxPitch = desperate ? 90 : Math.min(goodPitch + Baritone.settings().elytraPitchRange.value, 89); @@ -852,18 +863,16 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H if (displacement == null) { continue; } - final Vec3d result = displacement.get(displacement.size() - 1); - double goodness = goalDirection.dotProduct(result.normalize()); - if (goodness > bestDot) { - bestDot = goodness; - bestPitch = pitch; - bestLine = displacement; + final Vec3d last = displacement.get(displacement.size() - 1); + double goodness = goalDirection.dotProduct(last.normalize()); + if (result == null || goodness > result.dot) { + result = new PitchResult(pitch, goodness, displacement); } } - if (bestLine != null) { - this.simulationLine = bestLine; + if (result != null) { + this.simulationLine = result.steps; } - return bestPitch; + return result; } private List simulate(final ITickableAimProcessor aimProcessor, final Vec3d goalDelta, final float pitch, From 03ee30bca90dd090acd0499754fbdc2728d8f0b2 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 28 Jun 2023 00:46:14 -0500 Subject: [PATCH 252/405] Call elytra `tick()` from the process --- .../java/baritone/api/behavior/IBehavior.java | 8 +++++- src/main/java/baritone/Baritone.java | 8 +++++- .../baritone/behavior/ElytraBehavior.java | 27 +++++++++++++++---- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/api/java/baritone/api/behavior/IBehavior.java b/src/api/java/baritone/api/behavior/IBehavior.java index 811563b93..aea44ed3e 100644 --- a/src/api/java/baritone/api/behavior/IBehavior.java +++ b/src/api/java/baritone/api/behavior/IBehavior.java @@ -27,4 +27,10 @@ import baritone.api.event.listener.IGameEventListener; * @see IGameEventListener * @since 9/23/2018 */ -public interface IBehavior extends AbstractGameEventListener {} +public interface IBehavior extends AbstractGameEventListener { + + /** + * Called after Baritone's initialization is complete + */ + default void onLoad() {} +} diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index dcbad33f5..313725c4e 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -40,6 +40,8 @@ import net.minecraft.client.Minecraft; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadPoolExecutor; @@ -63,6 +65,7 @@ public class Baritone implements IBaritone { private final GameEventHandler gameEventHandler; + private final List behaviors; private final PathingBehavior pathingBehavior; private final ElytraBehavior elytraBehavior; private final LookBehavior lookBehavior; @@ -89,6 +92,7 @@ public class Baritone implements IBaritone { Baritone(Minecraft mc) { this.mc = mc; + this.behaviors = new ArrayList<>(); this.gameEventHandler = new GameEventHandler(this); this.directory = mc.gameDir.toPath().resolve("baritone"); @@ -121,15 +125,17 @@ public class Baritone implements IBaritone { this.farmProcess = this.registerProcess(FarmProcess::new); this.inventoryPauserProcess = this.registerProcess(InventoryPauserProcess::new); this.registerProcess(BackfillProcess::new); - this.registerProcess(__ -> this.elytraBehavior.new ElytraProcess()); // pain } this.worldProvider = new WorldProvider(this); this.selectionManager = new SelectionManager(this); this.commandManager = new CommandManager(this); + + this.behaviors.forEach(IBehavior::onLoad); } public void registerBehavior(IBehavior behavior) { + this.behaviors.add(behavior); this.gameEventHandler.registerEventListener(behavior); } diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 048a00e12..759d4b0bc 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -71,6 +71,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // :sunglasses: private final NetherPathfinderContext context; private final PathManager pathManager; + private final ElytraProcess process; /** * Remaining cool-down ticks between firework usage @@ -93,6 +94,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private BlockPos destination; private Future solver; + private Solution pendingSolution; private boolean solveNextTick; public ElytraBehavior(Baritone baritone) { @@ -102,6 +104,12 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.blockedLines = new CopyOnWriteArrayList<>(); this.visiblePath = Collections.emptyList(); this.pathManager = this.new PathManager(); + this.process = new ElytraProcess(); + } + + @Override + public void onLoad() { + baritone.getPathingControlManager().registerProcess(this.process); } private final class PathManager { @@ -398,16 +406,16 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } @Override - public void onTick(TickEvent event) { + public void onTick(final TickEvent event) { if (event.getType() == TickEvent.Type.OUT) { return; } // Fetch the previous solution, regardless of if it's going to be used - Solution solution = null; + this.pendingSolution = null; if (this.solver != null) { try { - solution = this.solver.get(); + this.pendingSolution = this.solver.get(); } catch (Exception ignored) { // it doesn't matter if get() fails since the solution can just be recalculated synchronously } finally { @@ -431,7 +439,12 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.blockedLines.clear(); this.simulationLine = null; this.aimPos = null; + } + /** + * Called by {@link ElytraProcess#onTick(boolean, boolean)} when the process is in control + */ + private void tick() { final List path = this.pathManager.getPath(); if (path.isEmpty()) { return; @@ -461,8 +474,11 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.solveNextTick = true; // If there's no previously calculated solution to use, or the context used at the end of last tick doesn't match this tick - if (solution == null || !solution.context.equals(solverContext)) { + final Solution solution; + if (this.pendingSolution == null || !this.pendingSolution.context.equals(solverContext)) { solution = this.solveAngles(solverContext); + } else { + solution = this.pendingSolution; } if (solution == null) { @@ -1010,7 +1026,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } - public final class ElytraProcess implements IBaritoneProcess { + private final class ElytraProcess implements IBaritoneProcess { private State state; private Goal goal; @@ -1032,6 +1048,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.state = State.FLYING; this.goal = null; baritone.getInputOverrideHandler().clearAllKeys(); + ElytraBehavior.this.tick(); return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } From 70166f385db5e333fe2b9407ea62345225b388d9 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 28 Jun 2023 00:47:20 -0500 Subject: [PATCH 253/405] That should be in the other tick method --- .../java/baritone/behavior/ElytraBehavior.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 759d4b0bc..3cb5c2f12 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -439,12 +439,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.blockedLines.clear(); this.simulationLine = null; this.aimPos = null; - } - /** - * Called by {@link ElytraProcess#onTick(boolean, boolean)} when the process is in control - */ - private void tick() { final List path = this.pathManager.getPath(); if (path.isEmpty()) { return; @@ -458,11 +453,12 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H Math.max(playerNear - 30, 0), Math.min(playerNear + 100, path.size()) ); + } - if (!ctx.player().isElytraFlying()) { - return; - } - + /** + * Called by {@link ElytraProcess#onTick(boolean, boolean)} when the process is in control + */ + private void tick() { if (ctx.player().collidedHorizontally) { logDirect("hbonk"); } From 7861860187a34e65f6acffd3f4286dbd9d82080f Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 28 Jun 2023 00:48:28 -0500 Subject: [PATCH 254/405] Clarify --- src/main/java/baritone/behavior/ElytraBehavior.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 3cb5c2f12..a118d5fbc 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -456,7 +456,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } /** - * Called by {@link ElytraProcess#onTick(boolean, boolean)} when the process is in control + * Called by {@link ElytraProcess#onTick(boolean, boolean)} when the process is in control and the player is flying */ private void tick() { if (ctx.player().collidedHorizontally) { From 7a61ab813742cbef4b09a634681e385d16f03d5c Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 28 Jun 2023 00:58:51 -0500 Subject: [PATCH 255/405] We need event priorities. --- src/main/java/baritone/Baritone.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index 313725c4e..805fb0488 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -107,8 +107,8 @@ public class Baritone implements IBaritone { { this.lookBehavior = this.registerBehavior(LookBehavior::new); - this.pathingBehavior = this.registerBehavior(PathingBehavior::new); this.elytraBehavior = this.registerBehavior(ElytraBehavior::new); + this.pathingBehavior = this.registerBehavior(PathingBehavior::new); this.inventoryBehavior = this.registerBehavior(InventoryBehavior::new); this.inputOverrideHandler = this.registerBehavior(InputOverrideHandler::new); this.registerBehavior(WaypointBehavior::new); From bb39fea4151fa16c3c0d5b5d85c701aba251f8a2 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 28 Jun 2023 01:04:08 -0500 Subject: [PATCH 256/405] Considerations --- src/main/java/baritone/behavior/ElytraBehavior.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index a118d5fbc..82045c7bc 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -459,6 +459,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H * Called by {@link ElytraProcess#onTick(boolean, boolean)} when the process is in control and the player is flying */ private void tick() { + if (this.pathManager.getPath().isEmpty()) { + return; + } + if (ctx.player().collidedHorizontally) { logDirect("hbonk"); } @@ -506,6 +510,9 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // changed. Updating it now will avoid unnecessary recalculation on the main thread. this.pathManager.updatePlayerNear(); + // TODO: If we used a firework at the end of the last tick, then it's worth it to solve with the assumption + // that we'll be boosted next tick (if our ping to the server is less than 50ms) since a recalc won't + // be needed on the main thread. final SolverContext context = this.new SolverContext(true); this.solver = CompletableFuture.supplyAsync(() -> this.solveAngles(context)); this.solveNextTick = false; From 0bb6f1b094a0151f375ce06e0f78564eee1531d4 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 28 Jun 2023 01:05:22 -0500 Subject: [PATCH 257/405] Invalidate `pendingSolution` --- src/main/java/baritone/behavior/ElytraBehavior.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 82045c7bc..7e328bfd4 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -398,6 +398,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.solver.cancel(true); this.solver = null; } + this.pendingSolution = null; } @Override From d640ebb02d8df07e1c12a30c8adfe4af1179b6e3 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 28 Jun 2023 17:47:01 -0500 Subject: [PATCH 258/405] Reliability improvements --- .../baritone/behavior/ElytraBehavior.java | 212 +++++++++++++----- 1 file changed, 156 insertions(+), 56 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 7e328bfd4..b4b119921 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -37,6 +37,8 @@ import baritone.behavior.elytra.UnpackedSegment; import baritone.cache.FasterWorldScanner; import baritone.utils.BlockStateInterface; import baritone.utils.accessor.IEntityFireworkRocket; +import it.unimi.dsi.fastutil.floats.FloatArrayList; +import it.unimi.dsi.fastutil.floats.FloatIterator; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.item.EntityFireworkRocket; @@ -52,6 +54,7 @@ import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Future; +import java.util.function.Supplier; import java.util.function.UnaryOperator; public final class ElytraBehavior extends Behavior implements IElytraBehavior, Helper { @@ -530,57 +533,84 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H for (int relaxation = 0; relaxation < 3; relaxation++) { // try for a strict solution first, then relax more and more (if we're in a corner or near some blocks, it will have to relax its constraints a bit) int[] heights = context.boost.isBoosted() ? new int[]{20, 10, 5, 0} : new int[]{0}; // attempt to gain height, if we can, so as not to waste the boost - float[] interps = new float[] {1.0f, 0.75f, 0.5f, 0.25f}; int lookahead = relaxation == 0 ? 2 : 3; // ideally this would be expressed as a distance in blocks, rather than a number of voxel steps //int minStep = Math.max(0, playerNear - relaxation); int minStep = playerNear; + for (int i = Math.min(playerNear + 20, path.size() - 1); i >= minStep; i--) { + final List> candidates = new ArrayList<>(); for (int dy : heights) { - for (float interp : interps) { - Vec3d dest; - if (interp == 1 || i == minStep) { - dest = path.getVec(i); + if (i == minStep) { + // no interp + candidates.add(new Pair<>(path.getVec(i).add(0, dy, 0), dy)); + } else { + if (relaxation == 2) { + final Vec3d delta = path.getVec(i).subtract(path.getVec(i - 1)); + final double stepLength = 0.5; + final int steps = MathHelper.floor(delta.length() / stepLength); + final Vec3d step = delta.normalize().scale(stepLength); + + Vec3d stepped = path.getVec(i); + for (int interp = 0; interp < steps; interp++) { + candidates.add(new Pair<>(stepped.add(0, dy, 0), dy)); + stepped = stepped.subtract(step); + } } else { - dest = path.getVec(i).scale(interp).add(path.getVec(i - 1).scale(1.0d - interp)); + final float[] interps = relaxation == 0 + ? new float[]{1.0f, 0.75f, 0.5f, 0.25f} + : new float[]{1.0f, 0.875f, 0.75f, 0.625f, 0.5f, 0.375f, 0.25f, 0.125f}; + for (float interp : interps) { + Vec3d dest; + if (interp == 1) { + dest = path.getVec(i); + } else { + dest = path.getVec(i).scale(interp).add(path.getVec(i - 1).scale(1.0d - interp)); + } + candidates.add(new Pair<>(dest.add(0, dy, 0), dy)); + } } + } + } - dest = dest.add(0, dy, 0); - if (dy != 0) { - if (i + lookahead >= path.size()) { + for (final Pair candidate : candidates) { + final Vec3d dest = candidate.first(); + final Integer augment = candidate.second(); + + if (augment != 0) { + if (i + lookahead >= path.size()) { + continue; + } + if (start.distanceTo(dest) < 40) { + if (!this.clearView(dest, path.getVec(i + lookahead).add(0, augment, 0), false) + || !this.clearView(dest, path.getVec(i + lookahead), false)) { + // aka: don't go upwards if doing so would prevent us from being able to see the next position **OR** the modified next position continue; } - if (start.distanceTo(dest) < 40) { - if (!this.clearView(dest, path.getVec(i + lookahead).add(0, dy, 0), false) - || !this.clearView(dest, path.getVec(i + lookahead), false)) { - // aka: don't go upwards if doing so would prevent us from being able to see the next position **OR** the modified next position - continue; - } - } else { - // but if it's far away, allow gaining altitude if we could lose it again by the time we get there - if (!this.clearView(dest, path.getVec(i), false)) { - continue; - } - } - } - - final double minAvoidance = Baritone.settings().elytraMinimumAvoidance.value; - final Double growth = relaxation == 2 ? null - : relaxation == 0 ? 2 * minAvoidance : minAvoidance; - - if (this.isHitboxClear(start, dest, growth, isInLava)) { - // Yaw is trivial, just calculate the rotation required to face the destination - final float yaw = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()).getYaw(); - - final Pair pitch = this.solvePitch(context, dest.subtract(start), relaxation, isInLava); - if (pitch.first() == null) { - solution = new Solution(context, new Rotation(yaw, ctx.playerRotations().getPitch()), null, false, false); + } else { + // but if it's far away, allow gaining altitude if we could lose it again by the time we get there + if (!this.clearView(dest, path.getVec(i), false)) { continue; } - - // A solution was found with yaw AND pitch, so just immediately return it. - return new Solution(context, new Rotation(yaw, pitch.first()), dest, true, pitch.second()); } } + + final double minAvoidance = Baritone.settings().elytraMinimumAvoidance.value; + final Double growth = relaxation == 2 ? null + : relaxation == 0 ? 2 * minAvoidance : minAvoidance; + + if (this.isHitboxClear(start, dest, growth, isInLava)) { + // Yaw is trivial, just calculate the rotation required to face the destination + final float yaw = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()).getYaw(); + + final Pair pitch = this.solvePitch(context, dest, relaxation, isInLava); + if (pitch == null) { + solution = new Solution(context, new Rotation(yaw, ctx.playerRotations().getPitch()), null, false, false); + continue; + } + + // A solution was found with yaw AND pitch, so just immediately return it. + return new Solution(context, new Rotation(yaw, pitch.first()), dest, true, pitch.second()); + } } } } @@ -680,10 +710,16 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return this.firework != null; } + /** + * @return The guaranteed number of remaining ticks with boost + */ public int getGuaranteedBoostTicks() { return this.isBoosted() ? Math.max(0, this.minimumBoostTicks - this.firework.ticksExisted) : 0; } + /** + * @return The maximum number of remaining ticks with boost + */ public int getMaximumBoostTicks() { return this.isBoosted() ? Math.max(0, this.maximumBoostTicks - this.firework.ticksExisted) : 0; } @@ -835,43 +871,92 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } - private Pair solvePitch(final SolverContext context, final Vec3d goalDelta, - final int relaxation, final boolean ignoreLava) { - final boolean desperate = relaxation == 2; - final int ticks = desperate ? 3 : context.boost.isBoosted() ? 5 : Baritone.settings().elytraSimulationTicks.value; - final int ticksBoosted = context.boost.isBoosted() ? ticks : 0; + @FunctionalInterface + private interface IntBiFunction { + T apply(int left, int right); + } - final PitchResult pitch = this.solvePitch(context, goalDelta, ticks, ticksBoosted, desperate, ignoreLava); - if (pitch != null) { - return new Pair<>(pitch.pitch, false); + private static FloatArrayList pitchesToSolveFor(final float goodPitch, final boolean desperate) { + final float minPitch = desperate ? -90 : Math.max(goodPitch - Baritone.settings().elytraPitchRange.value, -89); + final float maxPitch = desperate ? 90 : Math.min(goodPitch + Baritone.settings().elytraPitchRange.value, 89); + + final FloatArrayList pitchValues = new FloatArrayList(MathHelper.ceil(maxPitch - minPitch) + 1); + for (float pitch = goodPitch; pitch <= maxPitch; pitch++) { + pitchValues.add(pitch); + } + for (float pitch = goodPitch - 1; pitch >= minPitch; pitch--) { + pitchValues.add(pitch); + } + + return pitchValues; + } + + private Pair solvePitch(final SolverContext context, final Vec3d goal, + final int relaxation, final boolean ignoreLava) { + + final boolean desperate = relaxation == 2; + final float goodPitch = RotationUtils.calcRotationFromVec3d(context.start, goal, ctx.playerRotations()).getPitch(); + final FloatArrayList pitches = pitchesToSolveFor(goodPitch, desperate); + + final IntBiFunction solve = (ticks, ticksBoosted) -> + this.solvePitch(context, goal, relaxation, pitches.iterator(), ticks, ticksBoosted, ignoreLava); + + final List> tests = new ArrayList<>(); + + if (context.boost.isBoosted()) { + final int guaranteed = context.boost.getGuaranteedBoostTicks(); + if (guaranteed == 0) { + // uncertain when boost will run out + final int lookahead = Math.max(4, 10 - context.boost.getMaximumBoostTicks()); + tests.add(() -> solve.apply(lookahead, 1)); + tests.add(() -> solve.apply(5, 5)); + } else if (guaranteed <= 5) { + // boost will run out within 5 ticks + tests.add(() -> solve.apply(guaranteed + 5, guaranteed)); + } else { + // there's plenty of guaranteed boost + tests.add(() -> solve.apply(guaranteed + 1, guaranteed)); + } + } + + // Standard test, assume (not) boosted for entire duration + final int ticks = desperate ? 3 : context.boost.isBoosted() ? Math.max(5, context.boost.getGuaranteedBoostTicks()) : Baritone.settings().elytraSimulationTicks.value; + tests.add(() -> solve.apply(ticks, context.boost.isBoosted() ? ticks : 0)); + + final Optional result = tests.stream() + .map(Supplier::get) + .filter(Objects::nonNull) + .findFirst(); + if (result.isPresent()) { + return new Pair<>(result.get().pitch, false); } if (Baritone.settings().experimentalTakeoff.value && relaxation > 0) { // Simulate as if we were boosted for the entire duration - final PitchResult usingFirework = this.solvePitch(context, goalDelta, ticks, ticks, desperate, ignoreLava); + final PitchResult usingFirework = solve.apply(ticks, ticks); if (usingFirework != null) { return new Pair<>(usingFirework.pitch, true); } } - return new Pair<>(null, false); + return null; } - private PitchResult solvePitch(final SolverContext context, final Vec3d goalDelta, final int ticks, - final int ticksBoosted, final boolean desperate, final boolean ignoreLava) { + private PitchResult solvePitch(final SolverContext context, final Vec3d goal, final int relaxation, + final FloatIterator pitches, final int ticks, final int ticksBoosted, + final boolean ignoreLava) { // we are at a certain velocity, but we have a target velocity // what pitch would get us closest to our target velocity? // yaw is easy so we only care about pitch + final Vec3d goalDelta = goal.subtract(context.start); final Vec3d goalDirection = goalDelta.normalize(); - final float goodPitch = RotationUtils.calcRotationFromVec3d(Vec3d.ZERO, goalDirection, ctx.playerRotations()).getPitch(); PitchResult result = null; - final float minPitch = desperate ? -90 : Math.max(goodPitch - Baritone.settings().elytraPitchRange.value, -89); - final float maxPitch = desperate ? 90 : Math.min(goodPitch + Baritone.settings().elytraPitchRange.value, 89); - - for (float pitch = minPitch; pitch <= maxPitch; pitch++) { + outer: + while (pitches.hasNext()) { + final float pitch = pitches.nextFloat(); final List displacement = this.simulate( context.aimProcessor.fork(), goalDelta, @@ -883,9 +968,24 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H if (displacement == null) { continue; } - final Vec3d last = displacement.get(displacement.size() - 1); - double goodness = goalDirection.dotProduct(last.normalize()); + final int lastIndex = displacement.size() - 1; + final Vec3d last = displacement.get(lastIndex); + final double goodness = goalDirection.dotProduct(last.normalize()); if (result == null || goodness > result.dot) { + if (relaxation == 0) { + // Ensure that the goal is visible along the entire simulated path + // Reverse order iteration since the last position is most likely to fail + for (int i = lastIndex; i >= 1; i--) { + if (!clearView(context.start.add(displacement.get(i)), goal, false)) { + continue outer; + } + } + } else if (relaxation == 1) { + // Ensure that the goal is visible from the final position + if (!clearView(context.start.add(last), goal, false)) { + continue; + } + } result = new PitchResult(pitch, goodness, displacement); } } From 5126ec9c36b0ea47cbef6d0d344a05b4565b9fbc Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 28 Jun 2023 17:49:33 -0500 Subject: [PATCH 259/405] interp double --- src/main/java/baritone/behavior/ElytraBehavior.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index b4b119921..9bdb255ee 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -556,10 +556,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H stepped = stepped.subtract(step); } } else { - final float[] interps = relaxation == 0 - ? new float[]{1.0f, 0.75f, 0.5f, 0.25f} - : new float[]{1.0f, 0.875f, 0.75f, 0.625f, 0.5f, 0.375f, 0.25f, 0.125f}; - for (float interp : interps) { + final double[] interps = relaxation == 0 + ? new double[]{1.0, 0.75, 0.5, 0.25} + : new double[]{1.0, 0.875, 0.75, 0.625, 0.5, 0.375, 0.25, 0.125}; + for (double interp : interps) { Vec3d dest; if (interp == 1) { dest = path.getVec(i); From 4b689bd9462d29e34f7b7af59e203fbfdaeb97ee Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 28 Jun 2023 17:55:47 -0500 Subject: [PATCH 260/405] Fix `Supplier` meme --- .../baritone/behavior/ElytraBehavior.java | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 9bdb255ee..c2df278a4 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -871,11 +871,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } - @FunctionalInterface - private interface IntBiFunction { - T apply(int left, int right); - } - private static FloatArrayList pitchesToSolveFor(final float goodPitch, final boolean desperate) { final float minPitch = desperate ? -90 : Math.max(goodPitch - Baritone.settings().elytraPitchRange.value, -89); final float maxPitch = desperate ? 90 : Math.min(goodPitch + Baritone.settings().elytraPitchRange.value, 89); @@ -891,6 +886,21 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return pitchValues; } + @FunctionalInterface + private interface IntBiFunction { + T apply(int left, int right); + } + + private static final class IntPair { + public final int first; + public final int second; + + public IntPair(int first, int second) { + this.first = first; + this.second = second; + } + } + private Pair solvePitch(final SolverContext context, final Vec3d goal, final int relaxation, final boolean ignoreLava) { @@ -901,30 +911,30 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final IntBiFunction solve = (ticks, ticksBoosted) -> this.solvePitch(context, goal, relaxation, pitches.iterator(), ticks, ticksBoosted, ignoreLava); - final List> tests = new ArrayList<>(); + final List tests = new ArrayList<>(); if (context.boost.isBoosted()) { final int guaranteed = context.boost.getGuaranteedBoostTicks(); if (guaranteed == 0) { // uncertain when boost will run out final int lookahead = Math.max(4, 10 - context.boost.getMaximumBoostTicks()); - tests.add(() -> solve.apply(lookahead, 1)); - tests.add(() -> solve.apply(5, 5)); + tests.add(new IntPair(lookahead, 1)); + tests.add(new IntPair(5, 5)); } else if (guaranteed <= 5) { // boost will run out within 5 ticks - tests.add(() -> solve.apply(guaranteed + 5, guaranteed)); + tests.add(new IntPair(guaranteed + 5, guaranteed)); } else { // there's plenty of guaranteed boost - tests.add(() -> solve.apply(guaranteed + 1, guaranteed)); + tests.add(new IntPair(guaranteed + 1, guaranteed)); } } // Standard test, assume (not) boosted for entire duration final int ticks = desperate ? 3 : context.boost.isBoosted() ? Math.max(5, context.boost.getGuaranteedBoostTicks()) : Baritone.settings().elytraSimulationTicks.value; - tests.add(() -> solve.apply(ticks, context.boost.isBoosted() ? ticks : 0)); + tests.add(new IntPair(ticks, context.boost.isBoosted() ? ticks : 0)); final Optional result = tests.stream() - .map(Supplier::get) + .map(i -> solve.apply(i.first, i.second)) .filter(Objects::nonNull) .findFirst(); if (result.isPresent()) { From 48462da47373eab1a04cdd5f5927ac6698b263a1 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 28 Jun 2023 21:47:37 -0500 Subject: [PATCH 261/405] Disable interp on relaxation 0 --- .../baritone/behavior/ElytraBehavior.java | 46 +++++++++---------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index c2df278a4..5d1f51e00 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -540,34 +540,32 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H for (int i = Math.min(playerNear + 20, path.size() - 1); i >= minStep; i--) { final List> candidates = new ArrayList<>(); for (int dy : heights) { - if (i == minStep) { + if (relaxation == 0 || i == minStep) { // no interp candidates.add(new Pair<>(path.getVec(i).add(0, dy, 0), dy)); + } else if (relaxation == 1) { + // Create 4 points along the segment + final double[] interps = new double[]{1.0, 0.75, 0.5, 0.25}; + for (double interp : interps) { + Vec3d dest; + if (interp == 1) { + dest = path.getVec(i); + } else { + dest = path.getVec(i).scale(interp).add(path.getVec(i - 1).scale(1.0d - interp)); + } + candidates.add(new Pair<>(dest.add(0, dy, 0), dy)); + } } else { - if (relaxation == 2) { - final Vec3d delta = path.getVec(i).subtract(path.getVec(i - 1)); - final double stepLength = 0.5; - final int steps = MathHelper.floor(delta.length() / stepLength); - final Vec3d step = delta.normalize().scale(stepLength); + // Create a point along the segment every 0.5 blocks + final Vec3d delta = path.getVec(i).subtract(path.getVec(i - 1)); + final double stepLength = 0.5; + final int steps = MathHelper.floor(delta.length() / stepLength); + final Vec3d step = delta.normalize().scale(stepLength); - Vec3d stepped = path.getVec(i); - for (int interp = 0; interp < steps; interp++) { - candidates.add(new Pair<>(stepped.add(0, dy, 0), dy)); - stepped = stepped.subtract(step); - } - } else { - final double[] interps = relaxation == 0 - ? new double[]{1.0, 0.75, 0.5, 0.25} - : new double[]{1.0, 0.875, 0.75, 0.625, 0.5, 0.375, 0.25, 0.125}; - for (double interp : interps) { - Vec3d dest; - if (interp == 1) { - dest = path.getVec(i); - } else { - dest = path.getVec(i).scale(interp).add(path.getVec(i - 1).scale(1.0d - interp)); - } - candidates.add(new Pair<>(dest.add(0, dy, 0), dy)); - } + Vec3d stepped = path.getVec(i).add(0, dy, 0); + for (int interp = 0; interp < steps; interp++) { + candidates.add(new Pair<>(stepped, dy)); + stepped = stepped.subtract(step); } } } From fbb66a0586ee70d7d59a6eebf234d23e59252835 Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 29 Jun 2023 14:14:49 -0500 Subject: [PATCH 262/405] Tweaks --- src/api/java/baritone/api/Settings.java | 3 - .../baritone/behavior/ElytraBehavior.java | 78 ++++++++++--------- 2 files changed, 43 insertions(+), 38 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 47643245d..679a29043 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -61,9 +61,6 @@ public final class Settings { public final Setting elytraAutoJump = new Setting<>(false); public final Setting smoothLook = new Setting<>(false); - // Experimental Elytra Settings - public final Setting experimentalTakeoff = new Setting<>(false); - /** * Allow Baritone to break blocks */ diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 5d1f51e00..1479a9efe 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -54,7 +54,6 @@ import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Future; -import java.util.function.Supplier; import java.util.function.UnaryOperator; public final class ElytraBehavior extends Behavior implements IElytraBehavior, Helper { @@ -540,19 +539,17 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H for (int i = Math.min(playerNear + 20, path.size() - 1); i >= minStep; i--) { final List> candidates = new ArrayList<>(); for (int dy : heights) { - if (relaxation == 0 || i == minStep) { + if (i == minStep) { // no interp candidates.add(new Pair<>(path.getVec(i).add(0, dy, 0), dy)); - } else if (relaxation == 1) { - // Create 4 points along the segment - final double[] interps = new double[]{1.0, 0.75, 0.5, 0.25}; + } else if (relaxation < 2) { + final double[] interps = relaxation == 0 + ? new double[]{1.0, 0.75, 0.5, 0.25} + : new double[]{1.0, 0.875, 0.75, 0.625, 0.5, 0.375, 0.25, 0.125}; for (double interp : interps) { - Vec3d dest; - if (interp == 1) { - dest = path.getVec(i); - } else { - dest = path.getVec(i).scale(interp).add(path.getVec(i - 1).scale(1.0d - interp)); - } + final Vec3d dest = interp == 1.0 + ? path.getVec(i) + : path.getVec(i).scale(interp).add(path.getVec(i - 1).scale(1.0 - interp)); candidates.add(new Pair<>(dest.add(0, dy, 0), dy)); } } else { @@ -641,7 +638,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H logDirect("no fireworks"); return; } - logDirect("attempting to use firework" + (forceUseFirework ? " takeoff" : "")); + logDirect("attempting to use firework" + (forceUseFirework ? " (forced)" : "")); ctx.playerController().processRightClick(ctx.player(), ctx.world(), EnumHand.MAIN_HAND); this.minimumBoostTicks = 10 * (1 + getFireworkBoost(ctx.player().getHeldItemMainhand()).orElse(0)); this.remainingFireworkTicks = 10; @@ -885,17 +882,19 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } @FunctionalInterface - private interface IntBiFunction { - T apply(int left, int right); + private interface IntTriFunction { + T apply(int first, int second, int third); } - private static final class IntPair { + private static final class IntTriple { public final int first; public final int second; + public final int third; - public IntPair(int first, int second) { + public IntTriple(int first, int second, int third) { this.first = first; this.second = second; + this.third = third; } } @@ -906,44 +905,52 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final float goodPitch = RotationUtils.calcRotationFromVec3d(context.start, goal, ctx.playerRotations()).getPitch(); final FloatArrayList pitches = pitchesToSolveFor(goodPitch, desperate); - final IntBiFunction solve = (ticks, ticksBoosted) -> - this.solvePitch(context, goal, relaxation, pitches.iterator(), ticks, ticksBoosted, ignoreLava); + final IntTriFunction solve = (ticks, ticksBoosted, ticksBoostDelay) -> + this.solvePitch(context, goal, relaxation, pitches.iterator(), ticks, ticksBoosted, ticksBoostDelay, ignoreLava); - final List tests = new ArrayList<>(); + final List tests = new ArrayList<>(); if (context.boost.isBoosted()) { final int guaranteed = context.boost.getGuaranteedBoostTicks(); if (guaranteed == 0) { // uncertain when boost will run out final int lookahead = Math.max(4, 10 - context.boost.getMaximumBoostTicks()); - tests.add(new IntPair(lookahead, 1)); - tests.add(new IntPair(5, 5)); + tests.add(new IntTriple(lookahead, 1, 0)); + tests.add(new IntTriple(5, 5, 0)); } else if (guaranteed <= 5) { // boost will run out within 5 ticks - tests.add(new IntPair(guaranteed + 5, guaranteed)); + tests.add(new IntTriple(guaranteed + 5, guaranteed, 0)); } else { // there's plenty of guaranteed boost - tests.add(new IntPair(guaranteed + 1, guaranteed)); + tests.add(new IntTriple(guaranteed + 1, guaranteed, 0)); } } // Standard test, assume (not) boosted for entire duration final int ticks = desperate ? 3 : context.boost.isBoosted() ? Math.max(5, context.boost.getGuaranteedBoostTicks()) : Baritone.settings().elytraSimulationTicks.value; - tests.add(new IntPair(ticks, context.boost.isBoosted() ? ticks : 0)); + tests.add(new IntTriple(ticks, context.boost.isBoosted() ? ticks : 0, 0)); final Optional result = tests.stream() - .map(i -> solve.apply(i.first, i.second)) + .map(i -> solve.apply(i.first, i.second, i.third)) .filter(Objects::nonNull) .findFirst(); if (result.isPresent()) { return new Pair<>(result.get().pitch, false); } - if (Baritone.settings().experimentalTakeoff.value && relaxation > 0) { - // Simulate as if we were boosted for the entire duration - final PitchResult usingFirework = solve.apply(ticks, ticks); - if (usingFirework != null) { - return new Pair<>(usingFirework.pitch, true); + // If we used a firework would we be able to get out of the current situation??? perhaps + if (relaxation > 0) { + final List testsBoost = new ArrayList<>(); + testsBoost.add(new IntTriple(ticks, 10, 3)); + testsBoost.add(new IntTriple(ticks, 10, 2)); + testsBoost.add(new IntTriple(ticks, 10, 1)); + + final Optional resultBoost = testsBoost.stream() + .map(i -> solve.apply(i.first, i.second, i.third)) + .filter(Objects::nonNull) + .findFirst(); + if (resultBoost.isPresent()) { + return new Pair<>(resultBoost.get().pitch, true); } } @@ -952,7 +959,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private PitchResult solvePitch(final SolverContext context, final Vec3d goal, final int relaxation, final FloatIterator pitches, final int ticks, final int ticksBoosted, - final boolean ignoreLava) { + final int ticksBoostDelay, final boolean ignoreLava) { // we are at a certain velocity, but we have a target velocity // what pitch would get us closest to our target velocity? // yaw is easy so we only care about pitch @@ -971,6 +978,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H pitch, ticks, ticksBoosted, + ticksBoostDelay, ignoreLava ); if (displacement == null) { @@ -980,7 +988,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final Vec3d last = displacement.get(lastIndex); final double goodness = goalDirection.dotProduct(last.normalize()); if (result == null || goodness > result.dot) { - if (relaxation == 0) { + if (relaxation < 2) { // Ensure that the goal is visible along the entire simulated path // Reverse order iteration since the last position is most likely to fail for (int i = lastIndex; i >= 1; i--) { @@ -988,7 +996,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H continue outer; } } - } else if (relaxation == 1) { + } else { // Ensure that the goal is visible from the final position if (!clearView(context.start.add(last), goal, false)) { continue; @@ -1004,7 +1012,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } private List simulate(final ITickableAimProcessor aimProcessor, final Vec3d goalDelta, final float pitch, - final int ticks, int ticksBoosted, final boolean ignoreLava) { + final int ticks, int ticksBoosted, final int ticksBoostDelay, final boolean ignoreLava) { Vec3d delta = goalDelta; Vec3d motion = ctx.playerMotion(); AxisAlignedBB hitbox = ctx.player().getEntityBoundingBox(); @@ -1042,7 +1050,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H hitbox = hitbox.offset(motion); displacement.add(displacement.get(displacement.size() - 1).add(motion)); - if (ticksBoosted-- > 0) { + if (i >= ticksBoostDelay && ticksBoosted-- > 0) { // See EntityFireworkRocket motion = motion.add( lookDirection.x * 0.1 + (lookDirection.x * 1.5 - motion.x) * 0.5, From 12898df2f1274b34bdf0954c4d2ec73b27e19f8f Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 29 Jun 2023 14:46:04 -0500 Subject: [PATCH 263/405] Reduce main thread recalculations after using a firework --- .../baritone/behavior/ElytraBehavior.java | 42 ++++++++++++++----- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 1479a9efe..26bb68445 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -97,6 +97,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private Future solver; private Solution pendingSolution; + private boolean deployedFireworkLastTick; + private final int[] nextTickBoostCounter; private boolean solveNextTick; public ElytraBehavior(Baritone baritone) { @@ -107,6 +109,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.visiblePath = Collections.emptyList(); this.pathManager = this.new PathManager(); this.process = new ElytraProcess(); + this.nextTickBoostCounter = new int[2]; } @Override @@ -401,6 +404,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.solver = null; } this.pendingSolution = null; + this.nextTickBoostCounter[0] = 0; + this.nextTickBoostCounter[1] = 0; } @Override @@ -484,6 +489,11 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H solution = this.pendingSolution; } + if (this.deployedFireworkLastTick) { + this.nextTickBoostCounter[solverContext.boost.isBoosted() ? 1 : 0]++; + this.deployedFireworkLastTick = false; + } + if (solution == null) { logDirect("no solution"); return; @@ -642,6 +652,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H ctx.playerController().processRightClick(ctx.player(), ctx.world(), EnumHand.MAIN_HAND); this.minimumBoostTicks = 10 * (1 + getFireworkBoost(ctx.player().getHeldItemMainhand()).orElse(0)); this.remainingFireworkTicks = 10; + this.deployedFireworkLastTick = true; } } @@ -657,10 +668,15 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.path = ElytraBehavior.this.pathManager.getPath(); this.playerNear = ElytraBehavior.this.pathManager.getNear(); this.start = ElytraBehavior.this.ctx.playerFeetAsVec(); - this.boost = new FireworkBoost( - ElytraBehavior.this.getAttachedFirework().orElse(null), - ElytraBehavior.this.minimumBoostTicks - ); + + final Integer fireworkTicksExisted; + if (async && ElytraBehavior.this.deployedFireworkLastTick) { + final int[] counter = ElytraBehavior.this.nextTickBoostCounter; + fireworkTicksExisted = counter[1] > counter[0] ? 0 : null; + } else { + fireworkTicksExisted = ElytraBehavior.this.getAttachedFirework().map(e -> e.ticksExisted).orElse(null); + } + this.boost = new FireworkBoost(fireworkTicksExisted, ElytraBehavior.this.minimumBoostTicks); ITickableAimProcessor aim = ElytraBehavior.this.baritone.getLookBehavior().getAimProcessor().fork(); if (async) { @@ -689,12 +705,12 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private static final class FireworkBoost { - private final EntityFireworkRocket firework; + private final Integer fireworkTicksExisted; private final int minimumBoostTicks; private final int maximumBoostTicks; - public FireworkBoost(final EntityFireworkRocket firework, final int minimumBoostTicks) { - this.firework = firework; + public FireworkBoost(final Integer fireworkTicksExisted, final int minimumBoostTicks) { + this.fireworkTicksExisted = fireworkTicksExisted; // this.lifetime = 10 * i + this.rand.nextInt(6) + this.rand.nextInt(7); this.minimumBoostTicks = minimumBoostTicks; @@ -702,21 +718,21 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } public boolean isBoosted() { - return this.firework != null; + return this.fireworkTicksExisted != null; } /** * @return The guaranteed number of remaining ticks with boost */ public int getGuaranteedBoostTicks() { - return this.isBoosted() ? Math.max(0, this.minimumBoostTicks - this.firework.ticksExisted) : 0; + return this.isBoosted() ? Math.max(0, this.minimumBoostTicks - this.fireworkTicksExisted) : 0; } /** * @return The maximum number of remaining ticks with boost */ public int getMaximumBoostTicks() { - return this.isBoosted() ? Math.max(0, this.maximumBoostTicks - this.firework.ticksExisted) : 0; + return this.isBoosted() ? Math.max(0, this.maximumBoostTicks - this.fireworkTicksExisted) : 0; } @Override @@ -729,7 +745,11 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } FireworkBoost other = (FireworkBoost) o; - return Objects.equals(this.firework, other.firework) + if (!this.isBoosted() && !other.isBoosted()) { + return true; + } + + return Objects.equals(this.fireworkTicksExisted, other.fireworkTicksExisted) && this.minimumBoostTicks == other.minimumBoostTicks && this.maximumBoostTicks == other.maximumBoostTicks; } From 222f53b105d007b74b4bf8a46b372c22cea860f4 Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 29 Jun 2023 14:46:42 -0500 Subject: [PATCH 264/405] Use `Arrays.fill` --- src/main/java/baritone/behavior/ElytraBehavior.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 26bb68445..da54fbb4f 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -404,8 +404,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.solver = null; } this.pendingSolution = null; - this.nextTickBoostCounter[0] = 0; - this.nextTickBoostCounter[1] = 0; + Arrays.fill(this.nextTickBoostCounter, 0); } @Override From 494ebfa10dd8fb7a0793a8cdd936198916334671 Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 29 Jun 2023 14:53:12 -0500 Subject: [PATCH 265/405] More accurate `isActive` return value --- src/main/java/baritone/behavior/ElytraBehavior.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index da54fbb4f..d7082074e 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -409,7 +409,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H @Override public boolean isActive() { - return !this.pathManager.getPath().isEmpty(); + return baritone.getPathingControlManager().mostRecentInControl() + .filter(process -> this.process == process).isPresent(); } @Override From f30cb916bd38541ab9c267793e8a05e90cab5a5e Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 29 Jun 2023 14:53:55 -0500 Subject: [PATCH 266/405] Remove addressed TODO --- src/main/java/baritone/behavior/ElytraBehavior.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index d7082074e..ab403aa80 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -523,9 +523,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // changed. Updating it now will avoid unnecessary recalculation on the main thread. this.pathManager.updatePlayerNear(); - // TODO: If we used a firework at the end of the last tick, then it's worth it to solve with the assumption - // that we'll be boosted next tick (if our ping to the server is less than 50ms) since a recalc won't - // be needed on the main thread. final SolverContext context = this.new SolverContext(true); this.solver = CompletableFuture.supplyAsync(() -> this.solveAngles(context)); this.solveNextTick = false; From 974b86aac1c9db64eb573ceb78ec4be27dc927ec Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 29 Jun 2023 18:50:29 -0500 Subject: [PATCH 267/405] Bump `nether-pathfinder` to 0.20 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 41a495f4f..58929d98b 100755 --- a/build.gradle +++ b/build.gradle @@ -175,9 +175,9 @@ dependencies { transitive = false } launchAnnotationProcessor 'org.spongepowered:mixin:0.8.4-SNAPSHOT:processor' - launchImplementation('dev.babbaj:nether-pathfinder:0.18') + launchImplementation('dev.babbaj:nether-pathfinder:0.20') testImplementation 'junit:junit:4.12' - implementation 'dev.babbaj:nether-pathfinder:0.18' + implementation 'dev.babbaj:nether-pathfinder:0.20' } mixin { From 5a48f4119e602fea947861ba5b7dc2ed7faceb49 Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 29 Jun 2023 19:15:06 -0500 Subject: [PATCH 268/405] Reduce number of raytraces when validating simulation --- .../baritone/behavior/ElytraBehavior.java | 74 +++++++++---------- 1 file changed, 36 insertions(+), 38 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index ab403aa80..3318e105a 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -546,27 +546,23 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H for (int i = Math.min(playerNear + 20, path.size() - 1); i >= minStep; i--) { final List> candidates = new ArrayList<>(); for (int dy : heights) { - if (i == minStep) { + if (relaxation == 0 || i == minStep) { // no interp - candidates.add(new Pair<>(path.getVec(i).add(0, dy, 0), dy)); - } else if (relaxation < 2) { - final double[] interps = relaxation == 0 - ? new double[]{1.0, 0.75, 0.5, 0.25} - : new double[]{1.0, 0.875, 0.75, 0.625, 0.5, 0.375, 0.25, 0.125}; + candidates.add(new Pair<>(path.getVec(i), dy)); + } else if (relaxation == 1) { + final double[] interps = new double[]{1.0, 0.75, 0.5, 0.25}; for (double interp : interps) { final Vec3d dest = interp == 1.0 ? path.getVec(i) : path.getVec(i).scale(interp).add(path.getVec(i - 1).scale(1.0 - interp)); - candidates.add(new Pair<>(dest.add(0, dy, 0), dy)); + candidates.add(new Pair<>(dest, dy)); } } else { - // Create a point along the segment every 0.5 blocks + // Create a point along the segment every block final Vec3d delta = path.getVec(i).subtract(path.getVec(i - 1)); - final double stepLength = 0.5; - final int steps = MathHelper.floor(delta.length() / stepLength); - final Vec3d step = delta.normalize().scale(stepLength); - - Vec3d stepped = path.getVec(i).add(0, dy, 0); + final int steps = MathHelper.floor(delta.length()); + final Vec3d step = delta.normalize(); + Vec3d stepped = path.getVec(i); for (int interp = 0; interp < steps; interp++) { candidates.add(new Pair<>(stepped, dy)); stepped = stepped.subtract(step); @@ -575,8 +571,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } for (final Pair candidate : candidates) { - final Vec3d dest = candidate.first(); final Integer augment = candidate.second(); + final Vec3d dest = candidate.first().add(0, augment, 0); if (augment != 0) { if (i + lookahead >= path.size()) { @@ -933,7 +929,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // uncertain when boost will run out final int lookahead = Math.max(4, 10 - context.boost.getMaximumBoostTicks()); tests.add(new IntTriple(lookahead, 1, 0)); - tests.add(new IntTriple(5, 5, 0)); } else if (guaranteed <= 5) { // boost will run out within 5 ticks tests.add(new IntTriple(guaranteed + 5, guaranteed, 0)); @@ -956,7 +951,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } // If we used a firework would we be able to get out of the current situation??? perhaps - if (relaxation > 0) { + if (desperate) { final List testsBoost = new ArrayList<>(); testsBoost.add(new IntTriple(ticks, 10, 3)); testsBoost.add(new IntTriple(ticks, 10, 2)); @@ -984,9 +979,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final Vec3d goalDelta = goal.subtract(context.start); final Vec3d goalDirection = goalDelta.normalize(); - PitchResult result = null; + final Deque bestResults = new ArrayDeque<>(); - outer: while (pitches.hasNext()) { final float pitch = pitches.nextFloat(); final List displacement = this.simulate( @@ -1001,31 +995,35 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H if (displacement == null) { continue; } - final int lastIndex = displacement.size() - 1; - final Vec3d last = displacement.get(lastIndex); + final Vec3d last = displacement.get(displacement.size() - 1); final double goodness = goalDirection.dotProduct(last.normalize()); - if (result == null || goodness > result.dot) { - if (relaxation < 2) { - // Ensure that the goal is visible along the entire simulated path - // Reverse order iteration since the last position is most likely to fail - for (int i = lastIndex; i >= 1; i--) { - if (!clearView(context.start.add(displacement.get(i)), goal, false)) { - continue outer; - } - } - } else { - // Ensure that the goal is visible from the final position - if (!clearView(context.start.add(last), goal, false)) { - continue; - } - } - result = new PitchResult(pitch, goodness, displacement); + final PitchResult bestSoFar = bestResults.peek(); + if (bestSoFar == null || goodness > bestSoFar.dot) { + bestResults.push(new PitchResult(pitch, goodness, displacement)); } } - if (result != null) { + + outer: + for (final PitchResult result : bestResults) { + if (relaxation < 2) { + // Ensure that the goal is visible along the entire simulated path + // Reverse order iteration since the last position is most likely to fail + for (int i = result.steps.size() - 1; i >= 1; i--) { + if (!clearView(context.start.add(result.steps.get(i)), goal, false)) { + continue outer; + } + } + } else { + // Ensure that the goal is visible from the final position + if (!clearView(context.start.add(result.steps.get(result.steps.size() - 1)), goal, false)) { + continue; + } + } + this.simulationLine = result.steps; + return result; } - return result; + return null; } private List simulate(final ITickableAimProcessor aimProcessor, final Vec3d goalDelta, final float pitch, From 3eb7610f8917eb5f30d25593341ea98435c41e79 Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 29 Jun 2023 20:45:59 -0500 Subject: [PATCH 269/405] Block lookup optimization --- .../baritone/behavior/ElytraBehavior.java | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 3318e105a..192aa90b1 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -870,13 +870,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H clear = ctx.world().rayTraceBlocks(start, dest, false, false, false) == null; } - if (clear) { - this.clearLines.add(new Pair<>(start, dest)); - return true; - } else { - this.blockedLines.add(new Pair<>(start, dest)); - return false; + if (Baritone.settings().renderRaytraces.value) { + (clear ? this.clearLines : this.blockedLines).add(new Pair<>(start, dest)); } + return clear; } private static FloatArrayList pitchesToSolveFor(final float goodPitch, final boolean desperate) { @@ -1035,7 +1032,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H displacement.add(Vec3d.ZERO); for (int i = 0; i < ticks; i++) { - if (MC_1_12_Collision_Fix.bonk(ctx, hitbox)) { + if (MC_1_12_Collision_Fix.bonk(ctx, this.bsi, hitbox)) { return null; } if (delta.lengthSquared() < 1) { @@ -1132,32 +1129,35 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H */ private static final class MC_1_12_Collision_Fix { - public static boolean bonk(final IPlayerContext ctx, final AxisAlignedBB aabb) { + public static boolean bonk(final IPlayerContext ctx, final BlockStateInterface bsi, final AxisAlignedBB aabb) { final Vec3d center = aabb.getCenter(); final double width = (double) ctx.player().width * 0.35D; final double x = center.x; final double y = aabb.minY + 0.5D; final double z = center.z; - return pushOutOfBlocks(ctx, x - width, y, z + width) - || pushOutOfBlocks(ctx, x - width, y, z - width) - || pushOutOfBlocks(ctx, x + width, y, z - width) - || pushOutOfBlocks(ctx, x + width, y, z + width); + return pushOutOfBlocks(bsi, x - width, y, z + width) + || pushOutOfBlocks(bsi, x - width, y, z - width) + || pushOutOfBlocks(bsi, x + width, y, z - width) + || pushOutOfBlocks(bsi, x + width, y, z + width); } - private static boolean pushOutOfBlocks(final IPlayerContext ctx, final double x, final double y, final double z) { - final BlockPos pos = new BlockPos(x, y, z); - if (isOpenBlockSpace(ctx, pos)) { + private static boolean pushOutOfBlocks(final BlockStateInterface bsi, + final double xIn, final double yIn, final double zIn) { + final int x = MathHelper.floor(xIn); + final int y = MathHelper.floor(yIn); + final int z = MathHelper.floor(zIn); + if (isOpenBlockSpace(bsi, x, y, z)) { return false; } - return isOpenBlockSpace(ctx, pos.west()) - || isOpenBlockSpace(ctx, pos.east()) - || isOpenBlockSpace(ctx, pos.north()) - || isOpenBlockSpace(ctx, pos.south()); + return isOpenBlockSpace(bsi, x - 1, y, z) + || isOpenBlockSpace(bsi, x + 1, y, z) + || isOpenBlockSpace(bsi, x, y, z - 1) + || isOpenBlockSpace(bsi, x, y, z + 1); } - private static boolean isOpenBlockSpace(IPlayerContext ctx, BlockPos pos) { - return !ctx.world().getBlockState(pos).isNormalCube() && !ctx.world().getBlockState(pos.up()).isNormalCube(); + private static boolean isOpenBlockSpace(BlockStateInterface bsi, final int x, final int y, final int z) { + return !bsi.get0(x, y, z).isNormalCube() && !bsi.get0(x, y + 1, z).isNormalCube(); } } From b8ede0a652d11aa578b7fea44679f03cc447ea4e Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 29 Jun 2023 22:54:55 -0500 Subject: [PATCH 270/405] Remove unnecessary `IPlayerContext` argument --- src/main/java/baritone/behavior/ElytraBehavior.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 192aa90b1..12cb77a7a 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -1032,7 +1032,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H displacement.add(Vec3d.ZERO); for (int i = 0; i < ticks; i++) { - if (MC_1_12_Collision_Fix.bonk(ctx, this.bsi, hitbox)) { + if (MC_1_12_Collision_Fix.bonk(this.bsi, hitbox)) { return null; } if (delta.lengthSquared() < 1) { @@ -1129,9 +1129,9 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H */ private static final class MC_1_12_Collision_Fix { - public static boolean bonk(final IPlayerContext ctx, final BlockStateInterface bsi, final AxisAlignedBB aabb) { + public static boolean bonk(final BlockStateInterface bsi, final AxisAlignedBB aabb) { final Vec3d center = aabb.getCenter(); - final double width = (double) ctx.player().width * 0.35D; + final double width = (aabb.maxX - aabb.minX) * 0.35D; final double x = center.x; final double y = aabb.minY + 0.5D; final double z = center.z; From b4578931d3262af35a8dbb3cfb519fe197ef3591 Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 29 Jun 2023 22:59:15 -0500 Subject: [PATCH 271/405] Reduce passing around of `ignoreLava` --- .../baritone/behavior/ElytraBehavior.java | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 12cb77a7a..954755fa4 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -533,8 +533,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final NetherPath path = context.path; final int playerNear = context.playerNear; final Vec3d start = context.start; - - final boolean isInLava = ctx.player().isInLava(); Solution solution = null; for (int relaxation = 0; relaxation < 3; relaxation++) { // try for a strict solution first, then relax more and more (if we're in a corner or near some blocks, it will have to relax its constraints a bit) @@ -596,11 +594,11 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final Double growth = relaxation == 2 ? null : relaxation == 0 ? 2 * minAvoidance : minAvoidance; - if (this.isHitboxClear(start, dest, growth, isInLava)) { + if (this.isHitboxClear(context, dest, growth)) { // Yaw is trivial, just calculate the rotation required to face the destination final float yaw = RotationUtils.calcRotationFromVec3d(start, dest, ctx.playerRotations()).getYaw(); - final Pair pitch = this.solvePitch(context, dest, relaxation, isInLava); + final Pair pitch = this.solvePitch(context, dest, relaxation); if (pitch == null) { solution = new Solution(context, new Rotation(yaw, ctx.playerRotations().getPitch()), null, false, false); continue; @@ -654,6 +652,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H public final NetherPath path; public final int playerNear; public final Vec3d start; + public final boolean ignoreLava; public final FireworkBoost boost; public final IAimProcessor aimProcessor; @@ -661,6 +660,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.path = ElytraBehavior.this.pathManager.getPath(); this.playerNear = ElytraBehavior.this.pathManager.getNear(); this.start = ElytraBehavior.this.ctx.playerFeetAsVec(); + this.ignoreLava = ElytraBehavior.this.ctx.player().isInLava(); final Integer fireworkTicksExisted; if (async && ElytraBehavior.this.deployedFireworkLastTick) { @@ -692,6 +692,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return this.path == other.path // Contents aren't modified, just compare by reference && this.playerNear == other.playerNear && Objects.equals(this.start, other.start) + && this.ignoreLava == other.ignoreLava && Objects.equals(this.boost, other.boost); } } @@ -809,7 +810,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H .findFirst(); } - private boolean isHitboxClear(final Vec3d start, final Vec3d dest, final Double growAmount, boolean ignoreLava) { + private boolean isHitboxClear(final SolverContext context, final Vec3d dest, final Double growAmount) { + final Vec3d start = context.start; + final boolean ignoreLava = context.ignoreLava; + if (!this.clearView(start, dest, ignoreLava)) { return false; } @@ -908,15 +912,13 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } - private Pair solvePitch(final SolverContext context, final Vec3d goal, - final int relaxation, final boolean ignoreLava) { - + private Pair solvePitch(final SolverContext context, final Vec3d goal, final int relaxation) { final boolean desperate = relaxation == 2; final float goodPitch = RotationUtils.calcRotationFromVec3d(context.start, goal, ctx.playerRotations()).getPitch(); final FloatArrayList pitches = pitchesToSolveFor(goodPitch, desperate); final IntTriFunction solve = (ticks, ticksBoosted, ticksBoostDelay) -> - this.solvePitch(context, goal, relaxation, pitches.iterator(), ticks, ticksBoosted, ticksBoostDelay, ignoreLava); + this.solvePitch(context, goal, relaxation, pitches.iterator(), ticks, ticksBoosted, ticksBoostDelay); final List tests = new ArrayList<>(); @@ -968,7 +970,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private PitchResult solvePitch(final SolverContext context, final Vec3d goal, final int relaxation, final FloatIterator pitches, final int ticks, final int ticksBoosted, - final int ticksBoostDelay, final boolean ignoreLava) { + final int ticksBoostDelay) { // we are at a certain velocity, but we have a target velocity // what pitch would get us closest to our target velocity? // yaw is easy so we only care about pitch @@ -987,7 +989,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H ticks, ticksBoosted, ticksBoostDelay, - ignoreLava + context.ignoreLava ); if (displacement == null) { continue; From 4590ba3ff83788c64e1fe0e3b79a0b12b444ff53 Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 29 Jun 2023 23:35:12 -0500 Subject: [PATCH 272/405] Use separate executor for solver --- src/main/java/baritone/behavior/ElytraBehavior.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 954755fa4..3fbe06e44 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -51,9 +51,7 @@ import net.minecraft.util.math.*; import net.minecraft.world.chunk.Chunk; import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.Future; +import java.util.concurrent.*; import java.util.function.UnaryOperator; public final class ElytraBehavior extends Behavior implements IElytraBehavior, Helper { @@ -92,13 +90,15 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H */ private int minimumBoostTicks; + private boolean deployedFireworkLastTick; + private final int[] nextTickBoostCounter; + private BlockStateInterface bsi; private BlockPos destination; + private final ExecutorService solverExecutor; private Future solver; private Solution pendingSolution; - private boolean deployedFireworkLastTick; - private final int[] nextTickBoostCounter; private boolean solveNextTick; public ElytraBehavior(Baritone baritone) { @@ -109,6 +109,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.visiblePath = Collections.emptyList(); this.pathManager = this.new PathManager(); this.process = new ElytraProcess(); + this.solverExecutor = Executors.newSingleThreadExecutor(); this.nextTickBoostCounter = new int[2]; } @@ -524,7 +525,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.pathManager.updatePlayerNear(); final SolverContext context = this.new SolverContext(true); - this.solver = CompletableFuture.supplyAsync(() -> this.solveAngles(context)); + this.solver = this.solverExecutor.submit(() -> this.solveAngles(context)); this.solveNextTick = false; } } From 8211ae4af58585ca3077c558c00b480d7d72ab59 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 29 Jun 2023 21:59:31 -0700 Subject: [PATCH 273/405] memory leaks are joever --- src/api/java/baritone/api/Settings.java | 7 +++++++ src/main/java/baritone/cache/CachedWorld.java | 3 +++ 2 files changed, 10 insertions(+) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 824dfd7e2..a8e4ced7d 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -622,6 +622,13 @@ public final class Settings { */ public final Setting pruneRegionsFromRAM = new Setting<>(true); + /** + * The chunk packer queue can never grow to larger than this, if it does, the oldest chunks are discarded + *

+ * The newest chunks are kept, so that if you're moving in a straight line quickly then stop, your immediate render distance is still included + */ + public final Setting chunkPackerQueueMaxSize = new Setting<>(2000); + /** * Fill in blocks behind you */ diff --git a/src/main/java/baritone/cache/CachedWorld.java b/src/main/java/baritone/cache/CachedWorld.java index 6b3959fe3..32112f20f 100644 --- a/src/main/java/baritone/cache/CachedWorld.java +++ b/src/main/java/baritone/cache/CachedWorld.java @@ -307,6 +307,9 @@ public final class CachedWorld implements ICachedWorld, Helper { try { ChunkPos pos = toPackQueue.take(); Chunk chunk = toPackMap.remove(pos); + if (toPackQueue.size() > Baritone.settings().chunkPackerQueueMaxSize.value) { + continue; + } CachedChunk cached = ChunkPacker.pack(chunk); CachedWorld.this.updateCachedChunk(cached); //System.out.println("Processed chunk at " + chunk.x + "," + chunk.z); From d32f1b2a16a947794ef5b7e20827eb16faba9a6c Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 30 Jun 2023 20:38:45 -0500 Subject: [PATCH 274/405] Add hit pos raytrace method to context --- .../baritone/behavior/elytra/NetherPathfinderContext.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index d82372a99..f0197ca78 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -108,6 +108,10 @@ public final class NetherPathfinderContext { throw new IllegalArgumentException("lol"); } + public void raytrace(final int count, final double[] src, final double[] dst, final boolean[] hitsOut, final double[] hitPosOut) { + NetherPathfinder.raytrace(this.context, true, count, src, dst, hitsOut, hitPosOut); + } + public void cancel() { NetherPathfinder.cancel(this.context); } From 83066fc57c1173aa6595375578751410fcc2cdcb Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 30 Jun 2023 20:42:03 -0500 Subject: [PATCH 275/405] Find jump off spot using INSANE custom CalculationContext --- .../api/process/PathingCommandType.java | 7 +- .../baritone/behavior/ElytraBehavior.java | 175 +++++++++--------- .../baritone/behavior/PathingBehavior.java | 2 +- .../pathing/movement/CalculationContext.java | 4 +- .../movement/movements/MovementDescend.java | 8 + .../baritone/utils/InputOverrideHandler.java | 2 +- .../java/baritone/utils/PathRenderer.java | 4 +- .../baritone/utils/PathingControlManager.java | 4 +- 8 files changed, 117 insertions(+), 89 deletions(-) diff --git a/src/api/java/baritone/api/process/PathingCommandType.java b/src/api/java/baritone/api/process/PathingCommandType.java index af25591af..cde38eaf2 100644 --- a/src/api/java/baritone/api/process/PathingCommandType.java +++ b/src/api/java/baritone/api/process/PathingCommandType.java @@ -56,5 +56,10 @@ public enum PathingCommandType { /** * Go and ask the next process what to do */ - DEFER + DEFER, + + /** + * Sets the goal and calculates a path, but pauses instead of immediately starting the path. + */ + SET_GOAL_AND_PAUSE } diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 3fbe06e44..c31624435 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -18,24 +18,28 @@ package baritone.behavior; import baritone.Baritone; +import baritone.api.IBaritone; import baritone.api.behavior.IElytraBehavior; import baritone.api.behavior.look.IAimProcessor; import baritone.api.behavior.look.ITickableAimProcessor; import baritone.api.event.events.*; import baritone.api.pathing.goals.Goal; -import baritone.api.pathing.goals.GoalGetToBlock; +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.PathingCommand; import baritone.api.process.PathingCommandType; import baritone.api.utils.*; import baritone.api.utils.input.Input; -import baritone.api.utils.interfaces.IGoalRenderPos; import baritone.behavior.elytra.NetherPathfinderContext; import baritone.behavior.elytra.NetherPath; import baritone.behavior.elytra.PathCalculationException; import baritone.behavior.elytra.UnpackedSegment; -import baritone.cache.FasterWorldScanner; +import baritone.pathing.movement.CalculationContext; +import baritone.pathing.movement.movements.MovementFall; import baritone.utils.BlockStateInterface; +import baritone.utils.PathingCommandContext; import baritone.utils.accessor.IEntityFireworkRocket; import it.unimi.dsi.fastutil.floats.FloatArrayList; import it.unimi.dsi.fastutil.floats.FloatIterator; @@ -54,6 +58,8 @@ import java.util.*; import java.util.concurrent.*; import java.util.function.UnaryOperator; +import static baritone.api.pathing.movement.ActionCosts.COST_INF; + public final class ElytraBehavior extends Behavior implements IElytraBehavior, Helper { /** @@ -106,7 +112,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.context = new NetherPathfinderContext(NETHER_SEED); this.clearLines = new CopyOnWriteArrayList<>(); this.blockedLines = new CopyOnWriteArrayList<>(); - this.visiblePath = Collections.emptyList(); this.pathManager = this.new PathManager(); this.process = new ElytraProcess(); this.solverExecutor = Executors.newSingleThreadExecutor(); @@ -395,9 +400,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H @Override public void cancel() { this.destination = null; - this.visiblePath = Collections.emptyList(); this.pathManager.clear(); - this.aimPos = null; this.remainingFireworkTicks = 0; this.remainingSetBackTicks = 0; if (this.solver != null) { @@ -446,12 +449,16 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // Reset rendered elements this.clearLines.clear(); this.blockedLines.clear(); + this.visiblePath = null; this.simulationLine = null; this.aimPos = null; final List path = this.pathManager.getPath(); if (path.isEmpty()) { return; + } else if (this.destination == null) { + this.pathManager.clear(); + return; } this.bsi = new BlockStateInterface(ctx); @@ -1190,43 +1197,67 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } - if (!Baritone.settings().elytraAutoJump.value) { - return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); + if (this.state == State.FLYING || this.state == State.START_FLYING) { + this.state = ctx.player().onGround && Baritone.settings().elytraAutoJump.value + ? State.LOCATE_JUMP + : State.START_FLYING; } - // We were flying, but we're not anymore, reset the state - if (this.state == State.FLYING) { - this.state = State.GET_TO_JUMP; + if (this.state == State.LOCATE_JUMP) { + if (this.goal == null) { + this.goal = new GoalYLevel(31); + } + this.state = State.VALIDATE_PATH; + return new PathingCommandContext(this.goal, PathingCommandType.SET_GOAL_AND_PAUSE, new WalkOffCalculationContext(baritone)); + } + + if (this.state == State.VALIDATE_PATH) { + 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) { + ElytraBehavior.this.pathManager.pathToDestination(fall.getSrc()); + this.state = State.WAIT_ELYTRA_PATH; + } else { + onLostControl(); + logDirect("Jump off path didn't include a fall movement, canceling"); + return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); + } + } + return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); + } + + // yucky + if (this.state == State.WAIT_ELYTRA_PATH) { + if (!ElytraBehavior.this.pathManager.getPath().isEmpty()) { + this.state = State.GET_TO_JUMP; + } + return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); } if (this.state == State.GET_TO_JUMP) { - if (this.goal == null) { - final BlockPos jumpOff = this.findJumpOffSpot(); - if (jumpOff == null) { - onLostControl(); - logDirect("Couldn't find a suitable spot to jump off of, canceling"); - return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); - } - this.goal = new GoalGetToBlock(jumpOff); - ElytraBehavior.this.pathManager.pathToDestination(jumpOff.add(0, -4, 0)); - } - if (this.goal.isInGoal(ctx.playerFeet())) { + 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(this.goal, PathingCommandType.SET_GOAL_AND_PATH); + return new PathingCommand(null, PathingCommandType.SET_GOAL_AND_PATH); } } - if (this.state == State.START_FLYING && isSafeToCancel && !ElytraBehavior.this.pathManager.getPath().isEmpty()) { - baritone.getLookBehavior().updateTarget(RotationUtils.calcRotationFromVec3d( - ctx.playerHead(), - VecUtils.getBlockPosCenter(((IGoalRenderPos) this.goal).getGoalPos()), - ctx.playerRotations() - ), false); - baritone.getInputOverrideHandler().setInputForceState(Input.MOVE_FORWARD, true); - if (ctx.player().fallDistance > 0.0f) { - baritone.getInputOverrideHandler().setInputForceState(Input.JUMP, true); + if (this.state == State.START_FLYING) { + if (!isSafeToCancel) { + // owned + baritone.getPathingBehavior().secretInternalSegmentCancel(); } + baritone.getInputOverrideHandler().setInputForceState(Input.JUMP, true); } return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } @@ -1239,7 +1270,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H @Override public void onLostControl() { this.goal = null; - this.state = State.GET_TO_JUMP; + this.state = State.START_FLYING; ElytraBehavior.this.cancel(); } @@ -1252,64 +1283,42 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H public String displayName0() { return "Elytra"; } + } - // ok... now this.. is disgusting - // TODO: make less scuffed - private BlockPos findJumpOffSpot() { - BlockPos best = null; - final BetterBlockPos feet = ctx.playerFeet(); - final List nearby = FasterWorldScanner.getChunkRange(feet.x >> 4, feet.z >> 4, 3); - for (ChunkPos pos : nearby) { - final Chunk chunk = ctx.world().getChunk(pos.x, pos.z); - int[][] obstruction = new int[16][16]; - for (int y0 = 0; y0 < 8; y0++) { - for (int z = 0; z < 16; z++) { - for (int x = 0; x < 16; x++) { - int y = feet.y - y0; - if (chunk.getBlockState(x, y, z).getMaterial() != Material.AIR) { - if (obstruction[x][z] == 0 || obstruction[x][z] > y0 + 1) { - obstruction[x][z] = y0 + 1; - } - } - } - } - } - for (int x = 0; x < 16; x++) { - for (int z = 0; z < 16; z++) { - if (obstruction[x][z] != 0) { - continue; - } + /** + * Custom calculation context which makes the player fall into lava + */ + private static final class WalkOffCalculationContext extends CalculationContext { - final int[] adjacent = new int[4]; - if (x > 0) adjacent[0] = obstruction[x - 1][z]; - if (z > 0) adjacent[1] = obstruction[x][z - 1]; - if (x < 15) adjacent[2] = obstruction[x + 1][z]; - if (z < 15) adjacent[3] = obstruction[x][z + 1]; - final OptionalInt minLevel = Arrays.stream(adjacent).filter(i -> i != 0).min(); + public WalkOffCalculationContext(IBaritone baritone) { + super(baritone, true); + this.allowFallIntoLava = true; + this.maxFallHeightNoWater = 10000; + } - if (minLevel.isPresent() && minLevel.getAsInt() <= 4) { - final int yActual = feet.y - minLevel.getAsInt() + 2; // lol - // The target spot itself is clear - if (chunk.getBlockState(x, yActual, z).getMaterial() != Material.AIR - || chunk.getBlockState(x, yActual + 1, z).getMaterial() != Material.AIR) { - continue; - } - // lessgooo - final BlockPos target = new BlockPos(chunk.x << 4 | x, yActual, chunk.z << 4 | z); - if (best == null || target.distanceSq(feet) < best.distanceSq(feet)) { - best = target; - } - } - } - } - } - return best; + @Override + public double costOfPlacingAt(int x, int y, int z, IBlockState current) { + return COST_INF; + } + + @Override + public double breakCostMultiplierAt(int x, int y, int z, IBlockState current) { + return COST_INF; + } + + @Override + public double placeBucketCost() { + return COST_INF; } } private enum State { + LOCATE_JUMP, + VALIDATE_PATH, + WAIT_ELYTRA_PATH, GET_TO_JUMP, START_FLYING, - FLYING + FLYING, + RESTART_FLYING, } } diff --git a/src/main/java/baritone/behavior/PathingBehavior.java b/src/main/java/baritone/behavior/PathingBehavior.java index 31a884622..9b1bd9187 100644 --- a/src/main/java/baritone/behavior/PathingBehavior.java +++ b/src/main/java/baritone/behavior/PathingBehavior.java @@ -352,7 +352,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, } // just cancel the current path - private void secretInternalSegmentCancel() { + public void secretInternalSegmentCancel() { queuePathEvent(PathEvent.CANCELED); synchronized (pathPlanLock) { getInProgress().ifPresent(AbstractNodeCostSearch::cancel); diff --git a/src/main/java/baritone/pathing/movement/CalculationContext.java b/src/main/java/baritone/pathing/movement/CalculationContext.java index 129f00e20..2e7db9946 100644 --- a/src/main/java/baritone/pathing/movement/CalculationContext.java +++ b/src/main/java/baritone/pathing/movement/CalculationContext.java @@ -66,11 +66,12 @@ public class CalculationContext { public final boolean allowJumpAt256; public final boolean allowParkourAscend; public final boolean assumeWalkOnWater; + public boolean allowFallIntoLava; public final int frostWalker; public final boolean allowDiagonalDescend; public final boolean allowDiagonalAscend; public final boolean allowDownward; - public final int maxFallHeightNoWater; + public int maxFallHeightNoWater; public final int maxFallHeightBucket; public final double waterWalkSpeed; public final double breakBlockAdditionalCost; @@ -105,6 +106,7 @@ public class CalculationContext { this.allowJumpAt256 = Baritone.settings().allowJumpAt256.value; this.allowParkourAscend = Baritone.settings().allowParkourAscend.value; this.assumeWalkOnWater = Baritone.settings().assumeWalkOnWater.value; + this.allowFallIntoLava = false; // Super secret internal setting for ElytraBehavior this.frostWalker = EnchantmentHelper.getMaxEnchantmentLevel(Enchantments.FROST_WALKER, baritone.getPlayerContext().player()); this.allowDiagonalDescend = Baritone.settings().allowDiagonalDescend.value; this.allowDiagonalAscend = Baritone.settings().allowDiagonalAscend.value; diff --git a/src/main/java/baritone/pathing/movement/movements/MovementDescend.java b/src/main/java/baritone/pathing/movement/movements/MovementDescend.java index 2d8180356..7dac6159d 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementDescend.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementDescend.java @@ -178,6 +178,14 @@ public class MovementDescend extends Movement { res.cost = tentativeCost;// TODO incorporate water swim up cost? return false; } + if (context.allowFallIntoLava && MovementHelper.isLava(ontoBlock.getBlock())) { + // found a fall into lava + res.x = destX; + res.y = newY; + res.z = destZ; + res.cost = tentativeCost; + return false; + } if (unprotectedFallHeight <= 11 && (ontoBlock.getBlock() == Blocks.VINE || ontoBlock.getBlock() == Blocks.LADDER)) { // if fall height is greater than or equal to 11, we don't actually grab on to vines or ladders. the more you know // this effectively "resets" our falling speed diff --git a/src/main/java/baritone/utils/InputOverrideHandler.java b/src/main/java/baritone/utils/InputOverrideHandler.java index f110b9ce1..fe232786b 100755 --- a/src/main/java/baritone/utils/InputOverrideHandler.java +++ b/src/main/java/baritone/utils/InputOverrideHandler.java @@ -107,7 +107,7 @@ public final class InputOverrideHandler extends Behavior implements IInputOverri } private boolean inControl() { - for (Input input : new Input[]{Input.MOVE_FORWARD, Input.MOVE_BACK, Input.MOVE_LEFT, Input.MOVE_RIGHT, Input.SNEAK}) { + for (Input input : new Input[]{Input.MOVE_FORWARD, Input.MOVE_BACK, Input.MOVE_LEFT, Input.MOVE_RIGHT, Input.SNEAK, Input.JUMP}) { if (isInputForcedDown(input)) { return true; } diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index d09567914..eb7615de8 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -104,7 +104,9 @@ public final class PathRenderer implements IRenderer { final ElytraBehavior elytra = behavior.baritone.getElytraBehavior(); - drawPath(elytra.visiblePath, 0, Color.RED, false, 0, 0, 0.0D); + if (elytra.visiblePath != null) { + drawPath(elytra.visiblePath, 0, Color.RED, false, 0, 0, 0.0D); + } if (elytra.aimPos != null) { drawGoal(ctx.player(), new GoalBlock(elytra.aimPos), partialTicks, Color.GREEN); } diff --git a/src/main/java/baritone/utils/PathingControlManager.java b/src/main/java/baritone/utils/PathingControlManager.java index 236e41cc6..a174c842b 100644 --- a/src/main/java/baritone/utils/PathingControlManager.java +++ b/src/main/java/baritone/utils/PathingControlManager.java @@ -99,6 +99,8 @@ public class PathingControlManager implements IPathingControlManager { // get rid of the in progress stuff from the last process } switch (command.commandType) { + case SET_GOAL_AND_PAUSE: + p.secretInternalSetGoalAndPath(command); case REQUEST_PAUSE: p.requestPause(); break; @@ -119,7 +121,7 @@ public class PathingControlManager implements IPathingControlManager { case SET_GOAL_AND_PATH: // now this i can do if (command.goal != null) { - baritone.getPathingBehavior().secretInternalSetGoalAndPath(command); + p.secretInternalSetGoalAndPath(command); } break; default: From 3498082f2b7077877ef095fe9178cc632ba85f07 Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 30 Jun 2023 20:53:42 -0500 Subject: [PATCH 276/405] Better state switch and start path halfway down fall --- .../baritone/behavior/ElytraBehavior.java | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index c31624435..b844d7564 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -155,13 +155,13 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.attemptNextSegment(); } - public void pathToDestination() { - this.pathToDestination(ctx.playerFeet()); + public CompletableFuture pathToDestination() { + return this.pathToDestination(ctx.playerFeet()); } - public void pathToDestination(final BlockPos from) { + public CompletableFuture pathToDestination(final BlockPos from) { final long start = System.nanoTime(); - this.path0(from, ElytraBehavior.this.destination, UnaryOperator.identity()) + return this.path0(from, ElytraBehavior.this.destination, UnaryOperator.identity()) .thenRun(() -> { final double distance = this.path.get(0).distanceTo(this.path.get(this.path.size() - 1)); if (this.completePath) { @@ -1219,8 +1219,19 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H .findFirst().orElse(null); if (fall != null) { - ElytraBehavior.this.pathManager.pathToDestination(fall.getSrc()); - this.state = State.WAIT_ELYTRA_PATH; + 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 + ); + ElytraBehavior.this.pathManager.pathToDestination(from).whenComplete((result, ex) -> { + if (ex == null) { + this.state = State.GET_TO_JUMP; + } else { + this.onLostControl(); // this is fine :Smile: + } + }); + this.state = State.PAUSE; } else { onLostControl(); logDirect("Jump off path didn't include a fall movement, canceling"); @@ -1231,10 +1242,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } // yucky - if (this.state == State.WAIT_ELYTRA_PATH) { - if (!ElytraBehavior.this.pathManager.getPath().isEmpty()) { - this.state = State.GET_TO_JUMP; - } + if (this.state == State.PAUSE) { return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); } @@ -1257,7 +1265,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // owned baritone.getPathingBehavior().secretInternalSegmentCancel(); } - baritone.getInputOverrideHandler().setInputForceState(Input.JUMP, true); + baritone.getInputOverrideHandler().clearAllKeys(); + if (ctx.player().fallDistance > 1.0f) { + baritone.getInputOverrideHandler().setInputForceState(Input.JUMP, true); + } } return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } @@ -1315,7 +1326,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private enum State { LOCATE_JUMP, VALIDATE_PATH, - WAIT_ELYTRA_PATH, + PAUSE, GET_TO_JUMP, START_FLYING, FLYING, From 2f7dc2397e97994a5dd36fc6730636bb055fa05a Mon Sep 17 00:00:00 2001 From: Brady Date: Sat, 1 Jul 2023 01:32:03 -0500 Subject: [PATCH 277/405] Better start position selection and validation --- .../baritone/behavior/ElytraBehavior.java | 33 ++++++++++++++++--- .../movement/movements/MovementDescend.java | 2 +- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index b844d7564..d7f6ff8b9 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -56,6 +56,7 @@ import net.minecraft.world.chunk.Chunk; import java.util.*; import java.util.concurrent.*; +import java.util.function.Supplier; import java.util.function.UnaryOperator; import static baritone.api.pathing.movement.ActionCosts.COST_INF; @@ -1225,11 +1226,17 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H (fall.getSrc().z + fall.getDest().z) / 2 ); ElytraBehavior.this.pathManager.pathToDestination(from).whenComplete((result, ex) -> { + if (!ElytraBehavior.this.clearView(new Vec3d(from), ElytraBehavior.this.pathManager.getPath().getVec(0), false)) { + onLostControl(); + // TODO: Get to higher ground and then look again + logDirect("Can't see start of path from jump spot, canceling"); + return; + } if (ex == null) { this.state = State.GET_TO_JUMP; - } else { - this.onLostControl(); // this is fine :Smile: + return; } + onLostControl(); }); this.state = State.PAUSE; } else { @@ -1292,7 +1299,24 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H @Override public String displayName0() { - return "Elytra"; + final Supplier status = () -> { + switch (this.state) { + case LOCATE_JUMP: + return "Finding spot to jump off"; + case VALIDATE_PATH: + return "Validating path"; + case PAUSE: + return "Waiting for elytra path"; + case GET_TO_JUMP: + return "Walking to takeoff"; + case START_FLYING: + return "Begin flying"; + case FLYING: + return "Flying"; + } + return "Unknown"; + }; + return "Elytra - " + status.get(); } } @@ -1329,7 +1353,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H PAUSE, GET_TO_JUMP, START_FLYING, - FLYING, - RESTART_FLYING, + FLYING } } diff --git a/src/main/java/baritone/pathing/movement/movements/MovementDescend.java b/src/main/java/baritone/pathing/movement/movements/MovementDescend.java index 7dac6159d..51275bc00 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementDescend.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementDescend.java @@ -178,7 +178,7 @@ public class MovementDescend extends Movement { res.cost = tentativeCost;// TODO incorporate water swim up cost? return false; } - if (context.allowFallIntoLava && MovementHelper.isLava(ontoBlock.getBlock())) { + if (fallHeight >= 8 && context.allowFallIntoLava && MovementHelper.isLava(ontoBlock.getBlock())) { // found a fall into lava res.x = destX; res.y = newY; From 14b5a0cec3a601cb5c67b1e1fac0d40826b1e492 Mon Sep 17 00:00:00 2001 From: Brady Date: Sat, 1 Jul 2023 17:28:23 -0500 Subject: [PATCH 278/405] Fix Forge support --- src/launch/java/baritone/launch/mixins/MixinEntity.java | 3 --- .../java/baritone/launch/mixins/MixinEntityLivingBase.java | 5 +++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/launch/java/baritone/launch/mixins/MixinEntity.java b/src/launch/java/baritone/launch/mixins/MixinEntity.java index c4f99acbd..b71ee499e 100644 --- a/src/launch/java/baritone/launch/mixins/MixinEntity.java +++ b/src/launch/java/baritone/launch/mixins/MixinEntity.java @@ -40,7 +40,4 @@ public abstract class MixinEntity { @Shadow public float rotationYaw; - - @Shadow - public abstract void moveRelative(float strafe, float up, float forward, float friction); } diff --git a/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java b/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java index db2faa940..56b70f085 100644 --- a/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java +++ b/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java @@ -117,7 +117,8 @@ public abstract class MixinEntityLivingBase extends MixinEntity { private void onMoveRelative(EntityLivingBase self, float strafe, float up, float forward, float friction) { Optional baritone = this.getBaritone(); if (!baritone.isPresent()) { - this.moveRelative(strafe, up, forward, friction); + // If a shadow is used here it breaks on Forge + self.moveRelative(strafe, up, forward, friction); return; } @@ -127,7 +128,7 @@ public abstract class MixinEntityLivingBase extends MixinEntity { this.rotationYaw = event.getYaw(); this.rotationPitch = event.getPitch(); - this.moveRelative(strafe, up, forward, friction); + self.moveRelative(strafe, up, forward, friction); this.rotationYaw = event.getOriginal().getYaw(); this.rotationPitch = event.getOriginal().getPitch(); From ccd737d0a1e3c5afbd0db7b361cc2916b9862bd9 Mon Sep 17 00:00:00 2001 From: Brady Date: Sat, 1 Jul 2023 18:38:13 -0500 Subject: [PATCH 279/405] Actually fix Forge by reverting Mixin change completely --- .../java/baritone/launch/mixins/MixinEntity.java | 6 ------ .../launch/mixins/MixinEntityLivingBase.java | 12 +++++++++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/launch/java/baritone/launch/mixins/MixinEntity.java b/src/launch/java/baritone/launch/mixins/MixinEntity.java index b71ee499e..a611507b8 100644 --- a/src/launch/java/baritone/launch/mixins/MixinEntity.java +++ b/src/launch/java/baritone/launch/mixins/MixinEntity.java @@ -34,10 +34,4 @@ public abstract class MixinEntity { @Shadow protected EntityDataManager dataManager; - - @Shadow - public float rotationPitch; - - @Shadow - public float rotationYaw; } diff --git a/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java b/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java index 56b70f085..92f065184 100644 --- a/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java +++ b/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java @@ -21,7 +21,9 @@ import baritone.api.BaritoneAPI; import baritone.api.IBaritone; import baritone.api.event.events.RotationMoveEvent; import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; @@ -38,7 +40,7 @@ import static org.spongepowered.asm.lib.Opcodes.GETFIELD; * @since 9/10/2018 */ @Mixin(EntityLivingBase.class) -public abstract class MixinEntityLivingBase extends MixinEntity { +public abstract class MixinEntityLivingBase extends Entity { /** * Event called to override the movement direction when jumping @@ -49,6 +51,10 @@ public abstract class MixinEntityLivingBase extends MixinEntity { @Unique private RotationMoveEvent elytraRotationEvent; + public MixinEntityLivingBase(World worldIn) { + super(worldIn); + } + @Inject( method = "jump", at = @At("HEAD") @@ -118,7 +124,7 @@ public abstract class MixinEntityLivingBase extends MixinEntity { Optional baritone = this.getBaritone(); if (!baritone.isPresent()) { // If a shadow is used here it breaks on Forge - self.moveRelative(strafe, up, forward, friction); + this.moveRelative(strafe, up, forward, friction); return; } @@ -128,7 +134,7 @@ public abstract class MixinEntityLivingBase extends MixinEntity { this.rotationYaw = event.getYaw(); this.rotationPitch = event.getPitch(); - self.moveRelative(strafe, up, forward, friction); + this.moveRelative(strafe, up, forward, friction); this.rotationYaw = event.getOriginal().getYaw(); this.rotationPitch = event.getOriginal().getPitch(); From dee7df1534aec68f4bb017eb6d8f5ecc54e4b6f3 Mon Sep 17 00:00:00 2001 From: Brady Date: Sat, 1 Jul 2023 19:38:38 -0500 Subject: [PATCH 280/405] I HATE OLD MIXIN!!!! awesome buggy 0.7.11 hates referencing shadows in mixin superclasses wooooooo --- .../baritone/launch/mixins/MixinEntity.java | 37 ------------------- .../mixins/MixinEntityFireworkRocket.java | 7 +++- .../launch/mixins/MixinEntityLivingBase.java | 2 +- src/launch/resources/mixins.baritone.json | 1 - 4 files changed, 7 insertions(+), 40 deletions(-) delete mode 100644 src/launch/java/baritone/launch/mixins/MixinEntity.java diff --git a/src/launch/java/baritone/launch/mixins/MixinEntity.java b/src/launch/java/baritone/launch/mixins/MixinEntity.java deleted file mode 100644 index a611507b8..000000000 --- a/src/launch/java/baritone/launch/mixins/MixinEntity.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is part of Baritone. - * - * Baritone is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Baritone is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Baritone. If not, see . - */ - -package baritone.launch.mixins; - -import net.minecraft.entity.Entity; -import net.minecraft.network.datasync.EntityDataManager; -import net.minecraft.world.World; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -/** - * @author Brady - */ -@Mixin(Entity.class) -public abstract class MixinEntity { - - @Shadow - public World world; - - @Shadow - protected EntityDataManager dataManager; -} diff --git a/src/launch/java/baritone/launch/mixins/MixinEntityFireworkRocket.java b/src/launch/java/baritone/launch/mixins/MixinEntityFireworkRocket.java index 559ae0d54..f6c6fbd3e 100644 --- a/src/launch/java/baritone/launch/mixins/MixinEntityFireworkRocket.java +++ b/src/launch/java/baritone/launch/mixins/MixinEntityFireworkRocket.java @@ -22,12 +22,13 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.item.EntityFireworkRocket; import net.minecraft.network.datasync.DataParameter; +import net.minecraft.world.World; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @Mixin(EntityFireworkRocket.class) -public abstract class MixinEntityFireworkRocket extends MixinEntity implements IEntityFireworkRocket { +public abstract class MixinEntityFireworkRocket extends Entity implements IEntityFireworkRocket { @Shadow @Final @@ -39,6 +40,10 @@ public abstract class MixinEntityFireworkRocket extends MixinEntity implements I @Shadow public abstract boolean isAttachedToEntity(); + private MixinEntityFireworkRocket(World worldIn) { + super(worldIn); + } + @Override public EntityLivingBase getBoostedEntity() { if (this.isAttachedToEntity() && this.boostedEntity == null) { diff --git a/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java b/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java index 92f065184..df1163ea8 100644 --- a/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java +++ b/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java @@ -51,7 +51,7 @@ public abstract class MixinEntityLivingBase extends Entity { @Unique private RotationMoveEvent elytraRotationEvent; - public MixinEntityLivingBase(World worldIn) { + private MixinEntityLivingBase(World worldIn) { super(worldIn); } diff --git a/src/launch/resources/mixins.baritone.json b/src/launch/resources/mixins.baritone.json index cbade3329..5c221de58 100644 --- a/src/launch/resources/mixins.baritone.json +++ b/src/launch/resources/mixins.baritone.json @@ -16,7 +16,6 @@ "MixinChunkProviderServer", "MixinChunkRenderContainer", "MixinChunkRenderWorker", - "MixinEntity", "MixinEntityFireworkRocket", "MixinEntityLivingBase", "MixinEntityPlayerSP", From fc209599af9ffb17785ea36d3728147ac2357712 Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 2 Jul 2023 01:03:34 -0500 Subject: [PATCH 281/405] Update `nether-pathfinder` to 0.21 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 58929d98b..99d7cc823 100755 --- a/build.gradle +++ b/build.gradle @@ -175,9 +175,9 @@ dependencies { transitive = false } launchAnnotationProcessor 'org.spongepowered:mixin:0.8.4-SNAPSHOT:processor' - launchImplementation('dev.babbaj:nether-pathfinder:0.20') + launchImplementation('dev.babbaj:nether-pathfinder:0.21') testImplementation 'junit:junit:4.12' - implementation 'dev.babbaj:nether-pathfinder:0.20' + implementation 'dev.babbaj:nether-pathfinder:0.21' } mixin { From 6654476da435203df9f5f42ed9f41310f5560c30 Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 2 Jul 2023 19:59:26 -0500 Subject: [PATCH 282/405] Make `blockFreeLook` depend on `freeLook` --- src/api/java/baritone/api/Settings.java | 3 +-- src/main/java/baritone/behavior/LookBehavior.java | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index a8e4ced7d..da241d6ba 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -731,8 +731,7 @@ public final class Settings { public final Setting freeLook = new Setting<>(true); /** - * Break and place blocks without having to force the client-sided rotations. Having this setting enabled implies - * {@link #freeLook}. + * Break and place blocks without having to force the client-sided rotations. Requires {@link #freeLook}. */ public final Setting blockFreeLook = new Setting<>(false); diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index d438e8f85..372cf1aae 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -135,10 +135,10 @@ public final class LookBehavior extends Behavior implements ILookBehavior { } public Optional getEffectiveRotation() { - if (Baritone.settings().freeLook.value || Baritone.settings().blockFreeLook.value) { + if (Baritone.settings().freeLook.value) { return Optional.ofNullable(this.serverRotation); } - // If neither of the freeLook settings are on, just defer to the player's actual rotations + // If freeLook isn't on, just defer to the player's actual rotations return Optional.empty(); } @@ -306,7 +306,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior { final boolean blockFreeLook = settings.blockFreeLook.value; final boolean freeLook = settings.freeLook.value; - if (!freeLook && !blockFreeLook) return CLIENT; + if (!freeLook) return CLIENT; if (!blockFreeLook && blockInteract) return CLIENT; // Regardless of if antiCheatCompatibility is enabled, if a blockInteract is requested then the player From c8259d3e90b372ba55b25172dae133ed5761fc72 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 3 Jul 2023 13:27:23 -0500 Subject: [PATCH 283/405] ZOOM --- .../baritone/api/utils/BetterBlockPos.java | 20 ++++ .../baritone/behavior/ElytraBehavior.java | 99 +++++++++++++------ .../behavior/elytra/UnpackedSegment.java | 3 +- .../java/baritone/utils/BaritoneMath.java | 37 +++++++ 4 files changed, 125 insertions(+), 34 deletions(-) create mode 100644 src/main/java/baritone/utils/BaritoneMath.java diff --git a/src/api/java/baritone/api/utils/BetterBlockPos.java b/src/api/java/baritone/api/utils/BetterBlockPos.java index 01e53402e..3eb8068c1 100644 --- a/src/api/java/baritone/api/utils/BetterBlockPos.java +++ b/src/api/java/baritone/api/utils/BetterBlockPos.java @@ -35,6 +35,15 @@ import javax.annotation.Nonnull; */ public final class BetterBlockPos extends BlockPos { + private static final int NUM_X_BITS = 26; + private static final int NUM_Z_BITS = NUM_X_BITS; + private static final int NUM_Y_BITS = 64 - NUM_X_BITS - NUM_Z_BITS; + private static final int Y_SHIFT = NUM_Z_BITS; + private static final int X_SHIFT = Y_SHIFT + NUM_Y_BITS; + private static final long X_MASK = (1L << NUM_X_BITS) - 1L; + private static final long Y_MASK = (1L << NUM_Y_BITS) - 1L; + private static final long Z_MASK = (1L << NUM_Z_BITS) - 1L; + public static final BetterBlockPos ORIGIN = new BetterBlockPos(0, 0, 0); public final int x; @@ -226,4 +235,15 @@ public final class BetterBlockPos extends BlockPos { SettingsUtil.maybeCensor(z) ); } + + public static long serializeToLong(final int x, final int y, final int z) { + return ((long) x & X_MASK) << X_SHIFT | ((long) y & Y_MASK) << Y_SHIFT | ((long) z & Z_MASK); + } + + public static BetterBlockPos deserializeFromLong(final long serialized) { + final int x = (int) (serialized << 64 - X_SHIFT - NUM_X_BITS >> 64 - NUM_X_BITS); + final int y = (int) (serialized << 64 - Y_SHIFT - NUM_Y_BITS >> 64 - NUM_Y_BITS); + final int z = (int) (serialized << 64 - NUM_Z_BITS >> 64 - NUM_Z_BITS); + return new BetterBlockPos(x, y, z); + } } diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index d7f6ff8b9..73ccb69f1 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -43,6 +43,7 @@ import baritone.utils.PathingCommandContext; import baritone.utils.accessor.IEntityFireworkRocket; import it.unimi.dsi.fastutil.floats.FloatArrayList; import it.unimi.dsi.fastutil.floats.FloatIterator; +import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.item.EntityFireworkRocket; @@ -60,6 +61,8 @@ import java.util.function.Supplier; import java.util.function.UnaryOperator; import static baritone.api.pathing.movement.ActionCosts.COST_INF; +import static baritone.utils.BaritoneMath.fastCeil; +import static baritone.utils.BaritoneMath.fastFloor; public final class ElytraBehavior extends Behavior implements IElytraBehavior, Helper { @@ -447,6 +450,9 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H this.minimumBoostTicks = 0; } + // lol + MC_1_12_Collision_Fix.clear(); + // Reset rendered elements this.clearLines.clear(); this.blockedLines.clear(); @@ -567,7 +573,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } else { // Create a point along the segment every block final Vec3d delta = path.getVec(i).subtract(path.getVec(i - 1)); - final int steps = MathHelper.floor(delta.length()); + final int steps = fastFloor(delta.length()); final Vec3d step = delta.normalize(); Vec3d stepped = path.getVec(i); for (int interp = 0; interp < steps; interp++) { @@ -893,7 +899,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final float minPitch = desperate ? -90 : Math.max(goodPitch - Baritone.settings().elytraPitchRange.value, -89); final float maxPitch = desperate ? 90 : Math.min(goodPitch + Baritone.settings().elytraPitchRange.value, 89); - final FloatArrayList pitchValues = new FloatArrayList(MathHelper.ceil(maxPitch - minPitch) + 1); + final FloatArrayList pitchValues = new FloatArrayList(fastCeil(maxPitch - minPitch) + 1); for (float pitch = goodPitch; pitch <= maxPitch; pitch++) { pitchValues.add(pitch); } @@ -1039,11 +1045,13 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H Vec3d delta = goalDelta; Vec3d motion = ctx.playerMotion(); AxisAlignedBB hitbox = ctx.player().getEntityBoundingBox(); - List displacement = new ArrayList<>(); + List displacement = new ArrayList<>(ticks + 1); displacement.add(Vec3d.ZERO); for (int i = 0; i < ticks; i++) { - if (MC_1_12_Collision_Fix.bonk(this.bsi, hitbox)) { + final double cx = hitbox.minX + (hitbox.maxX - hitbox.minX) * 0.5D; + final double cz = hitbox.minZ + (hitbox.maxZ - hitbox.minZ) * 0.5D; + if (MC_1_12_Collision_Fix.bonk(this.bsi, cx, hitbox.minY, cz)) { return null; } if (delta.lengthSquared() < 1) { @@ -1060,9 +1068,9 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // Collision box while the player is in motion, with additional padding for safety final AxisAlignedBB inMotion = hitbox.expand(motion.x, motion.y, motion.z).grow(0.01); - for (int x = MathHelper.floor(inMotion.minX); x < MathHelper.ceil(inMotion.maxX); x++) { - for (int y = MathHelper.floor(inMotion.minY); y < MathHelper.ceil(inMotion.maxY); y++) { - for (int z = MathHelper.floor(inMotion.minZ); z < MathHelper.ceil(inMotion.maxZ); z++) { + for (int x = fastFloor(inMotion.minX); x < fastCeil(inMotion.maxX); x++) { + for (int y = fastFloor(inMotion.minY); y < fastCeil(inMotion.maxY); y++) { + for (int z = fastFloor(inMotion.minZ); z < fastCeil(inMotion.maxZ); z++) { if (!this.passable(x, y, z, ignoreLava)) { return null; } @@ -1140,35 +1148,62 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H */ private static final class MC_1_12_Collision_Fix { - public static boolean bonk(final BlockStateInterface bsi, final AxisAlignedBB aabb) { - final Vec3d center = aabb.getCenter(); - final double width = (aabb.maxX - aabb.minX) * 0.35D; - final double x = center.x; - final double y = aabb.minY + 0.5D; - final double z = center.z; + private static final Long2ReferenceOpenHashMap PUSH_OUT_CACHE = new Long2ReferenceOpenHashMap<>(); + private static final Long2ReferenceOpenHashMap IS_OPEN_CACHE = new Long2ReferenceOpenHashMap<>(); + private static final double WIDTH = 0.35D * 0.6F; - return pushOutOfBlocks(bsi, x - width, y, z + width) - || pushOutOfBlocks(bsi, x - width, y, z - width) - || pushOutOfBlocks(bsi, x + width, y, z - width) - || pushOutOfBlocks(bsi, x + width, y, z + width); - } - - private static boolean pushOutOfBlocks(final BlockStateInterface bsi, - final double xIn, final double yIn, final double zIn) { - final int x = MathHelper.floor(xIn); - final int y = MathHelper.floor(yIn); - final int z = MathHelper.floor(zIn); - if (isOpenBlockSpace(bsi, x, y, z)) { - return false; + public static void clear() { + // TODO: I don't like this.... + if (MC_1_12_Collision_Fix.PUSH_OUT_CACHE.size() > 4096) { + MC_1_12_Collision_Fix.PUSH_OUT_CACHE.clear(); + } + if (MC_1_12_Collision_Fix.IS_OPEN_CACHE.size() > 4096) { + MC_1_12_Collision_Fix.IS_OPEN_CACHE.clear(); } - return isOpenBlockSpace(bsi, x - 1, y, z) - || isOpenBlockSpace(bsi, x + 1, y, z) - || isOpenBlockSpace(bsi, x, y, z - 1) - || isOpenBlockSpace(bsi, x, y, z + 1); } - private static boolean isOpenBlockSpace(BlockStateInterface bsi, final int x, final int y, final int z) { - return !bsi.get0(x, y, z).isNormalCube() && !bsi.get0(x, y + 1, z).isNormalCube(); + public static boolean bonk(final BlockStateInterface bsi, final double xIn, final double yIn, final double zIn) { + final int y = fastFloor(yIn + 0.5D); + final int minX = fastFloor(xIn - WIDTH); + final int minZ = fastFloor(zIn - WIDTH); + final int maxX = fastFloor(xIn + WIDTH); + final int maxZ = fastFloor(zIn + WIDTH); + + if (minX == maxX && minZ == maxZ) { + return pushOutOfBlocks(bsi, minX, y, minZ); + } else if (minX == maxX) { + return pushOutOfBlocks(bsi, minX, y, minZ) || pushOutOfBlocks(bsi, minX, y, maxZ); + } else if (minZ == maxZ) { + return pushOutOfBlocks(bsi, minX, y, minZ) || pushOutOfBlocks(bsi, maxX, y, minZ); + } + + return pushOutOfBlocks(bsi, minX, y, maxZ) + || pushOutOfBlocks(bsi, minX, y, minZ) + || pushOutOfBlocks(bsi, maxX, y, minZ) + || pushOutOfBlocks(bsi, maxX, y, maxZ); + } + + private static boolean pushOutOfBlocks(final BlockStateInterface bsi, final int x, final int y, final int z) { + final long hash = BetterBlockPos.serializeToLong(x, y, z); + Boolean result = PUSH_OUT_CACHE.get(hash); + if (result == null) { + PUSH_OUT_CACHE.put(hash, result = !isOpenBlockSpace(bsi, x, y, z) && ( + isOpenBlockSpace(bsi, x - 1, y, z) + || isOpenBlockSpace(bsi, x + 1, y, z) + || isOpenBlockSpace(bsi, x, y, z - 1) + || isOpenBlockSpace(bsi, x, y, z + 1)) + ); + } + return result; + } + + private static boolean isOpenBlockSpace(final BlockStateInterface bsi, final int x, final int y, final int z) { + final long hash = BetterBlockPos.serializeToLong(x, y, z); + Boolean result = IS_OPEN_CACHE.get(hash); + if (result == null) { + IS_OPEN_CACHE.put(hash, result = !bsi.get0(x, y, z).isNormalCube() && !bsi.get0(x, y + 1, z).isNormalCube()); + } + return result; } } diff --git a/src/main/java/baritone/behavior/elytra/UnpackedSegment.java b/src/main/java/baritone/behavior/elytra/UnpackedSegment.java index 22fa4f82d..0e0759625 100644 --- a/src/main/java/baritone/behavior/elytra/UnpackedSegment.java +++ b/src/main/java/baritone/behavior/elytra/UnpackedSegment.java @@ -19,7 +19,6 @@ package baritone.behavior.elytra; import baritone.api.utils.BetterBlockPos; import dev.babbaj.pathfinder.PathSegment; -import net.minecraft.util.math.BlockPos; import java.util.Arrays; import java.util.HashMap; @@ -77,7 +76,7 @@ public final class UnpackedSegment { public static UnpackedSegment from(final PathSegment segment) { return new UnpackedSegment( - Arrays.stream(segment.packed).mapToObj(BlockPos::fromLong).map(BetterBlockPos::new), + Arrays.stream(segment.packed).mapToObj(BetterBlockPos::deserializeFromLong), segment.finished ); } diff --git a/src/main/java/baritone/utils/BaritoneMath.java b/src/main/java/baritone/utils/BaritoneMath.java new file mode 100644 index 000000000..944fc899e --- /dev/null +++ b/src/main/java/baritone/utils/BaritoneMath.java @@ -0,0 +1,37 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.utils; + +/** + * @author Brady + */ +public final class BaritoneMath { + + private BaritoneMath() {} + + private static final double FLOOR_DOUBLE_D = 1_073_741_824.0; + private static final int FLOOR_DOUBLE_I = 1_073_741_824; + + public static int fastFloor(final double v) { + return (int) (v + FLOOR_DOUBLE_D) - FLOOR_DOUBLE_I; + } + + public static int fastCeil(final double v) { + return FLOOR_DOUBLE_I - (int) (FLOOR_DOUBLE_D - v); + } +} From 4c0c263d1100d5f48caf9bf303ceb7654d73a463 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 3 Jul 2023 13:28:53 -0500 Subject: [PATCH 284/405] trolling --- src/main/java/baritone/behavior/ElytraBehavior.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 73ccb69f1..f22a3151d 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -1154,11 +1154,11 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H public static void clear() { // TODO: I don't like this.... - if (MC_1_12_Collision_Fix.PUSH_OUT_CACHE.size() > 4096) { - MC_1_12_Collision_Fix.PUSH_OUT_CACHE.clear(); + if (PUSH_OUT_CACHE.size() > 4096) { + PUSH_OUT_CACHE.clear(); } - if (MC_1_12_Collision_Fix.IS_OPEN_CACHE.size() > 4096) { - MC_1_12_Collision_Fix.IS_OPEN_CACHE.clear(); + if (IS_OPEN_CACHE.size() > 4096) { + IS_OPEN_CACHE.clear(); } } From 2552eb8dca36d7fac1ffe2eb4e3b81149c29763a Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 6 Jul 2023 18:57:51 -0700 Subject: [PATCH 285/405] Add setting documentation --- src/api/java/baritone/api/Settings.java | 81 +++++++++++++++++++++---- 1 file changed, 68 insertions(+), 13 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index c85280f60..9eed667f9 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -48,19 +48,6 @@ import java.util.function.Consumer; */ public final class Settings { - public final Setting elytraSimulationTicks = new Setting<>(20); - public final Setting elytraPitchRange = new Setting<>(25); - public final Setting elytraFireworkSpeed = new Setting<>(0.6); - public final Setting elytraFireworkSetbackUseDelay = new Setting<>(15); - public final Setting elytraMinimumAvoidance = new Setting<>(0.2); - public final Setting conserveFireworks = new Setting<>(true); - public final Setting renderRaytraces = new Setting<>(false); - public final Setting renderHitboxRaytraces = new Setting<>(false); - public final Setting renderElytraSimulation = new Setting<>(false); - public final Setting elytraFreeLook = new Setting<>(false); - public final Setting elytraAutoJump = new Setting<>(false); - public final Setting smoothLook = new Setting<>(false); - /** * Allow Baritone to break blocks */ @@ -748,6 +735,17 @@ public final class Settings { */ public final Setting blockFreeLook = new Setting<>(false); + /** + * Automatically elytra fly without having to force the client-sided rotations. Requires {@link #freeLook}. + */ + public final Setting elytraFreeLook = new Setting<>(false); + + /** + * Forces the client-sided rotations to an average of the last 10 ticks of server-sided rotations. + * Requires {@link #freeLook}. + */ + public final Setting smoothLook = new Setting<>(false); + /** * When true, the player will remain with its existing look direction as often as possible. * Although, in some cases this can get it stuck, hence this setting to disable that behavior. @@ -1333,6 +1331,63 @@ public final class Settings { */ public final Setting notificationOnMineFail = new Setting<>(true); + /** + * The number of ticks of elytra movement to simulate while firework boost is not active. Higher values are + * computationally more expensive. + */ + public final Setting elytraSimulationTicks = new Setting<>(20); + + /** + * The maximum allowed deviation in pitch from a direct line-of-sight to the flight target. Higher values are + * computationally more expensive. + */ + public final Setting elytraPitchRange = new Setting<>(25); + + /** + * The minimum speed that the player can drop to (in blocks/tick) before a firework is automatically deployed. + */ + public final Setting elytraFireworkSpeed = new Setting<>(0.6); + + /** + * The delay after the player's position is set-back by the server that a firework may be automatically deployed. + * Value is in ticks. + */ + public final Setting elytraFireworkSetbackUseDelay = new Setting<>(15); + + /** + * The minimum padding value that is added to the player's hitbox when considering which point to fly to on the + * path. High values can result in points not being considered which are otherwise safe to fly to. Low values can + * result in flight paths which are extremely tight, and there's the possibility of crashing due to getting too low + * to the ground. + */ + public final Setting elytraMinimumAvoidance = new Setting<>(0.2); + + /** + * If enabled, avoids using fireworks when descending along the flight path. + */ + public final Setting conserveFireworks = new Setting<>(true); + + /** + * Renders the raytraces that are performed by the elytra fly calculation. + */ + public final Setting renderRaytraces = new Setting<>(false); + + /** + * Renders the raytraces that are used in the hitbox part of the elytra fly calculation. + * Requires {@link #renderRaytraces}. + */ + public final Setting renderHitboxRaytraces = new Setting<>(false); + + /** + * Renders the best elytra flight path that was simulated each tick. + */ + public final Setting renderElytraSimulation = new Setting<>(false); + + /** + * Automatically path to and jump off of ledges to initiate elytra flight when grounded. + */ + public final Setting elytraAutoJump = new Setting<>(false); + /** * A map of lowercase setting field names to their respective setting */ From aeeb00120559a72f2123a11880375291b3c575cd Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 6 Jul 2023 19:02:13 -0700 Subject: [PATCH 286/405] Fix some codacy issues --- src/main/java/baritone/behavior/ElytraBehavior.java | 8 +++++--- src/main/java/baritone/behavior/InventoryBehavior.java | 2 -- .../baritone/behavior/elytra/NetherPathfinderContext.java | 7 ++++--- .../java/baritone/command/defaults/ElytraCommand.java | 1 - .../command/defaults/ExecutionControlCommands.java | 1 - .../baritone/command/defaults/ForceCancelCommand.java | 1 - src/main/java/baritone/utils/BaritoneMath.java | 4 ++-- 7 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index f22a3151d..fb8747bb2 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -1041,12 +1041,13 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } private List simulate(final ITickableAimProcessor aimProcessor, final Vec3d goalDelta, final float pitch, - final int ticks, int ticksBoosted, final int ticksBoostDelay, final boolean ignoreLava) { + final int ticks, final int ticksBoosted, final int ticksBoostDelay, final boolean ignoreLava) { Vec3d delta = goalDelta; Vec3d motion = ctx.playerMotion(); AxisAlignedBB hitbox = ctx.player().getEntityBoundingBox(); List displacement = new ArrayList<>(ticks + 1); displacement.add(Vec3d.ZERO); + int remainingTicksBoosted = ticksBoosted; for (int i = 0; i < ticks; i++) { final double cx = hitbox.minX + (hitbox.maxX - hitbox.minX) * 0.5D; @@ -1081,7 +1082,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H hitbox = hitbox.offset(motion); displacement.add(displacement.get(displacement.size() - 1).add(motion)); - if (i >= ticksBoostDelay && ticksBoosted-- > 0) { + if (i >= ticksBoostDelay && remainingTicksBoosted-- > 0) { // See EntityFireworkRocket motion = motion.add( lookDirection.x * 0.1 + (lookDirection.x * 1.5 - motion.x) * 0.5, @@ -1348,8 +1349,9 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return "Begin flying"; case FLYING: return "Flying"; + default: + return "Unknown"; } - return "Unknown"; }; return "Elytra - " + status.get(); } diff --git a/src/main/java/baritone/behavior/InventoryBehavior.java b/src/main/java/baritone/behavior/InventoryBehavior.java index 1ab31eb53..93dc200cc 100644 --- a/src/main/java/baritone/behavior/InventoryBehavior.java +++ b/src/main/java/baritone/behavior/InventoryBehavior.java @@ -25,10 +25,8 @@ import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.init.Blocks; -import net.minecraft.init.Items; import net.minecraft.inventory.ClickType; import net.minecraft.item.*; -import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; import net.minecraft.util.NonNullList; diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index f0197ca78..8e9a862c0 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -104,8 +104,9 @@ public final class NetherPathfinderContext { return NetherPathfinder.isVisibleMulti(this.context, true, count, src, dst, true) == -1; case Visibility.ANY: return NetherPathfinder.isVisibleMulti(this.context, true, count, src, dst, true) != -1; + default: + throw new IllegalArgumentException("lol"); } - throw new IllegalArgumentException("lol"); } public void raytrace(final int count, final double[] src, final double[] dst, final boolean[] hitsOut, final double[] hitPosOut) { @@ -166,10 +167,10 @@ public final class NetherPathfinderContext { public static final class Visibility { - private Visibility() {} - public static final int ALL = 0; public static final int NONE = 1; public static final int ANY = 2; + + private Visibility() {} } } diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index 3414c7bb3..93c4c2544 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -17,7 +17,6 @@ package baritone.command.defaults; -import baritone.Baritone; import baritone.api.IBaritone; import baritone.api.command.Command; import baritone.api.command.argument.IArgConsumer; diff --git a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java index e7f7c9497..43adca19f 100644 --- a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java +++ b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java @@ -17,7 +17,6 @@ package baritone.command.defaults; -import baritone.Baritone; import baritone.api.IBaritone; import baritone.api.command.Command; import baritone.api.command.argument.IArgConsumer; diff --git a/src/main/java/baritone/command/defaults/ForceCancelCommand.java b/src/main/java/baritone/command/defaults/ForceCancelCommand.java index bc6dbd0a4..ad19f168c 100644 --- a/src/main/java/baritone/command/defaults/ForceCancelCommand.java +++ b/src/main/java/baritone/command/defaults/ForceCancelCommand.java @@ -17,7 +17,6 @@ package baritone.command.defaults; -import baritone.Baritone; import baritone.api.IBaritone; import baritone.api.behavior.IPathingBehavior; import baritone.api.command.Command; diff --git a/src/main/java/baritone/utils/BaritoneMath.java b/src/main/java/baritone/utils/BaritoneMath.java index 944fc899e..be546f248 100644 --- a/src/main/java/baritone/utils/BaritoneMath.java +++ b/src/main/java/baritone/utils/BaritoneMath.java @@ -22,11 +22,11 @@ package baritone.utils; */ public final class BaritoneMath { - private BaritoneMath() {} - private static final double FLOOR_DOUBLE_D = 1_073_741_824.0; private static final int FLOOR_DOUBLE_I = 1_073_741_824; + private BaritoneMath() {} + public static int fastFloor(final double v) { return (int) (v + FLOOR_DOUBLE_D) - FLOOR_DOUBLE_I; } From c4ac23837fd0ddddebd39795dd5004251ad0c3e6 Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 6 Jul 2023 19:31:37 -0700 Subject: [PATCH 287/405] Set `safeToCancel` to `false` while flying --- src/main/java/baritone/behavior/ElytraBehavior.java | 4 ++++ src/main/java/baritone/behavior/PathingBehavior.java | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index fb8747bb2..9ff48f3a2 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -1208,6 +1208,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } + public boolean isSafeToCancel() { + return !this.isActive() || !(this.process.state == State.FLYING || this.process.state == State.START_FLYING); + } + private final class ElytraProcess implements IBaritoneProcess { private State state; diff --git a/src/main/java/baritone/behavior/PathingBehavior.java b/src/main/java/baritone/behavior/PathingBehavior.java index 9b1bd9187..19266b2c2 100644 --- a/src/main/java/baritone/behavior/PathingBehavior.java +++ b/src/main/java/baritone/behavior/PathingBehavior.java @@ -148,6 +148,9 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, } } if (current == null) { + if (baritone.getElytraBehavior().isActive()) { + safeToCancel = baritone.getElytraBehavior().isSafeToCancel(); + } return; } safeToCancel = current.onTick(); From ecfd664f30d2dd37b0a8ad9035e21bb793cac5d6 Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 6 Jul 2023 20:11:50 -0700 Subject: [PATCH 288/405] Fix `isSafeToCancel()` return value --- src/main/java/baritone/behavior/PathingBehavior.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/baritone/behavior/PathingBehavior.java b/src/main/java/baritone/behavior/PathingBehavior.java index 19266b2c2..670dd827c 100644 --- a/src/main/java/baritone/behavior/PathingBehavior.java +++ b/src/main/java/baritone/behavior/PathingBehavior.java @@ -148,9 +148,6 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, } } if (current == null) { - if (baritone.getElytraBehavior().isActive()) { - safeToCancel = baritone.getElytraBehavior().isSafeToCancel(); - } return; } safeToCancel = current.onTick(); @@ -312,7 +309,10 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, } public boolean isSafeToCancel() { - return current == null || safeToCancel; + if (current == null) { + return !baritone.getElytraBehavior().isActive() || baritone.getElytraBehavior().isSafeToCancel(); + } + return safeToCancel; } public void requestPause() { From 8de239f4688609de996107f36048e59f66ac2310 Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 6 Jul 2023 23:15:35 -0700 Subject: [PATCH 289/405] Use soft references for chunks queued for packing --- src/main/java/baritone/cache/CachedWorld.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/cache/CachedWorld.java b/src/main/java/baritone/cache/CachedWorld.java index 32112f20f..bed3185a5 100644 --- a/src/main/java/baritone/cache/CachedWorld.java +++ b/src/main/java/baritone/cache/CachedWorld.java @@ -23,6 +23,7 @@ import baritone.api.IBaritone; import baritone.api.cache.ICachedWorld; import baritone.api.cache.IWorldData; import baritone.api.utils.Helper; +import com.google.common.cache.CacheBuilder; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.minecraft.util.math.BlockPos; @@ -35,7 +36,6 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.LinkedBlockingQueue; /** @@ -69,7 +69,7 @@ public final class CachedWorld implements ICachedWorld, Helper { * All chunk positions pending packing. This map will be updated in-place if a new update to the chunk occurs * while waiting in the queue for the packer thread to get to it. */ - private final Map toPackMap = new ConcurrentHashMap<>(); + private final Map toPackMap = CacheBuilder.newBuilder().softValues().build().asMap(); private final int dimension; From b6bf4427ef077a75ad71314e1c97ff0106f454a0 Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 7 Jul 2023 00:30:07 -0700 Subject: [PATCH 290/405] Use soft references for nether chunk packing queue --- .../elytra/NetherPathfinderContext.java | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index 8e9a862c0..3fd7987e5 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -27,6 +27,7 @@ import net.minecraft.world.chunk.BlockStateContainer; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.storage.ExtendedBlockStorage; +import java.lang.ref.SoftReference; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -47,8 +48,16 @@ public final class NetherPathfinderContext { this.executor = Executors.newSingleThreadExecutor(); } - public void queueForPacking(Chunk chunk) { - this.executor.submit(() -> NetherPathfinder.insertChunkData(this.context, chunk.x, chunk.z, pack(chunk))); + public void queueForPacking(final Chunk chunkIn) { + final SoftReference ref = new SoftReference<>(chunkIn); + this.executor.execute(() -> { + // TODO: Prioritize packing recent chunks and/or ones that the path goes through, + // and prune the oldest chunks per chunkPackerQueueMaxSize + final Chunk chunk = ref.get(); + if (chunk != null) { + NetherPathfinder.insertChunkData(this.context, chunk.x, chunk.z, pack(chunk)); + } + }); } public CompletableFuture pathFindAsync(final BlockPos src, final BlockPos dst) { @@ -74,9 +83,9 @@ public final class NetherPathfinderContext { * @param startX The start X coordinate * @param startY The start Y coordinate * @param startZ The start Z coordinate - * @param endX The end X coordinate - * @param endY The end Y coordinate - * @param endZ The end Z coordinate + * @param endX The end X coordinate + * @param endY The end Y coordinate + * @param endZ The end Z coordinate * @return {@code true} if there is visibility between the points */ public boolean raytrace(final double startX, final double startY, final double startZ, @@ -89,7 +98,7 @@ public final class NetherPathfinderContext { * visibility between the two points. * * @param start The starting point - * @param end The ending point + * @param end The ending point * @return {@code true} if there is visibility between the points */ public boolean raytrace(final Vec3d start, final Vec3d end) { @@ -151,9 +160,7 @@ public final class NetherPathfinderContext { for (int z = 0; z < 16; z++) { for (int x = 0; x < 16; x++) { IBlockState state = bsc.get(x, y1, z); - if (state.getMaterial() != Material.AIR) { - packed[x | (z << 4) | (y << 8)] = true; - } + packed[x | (z << 4) | (y << 8)] = state.getMaterial() != Material.AIR; } } } From 537100a5e59e60eab80715faf8e00b0c0326eea0 Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 7 Jul 2023 10:44:56 -0700 Subject: [PATCH 291/405] Nether seed setting and automatic context reset --- src/api/java/baritone/api/Settings.java | 6 +++++ .../baritone/behavior/ElytraBehavior.java | 23 +++++++++++++------ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 9eed667f9..08fe54d3a 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -1388,6 +1388,12 @@ public final class Settings { */ public final Setting elytraAutoJump = new Setting<>(false); + /** + * The seed used to generate chunks for long distance elytra path-finding in the nether. + * Defaults to 2b2t's nether seed. + */ + public final Setting elytraNetherSeed = new Setting<>(146008555100680L); + /** * A map of lowercase setting field names to their respective setting */ diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 9ff48f3a2..edabf2912 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -66,11 +66,6 @@ import static baritone.utils.BaritoneMath.fastFloor; public final class ElytraBehavior extends Behavior implements IElytraBehavior, Helper { - /** - * 2b2t seed - */ - private static final long NETHER_SEED = 146008555100680L; - // Used exclusively for PathRenderer public List> clearLines; public List> blockedLines; @@ -79,7 +74,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H public List visiblePath; // :sunglasses: - private final NetherPathfinderContext context; + private NetherPathfinderContext context; private final PathManager pathManager; private final ElytraProcess process; @@ -113,7 +108,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H public ElytraBehavior(Baritone baritone) { super(baritone); - this.context = new NetherPathfinderContext(NETHER_SEED); this.clearLines = new CopyOnWriteArrayList<>(); this.blockedLines = new CopyOnWriteArrayList<>(); this.pathManager = this.new PathManager(); @@ -439,6 +433,21 @@ 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) { + if (this.context != null) { + this.context.destroy(); + } + this.context = new NetherPathfinderContext(netherSeed); + + if (this.isActive()) { + // TODO: Re-pack chunks? + logDirect("Nether seed changed, recalculating path"); + this.pathManager.pathToDestination(); + } + } + // Certified mojang employee incident if (this.remainingFireworkTicks > 0) { this.remainingFireworkTicks--; From bfb4ffcafcf5c51cfe25791f8e61f93e92baa088 Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 7 Jul 2023 11:19:18 -0700 Subject: [PATCH 292/405] Reset context on world load/unload --- .../baritone/behavior/ElytraBehavior.java | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index edabf2912..98bcf7a3f 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -23,6 +23,7 @@ import baritone.api.behavior.IElytraBehavior; import baritone.api.behavior.look.IAimProcessor; import baritone.api.behavior.look.ITickableAimProcessor; import baritone.api.event.events.*; +import baritone.api.event.events.type.EventState; import baritone.api.pathing.goals.Goal; import baritone.api.pathing.goals.GoalYLevel; import baritone.api.pathing.movement.IMovement; @@ -75,6 +76,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // :sunglasses: private NetherPathfinderContext context; + private boolean forceResetContext; private final PathManager pathManager; private final ElytraProcess process; @@ -363,6 +365,24 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } + @Override + public void onWorldEvent(WorldEvent event) { + 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; + } + } else { + if (event.getState() == EventState.POST) { + // Exiting the world, just destroy and invalidate the context + if (this.context != null) { + this.context.destroy(); + this.context = null; + } + } + } + } + @Override public void onChunkEvent(ChunkEvent event) { if (event.isPostPopulate()) { @@ -435,11 +455,12 @@ 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) { + if (this.context == null || this.context.getSeed() != netherSeed || this.forceResetContext) { if (this.context != null) { this.context.destroy(); } this.context = new NetherPathfinderContext(netherSeed); + this.forceResetContext = false; if (this.isActive()) { // TODO: Re-pack chunks? From 308b9bbfea2e58b44c4f1edae35f247de2557112 Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 7 Jul 2023 13:26:43 -0700 Subject: [PATCH 293/405] Apply minimum fall height to regular falls too --- src/main/java/baritone/behavior/ElytraBehavior.java | 1 + .../baritone/pathing/movement/CalculationContext.java | 2 ++ .../pathing/movement/movements/MovementDescend.java | 9 +++++---- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 98bcf7a3f..6374e7524 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -1399,6 +1399,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H public WalkOffCalculationContext(IBaritone baritone) { super(baritone, true); this.allowFallIntoLava = true; + this.minFallHeight = 8; this.maxFallHeightNoWater = 10000; } diff --git a/src/main/java/baritone/pathing/movement/CalculationContext.java b/src/main/java/baritone/pathing/movement/CalculationContext.java index 2e7db9946..75b6acd9b 100644 --- a/src/main/java/baritone/pathing/movement/CalculationContext.java +++ b/src/main/java/baritone/pathing/movement/CalculationContext.java @@ -71,6 +71,7 @@ public class CalculationContext { public final boolean allowDiagonalDescend; public final boolean allowDiagonalAscend; public final boolean allowDownward; + public int minFallHeight; public int maxFallHeightNoWater; public final int maxFallHeightBucket; public final double waterWalkSpeed; @@ -111,6 +112,7 @@ public class CalculationContext { this.allowDiagonalDescend = Baritone.settings().allowDiagonalDescend.value; this.allowDiagonalAscend = Baritone.settings().allowDiagonalAscend.value; this.allowDownward = Baritone.settings().allowDownward.value; + this.minFallHeight = 3; // Minimum fall height used by MovementFall this.maxFallHeightNoWater = Baritone.settings().maxFallHeightNoWater.value; this.maxFallHeightBucket = Baritone.settings().maxFallHeightBucket.value; int depth = EnchantmentHelper.getDepthStriderModifier(player); diff --git a/src/main/java/baritone/pathing/movement/movements/MovementDescend.java b/src/main/java/baritone/pathing/movement/movements/MovementDescend.java index 51275bc00..032171fe9 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementDescend.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementDescend.java @@ -154,10 +154,11 @@ public class MovementDescend extends Movement { // this check prevents it from getting the block at y=-1 and crashing return false; } + boolean reachedMinimum = fallHeight >= context.minFallHeight; IBlockState ontoBlock = context.get(destX, newY, destZ); int unprotectedFallHeight = fallHeight - (y - effectiveStartHeight); // equal to fallHeight - y + effectiveFallHeight, which is equal to -newY + effectiveFallHeight, which is equal to effectiveFallHeight - newY double tentativeCost = WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[unprotectedFallHeight] + frontBreak + costSoFar; - if (MovementHelper.isWater(ontoBlock.getBlock())) { + if (reachedMinimum && MovementHelper.isWater(ontoBlock.getBlock())) { if (!MovementHelper.canWalkThrough(context, destX, newY, destZ, ontoBlock)) { return false; } @@ -178,7 +179,7 @@ public class MovementDescend extends Movement { res.cost = tentativeCost;// TODO incorporate water swim up cost? return false; } - if (fallHeight >= 8 && context.allowFallIntoLava && MovementHelper.isLava(ontoBlock.getBlock())) { + if (reachedMinimum && context.allowFallIntoLava && MovementHelper.isLava(ontoBlock.getBlock())) { // found a fall into lava res.x = destX; res.y = newY; @@ -203,7 +204,7 @@ public class MovementDescend extends Movement { if (MovementHelper.isBottomSlab(ontoBlock)) { return false; // falling onto a half slab is really glitchy, and can cause more fall damage than we'd expect } - if (unprotectedFallHeight <= context.maxFallHeightNoWater + 1) { + if (reachedMinimum && unprotectedFallHeight <= context.maxFallHeightNoWater + 1) { // fallHeight = 4 means onto.up() is 3 blocks down, which is the max res.x = destX; res.y = newY + 1; @@ -211,7 +212,7 @@ public class MovementDescend extends Movement { res.cost = tentativeCost; return false; } - if (context.hasWaterBucket && unprotectedFallHeight <= context.maxFallHeightBucket + 1) { + if (reachedMinimum && context.hasWaterBucket && unprotectedFallHeight <= context.maxFallHeightBucket + 1) { res.x = destX; res.y = newY + 1;// this is the block we're falling onto, so dest is +1 res.z = destZ; From fe67489419dd3025e74e6700636814adf1dfb3ac Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 7 Jul 2023 14:38:11 -0700 Subject: [PATCH 294/405] Combine `VALIDATE_PATH` and `LOCATE_JUMP` states --- src/main/java/baritone/behavior/ElytraBehavior.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 6374e7524..f08fb9be6 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -1278,11 +1278,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H if (this.goal == null) { this.goal = new GoalYLevel(31); } - this.state = State.VALIDATE_PATH; - return new PathingCommandContext(this.goal, PathingCommandType.SET_GOAL_AND_PAUSE, new WalkOffCalculationContext(baritone)); - } - - if (this.state == State.VALIDATE_PATH) { final IPathExecutor executor = baritone.getPathingBehavior().getCurrent(); if (executor != null && executor.getPath().getGoal() == this.goal) { final IMovement fall = executor.getPath().movements().stream() @@ -1315,7 +1310,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } } - return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); + return new PathingCommandContext(this.goal, PathingCommandType.SET_GOAL_AND_PAUSE, new WalkOffCalculationContext(baritone)); } // yucky @@ -1373,8 +1368,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H switch (this.state) { case LOCATE_JUMP: return "Finding spot to jump off"; - case VALIDATE_PATH: - return "Validating path"; case PAUSE: return "Waiting for elytra path"; case GET_TO_JUMP: From 487b3a759aaebaae9bd5c757261a0376cc54dff5 Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 7 Jul 2023 18:35:02 -0700 Subject: [PATCH 295/405] `mostRecentGoal`, fixes immediate goal clear --- .../java/baritone/api/process/ICustomGoalProcess.java | 5 +++++ .../java/baritone/command/defaults/ElytraCommand.java | 2 +- src/main/java/baritone/process/CustomGoalProcess.java | 11 +++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/api/java/baritone/api/process/ICustomGoalProcess.java b/src/api/java/baritone/api/process/ICustomGoalProcess.java index 5084aff2f..2bae55ce3 100644 --- a/src/api/java/baritone/api/process/ICustomGoalProcess.java +++ b/src/api/java/baritone/api/process/ICustomGoalProcess.java @@ -38,6 +38,11 @@ public interface ICustomGoalProcess extends IBaritoneProcess { */ Goal getGoal(); + /** + * @return The most recent set goal, which doesn't invalidate upon {@link #onLostControl()} + */ + Goal mostRecentGoal(); + /** * Sets the goal and begins the path execution. * diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index 93c4c2544..cd7034ef8 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -42,7 +42,7 @@ public class ElytraCommand extends Command { public void execute(String label, IArgConsumer args) throws CommandException { ICustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess(); args.requireMax(0); - Goal iGoal = customGoalProcess.getGoal(); + Goal iGoal = customGoalProcess.mostRecentGoal(); if (iGoal == null) { throw new CommandInvalidStateException("No goal has been set"); } diff --git a/src/main/java/baritone/process/CustomGoalProcess.java b/src/main/java/baritone/process/CustomGoalProcess.java index ea9ff2092..71d212b38 100644 --- a/src/main/java/baritone/process/CustomGoalProcess.java +++ b/src/main/java/baritone/process/CustomGoalProcess.java @@ -36,6 +36,11 @@ public final class CustomGoalProcess extends BaritoneProcessHelper implements IC */ private Goal goal; + /** + * The most recent goal. Not invalidated upon {@link #onLostControl()} + */ + private Goal mostRecentGoal; + /** * The current process state. * @@ -50,6 +55,7 @@ public final class CustomGoalProcess extends BaritoneProcessHelper implements IC @Override public void setGoal(Goal goal) { this.goal = goal; + this.mostRecentGoal = goal; if (this.state == State.NONE) { this.state = State.GOAL_SET; } @@ -68,6 +74,11 @@ public final class CustomGoalProcess extends BaritoneProcessHelper implements IC return this.goal; } + @Override + public Goal mostRecentGoal() { + return this.mostRecentGoal; + } + @Override public boolean isActive() { return this.state != State.NONE; From c0cdfb7781e86b9c89bae4c9930d3a0461fb8512 Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 7 Jul 2023 19:44:59 -0700 Subject: [PATCH 296/405] Add commands for pathfinder reset and chunk repack --- .../api/behavior/IElytraBehavior.java | 12 ++++ .../baritone/behavior/ElytraBehavior.java | 30 +++++++-- .../command/defaults/ElytraCommand.java | 67 +++++++++++++------ 3 files changed, 80 insertions(+), 29 deletions(-) diff --git a/src/api/java/baritone/api/behavior/IElytraBehavior.java b/src/api/java/baritone/api/behavior/IElytraBehavior.java index 3c3b91466..21169b896 100644 --- a/src/api/java/baritone/api/behavior/IElytraBehavior.java +++ b/src/api/java/baritone/api/behavior/IElytraBehavior.java @@ -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 resetContext(); + + void repackChunks(); + void pathTo(BlockPos destination); void cancel(); diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index f08fb9be6..5549281f7 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -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 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 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(); } diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index cd7034ef8..de8cbadef 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -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 From 7a935fb2ea3cf491497b09b7a73b51a27f9ae83c Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 9 Jul 2023 09:12:21 -0700 Subject: [PATCH 297/405] Fix simulation not respecting `ignoreLava` --- build.gradle | 4 ++-- src/main/java/baritone/behavior/ElytraBehavior.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 99d7cc823..686f2bfbc 100755 --- a/build.gradle +++ b/build.gradle @@ -175,9 +175,9 @@ dependencies { transitive = false } launchAnnotationProcessor 'org.spongepowered:mixin:0.8.4-SNAPSHOT:processor' - launchImplementation('dev.babbaj:nether-pathfinder:0.21') + launchImplementation('dev.babbaj:nether-pathfinder:0.22') testImplementation 'junit:junit:4.12' - implementation 'dev.babbaj:nether-pathfinder:0.21' + implementation 'dev.babbaj:nether-pathfinder:0.22' } mixin { diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 5549281f7..bc2485b47 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -386,7 +386,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H @Override public void onChunkEvent(ChunkEvent event) { - if (event.isPostPopulate()) { + if (event.isPostPopulate() && this.context != null) { final Chunk chunk = ctx.world().getChunk(event.getX(), event.getZ()); this.context.queueForPacking(chunk); } @@ -1069,13 +1069,13 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // Ensure that the goal is visible along the entire simulated path // Reverse order iteration since the last position is most likely to fail for (int i = result.steps.size() - 1; i >= 1; i--) { - if (!clearView(context.start.add(result.steps.get(i)), goal, false)) { + if (!clearView(context.start.add(result.steps.get(i)), goal, context.ignoreLava)) { continue outer; } } } else { // Ensure that the goal is visible from the final position - if (!clearView(context.start.add(result.steps.get(result.steps.size() - 1)), goal, false)) { + if (!clearView(context.start.add(result.steps.get(result.steps.size() - 1)), goal, context.ignoreLava)) { continue; } } From 96a64b454ed62dab970afbe75e31f695ecd3b8a1 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sun, 9 Jul 2023 22:29:31 -0400 Subject: [PATCH 298/405] optimize uploading chunk data --- build.gradle | 4 +- .../elytra/NetherPathfinderContext.java | 60 ++++++++++++++++++- 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 686f2bfbc..da0e2232b 100755 --- a/build.gradle +++ b/build.gradle @@ -175,9 +175,9 @@ dependencies { transitive = false } launchAnnotationProcessor 'org.spongepowered:mixin:0.8.4-SNAPSHOT:processor' - launchImplementation('dev.babbaj:nether-pathfinder:0.22') + launchImplementation('dev.babbaj:nether-pathfinder:0.24') + implementation 'dev.babbaj:nether-pathfinder:0.24' testImplementation 'junit:junit:4.12' - implementation 'dev.babbaj:nether-pathfinder:0.22' } mixin { diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index 3fd7987e5..ed179b5b4 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -17,10 +17,14 @@ package baritone.behavior.elytra; +import baritone.utils.accessor.IBitArray; +import baritone.utils.accessor.IBlockStateContainer; import dev.babbaj.pathfinder.NetherPathfinder; +import dev.babbaj.pathfinder.Octree; import dev.babbaj.pathfinder.PathSegment; -import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.BitArray; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.chunk.BlockStateContainer; @@ -55,7 +59,8 @@ public final class NetherPathfinderContext { // and prune the oldest chunks per chunkPackerQueueMaxSize final Chunk chunk = ref.get(); if (chunk != null) { - NetherPathfinder.insertChunkData(this.context, chunk.x, chunk.z, pack(chunk)); + long ptr = NetherPathfinder.getOrCreateChunk(this.context, chunk.x, chunk.z); + writeChunkData(chunk, ptr); } }); } @@ -144,6 +149,8 @@ public final class NetherPathfinderContext { return this.seed; } + private static final IBlockState AIR_BLOCK_STATE = Blocks.AIR.getDefaultState(); + private static boolean[] pack(Chunk chunk) { try { boolean[] packed = new boolean[16 * 16 * 128]; @@ -160,7 +167,7 @@ public final class NetherPathfinderContext { for (int z = 0; z < 16; z++) { for (int x = 0; x < 16; x++) { IBlockState state = bsc.get(x, y1, z); - packed[x | (z << 4) | (y << 8)] = state.getMaterial() != Material.AIR; + packed[x | (z << 4) | (y << 8)] = state != AIR_BLOCK_STATE; } } } @@ -172,6 +179,53 @@ public final class NetherPathfinderContext { } } + private static void writeChunkData(Chunk chunk, long ptr) { + try { + ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray(); + for (int y0 = 0; y0 < 8; y0++) { + final ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0]; + if (extendedblockstorage == null) { + continue; + } + final BlockStateContainer bsc = extendedblockstorage.getData(); + final int airId = ((IBlockStateContainer) bsc).getPalette().idFor(AIR_BLOCK_STATE); + // pasted from FasterWorldScanner + final BitArray array = ((IBlockStateContainer) bsc).getStorage(); + if (array == null) continue; + final long[] longArray = array.getBackingLongArray(); + final int arraySize = array.size(); + final int bitsPerEntry = ((IBitArray) array).getBitsPerEntry(); + final long maxEntryValue = ((IBitArray) array).getMaxEntryValue(); + + final int yReal = y0 << 4; + for (int idx = 0, kl = bitsPerEntry - 1; idx < arraySize; idx++, kl += bitsPerEntry) { + final int i = idx * bitsPerEntry; + final int j = i >> 6; + final int l = i & 63; + final int k = kl >> 6; + final long jl = longArray[j] >>> l; + + final int id; + if (j == k) { + id = (int) (jl & maxEntryValue); + } else { + id = (int) ((jl | longArray[k] << (64 - l)) & maxEntryValue); + } + Octree.setBlock(ptr, + ((idx & 255) & 15), + yReal + (idx >> 8), + ((idx & 255) >> 4), + id != airId + ); + } + } + Octree.setIsFromJava(ptr); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + public static final class Visibility { public static final int ALL = 0; From eec4edea059416188daca4f2f6e429a87799c38e Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 9 Jul 2023 20:00:35 -0700 Subject: [PATCH 299/405] Remove old pack method --- .../elytra/NetherPathfinderContext.java | 32 ++----------------- 1 file changed, 2 insertions(+), 30 deletions(-) diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index ed179b5b4..b4f3daa9a 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -42,6 +42,8 @@ import java.util.concurrent.TimeUnit; */ public final class NetherPathfinderContext { + private static final IBlockState AIR_BLOCK_STATE = Blocks.AIR.getDefaultState(); + private final long context; private final long seed; private final ExecutorService executor; @@ -149,36 +151,6 @@ public final class NetherPathfinderContext { return this.seed; } - private static final IBlockState AIR_BLOCK_STATE = Blocks.AIR.getDefaultState(); - - private static boolean[] pack(Chunk chunk) { - try { - boolean[] packed = new boolean[16 * 16 * 128]; - ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray(); - for (int y0 = 0; y0 < 8; y0++) { - ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0]; - if (extendedblockstorage == null) { - continue; - } - BlockStateContainer bsc = extendedblockstorage.getData(); - int yReal = y0 << 4; - for (int y1 = 0; y1 < 16; y1++) { - int y = y1 | yReal; - for (int z = 0; z < 16; z++) { - for (int x = 0; x < 16; x++) { - IBlockState state = bsc.get(x, y1, z); - packed[x | (z << 4) | (y << 8)] = state != AIR_BLOCK_STATE; - } - } - } - } - return packed; - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - private static void writeChunkData(Chunk chunk, long ptr) { try { ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray(); From dc53a95befb002a01d8d75b5de2755e485754323 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Mon, 10 Jul 2023 00:45:12 -0400 Subject: [PATCH 300/405] don't send the whole chunk for small changes --- .../api/event/events/BlockChangeEvent.java | 8 ++++---- .../java/baritone/behavior/ElytraBehavior.java | 4 +--- .../behavior/elytra/NetherPathfinderContext.java | 16 ++++++++++++++++ .../java/baritone/event/GameEventHandler.java | 6 +++--- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/api/java/baritone/api/event/events/BlockChangeEvent.java b/src/api/java/baritone/api/event/events/BlockChangeEvent.java index 152c435ae..a65a51f35 100644 --- a/src/api/java/baritone/api/event/events/BlockChangeEvent.java +++ b/src/api/java/baritone/api/event/events/BlockChangeEvent.java @@ -31,16 +31,16 @@ import java.util.Set; */ public final class BlockChangeEvent { - private final Set affectedChunks; + private final ChunkPos chunk; private final List> blocks; public BlockChangeEvent(ChunkPos pos, List> blocks) { - this.affectedChunks = Collections.singleton(pos); + this.chunk = pos; this.blocks = blocks; } - public Set getAffectedChunks() { - return this.affectedChunks; + public ChunkPos getChunkPos() { + return this.chunk; } public List> getBlocks() { diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index bc2485b47..93bcbb5bf 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -394,9 +394,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H @Override public void onBlockChange(BlockChangeEvent event) { - event.getAffectedChunks().stream() - .map(pos -> ctx.world().getChunk(pos.x, pos.z)) - .forEach(this.context::queueForPacking); + this.context.queueBlockUpdate(event); } @Override diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index ed179b5b4..aaa4c62bf 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -17,6 +17,7 @@ package baritone.behavior.elytra; +import baritone.api.event.events.BlockChangeEvent; import baritone.utils.accessor.IBitArray; import baritone.utils.accessor.IBlockStateContainer; import dev.babbaj.pathfinder.NetherPathfinder; @@ -26,6 +27,7 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.util.BitArray; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.chunk.BlockStateContainer; import net.minecraft.world.chunk.Chunk; @@ -65,6 +67,20 @@ public final class NetherPathfinderContext { }); } + public void queueBlockUpdate(BlockChangeEvent event) { + this.executor.execute(() -> { + ChunkPos chunkPos = event.getChunkPos(); + long ptr = NetherPathfinder.getChunkPointer(this.context, chunkPos.x, chunkPos.z); + if (ptr == 0) return; // this shouldn't ever happen + event.getBlocks().forEach(pair -> { + BlockPos pos = pair.first(); + if (pos.getY() >= 128) return; + boolean isSolid = pair.second() != AIR_BLOCK_STATE; + Octree.setBlock(ptr, pos.getX() & 15, pos.getY(), pos.getZ() & 15, isSolid); + }); + }); + } + public CompletableFuture pathFindAsync(final BlockPos src, final BlockPos dst) { return CompletableFuture.supplyAsync(() -> { final PathSegment segment = NetherPathfinder.pathFind( diff --git a/src/main/java/baritone/event/GameEventHandler.java b/src/main/java/baritone/event/GameEventHandler.java index d26f2de24..1027a0126 100644 --- a/src/main/java/baritone/event/GameEventHandler.java +++ b/src/main/java/baritone/event/GameEventHandler.java @@ -28,6 +28,7 @@ import baritone.cache.CachedChunk; import baritone.cache.WorldProvider; import baritone.utils.BlockStateInterface; import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.ChunkPos; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; @@ -117,9 +118,8 @@ public final class GameEventHandler implements IEventBus, Helper { if (keepingTrackOf) { baritone.getWorldProvider().ifWorldLoaded(worldData -> { final World world = baritone.getPlayerContext().world(); - event.getAffectedChunks().stream() - .map(pos -> world.getChunk(pos.x, pos.z)) - .forEach(worldData.getCachedWorld()::queueForPacking); + ChunkPos pos = event.getChunkPos(); + worldData.getCachedWorld().queueForPacking(world.getChunk(pos.x, pos.z)); }); } } From 5dc403e643c9f641373b7e8889badd28281eeefb Mon Sep 17 00:00:00 2001 From: Leijurv Date: Mon, 10 Jul 2023 00:12:10 -0700 Subject: [PATCH 301/405] crucial performance optimization --- .../baritone/behavior/ElytraBehavior.java | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 93bcbb5bf..ec2363f29 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -33,8 +33,8 @@ import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommandType; import baritone.api.utils.*; import baritone.api.utils.input.Input; -import baritone.behavior.elytra.NetherPathfinderContext; import baritone.behavior.elytra.NetherPath; +import baritone.behavior.elytra.NetherPathfinderContext; import baritone.behavior.elytra.PathCalculationException; import baritone.behavior.elytra.UnpackedSegment; import baritone.pathing.movement.CalculationContext; @@ -54,7 +54,10 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.play.server.SPacketPlayerPosLook; import net.minecraft.util.EnumHand; -import net.minecraft.util.math.*; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.chunk.Chunk; import java.util.*; @@ -716,9 +719,9 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H public final IAimProcessor aimProcessor; public SolverContext(boolean async) { - this.path = ElytraBehavior.this.pathManager.getPath(); + this.path = ElytraBehavior.this.pathManager.getPath(); this.playerNear = ElytraBehavior.this.pathManager.getNear(); - this.start = ElytraBehavior.this.ctx.playerFeetAsVec(); + this.start = ElytraBehavior.this.ctx.playerFeetAsVec(); this.ignoreLava = ElytraBehavior.this.ctx.player().isInLava(); final Integer fireworkTicksExisted; @@ -863,10 +866,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private Optional getAttachedFirework() { return ctx.world().loadedEntityList.stream() - .filter(x -> x instanceof EntityFireworkRocket) - .filter(x -> Objects.equals(((IEntityFireworkRocket) x).getBoostedEntity(), ctx.player())) - .map(x -> (EntityFireworkRocket) x) - .findFirst(); + .filter(x -> x instanceof EntityFireworkRocket) + .filter(x -> Objects.equals(((IEntityFireworkRocket) x).getBoostedEntity(), ctx.player())) + .map(x -> (EntityFireworkRocket) x) + .findFirst(); } private boolean isHitboxClear(final SolverContext context, final Vec3d dest, final Double growAmount) { @@ -1113,9 +1116,15 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // Collision box while the player is in motion, with additional padding for safety final AxisAlignedBB inMotion = hitbox.expand(motion.x, motion.y, motion.z).grow(0.01); - for (int x = fastFloor(inMotion.minX); x < fastCeil(inMotion.maxX); x++) { - for (int y = fastFloor(inMotion.minY); y < fastCeil(inMotion.maxY); y++) { - for (int z = fastFloor(inMotion.minZ); z < fastCeil(inMotion.maxZ); z++) { + int xmin = fastFloor(inMotion.minX); + int xmax = fastCeil(inMotion.maxX); + int ymin = fastFloor(inMotion.minY); + int ymax = fastCeil(inMotion.maxY); + int zmin = fastFloor(inMotion.minZ); + int zmax = fastCeil(inMotion.maxZ); + for (int x = xmin; x < xmax; x++) { + for (int y = ymin; y < ymax; y++) { + for (int z = zmin; z < zmax; z++) { if (!this.passable(x, y, z, ignoreLava)) { return null; } From 349c951b5538d8f6b0eb653e99792d99f3f5dde1 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 11 Jul 2023 22:47:09 -0500 Subject: [PATCH 302/405] Better handling of unsupported systems --- .../api/behavior/IElytraBehavior.java | 10 +++ src/main/java/baritone/Baritone.java | 5 +- .../baritone/behavior/ElytraBehavior.java | 72 ++++++++++++++++--- .../elytra/NetherPathfinderContext.java | 4 ++ .../behavior/elytra/NullElytraBehavior.java | 70 ++++++++++++++++++ .../command/defaults/ElytraCommand.java | 11 +++ src/main/java/baritone/utils/IRenderer.java | 13 ++++ .../java/baritone/utils/PathRenderer.java | 59 +-------------- 8 files changed, 177 insertions(+), 67 deletions(-) create mode 100644 src/main/java/baritone/behavior/elytra/NullElytraBehavior.java diff --git a/src/api/java/baritone/api/behavior/IElytraBehavior.java b/src/api/java/baritone/api/behavior/IElytraBehavior.java index 21169b896..95ae62926 100644 --- a/src/api/java/baritone/api/behavior/IElytraBehavior.java +++ b/src/api/java/baritone/api/behavior/IElytraBehavior.java @@ -41,4 +41,14 @@ public interface IElytraBehavior extends IBehavior { * Returns {@code true} if the current {@link IElytraBehavior} is actively pathing. */ boolean isActive(); + + /** + * @return {@code true} if the native library loaded and elytra is actually usable + */ + boolean isLoaded(); + + /* + * FOR INTERNAL USE ONLY. MAY BE REMOVED AT ANY TIME. + */ + boolean isSafeToCancel(); } diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index 805fb0488..970bfc0a9 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -21,6 +21,7 @@ import baritone.api.BaritoneAPI; import baritone.api.IBaritone; import baritone.api.Settings; import baritone.api.behavior.IBehavior; +import baritone.api.behavior.IElytraBehavior; import baritone.api.event.listener.IEventBus; import baritone.api.process.IBaritoneProcess; import baritone.api.utils.IPlayerContext; @@ -107,7 +108,7 @@ public class Baritone implements IBaritone { { this.lookBehavior = this.registerBehavior(LookBehavior::new); - this.elytraBehavior = this.registerBehavior(ElytraBehavior::new); + this.elytraBehavior = this.registerBehavior(ElytraBehavior::create); this.pathingBehavior = this.registerBehavior(PathingBehavior::new); this.inventoryBehavior = this.registerBehavior(InventoryBehavior::new); this.inputOverrideHandler = this.registerBehavior(InputOverrideHandler::new); @@ -240,7 +241,7 @@ public class Baritone implements IBaritone { } @Override - public ElytraBehavior getElytraBehavior() { + public IElytraBehavior getElytraBehavior() { return this.elytraBehavior; } diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index ec2363f29..7fc47032b 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -19,12 +19,14 @@ package baritone.behavior; import baritone.Baritone; import baritone.api.IBaritone; +import baritone.api.Settings; import baritone.api.behavior.IElytraBehavior; import baritone.api.behavior.look.IAimProcessor; import baritone.api.behavior.look.ITickableAimProcessor; import baritone.api.event.events.*; import baritone.api.event.events.type.EventState; import baritone.api.pathing.goals.Goal; +import baritone.api.pathing.goals.GoalBlock; import baritone.api.pathing.goals.GoalYLevel; import baritone.api.pathing.movement.IMovement; import baritone.api.pathing.path.IPathExecutor; @@ -33,13 +35,12 @@ import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommandType; import baritone.api.utils.*; import baritone.api.utils.input.Input; -import baritone.behavior.elytra.NetherPath; -import baritone.behavior.elytra.NetherPathfinderContext; -import baritone.behavior.elytra.PathCalculationException; -import baritone.behavior.elytra.UnpackedSegment; +import baritone.behavior.elytra.*; import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.movements.MovementFall; import baritone.utils.BlockStateInterface; +import baritone.utils.IRenderer; +import baritone.utils.PathRenderer; import baritone.utils.PathingCommandContext; import baritone.utils.accessor.IChunkProviderClient; import baritone.utils.accessor.IEntityFireworkRocket; @@ -60,7 +61,9 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraft.world.chunk.Chunk; +import java.awt.*; import java.util.*; +import java.util.List; import java.util.concurrent.*; import java.util.function.Supplier; import java.util.function.UnaryOperator; @@ -112,7 +115,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private Solution pendingSolution; private boolean solveNextTick; - public ElytraBehavior(Baritone baritone) { + private ElytraBehavior(Baritone baritone) { super(baritone); this.clearLines = new CopyOnWriteArrayList<>(); this.blockedLines = new CopyOnWriteArrayList<>(); @@ -369,6 +372,45 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } + @Override + public void onRenderPass(RenderEvent event) { + final Settings settings = Baritone.settings(); + if (this.visiblePath != null) { + PathRenderer.drawPath(this.visiblePath, 0, Color.RED, false, 0, 0, 0.0D); + } + if (this.aimPos != null) { + PathRenderer.drawGoal(ctx.player(), new GoalBlock(this.aimPos), event.getPartialTicks(), Color.GREEN); + } + if (!this.clearLines.isEmpty() && settings.renderRaytraces.value) { + IRenderer.startLines(Color.GREEN, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); + for (Pair line : this.clearLines) { + IRenderer.emitLine(line.first(), line.second()); + } + IRenderer.endLines(settings.renderPathIgnoreDepth.value); + } + if (!this.blockedLines.isEmpty() && Baritone.settings().renderRaytraces.value) { + IRenderer.startLines(Color.BLUE, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); + for (Pair line : this.blockedLines) { + IRenderer.emitLine(line.first(), line.second()); + } + IRenderer.endLines(settings.renderPathIgnoreDepth.value); + } + if (this.simulationLine != null && Baritone.settings().renderElytraSimulation.value) { + IRenderer.startLines(new Color(0x36CCDC), settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); + final Vec3d offset = new Vec3d( + ctx.player().prevPosX + (ctx.player().posX - ctx.player().prevPosX) * event.getPartialTicks(), + ctx.player().prevPosY + (ctx.player().posY - ctx.player().prevPosY) * event.getPartialTicks(), + ctx.player().prevPosZ + (ctx.player().posZ - ctx.player().prevPosZ) * event.getPartialTicks() + ); + for (int i = 0; i < this.simulationLine.size() - 1; i++) { + final Vec3d src = this.simulationLine.get(i).add(offset); + final Vec3d dst = this.simulationLine.get(i + 1).add(offset); + IRenderer.emitLine(src, dst); + } + IRenderer.endLines(settings.renderPathIgnoreDepth.value); + } + } + @Override public void onWorldEvent(WorldEvent event) { if (event.getWorld() != null) { @@ -451,6 +493,16 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H .filter(process -> this.process == process).isPresent(); } + @Override + public boolean isLoaded() { + return true; + } + + @Override + public boolean isSafeToCancel() { + return !this.isActive() || !(this.process.state == State.FLYING || this.process.state == State.START_FLYING); + } + @Override public void onTick(final TickEvent event) { if (event.getType() == TickEvent.Type.OUT) { @@ -1261,10 +1313,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } - public boolean isSafeToCancel() { - return !this.isActive() || !(this.process.state == State.FLYING || this.process.state == State.START_FLYING); - } - private final class ElytraProcess implements IBaritoneProcess { private State state; @@ -1443,4 +1491,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H START_FLYING, FLYING } + + public static T create(final Baritone baritone) { + return (T) (NetherPathfinderContext.isSupported() + ? new ElytraBehavior(baritone) + : new NullElytraBehavior(baritone)); + } } diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index a30cb4aa1..9bbb2a24a 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -222,4 +222,8 @@ public final class NetherPathfinderContext { private Visibility() {} } + + public static boolean isSupported() { + return NetherPathfinder.isThisSystemSupported(); + } } diff --git a/src/main/java/baritone/behavior/elytra/NullElytraBehavior.java b/src/main/java/baritone/behavior/elytra/NullElytraBehavior.java new file mode 100644 index 000000000..b173d82b8 --- /dev/null +++ b/src/main/java/baritone/behavior/elytra/NullElytraBehavior.java @@ -0,0 +1,70 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.behavior.elytra; + +import baritone.Baritone; +import baritone.api.behavior.IElytraBehavior; +import baritone.behavior.Behavior; +import net.minecraft.util.math.BlockPos; + +import java.util.concurrent.CompletableFuture; + +/** + * @author Brady + */ +public final class NullElytraBehavior extends Behavior implements IElytraBehavior { + + public NullElytraBehavior(Baritone baritone) { + super(baritone); + } + + @Override + public CompletableFuture resetContext() { + throw new UnsupportedOperationException("Called resetContext() on NullElytraBehavior"); + } + + @Override + public void repackChunks() { + throw new UnsupportedOperationException("Called repackChunks() on NullElytraBehavior"); + } + + @Override + public void pathTo(BlockPos destination) { + throw new UnsupportedOperationException("Called pathTo() on NullElytraBehavior"); + } + + @Override + public void cancel() { + throw new UnsupportedOperationException("Called cancel() on NullElytraBehavior"); + } + + @Override + public boolean isActive() { + return false; + } + + @Override + public boolean isLoaded() { + return false; + } + + @Override + public boolean isSafeToCancel() { + return true; + } +} diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index de8cbadef..252559b75 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -43,6 +43,17 @@ public class ElytraCommand extends Command { public void execute(String label, IArgConsumer args) throws CommandException { final ICustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess(); final IElytraBehavior elytra = baritone.getElytraBehavior(); + if (!elytra.isLoaded()) { + final String osArch = System.getProperty("os.arch"); + final String osName = System.getProperty("os.name"); + throw new CommandInvalidStateException(String.format( + "legacy architectures are not supported. your CPU is %s and your operating system is %s." + + "supported architectures are x86_64 or arm64, supported operating systems are windows," + + "linux, and mac", + osArch, osName + )); + } + if (!args.hasAny()) { Goal iGoal = customGoalProcess.mostRecentGoal(); if (iGoal == null) { diff --git a/src/main/java/baritone/utils/IRenderer.java b/src/main/java/baritone/utils/IRenderer.java index 680d7e380..3fd5c2556 100644 --- a/src/main/java/baritone/utils/IRenderer.java +++ b/src/main/java/baritone/utils/IRenderer.java @@ -27,6 +27,7 @@ import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.Vec3d; import java.awt.*; @@ -120,4 +121,16 @@ public interface IRenderer { emitAABB(aabb); tessellator.draw(); } + + static void emitLine(Vec3d start, Vec3d end) { + emitLine(start.x, start.y, start.z, end.x, end.y, end.z); + } + + static void emitLine(double x1, double y1, double z1, double x2, double y2, double z2) { + double vpX = renderManager.viewerPosX; + double vpY = renderManager.viewerPosY; + double vpZ = renderManager.viewerPosZ; + buffer.pos(x1 - vpX, y1 - vpY, z1 - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(x2 - vpX, y2 - vpY, z2 - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + } } diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index eb7615de8..0fcad054a 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -17,15 +17,12 @@ package baritone.utils; -import baritone.Baritone; import baritone.api.BaritoneAPI; import baritone.api.event.events.RenderEvent; import baritone.api.pathing.goals.*; import baritone.api.utils.BetterBlockPos; import baritone.api.utils.IPlayerContext; -import baritone.api.utils.Pair; import baritone.api.utils.interfaces.IGoalRenderPos; -import baritone.behavior.ElytraBehavior; import baritone.behavior.PathingBehavior; import baritone.pathing.path.PathExecutor; import net.minecraft.block.state.IBlockState; @@ -102,44 +99,6 @@ public final class PathRenderer implements IRenderer { drawPath(next.getPath().positions(), 0, settings.colorNextPath.value, settings.fadePath.value, 10, 20); } - final ElytraBehavior elytra = behavior.baritone.getElytraBehavior(); - - if (elytra.visiblePath != null) { - drawPath(elytra.visiblePath, 0, Color.RED, false, 0, 0, 0.0D); - } - if (elytra.aimPos != null) { - drawGoal(ctx.player(), new GoalBlock(elytra.aimPos), partialTicks, Color.GREEN); - } - if (!elytra.clearLines.isEmpty() && Baritone.settings().renderRaytraces.value) { - IRenderer.startLines(Color.GREEN, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); - for (Pair line : elytra.clearLines) { - emitLine(line.first(), line.second()); - } - IRenderer.endLines(settings.renderPathIgnoreDepth.value); - } - if (!elytra.blockedLines.isEmpty() && Baritone.settings().renderRaytraces.value) { - IRenderer.startLines(Color.BLUE, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); - for (Pair line : elytra.blockedLines) { - emitLine(line.first(), line.second()); - } - IRenderer.endLines(settings.renderPathIgnoreDepth.value); - } - if (elytra.simulationLine != null && Baritone.settings().renderElytraSimulation.value) { - IRenderer.startLines(new Color(0x36CCDC), settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); - final Vec3d offset = new Vec3d( - ctx.player().prevPosX + (ctx.player().posX - ctx.player().prevPosX) * partialTicks, - ctx.player().prevPosY + (ctx.player().posY - ctx.player().prevPosY) * partialTicks, - ctx.player().prevPosZ + (ctx.player().posZ - ctx.player().prevPosZ) * partialTicks - ); - for (int i = 0; i < elytra.simulationLine.size() - 1; i++) { - final Vec3d src = elytra.simulationLine.get(i).add(offset); - final Vec3d dst = elytra.simulationLine.get(i + 1).add(offset); - emitLine(src, dst); - } - IRenderer.endLines(settings.renderPathIgnoreDepth.value); - } - - // If there is a path calculation currently running, render the path calculation process behavior.getInProgress().ifPresent(currentlyRunning -> { currentlyRunning.bestPathSoFar().ifPresent(p -> { @@ -153,11 +112,11 @@ public final class PathRenderer implements IRenderer { }); } - private static void drawPath(List positions, int startIndex, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0) { + public static void drawPath(List positions, int startIndex, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0) { drawPath(positions, startIndex, color, fadeOut, fadeStart0, fadeEnd0, 0.5D); } - private static void drawPath(List positions, int startIndex, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0, double offset) { + public static void drawPath(List positions, int startIndex, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0, double offset) { IRenderer.startLines(color, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); int fadeStart = fadeStart0 + startIndex; @@ -199,18 +158,6 @@ public final class PathRenderer implements IRenderer { IRenderer.endLines(settings.renderPathIgnoreDepth.value); } - private static void emitLine(Vec3d start, Vec3d end) { - emitLine(start.x, start.y, start.z, end.x, end.y, end.z); - } - - private static void emitLine(double x1, double y1, double z1, double x2, double y2, double z2) { - double vpX = renderManager.viewerPosX; - double vpY = renderManager.viewerPosY; - double vpZ = renderManager.viewerPosZ; - buffer.pos(x1 - vpX, y1 - vpY, z1 - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.pos(x2 - vpX, y2 - vpY, z2 - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); - } - private static void emitPathLine(double x1, double y1, double z1, double x2, double y2, double z2, double offset) { final double extraOffset = offset + 0.03D; double vpX = renderManager.viewerPosX; @@ -255,7 +202,7 @@ public final class PathRenderer implements IRenderer { IRenderer.endLines(settings.renderSelectionBoxesIgnoreDepth.value); } - private static void drawGoal(Entity player, Goal goal, float partialTicks, Color color) { + public static void drawGoal(Entity player, Goal goal, float partialTicks, Color color) { drawGoal(player, goal, partialTicks, color, true); } From 7c696b70555a8a759d49565d4ebf6a855ff2cf2a Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 11 Jul 2023 22:49:51 -0500 Subject: [PATCH 303/405] trolled --- src/main/java/baritone/Baritone.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index 970bfc0a9..61866e927 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -68,7 +68,7 @@ public class Baritone implements IBaritone { private final List behaviors; private final PathingBehavior pathingBehavior; - private final ElytraBehavior elytraBehavior; + private final IElytraBehavior elytraBehavior; private final LookBehavior lookBehavior; private final InventoryBehavior inventoryBehavior; private final InputOverrideHandler inputOverrideHandler; From 8f5105c4546560a93f0acf0d0141e8f1b9f2fd3b Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 11 Jul 2023 22:50:35 -0500 Subject: [PATCH 304/405] trolled pt2 --- src/main/java/baritone/command/defaults/ElytraCommand.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index 252559b75..298a23cd7 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -47,8 +47,8 @@ public class ElytraCommand extends Command { final String osArch = System.getProperty("os.arch"); final String osName = System.getProperty("os.name"); throw new CommandInvalidStateException(String.format( - "legacy architectures are not supported. your CPU is %s and your operating system is %s." + - "supported architectures are x86_64 or arm64, supported operating systems are windows," + + "legacy architectures are not supported. your CPU is %s and your operating system is %s. " + + "supported architectures are x86_64 or arm64, supported operating systems are windows, " + "linux, and mac", osArch, osName )); From 42771686c6534cdebb4205597311c7011d192f55 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Wed, 12 Jul 2023 16:42:14 -0400 Subject: [PATCH 305/405] auto swap elytra --- src/api/java/baritone/api/Settings.java | 15 +++++ .../baritone/behavior/ElytraBehavior.java | 55 +++++++++++++++++++ .../elytra/NetherPathfinderContext.java | 10 ++-- 3 files changed, 74 insertions(+), 6 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 08fe54d3a..3f039fe91 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -1394,6 +1394,21 @@ public final class Settings { */ public final Setting elytraNetherSeed = new Setting<>(146008555100680L); + /** + * Automatically swap the current elytra with a new one when the durability gets too low + */ + public final Setting elytraAutoSwap = new Setting<>(true); + + /** + * The minimum durability an elytra can have before being swapped + */ + public final Setting elytraMinimumDurability = new Setting<>(5); + + /** + * The number of ticks between doing inventory clicks + */ + public final Setting elytraInventoryTicks = new Setting<>(5); + /** * A map of lowercase setting field names to their respective setting */ diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 7fc47032b..c39950f33 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -51,10 +51,12 @@ import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.item.EntityFireworkRocket; import net.minecraft.init.Items; +import net.minecraft.inventory.ClickType; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.play.server.SPacketPlayerPosLook; import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; @@ -115,6 +117,11 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private Solution pendingSolution; private boolean solveNextTick; + // auto swap + private int tickCounter; + private int tickLastTransaction = -Baritone.settings().elytraInventoryTicks.value; + private final Queue transactionQueue = new LinkedList<>(); + private ElytraBehavior(Baritone baritone) { super(baritone); this.clearLines = new CopyOnWriteArrayList<>(); @@ -585,6 +592,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return; } + trySwapElytra(); + if (ctx.player().collidedHorizontally) { logDirect("hbonk"); } @@ -1248,6 +1257,50 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return mat == Material.AIR || (ignoreLava && mat == Material.LAVA); } + private void tickInventoryTransactions() { + if (tickCounter - tickLastTransaction > Baritone.settings().elytraInventoryTicks.value) { + Runnable r = transactionQueue.poll(); + if (r != null) { + r.run(); + tickLastTransaction = tickCounter; + } + } + tickCounter++; + } + + private void queueWindowClick(int windowId, int slotId, int button, ClickType type) { + transactionQueue.add(() -> ctx.playerController().windowClick(windowId, slotId, button, type, ctx.player())); + } + + private int findGoodElytra() { + NonNullList invy = ctx.player().inventory.mainInventory; + for (int i = 0; i < invy.size(); i++) { + ItemStack slot = invy.get(i); + if (slot.getItem() == Items.ELYTRA && (slot.getItem().getMaxDamage() - slot.getItemDamage()) > Baritone.settings().elytraMinimumDurability.value) { + return i; + } + } + return -1; + } + + private void trySwapElytra() { + if (!Baritone.settings().elytraAutoSwap.value) return; + if (!transactionQueue.isEmpty()) return; + + ItemStack chest = ctx.player().inventory.armorInventory.get(2); + if (chest.getItem() != Items.ELYTRA) return; + if (chest.getItem().getMaxDamage() - chest.getItemDamage() > Baritone.settings().elytraMinimumDurability.value) return; + + int goodElytraSlot = findGoodElytra(); + if (goodElytraSlot != -1) { + final int CHEST_SLOT = 6; + final int slotId = goodElytraSlot < 9 ? goodElytraSlot + 36 : goodElytraSlot; + queueWindowClick(ctx.player().inventoryContainer.windowId, slotId, 0, ClickType.PICKUP); + queueWindowClick(ctx.player().inventoryContainer.windowId, CHEST_SLOT, 0, ClickType.PICKUP); + queueWindowClick(ctx.player().inventoryContainer.windowId, slotId, 0, ClickType.PICKUP); + } + } + /** * Minecraft 1.12's pushOutOfBlocks logic doesn't account for players being able to fit under single block spaces, * so whenever the edge of a ceiling is encountered while elytra flying it tries to push the player out. @@ -1331,6 +1384,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } + tickInventoryTransactions(); + if (ctx.player().isElytraFlying()) { this.state = State.FLYING; this.goal = null; diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index 9bbb2a24a..063082afb 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -199,12 +199,10 @@ public final class NetherPathfinderContext { } else { id = (int) ((jl | longArray[k] << (64 - l)) & maxEntryValue); } - Octree.setBlock(ptr, - ((idx & 255) & 15), - yReal + (idx >> 8), - ((idx & 255) >> 4), - id != airId - ); + int x = (idx & 15); + int y = yReal + (idx >> 8); + int z = ((idx >> 4) & 15); + Octree.setBlock(ptr, x, y, z, id != airId); } } Octree.setIsFromJava(ptr); From 0b5d5b81768217544be3240355e2d2d90228c358 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Wed, 12 Jul 2023 22:54:04 -0400 Subject: [PATCH 306/405] use ticksBetweenInventoryMoves --- src/api/java/baritone/api/Settings.java | 5 ----- src/main/java/baritone/behavior/ElytraBehavior.java | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 3f039fe91..eafa22b22 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -1404,11 +1404,6 @@ public final class Settings { */ public final Setting elytraMinimumDurability = new Setting<>(5); - /** - * The number of ticks between doing inventory clicks - */ - public final Setting elytraInventoryTicks = new Setting<>(5); - /** * A map of lowercase setting field names to their respective setting */ diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index c39950f33..0c5d47023 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -119,7 +119,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // auto swap private int tickCounter; - private int tickLastTransaction = -Baritone.settings().elytraInventoryTicks.value; + private int tickLastTransaction = -Baritone.settings().ticksBetweenInventoryMoves.value; private final Queue transactionQueue = new LinkedList<>(); private ElytraBehavior(Baritone baritone) { @@ -1258,7 +1258,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } private void tickInventoryTransactions() { - if (tickCounter - tickLastTransaction > Baritone.settings().elytraInventoryTicks.value) { + if (tickCounter - tickLastTransaction > Baritone.settings().ticksBetweenInventoryMoves.value) { Runnable r = transactionQueue.poll(); if (r != null) { r.run(); From 461f56c4d648d62bc6d7ea1c05be6cd923143f63 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Thu, 13 Jul 2023 14:21:15 -0400 Subject: [PATCH 307/405] countdown instead of count up --- src/main/java/baritone/behavior/ElytraBehavior.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 0c5d47023..cbff38815 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -118,8 +118,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private boolean solveNextTick; // auto swap - private int tickCounter; - private int tickLastTransaction = -Baritone.settings().ticksBetweenInventoryMoves.value; + private int invTickCountdown = 0; private final Queue transactionQueue = new LinkedList<>(); private ElytraBehavior(Baritone baritone) { @@ -1258,14 +1257,14 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } private void tickInventoryTransactions() { - if (tickCounter - tickLastTransaction > Baritone.settings().ticksBetweenInventoryMoves.value) { + if (invTickCountdown <= 0) { Runnable r = transactionQueue.poll(); if (r != null) { r.run(); - tickLastTransaction = tickCounter; + invTickCountdown = Baritone.settings().ticksBetweenInventoryMoves.value; } } - tickCounter++; + if (invTickCountdown > 0) invTickCountdown--; } private void queueWindowClick(int windowId, int slotId, int button, ClickType type) { From d35571923f41ae507fb066b9322ef18ea2dfebed Mon Sep 17 00:00:00 2001 From: Babbaj Date: Thu, 13 Jul 2023 14:35:33 -0400 Subject: [PATCH 308/405] appease brady --- .../java/baritone/behavior/ElytraBehavior.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index cbff38815..0d61d1894 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -544,6 +544,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } + tickInventoryTransactions(); + // Certified mojang employee incident if (this.remainingFireworkTicks > 0) { this.remainingFireworkTicks--; @@ -1283,12 +1285,15 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } private void trySwapElytra() { - if (!Baritone.settings().elytraAutoSwap.value) return; - if (!transactionQueue.isEmpty()) return; + if (!Baritone.settings().elytraAutoSwap.value || !transactionQueue.isEmpty()) { + return; + } ItemStack chest = ctx.player().inventory.armorInventory.get(2); - if (chest.getItem() != Items.ELYTRA) return; - if (chest.getItem().getMaxDamage() - chest.getItemDamage() > Baritone.settings().elytraMinimumDurability.value) return; + if (chest.getItem() != Items.ELYTRA + || chest.getItem().getMaxDamage() - chest.getItemDamage() > Baritone.settings().elytraMinimumDurability.value) { + return; + } int goodElytraSlot = findGoodElytra(); if (goodElytraSlot != -1) { @@ -1383,8 +1388,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } - tickInventoryTransactions(); - if (ctx.player().isElytraFlying()) { this.state = State.FLYING; this.goal = null; From 29bf046aa8412f80a4eceb529dca02d6dfd170f8 Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 13 Jul 2023 14:28:51 -0500 Subject: [PATCH 309/405] BlockStateOctreeInterface --- .../baritone/behavior/ElytraBehavior.java | 18 ++++--- .../elytra/BlockStateOctreeInterface.java | 50 +++++++++++++++++++ .../elytra/NetherPathfinderContext.java | 3 +- 3 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 src/main/java/baritone/behavior/elytra/BlockStateOctreeInterface.java diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 0d61d1894..ceab9db7c 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -110,6 +110,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private final int[] nextTickBoostCounter; private BlockStateInterface bsi; + private BlockStateOctreeInterface boi; private BlockPos destination; private final ExecutorService solverExecutor; @@ -299,7 +300,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // not loaded yet? return; } - if (!passable(ctx.world().getBlockState(path.get(rangeStartIncl)), false)) { + final BetterBlockPos rangeStart = path.get(rangeStartIncl); + if (!ElytraBehavior.this.passable(rangeStart.x, rangeStart.y, rangeStart.z, false)) { // we're in a wall return; // previous iterations of this function SHOULD have fixed this by now :rage_cat: } @@ -575,7 +577,9 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return; } + // ctx AND context???? :DDD this.bsi = new BlockStateInterface(ctx); + this.boi = new BlockStateOctreeInterface(context); this.pathManager.tick(); final int playerNear = this.pathManager.getNear(); @@ -1250,12 +1254,12 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } private boolean passable(int x, int y, int z, boolean ignoreLava) { - return passable(this.bsi.get0(x, y, z), ignoreLava); - } - - private static boolean passable(IBlockState state, boolean ignoreLava) { - Material mat = state.getMaterial(); - return mat == Material.AIR || (ignoreLava && mat == Material.LAVA); + if (ignoreLava) { + final Material mat = this.bsi.get0(x, y, z).getMaterial(); + return mat == Material.AIR || mat == Material.LAVA; + } else { + return !this.boi.get0(x, y, z); + } } private void tickInventoryTransactions() { diff --git a/src/main/java/baritone/behavior/elytra/BlockStateOctreeInterface.java b/src/main/java/baritone/behavior/elytra/BlockStateOctreeInterface.java new file mode 100644 index 000000000..261abdbf6 --- /dev/null +++ b/src/main/java/baritone/behavior/elytra/BlockStateOctreeInterface.java @@ -0,0 +1,50 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.behavior.elytra; + +import dev.babbaj.pathfinder.NetherPathfinder; +import dev.babbaj.pathfinder.Octree; + +/** + * @author Brady + */ +public final class BlockStateOctreeInterface { + + private final long context; + private long chunkPtr; + private int prevChunkX; + private int prevChunkZ; + + public BlockStateOctreeInterface(final NetherPathfinderContext context) { + this.context = context.context; + } + + public boolean get0(final int x, final int y, final int z) { + if (y < 0 || y >= 128) { + return false; + } + final int chunkX = x >> 4; + final int chunkZ = z >> 4; + if (chunkX != this.prevChunkX || chunkZ != this.prevChunkZ || this.chunkPtr == 0) { + this.prevChunkX = chunkX; + this.prevChunkZ = chunkZ; + this.chunkPtr = NetherPathfinder.getOrCreateChunk(this.context, chunkX, chunkZ); + } + return Octree.getBlock(this.chunkPtr, x & 0xF, y & 0x7F, z & 0xF); + } +} diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index 063082afb..457b2a7a5 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -46,7 +46,8 @@ public final class NetherPathfinderContext { private static final IBlockState AIR_BLOCK_STATE = Blocks.AIR.getDefaultState(); - private final long context; + // Visible for access in BlockStateOctreeInterface + final long context; private final long seed; private final ExecutorService executor; From 1d109d4b9fb7abe9d2d1ea31def84abf6cb32aee Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 13 Jul 2023 14:47:19 -0500 Subject: [PATCH 310/405] crucial performance optimization --- .../behavior/elytra/BlockStateOctreeInterface.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/baritone/behavior/elytra/BlockStateOctreeInterface.java b/src/main/java/baritone/behavior/elytra/BlockStateOctreeInterface.java index 261abdbf6..8a07b96e5 100644 --- a/src/main/java/baritone/behavior/elytra/BlockStateOctreeInterface.java +++ b/src/main/java/baritone/behavior/elytra/BlockStateOctreeInterface.java @@ -27,20 +27,22 @@ public final class BlockStateOctreeInterface { private final long context; private long chunkPtr; - private int prevChunkX; - private int prevChunkZ; + + // Guarantee that the first lookup will fetch the context by setting MAX_VALUE + private int prevChunkX = Integer.MAX_VALUE; + private int prevChunkZ = Integer.MAX_VALUE; public BlockStateOctreeInterface(final NetherPathfinderContext context) { this.context = context.context; } public boolean get0(final int x, final int y, final int z) { - if (y < 0 || y >= 128) { + if ((y | (128 - y)) < 0) { return false; } final int chunkX = x >> 4; final int chunkZ = z >> 4; - if (chunkX != this.prevChunkX || chunkZ != this.prevChunkZ || this.chunkPtr == 0) { + if (((chunkX ^ this.prevChunkX) | (chunkZ ^ this.prevChunkZ)) != 0) { this.prevChunkX = chunkX; this.prevChunkZ = chunkZ; this.chunkPtr = NetherPathfinder.getOrCreateChunk(this.context, chunkX, chunkZ); From b468b8eb95f27efa27756c244973809fec8d4dfd Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sat, 15 Jul 2023 22:17:21 -0400 Subject: [PATCH 311/405] landing procedure --- .../baritone/behavior/ElytraBehavior.java | 22 ++++++++++++++++++- .../baritone/behavior/elytra/NetherPath.java | 4 ++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index ceab9db7c..43c138846 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -1393,6 +1393,23 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } if (ctx.player().isElytraFlying()) { + if (ctx.player().getDistanceSqToCenter(ElytraBehavior.this.pathManager.path.getLast()) < (5 * 5)) { + this.state = State.LANDING; + } + } + + if (this.state == State.LANDING) { + if (ctx.player().isElytraFlying()) { + BetterBlockPos endPos = ElytraBehavior.this.pathManager.path.getLast(); + Vec3d from = ctx.player().getPositionVector(); + Vec3d to = new Vec3d(endPos.x, from.y, endPos.z); + Rotation rotation = RotationUtils.calcRotationFromVec3d(from, to, ctx.playerRotations()); + baritone.getLookBehavior().updateTarget(rotation, false); + } else { + this.onLostControl(); + return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); + } + } else if (ctx.player().isElytraFlying()) { this.state = State.FLYING; this.goal = null; baritone.getInputOverrideHandler().clearAllKeys(); @@ -1508,6 +1525,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return "Begin flying"; case FLYING: return "Flying"; + case LANDING: + return "Landing"; default: return "Unknown"; } @@ -1550,7 +1569,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H PAUSE, GET_TO_JUMP, START_FLYING, - FLYING + FLYING, + LANDING } public static T create(final Baritone baritone) { diff --git a/src/main/java/baritone/behavior/elytra/NetherPath.java b/src/main/java/baritone/behavior/elytra/NetherPath.java index e90075b87..e8f8e2793 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPath.java +++ b/src/main/java/baritone/behavior/elytra/NetherPath.java @@ -47,6 +47,10 @@ public final class NetherPath extends AbstractList { return this.backing.size(); } + public BetterBlockPos getLast() { + return this.backing.get(this.backing.size() - 1); + } + public Vec3d getVec(int index) { final BetterBlockPos pos = this.get(index); return new Vec3d(pos.x, pos.y, pos.z); From 716b3ae0d23ae7a253f87b76b983dd94f1f5a730 Mon Sep 17 00:00:00 2001 From: Brady Hahn Date: Sat, 15 Jul 2023 22:23:35 -0500 Subject: [PATCH 312/405] Update ElytraBehavior.java i love github web editor --- src/main/java/baritone/behavior/ElytraBehavior.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 43c138846..197ea61b8 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -306,7 +306,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return; // previous iterations of this function SHOULD have fixed this by now :rage_cat: } - if (this.ticksNearUnchanged > 100) { + if (ElytraBehavior.this.process.state != State.LANDING && this.ticksNearUnchanged > 100) { this.pathRecalcSegment(rangeEndExcl - 1) .thenRun(() -> { logDirect("Recalculating segment, no progress in last 100 ticks"); @@ -1393,14 +1393,15 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } if (ctx.player().isElytraFlying()) { - if (ctx.player().getDistanceSqToCenter(ElytraBehavior.this.pathManager.path.getLast()) < (5 * 5)) { + final BetterBlockPos last = ElytraBehavior.this.pathManager.path.getLast(); + if (last != null && ctx.player().getDistanceSqToCenter(last) < (5 * 5)) { this.state = State.LANDING; } } if (this.state == State.LANDING) { - if (ctx.player().isElytraFlying()) { - BetterBlockPos endPos = ElytraBehavior.this.pathManager.path.getLast(); + final BetterBlockPos endPos = ElytraBehavior.this.pathManager.path.getLast(); + if (ctx.player().isElytraFlying() && endPos != null) { Vec3d from = ctx.player().getPositionVector(); Vec3d to = new Vec3d(endPos.x, from.y, endPos.z); Rotation rotation = RotationUtils.calcRotationFromVec3d(from, to, ctx.playerRotations()); From e579bf980d3f2021b57723f3e9d7c0c4d0a70b15 Mon Sep 17 00:00:00 2001 From: Brady Hahn Date: Sat, 15 Jul 2023 22:23:59 -0500 Subject: [PATCH 313/405] Update NetherPath.java --- src/main/java/baritone/behavior/elytra/NetherPath.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/baritone/behavior/elytra/NetherPath.java b/src/main/java/baritone/behavior/elytra/NetherPath.java index e8f8e2793..e746665c4 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPath.java +++ b/src/main/java/baritone/behavior/elytra/NetherPath.java @@ -47,8 +47,11 @@ public final class NetherPath extends AbstractList { return this.backing.size(); } + /** + * @return The last position in the path, or {@code null} if empty + */ public BetterBlockPos getLast() { - return this.backing.get(this.backing.size() - 1); + return this.isEmpty() ? null : this.backing.get(this.backing.size() - 1); } public Vec3d getVec(int index) { From 76d3a13f58ba5b430f6ceed8f6d53db090d39713 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sun, 16 Jul 2023 01:19:51 -0400 Subject: [PATCH 314/405] cull far away chunks from the cache --- build.gradle | 4 ++-- src/api/java/baritone/api/Settings.java | 11 +++++++++++ .../java/baritone/behavior/ElytraBehavior.java | 15 +++++++++++---- .../behavior/elytra/NetherPathfinderContext.java | 4 ++++ 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index da0e2232b..e44d68e04 100755 --- a/build.gradle +++ b/build.gradle @@ -175,8 +175,8 @@ dependencies { transitive = false } launchAnnotationProcessor 'org.spongepowered:mixin:0.8.4-SNAPSHOT:processor' - launchImplementation('dev.babbaj:nether-pathfinder:0.24') - implementation 'dev.babbaj:nether-pathfinder:0.24' + launchImplementation('dev.babbaj:nether-pathfinder:0.34') + implementation 'dev.babbaj:nether-pathfinder:0.34' testImplementation 'junit:junit:4.12' } diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index eafa22b22..e203a0ebf 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -38,6 +38,7 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -1404,6 +1405,16 @@ public final class Settings { */ public final Setting elytraMinimumDurability = new Setting<>(5); + /** + * Time between culling far away chunks from the nether pathfinder chunk cache + */ + public final Setting elytraTimeBetweenCacheCullSecs = new Setting<>(TimeUnit.MINUTES.toSeconds(3)); + + /** + * Maximum distance chunks can be before being culled from the nether pathfinder chunk cache + */ + public final Setting elytraCacheCullDistance = new Setting<>(5000); + /** * A map of lowercase setting field names to their respective setting */ diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 197ea61b8..42f226e79 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -118,9 +118,11 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private Solution pendingSolution; private boolean solveNextTick; + private long timeLastCacheCull = 0L; + // auto swap private int invTickCountdown = 0; - private final Queue transactionQueue = new LinkedList<>(); + private final Queue invTransactionQueue = new LinkedList<>(); private ElytraBehavior(Baritone baritone) { super(baritone); @@ -516,6 +518,11 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H if (event.getType() == TickEvent.Type.OUT) { return; } + final long now = System.currentTimeMillis(); + if ((now - this.timeLastCacheCull) / 1000 > Baritone.settings().elytraTimeBetweenCacheCullSecs.value) { + this.context.queueCacheCulling(ctx.player().chunkCoordX, ctx.player().chunkCoordZ, Baritone.settings().elytraCacheCullDistance.value); + this.timeLastCacheCull = now; + } // Fetch the previous solution, regardless of if it's going to be used this.pendingSolution = null; @@ -1264,7 +1271,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private void tickInventoryTransactions() { if (invTickCountdown <= 0) { - Runnable r = transactionQueue.poll(); + Runnable r = invTransactionQueue.poll(); if (r != null) { r.run(); invTickCountdown = Baritone.settings().ticksBetweenInventoryMoves.value; @@ -1274,7 +1281,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } private void queueWindowClick(int windowId, int slotId, int button, ClickType type) { - transactionQueue.add(() -> ctx.playerController().windowClick(windowId, slotId, button, type, ctx.player())); + invTransactionQueue.add(() -> ctx.playerController().windowClick(windowId, slotId, button, type, ctx.player())); } private int findGoodElytra() { @@ -1289,7 +1296,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } private void trySwapElytra() { - if (!Baritone.settings().elytraAutoSwap.value || !transactionQueue.isEmpty()) { + if (!Baritone.settings().elytraAutoSwap.value || !invTransactionQueue.isEmpty()) { return; } diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index 457b2a7a5..e0eb7de0b 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -57,6 +57,10 @@ public final class NetherPathfinderContext { this.executor = Executors.newSingleThreadExecutor(); } + public void queueCacheCulling(int chunkX, int chunkZ, int maxDistanceBlocks) { + this.executor.execute(() -> NetherPathfinder.cullFarChunks(this.context, chunkX, chunkZ, maxDistanceBlocks)); + } + public void queueForPacking(final Chunk chunkIn) { final SoftReference ref = new SoftReference<>(chunkIn); this.executor.execute(() -> { From f3bb5a0cb2b490ce7ce1cf98120f27567a9ea4a6 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sun, 16 Jul 2023 13:53:02 -0400 Subject: [PATCH 315/405] make sure BlockStateOctreeInterface doesn't use freed chunk pointers --- .../java/baritone/behavior/ElytraBehavior.java | 2 +- .../elytra/BlockStateOctreeInterface.java | 17 +++++++++++------ .../elytra/NetherPathfinderContext.java | 10 ++++++++-- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index 42f226e79..b9bbd65e7 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -520,7 +520,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } final long now = System.currentTimeMillis(); if ((now - this.timeLastCacheCull) / 1000 > Baritone.settings().elytraTimeBetweenCacheCullSecs.value) { - this.context.queueCacheCulling(ctx.player().chunkCoordX, ctx.player().chunkCoordZ, Baritone.settings().elytraCacheCullDistance.value); + this.context.queueCacheCulling(ctx.player().chunkCoordX, ctx.player().chunkCoordZ, Baritone.settings().elytraCacheCullDistance.value, this.boi); this.timeLastCacheCull = now; } diff --git a/src/main/java/baritone/behavior/elytra/BlockStateOctreeInterface.java b/src/main/java/baritone/behavior/elytra/BlockStateOctreeInterface.java index 8a07b96e5..b81a6aed5 100644 --- a/src/main/java/baritone/behavior/elytra/BlockStateOctreeInterface.java +++ b/src/main/java/baritone/behavior/elytra/BlockStateOctreeInterface.java @@ -25,15 +25,17 @@ import dev.babbaj.pathfinder.Octree; */ public final class BlockStateOctreeInterface { - private final long context; - private long chunkPtr; + private final NetherPathfinderContext context; + private final long contextPtr; + volatile long chunkPtr; // Guarantee that the first lookup will fetch the context by setting MAX_VALUE private int prevChunkX = Integer.MAX_VALUE; private int prevChunkZ = Integer.MAX_VALUE; public BlockStateOctreeInterface(final NetherPathfinderContext context) { - this.context = context.context; + this.context = context; + this.contextPtr = context.context; } public boolean get0(final int x, final int y, final int z) { @@ -42,11 +44,14 @@ public final class BlockStateOctreeInterface { } final int chunkX = x >> 4; final int chunkZ = z >> 4; - if (((chunkX ^ this.prevChunkX) | (chunkZ ^ this.prevChunkZ)) != 0) { + long pointer = this.chunkPtr; + if (pointer == 0 | ((chunkX ^ this.prevChunkX) | (chunkZ ^ this.prevChunkZ)) != 0) { this.prevChunkX = chunkX; this.prevChunkZ = chunkZ; - this.chunkPtr = NetherPathfinder.getOrCreateChunk(this.context, chunkX, chunkZ); + synchronized (this.context.cacheLock) { + this.chunkPtr = pointer = NetherPathfinder.getOrCreateChunk(this.contextPtr, chunkX, chunkZ); + } } - return Octree.getBlock(this.chunkPtr, x & 0xF, y & 0x7F, z & 0xF); + return Octree.getBlock(pointer, x & 0xF, y & 0x7F, z & 0xF); } } diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index e0eb7de0b..ebe563374 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -45,6 +45,7 @@ import java.util.concurrent.TimeUnit; public final class NetherPathfinderContext { private static final IBlockState AIR_BLOCK_STATE = Blocks.AIR.getDefaultState(); + public final Object cacheLock = new Object(); // Visible for access in BlockStateOctreeInterface final long context; @@ -57,8 +58,13 @@ public final class NetherPathfinderContext { this.executor = Executors.newSingleThreadExecutor(); } - public void queueCacheCulling(int chunkX, int chunkZ, int maxDistanceBlocks) { - this.executor.execute(() -> NetherPathfinder.cullFarChunks(this.context, chunkX, chunkZ, maxDistanceBlocks)); + public void queueCacheCulling(int chunkX, int chunkZ, int maxDistanceBlocks, BlockStateOctreeInterface boi) { + this.executor.execute(() -> { + synchronized (this.cacheLock) { + boi.chunkPtr = 0L; + NetherPathfinder.cullFarChunks(this.context, chunkX, chunkZ, maxDistanceBlocks); + } + }); } public void queueForPacking(final Chunk chunkIn) { From 41e8c69db9718a2032fb109ce1f4d34de3b5a41a Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sun, 16 Jul 2023 18:58:42 -0400 Subject: [PATCH 316/405] consistent elytra setting naming --- src/api/java/baritone/api/Settings.java | 10 +++++----- src/main/java/baritone/behavior/ElytraBehavior.java | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index e203a0ebf..2ec56b1a4 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -1366,23 +1366,23 @@ public final class Settings { /** * If enabled, avoids using fireworks when descending along the flight path. */ - public final Setting conserveFireworks = new Setting<>(true); + public final Setting elytraConserveFireworks = new Setting<>(true); /** * Renders the raytraces that are performed by the elytra fly calculation. */ - public final Setting renderRaytraces = new Setting<>(false); + public final Setting elytraRenderRaytraces = new Setting<>(false); /** * Renders the raytraces that are used in the hitbox part of the elytra fly calculation. - * Requires {@link #renderRaytraces}. + * Requires {@link #elytraRenderRaytraces}. */ - public final Setting renderHitboxRaytraces = new Setting<>(false); + public final Setting elytraRenderHitboxRaytraces = new Setting<>(false); /** * Renders the best elytra flight path that was simulated each tick. */ - public final Setting renderElytraSimulation = new Setting<>(false); + public final Setting elytraRenderSimulation = new Setting<>(false); /** * Automatically path to and jump off of ledges to initiate elytra flight when grounded. diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index b9bbd65e7..1f969dc23 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -391,21 +391,21 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H if (this.aimPos != null) { PathRenderer.drawGoal(ctx.player(), new GoalBlock(this.aimPos), event.getPartialTicks(), Color.GREEN); } - if (!this.clearLines.isEmpty() && settings.renderRaytraces.value) { + if (!this.clearLines.isEmpty() && settings.elytraRenderRaytraces.value) { IRenderer.startLines(Color.GREEN, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); for (Pair line : this.clearLines) { IRenderer.emitLine(line.first(), line.second()); } IRenderer.endLines(settings.renderPathIgnoreDepth.value); } - if (!this.blockedLines.isEmpty() && Baritone.settings().renderRaytraces.value) { + if (!this.blockedLines.isEmpty() && Baritone.settings().elytraRenderRaytraces.value) { IRenderer.startLines(Color.BLUE, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); for (Pair line : this.blockedLines) { IRenderer.emitLine(line.first(), line.second()); } IRenderer.endLines(settings.renderPathIgnoreDepth.value); } - if (this.simulationLine != null && Baritone.settings().renderElytraSimulation.value) { + if (this.simulationLine != null && Baritone.settings().elytraRenderSimulation.value) { IRenderer.startLines(new Color(0x36CCDC), settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); final Vec3d offset = new Vec3d( ctx.player().prevPosX + (ctx.player().posX - ctx.player().prevPosX) * event.getPartialTicks(), @@ -753,7 +753,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H logDebug("waiting for elytraFireworkSetbackUseDelay: " + this.remainingSetBackTicks); return; } - final boolean useOnDescend = !Baritone.settings().conserveFireworks.value || ctx.player().posY < goingTo.y + 5; + final boolean useOnDescend = !Baritone.settings().elytraConserveFireworks.value || ctx.player().posY < goingTo.y + 5; final double currentSpeed = new Vec3d( ctx.player().motionX, // ignore y component if we are BOTH below where we want to be AND descending @@ -984,7 +984,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H }; // Use non-batching method without early failure - if (Baritone.settings().renderHitboxRaytraces.value) { + if (Baritone.settings().elytraRenderHitboxRaytraces.value) { boolean clear = true; for (int i = 0; i < 8; i++) { final Vec3d s = new Vec3d(src[i * 3], src[i * 3 + 1], src[i * 3 + 2]); @@ -1009,7 +1009,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H clear = ctx.world().rayTraceBlocks(start, dest, false, false, false) == null; } - if (Baritone.settings().renderRaytraces.value) { + if (Baritone.settings().elytraRenderRaytraces.value) { (clear ? this.clearLines : this.blockedLines).add(new Pair<>(start, dest)); } return clear; From 0e567f2f90b32a3b669c45ec9f58c36f4432a1dc Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 16 Jul 2023 18:17:15 -0700 Subject: [PATCH 317/405] shrimple --- .../elytra/NetherPathfinderContext.java | 76 +++++++++++-------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index ebe563374..defc3fa19 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -34,10 +34,7 @@ import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.storage.ExtendedBlockStorage; import java.lang.ref.SoftReference; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; /** * @author Brady @@ -50,12 +47,15 @@ public final class NetherPathfinderContext { // Visible for access in BlockStateOctreeInterface final long context; private final long seed; - private final ExecutorService executor; + private final ThreadPoolExecutor executor; + private final ExecutorService executorHighPriority; public NetherPathfinderContext(long seed) { this.context = NetherPathfinder.newContext(seed); this.seed = seed; - this.executor = Executors.newSingleThreadExecutor(); + + this.executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()); + this.executorHighPriority = Executors.newSingleThreadExecutor(); } public void queueCacheCulling(int chunkX, int chunkZ, int maxDistanceBlocks, BlockStateOctreeInterface boi) { @@ -68,46 +68,58 @@ public final class NetherPathfinderContext { } public void queueForPacking(final Chunk chunkIn) { + if (this.executor.getQueue().size() > 50000) { + return; + } final SoftReference ref = new SoftReference<>(chunkIn); this.executor.execute(() -> { - // TODO: Prioritize packing recent chunks and/or ones that the path goes through, - // and prune the oldest chunks per chunkPackerQueueMaxSize - final Chunk chunk = ref.get(); - if (chunk != null) { - long ptr = NetherPathfinder.getOrCreateChunk(this.context, chunk.x, chunk.z); - writeChunkData(chunk, ptr); + synchronized (this.cacheLock) { + // TODO: Prioritize packing recent chunks and/or ones that the path goes through, + // and prune the oldest chunks per chunkPackerQueueMaxSize + final Chunk chunk = ref.get(); + if (chunk != null) { + long ptr = NetherPathfinder.getOrCreateChunk(this.context, chunk.x, chunk.z); + writeChunkData(chunk, ptr); + } } }); } public void queueBlockUpdate(BlockChangeEvent event) { + if (this.executor.getQueue().size() > 50000) { + return; + } this.executor.execute(() -> { - ChunkPos chunkPos = event.getChunkPos(); - long ptr = NetherPathfinder.getChunkPointer(this.context, chunkPos.x, chunkPos.z); - if (ptr == 0) return; // this shouldn't ever happen - event.getBlocks().forEach(pair -> { - BlockPos pos = pair.first(); - if (pos.getY() >= 128) return; - boolean isSolid = pair.second() != AIR_BLOCK_STATE; - Octree.setBlock(ptr, pos.getX() & 15, pos.getY(), pos.getZ() & 15, isSolid); - }); + synchronized (this.cacheLock) { + ChunkPos chunkPos = event.getChunkPos(); + long ptr = NetherPathfinder.getChunkPointer(this.context, chunkPos.x, chunkPos.z); + if (ptr == 0) return; // this shouldn't ever happen + event.getBlocks().forEach(pair -> { + BlockPos pos = pair.first(); + if (pos.getY() >= 128) return; + boolean isSolid = pair.second() != AIR_BLOCK_STATE; + Octree.setBlock(ptr, pos.getX() & 15, pos.getY(), pos.getZ() & 15, isSolid); + }); + } }); } public CompletableFuture pathFindAsync(final BlockPos src, final BlockPos dst) { return CompletableFuture.supplyAsync(() -> { - final PathSegment segment = NetherPathfinder.pathFind( - this.context, - src.getX(), src.getY(), src.getZ(), - dst.getX(), dst.getY(), dst.getZ(), - true, - 10000 - ); - if (segment == null) { - throw new PathCalculationException("Path calculation failed"); + synchronized (this.cacheLock) { + final PathSegment segment = NetherPathfinder.pathFind( + this.context, + src.getX(), src.getY(), src.getZ(), + dst.getX(), dst.getY(), dst.getZ(), + true, + 10000 + ); + if (segment == null) { + throw new PathCalculationException("Path calculation failed"); + } + return segment; } - return segment; - }, this.executor); + }, this.executorHighPriority); } /** From edc92753cfa98a11d30c855d661ad8f3d1f1be9c Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 16 Jul 2023 18:17:53 -0700 Subject: [PATCH 318/405] Revert "shrimple" This reverts commit 0e567f2f90b32a3b669c45ec9f58c36f4432a1dc. --- .../elytra/NetherPathfinderContext.java | 76 ++++++++----------- 1 file changed, 32 insertions(+), 44 deletions(-) diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index defc3fa19..ebe563374 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -34,7 +34,10 @@ import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.storage.ExtendedBlockStorage; import java.lang.ref.SoftReference; -import java.util.concurrent.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; /** * @author Brady @@ -47,15 +50,12 @@ public final class NetherPathfinderContext { // Visible for access in BlockStateOctreeInterface final long context; private final long seed; - private final ThreadPoolExecutor executor; - private final ExecutorService executorHighPriority; + private final ExecutorService executor; public NetherPathfinderContext(long seed) { this.context = NetherPathfinder.newContext(seed); this.seed = seed; - - this.executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()); - this.executorHighPriority = Executors.newSingleThreadExecutor(); + this.executor = Executors.newSingleThreadExecutor(); } public void queueCacheCulling(int chunkX, int chunkZ, int maxDistanceBlocks, BlockStateOctreeInterface boi) { @@ -68,58 +68,46 @@ public final class NetherPathfinderContext { } public void queueForPacking(final Chunk chunkIn) { - if (this.executor.getQueue().size() > 50000) { - return; - } final SoftReference ref = new SoftReference<>(chunkIn); this.executor.execute(() -> { - synchronized (this.cacheLock) { - // TODO: Prioritize packing recent chunks and/or ones that the path goes through, - // and prune the oldest chunks per chunkPackerQueueMaxSize - final Chunk chunk = ref.get(); - if (chunk != null) { - long ptr = NetherPathfinder.getOrCreateChunk(this.context, chunk.x, chunk.z); - writeChunkData(chunk, ptr); - } + // TODO: Prioritize packing recent chunks and/or ones that the path goes through, + // and prune the oldest chunks per chunkPackerQueueMaxSize + final Chunk chunk = ref.get(); + if (chunk != null) { + long ptr = NetherPathfinder.getOrCreateChunk(this.context, chunk.x, chunk.z); + writeChunkData(chunk, ptr); } }); } public void queueBlockUpdate(BlockChangeEvent event) { - if (this.executor.getQueue().size() > 50000) { - return; - } this.executor.execute(() -> { - synchronized (this.cacheLock) { - ChunkPos chunkPos = event.getChunkPos(); - long ptr = NetherPathfinder.getChunkPointer(this.context, chunkPos.x, chunkPos.z); - if (ptr == 0) return; // this shouldn't ever happen - event.getBlocks().forEach(pair -> { - BlockPos pos = pair.first(); - if (pos.getY() >= 128) return; - boolean isSolid = pair.second() != AIR_BLOCK_STATE; - Octree.setBlock(ptr, pos.getX() & 15, pos.getY(), pos.getZ() & 15, isSolid); - }); - } + ChunkPos chunkPos = event.getChunkPos(); + long ptr = NetherPathfinder.getChunkPointer(this.context, chunkPos.x, chunkPos.z); + if (ptr == 0) return; // this shouldn't ever happen + event.getBlocks().forEach(pair -> { + BlockPos pos = pair.first(); + if (pos.getY() >= 128) return; + boolean isSolid = pair.second() != AIR_BLOCK_STATE; + Octree.setBlock(ptr, pos.getX() & 15, pos.getY(), pos.getZ() & 15, isSolid); + }); }); } public CompletableFuture pathFindAsync(final BlockPos src, final BlockPos dst) { return CompletableFuture.supplyAsync(() -> { - synchronized (this.cacheLock) { - final PathSegment segment = NetherPathfinder.pathFind( - this.context, - src.getX(), src.getY(), src.getZ(), - dst.getX(), dst.getY(), dst.getZ(), - true, - 10000 - ); - if (segment == null) { - throw new PathCalculationException("Path calculation failed"); - } - return segment; + final PathSegment segment = NetherPathfinder.pathFind( + this.context, + src.getX(), src.getY(), src.getZ(), + dst.getX(), dst.getY(), dst.getZ(), + true, + 10000 + ); + if (segment == null) { + throw new PathCalculationException("Path calculation failed"); } - }, this.executorHighPriority); + return segment; + }, this.executor); } /** From 32a4c4644eccaaf0b50a0daf3ae1b144a57b85a0 Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 16 Jul 2023 20:21:40 -0500 Subject: [PATCH 319/405] Move cull code --- src/main/java/baritone/behavior/ElytraBehavior.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index b9bbd65e7..0ad6ad62d 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -518,11 +518,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H if (event.getType() == TickEvent.Type.OUT) { return; } - final long now = System.currentTimeMillis(); - if ((now - this.timeLastCacheCull) / 1000 > Baritone.settings().elytraTimeBetweenCacheCullSecs.value) { - this.context.queueCacheCulling(ctx.player().chunkCoordX, ctx.player().chunkCoordZ, Baritone.settings().elytraCacheCullDistance.value, this.boi); - this.timeLastCacheCull = now; - } // Fetch the previous solution, regardless of if it's going to be used this.pendingSolution = null; @@ -594,6 +589,12 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H Math.max(playerNear - 30, 0), Math.min(playerNear + 100, path.size()) ); + + final long now = System.currentTimeMillis(); + if ((now - this.timeLastCacheCull) / 1000 > Baritone.settings().elytraTimeBetweenCacheCullSecs.value) { + this.context.queueCacheCulling(ctx.player().chunkCoordX, ctx.player().chunkCoordZ, Baritone.settings().elytraCacheCullDistance.value, this.boi); + this.timeLastCacheCull = now; + } } /** From 108dbdae5d8ba87eac0dcb1dd7a7ce625f23d874 Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 16 Jul 2023 20:29:30 -0500 Subject: [PATCH 320/405] partially appease codacy --- src/api/java/baritone/api/event/events/BlockChangeEvent.java | 2 -- src/main/java/baritone/command/defaults/ElytraCommand.java | 4 +++- src/main/java/baritone/utils/PathRenderer.java | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/api/java/baritone/api/event/events/BlockChangeEvent.java b/src/api/java/baritone/api/event/events/BlockChangeEvent.java index a65a51f35..00743f025 100644 --- a/src/api/java/baritone/api/event/events/BlockChangeEvent.java +++ b/src/api/java/baritone/api/event/events/BlockChangeEvent.java @@ -22,9 +22,7 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkPos; -import java.util.Collections; import java.util.List; -import java.util.Set; /** * @author Brady diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index 298a23cd7..5288ade47 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -59,7 +59,9 @@ public class ElytraCommand extends Command { if (iGoal == null) { throw new CommandInvalidStateException("No goal has been set"); } - final int x, y, z; + final int x; + final int y; + final int z; if (iGoal instanceof GoalXZ) { GoalXZ goal = (GoalXZ) iGoal; x = goal.getX(); diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index 0fcad054a..a30ec45b7 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -33,7 +33,6 @@ import net.minecraft.init.Blocks; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.Vec3d; import java.awt.*; import java.util.Arrays; From bf9cb76604b576607f4c6b70f8a51a1a12493b14 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 17 Jul 2023 16:34:01 -0500 Subject: [PATCH 321/405] VulkanMod compatibility + use `LINES` instead of `DEBUG_LINES` --- src/main/java/baritone/utils/GuiClick.java | 1 - src/main/java/baritone/utils/IRenderer.java | 85 +++++++++++-------- .../java/baritone/utils/PathRenderer.java | 68 ++++++--------- 3 files changed, 76 insertions(+), 78 deletions(-) diff --git a/src/main/java/baritone/utils/GuiClick.java b/src/main/java/baritone/utils/GuiClick.java index ab0e5c4fa..7e1a9cfce 100644 --- a/src/main/java/baritone/utils/GuiClick.java +++ b/src/main/java/baritone/utils/GuiClick.java @@ -43,7 +43,6 @@ import java.awt.*; import java.util.Collections; import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX; -import static org.lwjgl.opengl.GL11.*; public class GuiClick extends Screen implements Helper { diff --git a/src/main/java/baritone/utils/IRenderer.java b/src/main/java/baritone/utils/IRenderer.java index c7415b96c..83436c408 100644 --- a/src/main/java/baritone/utils/IRenderer.java +++ b/src/main/java/baritone/utils/IRenderer.java @@ -20,17 +20,19 @@ package baritone.utils; import baritone.api.BaritoneAPI; import baritone.api.Settings; import baritone.utils.accessor.IEntityRenderManager; +import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.math.Matrix3f; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.texture.TextureManager; import com.mojang.blaze3d.vertex.*; import com.mojang.math.Matrix4f; +import net.minecraft.util.Mth; import net.minecraft.world.phys.AABB; import java.awt.*; -import static org.lwjgl.opengl.GL11.*; - public interface IRenderer { Tesselator tessellator = Tesselator.getInstance(); @@ -51,17 +53,23 @@ public interface IRenderer { static void startLines(Color color, float alpha, float lineWidth, boolean ignoreDepth) { RenderSystem.enableBlend(); - RenderSystem.blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); + RenderSystem.blendFuncSeparate( + GlStateManager.SourceFactor.SRC_ALPHA, + GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, + GlStateManager.SourceFactor.ONE, + GlStateManager.DestFactor.ZERO + ); glColor(color, alpha); RenderSystem.lineWidth(lineWidth); RenderSystem.disableTexture(); RenderSystem.depthMask(false); + RenderSystem.disableCull(); if (ignoreDepth) { RenderSystem.disableDepthTest(); } - //TODO: check - buffer.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR); + RenderSystem.setShader(GameRenderer::getRendertypeLinesShader); + buffer.begin(VertexFormat.Mode.LINES, DefaultVertexFormat.POSITION_COLOR_NORMAL); } static void startLines(Color color, float lineWidth, boolean ignoreDepth) { @@ -74,51 +82,56 @@ public interface IRenderer { RenderSystem.enableDepthTest(); } + RenderSystem.enableCull(); RenderSystem.depthMask(true); RenderSystem.enableTexture(); RenderSystem.disableBlend(); } + static void emitLine(PoseStack stack, double x1, double y1, double z1, double x2, double y2, double z2) { + final Matrix4f matrix4f = stack.last().pose(); + final Matrix3f normal = stack.last().normal(); + + final double dx = x2 - x1; + final double dy = y2 - y1; + final double dz = z2 - z1; + + final double invMag = Mth.fastInvSqrt(dx * dx + dy * dy + dz * dz); + final float nx = (float) (dx * invMag); + final float ny = (float) (dy * invMag); + final float nz = (float) (dz * invMag); + + buffer.vertex(matrix4f, (float) x1, (float) y1, (float) z1) + .color(color[0], color[1], color[2], color[3]) + .normal(normal, nx, ny, nz) + .endVertex(); + buffer.vertex(matrix4f, (float) x2, (float) y2, (float) z2) + .color(color[0], color[1], color[2], color[3]) + .normal(normal, nx, ny, nz) + .endVertex(); + } + static void emitAABB(PoseStack stack, AABB aabb) { AABB toDraw = aabb.move(-renderManager.renderPosX(), -renderManager.renderPosY(), -renderManager.renderPosZ()); - Matrix4f matrix4f = stack.last().pose(); // bottom - buffer.vertex(matrix4f, (float) toDraw.minX, (float) toDraw.minY, (float) toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) toDraw.maxX, (float) toDraw.minY, (float) toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) toDraw.maxX, (float) toDraw.minY, (float) toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) toDraw.maxX, (float) toDraw.minY, (float) toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) toDraw.maxX, (float) toDraw.minY, (float) toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) toDraw.minX, (float) toDraw.minY, (float) toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) toDraw.minX, (float) toDraw.minY, (float) toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) toDraw.minX, (float) toDraw.minY, (float) toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + emitLine(stack, toDraw.minX, toDraw.minY, toDraw.minZ, toDraw.maxX, toDraw.minY, toDraw.minZ); + emitLine(stack, toDraw.maxX, toDraw.minY, toDraw.minZ, toDraw.maxX, toDraw.minY, toDraw.maxZ); + emitLine(stack, toDraw.maxX, toDraw.minY, toDraw.maxZ, toDraw.minX, toDraw.minY, toDraw.maxZ); + emitLine(stack, toDraw.minX, toDraw.minY, toDraw.maxZ, toDraw.minX, toDraw.minY, toDraw.minZ); // top - buffer.vertex(matrix4f, (float) toDraw.minX, (float) toDraw.maxY, (float) toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) toDraw.maxX, (float) toDraw.maxY, (float) toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) toDraw.maxX, (float) toDraw.maxY, (float) toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) toDraw.maxX, (float) toDraw.maxY, (float) toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) toDraw.maxX, (float) toDraw.maxY, (float) toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) toDraw.minX, (float) toDraw.maxY, (float) toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) toDraw.minX, (float) toDraw.maxY, (float) toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) toDraw.minX, (float) toDraw.maxY, (float) toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + emitLine(stack, toDraw.minX, toDraw.maxY, toDraw.minZ, toDraw.maxX, toDraw.maxY, toDraw.minZ); + emitLine(stack, toDraw.maxX, toDraw.maxY, toDraw.minZ, toDraw.maxX, toDraw.maxY, toDraw.maxZ); + emitLine(stack, toDraw.maxX, toDraw.maxY, toDraw.maxZ, toDraw.minX, toDraw.maxY, toDraw.maxZ); + emitLine(stack, toDraw.minX, toDraw.maxY, toDraw.maxZ, toDraw.minX, toDraw.maxY, toDraw.minZ); // corners - buffer.vertex(matrix4f, (float) toDraw.minX, (float) toDraw.minY, (float) toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) toDraw.minX, (float) toDraw.maxY, (float) toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) toDraw.maxX, (float) toDraw.minY, (float) toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) toDraw.maxX, (float) toDraw.maxY, (float) toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) toDraw.maxX, (float) toDraw.minY, (float) toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) toDraw.maxX, (float) toDraw.maxY, (float) toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) toDraw.minX, (float) toDraw.minY, (float) toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) toDraw.minX, (float) toDraw.maxY, (float) toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + emitLine(stack, toDraw.minX, toDraw.minY, toDraw.minZ, toDraw.minX, toDraw.maxY, toDraw.minZ); + emitLine(stack, toDraw.maxX, toDraw.minY, toDraw.minZ, toDraw.maxX, toDraw.maxY, toDraw.minZ); + emitLine(stack, toDraw.maxX, toDraw.minY, toDraw.maxZ, toDraw.maxX, toDraw.maxY, toDraw.maxZ); + emitLine(stack, toDraw.minX, toDraw.minY, toDraw.maxZ, toDraw.minX, toDraw.maxY, toDraw.maxZ); } static void emitAABB(PoseStack stack, AABB aabb, double expand) { emitAABB(stack, aabb.inflate(expand, expand, expand)); } - - static void drawAABB(PoseStack stack, AABB aabb) { - buffer.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR); - emitAABB(stack, aabb); - tessellator.end(); - } } diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index 304de21cd..edb3bca5d 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -28,6 +28,7 @@ import baritone.behavior.PathingBehavior; import baritone.pathing.path.PathExecutor; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Matrix3f; import com.mojang.math.Matrix4f; import net.minecraft.client.renderer.blockentity.BeaconRenderer; import net.minecraft.core.BlockPos; @@ -46,8 +47,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import static org.lwjgl.opengl.GL11.*; - /** * @author Brady * @since 8/9/2018 @@ -168,31 +167,35 @@ public final class PathRenderer implements IRenderer { IRenderer.glColor(color, alpha); } - emitLine(stack, start.x, start.y, start.z, end.x, end.y, end.z); + emitPathLine(stack, start.x, start.y, start.z, end.x, end.y, end.z); } IRenderer.endLines(settings.renderPathIgnoreDepth.value); } - private static void emitLine(PoseStack stack, double x1, double y1, double z1, double x2, double y2, double z2) { - Matrix4f matrix4f = stack.last().pose(); + private static void emitPathLine(PoseStack stack, double x1, double y1, double z1, double x2, double y2, double z2) { double vpX = posX(); double vpY = posY(); double vpZ = posZ(); boolean renderPathAsFrickinThingy = !settings.renderPathAsLine.value; - buffer.vertex(matrix4f, (float) (x1 + 0.5D - vpX), (float) (y1 + 0.5D - vpY), (float) (z1 + 0.5D - vpZ)).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) (x2 + 0.5D - vpX), (float) (y2 + 0.5D - vpY), (float) (z2 + 0.5D - vpZ)).color(color[0], color[1], color[2], color[3]).endVertex(); - + IRenderer.emitLine(stack, + x1 + 0.5D - vpX, y1 + 0.5D - vpY, z1 + 0.5D - vpZ, + x2 + 0.5D - vpX, y2 + 0.5D - vpY, z2 + 0.5D - vpZ + ); if (renderPathAsFrickinThingy) { - buffer.vertex(matrix4f, (float) (x2 + 0.5D - vpX), (float) (y2 + 0.5D - vpY), (float) (z2 + 0.5D - vpZ)).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) (x2 + 0.5D - vpX), (float) (y2 + 0.53D - vpY), (float) (z2 + 0.5D - vpZ)).color(color[0], color[1], color[2], color[3]).endVertex(); - - buffer.vertex(matrix4f, (float) (x2 + 0.5D - vpX), (float) (y2 + 0.53D - vpY), (float) (z2 + 0.5D - vpZ)).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) (x1 + 0.5D - vpX), (float) (y1 + 0.53D - vpY), (float) (z1 + 0.5D - vpZ)).color(color[0], color[1], color[2], color[3]).endVertex(); - - buffer.vertex(matrix4f, (float) (x1 + 0.5D - vpX), (float) (y1 + 0.53D - vpY), (float) (z1 + 0.5D - vpZ)).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) (x1 + 0.5D - vpX), (float) (y1 + 0.5D - vpY), (float) (z1 + 0.5D - vpZ)).color(color[0], color[1], color[2], color[3]).endVertex(); + IRenderer.emitLine(stack, + x2 + 0.5D - vpX, y2 + 0.5D - vpY, z2 + 0.5D - vpZ, + x2 + 0.5D - vpX, y2 + 0.53D - vpY, z2 + 0.5D - vpZ + ); + IRenderer.emitLine(stack, + x2 + 0.5D - vpX, y2 + 0.53D - vpY, z2 + 0.5D - vpZ, + x1 + 0.5D - vpX, y1 + 0.53D - vpY, z1 + 0.5D - vpZ + ); + IRenderer.emitLine(stack, + x1 + 0.5D - vpX, y1 + 0.53D - vpY, z1 + 0.5D - vpZ, + x1 + 0.5D - vpX, y1 + 0.5D - vpY, z1 + 0.5D - vpZ + ); } } @@ -256,8 +259,6 @@ public final class PathRenderer implements IRenderer { maxY = ctx.world().getMaxBuildHeight(); if (settings.renderGoalXZBeacon.value) { - glPushAttrib(GL_LIGHTING_BIT); - //TODO: check textureManager.bindForSetup(TEXTURE_BEACON_BEAM); if (settings.renderGoalIgnoreDepth.value) { @@ -289,8 +290,6 @@ public final class PathRenderer implements IRenderer { if (settings.renderGoalIgnoreDepth.value) { RenderSystem.enableDepthTest(); } - - glPopAttrib(); return; } @@ -341,15 +340,10 @@ public final class PathRenderer implements IRenderer { renderHorizontalQuad(stack, minX, maxX, minZ, maxZ, y1); renderHorizontalQuad(stack, minX, maxX, minZ, maxZ, y2); - Matrix4f matrix4f = stack.last().pose(); - buffer.vertex(matrix4f, (float) minX, (float) minY, (float) minZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) minX, (float) maxY, (float) minZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) maxX, (float) minY, (float) minZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) maxX, (float) maxY, (float) minZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) maxX, (float) minY, (float) maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) maxX, (float) maxY, (float) maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) minX, (float) minY, (float) maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) minX, (float) maxY, (float) maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + IRenderer.emitLine(stack, minX, minY, minZ, minX, maxY, minZ); + IRenderer.emitLine(stack, maxX, minY, minZ, maxX, maxY, minZ); + IRenderer.emitLine(stack, maxX, minY, maxZ, maxX, maxY, maxZ); + IRenderer.emitLine(stack, minX, minY, maxZ, minX, maxY, maxZ); if (setupRender) { IRenderer.endLines(settings.renderGoalIgnoreDepth.value); @@ -358,18 +352,10 @@ public final class PathRenderer implements IRenderer { private static void renderHorizontalQuad(PoseStack stack, double minX, double maxX, double minZ, double maxZ, double y) { if (y != 0) { - Matrix4f matrix4f = stack.last().pose(); - buffer.vertex(matrix4f, (float) minX, (float) y, (float) minZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) maxX, (float) y, (float) minZ).color(color[0], color[1], color[2], color[3]).endVertex(); - - buffer.vertex(matrix4f, (float) maxX, (float) y, (float) minZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) maxX, (float) y, (float) maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); - - buffer.vertex(matrix4f, (float) maxX, (float) y, (float) maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) minX, (float) y, (float) maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); - - buffer.vertex(matrix4f, (float) minX, (float) y, (float) maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(matrix4f, (float) minX, (float) y, (float) minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + IRenderer.emitLine(stack, minX, y, minZ, maxX, y, minZ); + IRenderer.emitLine(stack, maxX, y, minZ, maxX, y, maxZ); + IRenderer.emitLine(stack, maxX, y, maxZ, minX, y, maxZ); + IRenderer.emitLine(stack, minX, y, maxZ, minX, y, minZ); } } } From 1b82bd1f33b7bc76537f7a299917d78862dbd217 Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 17 Jul 2023 17:58:08 -0500 Subject: [PATCH 322/405] pitch smooth look and setting for ticks --- src/api/java/baritone/api/Settings.java | 15 +++++++-- .../java/baritone/behavior/LookBehavior.java | 32 ++++++++++++------- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 2ec56b1a4..3ab2a068b 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -742,10 +742,21 @@ public final class Settings { public final Setting elytraFreeLook = new Setting<>(false); /** - * Forces the client-sided rotations to an average of the last 10 ticks of server-sided rotations. + * Forces the client-sided yaw rotation to an average of the last {@link #smoothLookTicks} of server-sided rotations. * Requires {@link #freeLook}. */ - public final Setting smoothLook = new Setting<>(false); + public final Setting smoothLookYaw = new Setting<>(false); + + /** + * Forces the client-sided pitch rotation to an average of the last {@link #smoothLookTicks} of server-sided rotations. + * Requires {@link #freeLook}. + */ + public final Setting smoothLookPitch = new Setting<>(false); + + /** + * The number of ticks to average across for {@link #smoothLookYaw} and {@link #smoothLookPitch}; + */ + public final Setting smoothLookTicks = new Setting<>(10); /** * When true, the player will remain with its existing look direction as often as possible. diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index d93607644..5f6421d08 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -26,9 +26,10 @@ import baritone.api.event.events.*; import baritone.api.utils.IPlayerContext; import baritone.api.utils.Rotation; import baritone.behavior.look.ForkableRandom; -import com.google.common.collect.EvictingQueue; import net.minecraft.network.play.client.CPacketPlayer; +import java.util.ArrayDeque; +import java.util.Deque; import java.util.Optional; public final class LookBehavior extends Behavior implements ILookBehavior { @@ -52,12 +53,14 @@ public final class LookBehavior extends Behavior implements ILookBehavior { private final AimProcessor processor; - private final EvictingQueue smoothYawBuffer; + private final Deque smoothYawBuffer; + private final Deque smoothPitchBuffer; public LookBehavior(Baritone baritone) { super(baritone); this.processor = new AimProcessor(baritone.getPlayerContext()); - this.smoothYawBuffer = EvictingQueue.create(10); + this.smoothYawBuffer = new ArrayDeque<>(); + this.smoothPitchBuffer = new ArrayDeque<>(); } @Override @@ -100,15 +103,22 @@ public final class LookBehavior extends Behavior implements ILookBehavior { case POST: { // Reset the player's rotations back to their original values if (this.prevRotation != null) { - if (Baritone.settings().smoothLook.value) { - this.smoothYawBuffer.add(this.target.rotation.getYaw()); - ctx.player().rotationYaw = (float) this.smoothYawBuffer.stream() - .mapToDouble(d -> d).average().orElseGet(this.prevRotation::getYaw); - ctx.player().rotationPitch = this.prevRotation.getPitch(); - } else { - ctx.player().rotationYaw = this.prevRotation.getYaw(); - ctx.player().rotationPitch = this.prevRotation.getPitch(); + this.smoothYawBuffer.add(this.target.rotation.getYaw()); + while (this.smoothYawBuffer.size() > Baritone.settings().smoothLookTicks.value) { + this.smoothYawBuffer.pop(); } + this.smoothPitchBuffer.add(this.target.rotation.getPitch()); + while (this.smoothPitchBuffer.size() > Baritone.settings().smoothLookTicks.value) { + this.smoothPitchBuffer.pop(); + } + + ctx.player().rotationYaw = Baritone.settings().smoothLookYaw.value + ? (float) this.smoothYawBuffer.stream().mapToDouble(d -> d).average().orElseGet(this.prevRotation::getYaw) + : this.prevRotation.getYaw(); + ctx.player().rotationPitch = Baritone.settings().smoothLookPitch.value + ? (float) this.smoothPitchBuffer.stream().mapToDouble(d -> d).average().orElseGet(this.prevRotation::getPitch) + : this.prevRotation.getPitch(); + this.prevRotation = null; } // The target is done being used for this game tick, so it can be invalidated From 9a6241af8a5cf4d8bd686ccefc3a3dab11dbfeff Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sun, 16 Jul 2023 22:56:17 -0400 Subject: [PATCH 323/405] refactor elytra into being just a process --- src/api/java/baritone/api/IBaritone.java | 13 +- .../IElytraProcess.java} | 9 +- src/main/java/baritone/Baritone.java | 11 +- .../baritone/behavior/PathingBehavior.java | 2 +- .../command/defaults/ElytraCommand.java | 4 +- .../defaults/ExecutionControlCommands.java | 2 +- .../command/defaults/ForceCancelCommand.java | 2 +- .../java/baritone/process/ElytraProcess.java | 255 ++++++++++++++++ .../elytra/BlockStateOctreeInterface.java | 2 +- .../elytra/LegacyElytraBehavior.java} | 275 +++--------------- .../elytra/NetherPath.java | 2 +- .../elytra/NetherPathfinderContext.java | 4 +- .../elytra/NullElytraProcess.java} | 26 +- .../elytra/PathCalculationException.java | 2 +- .../elytra/UnpackedSegment.java | 2 +- 15 files changed, 340 insertions(+), 271 deletions(-) rename src/api/java/baritone/api/{behavior/IElytraBehavior.java => process/IElytraProcess.java} (87%) create mode 100644 src/main/java/baritone/process/ElytraProcess.java rename src/main/java/baritone/{behavior => process}/elytra/BlockStateOctreeInterface.java (98%) rename src/main/java/baritone/{behavior/ElytraBehavior.java => process/elytra/LegacyElytraBehavior.java} (84%) rename src/main/java/baritone/{behavior => process}/elytra/NetherPath.java (98%) rename src/main/java/baritone/{behavior => process}/elytra/NetherPathfinderContext.java (98%) rename src/main/java/baritone/{behavior/elytra/NullElytraBehavior.java => process/elytra/NullElytraProcess.java} (72%) rename src/main/java/baritone/{behavior => process}/elytra/PathCalculationException.java (96%) rename src/main/java/baritone/{behavior => process}/elytra/UnpackedSegment.java (98%) diff --git a/src/api/java/baritone/api/IBaritone.java b/src/api/java/baritone/api/IBaritone.java index 0913a8c43..3c9681532 100644 --- a/src/api/java/baritone/api/IBaritone.java +++ b/src/api/java/baritone/api/IBaritone.java @@ -17,7 +17,6 @@ package baritone.api; -import baritone.api.behavior.IElytraBehavior; import baritone.api.behavior.ILookBehavior; import baritone.api.behavior.IPathingBehavior; import baritone.api.cache.IWorldProvider; @@ -41,12 +40,6 @@ public interface IBaritone { */ IPathingBehavior getPathingBehavior(); - /** - * @return The {@link IElytraBehavior} instance - * @see IElytraBehavior - */ - IElytraBehavior getElytraBehavior(); - /** * @return The {@link ILookBehavior} instance * @see ILookBehavior @@ -95,6 +88,12 @@ public interface IBaritone { */ IGetToBlockProcess getGetToBlockProcess(); + /** + * @return The {@link IElytraProcess} instance + * @see IElytraProcess + */ + IElytraProcess getElytraProcess(); + /** * @return The {@link IWorldProvider} instance * @see IWorldProvider diff --git a/src/api/java/baritone/api/behavior/IElytraBehavior.java b/src/api/java/baritone/api/process/IElytraProcess.java similarity index 87% rename from src/api/java/baritone/api/behavior/IElytraBehavior.java rename to src/api/java/baritone/api/process/IElytraProcess.java index 95ae62926..06c658f42 100644 --- a/src/api/java/baritone/api/behavior/IElytraBehavior.java +++ b/src/api/java/baritone/api/process/IElytraProcess.java @@ -15,13 +15,13 @@ * along with Baritone. If not, see . */ -package baritone.api.behavior; +package baritone.api.process; import net.minecraft.util.math.BlockPos; import java.util.concurrent.CompletableFuture; -public interface IElytraBehavior extends IBehavior { +public interface IElytraProcess extends IBaritoneProcess { /** * Marks the nether pathfinder context to be reset when it is safe to do so. Because this operation is not @@ -37,11 +37,6 @@ public interface IElytraBehavior extends IBehavior { void cancel(); - /** - * Returns {@code true} if the current {@link IElytraBehavior} is actively pathing. - */ - boolean isActive(); - /** * @return {@code true} if the native library loaded and elytra is actually usable */ diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index 61866e927..c6d31a3dd 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -21,9 +21,9 @@ import baritone.api.BaritoneAPI; import baritone.api.IBaritone; import baritone.api.Settings; import baritone.api.behavior.IBehavior; -import baritone.api.behavior.IElytraBehavior; import baritone.api.event.listener.IEventBus; import baritone.api.process.IBaritoneProcess; +import baritone.api.process.IElytraProcess; import baritone.api.utils.IPlayerContext; import baritone.behavior.*; import baritone.cache.WorldProvider; @@ -68,7 +68,6 @@ public class Baritone implements IBaritone { private final List behaviors; private final PathingBehavior pathingBehavior; - private final IElytraBehavior elytraBehavior; private final LookBehavior lookBehavior; private final InventoryBehavior inventoryBehavior; private final InputOverrideHandler inputOverrideHandler; @@ -81,6 +80,7 @@ public class Baritone implements IBaritone { private final ExploreProcess exploreProcess; private final FarmProcess farmProcess; private final InventoryPauserProcess inventoryPauserProcess; + private final ElytraProcess elytraProcess; private final PathingControlManager pathingControlManager; private final SelectionManager selectionManager; @@ -108,7 +108,6 @@ public class Baritone implements IBaritone { { this.lookBehavior = this.registerBehavior(LookBehavior::new); - this.elytraBehavior = this.registerBehavior(ElytraBehavior::create); this.pathingBehavior = this.registerBehavior(PathingBehavior::new); this.inventoryBehavior = this.registerBehavior(InventoryBehavior::new); this.inputOverrideHandler = this.registerBehavior(InputOverrideHandler::new); @@ -125,6 +124,8 @@ public class Baritone implements IBaritone { this.exploreProcess = this.registerProcess(ExploreProcess::new); this.farmProcess = this.registerProcess(FarmProcess::new); this.inventoryPauserProcess = this.registerProcess(InventoryPauserProcess::new); + this.elytraProcess = this.registerProcess(ElytraProcess::create); + this.registerProcess(BackfillProcess::new); } @@ -241,8 +242,8 @@ public class Baritone implements IBaritone { } @Override - public IElytraBehavior getElytraBehavior() { - return this.elytraBehavior; + public IElytraProcess getElytraProcess() { + return this.elytraProcess; } @Override diff --git a/src/main/java/baritone/behavior/PathingBehavior.java b/src/main/java/baritone/behavior/PathingBehavior.java index 670dd827c..0404921ae 100644 --- a/src/main/java/baritone/behavior/PathingBehavior.java +++ b/src/main/java/baritone/behavior/PathingBehavior.java @@ -310,7 +310,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, public boolean isSafeToCancel() { if (current == null) { - return !baritone.getElytraBehavior().isActive() || baritone.getElytraBehavior().isSafeToCancel(); + return !baritone.getElytraProcess().isActive() || baritone.getElytraProcess().isSafeToCancel(); } return safeToCancel; } diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index 5288ade47..05695d82b 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -18,7 +18,6 @@ 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; @@ -27,6 +26,7 @@ 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; @@ -42,7 +42,7 @@ public class ElytraCommand extends Command { @Override public void execute(String label, IArgConsumer args) throws CommandException { final ICustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess(); - final IElytraBehavior elytra = baritone.getElytraBehavior(); + final IElytraProcess elytra = baritone.getElytraProcess(); if (!elytra.isLoaded()) { final String osArch = System.getProperty("os.arch"); final String osName = System.getProperty("os.name"); diff --git a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java index 43adca19f..b91014a67 100644 --- a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java +++ b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java @@ -180,7 +180,7 @@ public class ExecutionControlCommands { paused[0] = false; } baritone.getPathingBehavior().cancelEverything(); - baritone.getElytraBehavior().cancel(); + baritone.getElytraProcess().cancel(); // TODO: this shouldnt be necessary logDirect("ok canceled"); } diff --git a/src/main/java/baritone/command/defaults/ForceCancelCommand.java b/src/main/java/baritone/command/defaults/ForceCancelCommand.java index ad19f168c..d86cddd5e 100644 --- a/src/main/java/baritone/command/defaults/ForceCancelCommand.java +++ b/src/main/java/baritone/command/defaults/ForceCancelCommand.java @@ -39,7 +39,7 @@ public class ForceCancelCommand extends Command { IPathingBehavior pathingBehavior = baritone.getPathingBehavior(); pathingBehavior.cancelEverything(); pathingBehavior.forceCancel(); - baritone.getElytraBehavior().cancel(); + baritone.getElytraProcess().cancel(); logDirect("ok force canceled"); } diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java new file mode 100644 index 000000000..121b37b8a --- /dev/null +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -0,0 +1,255 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.process; + +import baritone.Baritone; +import baritone.api.pathing.goals.Goal; +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; +import baritone.api.process.PathingCommandType; +import baritone.api.utils.BetterBlockPos; +import baritone.api.utils.Rotation; +import baritone.api.utils.RotationUtils; +import baritone.api.utils.input.Input; +import baritone.pathing.movement.movements.MovementFall; +import baritone.process.elytra.LegacyElytraBehavior; +import baritone.process.elytra.NetherPathfinderContext; +import baritone.process.elytra.NullElytraProcess; +import baritone.utils.BaritoneProcessHelper; +import baritone.utils.PathingCommandContext; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; + + +import java.util.concurrent.*; +import java.util.function.Supplier; + +public class ElytraProcess extends BaritoneProcessHelper implements IBaritoneProcess, IElytraProcess { + public State state; + private Goal goal; + private LegacyElytraBehavior behavior; + + private ElytraProcess(Baritone baritone) { + super(baritone); + this.behavior = new LegacyElytraBehavior(baritone, this); + baritone.getGameEventHandler().registerEventListener(this.behavior); + } + + public static T create(final Baritone baritone) { + return (T) (NetherPathfinderContext.isSupported() + ? new ElytraProcess(baritone) + : new NullElytraProcess(baritone)); + } + + @Override + public boolean isActive() { + return behavior.destination != null; + } + + @Override + public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { + if (calcFailed) { + onLostControl(); + logDirect("Failed to get to jump off spot, canceling"); + return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); + } + + if (ctx.player().isElytraFlying()) { + final BetterBlockPos last = behavior.pathManager.path.getLast(); + if (last != null && ctx.player().getDistanceSqToCenter(last) < (5 * 5)) { + this.state = State.LANDING; + } + } + + if (this.state == State.LANDING) { + final BetterBlockPos endPos = behavior.pathManager.path.getLast(); + if (ctx.player().isElytraFlying() && endPos != null) { + Vec3d from = ctx.player().getPositionVector(); + Vec3d to = new Vec3d(endPos.x, from.y, endPos.z); + Rotation rotation = RotationUtils.calcRotationFromVec3d(from, to, ctx.playerRotations()); + baritone.getLookBehavior().updateTarget(rotation, false); + } else { + this.onLostControl(); + return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); + } + } else if (ctx.player().isElytraFlying()) { + this.state = State.FLYING; + this.goal = null; + baritone.getInputOverrideHandler().clearAllKeys(); + behavior.tick(); + return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); + } + + if (this.state == State.FLYING || this.state == State.START_FLYING) { + this.state = ctx.player().onGround && Baritone.settings().elytraAutoJump.value + ? State.LOCATE_JUMP + : State.START_FLYING; + } + + if (this.state == State.LOCATE_JUMP) { + if (this.goal == null) { + this.goal = new GoalYLevel(31); + } + 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 + ); + behavior.pathManager.pathToDestination(from).whenComplete((result, ex) -> { + if (!behavior.clearView(new Vec3d(from), behavior.pathManager.getPath().getVec(0), false)) { + onLostControl(); + // TODO: Get to higher ground and then look again + logDirect("Can't see start of path from jump spot, canceling"); + return; + } + if (ex == null) { + this.state = State.GET_TO_JUMP; + return; + } + onLostControl(); + }); + this.state = State.PAUSE; + } else { + onLostControl(); + logDirect("Jump off path didn't include a fall movement, canceling"); + return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); + } + } + return new PathingCommandContext(this.goal, PathingCommandType.SET_GOAL_AND_PAUSE, new LegacyElytraBehavior.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) { + baritone.getInputOverrideHandler().setInputForceState(Input.JUMP, true); + } + } + return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); + } + + @Override + public boolean isTemporary() { + return false; + } + + @Override + public void onLostControl() { + this.goal = null; + this.state = State.START_FLYING; + behavior.cancel(); + } + + + + @Override + public String displayName0() { + final Supplier status = () -> { + switch (this.state) { + case LOCATE_JUMP: + return "Finding spot to jump off"; + case PAUSE: + return "Waiting for elytra path"; + case GET_TO_JUMP: + return "Walking to takeoff"; + case START_FLYING: + return "Begin flying"; + case FLYING: + return "Flying"; + case LANDING: + return "Landing"; + default: + return "Unknown"; + } + }; + return "Elytra - " + status.get(); + } + + @Override + public CompletableFuture resetContext() { + return behavior.resetContext(); + } + + @Override + public void repackChunks() { + behavior.repackChunks(); + } + + @Override + public void pathTo(BlockPos destination) { + behavior.pathTo(destination); + } + + @Override + public void cancel() { + behavior.cancel(); + } + + @Override + public boolean isLoaded() { + return true; + } + + @Override + public boolean isSafeToCancel() { + return behavior.isSafeToCancel(); + } + + public enum State { + LOCATE_JUMP, + VALIDATE_PATH, + PAUSE, + GET_TO_JUMP, + START_FLYING, + FLYING, + LANDING + } +} diff --git a/src/main/java/baritone/behavior/elytra/BlockStateOctreeInterface.java b/src/main/java/baritone/process/elytra/BlockStateOctreeInterface.java similarity index 98% rename from src/main/java/baritone/behavior/elytra/BlockStateOctreeInterface.java rename to src/main/java/baritone/process/elytra/BlockStateOctreeInterface.java index b81a6aed5..f9e700085 100644 --- a/src/main/java/baritone/behavior/elytra/BlockStateOctreeInterface.java +++ b/src/main/java/baritone/process/elytra/BlockStateOctreeInterface.java @@ -15,7 +15,7 @@ * along with Baritone. If not, see . */ -package baritone.behavior.elytra; +package baritone.process.elytra; import dev.babbaj.pathfinder.NetherPathfinder; import dev.babbaj.pathfinder.Octree; diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java similarity index 84% rename from src/main/java/baritone/behavior/ElytraBehavior.java rename to src/main/java/baritone/process/elytra/LegacyElytraBehavior.java index 6e1765180..48066f3ea 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java @@ -15,33 +15,23 @@ * along with Baritone. If not, see . */ -package baritone.behavior; +package baritone.process.elytra; import baritone.Baritone; import baritone.api.IBaritone; import baritone.api.Settings; -import baritone.api.behavior.IElytraBehavior; import baritone.api.behavior.look.IAimProcessor; import baritone.api.behavior.look.ITickableAimProcessor; import baritone.api.event.events.*; import baritone.api.event.events.type.EventState; -import baritone.api.pathing.goals.Goal; +import baritone.api.event.listener.AbstractGameEventListener; import baritone.api.pathing.goals.GoalBlock; -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.PathingCommand; -import baritone.api.process.PathingCommandType; import baritone.api.utils.*; -import baritone.api.utils.input.Input; -import baritone.behavior.elytra.*; import baritone.pathing.movement.CalculationContext; -import baritone.pathing.movement.movements.MovementFall; +import baritone.process.ElytraProcess; import baritone.utils.BlockStateInterface; import baritone.utils.IRenderer; import baritone.utils.PathRenderer; -import baritone.utils.PathingCommandContext; import baritone.utils.accessor.IChunkProviderClient; import baritone.utils.accessor.IEntityFireworkRocket; import it.unimi.dsi.fastutil.floats.FloatArrayList; @@ -67,14 +57,16 @@ import java.awt.*; import java.util.*; import java.util.List; import java.util.concurrent.*; -import java.util.function.Supplier; import java.util.function.UnaryOperator; import static baritone.api.pathing.movement.ActionCosts.COST_INF; import static baritone.utils.BaritoneMath.fastCeil; import static baritone.utils.BaritoneMath.fastFloor; -public final class ElytraBehavior extends Behavior implements IElytraBehavior, Helper { +public final class LegacyElytraBehavior implements AbstractGameEventListener, Helper { + private final Baritone baritone; + private final IPlayerContext ctx; + // Used exclusively for PathRenderer public List> clearLines; @@ -86,7 +78,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // :sunglasses: private NetherPathfinderContext context; private CompletableFuture forceResetContext; - private final PathManager pathManager; + public final PathManager pathManager; private final ElytraProcess process; /** @@ -111,7 +103,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private BlockStateInterface bsi; private BlockStateOctreeInterface boi; - private BlockPos destination; + public BlockPos destination; private final ExecutorService solverExecutor; private Future solver; @@ -124,24 +116,20 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private int invTickCountdown = 0; private final Queue invTransactionQueue = new LinkedList<>(); - private ElytraBehavior(Baritone baritone) { - super(baritone); + public LegacyElytraBehavior(Baritone baritone, ElytraProcess process) { + this.baritone = baritone; + this.ctx = baritone.getPlayerContext(); this.clearLines = new CopyOnWriteArrayList<>(); this.blockedLines = new CopyOnWriteArrayList<>(); this.pathManager = this.new PathManager(); - this.process = new ElytraProcess(); + this.process = process; this.solverExecutor = Executors.newSingleThreadExecutor(); this.nextTickBoostCounter = new int[2]; } - @Override - public void onLoad() { - baritone.getPathingControlManager().registerProcess(this.process); - } + public final class PathManager { - private final class PathManager { - - private NetherPath path; + public NetherPath path; private boolean completePath; private boolean recalculating; @@ -177,7 +165,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H public CompletableFuture pathToDestination(final BlockPos from) { final long start = System.nanoTime(); - return this.path0(from, ElytraBehavior.this.destination, UnaryOperator.identity()) + return this.path0(from, LegacyElytraBehavior.this.destination, UnaryOperator.identity()) .thenRun(() -> { final double distance = this.path.get(0).distanceTo(this.path.get(this.path.size() - 1)); if (this.completePath) { @@ -231,7 +219,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H final List before = this.path.subList(0, afterIncl + 1); final long start = System.nanoTime(); - this.path0(this.path.get(afterIncl), ElytraBehavior.this.destination, segment -> segment.prepend(before.stream())) + this.path0(this.path.get(afterIncl), LegacyElytraBehavior.this.destination, segment -> segment.prepend(before.stream())) .thenRun(() -> { final int recompute = this.path.size() - before.size() - 1; final double distance = this.path.get(0).distanceTo(this.path.get(recompute)); @@ -282,7 +270,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H // mickey resigned private CompletableFuture path0(BlockPos src, BlockPos dst, UnaryOperator operator) { - return ElytraBehavior.this.context.pathFindAsync(src, dst) + return LegacyElytraBehavior.this.context.pathFindAsync(src, dst) .thenApply(UnpackedSegment::from) .thenApply(operator) .thenAcceptAsync(this::setPath, ctx.minecraft()::addScheduledTask); @@ -303,12 +291,12 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return; } final BetterBlockPos rangeStart = path.get(rangeStartIncl); - if (!ElytraBehavior.this.passable(rangeStart.x, rangeStart.y, rangeStart.z, false)) { + if (!LegacyElytraBehavior.this.passable(rangeStart.x, rangeStart.y, rangeStart.z, false)) { // we're in a wall return; // previous iterations of this function SHOULD have fixed this by now :rage_cat: } - if (ElytraBehavior.this.process.state != State.LANDING && this.ticksNearUnchanged > 100) { + if (LegacyElytraBehavior.this.process.state != ElytraProcess.State.LANDING && this.ticksNearUnchanged > 100) { this.pathRecalcSegment(rangeEndExcl - 1) .thenRun(() -> { logDirect("Recalculating segment, no progress in last 100 ticks"); @@ -318,7 +306,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } for (int i = rangeStartIncl; i < rangeEndExcl - 1; i++) { - if (!ElytraBehavior.this.clearView(this.path.getVec(i), this.path.getVec(i + 1), false)) { + if (!LegacyElytraBehavior.this.clearView(this.path.getVec(i), this.path.getVec(i + 1), false)) { // obstacle. where do we return to pathing? // find the next valid segment final BetterBlockPos blockage = this.path.get(i); @@ -461,7 +449,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } - @Override public void pathTo(BlockPos destination) { this.destination = destination; if (!Baritone.settings().elytraAutoJump.value || ctx.player().isElytraFlying()) { @@ -469,7 +456,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } - @Override public void cancel() { this.destination = null; this.pathManager.clear(); @@ -483,7 +469,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H Arrays.fill(this.nextTickBoostCounter, 0); } - @Override public CompletableFuture resetContext() { if (this.forceResetContext == null) { this.forceResetContext = new CompletableFuture<>(); @@ -491,26 +476,18 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H 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() .filter(process -> this.process == process).isPresent(); } - @Override - public boolean isLoaded() { - return true; - } - - @Override public boolean isSafeToCancel() { - return !this.isActive() || !(this.process.state == State.FLYING || this.process.state == State.START_FLYING); + return !this.isActive() || !(this.process.state == ElytraProcess.State.FLYING || this.process.state == ElytraProcess.State.START_FLYING); } @Override @@ -598,9 +575,9 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } /** - * Called by {@link ElytraProcess#onTick(boolean, boolean)} when the process is in control and the player is flying + * Called by {@link baritone.process.ElytraProcess#onTick(boolean, boolean)} when the process is in control and the player is flying */ - private void tick() { + public void tick() { if (this.pathManager.getPath().isEmpty()) { return; } @@ -770,8 +747,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H ) { // Prioritize boosting fireworks over regular ones // TODO: Take the minimum boost time into account? - if (!baritone.getInventoryBehavior().throwaway(true, ElytraBehavior::isBoostingFireworks) && - !baritone.getInventoryBehavior().throwaway(true, ElytraBehavior::isFireworks)) { + if (!baritone.getInventoryBehavior().throwaway(true, LegacyElytraBehavior::isBoostingFireworks) && + !baritone.getInventoryBehavior().throwaway(true, LegacyElytraBehavior::isFireworks)) { logDirect("no fireworks"); return; } @@ -793,21 +770,21 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H public final IAimProcessor aimProcessor; public SolverContext(boolean async) { - this.path = ElytraBehavior.this.pathManager.getPath(); - this.playerNear = ElytraBehavior.this.pathManager.getNear(); - this.start = ElytraBehavior.this.ctx.playerFeetAsVec(); - this.ignoreLava = ElytraBehavior.this.ctx.player().isInLava(); + this.path = LegacyElytraBehavior.this.pathManager.getPath(); + this.playerNear = LegacyElytraBehavior.this.pathManager.getNear(); + this.start = LegacyElytraBehavior.this.ctx.playerFeetAsVec(); + this.ignoreLava = LegacyElytraBehavior.this.ctx.player().isInLava(); final Integer fireworkTicksExisted; - if (async && ElytraBehavior.this.deployedFireworkLastTick) { - final int[] counter = ElytraBehavior.this.nextTickBoostCounter; + if (async && LegacyElytraBehavior.this.deployedFireworkLastTick) { + final int[] counter = LegacyElytraBehavior.this.nextTickBoostCounter; fireworkTicksExisted = counter[1] > counter[0] ? 0 : null; } else { - fireworkTicksExisted = ElytraBehavior.this.getAttachedFirework().map(e -> e.ticksExisted).orElse(null); + fireworkTicksExisted = LegacyElytraBehavior.this.getAttachedFirework().map(e -> e.ticksExisted).orElse(null); } - this.boost = new FireworkBoost(fireworkTicksExisted, ElytraBehavior.this.minimumBoostTicks); + this.boost = new FireworkBoost(fireworkTicksExisted, LegacyElytraBehavior.this.minimumBoostTicks); - ITickableAimProcessor aim = ElytraBehavior.this.baritone.getLookBehavior().getAimProcessor().fork(); + ITickableAimProcessor aim = LegacyElytraBehavior.this.baritone.getLookBehavior().getAimProcessor().fork(); if (async) { // async computation is done at the end of a tick, advance by 1 to prepare for the next tick aim.advance(1); @@ -1001,7 +978,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H return this.context.raytrace(8, src, dst, NetherPathfinderContext.Visibility.ALL); } - private boolean clearView(Vec3d start, Vec3d dest, boolean ignoreLava) { + public boolean clearView(Vec3d start, Vec3d dest, boolean ignoreLava) { final boolean clear; if (!ignoreLava) { // if start == dest then the cpp raytracer dies @@ -1303,7 +1280,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H ItemStack chest = ctx.player().inventory.armorInventory.get(2); if (chest.getItem() != Items.ELYTRA - || chest.getItem().getMaxDamage() - chest.getItemDamage() > Baritone.settings().elytraMinimumDurability.value) { + || chest.getItem().getMaxDamage() - chest.getItemDamage() > Baritone.settings().elytraMinimumDurability.value) { return; } @@ -1382,172 +1359,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } - private final class ElytraProcess implements IBaritoneProcess { - - private State state; - private Goal goal; - - @Override - public boolean isActive() { - return ElytraBehavior.this.destination != null; - } - - @Override - public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { - if (calcFailed) { - onLostControl(); - logDirect("Failed to get to jump off spot, canceling"); - return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); - } - - if (ctx.player().isElytraFlying()) { - final BetterBlockPos last = ElytraBehavior.this.pathManager.path.getLast(); - if (last != null && ctx.player().getDistanceSqToCenter(last) < (5 * 5)) { - this.state = State.LANDING; - } - } - - if (this.state == State.LANDING) { - final BetterBlockPos endPos = ElytraBehavior.this.pathManager.path.getLast(); - if (ctx.player().isElytraFlying() && endPos != null) { - Vec3d from = ctx.player().getPositionVector(); - Vec3d to = new Vec3d(endPos.x, from.y, endPos.z); - Rotation rotation = RotationUtils.calcRotationFromVec3d(from, to, ctx.playerRotations()); - baritone.getLookBehavior().updateTarget(rotation, false); - } else { - this.onLostControl(); - return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); - } - } else if (ctx.player().isElytraFlying()) { - this.state = State.FLYING; - this.goal = null; - baritone.getInputOverrideHandler().clearAllKeys(); - ElytraBehavior.this.tick(); - return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); - } - - if (this.state == State.FLYING || this.state == State.START_FLYING) { - this.state = ctx.player().onGround && Baritone.settings().elytraAutoJump.value - ? State.LOCATE_JUMP - : State.START_FLYING; - } - - if (this.state == State.LOCATE_JUMP) { - if (this.goal == null) { - this.goal = new GoalYLevel(31); - } - 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 - ); - ElytraBehavior.this.pathManager.pathToDestination(from).whenComplete((result, ex) -> { - if (!ElytraBehavior.this.clearView(new Vec3d(from), ElytraBehavior.this.pathManager.getPath().getVec(0), false)) { - onLostControl(); - // TODO: Get to higher ground and then look again - logDirect("Can't see start of path from jump spot, canceling"); - return; - } - if (ex == null) { - this.state = State.GET_TO_JUMP; - return; - } - onLostControl(); - }); - this.state = State.PAUSE; - } else { - onLostControl(); - logDirect("Jump off path didn't include a fall movement, canceling"); - return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); - } - } - 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) { - baritone.getInputOverrideHandler().setInputForceState(Input.JUMP, true); - } - } - return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); - } - - @Override - public boolean isTemporary() { - return false; - } - - @Override - public void onLostControl() { - this.goal = null; - this.state = State.START_FLYING; - ElytraBehavior.this.cancel(); - } - - @Override - public double priority() { - return 10; - } - - @Override - public String displayName0() { - final Supplier status = () -> { - switch (this.state) { - case LOCATE_JUMP: - return "Finding spot to jump off"; - case PAUSE: - return "Waiting for elytra path"; - case GET_TO_JUMP: - return "Walking to takeoff"; - case START_FLYING: - return "Begin flying"; - case FLYING: - return "Flying"; - case LANDING: - return "Landing"; - default: - return "Unknown"; - } - }; - return "Elytra - " + status.get(); - } - } - /** * Custom calculation context which makes the player fall into lava */ - private static final class WalkOffCalculationContext extends CalculationContext { + public static final class WalkOffCalculationContext extends CalculationContext { public WalkOffCalculationContext(IBaritone baritone) { super(baritone, true); @@ -1572,19 +1387,5 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } - private enum State { - LOCATE_JUMP, - VALIDATE_PATH, - PAUSE, - GET_TO_JUMP, - START_FLYING, - FLYING, - LANDING - } - public static T create(final Baritone baritone) { - return (T) (NetherPathfinderContext.isSupported() - ? new ElytraBehavior(baritone) - : new NullElytraBehavior(baritone)); - } } diff --git a/src/main/java/baritone/behavior/elytra/NetherPath.java b/src/main/java/baritone/process/elytra/NetherPath.java similarity index 98% rename from src/main/java/baritone/behavior/elytra/NetherPath.java rename to src/main/java/baritone/process/elytra/NetherPath.java index e746665c4..59cd447ce 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPath.java +++ b/src/main/java/baritone/process/elytra/NetherPath.java @@ -15,7 +15,7 @@ * along with Baritone. If not, see . */ -package baritone.behavior.elytra; +package baritone.process.elytra; import baritone.api.utils.BetterBlockPos; import net.minecraft.util.math.Vec3d; diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/process/elytra/NetherPathfinderContext.java similarity index 98% rename from src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java rename to src/main/java/baritone/process/elytra/NetherPathfinderContext.java index ebe563374..46a840981 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/process/elytra/NetherPathfinderContext.java @@ -15,7 +15,7 @@ * along with Baritone. If not, see . */ -package baritone.behavior.elytra; +package baritone.process.elytra; import baritone.api.event.events.BlockChangeEvent; import baritone.utils.accessor.IBitArray; @@ -38,6 +38,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; /** * @author Brady @@ -51,6 +52,7 @@ public final class NetherPathfinderContext { final long context; private final long seed; private final ExecutorService executor; + private final AtomicInteger packQueueSize = new AtomicInteger(); public NetherPathfinderContext(long seed) { this.context = NetherPathfinder.newContext(seed); diff --git a/src/main/java/baritone/behavior/elytra/NullElytraBehavior.java b/src/main/java/baritone/process/elytra/NullElytraProcess.java similarity index 72% rename from src/main/java/baritone/behavior/elytra/NullElytraBehavior.java rename to src/main/java/baritone/process/elytra/NullElytraProcess.java index b173d82b8..a84caf43f 100644 --- a/src/main/java/baritone/behavior/elytra/NullElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/NullElytraProcess.java @@ -15,11 +15,12 @@ * along with Baritone. If not, see . */ -package baritone.behavior.elytra; +package baritone.process.elytra; import baritone.Baritone; -import baritone.api.behavior.IElytraBehavior; -import baritone.behavior.Behavior; +import baritone.api.process.IElytraProcess; +import baritone.api.process.PathingCommand; +import baritone.utils.BaritoneProcessHelper; import net.minecraft.util.math.BlockPos; import java.util.concurrent.CompletableFuture; @@ -27,9 +28,9 @@ import java.util.concurrent.CompletableFuture; /** * @author Brady */ -public final class NullElytraBehavior extends Behavior implements IElytraBehavior { +public final class NullElytraProcess extends BaritoneProcessHelper implements IElytraProcess { - public NullElytraBehavior(Baritone baritone) { + public NullElytraProcess(Baritone baritone) { super(baritone); } @@ -58,6 +59,21 @@ public final class NullElytraBehavior extends Behavior implements IElytraBehavio return false; } + @Override + public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { + throw new UnsupportedOperationException("Called onTick on NullElytraProcess"); + } + + @Override + public void onLostControl() { + + } + + @Override + public String displayName0() { + return "NullElytraProcess"; + } + @Override public boolean isLoaded() { return false; diff --git a/src/main/java/baritone/behavior/elytra/PathCalculationException.java b/src/main/java/baritone/process/elytra/PathCalculationException.java similarity index 96% rename from src/main/java/baritone/behavior/elytra/PathCalculationException.java rename to src/main/java/baritone/process/elytra/PathCalculationException.java index 73ce82faf..7c9721487 100644 --- a/src/main/java/baritone/behavior/elytra/PathCalculationException.java +++ b/src/main/java/baritone/process/elytra/PathCalculationException.java @@ -15,7 +15,7 @@ * along with Baritone. If not, see . */ -package baritone.behavior.elytra; +package baritone.process.elytra; /** * @author Brady diff --git a/src/main/java/baritone/behavior/elytra/UnpackedSegment.java b/src/main/java/baritone/process/elytra/UnpackedSegment.java similarity index 98% rename from src/main/java/baritone/behavior/elytra/UnpackedSegment.java rename to src/main/java/baritone/process/elytra/UnpackedSegment.java index 0e0759625..02f07feb8 100644 --- a/src/main/java/baritone/behavior/elytra/UnpackedSegment.java +++ b/src/main/java/baritone/process/elytra/UnpackedSegment.java @@ -15,7 +15,7 @@ * along with Baritone. If not, see . */ -package baritone.behavior.elytra; +package baritone.process.elytra; import baritone.api.utils.BetterBlockPos; import dev.babbaj.pathfinder.PathSegment; From dbc0a46b103687f8480f0dc6be688c1ed09e6a0e Mon Sep 17 00:00:00 2001 From: Babbaj Date: Mon, 17 Jul 2023 00:34:48 -0400 Subject: [PATCH 324/405] call elytra event handlers from ElytraProcess --- .../baritone/api/process/IElytraProcess.java | 1 + .../baritone/behavior/PathingBehavior.java | 2 + .../java/baritone/process/ElytraProcess.java | 65 +++++++++++++++---- .../process/elytra/LegacyElytraBehavior.java | 26 ++++---- .../elytra/NetherPathfinderContext.java | 1 - 5 files changed, 66 insertions(+), 29 deletions(-) diff --git a/src/api/java/baritone/api/process/IElytraProcess.java b/src/api/java/baritone/api/process/IElytraProcess.java index 06c658f42..b1bd3d833 100644 --- a/src/api/java/baritone/api/process/IElytraProcess.java +++ b/src/api/java/baritone/api/process/IElytraProcess.java @@ -29,6 +29,7 @@ public interface IElytraProcess extends IBaritoneProcess { * * @return A {@link CompletableFuture} that is completed when the context is reset */ + @Deprecated CompletableFuture resetContext(); void repackChunks(); diff --git a/src/main/java/baritone/behavior/PathingBehavior.java b/src/main/java/baritone/behavior/PathingBehavior.java index 0404921ae..9b15b88ba 100644 --- a/src/main/java/baritone/behavior/PathingBehavior.java +++ b/src/main/java/baritone/behavior/PathingBehavior.java @@ -33,6 +33,7 @@ import baritone.pathing.calc.AbstractNodeCostSearch; import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.MovementHelper; import baritone.pathing.path.PathExecutor; +import baritone.process.ElytraProcess; import baritone.utils.PathRenderer; import baritone.utils.PathingCommandContext; import baritone.utils.pathing.Favoring; @@ -93,6 +94,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, @Override public void onTick(TickEvent event) { + ((ElytraProcess) baritone.getElytraProcess()).onTickBeforePathingBehavior(event); dispatchEvents(); if (event.getType() == TickEvent.Type.OUT) { secretInternalSegmentCancel(); diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index 121b37b8a..11f4fdeaf 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -18,6 +18,8 @@ package baritone.process; import baritone.Baritone; +import baritone.api.event.events.*; +import baritone.api.event.listener.AbstractGameEventListener; import baritone.api.pathing.goals.Goal; import baritone.api.pathing.goals.GoalYLevel; import baritone.api.pathing.movement.IMovement; @@ -43,7 +45,7 @@ import net.minecraft.util.math.Vec3d; import java.util.concurrent.*; import java.util.function.Supplier; -public class ElytraProcess extends BaritoneProcessHelper implements IBaritoneProcess, IElytraProcess { +public class ElytraProcess extends BaritoneProcessHelper implements IBaritoneProcess, IElytraProcess, AbstractGameEventListener { public State state; private Goal goal; private LegacyElytraBehavior behavior; @@ -51,7 +53,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro private ElytraProcess(Baritone baritone) { super(baritone); this.behavior = new LegacyElytraBehavior(baritone, this); - baritone.getGameEventHandler().registerEventListener(this.behavior); + baritone.getGameEventHandler().registerEventListener(this); } public static T create(final Baritone baritone) { @@ -62,7 +64,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro @Override public boolean isActive() { - return behavior.destination != null; + return behavior != null; } @Override @@ -176,16 +178,12 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } - @Override - public boolean isTemporary() { - return false; - } - @Override public void onLostControl() { this.goal = null; - this.state = State.START_FLYING; - behavior.cancel(); + this.state = State.START_FLYING; // TODO: null state? + if (this.behavior != null) this.behavior.cancel(); + this.behavior = null; } @@ -220,17 +218,22 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro @Override public void repackChunks() { - behavior.repackChunks(); + this.behavior.repackChunks(); } @Override public void pathTo(BlockPos destination) { - behavior.pathTo(destination); + this.behavior = new LegacyElytraBehavior(this.baritone, this); + if (ctx.world() != null) { + this.behavior.repackChunks(); + } + this.behavior.pathTo(destination); } @Override public void cancel() { - behavior.cancel(); + if (this.behavior != null) this.behavior.cancel(); + this.behavior = null; } @Override @@ -240,7 +243,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro @Override public boolean isSafeToCancel() { - return behavior.isSafeToCancel(); + return !this.isActive() || !(this.state == State.FLYING || this.state == State.START_FLYING); } public enum State { @@ -252,4 +255,38 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro FLYING, LANDING } + + @Override + public void onRenderPass(RenderEvent event) { + if (this.behavior != null) this.behavior.onRenderPass(event); + } + + @Override + public void onWorldEvent(WorldEvent event) { + if (this.behavior != null) this.behavior.onWorldEvent(event); + } + + @Override + public void onChunkEvent(ChunkEvent event) { + if (this.behavior != null) this.behavior.onChunkEvent(event); + } + + @Override + public void onBlockChange(BlockChangeEvent event) { + if (this.behavior != null) this.behavior.onBlockChange(event); + } + + @Override + public void onReceivePacket(PacketEvent event) { + if (this.behavior != null) this.behavior.onReceivePacket(event); + } + + public void onTickBeforePathingBehavior(final TickEvent event) { + if (this.behavior != null) this.behavior.onTick(event); + } + + @Override + public void onPostTick(TickEvent event) { + if (this.behavior != null) this.behavior.onPostTick(event); + } } diff --git a/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java b/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java index 48066f3ea..6553f1ef8 100644 --- a/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java @@ -24,7 +24,6 @@ import baritone.api.behavior.look.IAimProcessor; import baritone.api.behavior.look.ITickableAimProcessor; import baritone.api.event.events.*; import baritone.api.event.events.type.EventState; -import baritone.api.event.listener.AbstractGameEventListener; import baritone.api.pathing.goals.GoalBlock; import baritone.api.utils.*; import baritone.pathing.movement.CalculationContext; @@ -51,6 +50,7 @@ import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; import java.awt.*; @@ -63,7 +63,7 @@ import static baritone.api.pathing.movement.ActionCosts.COST_INF; import static baritone.utils.BaritoneMath.fastCeil; import static baritone.utils.BaritoneMath.fastFloor; -public final class LegacyElytraBehavior implements AbstractGameEventListener, Helper { +public final class LegacyElytraBehavior implements Helper { private final Baritone baritone; private final IPlayerContext ctx; @@ -76,7 +76,7 @@ public final class LegacyElytraBehavior implements AbstractGameEventListener, H public List visiblePath; // :sunglasses: - private NetherPathfinderContext context; + private NetherPathfinderContext context; // TODO: make this final private CompletableFuture forceResetContext; public final PathManager pathManager; private final ElytraProcess process; @@ -125,6 +125,8 @@ public final class LegacyElytraBehavior implements AbstractGameEventListener, H this.process = process; this.solverExecutor = Executors.newSingleThreadExecutor(); this.nextTickBoostCounter = new int[2]; + + this.context = new NetherPathfinderContext(Baritone.settings().elytraNetherSeed.value); } public final class PathManager { @@ -370,7 +372,6 @@ public final class LegacyElytraBehavior implements AbstractGameEventListener, H } } - @Override public void onRenderPass(RenderEvent event) { final Settings settings = Baritone.settings(); if (this.visiblePath != null) { @@ -409,7 +410,7 @@ public final class LegacyElytraBehavior implements AbstractGameEventListener, H } } - @Override + // TODO: move this logic to ElytraProcess public void onWorldEvent(WorldEvent event) { if (event.getWorld() != null) { if (event.getState() == EventState.PRE) { @@ -427,7 +428,6 @@ public final class LegacyElytraBehavior implements AbstractGameEventListener, H } } - @Override public void onChunkEvent(ChunkEvent event) { if (event.isPostPopulate() && this.context != null) { final Chunk chunk = ctx.world().getChunk(event.getX(), event.getZ()); @@ -435,12 +435,16 @@ public final class LegacyElytraBehavior implements AbstractGameEventListener, H } } - @Override + public void uploadRenderDistance(World world) { + ((IChunkProviderClient) world.getChunkProvider()).loadedChunks().forEach((l, chunk) -> { + this.context.queueForPacking(chunk); + }); + } + public void onBlockChange(BlockChangeEvent event) { this.context.queueBlockUpdate(event); } - @Override public void onReceivePacket(PacketEvent event) { if (event.getPacket() instanceof SPacketPlayerPosLook) { ctx.minecraft().addScheduledTask(() -> { @@ -486,11 +490,6 @@ public final class LegacyElytraBehavior implements AbstractGameEventListener, H .filter(process -> this.process == process).isPresent(); } - public boolean isSafeToCancel() { - return !this.isActive() || !(this.process.state == ElytraProcess.State.FLYING || this.process.state == ElytraProcess.State.START_FLYING); - } - - @Override public void onTick(final TickEvent event) { if (event.getType() == TickEvent.Type.OUT) { return; @@ -629,7 +628,6 @@ public final class LegacyElytraBehavior implements AbstractGameEventListener, H ); } - @Override public void onPostTick(TickEvent event) { if (event.getType() == TickEvent.Type.IN && this.solveNextTick) { // We're at the end of the tick, the player's position likely updated and the closest path node could've diff --git a/src/main/java/baritone/process/elytra/NetherPathfinderContext.java b/src/main/java/baritone/process/elytra/NetherPathfinderContext.java index 46a840981..69ac41992 100644 --- a/src/main/java/baritone/process/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/process/elytra/NetherPathfinderContext.java @@ -52,7 +52,6 @@ public final class NetherPathfinderContext { final long context; private final long seed; private final ExecutorService executor; - private final AtomicInteger packQueueSize = new AtomicInteger(); public NetherPathfinderContext(long seed) { this.context = NetherPathfinder.newContext(seed); From 4b5d629df6097a8b0735314f48fd57f61c939c9c Mon Sep 17 00:00:00 2001 From: Babbaj Date: Mon, 17 Jul 2023 17:21:06 -0400 Subject: [PATCH 325/405] fix off by one error (causing the last point to be stuck in terrain) --- build.gradle | 4 ++-- .../java/baritone/process/elytra/LegacyElytraBehavior.java | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index e44d68e04..04017277c 100755 --- a/build.gradle +++ b/build.gradle @@ -175,8 +175,8 @@ dependencies { transitive = false } launchAnnotationProcessor 'org.spongepowered:mixin:0.8.4-SNAPSHOT:processor' - launchImplementation('dev.babbaj:nether-pathfinder:0.34') - implementation 'dev.babbaj:nether-pathfinder:0.34' + launchImplementation('dev.babbaj:nether-pathfinder:0.39') + implementation 'dev.babbaj:nether-pathfinder:0.39' testImplementation 'junit:junit:4.12' } diff --git a/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java b/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java index 6553f1ef8..f537f93bc 100644 --- a/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java @@ -195,7 +195,7 @@ public final class LegacyElytraBehavior implements Helper { } this.recalculating = true; - final List after = this.path.subList(upToIncl, this.path.size()); + final List after = this.path.subList(upToIncl + 1, this.path.size()); final boolean complete = this.completePath; return this.path0(ctx.playerFeet(), this.path.get(upToIncl), segment -> segment.append(after.stream(), complete)) @@ -288,6 +288,7 @@ public final class LegacyElytraBehavior implements Helper { while (rangeEndExcl < path.size() && ctx.world().isBlockLoaded(path.get(rangeEndExcl), false)) { rangeEndExcl++; } + // rangeEndExcl now represents an index either not in the path, or just outside render distance if (rangeStartIncl >= rangeEndExcl) { // not loaded yet? return; From afe9359d3e781db9c12af778769658ce25e58ac5 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Mon, 17 Jul 2023 18:11:33 -0400 Subject: [PATCH 326/405] don't call onTick if we are pawsed --- .../java/baritone/behavior/PathingBehavior.java | 1 - src/main/java/baritone/process/ElytraProcess.java | 15 ++++++++++----- .../process/elytra/LegacyElytraBehavior.java | 6 +----- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/baritone/behavior/PathingBehavior.java b/src/main/java/baritone/behavior/PathingBehavior.java index 9b15b88ba..3733a9144 100644 --- a/src/main/java/baritone/behavior/PathingBehavior.java +++ b/src/main/java/baritone/behavior/PathingBehavior.java @@ -94,7 +94,6 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, @Override public void onTick(TickEvent event) { - ((ElytraProcess) baritone.getElytraProcess()).onTickBeforePathingBehavior(event); dispatchEvents(); if (event.getType() == TickEvent.Type.OUT) { secretInternalSegmentCancel(); diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index 11f4fdeaf..0f6763346 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -49,6 +49,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro public State state; private Goal goal; private LegacyElytraBehavior behavior; + private boolean skippedThisTick = false; private ElytraProcess(Baritone baritone) { super(baritone); @@ -69,6 +70,14 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro @Override public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { + IBaritoneProcess procLastTick = baritone.getPathingControlManager().mostRecentInControl().orElse(null); + // this is true if the pause process was running or any other processes that causes us to not tick + skippedThisTick = procLastTick != null && procLastTick.priority() > this.priority(); + if (skippedThisTick) { + return new PathingCommand(null, PathingCommandType.DEFER); + } + + this.behavior.onTick(); if (calcFailed) { onLostControl(); logDirect("Failed to get to jump off spot, canceling"); @@ -281,12 +290,8 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro if (this.behavior != null) this.behavior.onReceivePacket(event); } - public void onTickBeforePathingBehavior(final TickEvent event) { - if (this.behavior != null) this.behavior.onTick(event); - } - @Override public void onPostTick(TickEvent event) { - if (this.behavior != null) this.behavior.onPostTick(event); + if (this.behavior != null && !skippedThisTick) this.behavior.onPostTick(event); } } diff --git a/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java b/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java index f537f93bc..2ce91a866 100644 --- a/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java @@ -491,11 +491,7 @@ public final class LegacyElytraBehavior implements Helper { .filter(process -> this.process == process).isPresent(); } - public void onTick(final TickEvent event) { - if (event.getType() == TickEvent.Type.OUT) { - return; - } - + public void onTick() { // Fetch the previous solution, regardless of if it's going to be used this.pendingSolution = null; if (this.solver != null) { From 2f0497756b1133e05a3db77037cb411eb6b4c48e Mon Sep 17 00:00:00 2001 From: Babbaj Date: Mon, 17 Jul 2023 18:16:09 -0400 Subject: [PATCH 327/405] simplify icky code --- src/main/java/baritone/process/ElytraProcess.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index 0f6763346..cf21b8207 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -70,13 +70,6 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro @Override public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { - IBaritoneProcess procLastTick = baritone.getPathingControlManager().mostRecentInControl().orElse(null); - // this is true if the pause process was running or any other processes that causes us to not tick - skippedThisTick = procLastTick != null && procLastTick.priority() > this.priority(); - if (skippedThisTick) { - return new PathingCommand(null, PathingCommandType.DEFER); - } - this.behavior.onTick(); if (calcFailed) { onLostControl(); @@ -292,6 +285,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro @Override public void onPostTick(TickEvent event) { - if (this.behavior != null && !skippedThisTick) this.behavior.onPostTick(event); + IBaritoneProcess procThisTick = baritone.getPathingControlManager().mostRecentInControl().orElse(null); + if (this.behavior != null && procThisTick == this) this.behavior.onPostTick(event); } } From ff1b3e7c5f24daa0de448bf834019fda90bd62ae Mon Sep 17 00:00:00 2001 From: Babbaj Date: Mon, 17 Jul 2023 22:57:24 -0400 Subject: [PATCH 328/405] simplify management of elytra state --- build.gradle | 4 +- .../baritone/api/process/IElytraProcess.java | 21 ++--- .../command/defaults/ElytraCommand.java | 9 +- .../defaults/ExecutionControlCommands.java | 1 - .../command/defaults/ForceCancelCommand.java | 2 +- .../java/baritone/process/ElytraProcess.java | 92 ++++++++++--------- .../process/elytra/LegacyElytraBehavior.java | 74 ++------------- .../process/elytra/NullElytraProcess.java | 12 +-- 8 files changed, 76 insertions(+), 139 deletions(-) diff --git a/build.gradle b/build.gradle index 04017277c..accb7ca54 100755 --- a/build.gradle +++ b/build.gradle @@ -175,8 +175,8 @@ dependencies { transitive = false } launchAnnotationProcessor 'org.spongepowered:mixin:0.8.4-SNAPSHOT:processor' - launchImplementation('dev.babbaj:nether-pathfinder:0.39') - implementation 'dev.babbaj:nether-pathfinder:0.39' + launchImplementation('dev.babbaj:nether-pathfinder:0.41') + implementation 'dev.babbaj:nether-pathfinder:0.41' testImplementation 'junit:junit:4.12' } diff --git a/src/api/java/baritone/api/process/IElytraProcess.java b/src/api/java/baritone/api/process/IElytraProcess.java index b1bd3d833..639f69f0e 100644 --- a/src/api/java/baritone/api/process/IElytraProcess.java +++ b/src/api/java/baritone/api/process/IElytraProcess.java @@ -19,24 +19,21 @@ package baritone.api.process; import net.minecraft.util.math.BlockPos; -import java.util.concurrent.CompletableFuture; - public interface IElytraProcess extends IBaritoneProcess { - /** - * 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 - */ - @Deprecated - CompletableFuture resetContext(); - void repackChunks(); + /** + * @return Where it is currently flying to, null if not active + */ + BlockPos currentDestination(); + void pathTo(BlockPos destination); - void cancel(); + /** + * Resets the state of the process but will maintain the same destination and will try to keep flying + */ + void resetState(); /** * @return {@code true} if the native library loaded and elytra is actually usable diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index 05695d82b..418a6c7ac 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -85,10 +85,11 @@ public class ElytraCommand extends Command { final String action = args.getString(); switch (action) { case "reset": { - elytra.resetContext().whenComplete((result, ex) -> { - logDirect("Context reset, repacking chunks"); - elytra.repackChunks(); - }); + BlockPos destination = elytra.currentDestination(); + elytra.onLostControl(); + elytra.pathTo(destination); + elytra.repackChunks(); + logDirect("Reset state but still flying to same goal"); break; } case "repack": { diff --git a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java index b91014a67..6f6293ccd 100644 --- a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java +++ b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java @@ -180,7 +180,6 @@ public class ExecutionControlCommands { paused[0] = false; } baritone.getPathingBehavior().cancelEverything(); - baritone.getElytraProcess().cancel(); // TODO: this shouldnt be necessary logDirect("ok canceled"); } diff --git a/src/main/java/baritone/command/defaults/ForceCancelCommand.java b/src/main/java/baritone/command/defaults/ForceCancelCommand.java index d86cddd5e..b5abb6392 100644 --- a/src/main/java/baritone/command/defaults/ForceCancelCommand.java +++ b/src/main/java/baritone/command/defaults/ForceCancelCommand.java @@ -39,7 +39,7 @@ public class ForceCancelCommand extends Command { IPathingBehavior pathingBehavior = baritone.getPathingBehavior(); pathingBehavior.cancelEverything(); pathingBehavior.forceCancel(); - baritone.getElytraProcess().cancel(); + baritone.getElytraProcess().onLostControl(); // is this necessary? logDirect("ok force canceled"); } diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index cf21b8207..793f2a807 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -19,6 +19,7 @@ package baritone.process; import baritone.Baritone; 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.GoalYLevel; @@ -42,9 +43,6 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; -import java.util.concurrent.*; -import java.util.function.Supplier; - public class ElytraProcess extends BaritoneProcessHelper implements IBaritoneProcess, IElytraProcess, AbstractGameEventListener { public State state; private Goal goal; @@ -63,14 +61,32 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro : new NullElytraProcess(baritone)); } + + @Override public boolean isActive() { return behavior != null; } + @Override + public void resetState() { + BlockPos destination = this.currentDestination(); + this.onLostControl(); + this.pathTo(destination); + this.repackChunks(); + } + @Override public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { - this.behavior.onTick(); + final long seedSetting = Baritone.settings().elytraNetherSeed.value; + if (this.behavior != null && seedSetting != behavior.context.getSeed()) { + logDirect("Nether seed changed, recalculating path"); + this.resetState(); + } + + if (this.behavior != null) { + this.behavior.onTick(); + } if (calcFailed) { onLostControl(); logDirect("Failed to get to jump off spot, canceling"); @@ -184,38 +200,13 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro public void onLostControl() { this.goal = null; this.state = State.START_FLYING; // TODO: null state? - if (this.behavior != null) this.behavior.cancel(); + if (this.behavior != null) this.behavior.destroy(); this.behavior = null; } - - @Override public String displayName0() { - final Supplier status = () -> { - switch (this.state) { - case LOCATE_JUMP: - return "Finding spot to jump off"; - case PAUSE: - return "Waiting for elytra path"; - case GET_TO_JUMP: - return "Walking to takeoff"; - case START_FLYING: - return "Begin flying"; - case FLYING: - return "Flying"; - case LANDING: - return "Landing"; - default: - return "Unknown"; - } - }; - return "Elytra - " + status.get(); - } - - @Override - public CompletableFuture resetContext() { - return behavior.resetContext(); + return "Elytra - " + this.state.description; } @Override @@ -223,6 +214,11 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro this.behavior.repackChunks(); } + @Override + public BlockPos currentDestination() { + return this.behavior != null ? this.behavior.destination : null; + } + @Override public void pathTo(BlockPos destination) { this.behavior = new LegacyElytraBehavior(this.baritone, this); @@ -232,12 +228,6 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro this.behavior.pathTo(destination); } - @Override - public void cancel() { - if (this.behavior != null) this.behavior.cancel(); - this.behavior = null; - } - @Override public boolean isLoaded() { return true; @@ -249,13 +239,19 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro } public enum State { - LOCATE_JUMP, - VALIDATE_PATH, - PAUSE, - GET_TO_JUMP, - START_FLYING, - FLYING, - LANDING + 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"), + FLYING("Flying"), + LANDING("Landing"); + + public String description; + + State(String desc) { + this.description = desc; + } } @Override @@ -265,7 +261,13 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro @Override public void onWorldEvent(WorldEvent event) { - if (this.behavior != null) this.behavior.onWorldEvent(event); + if (event.getWorld() != null && event.getState() == EventState.POST) { + // Exiting the world, just destroy + if (this.behavior != null) { + this.behavior.destroy(); + this.behavior = new LegacyElytraBehavior(baritone, this); + } + } } @Override diff --git a/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java b/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java index 2ce91a866..11e69e620 100644 --- a/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java @@ -23,7 +23,6 @@ import baritone.api.Settings; import baritone.api.behavior.look.IAimProcessor; import baritone.api.behavior.look.ITickableAimProcessor; import baritone.api.event.events.*; -import baritone.api.event.events.type.EventState; import baritone.api.pathing.goals.GoalBlock; import baritone.api.utils.*; import baritone.pathing.movement.CalculationContext; @@ -50,7 +49,6 @@ import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; -import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; import java.awt.*; @@ -76,8 +74,7 @@ public final class LegacyElytraBehavior implements Helper { public List visiblePath; // :sunglasses: - private NetherPathfinderContext context; // TODO: make this final - private CompletableFuture forceResetContext; + public final NetherPathfinderContext context; // TODO: make this final public final PathManager pathManager; private final ElytraProcess process; @@ -102,8 +99,8 @@ public final class LegacyElytraBehavior implements Helper { private final int[] nextTickBoostCounter; private BlockStateInterface bsi; - private BlockStateOctreeInterface boi; - public BlockPos destination; + private final BlockStateOctreeInterface boi; + public BlockPos destination; // TODO: make this final? private final ExecutorService solverExecutor; private Future solver; @@ -127,6 +124,7 @@ public final class LegacyElytraBehavior implements Helper { this.nextTickBoostCounter = new int[2]; this.context = new NetherPathfinderContext(Baritone.settings().elytraNetherSeed.value); + this.boi = new BlockStateOctreeInterface(context); } public final class PathManager { @@ -411,24 +409,6 @@ public final class LegacyElytraBehavior implements Helper { } } - // TODO: move this logic to ElytraProcess - public void onWorldEvent(WorldEvent event) { - 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.resetContext(); - } - } else { - if (event.getState() == EventState.POST) { - // Exiting the world, just destroy and invalidate the context - if (this.context != null) { - this.context.destroy(); - this.context = null; - } - } - } - } - public void onChunkEvent(ChunkEvent event) { if (event.isPostPopulate() && this.context != null) { final Chunk chunk = ctx.world().getChunk(event.getX(), event.getZ()); @@ -436,12 +416,6 @@ public final class LegacyElytraBehavior implements Helper { } } - public void uploadRenderDistance(World world) { - ((IChunkProviderClient) world.getChunkProvider()).loadedChunks().forEach((l, chunk) -> { - this.context.queueForPacking(chunk); - }); - } - public void onBlockChange(BlockChangeEvent event) { this.context.queueBlockUpdate(event); } @@ -461,24 +435,11 @@ public final class LegacyElytraBehavior implements Helper { } } - public void cancel() { - this.destination = null; - this.pathManager.clear(); - this.remainingFireworkTicks = 0; - this.remainingSetBackTicks = 0; + public void destroy() { if (this.solver != null) { this.solver.cancel(true); - this.solver = null; } - this.pendingSolution = null; - Arrays.fill(this.nextTickBoostCounter, 0); - } - - public CompletableFuture resetContext() { - if (this.forceResetContext == null) { - this.forceResetContext = new CompletableFuture<>(); - } - return this.forceResetContext; + this.context.destroy(); } public void repackChunks() { @@ -486,11 +447,6 @@ public final class LegacyElytraBehavior implements Helper { .forEach(this.context::queueForPacking); } - public boolean isActive() { - return baritone.getPathingControlManager().mostRecentInControl() - .filter(process -> this.process == process).isPresent(); - } - public void onTick() { // Fetch the previous solution, regardless of if it's going to be used this.pendingSolution = null; @@ -504,23 +460,6 @@ public final class LegacyElytraBehavior implements Helper { } } - // Setup/reset context - final long netherSeed = Baritone.settings().elytraNetherSeed.value; - if (this.context == null || this.context.getSeed() != netherSeed || this.forceResetContext != null) { - if (this.context != null) { - this.context.destroy(); - } - this.context = new NetherPathfinderContext(netherSeed); - 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(); - } - } - tickInventoryTransactions(); // Certified mojang employee incident @@ -554,7 +493,6 @@ public final class LegacyElytraBehavior implements Helper { // ctx AND context???? :DDD this.bsi = new BlockStateInterface(ctx); - this.boi = new BlockStateOctreeInterface(context); this.pathManager.tick(); final int playerNear = this.pathManager.getNear(); diff --git a/src/main/java/baritone/process/elytra/NullElytraProcess.java b/src/main/java/baritone/process/elytra/NullElytraProcess.java index a84caf43f..0c11ba618 100644 --- a/src/main/java/baritone/process/elytra/NullElytraProcess.java +++ b/src/main/java/baritone/process/elytra/NullElytraProcess.java @@ -35,13 +35,13 @@ public final class NullElytraProcess extends BaritoneProcessHelper implements IE } @Override - public CompletableFuture resetContext() { - throw new UnsupportedOperationException("Called resetContext() on NullElytraBehavior"); + public void repackChunks() { + throw new UnsupportedOperationException("Called repackChunks() on NullElytraBehavior"); } @Override - public void repackChunks() { - throw new UnsupportedOperationException("Called repackChunks() on NullElytraBehavior"); + public BlockPos currentDestination() { + return null; } @Override @@ -50,8 +50,8 @@ public final class NullElytraProcess extends BaritoneProcessHelper implements IE } @Override - public void cancel() { - throw new UnsupportedOperationException("Called cancel() on NullElytraBehavior"); + public void resetState() { + } @Override From ccd80dfc8fec365185730eec928d68e89f988cd1 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Mon, 17 Jul 2023 23:02:35 -0400 Subject: [PATCH 329/405] that isn't necessary --- src/main/java/baritone/command/defaults/ForceCancelCommand.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/baritone/command/defaults/ForceCancelCommand.java b/src/main/java/baritone/command/defaults/ForceCancelCommand.java index b5abb6392..513d61bcb 100644 --- a/src/main/java/baritone/command/defaults/ForceCancelCommand.java +++ b/src/main/java/baritone/command/defaults/ForceCancelCommand.java @@ -39,7 +39,6 @@ public class ForceCancelCommand extends Command { IPathingBehavior pathingBehavior = baritone.getPathingBehavior(); pathingBehavior.cancelEverything(); pathingBehavior.forceCancel(); - baritone.getElytraProcess().onLostControl(); // is this necessary? logDirect("ok force canceled"); } From f4996137a33d6dc0dcecdd15395a823308d5e6ca Mon Sep 17 00:00:00 2001 From: Babbaj Date: Tue, 18 Jul 2023 00:02:23 -0400 Subject: [PATCH 330/405] minor code improvements --- src/main/java/baritone/Baritone.java | 1 - src/main/java/baritone/command/defaults/ElytraCommand.java | 5 +---- src/main/java/baritone/process/ElytraProcess.java | 3 +-- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index c6d31a3dd..0bd6a814a 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -125,7 +125,6 @@ public class Baritone implements IBaritone { this.farmProcess = this.registerProcess(FarmProcess::new); this.inventoryPauserProcess = this.registerProcess(InventoryPauserProcess::new); this.elytraProcess = this.registerProcess(ElytraProcess::create); - this.registerProcess(BackfillProcess::new); } diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index 418a6c7ac..eea7f3f33 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -85,10 +85,7 @@ public class ElytraCommand extends Command { final String action = args.getString(); switch (action) { case "reset": { - BlockPos destination = elytra.currentDestination(); - elytra.onLostControl(); - elytra.pathTo(destination); - elytra.repackChunks(); + elytra.resetState(); logDirect("Reset state but still flying to same goal"); break; } diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index 793f2a807..6738cab55 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -47,7 +47,6 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro public State state; private Goal goal; private LegacyElytraBehavior behavior; - private boolean skippedThisTick = false; private ElytraProcess(Baritone baritone) { super(baritone); @@ -247,7 +246,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro FLYING("Flying"), LANDING("Landing"); - public String description; + public final String description; State(String desc) { this.description = desc; From ba78c48a7563f1b77ef3348ece08a57cf0f4e84f Mon Sep 17 00:00:00 2001 From: Babbaj Date: Tue, 18 Jul 2023 00:07:26 -0400 Subject: [PATCH 331/405] shutdown solverExecutor --- src/main/java/baritone/process/elytra/LegacyElytraBehavior.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java b/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java index 11e69e620..c7a164593 100644 --- a/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java @@ -439,6 +439,7 @@ public final class LegacyElytraBehavior implements Helper { if (this.solver != null) { this.solver.cancel(true); } + this.solverExecutor.shutdown(); this.context.destroy(); } From 38553b33248f0146ec18cb56bc62f3b8515ea46a Mon Sep 17 00:00:00 2001 From: Babbaj Date: Tue, 18 Jul 2023 14:52:09 -0400 Subject: [PATCH 332/405] behavior can't be null in onTick --- .../java/baritone/process/ElytraProcess.java | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index 6738cab55..eb3c1bdd8 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -78,14 +78,13 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro @Override public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { final long seedSetting = Baritone.settings().elytraNetherSeed.value; - if (this.behavior != null && seedSetting != behavior.context.getSeed()) { + if (seedSetting != behavior.context.getSeed()) { logDirect("Nether seed changed, recalculating path"); this.resetState(); } - if (this.behavior != null) { - this.behavior.onTick(); - } + this.behavior.onTick(); + if (calcFailed) { onLostControl(); logDirect("Failed to get to jump off spot, canceling"); @@ -199,8 +198,10 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro public void onLostControl() { this.goal = null; this.state = State.START_FLYING; // TODO: null state? - if (this.behavior != null) this.behavior.destroy(); - this.behavior = null; + if (this.behavior != null) { + this.behavior.destroy(); + this.behavior = null; + } } @Override @@ -210,7 +211,9 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro @Override public void repackChunks() { - this.behavior.repackChunks(); + if (this.behavior != null) { + this.behavior.repackChunks(); + } } @Override @@ -260,12 +263,10 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro @Override public void onWorldEvent(WorldEvent event) { - if (event.getWorld() != null && event.getState() == EventState.POST) { + if (event.getWorld() != null && event.getState() == EventState.POST && this.behavior != null) { // Exiting the world, just destroy - if (this.behavior != null) { - this.behavior.destroy(); - this.behavior = new LegacyElytraBehavior(baritone, this); - } + this.behavior.destroy(); + this.behavior = new LegacyElytraBehavior(baritone, this); } } From 0239a2cad435d5a04e94555ddee280e493527222 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Tue, 18 Jul 2023 15:36:29 -0400 Subject: [PATCH 333/405] notificationOnPathComplete and disconnectOnArrival --- src/main/java/baritone/process/ElytraProcess.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index eb3c1bdd8..e75fbeb81 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -94,6 +94,15 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro if (ctx.player().isElytraFlying()) { final BetterBlockPos last = behavior.pathManager.path.getLast(); if (last != null && ctx.player().getDistanceSqToCenter(last) < (5 * 5)) { + if (Baritone.settings().notificationOnPathComplete.value) { + logNotification("Pathing complete", false); + } + if (Baritone.settings().disconnectOnArrival.value) { + // don't be active when the user logs back in + this.onLostControl(); + ctx.world().sendQuittingDisconnectingPacket(); + return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); + } this.state = State.LANDING; } } From 6a9694b03a7fda9a4b0af7be9935a38be60a7760 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 18 Jul 2023 15:24:21 -0500 Subject: [PATCH 334/405] Manually specify some normals, fix GoalXZ rendering --- src/main/java/baritone/utils/IRenderer.java | 58 +++++++++++-------- .../java/baritone/utils/PathRenderer.java | 19 +++--- 2 files changed, 46 insertions(+), 31 deletions(-) diff --git a/src/main/java/baritone/utils/IRenderer.java b/src/main/java/baritone/utils/IRenderer.java index 83436c408..e7a853859 100644 --- a/src/main/java/baritone/utils/IRenderer.java +++ b/src/main/java/baritone/utils/IRenderer.java @@ -89,9 +89,6 @@ public interface IRenderer { } static void emitLine(PoseStack stack, double x1, double y1, double z1, double x2, double y2, double z2) { - final Matrix4f matrix4f = stack.last().pose(); - final Matrix3f normal = stack.last().normal(); - final double dx = x2 - x1; final double dy = y2 - y1; final double dz = z2 - z1; @@ -101,34 +98,49 @@ public interface IRenderer { final float ny = (float) (dy * invMag); final float nz = (float) (dz * invMag); - buffer.vertex(matrix4f, (float) x1, (float) y1, (float) z1) - .color(color[0], color[1], color[2], color[3]) - .normal(normal, nx, ny, nz) - .endVertex(); - buffer.vertex(matrix4f, (float) x2, (float) y2, (float) z2) - .color(color[0], color[1], color[2], color[3]) - .normal(normal, nx, ny, nz) - .endVertex(); + emitLine(stack, x1, y1, z1, x2, y2, z2, nx, ny, nz); + } + + static void emitLine(PoseStack stack, + double x1, double y1, double z1, + double x2, double y2, double z2, + double nx, double ny, double nz) { + emitLine(stack, + (float) x1, (float) y1, (float) z1, + (float) x2, (float) y2, (float) z2, + (float) nx, (float) ny, (float) nz + ); + } + + static void emitLine(PoseStack stack, + float x1, float y1, float z1, + float x2, float y2, float z2, + float nx, float ny, float nz) { + final Matrix4f matrix4f = stack.last().pose(); + final Matrix3f normal = stack.last().normal(); + + buffer.vertex(matrix4f, x1, y1, z1).color(color[0], color[1], color[2], color[3]).normal(normal, nx, ny, nz).endVertex(); + buffer.vertex(matrix4f, x2, y2, z2).color(color[0], color[1], color[2], color[3]).normal(normal, nx, ny, nz).endVertex(); } static void emitAABB(PoseStack stack, AABB aabb) { AABB toDraw = aabb.move(-renderManager.renderPosX(), -renderManager.renderPosY(), -renderManager.renderPosZ()); // bottom - emitLine(stack, toDraw.minX, toDraw.minY, toDraw.minZ, toDraw.maxX, toDraw.minY, toDraw.minZ); - emitLine(stack, toDraw.maxX, toDraw.minY, toDraw.minZ, toDraw.maxX, toDraw.minY, toDraw.maxZ); - emitLine(stack, toDraw.maxX, toDraw.minY, toDraw.maxZ, toDraw.minX, toDraw.minY, toDraw.maxZ); - emitLine(stack, toDraw.minX, toDraw.minY, toDraw.maxZ, toDraw.minX, toDraw.minY, toDraw.minZ); + emitLine(stack, toDraw.minX, toDraw.minY, toDraw.minZ, toDraw.maxX, toDraw.minY, toDraw.minZ, 1.0, 0.0, 0.0); + emitLine(stack, toDraw.maxX, toDraw.minY, toDraw.minZ, toDraw.maxX, toDraw.minY, toDraw.maxZ, 0.0, 0.0, 1.0); + emitLine(stack, toDraw.maxX, toDraw.minY, toDraw.maxZ, toDraw.minX, toDraw.minY, toDraw.maxZ, -1.0, 0.0, 0.0); + emitLine(stack, toDraw.minX, toDraw.minY, toDraw.maxZ, toDraw.minX, toDraw.minY, toDraw.minZ, 0.0, 0.0, -1.0); // top - emitLine(stack, toDraw.minX, toDraw.maxY, toDraw.minZ, toDraw.maxX, toDraw.maxY, toDraw.minZ); - emitLine(stack, toDraw.maxX, toDraw.maxY, toDraw.minZ, toDraw.maxX, toDraw.maxY, toDraw.maxZ); - emitLine(stack, toDraw.maxX, toDraw.maxY, toDraw.maxZ, toDraw.minX, toDraw.maxY, toDraw.maxZ); - emitLine(stack, toDraw.minX, toDraw.maxY, toDraw.maxZ, toDraw.minX, toDraw.maxY, toDraw.minZ); + emitLine(stack, toDraw.minX, toDraw.maxY, toDraw.minZ, toDraw.maxX, toDraw.maxY, toDraw.minZ, 1.0, 0.0, 0.0); + emitLine(stack, toDraw.maxX, toDraw.maxY, toDraw.minZ, toDraw.maxX, toDraw.maxY, toDraw.maxZ, 0.0, 0.0, 1.0); + emitLine(stack, toDraw.maxX, toDraw.maxY, toDraw.maxZ, toDraw.minX, toDraw.maxY, toDraw.maxZ, -1.0, 0.0, 0.0); + emitLine(stack, toDraw.minX, toDraw.maxY, toDraw.maxZ, toDraw.minX, toDraw.maxY, toDraw.minZ, 0.0, 0.0, -1.0); // corners - emitLine(stack, toDraw.minX, toDraw.minY, toDraw.minZ, toDraw.minX, toDraw.maxY, toDraw.minZ); - emitLine(stack, toDraw.maxX, toDraw.minY, toDraw.minZ, toDraw.maxX, toDraw.maxY, toDraw.minZ); - emitLine(stack, toDraw.maxX, toDraw.minY, toDraw.maxZ, toDraw.maxX, toDraw.maxY, toDraw.maxZ); - emitLine(stack, toDraw.minX, toDraw.minY, toDraw.maxZ, toDraw.minX, toDraw.maxY, toDraw.maxZ); + emitLine(stack, toDraw.minX, toDraw.minY, toDraw.minZ, toDraw.minX, toDraw.maxY, toDraw.minZ, 0.0, 1.0, 0.0); + emitLine(stack, toDraw.maxX, toDraw.minY, toDraw.minZ, toDraw.maxX, toDraw.maxY, toDraw.minZ, 0.0, 1.0, 0.0); + emitLine(stack, toDraw.maxX, toDraw.minY, toDraw.maxZ, toDraw.maxX, toDraw.maxY, toDraw.maxZ, 0.0, 1.0, 0.0); + emitLine(stack, toDraw.minX, toDraw.minY, toDraw.maxZ, toDraw.minX, toDraw.maxY, toDraw.maxZ, 0.0, 1.0, 0.0); } static void emitAABB(PoseStack stack, AABB aabb, double expand) { diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index edb3bca5d..88c56bc96 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -340,10 +340,13 @@ public final class PathRenderer implements IRenderer { renderHorizontalQuad(stack, minX, maxX, minZ, maxZ, y1); renderHorizontalQuad(stack, minX, maxX, minZ, maxZ, y2); - IRenderer.emitLine(stack, minX, minY, minZ, minX, maxY, minZ); - IRenderer.emitLine(stack, maxX, minY, minZ, maxX, maxY, minZ); - IRenderer.emitLine(stack, maxX, minY, maxZ, maxX, maxY, maxZ); - IRenderer.emitLine(stack, minX, minY, maxZ, minX, maxY, maxZ); + for (double y = minY; y < maxY; y += 16) { + double max = Math.min(maxY, y + 16); + IRenderer.emitLine(stack, minX, y, minZ, minX, max, minZ, 0.0, 1.0, 0.0); + IRenderer.emitLine(stack, maxX, y, minZ, maxX, max, minZ, 0.0, 1.0, 0.0); + IRenderer.emitLine(stack, maxX, y, maxZ, maxX, max, maxZ, 0.0, 1.0, 0.0); + IRenderer.emitLine(stack, minX, y, maxZ, minX, max, maxZ, 0.0, 1.0, 0.0); + } if (setupRender) { IRenderer.endLines(settings.renderGoalIgnoreDepth.value); @@ -352,10 +355,10 @@ public final class PathRenderer implements IRenderer { private static void renderHorizontalQuad(PoseStack stack, double minX, double maxX, double minZ, double maxZ, double y) { if (y != 0) { - IRenderer.emitLine(stack, minX, y, minZ, maxX, y, minZ); - IRenderer.emitLine(stack, maxX, y, minZ, maxX, y, maxZ); - IRenderer.emitLine(stack, maxX, y, maxZ, minX, y, maxZ); - IRenderer.emitLine(stack, minX, y, maxZ, minX, y, minZ); + IRenderer.emitLine(stack, minX, y, minZ, maxX, y, minZ, 1.0, 0.0, 0.0); + IRenderer.emitLine(stack, maxX, y, minZ, maxX, y, maxZ, 0.0, 0.0, 1.0); + IRenderer.emitLine(stack, maxX, y, maxZ, minX, y, maxZ, -1.0, 0.0, 0.0); + IRenderer.emitLine(stack, minX, y, maxZ, minX, y, minZ, 0.0, 0.0, -1.0); } } } From 218de1cb984678855009fd487b7c9b97452205fd Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 18 Jul 2023 16:48:00 -0500 Subject: [PATCH 335/405] Requested changes --- src/api/java/baritone/api/behavior/IBehavior.java | 8 +------- src/main/java/baritone/Baritone.java | 5 ----- src/main/java/baritone/process/ElytraProcess.java | 15 ++++++--------- .../process/elytra/LegacyElytraBehavior.java | 10 +++++----- 4 files changed, 12 insertions(+), 26 deletions(-) diff --git a/src/api/java/baritone/api/behavior/IBehavior.java b/src/api/java/baritone/api/behavior/IBehavior.java index aea44ed3e..811563b93 100644 --- a/src/api/java/baritone/api/behavior/IBehavior.java +++ b/src/api/java/baritone/api/behavior/IBehavior.java @@ -27,10 +27,4 @@ import baritone.api.event.listener.IGameEventListener; * @see IGameEventListener * @since 9/23/2018 */ -public interface IBehavior extends AbstractGameEventListener { - - /** - * Called after Baritone's initialization is complete - */ - default void onLoad() {} -} +public interface IBehavior extends AbstractGameEventListener {} diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index 0bd6a814a..08bc6fa24 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -66,7 +66,6 @@ public class Baritone implements IBaritone { private final GameEventHandler gameEventHandler; - private final List behaviors; private final PathingBehavior pathingBehavior; private final LookBehavior lookBehavior; private final InventoryBehavior inventoryBehavior; @@ -93,7 +92,6 @@ public class Baritone implements IBaritone { Baritone(Minecraft mc) { this.mc = mc; - this.behaviors = new ArrayList<>(); this.gameEventHandler = new GameEventHandler(this); this.directory = mc.gameDir.toPath().resolve("baritone"); @@ -131,12 +129,9 @@ public class Baritone implements IBaritone { this.worldProvider = new WorldProvider(this); this.selectionManager = new SelectionManager(this); this.commandManager = new CommandManager(this); - - this.behaviors.forEach(IBehavior::onLoad); } public void registerBehavior(IBehavior behavior) { - this.behaviors.add(behavior); this.gameEventHandler.registerEventListener(behavior); } diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index e75fbeb81..edd0da2f6 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -42,15 +42,14 @@ import baritone.utils.PathingCommandContext; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; - public class ElytraProcess extends BaritoneProcessHelper implements IBaritoneProcess, IElytraProcess, AbstractGameEventListener { + public State state; private Goal goal; private LegacyElytraBehavior behavior; private ElytraProcess(Baritone baritone) { super(baritone); - this.behavior = new LegacyElytraBehavior(baritone, this); baritone.getGameEventHandler().registerEventListener(this); } @@ -60,11 +59,9 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro : new NullElytraProcess(baritone)); } - - @Override public boolean isActive() { - return behavior != null; + return this.behavior != null; } @Override @@ -78,7 +75,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro @Override public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { final long seedSetting = Baritone.settings().elytraNetherSeed.value; - if (seedSetting != behavior.context.getSeed()) { + if (seedSetting != this.behavior.context.getSeed()) { logDirect("Nether seed changed, recalculating path"); this.resetState(); } @@ -232,11 +229,11 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro @Override public void pathTo(BlockPos destination) { - this.behavior = new LegacyElytraBehavior(this.baritone, this); + this.behavior = new LegacyElytraBehavior(this.baritone, this, destination); if (ctx.world() != null) { this.behavior.repackChunks(); } - this.behavior.pathTo(destination); + this.behavior.pathTo(); } @Override @@ -275,7 +272,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro if (event.getWorld() != null && event.getState() == EventState.POST && this.behavior != null) { // Exiting the world, just destroy this.behavior.destroy(); - this.behavior = new LegacyElytraBehavior(baritone, this); + this.behavior = null; } } diff --git a/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java b/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java index c7a164593..825d3087d 100644 --- a/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java @@ -74,7 +74,7 @@ public final class LegacyElytraBehavior implements Helper { public List visiblePath; // :sunglasses: - public final NetherPathfinderContext context; // TODO: make this final + public final NetherPathfinderContext context; public final PathManager pathManager; private final ElytraProcess process; @@ -100,7 +100,7 @@ public final class LegacyElytraBehavior implements Helper { private BlockStateInterface bsi; private final BlockStateOctreeInterface boi; - public BlockPos destination; // TODO: make this final? + public final BlockPos destination; private final ExecutorService solverExecutor; private Future solver; @@ -113,13 +113,14 @@ public final class LegacyElytraBehavior implements Helper { private int invTickCountdown = 0; private final Queue invTransactionQueue = new LinkedList<>(); - public LegacyElytraBehavior(Baritone baritone, ElytraProcess process) { + public LegacyElytraBehavior(Baritone baritone, ElytraProcess process, BlockPos destination) { this.baritone = baritone; this.ctx = baritone.getPlayerContext(); this.clearLines = new CopyOnWriteArrayList<>(); this.blockedLines = new CopyOnWriteArrayList<>(); this.pathManager = this.new PathManager(); this.process = process; + this.destination = destination; this.solverExecutor = Executors.newSingleThreadExecutor(); this.nextTickBoostCounter = new int[2]; @@ -428,8 +429,7 @@ public final class LegacyElytraBehavior implements Helper { } } - public void pathTo(BlockPos destination) { - this.destination = destination; + public void pathTo() { if (!Baritone.settings().elytraAutoJump.value || ctx.player().isElytraFlying()) { this.pathManager.pathToDestination(); } From dfa838a6f94f3fc4090a30143ba24f0ec747f352 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 18 Jul 2023 19:19:08 -0500 Subject: [PATCH 336/405] Replace `Mth.fastInvSqrt` with `1.0 / Math.sqrt` --- src/main/java/baritone/utils/IRenderer.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/baritone/utils/IRenderer.java b/src/main/java/baritone/utils/IRenderer.java index e7a853859..010346bd9 100644 --- a/src/main/java/baritone/utils/IRenderer.java +++ b/src/main/java/baritone/utils/IRenderer.java @@ -28,7 +28,6 @@ import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.texture.TextureManager; import com.mojang.blaze3d.vertex.*; import com.mojang.math.Matrix4f; -import net.minecraft.util.Mth; import net.minecraft.world.phys.AABB; import java.awt.*; @@ -93,7 +92,7 @@ public interface IRenderer { final double dy = y2 - y1; final double dz = z2 - z1; - final double invMag = Mth.fastInvSqrt(dx * dx + dy * dy + dz * dz); + final double invMag = 1.0 / Math.sqrt(dx * dx + dy * dy + dz * dz); final float nx = (float) (dx * invMag); final float ny = (float) (dy * invMag); final float nz = (float) (dz * invMag); From 097e30850f4a577c01b668c7d4a35a6acc27ee54 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 18 Jul 2023 23:35:09 -0500 Subject: [PATCH 337/405] Move `WalkOffCalculationContext` into `ElytraProcess` --- .../java/baritone/process/ElytraProcess.java | 35 ++++++++++++++++++- .../process/elytra/LegacyElytraBehavior.java | 34 ------------------ 2 files changed, 34 insertions(+), 35 deletions(-) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index edd0da2f6..c56ab9896 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -18,6 +18,7 @@ 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; @@ -33,15 +34,19 @@ import baritone.api.utils.BetterBlockPos; 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.LegacyElytraBehavior; import baritone.process.elytra.NetherPathfinderContext; import baritone.process.elytra.NullElytraProcess; import baritone.utils.BaritoneProcessHelper; import baritone.utils.PathingCommandContext; +import net.minecraft.block.state.IBlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; +import static baritone.api.pathing.movement.ActionCosts.COST_INF; + public class ElytraProcess extends BaritoneProcessHelper implements IBaritoneProcess, IElytraProcess, AbstractGameEventListener { public State state; @@ -165,7 +170,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } } - return new PathingCommandContext(this.goal, PathingCommandType.SET_GOAL_AND_PAUSE, new LegacyElytraBehavior.WalkOffCalculationContext(baritone)); + return new PathingCommandContext(this.goal, PathingCommandType.SET_GOAL_AND_PAUSE, new WalkOffCalculationContext(baritone)); } // yucky @@ -296,4 +301,32 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro IBaritoneProcess procThisTick = baritone.getPathingControlManager().mostRecentInControl().orElse(null); 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, IBlockState current) { + return COST_INF; + } + + @Override + public double breakCostMultiplierAt(int x, int y, int z, IBlockState current) { + return COST_INF; + } + + @Override + public double placeBucketCost() { + return COST_INF; + } + } } diff --git a/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java b/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java index 825d3087d..c147442ce 100644 --- a/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java @@ -18,14 +18,12 @@ package baritone.process.elytra; import baritone.Baritone; -import baritone.api.IBaritone; import baritone.api.Settings; import baritone.api.behavior.look.IAimProcessor; import baritone.api.behavior.look.ITickableAimProcessor; import baritone.api.event.events.*; import baritone.api.pathing.goals.GoalBlock; import baritone.api.utils.*; -import baritone.pathing.movement.CalculationContext; import baritone.process.ElytraProcess; import baritone.utils.BlockStateInterface; import baritone.utils.IRenderer; @@ -36,7 +34,6 @@ import it.unimi.dsi.fastutil.floats.FloatArrayList; import it.unimi.dsi.fastutil.floats.FloatIterator; import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap; import net.minecraft.block.material.Material; -import net.minecraft.block.state.IBlockState; import net.minecraft.entity.item.EntityFireworkRocket; import net.minecraft.init.Items; import net.minecraft.inventory.ClickType; @@ -57,7 +54,6 @@ import java.util.List; import java.util.concurrent.*; import java.util.function.UnaryOperator; -import static baritone.api.pathing.movement.ActionCosts.COST_INF; import static baritone.utils.BaritoneMath.fastCeil; import static baritone.utils.BaritoneMath.fastFloor; @@ -1292,34 +1288,4 @@ public final class LegacyElytraBehavior implements Helper { return result; } } - - /** - * 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, IBlockState current) { - return COST_INF; - } - - @Override - public double breakCostMultiplierAt(int x, int y, int z, IBlockState current) { - return COST_INF; - } - - @Override - public double placeBucketCost() { - return COST_INF; - } - } - - } From 664375a678080df599c154e04b9cb05444782198 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sat, 22 Jul 2023 01:55:12 -0400 Subject: [PATCH 338/405] make elytra play nice with CustomGoalProcess --- .../baritone/api/process/IElytraProcess.java | 3 ++ .../command/defaults/ElytraCommand.java | 23 +++--------- .../baritone/process/CustomGoalProcess.java | 3 ++ .../java/baritone/process/ElytraProcess.java | 36 +++++++++++++++++-- .../process/elytra/NullElytraProcess.java | 6 ++++ .../baritone/utils/PathingControlManager.java | 14 +++++--- 6 files changed, 58 insertions(+), 27 deletions(-) diff --git a/src/api/java/baritone/api/process/IElytraProcess.java b/src/api/java/baritone/api/process/IElytraProcess.java index 639f69f0e..d0ca6f00c 100644 --- a/src/api/java/baritone/api/process/IElytraProcess.java +++ b/src/api/java/baritone/api/process/IElytraProcess.java @@ -17,6 +17,7 @@ package baritone.api.process; +import baritone.api.pathing.goals.Goal; import net.minecraft.util.math.BlockPos; public interface IElytraProcess extends IBaritoneProcess { @@ -30,6 +31,8 @@ public interface IElytraProcess extends IBaritoneProcess { void pathTo(BlockPos destination); + void pathTo(Goal destination); + /** * Resets the state of the process but will maintain the same destination and will try to keep flying */ diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index eea7f3f33..7f985ad55 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -59,26 +59,11 @@ public class ElytraCommand extends Command { if (iGoal == null) { throw new CommandInvalidStateException("No goal has been set"); } - final int x; - final int y; - final int 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"); + try { + elytra.pathTo(iGoal); + } catch (IllegalArgumentException ex) { + throw new CommandInvalidStateException(ex.getMessage()); } - 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; } diff --git a/src/main/java/baritone/process/CustomGoalProcess.java b/src/main/java/baritone/process/CustomGoalProcess.java index 71d212b38..25c7a3d63 100644 --- a/src/main/java/baritone/process/CustomGoalProcess.java +++ b/src/main/java/baritone/process/CustomGoalProcess.java @@ -56,6 +56,9 @@ public final class CustomGoalProcess extends BaritoneProcessHelper implements IC public void setGoal(Goal goal) { this.goal = goal; this.mostRecentGoal = goal; + if (baritone.getElytraProcess().isActive()) { + baritone.getElytraProcess().pathTo(goal); + } if (this.state == State.NONE) { this.state = State.GOAL_SET; } diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index c56ab9896..816658593 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -23,6 +23,8 @@ 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; @@ -48,7 +50,6 @@ import net.minecraft.util.math.Vec3d; import static baritone.api.pathing.movement.ActionCosts.COST_INF; public class ElytraProcess extends BaritoneProcessHelper implements IBaritoneProcess, IElytraProcess, AbstractGameEventListener { - public State state; private Goal goal; private LegacyElytraBehavior behavior; @@ -93,7 +94,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } - if (ctx.player().isElytraFlying()) { + if (ctx.player().isElytraFlying() && this.state != State.LANDING) { final BetterBlockPos last = behavior.pathManager.path.getLast(); if (last != null && ctx.player().getDistanceSqToCenter(last) < (5 * 5)) { if (Baritone.settings().notificationOnPathComplete.value) { @@ -215,6 +216,11 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro } } + @Override + public double priority() { + return 0; // higher priority than CustomGoalProcess + } + @Override public String displayName0() { return "Elytra - " + this.state.description; @@ -234,6 +240,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(); @@ -241,6 +248,30 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro this.behavior.pathTo(); } + @Override + public void pathTo(Goal iGoal) { + final int x; + final int y; + final int 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 IllegalArgumentException("The goal must be a GoalXZ or GoalBlock"); + } + if (y <= 0 || y >= 128) { + throw new IllegalArgumentException("The y of the goal is not between 0 and 128"); + } + this.pathTo(new BlockPos(x, y, z)); + } + @Override public boolean isLoaded() { return true; @@ -253,7 +284,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"), diff --git a/src/main/java/baritone/process/elytra/NullElytraProcess.java b/src/main/java/baritone/process/elytra/NullElytraProcess.java index 0c11ba618..cd944cc7c 100644 --- a/src/main/java/baritone/process/elytra/NullElytraProcess.java +++ b/src/main/java/baritone/process/elytra/NullElytraProcess.java @@ -18,6 +18,7 @@ package baritone.process.elytra; import baritone.Baritone; +import baritone.api.pathing.goals.Goal; import baritone.api.process.IElytraProcess; import baritone.api.process.PathingCommand; import baritone.utils.BaritoneProcessHelper; @@ -49,6 +50,11 @@ public final class NullElytraProcess extends BaritoneProcessHelper implements IE throw new UnsupportedOperationException("Called pathTo() on NullElytraBehavior"); } + @Override + public void pathTo(Goal destination) { + throw new UnsupportedOperationException("Called pathTo() on NullElytraBehavior"); + } + @Override public void resetState() { diff --git a/src/main/java/baritone/utils/PathingControlManager.java b/src/main/java/baritone/utils/PathingControlManager.java index a174c842b..2ae4b00ce 100644 --- a/src/main/java/baritone/utils/PathingControlManager.java +++ b/src/main/java/baritone/utils/PathingControlManager.java @@ -27,6 +27,8 @@ import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommandType; import baritone.behavior.PathingBehavior; import baritone.pathing.path.PathExecutor; +import baritone.process.CustomGoalProcess; +import baritone.process.ElytraProcess; import net.minecraft.util.math.BlockPos; import java.util.*; @@ -109,10 +111,6 @@ public class PathingControlManager implements IPathingControlManager { p.cancelSegmentIfSafe(); break; case FORCE_REVALIDATE_GOAL_AND_PATH: - if (!p.isPathing() && !p.getInProgress().isPresent()) { - p.secretInternalSetGoalAndPath(command); - } - break; case REVALIDATE_GOAL_AND_PATH: if (!p.isPathing() && !p.getInProgress().isPresent()) { p.secretInternalSetGoalAndPath(command); @@ -209,7 +207,13 @@ public class PathingControlManager implements IPathingControlManager { } else if (exec.commandType != PathingCommandType.DEFER) { inControlThisTick = proc; if (!proc.isTemporary()) { - iterator.forEachRemaining(IBaritoneProcess::onLostControl); + iterator.forEachRemaining(it -> { + // TODO: find a better way to make these behave well together + if (proc instanceof CustomGoalProcess && it instanceof ElytraProcess) { + return; + } + it.onLostControl(); + }); } return exec; } From 7f9e50bbe27d6e80da0e7481e854304d0e48e885 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sat, 22 Jul 2023 19:12:53 -0400 Subject: [PATCH 339/405] initial safe landing impl --- .../command/defaults/ElytraCommand.java | 3 - .../java/baritone/process/ElytraProcess.java | 64 ++++++++++++++++++- 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index eea7f3f33..3232ecb03 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -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; diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index c56ab9896..ff082fada 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -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 queue = new LinkedList<>(); + Set 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; + } } From c9aa1658b2ae7a8fc5f9cb423ec13da7147ff5c6 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sat, 22 Jul 2023 20:24:36 -0400 Subject: [PATCH 340/405] improvements/fixes --- .../java/baritone/process/ElytraProcess.java | 36 +++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index ff082fada..ccab3e2cd 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -57,6 +57,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro public State state; private boolean goingToLandingSpot; + private BetterBlockPos landingSpot; private Goal goal; private LegacyElytraBehavior behavior; @@ -102,7 +103,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro 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 (last != null && ctx.player().getDistanceSqToCenter(last) < 1) { if (Baritone.settings().notificationOnPathComplete.value) { logNotification("Pathing complete", false); } @@ -113,22 +114,25 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } if (!goingToLandingSpot) { - BlockPos landingSpot = findSafeLandingSpot(); + BetterBlockPos landingSpot = findSafeLandingSpot(); if (landingSpot != null) { this.pathTo(landingSpot); + this.landingSpot = landingSpot; this.goingToLandingSpot = true; return this.onTick(calcFailed, isSafeToCancel); } + // don't spam call findLandingSpot if it somehow fails (it's slow) + this.goingToLandingSpot = true; } this.state = State.LANDING; } } if (this.state == State.LANDING) { - final BetterBlockPos endPos = behavior.pathManager.path.getLast(); + final BetterBlockPos endPos = this.landingSpot != null ? this.landingSpot : behavior.pathManager.path.getLast(); if (ctx.player().isElytraFlying() && endPos != null) { Vec3d from = ctx.player().getPositionVector(); - Vec3d to = new Vec3d(endPos.x, from.y, endPos.z); + Vec3d to = new Vec3d(((double) endPos.x) + 0.5, from.y, ((double) endPos.z) + 0.5); Rotation rotation = RotationUtils.calcRotationFromVec3d(from, to, ctx.playerRotations()); baritone.getLookBehavior().updateTarget(rotation, false); } else { @@ -350,6 +354,18 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro return pos.getY() >= 0 && pos.getY() < 128; } + private boolean isAtEdge(BlockPos pos) { + return ctx.world().isAirBlock(pos.north()) + || ctx.world().isAirBlock(pos.south()) + || ctx.world().isAirBlock(pos.east()) + || ctx.world().isAirBlock(pos.west()) + // corners + || ctx.world().isAirBlock(pos.north().west()) + || ctx.world().isAirBlock(pos.north().east()) + || ctx.world().isAirBlock(pos.south().west()) + || ctx.world().isAirBlock(pos.south().east()); + } + private boolean isSafeLandingSpot(BlockPos pos) { BlockPos.MutableBlockPos mut = new BlockPos.MutableBlockPos(pos); while (mut.getY() >= 0) { @@ -358,21 +374,21 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro return false; } if (state.getMaterial().blocksMovement() && state.getBlock() != Blocks.MAGMA) { - return true; + return !isAtEdge(mut); } mut.setPos(mut.getX(), mut.getY() - 1, mut.getZ()); } return false; // void } - private BlockPos findSafeLandingSpot() { - final BlockPos start = new BlockPos(ctx.playerFeet()); - Queue queue = new LinkedList<>(); - Set visited = new HashSet<>(); + private BetterBlockPos findSafeLandingSpot() { + final BetterBlockPos start = ctx.playerFeet(); + Queue queue = new LinkedList<>(); + Set visited = new HashSet<>(); queue.add(start); while (!queue.isEmpty()) { - BlockPos pos = queue.poll(); + BetterBlockPos pos = queue.poll(); if (ctx.world().isBlockLoaded(pos) && isInBounds(pos) && ctx.world().getBlockState(pos).getBlock() == Blocks.AIR) { if (isSafeLandingSpot(pos)) { return pos; From 58723a33cabc5f5a0d0aaa7454441d11f3a743b8 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sun, 23 Jul 2023 00:05:11 -0400 Subject: [PATCH 341/405] hate cherry pick now --- src/main/java/baritone/command/defaults/ElytraCommand.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index 3232ecb03..eea7f3f33 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -23,8 +23,11 @@ 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; From 9e784435956010f986f1bc337c0be2ec3549881f Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sun, 23 Jul 2023 00:53:26 -0400 Subject: [PATCH 342/405] resolve comment --- src/main/java/baritone/process/ElytraProcess.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index ccab3e2cd..490c7e2e2 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -370,10 +370,10 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro BlockPos.MutableBlockPos mut = new BlockPos.MutableBlockPos(pos); while (mut.getY() >= 0) { IBlockState state = ctx.world().getBlockState(mut); - if (state.getMaterial().isLiquid()) { // lava + if (state.getMaterial().isLiquid() || state.getBlock() != Blocks.MAGMA) { // lava return false; } - if (state.getMaterial().blocksMovement() && state.getBlock() != Blocks.MAGMA) { + if (state.getMaterial().blocksMovement()) { return !isAtEdge(mut); } mut.setPos(mut.getX(), mut.getY() - 1, mut.getZ()); From 985148b49aa7d58c0fce181e1fb16494c987083b Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sun, 23 Jul 2023 01:00:23 -0400 Subject: [PATCH 343/405] check for specific blocks to land on and anything non air is lava --- src/main/java/baritone/process/ElytraProcess.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index 490c7e2e2..4b089ec49 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -41,6 +41,8 @@ import baritone.process.elytra.NetherPathfinderContext; import baritone.process.elytra.NullElytraProcess; import baritone.utils.BaritoneProcessHelper; import baritone.utils.PathingCommandContext; +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.util.math.BlockPos; @@ -370,12 +372,13 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro BlockPos.MutableBlockPos mut = new BlockPos.MutableBlockPos(pos); while (mut.getY() >= 0) { IBlockState state = ctx.world().getBlockState(mut); - if (state.getMaterial().isLiquid() || state.getBlock() != Blocks.MAGMA) { // lava + Block block = state.getBlock(); + + if (block == Blocks.NETHERRACK || block == Blocks.GRAVEL || state.getMaterial() == Material.ROCK) { + return true; + } else if (block != Blocks.AIR) { return false; } - if (state.getMaterial().blocksMovement()) { - return !isAtEdge(mut); - } mut.setPos(mut.getX(), mut.getY() - 1, mut.getZ()); } return false; // void From bf63ffbc1dd0d9fe1d02d9667494e8de17cc7802 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sun, 23 Jul 2023 01:01:59 -0400 Subject: [PATCH 344/405] cringe fence hater :sob: --- src/main/java/baritone/process/ElytraProcess.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index 4b089ec49..9fdcdcc75 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -374,7 +374,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro IBlockState state = ctx.world().getBlockState(mut); Block block = state.getBlock(); - if (block == Blocks.NETHERRACK || block == Blocks.GRAVEL || state.getMaterial() == Material.ROCK) { + if (block == Blocks.NETHERRACK || block == Blocks.GRAVEL || block == Blocks.NETHER_BRICK) { return true; } else if (block != Blocks.AIR) { return false; From 9bfa2025d5327aaae0903fedb115ef93fb7e387f Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sun, 23 Jul 2023 01:14:19 -0400 Subject: [PATCH 345/405] memoize isSafeLandingSPot --- src/main/java/baritone/process/ElytraProcess.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index 9fdcdcc75..b4ce3623a 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -41,6 +41,7 @@ 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.block.Block; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; @@ -368,9 +369,11 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro || ctx.world().isAirBlock(pos.south().east()); } - private boolean isSafeLandingSpot(BlockPos pos) { + private boolean isSafeLandingSpot(BlockPos pos, LongOpenHashSet checkedSpots) { BlockPos.MutableBlockPos mut = new BlockPos.MutableBlockPos(pos); + checkedSpots.add(mut.toLong()); while (mut.getY() >= 0) { + IBlockState state = ctx.world().getBlockState(mut); Block block = state.getBlock(); @@ -380,6 +383,9 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro return false; } mut.setPos(mut.getX(), mut.getY() - 1, mut.getZ()); + if (checkedSpots.contains(mut.toLong())) { + return false; + } } return false; // void } @@ -388,14 +394,16 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro final BetterBlockPos start = ctx.playerFeet(); Queue queue = new LinkedList<>(); Set visited = new HashSet<>(); + LongOpenHashSet checkedPositions = new LongOpenHashSet(); queue.add(start); while (!queue.isEmpty()) { BetterBlockPos pos = queue.poll(); if (ctx.world().isBlockLoaded(pos) && isInBounds(pos) && ctx.world().getBlockState(pos).getBlock() == Blocks.AIR) { - if (isSafeLandingSpot(pos)) { + if (isSafeLandingSpot(pos, checkedPositions)) { return pos; } + checkedPositions.add(pos.toLong()); 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()); From c0ead0147a9741b10ae869d9e1173cd2485ee3b1 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sun, 23 Jul 2023 01:38:07 -0400 Subject: [PATCH 346/405] use priority queue to bias upwards --- src/main/java/baritone/process/ElytraProcess.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index b4ce3623a..135221967 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -48,11 +48,9 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.Vec3i; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.Queue; -import java.util.Set; +import java.util.*; import static baritone.api.pathing.movement.ActionCosts.COST_INF; @@ -373,12 +371,11 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro BlockPos.MutableBlockPos mut = new BlockPos.MutableBlockPos(pos); checkedSpots.add(mut.toLong()); while (mut.getY() >= 0) { - IBlockState state = ctx.world().getBlockState(mut); Block block = state.getBlock(); if (block == Blocks.NETHERRACK || block == Blocks.GRAVEL || block == Blocks.NETHER_BRICK) { - return true; + return !isAtEdge(mut); } else if (block != Blocks.AIR) { return false; } @@ -392,7 +389,8 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro private BetterBlockPos findSafeLandingSpot() { final BetterBlockPos start = ctx.playerFeet(); - Queue queue = new LinkedList<>(); + Queue queue = new PriorityQueue<>(Comparator.comparingInt(Vec3i::getY).reversed()); + //Queue queue = new LinkedList<>(); Set visited = new HashSet<>(); LongOpenHashSet checkedPositions = new LongOpenHashSet(); queue.add(start); From eec85b20be04b0ccd20d3d75656b4ded11625d2e Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sun, 23 Jul 2023 01:45:39 -0400 Subject: [PATCH 347/405] fix bias in comparator --- src/main/java/baritone/process/ElytraProcess.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index 135221967..d0ec7dd6b 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -389,8 +389,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro private BetterBlockPos findSafeLandingSpot() { final BetterBlockPos start = ctx.playerFeet(); - Queue queue = new PriorityQueue<>(Comparator.comparingInt(Vec3i::getY).reversed()); - //Queue queue = new LinkedList<>(); + Queue queue = new PriorityQueue<>(Comparator.comparingInt(pos -> (pos.x-start.x)*(pos.x-start.x) + (pos.z-start.z)*(pos.z-start.z)).thenComparingInt(pos -> -pos.y)); Set visited = new HashSet<>(); LongOpenHashSet checkedPositions = new LongOpenHashSet(); queue.add(start); From b81d712a33eef0e2a663b11eb17c73b01452c84c Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sun, 23 Jul 2023 01:57:27 -0400 Subject: [PATCH 348/405] higher priority is good enough lol --- src/main/java/baritone/utils/PathingControlManager.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/main/java/baritone/utils/PathingControlManager.java b/src/main/java/baritone/utils/PathingControlManager.java index 2ae4b00ce..6123412f7 100644 --- a/src/main/java/baritone/utils/PathingControlManager.java +++ b/src/main/java/baritone/utils/PathingControlManager.java @@ -207,13 +207,7 @@ public class PathingControlManager implements IPathingControlManager { } else if (exec.commandType != PathingCommandType.DEFER) { inControlThisTick = proc; if (!proc.isTemporary()) { - iterator.forEachRemaining(it -> { - // TODO: find a better way to make these behave well together - if (proc instanceof CustomGoalProcess && it instanceof ElytraProcess) { - return; - } - it.onLostControl(); - }); + iterator.forEachRemaining(IBaritoneProcess::onLostControl); } return exec; } From 9707dd7ce83526207d592b1620911896cc93e413 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sat, 22 Jul 2023 23:02:29 -0700 Subject: [PATCH 349/405] redo checkedpositions given y descending iteration order --- src/main/java/baritone/process/ElytraProcess.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index d0ec7dd6b..873dd5e48 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -43,12 +43,10 @@ import baritone.utils.BaritoneProcessHelper; import baritone.utils.PathingCommandContext; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import net.minecraft.block.Block; -import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; -import net.minecraft.util.math.Vec3i; import java.util.*; @@ -369,8 +367,11 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro private boolean isSafeLandingSpot(BlockPos pos, LongOpenHashSet checkedSpots) { BlockPos.MutableBlockPos mut = new BlockPos.MutableBlockPos(pos); - checkedSpots.add(mut.toLong()); while (mut.getY() >= 0) { + if (checkedSpots.contains(mut.toLong())) { + return false; + } + checkedSpots.add(mut.toLong()); IBlockState state = ctx.world().getBlockState(mut); Block block = state.getBlock(); @@ -380,16 +381,13 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro return false; } mut.setPos(mut.getX(), mut.getY() - 1, mut.getZ()); - if (checkedSpots.contains(mut.toLong())) { - return false; - } } return false; // void } private BetterBlockPos findSafeLandingSpot() { final BetterBlockPos start = ctx.playerFeet(); - Queue queue = new PriorityQueue<>(Comparator.comparingInt(pos -> (pos.x-start.x)*(pos.x-start.x) + (pos.z-start.z)*(pos.z-start.z)).thenComparingInt(pos -> -pos.y)); + Queue queue = new PriorityQueue<>(Comparator.comparingInt(pos -> (pos.x - start.x) * (pos.x - start.x) + (pos.z - start.z) * (pos.z - start.z)).thenComparingInt(pos -> -pos.y)); Set visited = new HashSet<>(); LongOpenHashSet checkedPositions = new LongOpenHashSet(); queue.add(start); @@ -400,7 +398,6 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro if (isSafeLandingSpot(pos, checkedPositions)) { return pos; } - checkedPositions.add(pos.toLong()); 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()); From f7f05210935d202fab13b6b615c444f0595f65fa Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sat, 22 Jul 2023 23:29:07 -0700 Subject: [PATCH 350/405] not legacy --- .../java/baritone/process/ElytraProcess.java | 6 +-- ...lytraBehavior.java => ElytraBehavior.java} | 41 ++++++++++--------- 2 files changed, 24 insertions(+), 23 deletions(-) rename src/main/java/baritone/process/elytra/{LegacyElytraBehavior.java => ElytraBehavior.java} (97%) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index 188625508..327018faf 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -38,7 +38,7 @@ 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.LegacyElytraBehavior; +import baritone.process.elytra.ElytraBehavior; import baritone.process.elytra.NetherPathfinderContext; import baritone.process.elytra.NullElytraProcess; import baritone.utils.BaritoneProcessHelper; @@ -59,7 +59,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro private boolean goingToLandingSpot; private BetterBlockPos landingSpot; private Goal goal; - private LegacyElytraBehavior behavior; + private ElytraBehavior behavior; private ElytraProcess(Baritone baritone) { super(baritone); @@ -260,7 +260,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro @Override public void pathTo(BlockPos destination) { this.onLostControl(); - this.behavior = new LegacyElytraBehavior(this.baritone, this, destination); + this.behavior = new ElytraBehavior(this.baritone, this, destination); if (ctx.world() != null) { this.behavior.repackChunks(); } diff --git a/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java b/src/main/java/baritone/process/elytra/ElytraBehavior.java similarity index 97% rename from src/main/java/baritone/process/elytra/LegacyElytraBehavior.java rename to src/main/java/baritone/process/elytra/ElytraBehavior.java index c147442ce..a99b4e331 100644 --- a/src/main/java/baritone/process/elytra/LegacyElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/ElytraBehavior.java @@ -49,15 +49,16 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.world.chunk.Chunk; 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; import static baritone.utils.BaritoneMath.fastCeil; import static baritone.utils.BaritoneMath.fastFloor; -public final class LegacyElytraBehavior implements Helper { +public final class ElytraBehavior implements Helper { private final Baritone baritone; private final IPlayerContext ctx; @@ -109,7 +110,7 @@ public final class LegacyElytraBehavior implements Helper { private int invTickCountdown = 0; private final Queue invTransactionQueue = new LinkedList<>(); - public LegacyElytraBehavior(Baritone baritone, ElytraProcess process, BlockPos destination) { + public ElytraBehavior(Baritone baritone, ElytraProcess process, BlockPos destination) { this.baritone = baritone; this.ctx = baritone.getPlayerContext(); this.clearLines = new CopyOnWriteArrayList<>(); @@ -162,7 +163,7 @@ public final class LegacyElytraBehavior implements Helper { public CompletableFuture pathToDestination(final BlockPos from) { final long start = System.nanoTime(); - return this.path0(from, LegacyElytraBehavior.this.destination, UnaryOperator.identity()) + return this.path0(from, ElytraBehavior.this.destination, UnaryOperator.identity()) .thenRun(() -> { final double distance = this.path.get(0).distanceTo(this.path.get(this.path.size() - 1)); if (this.completePath) { @@ -216,7 +217,7 @@ public final class LegacyElytraBehavior implements Helper { final List before = this.path.subList(0, afterIncl + 1); final long start = System.nanoTime(); - this.path0(this.path.get(afterIncl), LegacyElytraBehavior.this.destination, segment -> segment.prepend(before.stream())) + this.path0(this.path.get(afterIncl), ElytraBehavior.this.destination, segment -> segment.prepend(before.stream())) .thenRun(() -> { final int recompute = this.path.size() - before.size() - 1; final double distance = this.path.get(0).distanceTo(this.path.get(recompute)); @@ -267,7 +268,7 @@ public final class LegacyElytraBehavior implements Helper { // mickey resigned private CompletableFuture path0(BlockPos src, BlockPos dst, UnaryOperator operator) { - return LegacyElytraBehavior.this.context.pathFindAsync(src, dst) + return ElytraBehavior.this.context.pathFindAsync(src, dst) .thenApply(UnpackedSegment::from) .thenApply(operator) .thenAcceptAsync(this::setPath, ctx.minecraft()::addScheduledTask); @@ -289,12 +290,12 @@ public final class LegacyElytraBehavior implements Helper { return; } final BetterBlockPos rangeStart = path.get(rangeStartIncl); - if (!LegacyElytraBehavior.this.passable(rangeStart.x, rangeStart.y, rangeStart.z, false)) { + if (!ElytraBehavior.this.passable(rangeStart.x, rangeStart.y, rangeStart.z, false)) { // we're in a wall return; // previous iterations of this function SHOULD have fixed this by now :rage_cat: } - if (LegacyElytraBehavior.this.process.state != ElytraProcess.State.LANDING && this.ticksNearUnchanged > 100) { + if (ElytraBehavior.this.process.state != ElytraProcess.State.LANDING && this.ticksNearUnchanged > 100) { this.pathRecalcSegment(rangeEndExcl - 1) .thenRun(() -> { logDirect("Recalculating segment, no progress in last 100 ticks"); @@ -304,7 +305,7 @@ public final class LegacyElytraBehavior implements Helper { } for (int i = rangeStartIncl; i < rangeEndExcl - 1; i++) { - if (!LegacyElytraBehavior.this.clearView(this.path.getVec(i), this.path.getVec(i + 1), false)) { + if (!ElytraBehavior.this.clearView(this.path.getVec(i), this.path.getVec(i + 1), false)) { // obstacle. where do we return to pathing? // find the next valid segment final BetterBlockPos blockage = this.path.get(i); @@ -677,8 +678,8 @@ public final class LegacyElytraBehavior implements Helper { ) { // Prioritize boosting fireworks over regular ones // TODO: Take the minimum boost time into account? - if (!baritone.getInventoryBehavior().throwaway(true, LegacyElytraBehavior::isBoostingFireworks) && - !baritone.getInventoryBehavior().throwaway(true, LegacyElytraBehavior::isFireworks)) { + if (!baritone.getInventoryBehavior().throwaway(true, ElytraBehavior::isBoostingFireworks) && + !baritone.getInventoryBehavior().throwaway(true, ElytraBehavior::isFireworks)) { logDirect("no fireworks"); return; } @@ -700,21 +701,21 @@ public final class LegacyElytraBehavior implements Helper { public final IAimProcessor aimProcessor; public SolverContext(boolean async) { - this.path = LegacyElytraBehavior.this.pathManager.getPath(); - this.playerNear = LegacyElytraBehavior.this.pathManager.getNear(); - this.start = LegacyElytraBehavior.this.ctx.playerFeetAsVec(); - this.ignoreLava = LegacyElytraBehavior.this.ctx.player().isInLava(); + this.path = ElytraBehavior.this.pathManager.getPath(); + this.playerNear = ElytraBehavior.this.pathManager.getNear(); + this.start = ElytraBehavior.this.ctx.playerFeetAsVec(); + this.ignoreLava = ElytraBehavior.this.ctx.player().isInLava(); final Integer fireworkTicksExisted; - if (async && LegacyElytraBehavior.this.deployedFireworkLastTick) { - final int[] counter = LegacyElytraBehavior.this.nextTickBoostCounter; + if (async && ElytraBehavior.this.deployedFireworkLastTick) { + final int[] counter = ElytraBehavior.this.nextTickBoostCounter; fireworkTicksExisted = counter[1] > counter[0] ? 0 : null; } else { - fireworkTicksExisted = LegacyElytraBehavior.this.getAttachedFirework().map(e -> e.ticksExisted).orElse(null); + fireworkTicksExisted = ElytraBehavior.this.getAttachedFirework().map(e -> e.ticksExisted).orElse(null); } - this.boost = new FireworkBoost(fireworkTicksExisted, LegacyElytraBehavior.this.minimumBoostTicks); + this.boost = new FireworkBoost(fireworkTicksExisted, ElytraBehavior.this.minimumBoostTicks); - ITickableAimProcessor aim = LegacyElytraBehavior.this.baritone.getLookBehavior().getAimProcessor().fork(); + ITickableAimProcessor aim = ElytraBehavior.this.baritone.getLookBehavior().getAimProcessor().fork(); if (async) { // async computation is done at the end of a tick, advance by 1 to prepare for the next tick aim.advance(1); From 75e8035551fcce2c1e0076f767f9aa3fc086681d Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sun, 23 Jul 2023 14:26:31 -0400 Subject: [PATCH 351/405] safe landing improvements --- .../java/baritone/process/ElytraProcess.java | 62 +++++++++++++------ 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index 327018faf..be385a853 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -383,36 +383,57 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro return pos.getY() >= 0 && pos.getY() < 128; } - private boolean isAtEdge(BlockPos pos) { - return ctx.world().isAirBlock(pos.north()) - || ctx.world().isAirBlock(pos.south()) - || ctx.world().isAirBlock(pos.east()) - || ctx.world().isAirBlock(pos.west()) - // corners - || ctx.world().isAirBlock(pos.north().west()) - || ctx.world().isAirBlock(pos.north().east()) - || ctx.world().isAirBlock(pos.south().west()) - || ctx.world().isAirBlock(pos.south().east()); + private boolean isSafeBlock(Block block) { + return block == Blocks.NETHERRACK || block == Blocks.GRAVEL || block == Blocks.NETHER_BRICK; + } + private boolean isSafeBlock(BlockPos pos) { + return isSafeBlock(ctx.world().getBlockState(pos).getBlock()); } - private boolean isSafeLandingSpot(BlockPos pos, LongOpenHashSet checkedSpots) { + private boolean isAtEdge(BlockPos pos) { + return !isSafeBlock(pos.north()) + || !isSafeBlock(pos.south()) + || !isSafeBlock(pos.east()) + || !isSafeBlock(pos.west()) + // corners + || !isSafeBlock(pos.north().west()) + || !isSafeBlock(pos.north().east()) + || !isSafeBlock(pos.south().west()) + || !isSafeBlock(pos.south().east()); + } + + private boolean isColumnAir(BlockPos landingSpot, int minHeight) { + BlockPos.MutableBlockPos mut = new BlockPos.MutableBlockPos(landingSpot); + final int maxY = mut.getY() + minHeight; + for (int y = mut.getY() + 1; y <= maxY; y++) { + mut.setPos(mut.getX(), y, mut.getZ()); + if (!ctx.world().isAirBlock(mut)) { + return false; + } + } + return true; + } + + private BetterBlockPos checkLandingSpot(BlockPos pos, LongOpenHashSet checkedSpots) { BlockPos.MutableBlockPos mut = new BlockPos.MutableBlockPos(pos); while (mut.getY() >= 0) { if (checkedSpots.contains(mut.toLong())) { - return false; + return null; } checkedSpots.add(mut.toLong()); - IBlockState state = ctx.world().getBlockState(mut); - Block block = state.getBlock(); + Block block = ctx.world().getBlockState(mut).getBlock(); - if (block == Blocks.NETHERRACK || block == Blocks.GRAVEL || block == Blocks.NETHER_BRICK) { - return !isAtEdge(mut); + if (isSafeBlock(block)) { + if (!isAtEdge(mut)) { + return new BetterBlockPos(mut); + } + return null; } else if (block != Blocks.AIR) { - return false; + return null; } mut.setPos(mut.getX(), mut.getY() - 1, mut.getZ()); } - return false; // void + return null; // void } private BetterBlockPos findSafeLandingSpot() { @@ -425,8 +446,9 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro while (!queue.isEmpty()) { BetterBlockPos pos = queue.poll(); if (ctx.world().isBlockLoaded(pos) && isInBounds(pos) && ctx.world().getBlockState(pos).getBlock() == Blocks.AIR) { - if (isSafeLandingSpot(pos, checkedPositions)) { - return pos; + BetterBlockPos actualLandingSpot = checkLandingSpot(pos, checkedPositions); + if (actualLandingSpot != null && isColumnAir(actualLandingSpot, 15)) { + return actualLandingSpot.up(15); } if (visited.add(pos.north())) queue.add(pos.north()); if (visited.add(pos.east())) queue.add(pos.east()); From 212ef4d4cc8d3d52d07d9dc20e33f585a657144c Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 23 Jul 2023 11:44:29 -0700 Subject: [PATCH 352/405] waste fireworks smiling_imp --- src/api/java/baritone/api/Settings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 3ab2a068b..d664b569c 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -1377,7 +1377,7 @@ public final class Settings { /** * If enabled, avoids using fireworks when descending along the flight path. */ - public final Setting elytraConserveFireworks = new Setting<>(true); + public final Setting elytraConserveFireworks = new Setting<>(false); /** * Renders the raytraces that are performed by the elytra fly calculation. From e63aad782518667b180dde3c7bb404ca8fb45903 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sun, 23 Jul 2023 15:09:56 -0400 Subject: [PATCH 353/405] elytra command improvements --- .../command/defaults/ElytraCommand.java | 44 +++++++++++++------ 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index 7f985ad55..f7aaebc81 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -22,12 +22,10 @@ import baritone.api.command.Command; import baritone.api.command.argument.IArgConsumer; import baritone.api.command.exception.CommandException; import baritone.api.command.exception.CommandInvalidStateException; +import baritone.api.command.helpers.TabCompleteHelper; 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; @@ -43,15 +41,12 @@ public class ElytraCommand extends Command { public void execute(String label, IArgConsumer args) throws CommandException { final ICustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess(); final IElytraProcess elytra = baritone.getElytraProcess(); + if (args.hasExactlyOne() && args.peekString().equals("supported")) { + logDirect(elytra.isLoaded() ? "yes" : unsupportedSystemMessage()); + return; + } if (!elytra.isLoaded()) { - final String osArch = System.getProperty("os.arch"); - final String osName = System.getProperty("os.name"); - throw new CommandInvalidStateException(String.format( - "legacy architectures are not supported. your CPU is %s and your operating system is %s. " + - "supported architectures are x86_64 or arm64, supported operating systems are windows, " + - "linux, and mac", - osArch, osName - )); + throw new CommandInvalidStateException(unsupportedSystemMessage()); } if (!args.hasAny()) { @@ -87,7 +82,11 @@ public class ElytraCommand extends Command { @Override public Stream tabComplete(String label, IArgConsumer args) throws CommandException { - return Stream.empty(); + TabCompleteHelper helper = new TabCompleteHelper(); + if (args.hasExactlyOne()) { + helper.append("reset", "repack", "supported"); + } + return helper.filterPrefix(args.getString()).stream(); } @Override @@ -97,6 +96,25 @@ public class ElytraCommand extends Command { @Override public List getLongDesc() { - return Arrays.asList(); + return Arrays.asList( + "The elytra command tells baritone to, in the nether, automatically fly to the current goal.", + "", + "Usage:", + "> elytra - fly to the current goal", + "> elytra reset - Resets the state of the process, but will try to keep flying to the same goal.", + "> elytra repack - Queues all of the chunks in render distance to be given to the native library.", + "> elytra supported - Tells you if baritone ships a native library that is compatible with your PC." + ); + } + + private static String unsupportedSystemMessage() { + final String osArch = System.getProperty("os.arch"); + final String osName = System.getProperty("os.name"); + return String.format( + "Legacy architectures are not supported. your CPU is %s and your operating system is %s. " + + "Supported architectures are 64 bit x86, and 64 bit arm, supported operating systems are Windows, " + + "Linux, and Mac", + osArch, osName + ); } } From 293b556b56e95ea73824b7b65a93091ec4deb9f4 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sun, 23 Jul 2023 20:46:12 -0400 Subject: [PATCH 354/405] add dimension checks --- src/main/java/baritone/command/defaults/ElytraCommand.java | 3 +++ src/main/java/baritone/process/ElytraProcess.java | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index f7aaebc81..6ba08dba9 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -54,6 +54,9 @@ public class ElytraCommand extends Command { if (iGoal == null) { throw new CommandInvalidStateException("No goal has been set"); } + if (ctx.player().dimension != -1) { + throw new CommandInvalidStateException("Only works in the nether"); + } try { elytra.pathTo(iGoal); } catch (IllegalArgumentException ex) { diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index be385a853..754587a47 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -259,6 +259,9 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro @Override public void pathTo(BlockPos destination) { + if (ctx.player() == null || ctx.player().dimension != -1) { + return; + } this.onLostControl(); this.behavior = new ElytraBehavior(this.baritone, this, destination); if (ctx.world() != null) { From 45400a968562a6f6d880f7c2de97cfcc1f1ab8f6 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Mon, 24 Jul 2023 03:30:06 -0400 Subject: [PATCH 355/405] fix concurrency concerns --- .../elytra/BlockStateOctreeInterface.java | 11 ++++------- .../baritone/process/elytra/ElytraBehavior.java | 17 +++++++++++------ .../process/elytra/NetherPathfinderContext.java | 7 ++++--- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/main/java/baritone/process/elytra/BlockStateOctreeInterface.java b/src/main/java/baritone/process/elytra/BlockStateOctreeInterface.java index f9e700085..efbfb9216 100644 --- a/src/main/java/baritone/process/elytra/BlockStateOctreeInterface.java +++ b/src/main/java/baritone/process/elytra/BlockStateOctreeInterface.java @@ -27,7 +27,7 @@ public final class BlockStateOctreeInterface { private final NetherPathfinderContext context; private final long contextPtr; - volatile long chunkPtr; + transient long chunkPtr; // Guarantee that the first lookup will fetch the context by setting MAX_VALUE private int prevChunkX = Integer.MAX_VALUE; @@ -44,14 +44,11 @@ public final class BlockStateOctreeInterface { } final int chunkX = x >> 4; final int chunkZ = z >> 4; - long pointer = this.chunkPtr; - if (pointer == 0 | ((chunkX ^ this.prevChunkX) | (chunkZ ^ this.prevChunkZ)) != 0) { + if (this.chunkPtr == 0 | ((chunkX ^ this.prevChunkX) | (chunkZ ^ this.prevChunkZ)) != 0) { this.prevChunkX = chunkX; this.prevChunkZ = chunkZ; - synchronized (this.context.cacheLock) { - this.chunkPtr = pointer = NetherPathfinder.getOrCreateChunk(this.contextPtr, chunkX, chunkZ); - } + this.chunkPtr = NetherPathfinder.getOrCreateChunk(this.contextPtr, chunkX, chunkZ); } - return Octree.getBlock(pointer, x & 0xF, y & 0x7F, z & 0xF); + return Octree.getBlock(this.chunkPtr, x & 0xF, y & 0x7F, z & 0xF); } } diff --git a/src/main/java/baritone/process/elytra/ElytraBehavior.java b/src/main/java/baritone/process/elytra/ElytraBehavior.java index a99b4e331..0e6b7ad2a 100644 --- a/src/main/java/baritone/process/elytra/ElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/ElytraBehavior.java @@ -446,6 +446,17 @@ public final class ElytraBehavior implements Helper { } public void onTick() { + synchronized (this.context.cullingLock) { + this.onTick0(); + } + final long now = System.currentTimeMillis(); + if ((now - this.timeLastCacheCull) / 1000 > Baritone.settings().elytraTimeBetweenCacheCullSecs.value) { + this.context.queueCacheCulling(ctx.player().chunkCoordX, ctx.player().chunkCoordZ, Baritone.settings().elytraCacheCullDistance.value, this.boi); + this.timeLastCacheCull = now; + } + } + + private void onTick0() { // Fetch the previous solution, regardless of if it's going to be used this.pendingSolution = null; if (this.solver != null) { @@ -498,12 +509,6 @@ public final class ElytraBehavior implements Helper { Math.max(playerNear - 30, 0), Math.min(playerNear + 100, path.size()) ); - - final long now = System.currentTimeMillis(); - if ((now - this.timeLastCacheCull) / 1000 > Baritone.settings().elytraTimeBetweenCacheCullSecs.value) { - this.context.queueCacheCulling(ctx.player().chunkCoordX, ctx.player().chunkCoordZ, Baritone.settings().elytraCacheCullDistance.value, this.boi); - this.timeLastCacheCull = now; - } } /** diff --git a/src/main/java/baritone/process/elytra/NetherPathfinderContext.java b/src/main/java/baritone/process/elytra/NetherPathfinderContext.java index 69ac41992..991457d10 100644 --- a/src/main/java/baritone/process/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/process/elytra/NetherPathfinderContext.java @@ -38,7 +38,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; /** * @author Brady @@ -46,7 +45,9 @@ import java.util.concurrent.atomic.AtomicInteger; public final class NetherPathfinderContext { private static final IBlockState AIR_BLOCK_STATE = Blocks.AIR.getDefaultState(); - public final Object cacheLock = new Object(); + // This lock must be held while there are active pointers to chunks in java, + // but we just hold it for the entire tick so we don't have to think much about it. + public final Object cullingLock = new Object(); // Visible for access in BlockStateOctreeInterface final long context; @@ -61,7 +62,7 @@ public final class NetherPathfinderContext { public void queueCacheCulling(int chunkX, int chunkZ, int maxDistanceBlocks, BlockStateOctreeInterface boi) { this.executor.execute(() -> { - synchronized (this.cacheLock) { + synchronized (this.cullingLock) { boi.chunkPtr = 0L; NetherPathfinder.cullFarChunks(this.context, chunkX, chunkZ, maxDistanceBlocks); } From 1e0dce8f416db615c2f76f20c1d5419f576a4a91 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Mon, 24 Jul 2023 03:30:38 -0400 Subject: [PATCH 356/405] 127 instead of 128 --- .../java/baritone/process/elytra/BlockStateOctreeInterface.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/process/elytra/BlockStateOctreeInterface.java b/src/main/java/baritone/process/elytra/BlockStateOctreeInterface.java index efbfb9216..7db0e2d64 100644 --- a/src/main/java/baritone/process/elytra/BlockStateOctreeInterface.java +++ b/src/main/java/baritone/process/elytra/BlockStateOctreeInterface.java @@ -39,7 +39,7 @@ public final class BlockStateOctreeInterface { } public boolean get0(final int x, final int y, final int z) { - if ((y | (128 - y)) < 0) { + if ((y | (127 - y)) < 0) { return false; } final int chunkX = x >> 4; From f14bb282f049d7ad723c6ebcb3c5e61fec12a9c6 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Mon, 24 Jul 2023 04:41:19 -0400 Subject: [PATCH 357/405] add null check to resetState --- src/main/java/baritone/process/ElytraProcess.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index 754587a47..1ab9f74f5 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -81,8 +81,10 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro public void resetState() { BlockPos destination = this.currentDestination(); this.onLostControl(); - this.pathTo(destination); - this.repackChunks(); + if (destination != null) { + this.pathTo(destination); + this.repackChunks(); + } } @Override From 601a781983ba3157fec32c29c3817e787530c340 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Mon, 24 Jul 2023 08:21:46 -0400 Subject: [PATCH 358/405] improve control flow (fixes behavior.onTick() being called twice) --- .../java/baritone/process/ElytraProcess.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index 1ab9f74f5..126621ed9 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -58,6 +58,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro 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; @@ -106,27 +107,29 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro if (ctx.player().isElytraFlying() && this.state != State.LANDING) { final BetterBlockPos last = this.behavior.pathManager.path.getLast(); if (last != null && ctx.player().getDistanceSqToCenter(last) < 1) { - if (Baritone.settings().notificationOnPathComplete.value) { + if (Baritone.settings().notificationOnPathComplete.value && !reachedGoal) { logNotification("Pathing complete", false); } - if (Baritone.settings().disconnectOnArrival.value) { + if (Baritone.settings().disconnectOnArrival.value && !reachedGoal) { // don't be active when the user logs back in this.onLostControl(); ctx.world().sendQuittingDisconnectingPacket(); return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } + reachedGoal = true; + if (!goingToLandingSpot) { BetterBlockPos landingSpot = findSafeLandingSpot(); + // if this fails we will just keep orbiting the last node until we run out of rockets or the user intervenes if (landingSpot != null) { this.pathTo(landingSpot); this.landingSpot = landingSpot; this.goingToLandingSpot = true; - return this.onTick(calcFailed, isSafeToCancel); } - // don't spam call findLandingSpot if it somehow fails (it's slow) - this.goingToLandingSpot = true; + } else { + // we are goingToLandingSpot and we are in the in the last node of the path + this.state = State.LANDING; } - this.state = State.LANDING; } } @@ -230,6 +233,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro public void onLostControl() { this.goal = null; this.goingToLandingSpot = false; + this.reachedGoal = false; this.state = State.START_FLYING; // TODO: null state? if (this.behavior != null) { this.behavior.destroy(); From 90f2b39fba61b2adcb7741f4c4711374a596e30e Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 26 Jul 2023 19:52:25 -0500 Subject: [PATCH 359/405] Remove glPushAttrib/glPopAttrib usage --- src/main/java/baritone/utils/IRenderer.java | 2 ++ src/main/java/baritone/utils/PathRenderer.java | 6 ------ 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/java/baritone/utils/IRenderer.java b/src/main/java/baritone/utils/IRenderer.java index 680d7e380..6ccc0847c 100644 --- a/src/main/java/baritone/utils/IRenderer.java +++ b/src/main/java/baritone/utils/IRenderer.java @@ -57,6 +57,7 @@ public interface IRenderer { GlStateManager.glLineWidth(lineWidth); GlStateManager.disableTexture2D(); GlStateManager.depthMask(false); + GlStateManager.disableLighting(); if (ignoreDepth) { GlStateManager.disableDepth(); @@ -77,6 +78,7 @@ public interface IRenderer { GlStateManager.depthMask(true); GlStateManager.enableTexture2D(); GlStateManager.disableBlend(); + GlStateManager.enableLighting(); } static void emitAABB(AxisAlignedBB aabb) { diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index b3abc8cd2..93f916f1d 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -41,8 +41,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import static org.lwjgl.opengl.GL11.*; - /** * @author Brady * @since 8/9/2018 @@ -239,8 +237,6 @@ public final class PathRenderer implements IRenderer { GoalXZ goalPos = (GoalXZ) goal; if (settings.renderGoalXZBeacon.value) { - glPushAttrib(GL_LIGHTING_BIT); - textureManager.bindTexture(TileEntityBeaconRenderer.TEXTURE_BEACON_BEAM); if (settings.renderGoalIgnoreDepth.value) { @@ -262,8 +258,6 @@ public final class PathRenderer implements IRenderer { if (settings.renderGoalIgnoreDepth.value) { GlStateManager.enableDepth(); } - - glPopAttrib(); return; } From 6b611cf4c7e0be9a7e19aeeb0c635a0175dd65d9 Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 28 Jul 2023 01:30:54 -0500 Subject: [PATCH 360/405] Move more state into `SolverContext` --- .../process/elytra/ElytraBehavior.java | 40 ++++++++++++++----- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/src/main/java/baritone/process/elytra/ElytraBehavior.java b/src/main/java/baritone/process/elytra/ElytraBehavior.java index 0e6b7ad2a..f5a32c5f2 100644 --- a/src/main/java/baritone/process/elytra/ElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/ElytraBehavior.java @@ -701,15 +701,26 @@ public final class ElytraBehavior implements Helper { public final NetherPath path; public final int playerNear; public final Vec3d start; + public final Vec3d motion; + public final AxisAlignedBB boundingBox; public final boolean ignoreLava; public final FireworkBoost boost; public final IAimProcessor aimProcessor; + /** + * Creates a new SolverContext using the current state of the path, player, and firework boost at the time of + * construction. + * + * @param async Whether the computation is being done asynchronously at the end of a game tick. + */ public SolverContext(boolean async) { this.path = ElytraBehavior.this.pathManager.getPath(); this.playerNear = ElytraBehavior.this.pathManager.getNear(); - this.start = ElytraBehavior.this.ctx.playerFeetAsVec(); - this.ignoreLava = ElytraBehavior.this.ctx.player().isInLava(); + + this.start = ctx.playerFeetAsVec(); + this.motion = ctx.playerMotion(); + this.boundingBox = ctx.player().getEntityBoundingBox(); + this.ignoreLava = ctx.player().isInLava(); final Integer fireworkTicksExisted; if (async && ElytraBehavior.this.deployedFireworkLastTick) { @@ -741,6 +752,8 @@ public final class ElytraBehavior implements Helper { return this.path == other.path // Contents aren't modified, just compare by reference && this.playerNear == other.playerNear && Objects.equals(this.start, other.start) + && Objects.equals(this.motion, other.motion) + && Objects.equals(this.boundingBox, other.boundingBox) && this.ignoreLava == other.ignoreLava && Objects.equals(this.boost, other.boost); } @@ -752,6 +765,11 @@ public final class ElytraBehavior implements Helper { private final int minimumBoostTicks; private final int maximumBoostTicks; + /** + * @param fireworkTicksExisted The ticksExisted of the attached firework entity, or {@code null} if no entity. + * @param minimumBoostTicks The minimum number of boost ticks that the attached firework entity, if any, will + * provide. + */ public FireworkBoost(final Integer fireworkTicksExisted, final int minimumBoostTicks) { this.fireworkTicksExisted = fireworkTicksExisted; @@ -870,7 +888,7 @@ public final class ElytraBehavior implements Helper { return true; } - final AxisAlignedBB bb = ctx.player().getEntityBoundingBox().grow(growAmount); + final AxisAlignedBB bb = context.boundingBox.grow(growAmount); final double ox = dest.x - start.x; final double oy = dest.y - start.y; @@ -1032,13 +1050,12 @@ public final class ElytraBehavior implements Helper { while (pitches.hasNext()) { final float pitch = pitches.nextFloat(); final List displacement = this.simulate( - context.aimProcessor.fork(), + context, goalDelta, pitch, ticks, ticksBoosted, - ticksBoostDelay, - context.ignoreLava + ticksBoostDelay ); if (displacement == null) { continue; @@ -1074,11 +1091,12 @@ public final class ElytraBehavior implements Helper { return null; } - private List simulate(final ITickableAimProcessor aimProcessor, final Vec3d goalDelta, final float pitch, - final int ticks, final int ticksBoosted, final int ticksBoostDelay, final boolean ignoreLava) { + private List simulate(final SolverContext context, final Vec3d goalDelta, final float pitch, final int ticks, + final int ticksBoosted, final int ticksBoostDelay) { + final ITickableAimProcessor aimProcessor = context.aimProcessor.fork(); Vec3d delta = goalDelta; - Vec3d motion = ctx.playerMotion(); - AxisAlignedBB hitbox = ctx.player().getEntityBoundingBox(); + Vec3d motion = context.motion; + AxisAlignedBB hitbox = context.boundingBox; List displacement = new ArrayList<>(ticks + 1); displacement.add(Vec3d.ZERO); int remainingTicksBoosted = ticksBoosted; @@ -1112,7 +1130,7 @@ public final class ElytraBehavior implements Helper { for (int x = xmin; x < xmax; x++) { for (int y = ymin; y < ymax; y++) { for (int z = zmin; z < zmax; z++) { - if (!this.passable(x, y, z, ignoreLava)) { + if (!this.passable(x, y, z, context.ignoreLava)) { return null; } } From 4b5a094f308f3a06a63a2f3dd28d5bb4ca9de3dd Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 28 Jul 2023 01:41:03 -0500 Subject: [PATCH 361/405] Render fields can be private now --- .../baritone/process/elytra/ElytraBehavior.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/baritone/process/elytra/ElytraBehavior.java b/src/main/java/baritone/process/elytra/ElytraBehavior.java index f5a32c5f2..c0cd07c87 100644 --- a/src/main/java/baritone/process/elytra/ElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/ElytraBehavior.java @@ -62,13 +62,12 @@ public final class ElytraBehavior implements Helper { private final Baritone baritone; private final IPlayerContext ctx; - - // Used exclusively for PathRenderer - public List> clearLines; - public List> blockedLines; - public List simulationLine; - public BlockPos aimPos; - public List visiblePath; + // Render stuff + private final List> clearLines; + private final List> blockedLines; + private List simulationLine; + private BlockPos aimPos; + private List visiblePath; // :sunglasses: public final NetherPathfinderContext context; From 31d1656c48633528afa511bad9bb683d58336884 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sat, 29 Jul 2023 00:22:52 -0400 Subject: [PATCH 362/405] safer landing --- .../java/baritone/process/ElytraProcess.java | 48 +++++++++++++------ .../process/elytra/ElytraBehavior.java | 4 ++ 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index 126621ed9..ff374aad1 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -104,8 +104,18 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } - if (ctx.player().isElytraFlying() && this.state != State.LANDING) { + if (ctx.player().isElytraFlying() && this.state != State.LANDING && this.behavior.pathManager.isComplete()) { final BetterBlockPos last = this.behavior.pathManager.path.getLast(); + if (last != null && ctx.player().getDistanceSqToCenter(last) < (48 * 48) && !goingToLandingSpot) { + BetterBlockPos landingSpot = findSafeLandingSpot(last); + // if this fails we will just keep orbiting the last node until we run out of rockets or the user intervenes + if (landingSpot != null) { + this.pathTo(landingSpot); + this.landingSpot = landingSpot; + this.goingToLandingSpot = true; + } + } + if (last != null && ctx.player().getDistanceSqToCenter(last) < 1) { if (Baritone.settings().notificationOnPathComplete.value && !reachedGoal) { logNotification("Pathing complete", false); @@ -118,16 +128,8 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro } reachedGoal = true; - if (!goingToLandingSpot) { - BetterBlockPos landingSpot = findSafeLandingSpot(); - // if this fails we will just keep orbiting the last node until we run out of rockets or the user intervenes - if (landingSpot != null) { - this.pathTo(landingSpot); - this.landingSpot = landingSpot; - this.goingToLandingSpot = true; - } - } else { - // we are goingToLandingSpot and we are in the in the last node of the path + // we are goingToLandingSpot and we are in the last node of the path + if (this.goingToLandingSpot) { this.state = State.LANDING; } } @@ -423,6 +425,25 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro return true; } + private boolean hasAirBubble(BlockPos pos) { + final int radius = 2; // Half of 5, as we're counting blocks in each direction from the center + + for (int x = -radius; x <= radius; x++) { + for (int y = -radius; y <= radius; y++) { + for (int z = -radius; z <= radius; z++) { + BlockPos currentPos = pos.add(x, y, z); + IBlockState blockState = ctx.world().getBlockState(currentPos); + + if (blockState.getBlock() != Blocks.AIR) { + return false; + } + } + } + } + + return true; + } + private BetterBlockPos checkLandingSpot(BlockPos pos, LongOpenHashSet checkedSpots) { BlockPos.MutableBlockPos mut = new BlockPos.MutableBlockPos(pos); while (mut.getY() >= 0) { @@ -445,8 +466,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro return null; // void } - private BetterBlockPos findSafeLandingSpot() { - final BetterBlockPos start = ctx.playerFeet(); + private BetterBlockPos findSafeLandingSpot(BetterBlockPos start) { Queue queue = new PriorityQueue<>(Comparator.comparingInt(pos -> (pos.x - start.x) * (pos.x - start.x) + (pos.z - start.z) * (pos.z - start.z)).thenComparingInt(pos -> -pos.y)); Set visited = new HashSet<>(); LongOpenHashSet checkedPositions = new LongOpenHashSet(); @@ -456,7 +476,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro BetterBlockPos pos = queue.poll(); if (ctx.world().isBlockLoaded(pos) && isInBounds(pos) && ctx.world().getBlockState(pos).getBlock() == Blocks.AIR) { BetterBlockPos actualLandingSpot = checkLandingSpot(pos, checkedPositions); - if (actualLandingSpot != null && isColumnAir(actualLandingSpot, 15)) { + if (actualLandingSpot != null && isColumnAir(actualLandingSpot, 15) && hasAirBubble(actualLandingSpot.up(15))) { return actualLandingSpot.up(15); } if (visited.add(pos.north())) queue.add(pos.north()); diff --git a/src/main/java/baritone/process/elytra/ElytraBehavior.java b/src/main/java/baritone/process/elytra/ElytraBehavior.java index c0cd07c87..9311b296c 100644 --- a/src/main/java/baritone/process/elytra/ElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/ElytraBehavior.java @@ -366,6 +366,10 @@ public final class ElytraBehavior implements Helper { } this.playerNear = index; } + + public boolean isComplete() { + return this.completePath; + } } public void onRenderPass(RenderEvent event) { From 2e2c0ecc0b895c68c92be21ce2bf1b36df494576 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sat, 29 Jul 2023 11:52:37 -0400 Subject: [PATCH 363/405] use MutableBlockPos --- src/main/java/baritone/process/ElytraProcess.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index ff374aad1..ca6988b20 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -427,14 +427,12 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro private boolean hasAirBubble(BlockPos pos) { final int radius = 2; // Half of 5, as we're counting blocks in each direction from the center - + BlockPos.MutableBlockPos mut = new BlockPos.MutableBlockPos(); for (int x = -radius; x <= radius; x++) { for (int y = -radius; y <= radius; y++) { for (int z = -radius; z <= radius; z++) { - BlockPos currentPos = pos.add(x, y, z); - IBlockState blockState = ctx.world().getBlockState(currentPos); - - if (blockState.getBlock() != Blocks.AIR) { + mut.setPos(pos.getX() + x, pos.getY() + y, pos.getZ() + z); + if (!ctx.world().isAirBlock(mut)) { return false; } } From d6adb52718e741e12eb658007dbc8da26835e10b Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 30 Jul 2023 15:46:18 -0700 Subject: [PATCH 364/405] tweaks --- .../java/baritone/process/ElytraProcess.java | 47 ++++++++++++------- .../process/elytra/ElytraBehavior.java | 7 ++- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index ca6988b20..f5329d8d1 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -88,6 +88,8 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro } } + 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; @@ -100,13 +102,14 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro if (calcFailed) { onLostControl(); - logDirect("Failed to get to jump off spot, canceling"); + logDirect(AUTO_JUMP_FAILURE_MSG); return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } if (ctx.player().isElytraFlying() && this.state != State.LANDING && this.behavior.pathManager.isComplete()) { final BetterBlockPos last = this.behavior.pathManager.path.getLast(); if (last != null && ctx.player().getDistanceSqToCenter(last) < (48 * 48) && !goingToLandingSpot) { + logDirect("Path complete, picking a nearby safe landing spot..."); BetterBlockPos landingSpot = findSafeLandingSpot(last); // if this fails we will just keep orbiting the last node until we run out of rockets or the user intervenes if (landingSpot != null) { @@ -131,6 +134,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro // we are goingToLandingSpot and we are in the last node of the path if (this.goingToLandingSpot) { this.state = State.LANDING; + logDirect("Above the landing spot, landing..."); } } } @@ -141,17 +145,30 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro Vec3d from = ctx.player().getPositionVector(); Vec3d to = new Vec3d(((double) endPos.x) + 0.5, from.y, ((double) endPos.z) + 0.5); Rotation rotation = RotationUtils.calcRotationFromVec3d(from, to, ctx.playerRotations()); - baritone.getLookBehavior().updateTarget(rotation, false); - } else { - this.onLostControl(); - return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); + baritone.getLookBehavior().updateTarget(new Rotation(rotation.getYaw(), 0), false); // this will be overwritten, probably, by behavior tick + + if (ctx.player().posY < endPos.y - LANDING_COLUMN_HEIGHT) { + logDirect("bad landing spot, trying again..."); + badLandingSpots.add(endPos); + } } - } else if (ctx.player().isElytraFlying()) { - this.state = State.FLYING; + } + + if (ctx.player().isElytraFlying()) { + behavior.landingMode = this.state == State.LANDING; this.goal = null; baritone.getInputOverrideHandler().clearAllKeys(); behavior.tick(); return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); + } else if (this.state == State.LANDING) { + if (Math.sqrt(ctx.player().motionX * ctx.player().motionX + ctx.player().motionZ * ctx.player().motionZ) > 0.001) { + logDirect("Landed, but still moving, waiting for velocity to die down... " + ctx.player().motionX + " " + ctx.player().motionZ); + baritone.getInputOverrideHandler().setInputForceState(Input.SNEAK, true); + return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); + } + baritone.getInputOverrideHandler().clearAllKeys(); + this.onLostControl(); + return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); } if (this.state == State.FLYING || this.state == State.START_FLYING) { @@ -177,12 +194,6 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro (fall.getSrc().z + fall.getDest().z) / 2 ); behavior.pathManager.pathToDestination(from).whenComplete((result, ex) -> { - if (!behavior.clearView(new Vec3d(from), behavior.pathManager.getPath().getVec(0), false)) { - onLostControl(); - // TODO: Get to higher ground and then look again - logDirect("Can't see start of path from jump spot, canceling"); - return; - } if (ex == null) { this.state = State.GET_TO_JUMP; return; @@ -192,7 +203,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro this.state = State.PAUSE; } else { onLostControl(); - logDirect("Jump off path didn't include a fall movement, canceling"); + logDirect(AUTO_JUMP_FAILURE_MSG); return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } } @@ -397,6 +408,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro private boolean isSafeBlock(Block block) { return block == Blocks.NETHERRACK || block == Blocks.GRAVEL || block == Blocks.NETHER_BRICK; } + private boolean isSafeBlock(BlockPos pos) { return isSafeBlock(ctx.world().getBlockState(pos).getBlock()); } @@ -464,6 +476,9 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro return null; // void } + private static final int LANDING_COLUMN_HEIGHT = 15; + private Set badLandingSpots = new HashSet<>(); + private BetterBlockPos findSafeLandingSpot(BetterBlockPos start) { Queue queue = new PriorityQueue<>(Comparator.comparingInt(pos -> (pos.x - start.x) * (pos.x - start.x) + (pos.z - start.z) * (pos.z - start.z)).thenComparingInt(pos -> -pos.y)); Set visited = new HashSet<>(); @@ -474,8 +489,8 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro BetterBlockPos pos = queue.poll(); if (ctx.world().isBlockLoaded(pos) && isInBounds(pos) && ctx.world().getBlockState(pos).getBlock() == Blocks.AIR) { BetterBlockPos actualLandingSpot = checkLandingSpot(pos, checkedPositions); - if (actualLandingSpot != null && isColumnAir(actualLandingSpot, 15) && hasAirBubble(actualLandingSpot.up(15))) { - return actualLandingSpot.up(15); + if (actualLandingSpot != null && isColumnAir(actualLandingSpot, LANDING_COLUMN_HEIGHT) && hasAirBubble(actualLandingSpot.up(LANDING_COLUMN_HEIGHT)) && !badLandingSpots.contains(actualLandingSpot.up(LANDING_COLUMN_HEIGHT))) { + return actualLandingSpot.up(LANDING_COLUMN_HEIGHT); } if (visited.add(pos.north())) queue.add(pos.north()); if (visited.add(pos.east())) queue.add(pos.east()); diff --git a/src/main/java/baritone/process/elytra/ElytraBehavior.java b/src/main/java/baritone/process/elytra/ElytraBehavior.java index 9311b296c..39af6fc38 100644 --- a/src/main/java/baritone/process/elytra/ElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/ElytraBehavior.java @@ -84,6 +84,8 @@ public final class ElytraBehavior implements Helper { */ private int remainingSetBackTicks; + public boolean landingMode; + /** * The most recent minimum number of firework boost ticks, equivalent to {@code 10 * (1 + Flight)} *

@@ -583,7 +585,7 @@ public final class ElytraBehavior implements Helper { private Solution solveAngles(final SolverContext context) { final NetherPath path = context.path; - final int playerNear = context.playerNear; + final int playerNear = landingMode ? path.size() - 1 : context.playerNear; final Vec3d start = context.start; Solution solution = null; @@ -670,6 +672,9 @@ public final class ElytraBehavior implements Helper { logDebug("waiting for elytraFireworkSetbackUseDelay: " + this.remainingSetBackTicks); return; } + if (this.landingMode) { + return; + } final boolean useOnDescend = !Baritone.settings().elytraConserveFireworks.value || ctx.player().posY < goingTo.y + 5; final double currentSpeed = new Vec3d( ctx.player().motionX, From a83d275622998c710e665f40e823e1543a99bb7b Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 30 Jul 2023 15:47:43 -0700 Subject: [PATCH 365/405] forgot --- src/main/java/baritone/process/ElytraProcess.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index f5329d8d1..6a19707e4 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -150,6 +150,8 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro if (ctx.player().posY < endPos.y - LANDING_COLUMN_HEIGHT) { logDirect("bad landing spot, trying again..."); badLandingSpots.add(endPos); + goingToLandingSpot = false; + this.state = State.FLYING; } } } From 3a6e5541fb79270a4e8421dbd298281444ecc91c Mon Sep 17 00:00:00 2001 From: Brady Date: Sun, 30 Jul 2023 17:48:40 -0500 Subject: [PATCH 366/405] Don't deploy elytra while PathingBehavior is active --- .../launch/mixins/MixinEntityPlayerSP.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java b/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java index 281ff96f5..efc56ca65 100644 --- a/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java +++ b/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java @@ -27,6 +27,8 @@ import baritone.behavior.LookBehavior; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.settings.KeyBinding; import net.minecraft.entity.player.PlayerCapabilities; +import net.minecraft.item.ItemElytra; +import net.minecraft.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -123,4 +125,19 @@ public class MixinEntityPlayerSP { ((LookBehavior) baritone.getLookBehavior()).pig(); } } + + @Redirect( + method = "onLivingUpdate", + at = @At( + value = "INVOKE", + target = "net/minecraft/item/ItemElytra.isUsable(Lnet/minecraft/item/ItemStack;)Z" + ) + ) + private boolean isElytraUsable(ItemStack stack) { + IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this); + if (baritone != null && baritone.getPathingBehavior().isPathing()) { + return false; + } + return ItemElytra.isUsable(stack); + } } From 27e45b816d1fb876d7165379d5559fa01f449644 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sun, 30 Jul 2023 19:45:25 -0400 Subject: [PATCH 367/405] increase air bubble radius, append destination to path when landing --- src/main/java/baritone/process/ElytraProcess.java | 11 ++++++++--- .../baritone/process/elytra/ElytraBehavior.java | 14 ++++++++++++-- .../baritone/process/elytra/UnpackedSegment.java | 4 ++-- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index 6a19707e4..cfcf5373f 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -113,7 +113,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro BetterBlockPos landingSpot = findSafeLandingSpot(last); // if this fails we will just keep orbiting the last node until we run out of rockets or the user intervenes if (landingSpot != null) { - this.pathTo(landingSpot); + this.pathTo0(landingSpot, true); this.landingSpot = landingSpot; this.goingToLandingSpot = true; } @@ -248,6 +248,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro public void onLostControl() { this.goal = null; this.goingToLandingSpot = false; + this.landingSpot = null; this.reachedGoal = false; this.state = State.START_FLYING; // TODO: null state? if (this.behavior != null) { @@ -280,11 +281,15 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro @Override public void pathTo(BlockPos destination) { + this.pathTo0(destination, false); + } + + private void pathTo0(BlockPos destination, boolean appendDestination) { if (ctx.player() == null || ctx.player().dimension != -1) { return; } this.onLostControl(); - this.behavior = new ElytraBehavior(this.baritone, this, destination); + this.behavior = new ElytraBehavior(this.baritone, this, destination, appendDestination); if (ctx.world() != null) { this.behavior.repackChunks(); } @@ -440,7 +445,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro } private boolean hasAirBubble(BlockPos pos) { - final int radius = 2; // Half of 5, as we're counting blocks in each direction from the center + final int radius = 4; // Half of the full width, rounded down, as we're counting blocks in each direction from the center BlockPos.MutableBlockPos mut = new BlockPos.MutableBlockPos(); for (int x = -radius; x <= radius; x++) { for (int y = -radius; y <= radius; y++) { diff --git a/src/main/java/baritone/process/elytra/ElytraBehavior.java b/src/main/java/baritone/process/elytra/ElytraBehavior.java index 39af6fc38..211835dda 100644 --- a/src/main/java/baritone/process/elytra/ElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/ElytraBehavior.java @@ -99,6 +99,7 @@ public final class ElytraBehavior implements Helper { private BlockStateInterface bsi; private final BlockStateOctreeInterface boi; public final BlockPos destination; + private final boolean appendDestination; private final ExecutorService solverExecutor; private Future solver; @@ -111,7 +112,7 @@ public final class ElytraBehavior implements Helper { private int invTickCountdown = 0; private final Queue invTransactionQueue = new LinkedList<>(); - public ElytraBehavior(Baritone baritone, ElytraProcess process, BlockPos destination) { + public ElytraBehavior(Baritone baritone, ElytraProcess process, BlockPos destination, boolean appendDestination) { this.baritone = baritone; this.ctx = baritone.getPlayerContext(); this.clearLines = new CopyOnWriteArrayList<>(); @@ -119,6 +120,7 @@ public final class ElytraBehavior implements Helper { this.pathManager = this.new PathManager(); this.process = process; this.destination = destination; + this.appendDestination = appendDestination; this.solverExecutor = Executors.newSingleThreadExecutor(); this.nextTickBoostCounter = new int[2]; @@ -252,7 +254,15 @@ public final class ElytraBehavior implements Helper { } private void setPath(final UnpackedSegment segment) { - this.path = segment.collect(); + List path = segment.collect(); + if (ElytraBehavior.this.appendDestination) { + BlockPos dest = ElytraBehavior.this.destination; + BlockPos last = !path.isEmpty() ? path.get(path.size() - 1) : null; + if (last != null && ElytraBehavior.this.clearView(new Vec3d(dest), new Vec3d(last), false)) { + path.add(new BetterBlockPos(dest)); + } + } + this.path = new NetherPath(path); this.completePath = segment.isFinished(); this.playerNear = 0; this.ticksNearUnchanged = 0; diff --git a/src/main/java/baritone/process/elytra/UnpackedSegment.java b/src/main/java/baritone/process/elytra/UnpackedSegment.java index 02f07feb8..e50ab3235 100644 --- a/src/main/java/baritone/process/elytra/UnpackedSegment.java +++ b/src/main/java/baritone/process/elytra/UnpackedSegment.java @@ -49,7 +49,7 @@ public final class UnpackedSegment { return new UnpackedSegment(Stream.concat(other, this.path), this.finished); } - public NetherPath collect() { + public List collect() { final List path = this.path.collect(Collectors.toList()); // Remove backtracks @@ -67,7 +67,7 @@ public final class UnpackedSegment { } } - return new NetherPath(path); + return path; } public boolean isFinished() { From 7e9cf2e1e9733cc5258cfe9a55c153dab0fd343f Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 30 Jul 2023 22:47:39 -0700 Subject: [PATCH 368/405] ok its based now --- src/main/java/baritone/process/ElytraProcess.java | 3 ++- .../java/baritone/process/elytra/ElytraBehavior.java | 10 ++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index cfcf5373f..761ab78ea 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -164,10 +164,11 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } else if (this.state == State.LANDING) { if (Math.sqrt(ctx.player().motionX * ctx.player().motionX + ctx.player().motionZ * ctx.player().motionZ) > 0.001) { - logDirect("Landed, but still moving, waiting for velocity to die down... " + ctx.player().motionX + " " + ctx.player().motionZ); + logDirect("Landed, but still moving, waiting for velocity to die down... "); baritone.getInputOverrideHandler().setInputForceState(Input.SNEAK, true); return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); } + logDirect("Done :)"); baritone.getInputOverrideHandler().clearAllKeys(); this.onLostControl(); return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); diff --git a/src/main/java/baritone/process/elytra/ElytraBehavior.java b/src/main/java/baritone/process/elytra/ElytraBehavior.java index 211835dda..503944981 100644 --- a/src/main/java/baritone/process/elytra/ElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/ElytraBehavior.java @@ -634,7 +634,10 @@ public final class ElytraBehavior implements Helper { for (final Pair candidate : candidates) { final Integer augment = candidate.second(); - final Vec3d dest = candidate.first().add(0, augment, 0); + Vec3d dest = candidate.first().add(0, augment, 0); + if (landingMode) { + dest = dest.add(0.5, 0.5, 0.5); + } if (augment != 0) { if (i + lookahead >= path.size()) { @@ -1079,7 +1082,10 @@ public final class ElytraBehavior implements Helper { continue; } final Vec3d last = displacement.get(displacement.size() - 1); - final double goodness = goalDirection.dotProduct(last.normalize()); + double goodness = goalDirection.dotProduct(last.normalize()); + if (landingMode) { + goodness = -goalDelta.subtract(last).length(); + } final PitchResult bestSoFar = bestResults.peek(); if (bestSoFar == null || goodness > bestSoFar.dot) { bestResults.push(new PitchResult(pitch, goodness, displacement)); From 36df7b17f8586083f4d3d541af220480ccb0fb38 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 30 Jul 2023 22:56:33 -0700 Subject: [PATCH 369/405] destroy async --- src/main/java/baritone/process/ElytraProcess.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index 761ab78ea..757e9a294 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -252,8 +252,13 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro this.landingSpot = null; this.reachedGoal = false; this.state = State.START_FLYING; // TODO: null state? - if (this.behavior != null) { - this.behavior.destroy(); + destroyBehaviorAsync(); + } + + private void destroyBehaviorAsync() { + ElytraBehavior behavior = this.behavior; + if (behavior != null) { + Baritone.getExecutor().execute(behavior::destroy); this.behavior = null; } } @@ -353,10 +358,9 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro @Override public void onWorldEvent(WorldEvent event) { - if (event.getWorld() != null && event.getState() == EventState.POST && this.behavior != null) { + if (event.getWorld() != null && event.getState() == EventState.POST) { // Exiting the world, just destroy - this.behavior.destroy(); - this.behavior = null; + destroyBehaviorAsync(); } } From 134bfb2a164d8263b702a354e67b353460670434 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 30 Jul 2023 23:24:04 -0700 Subject: [PATCH 370/405] fix two cases where it could get stuck indefinitely --- src/main/java/baritone/process/ElytraProcess.java | 11 ++++++++--- .../java/baritone/process/elytra/ElytraBehavior.java | 10 +++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index 757e9a294..33acd6d4e 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -149,9 +149,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro if (ctx.player().posY < endPos.y - LANDING_COLUMN_HEIGHT) { logDirect("bad landing spot, trying again..."); - badLandingSpots.add(endPos); - goingToLandingSpot = false; - this.state = State.FLYING; + landingSpotIsBad(endPos); } } } @@ -245,6 +243,13 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } + public void landingSpotIsBad(BetterBlockPos endPos) { + badLandingSpots.add(endPos); + goingToLandingSpot = false; + this.landingSpot = null; + this.state = State.FLYING; + } + @Override public void onLostControl() { this.goal = null; diff --git a/src/main/java/baritone/process/elytra/ElytraBehavior.java b/src/main/java/baritone/process/elytra/ElytraBehavior.java index 503944981..4164bae5e 100644 --- a/src/main/java/baritone/process/elytra/ElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/ElytraBehavior.java @@ -219,8 +219,9 @@ public final class ElytraBehavior implements Helper { this.recalculating = true; final List before = this.path.subList(0, afterIncl + 1); final long start = System.nanoTime(); + final BetterBlockPos pathStart = this.path.get(afterIncl); - this.path0(this.path.get(afterIncl), ElytraBehavior.this.destination, segment -> segment.prepend(before.stream())) + this.path0(pathStart, ElytraBehavior.this.destination, segment -> segment.prepend(before.stream())) .thenRun(() -> { final int recompute = this.path.size() - before.size() - 1; final double distance = this.path.get(0).distanceTo(this.path.get(recompute)); @@ -237,6 +238,10 @@ public final class ElytraBehavior implements Helper { final Throwable cause = ex.getCause(); if (cause instanceof PathCalculationException) { logDirect("Failed to compute next segment"); + if (ctx.player().getDistanceSq(pathStart) < 16 * 16) { + logDirect("Player is near the segment start, therefore repeating this calculation is pointless. Marking as complete"); + completePath = true; + } } else { logUnhandledException(cause); } @@ -260,6 +265,9 @@ public final class ElytraBehavior implements Helper { BlockPos last = !path.isEmpty() ? path.get(path.size() - 1) : null; if (last != null && ElytraBehavior.this.clearView(new Vec3d(dest), new Vec3d(last), false)) { path.add(new BetterBlockPos(dest)); + } else { + logDirect("unable to land at " + ElytraBehavior.this.destination); + process.landingSpotIsBad(new BetterBlockPos(ElytraBehavior.this.destination)); } } this.path = new NetherPath(path); From 9630224e7817bd1571308e7805569a4e56688df0 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 30 Jul 2023 23:26:46 -0700 Subject: [PATCH 371/405] whatever --- src/main/java/baritone/process/ElytraProcess.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index 33acd6d4e..433597d06 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -263,8 +263,8 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro private void destroyBehaviorAsync() { ElytraBehavior behavior = this.behavior; if (behavior != null) { - Baritone.getExecutor().execute(behavior::destroy); this.behavior = null; + Baritone.getExecutor().execute(behavior::destroy); } } From d921d2e36709f262da4120e0a91fa2a14f70cb1e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 30 Jul 2023 23:33:49 -0700 Subject: [PATCH 372/405] live a little --- src/api/java/baritone/api/Settings.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index d664b569c..4baabfbdd 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -1358,7 +1358,7 @@ public final class Settings { /** * The minimum speed that the player can drop to (in blocks/tick) before a firework is automatically deployed. */ - public final Setting elytraFireworkSpeed = new Setting<>(0.6); + public final Setting elytraFireworkSpeed = new Setting<>(1.2); /** * The delay after the player's position is set-back by the server that a firework may be automatically deployed. @@ -1393,7 +1393,7 @@ public final class Settings { /** * Renders the best elytra flight path that was simulated each tick. */ - public final Setting elytraRenderSimulation = new Setting<>(false); + public final Setting elytraRenderSimulation = new Setting<>(true); /** * Automatically path to and jump off of ledges to initiate elytra flight when grounded. From 7662810405a3f73496f6054886674e0009d74a61 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Mon, 31 Jul 2023 00:12:01 -0700 Subject: [PATCH 373/405] add back unsegmenting --- src/main/java/baritone/utils/PathRenderer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index a30ec45b7..c04bdf10f 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -129,12 +129,12 @@ public final class PathRenderer implements IRenderer { int dirY = end.y - start.y; int dirZ = end.z - start.z; - /*while (next + 1 < positions.size() && (!fadeOut || next + 1 < fadeStart) && + while (next + 1 < positions.size() && (!fadeOut || next + 1 < fadeStart) && (dirX == positions.get(next + 1).x - end.x && dirY == positions.get(next + 1).y - end.y && dirZ == positions.get(next + 1).z - end.z)) { end = positions.get(++next); - }*/ + } if (fadeOut) { float alpha; From 83feddf6bedda7b46e400994939f64fdc1501b77 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Mon, 31 Jul 2023 00:12:15 -0700 Subject: [PATCH 374/405] recalc if all points out of view --- src/main/java/baritone/process/elytra/ElytraBehavior.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/baritone/process/elytra/ElytraBehavior.java b/src/main/java/baritone/process/elytra/ElytraBehavior.java index 4164bae5e..cf7db7ac3 100644 --- a/src/main/java/baritone/process/elytra/ElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/ElytraBehavior.java @@ -323,7 +323,11 @@ public final class ElytraBehavior implements Helper { return; } + boolean canSeeAny = false; for (int i = rangeStartIncl; i < rangeEndExcl - 1; i++) { + if (ElytraBehavior.this.clearView(ctx.playerFeetAsVec(), this.path.getVec(i), false)) { + canSeeAny = true; + } if (!ElytraBehavior.this.clearView(this.path.getVec(i), this.path.getVec(i + 1), false)) { // obstacle. where do we return to pathing? // find the next valid segment @@ -344,6 +348,9 @@ public final class ElytraBehavior implements Helper { return; } } + if (!canSeeAny) { + this.pathRecalcSegment(rangeEndExcl - 1).thenRun(() -> logDirect("Recalculated segment since no path points were visible")); + } } private void attemptNextSegment() { From cc8afe95c5d8cf9f1c028ad8013b8df6b42d5c27 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Mon, 31 Jul 2023 00:18:43 -0700 Subject: [PATCH 375/405] setting for nether fortress --- src/api/java/baritone/api/Settings.java | 5 +++++ src/main/java/baritone/process/ElytraProcess.java | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 4baabfbdd..5262549c2 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -1426,6 +1426,11 @@ public final class Settings { */ public final Setting elytraCacheCullDistance = new Setting<>(5000); + /** + * Should elytra consider nether brick a valid landing block + */ + public final Setting elytraAllowLandOnNetherFortress = new Setting<>(false); + /** * A map of lowercase setting field names to their respective setting */ diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index 433597d06..f687e39ca 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -423,7 +423,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro } private boolean isSafeBlock(Block block) { - return block == Blocks.NETHERRACK || block == Blocks.GRAVEL || block == Blocks.NETHER_BRICK; + return block == Blocks.NETHERRACK || block == Blocks.GRAVEL || (block == Blocks.NETHER_BRICK && Baritone.settings().elytraAllowLandOnNetherFortress.value); } private boolean isSafeBlock(BlockPos pos) { From 541b710ea73cc1a9339c05df34d08095730b06ff Mon Sep 17 00:00:00 2001 From: Leijurv Date: Mon, 31 Jul 2023 00:27:50 -0700 Subject: [PATCH 376/405] too aggressive --- src/main/java/baritone/process/elytra/ElytraBehavior.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/process/elytra/ElytraBehavior.java b/src/main/java/baritone/process/elytra/ElytraBehavior.java index cf7db7ac3..65bce93fe 100644 --- a/src/main/java/baritone/process/elytra/ElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/ElytraBehavior.java @@ -348,7 +348,7 @@ public final class ElytraBehavior implements Helper { return; } } - if (!canSeeAny) { + if (!canSeeAny && rangeStartIncl < rangeEndExcl - 2 && process.state != ElytraProcess.State.GET_TO_JUMP) { this.pathRecalcSegment(rangeEndExcl - 1).thenRun(() -> logDirect("Recalculated segment since no path points were visible")); } } From 64a881f99035920f600ec950eb8de743a74532be Mon Sep 17 00:00:00 2001 From: Leijurv Date: Mon, 31 Jul 2023 01:36:01 -0700 Subject: [PATCH 377/405] elytra warning --- src/api/java/baritone/api/Settings.java | 5 +++ .../command/defaults/ElytraCommand.java | 39 ++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 5262549c2..d7086dad4 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -1431,6 +1431,11 @@ public final class Settings { */ public final Setting elytraAllowLandOnNetherFortress = new Setting<>(false); + /** + * Has the user read and understood the elytra terms and conditions + */ + public final Setting elytraTermsAccepted = new Setting<>(false); + /** * A map of lowercase setting field names to their respective setting */ diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index 6ba08dba9..a0d39d850 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -17,6 +17,7 @@ package baritone.command.defaults; +import baritone.Baritone; import baritone.api.IBaritone; import baritone.api.command.Command; import baritone.api.command.argument.IArgConsumer; @@ -26,6 +27,9 @@ import baritone.api.command.helpers.TabCompleteHelper; import baritone.api.pathing.goals.Goal; import baritone.api.process.ICustomGoalProcess; import baritone.api.process.IElytraProcess; +import net.minecraft.util.text.TextComponentString; +import net.minecraft.util.text.TextFormatting; +import net.minecraft.util.text.event.HoverEvent; import java.util.Arrays; import java.util.List; @@ -50,6 +54,11 @@ public class ElytraCommand extends Command { } if (!args.hasAny()) { + if (!Baritone.settings().elytraTermsAccepted.value && !ctx.player().isElytraFlying()) { + // only gatekeep if they are standing on the ground, don't mess them up in midair lol + gatekeep(); + return; + } Goal iGoal = customGoalProcess.mostRecentGoal(); if (iGoal == null) { throw new CommandInvalidStateException("No goal has been set"); @@ -83,6 +92,32 @@ public class ElytraCommand extends Command { } } + private void gatekeep() { + TextComponentString gatekeep = new TextComponentString(""); + gatekeep.appendText("Once you've read the below, and entered the seed, run "); + TextComponentString cmd = new TextComponentString(Baritone.settings().prefix.value + "set elytraTermsAccepted true"); + cmd.getStyle().setColor(TextFormatting.GRAY); + gatekeep.appendSibling(cmd); + gatekeep.appendText(" and then try again.\n"); + gatekeep.appendText("Baritone Elytra is an experimental feature. It is only intended for long distance travel in the Nether using fireworks for vanilla boost. It will not work with any other mods (\"hacks\") for non-vanilla boost. "); + TextComponentString gatekeep2 = new TextComponentString("If you want Baritone to attempt to take off from the ground for you, you can enable the elytraAutoJump setting. This may not be advisable on laggy servers. "); + gatekeep2.getStyle().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString(Baritone.settings().prefix.value + "set elytraAutoJump true"))); + gatekeep.appendSibling(gatekeep2); + TextComponentString gatekeep3 = new TextComponentString("If you want Baritone to go slower and use less fireworks, enable the elytraConserveFireworks setting and/or decrease the elytraFireworkSpeed setting. "); + gatekeep3.getStyle().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString(Baritone.settings().prefix.value + "set elytraConserveFireworks true\n" + Baritone.settings().prefix.value + "set elytraFireworkSpeed 0.6\n(the 0.6 number is just an example, tweak to your liking)"))); + gatekeep.appendSibling(gatekeep3); + TextComponentString gatekeep4 = new TextComponentString("Baritone Elytra "); + TextComponentString red = new TextComponentString("needs to know the seed"); + red.getStyle().setColor(TextFormatting.RED).setUnderlined(true).setBold(true); + gatekeep4.appendSibling(red); + gatekeep4.appendText(" of the world you are in. If it doesn't have the correct seed, it will constantly frustratingly recalculate and backtrack. It uses the seed to generate terrain far beyond what you can see, since terrain obstacles in the Nether can be much larger than your render distance. "); + gatekeep.appendSibling(gatekeep4); + TextComponentString gatekeep5 = new TextComponentString("If you're on 2b2t, no need to change anything, since its seed is the default. Otherwise, set it with: " + Baritone.settings().prefix.value + "set elytraNetherSeed seedgoeshere"); + gatekeep5.getStyle().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString("2b2t's nether seed is 146008555100680, so for example you would run\n" + Baritone.settings().prefix.value + "set elytraNetherSeed 146008555100680\n\nAlso, if you're on 2b2t, note that the Nether near spawn is old terrain gen, so you'll see recalculating and backtracking there.\nIt'll only work well further away from spawn/highways."))); + gatekeep.appendSibling(gatekeep5); + logDirect(gatekeep); + } + @Override public Stream tabComplete(String label, IArgConsumer args) throws CommandException { TabCompleteHelper helper = new TabCompleteHelper(); @@ -114,8 +149,8 @@ public class ElytraCommand extends Command { final String osArch = System.getProperty("os.arch"); final String osName = System.getProperty("os.name"); return String.format( - "Legacy architectures are not supported. your CPU is %s and your operating system is %s. " + - "Supported architectures are 64 bit x86, and 64 bit arm, supported operating systems are Windows, " + + "Legacy architectures are not supported. Your CPU is %s and your operating system is %s. " + + "Supported architectures are 64 bit x86, and 64 bit ARM. Supported operating systems are Windows, " + "Linux, and Mac", osArch, osName ); From 46f38f2ce7bc170899ef7ff2e82a45f6b00626ec Mon Sep 17 00:00:00 2001 From: Leijurv Date: Mon, 31 Jul 2023 15:06:25 -0700 Subject: [PATCH 378/405] orderly shutdown --- src/main/java/baritone/process/elytra/ElytraBehavior.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/baritone/process/elytra/ElytraBehavior.java b/src/main/java/baritone/process/elytra/ElytraBehavior.java index 65bce93fe..64615ed8a 100644 --- a/src/main/java/baritone/process/elytra/ElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/ElytraBehavior.java @@ -467,6 +467,11 @@ public final class ElytraBehavior implements Helper { this.solver.cancel(true); } this.solverExecutor.shutdown(); + try { + while (!this.solverExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) {} + } catch (InterruptedException e) { + e.printStackTrace(); + } this.context.destroy(); } From c0a1e6540ff312668a9d666433bf5917484a594c Mon Sep 17 00:00:00 2001 From: Babbaj Date: Mon, 31 Jul 2023 16:14:09 -0400 Subject: [PATCH 379/405] simplify smoothLook into one setting and separate smoothLook from freeLook --- src/api/java/baritone/api/Settings.java | 10 ++------- .../java/baritone/behavior/LookBehavior.java | 21 ++++++++++--------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index d7086dad4..46a7f62e2 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -745,16 +745,10 @@ public final class Settings { * Forces the client-sided yaw rotation to an average of the last {@link #smoothLookTicks} of server-sided rotations. * Requires {@link #freeLook}. */ - public final Setting smoothLookYaw = new Setting<>(false); + public final Setting smoothLook = new Setting<>(false); /** - * Forces the client-sided pitch rotation to an average of the last {@link #smoothLookTicks} of server-sided rotations. - * Requires {@link #freeLook}. - */ - public final Setting smoothLookPitch = new Setting<>(false); - - /** - * The number of ticks to average across for {@link #smoothLookYaw} and {@link #smoothLookPitch}; + * The number of ticks to average across for {@link #smoothLook}; */ public final Setting smoothLookTicks = new Setting<>(10); diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index 5f6421d08..869b8efb8 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -112,12 +112,15 @@ public final class LookBehavior extends Behavior implements ILookBehavior { this.smoothPitchBuffer.pop(); } - ctx.player().rotationYaw = Baritone.settings().smoothLookYaw.value - ? (float) this.smoothYawBuffer.stream().mapToDouble(d -> d).average().orElseGet(this.prevRotation::getYaw) - : this.prevRotation.getYaw(); - ctx.player().rotationPitch = Baritone.settings().smoothLookPitch.value - ? (float) this.smoothPitchBuffer.stream().mapToDouble(d -> d).average().orElseGet(this.prevRotation::getPitch) - : this.prevRotation.getPitch(); + if (Baritone.settings().freeLook.value) { + ctx.player().rotationYaw = this.prevRotation.getYaw(); + ctx.player().rotationPitch = this.prevRotation.getPitch(); + } else if (Baritone.settings().smoothLook.value) { + ctx.player().rotationYaw = (float) this.smoothYawBuffer.stream().mapToDouble(d -> d).average().orElseGet(this.prevRotation::getYaw); + ctx.player().rotationPitch = ctx.player().isElytraFlying() + ? (float) this.smoothPitchBuffer.stream().mapToDouble(d -> d).average().orElseGet(this.prevRotation::getPitch) + : this.prevRotation.getPitch(); + } this.prevRotation = null; } @@ -327,12 +330,10 @@ public final class LookBehavior extends Behavior implements ILookBehavior { final boolean blockFreeLook = settings.blockFreeLook.value; final boolean freeLook = settings.freeLook.value; - if (!freeLook) return CLIENT; + if (!freeLook && !settings.smoothLook.value) return CLIENT; if (!blockFreeLook && blockInteract) return CLIENT; - if (ctx.player().isElytraFlying()) { - return settings.elytraFreeLook.value ? SERVER : CLIENT; - } + // Regardless of if antiCheatCompatibility is enabled, if a blockInteract is requested then the player // rotation needs to be set somehow, otherwise Baritone will halt since objectMouseOver() will just be From 0ca173f5dcb4c770791b93242bf47ee83560a264 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Mon, 31 Jul 2023 16:41:10 -0400 Subject: [PATCH 380/405] separate smooth look setting for elytra --- src/api/java/baritone/api/Settings.java | 8 ++++++-- src/main/java/baritone/behavior/LookBehavior.java | 8 ++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 46a7f62e2..051cb5686 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -737,16 +737,20 @@ public final class Settings { public final Setting blockFreeLook = new Setting<>(false); /** - * Automatically elytra fly without having to force the client-sided rotations. Requires {@link #freeLook}. + * Automatically elytra fly without having to force the client-sided rotations. */ public final Setting elytraFreeLook = new Setting<>(false); /** * Forces the client-sided yaw rotation to an average of the last {@link #smoothLookTicks} of server-sided rotations. - * Requires {@link #freeLook}. */ public final Setting smoothLook = new Setting<>(false); + /** + * Same as {@link #smoothLook} but for elytra flying. + */ + public final Setting elytraSmoothLook = new Setting<>(true); + /** * The number of ticks to average across for {@link #smoothLook}; */ diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index 869b8efb8..133c00e73 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -112,10 +112,10 @@ public final class LookBehavior extends Behavior implements ILookBehavior { this.smoothPitchBuffer.pop(); } - if (Baritone.settings().freeLook.value) { + if ((ctx.player().isElytraFlying() && Baritone.settings().elytraFreeLook.value) || (!ctx.player().isElytraFlying() && Baritone.settings().freeLook.value)) { ctx.player().rotationYaw = this.prevRotation.getYaw(); ctx.player().rotationPitch = this.prevRotation.getPitch(); - } else if (Baritone.settings().smoothLook.value) { + } else if ((ctx.player().isElytraFlying() && Baritone.settings().elytraSmoothLook.value) || (!ctx.player().isElytraFlying() && Baritone.settings().smoothLook.value)) { ctx.player().rotationYaw = (float) this.smoothYawBuffer.stream().mapToDouble(d -> d).average().orElseGet(this.prevRotation::getYaw); ctx.player().rotationPitch = ctx.player().isElytraFlying() ? (float) this.smoothPitchBuffer.stream().mapToDouble(d -> d).average().orElseGet(this.prevRotation::getPitch) @@ -328,13 +328,9 @@ public final class LookBehavior extends Behavior implements ILookBehavior { final Settings settings = Baritone.settings(); final boolean antiCheat = settings.antiCheatCompatibility.value; final boolean blockFreeLook = settings.blockFreeLook.value; - final boolean freeLook = settings.freeLook.value; - if (!freeLook && !settings.smoothLook.value) return CLIENT; if (!blockFreeLook && blockInteract) return CLIENT; - - // Regardless of if antiCheatCompatibility is enabled, if a blockInteract is requested then the player // rotation needs to be set somehow, otherwise Baritone will halt since objectMouseOver() will just be // whatever the player is mousing over visually. Let's just settle for setting it silently. From 7aa3eda3f6d75c5fdaea7a6c4be71921f2e1c34c Mon Sep 17 00:00:00 2001 From: Babbaj Date: Mon, 31 Jul 2023 17:07:38 -0400 Subject: [PATCH 381/405] fix nudgeToLevel with smoothLook --- src/main/java/baritone/behavior/LookBehavior.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index 133c00e73..9a43f0099 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -117,9 +117,9 @@ public final class LookBehavior extends Behavior implements ILookBehavior { ctx.player().rotationPitch = this.prevRotation.getPitch(); } else if ((ctx.player().isElytraFlying() && Baritone.settings().elytraSmoothLook.value) || (!ctx.player().isElytraFlying() && Baritone.settings().smoothLook.value)) { ctx.player().rotationYaw = (float) this.smoothYawBuffer.stream().mapToDouble(d -> d).average().orElseGet(this.prevRotation::getYaw); - ctx.player().rotationPitch = ctx.player().isElytraFlying() - ? (float) this.smoothPitchBuffer.stream().mapToDouble(d -> d).average().orElseGet(this.prevRotation::getPitch) - : this.prevRotation.getPitch(); + if (ctx.player().isElytraFlying()) { + ctx.player().rotationPitch = (float) this.smoothPitchBuffer.stream().mapToDouble(d -> d).average().orElseGet(this.prevRotation::getPitch); + } } this.prevRotation = null; From 379156951940a04e602dd0409a24bc69847b7768 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Mon, 31 Jul 2023 22:31:45 -0400 Subject: [PATCH 382/405] refactor so that Target.Mode is not a lie fine yes honey --- .../java/baritone/behavior/LookBehavior.java | 43 ++++++++++--------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index 9a43f0099..5c46c6d2f 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -91,10 +91,8 @@ public final class LookBehavior extends Behavior implements ILookBehavior { // Just return for PRE, we still want to set target to null on POST return; } - if (this.target.mode == Target.Mode.SERVER) { - this.prevRotation = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch); - } + this.prevRotation = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch); final Rotation actual = this.processor.peekRotation(this.target.rotation); ctx.player().rotationYaw = actual.getYaw(); ctx.player().rotationPitch = actual.getPitch(); @@ -103,22 +101,21 @@ public final class LookBehavior extends Behavior implements ILookBehavior { case POST: { // Reset the player's rotations back to their original values if (this.prevRotation != null) { - this.smoothYawBuffer.add(this.target.rotation.getYaw()); + this.smoothYawBuffer.addLast(this.target.rotation.getYaw()); while (this.smoothYawBuffer.size() > Baritone.settings().smoothLookTicks.value) { - this.smoothYawBuffer.pop(); + this.smoothYawBuffer.removeFirst(); } - this.smoothPitchBuffer.add(this.target.rotation.getPitch()); + this.smoothPitchBuffer.addLast(this.target.rotation.getPitch()); while (this.smoothPitchBuffer.size() > Baritone.settings().smoothLookTicks.value) { - this.smoothPitchBuffer.pop(); + this.smoothPitchBuffer.removeFirst(); } - - if ((ctx.player().isElytraFlying() && Baritone.settings().elytraFreeLook.value) || (!ctx.player().isElytraFlying() && Baritone.settings().freeLook.value)) { + if (this.target.mode == Target.Mode.SERVER) { ctx.player().rotationYaw = this.prevRotation.getYaw(); ctx.player().rotationPitch = this.prevRotation.getPitch(); - } else if ((ctx.player().isElytraFlying() && Baritone.settings().elytraSmoothLook.value) || (!ctx.player().isElytraFlying() && Baritone.settings().smoothLook.value)) { - ctx.player().rotationYaw = (float) this.smoothYawBuffer.stream().mapToDouble(d -> d).average().orElseGet(this.prevRotation::getYaw); + } else if (ctx.player().isElytraFlying() ? Baritone.settings().elytraSmoothLook.value : Baritone.settings().smoothLook.value) { + ctx.player().rotationYaw = (float) this.smoothYawBuffer.stream().mapToDouble(d -> d).average().orElse(this.prevRotation.getYaw()); if (ctx.player().isElytraFlying()) { - ctx.player().rotationPitch = (float) this.smoothPitchBuffer.stream().mapToDouble(d -> d).average().orElseGet(this.prevRotation::getPitch); + ctx.player().rotationPitch = (float) this.smoothPitchBuffer.stream().mapToDouble(d -> d).average().orElse(this.prevRotation.getPitch()); } } @@ -329,15 +326,21 @@ public final class LookBehavior extends Behavior implements ILookBehavior { final boolean antiCheat = settings.antiCheatCompatibility.value; final boolean blockFreeLook = settings.blockFreeLook.value; - if (!blockFreeLook && blockInteract) return CLIENT; + if (ctx.player().isElytraFlying()) { + // always need to set angles while flying + return settings.elytraFreeLook.value ? SERVER : CLIENT; + } else if (settings.freeLook.value) { + // Regardless of if antiCheatCompatibility is enabled, if a blockInteract is requested then the player + // rotation needs to be set somehow, otherwise Baritone will halt since objectMouseOver() will just be + // whatever the player is mousing over visually. Let's just settle for setting it silently. + if (blockInteract) { + return blockFreeLook ? SERVER : CLIENT; + } + return antiCheat ? SERVER : NONE; + } - // Regardless of if antiCheatCompatibility is enabled, if a blockInteract is requested then the player - // rotation needs to be set somehow, otherwise Baritone will halt since objectMouseOver() will just be - // whatever the player is mousing over visually. Let's just settle for setting it silently. - if (antiCheat || blockInteract) return SERVER; - - // Pathing regularly without antiCheatCompatibility, don't set the player rotation - return NONE; + // all freeLook settings are disabled so set the angles + return CLIENT; } } } From 7813a9caba9712c85b42d7f9da995af1cacba374 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 1 Aug 2023 11:30:30 -0700 Subject: [PATCH 383/405] looks better --- src/api/java/baritone/api/Settings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 051cb5686..aeaa55542 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -754,7 +754,7 @@ public final class Settings { /** * The number of ticks to average across for {@link #smoothLook}; */ - public final Setting smoothLookTicks = new Setting<>(10); + public final Setting smoothLookTicks = new Setting<>(5); /** * When true, the player will remain with its existing look direction as often as possible. From 8c1ccd6c19058b7d3f9de4b8a770665b3f3a6388 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 1 Aug 2023 11:45:53 -0700 Subject: [PATCH 384/405] reduce dumb behavior --- src/main/java/baritone/process/elytra/ElytraBehavior.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/process/elytra/ElytraBehavior.java b/src/main/java/baritone/process/elytra/ElytraBehavior.java index 64615ed8a..9d497932b 100644 --- a/src/main/java/baritone/process/elytra/ElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/ElytraBehavior.java @@ -325,7 +325,7 @@ public final class ElytraBehavior implements Helper { boolean canSeeAny = false; for (int i = rangeStartIncl; i < rangeEndExcl - 1; i++) { - if (ElytraBehavior.this.clearView(ctx.playerFeetAsVec(), this.path.getVec(i), false)) { + if (ElytraBehavior.this.clearView(ctx.playerFeetAsVec(), this.path.getVec(i), false) || ElytraBehavior.this.clearView(ctx.playerHead(), this.path.getVec(i), false)) { canSeeAny = true; } if (!ElytraBehavior.this.clearView(this.path.getVec(i), this.path.getVec(i + 1), false)) { From 70640246b6ca0b83ed1f63de627509bf955e1c81 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 1 Aug 2023 14:11:25 -0700 Subject: [PATCH 385/405] fix infinite memory usage / crash --- src/main/java/baritone/process/ElytraProcess.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index f687e39ca..23ca7647f 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -115,8 +115,8 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro if (landingSpot != null) { this.pathTo0(landingSpot, true); this.landingSpot = landingSpot; - this.goingToLandingSpot = true; } + this.goingToLandingSpot = true; } if (last != null && ctx.player().getDistanceSqToCenter(last) < 1) { @@ -504,7 +504,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro while (!queue.isEmpty()) { BetterBlockPos pos = queue.poll(); - if (ctx.world().isBlockLoaded(pos) && isInBounds(pos) && ctx.world().getBlockState(pos).getBlock() == Blocks.AIR) { + if (ctx.world().isBlockLoaded(pos, false) && isInBounds(pos) && ctx.world().getBlockState(pos).getBlock() == Blocks.AIR) { BetterBlockPos actualLandingSpot = checkLandingSpot(pos, checkedPositions); if (actualLandingSpot != null && isColumnAir(actualLandingSpot, LANDING_COLUMN_HEIGHT) && hasAirBubble(actualLandingSpot.up(LANDING_COLUMN_HEIGHT)) && !badLandingSpots.contains(actualLandingSpot.up(LANDING_COLUMN_HEIGHT))) { return actualLandingSpot.up(LANDING_COLUMN_HEIGHT); From f5bd737ee97d5963e8d4f7f78ade428a2f92f804 Mon Sep 17 00:00:00 2001 From: Dennis <43997085+TheAlan404@users.noreply.github.com> Date: Wed, 2 Aug 2023 21:19:35 +0300 Subject: [PATCH 386/405] add badge count badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c6a90ff93..a5bf404e1 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ Code size GitHub repo size Lines of Code + yes

From 139fd03470116b17b7d07e0a6fc00b640552dcbd Mon Sep 17 00:00:00 2001 From: Brady Hahn Date: Wed, 2 Aug 2023 17:07:03 -0500 Subject: [PATCH 387/405] Update lines of code badge to match style --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a5bf404e1..b99f4a20c 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ GitHub commits Code size GitHub repo size - Lines of Code + Lines of Code yes

From 0edcf650444219033bfbfecdb0f2bc49cbc0817a Mon Sep 17 00:00:00 2001 From: William Gray Date: Mon, 7 Aug 2023 21:33:42 +0000 Subject: [PATCH 388/405] fix badges --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b99f4a20c..de3241e31 100644 --- a/README.md +++ b/README.md @@ -46,8 +46,8 @@

- forthebadge - forthebadge + forthebadge + forthebadge

A Minecraft pathfinder bot. From 15a38c4871caac7329da9e90869133cebccdeaaf Mon Sep 17 00:00:00 2001 From: Babbaj Date: Sun, 13 Aug 2023 21:58:07 -0400 Subject: [PATCH 389/405] add setting that makes unknown chunks air --- build.gradle | 4 ++-- src/api/java/baritone/api/Settings.java | 6 ++++++ .../baritone/process/elytra/NetherPathfinderContext.java | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index accb7ca54..0c8e58364 100755 --- a/build.gradle +++ b/build.gradle @@ -175,8 +175,8 @@ dependencies { transitive = false } launchAnnotationProcessor 'org.spongepowered:mixin:0.8.4-SNAPSHOT:processor' - launchImplementation('dev.babbaj:nether-pathfinder:0.41') - implementation 'dev.babbaj:nether-pathfinder:0.41' + launchImplementation('dev.babbaj:nether-pathfinder:1.2') + implementation 'dev.babbaj:nether-pathfinder:1.2' testImplementation 'junit:junit:4.12' } diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index aeaa55542..076f8f395 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -1404,6 +1404,12 @@ public final class Settings { */ public final Setting elytraNetherSeed = new Setting<>(146008555100680L); + /** + * Whether nether-pathfinder should generate terrain based on {@link #elytraNetherSeed}. + * If false all chunks that haven't been loaded are assumed to be air. + */ + public final Setting elytraPredictTerrain = new Setting<>(true); + /** * Automatically swap the current elytra with a new one when the durability gets too low */ diff --git a/src/main/java/baritone/process/elytra/NetherPathfinderContext.java b/src/main/java/baritone/process/elytra/NetherPathfinderContext.java index 991457d10..93e0587f0 100644 --- a/src/main/java/baritone/process/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/process/elytra/NetherPathfinderContext.java @@ -17,6 +17,7 @@ package baritone.process.elytra; +import baritone.Baritone; import baritone.api.event.events.BlockChangeEvent; import baritone.utils.accessor.IBitArray; import baritone.utils.accessor.IBlockStateContainer; @@ -103,7 +104,9 @@ public final class NetherPathfinderContext { src.getX(), src.getY(), src.getZ(), dst.getX(), dst.getY(), dst.getZ(), true, - 10000 + false, + 10000, + !Baritone.settings().elytraPredictTerrain.value ); if (segment == null) { throw new PathCalculationException("Path calculation failed"); From 4e3a7abac93e7fec43824ff9d1b88b4f4488d27e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 13 Aug 2023 19:29:19 -0700 Subject: [PATCH 390/405] recompute on change --- src/main/java/baritone/process/ElytraProcess.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index 23ca7647f..a93980cbd 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -61,6 +61,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro private boolean reachedGoal; // this basically just prevents potential notification spam private Goal goal; private ElytraBehavior behavior; + private boolean predictingTerrain; private ElytraProcess(Baritone baritone) { super(baritone); @@ -97,6 +98,11 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro logDirect("Nether seed changed, recalculating path"); this.resetState(); } + if (predictingTerrain != Baritone.settings().elytraPredictTerrain.value) { + logDirect("elytraPredictTerrain setting changed, recalculating path"); + predictingTerrain = Baritone.settings().elytraPredictTerrain.value; + this.resetState(); + } this.behavior.onTick(); @@ -300,6 +306,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro return; } this.onLostControl(); + this.predictingTerrain = Baritone.settings().elytraPredictTerrain.value; this.behavior = new ElytraBehavior(this.baritone, this, destination, appendDestination); if (ctx.world() != null) { this.behavior.repackChunks(); From 36534eeb2d95185d1461d7e03f1ecb3d2ddbf24a Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 13 Aug 2023 22:13:33 -0700 Subject: [PATCH 391/405] vastly more helpful --- .../command/defaults/ElytraCommand.java | 112 +++++++++++++++--- 1 file changed, 98 insertions(+), 14 deletions(-) diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index a0d39d850..7064deb5c 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -27,14 +27,22 @@ import baritone.api.command.helpers.TabCompleteHelper; import baritone.api.pathing.goals.Goal; import baritone.api.process.ICustomGoalProcess; import baritone.api.process.IElytraProcess; +import net.minecraft.client.multiplayer.ServerData; +import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextFormatting; +import net.minecraft.util.text.event.ClickEvent; import net.minecraft.util.text.event.HoverEvent; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Arrays; import java.util.List; import java.util.stream.Stream; +import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX; + public class ElytraCommand extends Command { public ElytraCommand(IBaritone baritone) { @@ -54,10 +62,13 @@ public class ElytraCommand extends Command { } if (!args.hasAny()) { - if (!Baritone.settings().elytraTermsAccepted.value && !ctx.player().isElytraFlying()) { + if (Baritone.settings().elytraTermsAccepted.value) { + if (detectOn2b2t()) { + warn2b2t(); + } + } else { // only gatekeep if they are standing on the ground, don't mess them up in midair lol gatekeep(); - return; } Goal iGoal = customGoalProcess.mostRecentGoal(); if (iGoal == null) { @@ -92,32 +103,105 @@ public class ElytraCommand extends Command { } } + private void warn2b2t() { + if (!Baritone.settings().elytraPredictTerrain.value) { + if (ctx.playerFeet().distanceSq(0, 0, 0) > 2000 * 2000) { + TextComponentString clippy = new TextComponentString(""); + clippy.appendText("It looks like you're on 2b2t and more than 2000 blocks from spawn. It is recommended that you "); + TextComponentString predictTerrain = new TextComponentString("enable elytraPredictTerrain"); + predictTerrain.getStyle().setUnderlined(true).setBold(true).setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString(Baritone.settings().prefix.value + "set elytraPredictTerrain true"))).setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, FORCE_COMMAND_PREFIX + "set elytraPredictTerrain true")); + clippy.appendSibling(predictTerrain); + logDirect(clippy); + } + } else { + long seed = Baritone.settings().elytraNetherSeed.value; + if (seed != NEW_2B2T_SEED && seed != OLD_2B2T_SEED) { + logDirect(new TextComponentString("It looks like you're on 2b2t, but elytraNetherSeed is incorrect.")); // match color + logDirect(suggest2b2tSeeds()); + } + } + } + + private ITextComponent suggest2b2tSeeds() { + TextComponentString clippy = new TextComponentString(""); + clippy.appendText("Within a few hundred blocks of spawn/axis/highways/etc, the terrain is too fragmented to be predictable. Baritone Elytra will still work, just with backtracking. "); + clippy.appendText("However, once you get more than a few thousand blocks out, you should try "); + TextComponentString olderSeed = new TextComponentString("the older seed (click here)"); + olderSeed.getStyle().setUnderlined(true).setBold(true).setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString(Baritone.settings().prefix.value + "set elytraNetherSeed " + OLD_2B2T_SEED))).setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, FORCE_COMMAND_PREFIX + "set elytraNetherSeed " + OLD_2B2T_SEED)); + clippy.appendSibling(olderSeed); + clippy.appendText(". Once you're further out into newer terrain generation (this includes everything 1.12 and upwards), you should try "); + TextComponentString newerSeed = new TextComponentString("the newer seed (click here)"); + newerSeed.getStyle().setUnderlined(true).setBold(true).setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString(Baritone.settings().prefix.value + "set elytraNetherSeed " + NEW_2B2T_SEED))).setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, FORCE_COMMAND_PREFIX + "set elytraNetherSeed " + NEW_2B2T_SEED)); + clippy.appendSibling(newerSeed); + clippy.appendText(". "); + return clippy; + } + private void gatekeep() { TextComponentString gatekeep = new TextComponentString(""); - gatekeep.appendText("Once you've read the below, and entered the seed, run "); - TextComponentString cmd = new TextComponentString(Baritone.settings().prefix.value + "set elytraTermsAccepted true"); - cmd.getStyle().setColor(TextFormatting.GRAY); - gatekeep.appendSibling(cmd); - gatekeep.appendText(" and then try again.\n"); + gatekeep.appendText("To disable this message, enable the setting elytraTermsAccepted\n"); gatekeep.appendText("Baritone Elytra is an experimental feature. It is only intended for long distance travel in the Nether using fireworks for vanilla boost. It will not work with any other mods (\"hacks\") for non-vanilla boost. "); - TextComponentString gatekeep2 = new TextComponentString("If you want Baritone to attempt to take off from the ground for you, you can enable the elytraAutoJump setting. This may not be advisable on laggy servers. "); + TextComponentString gatekeep2 = new TextComponentString("If you want Baritone to attempt to take off from the ground for you, you can enable the elytraAutoJump setting (not advisable on laggy servers!). "); gatekeep2.getStyle().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString(Baritone.settings().prefix.value + "set elytraAutoJump true"))); gatekeep.appendSibling(gatekeep2); - TextComponentString gatekeep3 = new TextComponentString("If you want Baritone to go slower and use less fireworks, enable the elytraConserveFireworks setting and/or decrease the elytraFireworkSpeed setting. "); + TextComponentString gatekeep3 = new TextComponentString("If you want Baritone to go slower, enable the elytraConserveFireworks setting and/or decrease the elytraFireworkSpeed setting. "); gatekeep3.getStyle().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString(Baritone.settings().prefix.value + "set elytraConserveFireworks true\n" + Baritone.settings().prefix.value + "set elytraFireworkSpeed 0.6\n(the 0.6 number is just an example, tweak to your liking)"))); gatekeep.appendSibling(gatekeep3); TextComponentString gatekeep4 = new TextComponentString("Baritone Elytra "); - TextComponentString red = new TextComponentString("needs to know the seed"); + TextComponentString red = new TextComponentString("wants to know the seed"); red.getStyle().setColor(TextFormatting.RED).setUnderlined(true).setBold(true); gatekeep4.appendSibling(red); - gatekeep4.appendText(" of the world you are in. If it doesn't have the correct seed, it will constantly frustratingly recalculate and backtrack. It uses the seed to generate terrain far beyond what you can see, since terrain obstacles in the Nether can be much larger than your render distance. "); + gatekeep4.appendText(" of the world you are in. If it doesn't have the correct seed, it will frequently backtrack. It uses the seed to generate terrain far beyond what you can see, since terrain obstacles in the Nether can be much larger than your render distance. "); gatekeep.appendSibling(gatekeep4); - TextComponentString gatekeep5 = new TextComponentString("If you're on 2b2t, no need to change anything, since its seed is the default. Otherwise, set it with: " + Baritone.settings().prefix.value + "set elytraNetherSeed seedgoeshere"); - gatekeep5.getStyle().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString("2b2t's nether seed is 146008555100680, so for example you would run\n" + Baritone.settings().prefix.value + "set elytraNetherSeed 146008555100680\n\nAlso, if you're on 2b2t, note that the Nether near spawn is old terrain gen, so you'll see recalculating and backtracking there.\nIt'll only work well further away from spawn/highways."))); - gatekeep.appendSibling(gatekeep5); + gatekeep.appendText("\n"); + if (detectOn2b2t()) { + TextComponentString gatekeep5 = new TextComponentString("It looks like you're on 2b2t, so elytraPredictTerrain is defaulting to true. "); + gatekeep5.appendSibling(suggest2b2tSeeds()); + if (Baritone.settings().elytraNetherSeed.value == NEW_2B2T_SEED) { + gatekeep5.appendText("You are using the newer seed. "); + } else if (Baritone.settings().elytraNetherSeed.value == OLD_2B2T_SEED) { + gatekeep5.appendText("You are using the older seed. "); + } else { + gatekeep5.appendText("Defaulting to the newer seed. "); + Baritone.settings().elytraNetherSeed.value = NEW_2B2T_SEED; + } + gatekeep.appendSibling(gatekeep5); + } else { + if (Baritone.settings().elytraNetherSeed.value == NEW_2B2T_SEED) { + TextComponentString gatekeep5 = new TextComponentString("Baritone doesn't know the seed of your world. Set it with: " + Baritone.settings().prefix.value + "set elytraNetherSeed seedgoeshere\n"); + gatekeep5.appendText("For the time being, elytraPredictTerrain is defaulting to false since the seed is unknown."); + gatekeep.appendSibling(gatekeep5); + Baritone.settings().elytraPredictTerrain.value = false; + } else { + if (Baritone.settings().elytraPredictTerrain.value) { + TextComponentString gatekeep5 = new TextComponentString("Baritone Elytra is predicting terrain assuming that " + Baritone.settings().elytraNetherSeed.value + " is the correct seed. Change that with " + Baritone.settings().prefix.value + "set elytraNetherSeed seedgoeshere, or disable it with " + Baritone.settings().prefix.value + "set elytraPredictTerrain false"); + gatekeep.appendSibling(gatekeep5); + } else { + TextComponentString gatekeep5 = new TextComponentString("Baritone Elytra is not predicting terrain. If you don't know the seed, this is the correct thing to do. If you do know the seed, input it with " + Baritone.settings().prefix.value + "set elytraNetherSeed seedgoeshere, and then enable it with " + Baritone.settings().prefix.value + "set elytraPredictTerrain true"); + gatekeep.appendSibling(gatekeep5); + } + } + } logDirect(gatekeep); } + private boolean detect2b2tPlayers() { + // if any cached worlds are 2b2t worlds + try (Stream stream = Files.list(((Baritone) baritone).getDirectory())) { + return stream.anyMatch(path -> path.getFileName().toString().toLowerCase().contains("2b2t")); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private boolean detectOn2b2t() { + ServerData data = ctx.minecraft().getCurrentServerData(); + return data != null && data.serverIP.toLowerCase().contains("2b2t"); + } + + private static final long OLD_2B2T_SEED = -4172144997902289642L; + private static final long NEW_2B2T_SEED = 146008555100680L; + @Override public Stream tabComplete(String label, IArgConsumer args) throws CommandException { TabCompleteHelper helper = new TabCompleteHelper(); From d67a3d8bbc0b4bf4aae376e8de6003de02953170 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 13 Aug 2023 22:37:47 -0700 Subject: [PATCH 392/405] much better safety --- src/api/java/baritone/api/Settings.java | 10 +++++ .../java/baritone/process/ElytraProcess.java | 43 +++++++++++++++++-- .../process/elytra/ElytraBehavior.java | 2 +- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 076f8f395..44701b798 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -1420,6 +1420,16 @@ public final class Settings { */ public final Setting elytraMinimumDurability = new Setting<>(5); + /** + * The minimum fireworks before landing early for safety + */ + public final Setting elytraMinFireworksBeforeLanding = new Setting<>(5); + + /** + * Automatically land when elytra is almost out of durability, or almost out of fireworks + */ + public final Setting elytraAllowEmergencyLand = new Setting<>(true); + /** * Time between culling far away chunks from the nether pathfinder chunk cache */ diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index a93980cbd..c6c41881d 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -47,6 +47,9 @@ import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.util.NonNullList; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; @@ -112,11 +115,21 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } - if (ctx.player().isElytraFlying() && this.state != State.LANDING && this.behavior.pathManager.isComplete()) { + boolean safetyLanding = false; + if (ctx.player().isElytraFlying() && shouldLandForSafety()) { + if (Baritone.settings().elytraAllowEmergencyLand.value) { + logDirect("Emergency landing - almost out of elytra durability or fireworks"); + safetyLanding = true; + } else { + logDirect("almost out of elytra durability or fireworks, but I'm going to continue since elytraAllowEmergencyLand is false"); + } + } + if (ctx.player().isElytraFlying() && this.state != State.LANDING && (this.behavior.pathManager.isComplete() || safetyLanding)) { final BetterBlockPos last = this.behavior.pathManager.path.getLast(); - if (last != null && ctx.player().getDistanceSqToCenter(last) < (48 * 48) && !goingToLandingSpot) { + logDirect((last != null) + " " + this.state + " " + safetyLanding + " " + goingToLandingSpot); + if (last != null && (ctx.player().getDistanceSqToCenter(last) < (48 * 48) || safetyLanding) && (!goingToLandingSpot || (safetyLanding && this.landingSpot == null))) { logDirect("Path complete, picking a nearby safe landing spot..."); - BetterBlockPos landingSpot = findSafeLandingSpot(last); + BetterBlockPos landingSpot = findSafeLandingSpot(ctx.playerFeet()); // if this fails we will just keep orbiting the last node until we run out of rockets or the user intervenes if (landingSpot != null) { this.pathTo0(landingSpot, true); @@ -185,6 +198,11 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro } if (this.state == State.LOCATE_JUMP) { + 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); } @@ -338,6 +356,25 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro this.pathTo(new BlockPos(x, y, z)); } + private boolean shouldLandForSafety() { + ItemStack chest = ctx.player().inventory.armorInventory.get(2); + if (chest.getItem() != Items.ELYTRA || chest.getItem().getMaxDamage() - chest.getItemDamage() < Baritone.settings().elytraMinimumDurability.value) { + // elytrabehavior replaces when durability <= minimumDurability, so if durability < minimumDurability then we can reasonably assume that the elytra will soon be broken without replacement + return true; + } + NonNullList inv = ctx.player().inventory.mainInventory; + int qty = 0; + for (int i = 0; i < 36; i++) { + if (ElytraBehavior.isFireworks(inv.get(i))) { + qty += inv.get(i).getCount(); + } + } + if (qty <= Baritone.settings().elytraMinFireworksBeforeLanding.value) { + return true; + } + return false; + } + @Override public boolean isLoaded() { return true; diff --git a/src/main/java/baritone/process/elytra/ElytraBehavior.java b/src/main/java/baritone/process/elytra/ElytraBehavior.java index 9d497932b..709d22334 100644 --- a/src/main/java/baritone/process/elytra/ElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/ElytraBehavior.java @@ -887,7 +887,7 @@ public final class ElytraBehavior implements Helper { } } - private static boolean isFireworks(final ItemStack itemStack) { + public static boolean isFireworks(final ItemStack itemStack) { if (itemStack.getItem() != Items.FIREWORKS) { return false; } From 81e004380fff168e42ed082c4b3ae1510c912971 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 13 Aug 2023 22:42:51 -0700 Subject: [PATCH 393/405] thanks lamp! i love lamp! --- src/main/java/baritone/command/defaults/ElytraCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index 7064deb5c..6db6a877d 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -199,7 +199,7 @@ public class ElytraCommand extends Command { return data != null && data.serverIP.toLowerCase().contains("2b2t"); } - private static final long OLD_2B2T_SEED = -4172144997902289642L; + private static final long OLD_2B2T_SEED = -4100785268875389365L; private static final long NEW_2B2T_SEED = 146008555100680L; @Override From 535eccfc245f0d6a0199c364d0254fdb97f07946 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 13 Aug 2023 22:46:51 -0700 Subject: [PATCH 394/405] no longer applies --- src/main/java/baritone/command/defaults/ElytraCommand.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index 6db6a877d..19f3a030f 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -67,7 +67,6 @@ public class ElytraCommand extends Command { warn2b2t(); } } else { - // only gatekeep if they are standing on the ground, don't mess them up in midair lol gatekeep(); } Goal iGoal = customGoalProcess.mostRecentGoal(); From bd263e1bf88bedff5d84ba41bf00ee82c1b6b3ee Mon Sep 17 00:00:00 2001 From: leijurv Date: Mon, 14 Aug 2023 01:40:15 -0700 Subject: [PATCH 395/405] message for 2b players just in case the update actually happens --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index de3241e31..a98eda73f 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,8 @@ Baritone is the pathfinding system used in [Impact](https://impactclient.net/) s | [1.19.4 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-forge-1.9.3.jar) | [1.19.4 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-fabric-1.9.3.jar) | | [1.20.1 Forge](https://github.com/cabaletta/baritone/releases/download/v1.10.1/baritone-api-forge-1.10.1.jar) | [1.20.1 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.10.1/baritone-api-fabric-1.10.1.jar) | +**Message for 2b2t players looking for 1.19/1.20 Baritone** (download it from right above ^). Please check back in a few days for Baritone Elytra ([vid 1](https://youtu.be/4bGGPo8yiHo) [vid 2](https://www.youtube.com/watch?v=pUN9nmINe3I)], which will be ported to 1.19/1.20 soon! It will work on 2b2t with its anticheat, that was the whole point of Baritone Elytra (it's fully vanilla compatible). Also join [**the discord**](http://discord.gg/s6fRBAUpmr). Thanks! + **How to immediately get started:** Type `#goto 1000 500` in chat to go to x=1000 z=500. Type `#mine diamond_ore` to mine diamond ore. Type `#stop` to stop. For more, read [the usage page](USAGE.md) and/or watch this [tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa) For other versions of Minecraft or more complicated situations or for development, see [Installation & setup](SETUP.md). Also consider just installing [Impact](https://impactclient.net/), which comes with Baritone and is easier to install than wrangling with version JSONs and zips. For 1.16.5, [click here](https://www.youtube.com/watch?v=_4eVJ9Qz2J8) and see description. Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it. There's a [showcase video](https://youtu.be/CZkLXWo4Fg4) made by @Adovin#6313 on Baritone which I recommend. From b0929991b15d011b9af60f29abf3e927db531b68 Mon Sep 17 00:00:00 2001 From: leijurv Date: Mon, 14 Aug 2023 01:40:47 -0700 Subject: [PATCH 396/405] typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a98eda73f..674825c2b 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ Baritone is the pathfinding system used in [Impact](https://impactclient.net/) s | [1.19.4 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-forge-1.9.3.jar) | [1.19.4 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-fabric-1.9.3.jar) | | [1.20.1 Forge](https://github.com/cabaletta/baritone/releases/download/v1.10.1/baritone-api-forge-1.10.1.jar) | [1.20.1 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.10.1/baritone-api-fabric-1.10.1.jar) | -**Message for 2b2t players looking for 1.19/1.20 Baritone** (download it from right above ^). Please check back in a few days for Baritone Elytra ([vid 1](https://youtu.be/4bGGPo8yiHo) [vid 2](https://www.youtube.com/watch?v=pUN9nmINe3I)], which will be ported to 1.19/1.20 soon! It will work on 2b2t with its anticheat, that was the whole point of Baritone Elytra (it's fully vanilla compatible). Also join [**the discord**](http://discord.gg/s6fRBAUpmr). Thanks! +**Message for 2b2t players looking for 1.19/1.20 Baritone** Download it from right above ^. But also please check back in a few days for Baritone Elytra ([vid 1](https://youtu.be/4bGGPo8yiHo) [vid 2](https://www.youtube.com/watch?v=pUN9nmINe3I)), which will be ported to 1.19/1.20 soon! It will work on 2b2t with its anticheat, that was the whole point of Baritone Elytra (it's fully vanilla compatible). Also join [**the discord**](http://discord.gg/s6fRBAUpmr). Thanks! **How to immediately get started:** Type `#goto 1000 500` in chat to go to x=1000 z=500. Type `#mine diamond_ore` to mine diamond ore. Type `#stop` to stop. For more, read [the usage page](USAGE.md) and/or watch this [tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa) From f35e55ef66531d68aaa3680b9551da032c40db0c Mon Sep 17 00:00:00 2001 From: Leijurv Date: Mon, 14 Aug 2023 12:34:24 -0700 Subject: [PATCH 397/405] unused --- .../java/baritone/command/defaults/ElytraCommand.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index 19f3a030f..ddbe6fa19 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -184,15 +184,6 @@ public class ElytraCommand extends Command { logDirect(gatekeep); } - private boolean detect2b2tPlayers() { - // if any cached worlds are 2b2t worlds - try (Stream stream = Files.list(((Baritone) baritone).getDirectory())) { - return stream.anyMatch(path -> path.getFileName().toString().toLowerCase().contains("2b2t")); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - private boolean detectOn2b2t() { ServerData data = ctx.minecraft().getCurrentServerData(); return data != null && data.serverIP.toLowerCase().contains("2b2t"); From 7b911aa0a71e1bc53c9458e8b41de3db7a005beb Mon Sep 17 00:00:00 2001 From: Leijurv Date: Mon, 14 Aug 2023 20:51:39 -0700 Subject: [PATCH 398/405] clean up elytra given 2b2t status --- .../command/defaults/ElytraCommand.java | 39 ++++++++----------- .../java/baritone/process/ElytraProcess.java | 1 - 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index ddbe6fa19..5895c36ad 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -34,9 +34,6 @@ import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.event.ClickEvent; import net.minecraft.util.text.event.HoverEvent; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.Arrays; import java.util.List; import java.util.stream.Stream; @@ -103,16 +100,7 @@ public class ElytraCommand extends Command { } private void warn2b2t() { - if (!Baritone.settings().elytraPredictTerrain.value) { - if (ctx.playerFeet().distanceSq(0, 0, 0) > 2000 * 2000) { - TextComponentString clippy = new TextComponentString(""); - clippy.appendText("It looks like you're on 2b2t and more than 2000 blocks from spawn. It is recommended that you "); - TextComponentString predictTerrain = new TextComponentString("enable elytraPredictTerrain"); - predictTerrain.getStyle().setUnderlined(true).setBold(true).setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString(Baritone.settings().prefix.value + "set elytraPredictTerrain true"))).setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, FORCE_COMMAND_PREFIX + "set elytraPredictTerrain true")); - clippy.appendSibling(predictTerrain); - logDirect(clippy); - } - } else { + if (Baritone.settings().elytraPredictTerrain.value) { long seed = Baritone.settings().elytraNetherSeed.value; if (seed != NEW_2B2T_SEED && seed != OLD_2B2T_SEED) { logDirect(new TextComponentString("It looks like you're on 2b2t, but elytraNetherSeed is incorrect.")); // match color @@ -128,11 +116,11 @@ public class ElytraCommand extends Command { TextComponentString olderSeed = new TextComponentString("the older seed (click here)"); olderSeed.getStyle().setUnderlined(true).setBold(true).setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString(Baritone.settings().prefix.value + "set elytraNetherSeed " + OLD_2B2T_SEED))).setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, FORCE_COMMAND_PREFIX + "set elytraNetherSeed " + OLD_2B2T_SEED)); clippy.appendSibling(olderSeed); - clippy.appendText(". Once you're further out into newer terrain generation (this includes everything 1.12 and upwards), you should try "); + clippy.appendText(". Once you're further out into newer terrain generation (this includes everything up through 1.12), you should try "); TextComponentString newerSeed = new TextComponentString("the newer seed (click here)"); newerSeed.getStyle().setUnderlined(true).setBold(true).setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString(Baritone.settings().prefix.value + "set elytraNetherSeed " + NEW_2B2T_SEED))).setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, FORCE_COMMAND_PREFIX + "set elytraNetherSeed " + NEW_2B2T_SEED)); clippy.appendSibling(newerSeed); - clippy.appendText(". "); + clippy.appendText(". Once you get into 1.19 terrain, the terrain becomes unpredictable again, due to custom non-vanilla generation, and you should set #elytraPredictTerrain to false. "); return clippy; } @@ -154,15 +142,19 @@ public class ElytraCommand extends Command { gatekeep.appendSibling(gatekeep4); gatekeep.appendText("\n"); if (detectOn2b2t()) { - TextComponentString gatekeep5 = new TextComponentString("It looks like you're on 2b2t, so elytraPredictTerrain is defaulting to true. "); + TextComponentString gatekeep5 = new TextComponentString("It looks like you're on 2b2t. "); gatekeep5.appendSibling(suggest2b2tSeeds()); - if (Baritone.settings().elytraNetherSeed.value == NEW_2B2T_SEED) { - gatekeep5.appendText("You are using the newer seed. "); - } else if (Baritone.settings().elytraNetherSeed.value == OLD_2B2T_SEED) { - gatekeep5.appendText("You are using the older seed. "); + if (!Baritone.settings().elytraPredictTerrain.value) { + gatekeep5.appendText(Baritone.settings().prefix.value + "elytraPredictTerrain is currently disabled. "); } else { - gatekeep5.appendText("Defaulting to the newer seed. "); - Baritone.settings().elytraNetherSeed.value = NEW_2B2T_SEED; + if (Baritone.settings().elytraNetherSeed.value == NEW_2B2T_SEED) { + gatekeep5.appendText("You are using the newer seed. "); + } else if (Baritone.settings().elytraNetherSeed.value == OLD_2B2T_SEED) { + gatekeep5.appendText("You are using the older seed. "); + } else { + gatekeep5.appendText("Defaulting to the newer seed. "); + Baritone.settings().elytraNetherSeed.value = NEW_2B2T_SEED; + } } gatekeep.appendSibling(gatekeep5); } else { @@ -185,8 +177,9 @@ public class ElytraCommand extends Command { } private boolean detectOn2b2t() { + if (true) return true; ServerData data = ctx.minecraft().getCurrentServerData(); - return data != null && data.serverIP.toLowerCase().contains("2b2t"); + return data != null && data.serverIP.toLowerCase().contains("2b2t.org"); } private static final long OLD_2B2T_SEED = -4100785268875389365L; diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index c6c41881d..bf0dd9802 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -126,7 +126,6 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro } if (ctx.player().isElytraFlying() && this.state != State.LANDING && (this.behavior.pathManager.isComplete() || safetyLanding)) { final BetterBlockPos last = this.behavior.pathManager.path.getLast(); - logDirect((last != null) + " " + this.state + " " + safetyLanding + " " + goingToLandingSpot); if (last != null && (ctx.player().getDistanceSqToCenter(last) < (48 * 48) || safetyLanding) && (!goingToLandingSpot || (safetyLanding && this.landingSpot == null))) { logDirect("Path complete, picking a nearby safe landing spot..."); BetterBlockPos landingSpot = findSafeLandingSpot(ctx.playerFeet()); From 050e3a570dff219bbbb168cccae468f81c8fa260 Mon Sep 17 00:00:00 2001 From: leijurv Date: Mon, 14 Aug 2023 21:56:41 -0700 Subject: [PATCH 399/405] bedrock is much lower now, although worth considering if deepslate needs similar special treatment --- src/main/java/baritone/cache/CachedChunk.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/cache/CachedChunk.java b/src/main/java/baritone/cache/CachedChunk.java index 3109d9293..2659c4feb 100644 --- a/src/main/java/baritone/cache/CachedChunk.java +++ b/src/main/java/baritone/cache/CachedChunk.java @@ -218,7 +218,7 @@ public final class CachedChunk { // nether roof is always unbreakable return Blocks.BEDROCK.defaultBlockState(); } - if (y < 5 && dimension.natural()) { + if (y < -59 && dimension.natural()) { // solid blocks below 5 are commonly bedrock // however, returning bedrock always would be a little yikes // discourage paths that include breaking blocks below 5 a little more heavily just so that it takes paths breaking what's known to be stone (at 5 or above) instead of what could maybe be bedrock (below 5) From b1be4f29adf8fbdc785e04e4221fc46ceb471e27 Mon Sep 17 00:00:00 2001 From: Babbaj Date: Tue, 15 Aug 2023 01:14:53 -0400 Subject: [PATCH 400/405] make raytracer collide with unknown chunks --- build.gradle | 4 ++-- .../process/elytra/NetherPathfinderContext.java | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build.gradle b/build.gradle index 0c8e58364..b9e486351 100755 --- a/build.gradle +++ b/build.gradle @@ -175,8 +175,8 @@ dependencies { transitive = false } launchAnnotationProcessor 'org.spongepowered:mixin:0.8.4-SNAPSHOT:processor' - launchImplementation('dev.babbaj:nether-pathfinder:1.2') - implementation 'dev.babbaj:nether-pathfinder:1.2' + launchImplementation('dev.babbaj:nether-pathfinder:1.3.0') + implementation 'dev.babbaj:nether-pathfinder:1.3.0' testImplementation 'junit:junit:4.12' } diff --git a/src/main/java/baritone/process/elytra/NetherPathfinderContext.java b/src/main/java/baritone/process/elytra/NetherPathfinderContext.java index 93e0587f0..55a780a79 100644 --- a/src/main/java/baritone/process/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/process/elytra/NetherPathfinderContext.java @@ -129,7 +129,7 @@ public final class NetherPathfinderContext { */ public boolean raytrace(final double startX, final double startY, final double startZ, final double endX, final double endY, final double endZ) { - return NetherPathfinder.isVisible(this.context, true, startX, startY, startZ, endX, endY, endZ); + return NetherPathfinder.isVisible(this.context, NetherPathfinder.CACHE_MISS_SOLID, startX, startY, startZ, endX, endY, endZ); } /** @@ -141,24 +141,24 @@ public final class NetherPathfinderContext { * @return {@code true} if there is visibility between the points */ public boolean raytrace(final Vec3d start, final Vec3d end) { - return NetherPathfinder.isVisible(this.context, true, start.x, start.y, start.z, end.x, end.y, end.z); + return NetherPathfinder.isVisible(this.context, NetherPathfinder.CACHE_MISS_SOLID, start.x, start.y, start.z, end.x, end.y, end.z); } public boolean raytrace(final int count, final double[] src, final double[] dst, final int visibility) { switch (visibility) { case Visibility.ALL: - return NetherPathfinder.isVisibleMulti(this.context, true, count, src, dst, false) == -1; + return NetherPathfinder.isVisibleMulti(this.context, NetherPathfinder.CACHE_MISS_SOLID, count, src, dst, false) == -1; case Visibility.NONE: - return NetherPathfinder.isVisibleMulti(this.context, true, count, src, dst, true) == -1; + return NetherPathfinder.isVisibleMulti(this.context, NetherPathfinder.CACHE_MISS_SOLID, count, src, dst, true) == -1; case Visibility.ANY: - return NetherPathfinder.isVisibleMulti(this.context, true, count, src, dst, true) != -1; + return NetherPathfinder.isVisibleMulti(this.context, NetherPathfinder.CACHE_MISS_SOLID, count, src, dst, true) != -1; default: throw new IllegalArgumentException("lol"); } } public void raytrace(final int count, final double[] src, final double[] dst, final boolean[] hitsOut, final double[] hitPosOut) { - NetherPathfinder.raytrace(this.context, true, count, src, dst, hitsOut, hitPosOut); + NetherPathfinder.raytrace(this.context, NetherPathfinder.CACHE_MISS_SOLID, count, src, dst, hitsOut, hitPosOut); } public void cancel() { From 661b16af7e651c4c5b98f73016faee7f201c57a4 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Mon, 14 Aug 2023 22:20:42 -0700 Subject: [PATCH 401/405] v1.2.18 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index b9e486351..b91dcf43c 100755 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ */ group 'baritone' -version '1.2.17' +version '1.2.18' buildscript { repositories { From ca4385da7a8cd002cc841a82606c8dd02fb7779b Mon Sep 17 00:00:00 2001 From: Leijurv Date: Mon, 14 Aug 2023 22:34:38 -0700 Subject: [PATCH 402/405] update readme --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 674825c2b..bc3552c5a 100644 --- a/README.md +++ b/README.md @@ -60,10 +60,10 @@ Baritone is the pathfinding system used in [Impact](https://impactclient.net/) s | Forge | Fabric | |---------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------| -| [1.12.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.2.17/baritone-api-forge-1.2.17.jar) | | -| [1.16.5 Forge](https://github.com/cabaletta/baritone/releases/download/v1.6.4/baritone-api-forge-1.6.4.jar) | [1.16.5 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.6.4/baritone-api-fabric-1.6.4.jar) | +| [1.12.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.2.18/baritone-api-forge-1.2.18.jar) | | +| [1.16.5 Forge](https://github.com/cabaletta/baritone/releases/download/v1.6.5/baritone-api-forge-1.6.5.jar) | [1.16.5 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.6.5/baritone-api-fabric-1.6.5.jar) | | [1.17.1 Forge](https://github.com/cabaletta/baritone/releases/download/v1.7.3/baritone-api-forge-1.7.3.jar) | [1.17.1 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.7.3/baritone-api-fabric-1.7.3.jar) | -| [1.18.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.8.4/baritone-api-forge-1.8.4.jar) | [1.18.2 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.8.4/baritone-api-fabric-1.8.4.jar) | +| [1.18.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.8.5/baritone-api-forge-1.8.5.jar) | [1.18.2 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.8.5/baritone-api-fabric-1.8.5.jar) | | [1.19.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.4/baritone-api-forge-1.9.4.jar) | [1.19.2 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.4/baritone-api-fabric-1.9.4.jar) | | [1.19.3 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-forge-1.9.1.jar) | [1.19.3 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-fabric-1.9.1.jar) | | [1.19.4 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-forge-1.9.3.jar) | [1.19.4 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-fabric-1.9.3.jar) | @@ -71,7 +71,7 @@ Baritone is the pathfinding system used in [Impact](https://impactclient.net/) s **Message for 2b2t players looking for 1.19/1.20 Baritone** Download it from right above ^. But also please check back in a few days for Baritone Elytra ([vid 1](https://youtu.be/4bGGPo8yiHo) [vid 2](https://www.youtube.com/watch?v=pUN9nmINe3I)), which will be ported to 1.19/1.20 soon! It will work on 2b2t with its anticheat, that was the whole point of Baritone Elytra (it's fully vanilla compatible). Also join [**the discord**](http://discord.gg/s6fRBAUpmr). Thanks! -**How to immediately get started:** Type `#goto 1000 500` in chat to go to x=1000 z=500. Type `#mine diamond_ore` to mine diamond ore. Type `#stop` to stop. For more, read [the usage page](USAGE.md) and/or watch this [tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa) +**How to immediately get started:** Type `#goto 1000 500` in chat to go to x=1000 z=500. Type `#mine diamond_ore` to mine diamond ore. Type `#stop` to stop. For more, read [the usage page](USAGE.md) and/or watch this [tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa). Also try `#elytra` for Elytra flying in the Nether using fireworks. For other versions of Minecraft or more complicated situations or for development, see [Installation & setup](SETUP.md). Also consider just installing [Impact](https://impactclient.net/), which comes with Baritone and is easier to install than wrangling with version JSONs and zips. For 1.16.5, [click here](https://www.youtube.com/watch?v=_4eVJ9Qz2J8) and see description. Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it. There's a [showcase video](https://youtu.be/CZkLXWo4Fg4) made by @Adovin#6313 on Baritone which I recommend. From bfc813a8022acf1ba70ec7826231bc68e6fb0e6e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 17 Aug 2023 20:03:44 -0700 Subject: [PATCH 403/405] mostly works --- fabric/build.gradle | 3 +++ .../java/baritone/behavior/LookBehavior.java | 15 ++++++++---- .../java/baritone/process/ElytraProcess.java | 5 +++- .../process/elytra/ElytraBehavior.java | 9 +++---- .../elytra/NetherPathfinderContext.java | 24 +++++++------------ src/main/java/baritone/utils/IRenderer.java | 10 +++----- 6 files changed, 33 insertions(+), 33 deletions(-) diff --git a/fabric/build.gradle b/fabric/build.gradle index 8adf7571b..c88ff80ef 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -26,6 +26,9 @@ archivesBaseName = archivesBaseName + "-fabric" minecraft { fabric() + runs.client = { + jvmArgs.add("-XstartOnFirstThread") + } } configurations { diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index 2ff732675..e694a8ee0 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -82,9 +82,12 @@ public final class LookBehavior extends Behavior implements ILookBehavior { @Override public void onPlayerUpdate(PlayerUpdateEvent event) { + System.out.println(event.getState() + " " + ctx.player().getXRot() + " " + ctx.player().getYRot() + " " + ctx.player().xRotO + " " + ctx.player().yRotO); + if (this.target == null) { return; } + switch (event.getState()) { case PRE: { if (this.target.mode == Target.Mode.NONE) { @@ -92,7 +95,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior { return; } - this.prevRotation = new Rotation(ctx.player().getXRot(), ctx.player().getYRot()); + this.prevRotation = new Rotation(ctx.player().getYRot(), ctx.player().getXRot()); final Rotation actual = this.processor.peekRotation(this.target.rotation); ctx.player().setYRot(actual.getYaw()); ctx.player().setXRot(actual.getPitch()); @@ -110,14 +113,16 @@ public final class LookBehavior extends Behavior implements ILookBehavior { this.smoothPitchBuffer.removeFirst(); } if (this.target.mode == Target.Mode.SERVER) { - ctx.player().setXRot(this.prevRotation.getYaw()); - ctx.player().setYRot(this.prevRotation.getPitch()); + ctx.player().setYRot(this.prevRotation.getYaw()); + ctx.player().setXRot(this.prevRotation.getPitch()); } else if (ctx.player().isFallFlying() ? Baritone.settings().elytraSmoothLook.value : Baritone.settings().smoothLook.value) { - ctx.player().setXRot((float) this.smoothYawBuffer.stream().mapToDouble(d -> d).average().orElse(this.prevRotation.getYaw())); + ctx.player().setYRot((float) this.smoothYawBuffer.stream().mapToDouble(d -> d).average().orElse(this.prevRotation.getYaw())); if (ctx.player().isFallFlying()) { - ctx.player().setYRot((float) this.smoothPitchBuffer.stream().mapToDouble(d -> d).average().orElse(this.prevRotation.getPitch())); + ctx.player().setXRot((float) this.smoothPitchBuffer.stream().mapToDouble(d -> d).average().orElse(this.prevRotation.getPitch())); } } + //ctx.player().xRotO = prevRotation.getPitch(); + //ctx.player().yRotO = prevRotation.getYaw(); this.prevRotation = null; } // The target is done being used for this game tick, so it can be invalidated diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index 7ede8543f..e0b6a1a03 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -364,7 +364,8 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro // elytrabehavior replaces when durability <= minimumDurability, so if durability < minimumDurability then we can reasonably assume that the elytra will soon be broken without replacement return true; } - NonNullList inv = ctx.player().inventoryMenu.getItems(); + + NonNullList inv = ctx.player().getInventory().items; int qty = 0; for (int i = 0; i < 36; i++) { if (ElytraBehavior.isFireworks(inv.get(i))) { @@ -404,6 +405,8 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro @Override public void onRenderPass(RenderEvent event) { + System.out.println(event.getPartialTicks() + " " + ctx.player().getXRot() + " " + ctx.player().getYRot() + " " + ctx.player().xRotO + " " + ctx.player().yRotO); + if (this.behavior != null) this.behavior.onRenderPass(event); } diff --git a/src/main/java/baritone/process/elytra/ElytraBehavior.java b/src/main/java/baritone/process/elytra/ElytraBehavior.java index 82225456e..2ba8744fb 100644 --- a/src/main/java/baritone/process/elytra/ElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/ElytraBehavior.java @@ -402,6 +402,7 @@ public final class ElytraBehavior implements Helper { } public void onRenderPass(RenderEvent event) { + final Settings settings = Baritone.settings(); if (this.visiblePath != null) { PathRenderer.drawPath(event.getModelViewStack(), this.visiblePath, 0, Color.RED, false, 0, 0, 0.0D); @@ -412,14 +413,14 @@ public final class ElytraBehavior implements Helper { if (!this.clearLines.isEmpty() && settings.elytraRenderRaytraces.value) { IRenderer.startLines(Color.GREEN, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); for (Pair line : this.clearLines) { - IRenderer.emitLine(line.first(), line.second()); + IRenderer.emitLine(event.getModelViewStack(), line.first(), line.second()); } IRenderer.endLines(settings.renderPathIgnoreDepth.value); } if (!this.blockedLines.isEmpty() && Baritone.settings().elytraRenderRaytraces.value) { IRenderer.startLines(Color.BLUE, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); for (Pair line : this.blockedLines) { - IRenderer.emitLine(line.first(), line.second()); + IRenderer.emitLine(event.getModelViewStack(), line.first(), line.second()); } IRenderer.endLines(settings.renderPathIgnoreDepth.value); } @@ -429,7 +430,7 @@ public final class ElytraBehavior implements Helper { for (int i = 0; i < this.simulationLine.size() - 1; i++) { final Vec3 src = this.simulationLine.get(i).add(offset); final Vec3 dst = this.simulationLine.get(i + 1).add(offset); - IRenderer.emitLine(src, dst); + IRenderer.emitLine(event.getModelViewStack(), src, dst); } IRenderer.endLines(settings.renderPathIgnoreDepth.value); } @@ -1272,7 +1273,7 @@ public final class ElytraBehavior implements Helper { } private int findGoodElytra() { - NonNullList invy = ctx.player().inventoryMenu.getItems(); + NonNullList invy = ctx.player().getInventory().items; for (int i = 0; i < invy.size(); i++) { ItemStack slot = invy.get(i); if (slot.getItem() == Items.ELYTRA && (slot.getItem().getMaxDamage() - slot.getDamageValue()) > Baritone.settings().elytraMinimumDurability.value) { diff --git a/src/main/java/baritone/process/elytra/NetherPathfinderContext.java b/src/main/java/baritone/process/elytra/NetherPathfinderContext.java index 47ecdca96..de666a0a8 100644 --- a/src/main/java/baritone/process/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/process/elytra/NetherPathfinderContext.java @@ -201,23 +201,15 @@ public final class NetherPathfinderContext { long maxEntryValue = (1L << bitsPerEntry) - 1L; final int yReal = y0 << 4; - for (int idx = 0, kl = bitsPerEntry - 1; idx < arraySize; idx++, kl += bitsPerEntry) { - final int i = idx * bitsPerEntry; - final int j = i >> 6; - final int l = i & 63; - final int k = kl >> 6; - final long jl = longArray[j] >>> l; - - final int id; - if (j == k) { - id = (int) (jl & maxEntryValue); - } else { - id = (int) ((jl | longArray[k] << (64 - l)) & maxEntryValue); + for (int i = 0, idx = 0; i < longArray.length && idx < arraySize; ++i) { + long l = longArray[i]; + for (int offset = 0; offset <= (64 - bitsPerEntry) && idx < arraySize; offset += bitsPerEntry, ++idx) { + int value = (int) ((l >> offset) & maxEntryValue); + int x = (idx & 15); + int y = yReal + (idx >> 8); + int z = ((idx >> 4) & 15); + Octree.setBlock(ptr, x, y, z, value != airId); } - int x = (idx & 15); - int y = yReal + (idx >> 8); - int z = ((idx >> 4) & 15); - Octree.setBlock(ptr, x, y, z, id != airId); } } Octree.setIsFromJava(ptr); diff --git a/src/main/java/baritone/utils/IRenderer.java b/src/main/java/baritone/utils/IRenderer.java index 0721019c6..7f6065b72 100644 --- a/src/main/java/baritone/utils/IRenderer.java +++ b/src/main/java/baritone/utils/IRenderer.java @@ -146,15 +146,11 @@ public interface IRenderer { emitAABB(stack, aabb.inflate(expand, expand, expand)); } - static void emitLine(Vec3 start, Vec3 end) { - emitLine(start.x, start.y, start.z, end.x, end.y, end.z); - } - - static void emitLine(double x1, double y1, double z1, double x2, double y2, double z2) { + static void emitLine(PoseStack stack, Vec3 start, Vec3 end) { double vpX = renderManager.renderPosX(); double vpY = renderManager.renderPosY(); double vpZ = renderManager.renderPosZ(); - buffer.vertex(x1 - vpX, y1 - vpY, z1 - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.vertex(x2 - vpX, y2 - vpY, z2 - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + emitLine(stack, start.x - vpX, start.y - vpY, start.z - vpZ, end.x - vpX, end.y - vpY, end.z - vpZ); } + } From fc474cfb49a4f4990770a38862ba1415e94b8db3 Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 18 Aug 2023 14:14:34 -0500 Subject: [PATCH 404/405] bradyfix --- .../mixins/MixinClientPlayNetHandler.java | 24 +-------------- .../mixins/MixinClientPlayerEntity.java | 2 +- .../launch/mixins/MixinLivingEntity.java | 29 +------------------ .../launch/mixins/MixinMinecraft.java | 16 ++-------- 4 files changed, 6 insertions(+), 65 deletions(-) diff --git a/src/launch/java/baritone/launch/mixins/MixinClientPlayNetHandler.java b/src/launch/java/baritone/launch/mixins/MixinClientPlayNetHandler.java index 460250617..6b4564aa9 100644 --- a/src/launch/java/baritone/launch/mixins/MixinClientPlayNetHandler.java +++ b/src/launch/java/baritone/launch/mixins/MixinClientPlayNetHandler.java @@ -183,7 +183,7 @@ public class MixinClientPlayNetHandler { List> changes = new ArrayList<>(); packetIn.runUpdates((mutPos, state) -> { - changes.add(new Pair<>(mutPos.immutable(), state)); // bradyfix is this right + changes.add(new Pair<>(mutPos.immutable(), state)); }); if (changes.isEmpty()) { return; @@ -192,28 +192,6 @@ public class MixinClientPlayNetHandler { new ChunkPos(changes.get(0).first()), changes )); - ChunkPos[] chunkPos = new ChunkPos[1]; - packetIn.runUpdates((pos, state) -> { - if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(state.getBlock())) { - chunkPos[0] = new ChunkPos(pos); - } - }); - if (chunkPos[0] == null) { - return; - } - for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) { - LocalPlayer player = ibaritone.getPlayerContext().player(); - if (player != null && player.connection == (ClientPacketListener) (Object) this) { - ibaritone.getGameEventHandler().onChunkEvent( - new ChunkEvent( - EventState.POST, - ChunkEvent.Type.POPULATE_FULL, - chunkPos[0].x, - chunkPos[0].z - ) - ); - } - } } @Inject( diff --git a/src/launch/java/baritone/launch/mixins/MixinClientPlayerEntity.java b/src/launch/java/baritone/launch/mixins/MixinClientPlayerEntity.java index e835d5e46..4674ffaa6 100644 --- a/src/launch/java/baritone/launch/mixins/MixinClientPlayerEntity.java +++ b/src/launch/java/baritone/launch/mixins/MixinClientPlayerEntity.java @@ -121,5 +121,5 @@ public class MixinClientPlayerEntity { return false; } return ElytraItem.isFlyEnabled(stack); - } // bradyfix is this right? + } } diff --git a/src/launch/java/baritone/launch/mixins/MixinLivingEntity.java b/src/launch/java/baritone/launch/mixins/MixinLivingEntity.java index ecc7829d9..ada92f6c2 100644 --- a/src/launch/java/baritone/launch/mixins/MixinLivingEntity.java +++ b/src/launch/java/baritone/launch/mixins/MixinLivingEntity.java @@ -51,7 +51,7 @@ public abstract class MixinLivingEntity extends Entity { @Unique private RotationMoveEvent elytraRotationEvent; - public MixinLivingEntity(EntityType entityTypeIn, Level worldIn) { + private MixinLivingEntity(EntityType entityTypeIn, Level worldIn) { super(entityTypeIn, worldIn); } @@ -111,33 +111,6 @@ public abstract class MixinLivingEntity extends Entity { this.elytraRotationEvent = null; } } - // bradyfix in 1.12.2 this is a redirect of moveRelative as called from travel, but it looks like in 1.19.4 we're doing it in MixinEntity as injecting into moveRelative itself, is that right? - /*@Redirect( - method = "travel", - at = @At( - value = "INVOKE", - target = "net/minecraft/entity/EntityLivingBase.moveRelative(FFFF)V" - ) - ) - private void onMoveRelative(EntityLivingBase self, float strafe, float up, float forward, float friction) { - Optional baritone = this.getBaritone(); - if (!baritone.isPresent()) { - // If a shadow is used here it breaks on Forge - this.moveRelative(strafe, up, forward, friction); - return; - } - - RotationMoveEvent event = new RotationMoveEvent(RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw, this.rotationPitch); - baritone.get().getGameEventHandler().onPlayerRotationMove(event); - - this.rotationYaw = event.getYaw(); - this.rotationPitch = event.getPitch(); - - this.moveRelative(strafe, up, forward, friction); - - this.rotationYaw = event.getOriginal().getYaw(); - this.rotationPitch = event.getOriginal().getPitch(); - }*/ @Unique private Optional getBaritone() { diff --git a/src/launch/java/baritone/launch/mixins/MixinMinecraft.java b/src/launch/java/baritone/launch/mixins/MixinMinecraft.java index d50534b7a..4f9925cc7 100644 --- a/src/launch/java/baritone/launch/mixins/MixinMinecraft.java +++ b/src/launch/java/baritone/launch/mixins/MixinMinecraft.java @@ -34,6 +34,7 @@ import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.Slice; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.function.BiFunction; @@ -61,21 +62,12 @@ public class MixinMinecraft { BaritoneAPI.getProvider().getPrimaryBaritone(); } - @Inject( method = "tick", at = @At( -//<<<<<<< HEAD value = "FIELD", opcode = Opcodes.GETFIELD, - target = "Lnet/minecraft/client/Minecraft;screen:Lnet/minecraft/client/gui/screens/Screen;", - ordinal = 4, - shift = At.Shift.BY, - by = -3 -/*======= - value = "FIELD", - opcode = Opcodes.GETFIELD, - target = "net/minecraft/client/Minecraft.currentScreen:Lnet/minecraft/client/gui/GuiScreen;", + target = "net/minecraft/client/Minecraft.screen:Lnet/minecraft/client/gui/screens/Screen;", ordinal = 0, shift = At.Shift.BEFORE ), @@ -83,10 +75,8 @@ public class MixinMinecraft { from = @At( value = "FIELD", opcode = Opcodes.PUTFIELD, - target = "net/minecraft/client/Minecraft.leftClickCounter:I" + target = "net/minecraft/client/Minecraft.missTime:I" ) ->>>>>>> master*/ - // bradyfix ^ ) ) private void runTick(CallbackInfo ci) { From 7969988099ffe22ab2e6b86d7772eaa1a60acc15 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 18 Aug 2023 13:09:28 -0700 Subject: [PATCH 405/405] yay fixing the build was actually easy --- buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java b/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java index 331f22ebe..bad182c1f 100644 --- a/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java +++ b/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java @@ -63,7 +63,6 @@ public class ProguardTask extends BaritoneGradleTask { private List requiredLibraries; - private File mixin; private File pathfinder; @TaskAction @@ -75,7 +74,7 @@ public class ProguardTask extends BaritoneGradleTask { downloadProguard(); extractProguard(); generateConfigs(); - acquireDependencies(); + pathfinder = acquireDependencies().filter(file -> file.getName().contains("nether-pathfinder")).findAny().get(); processArtifact(); proguardApi(); proguardStandalone();