diff --git a/src/api/java/baritone/api/utils/BlockOptionalMeta.java b/src/api/java/baritone/api/utils/BlockOptionalMeta.java index dcfda0f8..5bfabb4c 100644 --- a/src/api/java/baritone/api/utils/BlockOptionalMeta.java +++ b/src/api/java/baritone/api/utils/BlockOptionalMeta.java @@ -17,16 +17,21 @@ 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; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; import java.util.regex.MatchResult; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import static java.util.Objects.isNull; @@ -34,12 +39,25 @@ public final class BlockOptionalMeta { private final Block block; private final int meta; private final boolean noMeta; + private final ImmutableSet stateMetas; private static final Pattern pattern = Pattern.compile("^(.+?)(?::(\\d+))?$"); + private static ImmutableSet getStateMetas(@Nonnull Block block, @Nullable Integer meta) { + List blockstates = block.getBlockState().getValidStates(); + + return ImmutableSet.copyOf( + (ArrayList) blockstates.stream() + .filter(blockstate -> meta == null || block.getMetaFromState(blockstate.withRotation(Rotation.NONE)) == meta) + .map(IBlockState::hashCode) + .collect(Collectors.toCollection(ArrayList::new)) + ); + } + public BlockOptionalMeta(@Nonnull Block block, @Nullable Integer meta) { this.block = block; this.noMeta = isNull(meta); this.meta = noMeta ? 0 : meta; + this.stateMetas = getStateMetas(block, meta); } public BlockOptionalMeta(@Nonnull Block block) { @@ -64,6 +82,7 @@ public final class BlockOptionalMeta { block = Block.REGISTRY.getObject(id); meta = noMeta ? 0 : Integer.parseInt(matchResult.group(2)); + stateMetas = getStateMetas(block, noMeta ? null : meta); } public Block getBlock() { @@ -80,7 +99,7 @@ public final class BlockOptionalMeta { public boolean matches(@Nonnull IBlockState blockstate) { Block block = blockstate.getBlock(); - return block == this.block && (noMeta || block.damageDropped(blockstate) == this.meta); + return block == this.block && stateMetas.contains(blockstate.hashCode()); } @Override diff --git a/src/launch/java/baritone/launch/mixins/MixinStateImplementation.java b/src/launch/java/baritone/launch/mixins/MixinStateImplementation.java new file mode 100644 index 00000000..8d0f770e --- /dev/null +++ b/src/launch/java/baritone/launch/mixins/MixinStateImplementation.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.launch.mixins; + +import com.google.common.collect.ImmutableMap; +import net.minecraft.block.properties.IProperty; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +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.callback.CallbackInfo; + +@Mixin(targets = "net.minecraft.block.state.BlockStateContainer$StateImplementation") +public abstract class MixinStateImplementation { + @Shadow + @Final + private ImmutableMap, Comparable> properties; + + /** + * Block states are fucking immutable + */ + @Unique + private int hashCode; + + @Inject(method = "*", at = @At("RETURN")) + private void onInit(CallbackInfo ci) { + hashCode = properties.hashCode(); + } + + /** + * Cache this instead of using the fucking map every time + * + * @author LoganDark + */ + @Override + @Overwrite + public int hashCode() { + return hashCode; + } +} diff --git a/src/launch/resources/mixins.baritone.json b/src/launch/resources/mixins.baritone.json index c1116279..ff4cc584 100644 --- a/src/launch/resources/mixins.baritone.json +++ b/src/launch/resources/mixins.baritone.json @@ -27,6 +27,7 @@ "MixinNetworkManager", "MixinRenderChunk", "MixinRenderList", + "MixinStateImplementation", "MixinTabCompleter", "MixinVboRenderList", "MixinWorldClient"