11package org .dimdev .vanillafix .blockstates .mixins ;
22
3- import com .google .common .collect .ImmutableList ;
4- import com .google .common .collect .ImmutableMap ;
5- import com .google .common .collect .ImmutableSortedMap ;
3+ import com .google .common .collect .*;
64import net .minecraft .block .Block ;
75import net .minecraft .block .properties .IProperty ;
86import net .minecraft .block .state .BlockStateContainer ;
97import net .minecraft .block .state .IBlockState ;
108import net .minecraft .util .MapPopulator ;
119import net .minecraft .util .math .Cartesian ;
1210import net .minecraft .util .math .MathHelper ;
11+ import net .minecraftforge .common .property .ExtendedBlockState ;
1312import net .minecraftforge .common .property .IUnlistedProperty ;
1413import org .dimdev .vanillafix .blockstates .IPatchedBlockStateContainer ;
1514import org .dimdev .vanillafix .blockstates .NumericalBlockState ;
1817import javax .annotation .Nullable ;
1918import java .util .*;
2019
20+ @ SuppressWarnings ({"ResultOfMethodCallIgnored" , "ConstructorNotProtectedInAbstractClass" })
2121@ Mixin (BlockStateContainer .class )
2222public abstract class MixinBlockStateContainer implements IPatchedBlockStateContainer {
23+ // @formatter:off
2324 @ Shadow @ Final @ Mutable private Block block ;
2425 @ Shadow @ Final @ Mutable private ImmutableSortedMap <String , IProperty <?>> properties ;
2526 @ Shadow public static <T extends Comparable <T >> String validateProperty (Block block , IProperty <T > property ) { return null ; }
2627 @ Shadow protected abstract List <Iterable <Comparable <?>>> getAllowedValues ();
28+ @ Shadow public abstract Block getBlock ();
29+ @ Shadow @ Final private ImmutableList <IBlockState > validStates ;
30+ // @formatter:on
2731
32+ @ SuppressWarnings ("EqualsBetweenInconvertibleTypes" ) // mixin
33+ private boolean isNumerical = getClass ().equals (BlockStateContainer .class ) || getClass ().equals (ExtendedBlockState .class );
2834 private final ImmutableMap <IUnlistedProperty <?>, Optional <?>> unlistedProperties ;
2935 private final Map <IProperty <?>, Integer > propertyOffsets = new HashMap <>();
30- protected ImmutableList <IBlockState > validStatesCache ;
36+ protected ImmutableList <IBlockState > validStatesCache = null ;
37+ @ SuppressWarnings ({"FieldCanBeLocal" , "unused" }) private final Object x ; // workaround for mixin bug
3138
3239 @ Overwrite
3340 public MixinBlockStateContainer (Block block , IProperty <?>[] properties , ImmutableMap <IUnlistedProperty <?>, Optional <?>> unlistedProperties ) {
3441 this .block = block ;
3542 this .unlistedProperties = unlistedProperties ;
3643
3744 // Immutable map builder won't work, some mods have duplicate properties
38- LinkedHashMap <String , IProperty <?>> propertyMap = new LinkedHashMap <>();
45+ Map <String , IProperty <?>> propertyMap = new LinkedHashMap <>();
3946 int offset = 0 ;
4047
4148 for (IProperty <?> property : properties ) {
4249 validateProperty (block , property );
4350 propertyMap .put (property .getName (), property );
4451
45- NumericalBlockState .makePropertyInfo (property );
46- propertyOffsets .put (property , offset );
47- offset += MathHelper .log2 (property .getAllowedValues ().size ()) + 1 ;
52+ if (isNumerical ) {
53+ NumericalBlockState .makePropertyInfo (property );
54+ propertyOffsets .put (property , offset );
55+ offset += MathHelper .log2 (property .getAllowedValues ().size ()) + 1 ;
56+ }
4857 }
4958
5059 this .properties = ImmutableSortedMap .copyOf (propertyMap );
60+
61+ if (!isNumerical ) {
62+ Map <Map <IProperty <?>, Comparable <?>>, BlockStateContainer .StateImplementation > map2 = Maps .newLinkedHashMap ();
63+ List <BlockStateContainer .StateImplementation > validStates = Lists .newArrayList ();
64+
65+ for (List <Comparable <?>> list : Cartesian .cartesianProduct (getAllowedValues ())) {
66+ Map <IProperty <?>, Comparable <?>> map1 = MapPopulator .createMap (this .properties .values (), list );
67+ BlockStateContainer .StateImplementation blockstatecontainer$stateimplementation = createState (block , ImmutableMap .copyOf (map1 ), unlistedProperties );
68+ map2 .put (map1 , blockstatecontainer$stateimplementation );
69+ validStates .add (blockstatecontainer$stateimplementation );
70+ }
71+
72+ for (BlockStateContainer .StateImplementation blockstatecontainer$stateimplementation1 : validStates ) {
73+ blockstatecontainer$stateimplementation1 .buildPropertyValueTable (map2 );
74+ }
75+
76+ this .validStates = ImmutableList .copyOf (validStates );
77+ }
78+
79+ x = new Object ();
5180 }
5281
5382 @ Overwrite
5483 public ImmutableList <IBlockState > getValidStates () {
84+ if (!isNumerical ) {
85+ return validStates ;
86+ }
87+
5588 if (validStatesCache == null ) {
5689 ImmutableList .Builder <IBlockState > states = ImmutableList .builder ();
5790
@@ -69,6 +102,10 @@ public ImmutableList<IBlockState> getValidStates() {
69102
70103 @ Overwrite (remap = false )
71104 protected BlockStateContainer .StateImplementation createState (Block block , ImmutableMap <IProperty <?>, Comparable <?>> properties , @ Nullable ImmutableMap <IUnlistedProperty <?>, Optional <?>> unlistedProperties ) {
105+ if (!isNumerical ) {
106+ return new BlockStateContainer .StateImplementation (block , properties );
107+ }
108+
72109 return null ;
73110 }
74111
@@ -83,6 +120,10 @@ protected IBlockState createState(ImmutableMap<IProperty<?>, Comparable<?>> prop
83120
84121 @ Overwrite
85122 public IBlockState getBaseState () {
123+ if (!isNumerical ) {
124+ return validStates .get (0 );
125+ }
126+
86127 if (validStatesCache != null ) {
87128 return validStatesCache .get (0 );
88129 }
0 commit comments