diff --git a/src/api/java/baritone/api/utils/BlockOptionalMeta.java b/src/api/java/baritone/api/utils/BlockOptionalMeta.java index b77bf541..dcfda0f8 100644 --- a/src/api/java/baritone/api/utils/BlockOptionalMeta.java +++ b/src/api/java/baritone/api/utils/BlockOptionalMeta.java @@ -54,7 +54,7 @@ public final class BlockOptionalMeta { } MatchResult matchResult = matcher.toMatchResult(); - noMeta = matchResult.groupCount() < 2; + noMeta = matchResult.group(2) == null; ResourceLocation id = new ResourceLocation(matchResult.group(1)); @@ -74,13 +74,13 @@ public final class BlockOptionalMeta { return meta; } - public boolean matches(@Nonnull Block block, int meta) { - // & instead of && is intentional - return block == this.block & (noMeta || meta == this.meta); + public boolean matches(@Nonnull Block block) { + return block == this.block; } public boolean matches(@Nonnull IBlockState blockstate) { - return matches(blockstate.getBlock(), block.damageDropped(blockstate)); + Block block = blockstate.getBlock(); + return block == this.block && (noMeta || block.damageDropped(blockstate) == this.meta); } @Override diff --git a/src/api/java/baritone/api/utils/BlockOptionalMetaLookup.java b/src/api/java/baritone/api/utils/BlockOptionalMetaLookup.java index eafe49e1..2457484f 100644 --- a/src/api/java/baritone/api/utils/BlockOptionalMetaLookup.java +++ b/src/api/java/baritone/api/utils/BlockOptionalMetaLookup.java @@ -2,69 +2,34 @@ package baritone.api.utils; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; -import org.apache.commons.lang3.ArrayUtils; -import java.util.HashMap; +import java.util.Arrays; import java.util.List; -import java.util.Map; -import java.util.Set; + +import static java.util.Arrays.asList; public class BlockOptionalMetaLookup { - private final Map lookup = new HashMap<>(); - - public BlockOptionalMetaLookup() { - } + private final BlockOptionalMeta[] boms; public BlockOptionalMetaLookup(BlockOptionalMeta... boms) { - put(boms); + this.boms = boms; } public BlockOptionalMetaLookup(Block... blocks) { - put(blocks); + this.boms = Arrays.stream(blocks) + .map(BlockOptionalMeta::new) + .toArray(BlockOptionalMeta[]::new); } public BlockOptionalMetaLookup(List blocks) { - put(blocks); - } - - public void put(BlockOptionalMeta bom) { - final int[] metaArr = new int[] {bom.getMeta()}; - lookup.compute(bom.getBlock(), (__, arr) -> arr == null ? metaArr : ArrayUtils.addAll(arr, metaArr)); - } - - public void put(BlockOptionalMeta... boms) { - for (BlockOptionalMeta bom : boms) { - put(bom); - } - } - - public void put(Block... blocks) { - for (Block block : blocks) { - put(new BlockOptionalMeta(block)); - } - } - - public void put(List blocks) { - for (Block block : blocks) { - put(new BlockOptionalMeta(block)); - } + this.boms = blocks.stream() + .map(BlockOptionalMeta::new) + .toArray(BlockOptionalMeta[]::new); } public boolean has(Block block) { - return lookup.containsKey(block); - } - - public boolean has(IBlockState state) { - Block block = state.getBlock(); - int[] arr = lookup.get(block); - - if (arr == null) { - return false; - } - - int meta = block.damageDropped(state); - for (int value : arr) { - if (value == meta) { + for (BlockOptionalMeta bom : boms) { + if (bom.getBlock() == block) { return true; } } @@ -72,7 +37,25 @@ public class BlockOptionalMetaLookup { return false; } - public Set blocks() { - return lookup.keySet(); + public boolean has(IBlockState state) { + for (BlockOptionalMeta bom : boms) { + if (bom.matches(state)) { + return true; + } + } + + return false; + } + + public List blocks() { + return asList(boms); + } + + @Override + public String toString() { + return String.format( + "BlockOptionalMetaLookup{%s}", + Arrays.toString(boms) + ); } } diff --git a/src/api/java/baritone/api/utils/IPlayerContext.java b/src/api/java/baritone/api/utils/IPlayerContext.java index 9acb2ad9..a9f7cdf7 100644 --- a/src/api/java/baritone/api/utils/IPlayerContext.java +++ b/src/api/java/baritone/api/utils/IPlayerContext.java @@ -47,9 +47,14 @@ public interface IPlayerContext { default BetterBlockPos playerFeet() { // TODO find a better way to deal with soul sand!!!!! BetterBlockPos feet = new BetterBlockPos(player().posX, player().posY + 0.1251, player().posZ); - if (world().getBlockState(feet).getBlock() instanceof BlockSlab) { - return feet.up(); + + try { + if (world().getBlockState(feet).getBlock() instanceof BlockSlab) { + return feet.up(); + } + } catch (NullPointerException ignored) { } + return feet; } diff --git a/src/launch/java/baritone/launch/mixins/MixinBlockStateContainer.java b/src/launch/java/baritone/launch/mixins/MixinBlockStateContainer.java index b419952d..343bdda6 100644 --- a/src/launch/java/baritone/launch/mixins/MixinBlockStateContainer.java +++ b/src/launch/java/baritone/launch/mixins/MixinBlockStateContainer.java @@ -23,20 +23,29 @@ import net.minecraft.util.BitArray; import net.minecraft.world.chunk.BlockStateContainer; import net.minecraft.world.chunk.IBlockStatePalette; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.gen.Accessor; @Mixin(BlockStateContainer.class) public abstract class MixinBlockStateContainer implements IBlockStateContainer { - @Accessor - public abstract IBlockStatePalette getPalette(); + @Shadow + protected BitArray storage; + @Shadow + protected IBlockStatePalette palette; + + @Override @Accessor public abstract BitArray getStorage(); + @Override + @Accessor + public abstract IBlockStatePalette getPalette(); + @Override @Unique public IBlockState getFast(int x, int y, int z) { - return getPalette().getBlockState(getStorage().getAt(y << 8 | z << 4 | x)); + return palette.getBlockState(storage.getAt(y << 8 | z << 4 | x)); } } diff --git a/src/main/java/baritone/cache/CachedChunk.java b/src/main/java/baritone/cache/CachedChunk.java index 67ac6942..148b21e7 100644 --- a/src/main/java/baritone/cache/CachedChunk.java +++ b/src/main/java/baritone/cache/CachedChunk.java @@ -91,6 +91,16 @@ public final class CachedChunk { Blocks.VINE ); + public static boolean tracked(Block block) { + for (Block tracked : BLOCKS_TO_KEEP_TRACK_OF) { + if (tracked == block) { + return true; + } + } + + return false; + } + /** * The size of the chunk data in bits. Equal to 16 KiB. diff --git a/src/main/java/baritone/process/MineProcess.java b/src/main/java/baritone/process/MineProcess.java index 7e59bc92..75648ae1 100644 --- a/src/main/java/baritone/process/MineProcess.java +++ b/src/main/java/baritone/process/MineProcess.java @@ -26,17 +26,21 @@ import baritone.api.pathing.goals.GoalTwoBlocks; import baritone.api.process.IMineProcess; import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommandType; +import baritone.api.utils.BetterBlockPos; import baritone.api.utils.BlockOptionalMeta; import baritone.api.utils.BlockOptionalMetaLookup; +import baritone.api.utils.BlockUtils; import baritone.api.utils.IPlayerContext; import baritone.api.utils.Rotation; import baritone.api.utils.RotationUtils; import baritone.api.utils.input.Input; +import baritone.cache.CachedChunk; import baritone.cache.WorldScanner; import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.MovementHelper; import baritone.utils.BaritoneProcessHelper; import baritone.utils.BlockStateInterface; +import net.minecraft.block.Block; import net.minecraft.block.BlockAir; import net.minecraft.block.BlockFalling; import net.minecraft.block.state.IBlockState; @@ -122,10 +126,10 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro addNearby(); } Optional shaft = curr.stream() - .filter(pos -> pos.getX() == ctx.playerFeet().getX() && pos.getZ() == ctx.playerFeet().getZ()) - .filter(pos -> pos.getY() >= ctx.playerFeet().getY()) - .filter(pos -> !(BlockStateInterface.get(ctx, pos).getBlock() instanceof BlockAir)) // after breaking a block, it takes mineGoalUpdateInterval ticks for it to actually update this list =( - .min(Comparator.comparingDouble(ctx.player()::getDistanceSq)); + .filter(pos -> pos.getX() == ctx.playerFeet().getX() && pos.getZ() == ctx.playerFeet().getZ()) + .filter(pos -> pos.getY() >= ctx.playerFeet().getY()) + .filter(pos -> !(BlockStateInterface.get(ctx, pos).getBlock() instanceof BlockAir)) // after breaking a block, it takes mineGoalUpdateInterval ticks for it to actually update this list =( + .min(Comparator.comparingDouble(ctx.player()::getDistanceSq)); baritone.getInputOverrideHandler().clearAllKeys(); if (shaft.isPresent() && ctx.player().onGround) { BlockPos pos = shaft.get(); @@ -311,9 +315,36 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro public static List searchWorld(CalculationContext ctx, BlockOptionalMetaLookup filter, int max, List alreadyKnown, List blacklist) { List locs = new ArrayList<>(); - locs = prune(ctx, locs, filter, max, blacklist); - locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(ctx.getBaritone().getPlayerContext(), filter, max, 10, 32)); // maxSearchRadius is NOT sq + List untracked = new ArrayList<>(); + for (BlockOptionalMeta bom : filter.blocks()) { + Block block = bom.getBlock(); + if (CachedChunk.tracked(block)) { + BetterBlockPos pf = ctx.baritone.getPlayerContext().playerFeet(); + + locs.addAll(ctx.worldData.getCachedWorld().getLocationsOf( + BlockUtils.blockToString(block), + Baritone.settings().maxCachedWorldScanCount.value, + pf.x, + pf.z, + 2 + )); + } else { + untracked.add(block); + } + } + + if (!untracked.isEmpty()) { + locs.addAll(WorldScanner.INSTANCE.scanChunkRadius( + ctx.getBaritone().getPlayerContext(), + filter, + max, + 10, + 32 + )); // maxSearchRadius is NOT sq + } + locs.addAll(alreadyKnown); + return prune(ctx, locs, filter, max, blacklist); }