diff --git a/src/api/java/baritone/api/utils/BlockOptionalMeta.java b/src/api/java/baritone/api/utils/BlockOptionalMeta.java index 098dc2696..ac817e27a 100644 --- a/src/api/java/baritone/api/utils/BlockOptionalMeta.java +++ b/src/api/java/baritone/api/utils/BlockOptionalMeta.java @@ -20,16 +20,26 @@ package baritone.api.utils; import baritone.api.accessor.IItemStack; import com.google.common.collect.ImmutableSet; import net.minecraft.block.Block; +import net.minecraft.block.BlockDoor; +import net.minecraft.block.BlockDoublePlant; +import net.minecraft.block.BlockLever; +import net.minecraft.block.BlockSlab; +import net.minecraft.block.BlockStairs; +import net.minecraft.block.properties.IProperty; import net.minecraft.block.state.IBlockState; import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.Rotation; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Random; import java.util.Set; +import java.util.function.Consumer; import java.util.regex.MatchResult; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -45,10 +55,58 @@ public final class BlockOptionalMeta { private final ImmutableSet stateHashes; private final ImmutableSet stackHashes; private static final Pattern pattern = Pattern.compile("^(.+?)(?::(\\d+))?$"); + private static final Map, Enum> normalizations; + + static { + Map, Enum> _normalizations = new HashMap<>(); + Consumer put = instance -> _normalizations.put(instance.getClass(), instance); + put.accept(EnumFacing.NORTH); + put.accept(EnumFacing.Axis.Y); + put.accept(BlockStairs.EnumHalf.BOTTOM); + put.accept(BlockStairs.EnumShape.STRAIGHT); + put.accept(BlockLever.EnumOrientation.DOWN_X); + put.accept(BlockDoublePlant.EnumBlockHalf.LOWER); + put.accept(BlockSlab.EnumBlockHalf.BOTTOM); + put.accept(BlockDoor.EnumDoorHalf.LOWER); + normalizations = _normalizations; + } + + private static , P extends IProperty> P castToIProperty(Object value) { + //noinspection unchecked + return (P) value; + } + + @SuppressWarnings("unused") + private static , P extends IProperty> C castToIPropertyValue(P iproperty, Object value) { + //noinspection unchecked + return (C) value; + } + + public static IBlockState normalize(IBlockState state) { + IBlockState newState = state; + + for (IProperty property : state.getProperties().keySet()) { + Class valueClass = property.getValueClass(); + if (normalizations.containsKey(valueClass)) { + try { + newState = newState.withProperty( + castToIProperty(property), + castToIPropertyValue(property, normalizations.get(valueClass)) + ); + } catch (IllegalArgumentException ignored) {} + } + } + + return newState; + } + + public static int stateMeta(IBlockState state) { + return state.getBlock().getMetaFromState(normalize(state)); + } private static Set getStates(@Nonnull Block block, @Nullable Integer meta) { return block.getBlockState().getValidStates().stream() - .filter(blockstate -> meta == null || block.getMetaFromState(blockstate.withRotation(Rotation.NONE)) == meta) + .filter(blockstate -> meta == null || stateMeta(blockstate) == meta) .collect(Collectors.toCollection(HashSet::new)); }