diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ModelBakeryMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ModelBakeryMixin.java index 3bf8c51d..f0bab01e 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ModelBakeryMixin.java +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ModelBakeryMixin.java @@ -1,9 +1,11 @@ package org.embeddedt.modernfix.mixin.perf.dynamic_resources; +import com.google.common.base.Splitter; import com.google.common.base.Stopwatch; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.common.cache.RemovalNotification; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.gson.*; @@ -26,6 +28,7 @@ import net.minecraft.world.item.Item; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.Property; import net.minecraftforge.client.ForgeHooksClient; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.client.model.ModelLoaderRegistry; @@ -79,6 +82,12 @@ public abstract class ModelBakeryMixin { @Shadow @Final private static Logger LOGGER; + @Shadow @Final private static Splitter COMMA_SPLITTER; + @Shadow @Final private static Splitter EQUAL_SPLITTER; + @Shadow @Nullable static > T getValueHelper(Property property, String value) { + throw new AssertionError(); + } + @Shadow @Final @Mutable private Map bakedTopLevelModels; @@ -361,6 +370,49 @@ public abstract class ModelBakeryMixin { } } + private , V extends T> BlockState setPropertyGeneric(BlockState state, Property prop, Object o) { + return state.setValue(prop, (V)o); + } + @Redirect(method = "loadModel", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/StateDefinition;getPossibleStates()Lcom/google/common/collect/ImmutableList;")) + private ImmutableList loadOnlyRelevantBlockState(StateDefinition stateDefinition, ResourceLocation location) { + Set> fixedProperties = new HashSet<>(); + ModelResourceLocation mrl = (ModelResourceLocation)location; + BlockState fixedState = stateDefinition.any(); + for(String s : COMMA_SPLITTER.split(mrl.getVariant())) { + Iterator iterator = EQUAL_SPLITTER.split(s).iterator(); + if (iterator.hasNext()) { + String s1 = iterator.next(); + Property property = stateDefinition.getProperty(s1); + if (property != null && iterator.hasNext()) { + String s2 = iterator.next(); + Object value = getValueHelper(property, s2); + if (value == null) { + throw new RuntimeException("Unknown value: '" + s2 + "' for blockstate property: '" + s1 + "' " + property.getPossibleValues()); + } + fixedState = setPropertyGeneric(fixedState, property, value); + fixedProperties.add(property); + } else if (!s1.isEmpty()) { + throw new RuntimeException("Unknown blockstate property: '" + s1 + "'"); + } + } + } + // generate all possible blockstates from the remaining properties + ArrayList> anyProperties = new ArrayList<>(stateDefinition.getProperties()); + anyProperties.removeAll(fixedProperties); + ArrayList finalList = new ArrayList<>(); + finalList.add(fixedState); + for(Property property : anyProperties) { + ArrayList newPermutations = new ArrayList<>(); + for(BlockState state : finalList) { + for(Comparable value : property.getPossibleValues()) { + newPermutations.add(setPropertyGeneric(state, property, value)); + } + } + finalList = newPermutations; + } + return ImmutableList.copyOf(finalList); + } + @Overwrite public BakedModel getBakedModel(ResourceLocation arg, ModelState arg2, Function textureGetter) { Triple triple = Triple.of(arg, arg2.getRotation(), arg2.isUvLocked());