diff --git a/src/main/java/ca/spottedleaf/moonrise/mixin/blockstate_propertyaccess/StateHolderMixin.java b/src/main/java/ca/spottedleaf/moonrise/mixin/blockstate_propertyaccess/StateHolderMixin.java index a2c4699d..6baa5176 100644 --- a/src/main/java/ca/spottedleaf/moonrise/mixin/blockstate_propertyaccess/StateHolderMixin.java +++ b/src/main/java/ca/spottedleaf/moonrise/mixin/blockstate_propertyaccess/StateHolderMixin.java @@ -87,7 +87,20 @@ private void loadTable(final Map, Comparable>, S> map, final public , V extends T> S setValue(final Property property, final V value) { final S ret = this.optimisedTable.set(this.tableIndex, property, value); if (ret == null) { - throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner + ", it is not an allowed value"); + throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner); + } + return ret; + } + + /** + * @reason Replace with optimisedTable + * @author Spottedleaf + */ + @Overwrite + public , V extends T> S trySetValue(final Property property, final V value) { + final S ret = this.optimisedTable.trySet(this.tableIndex, property, value, (S)(StateHolder)(Object)this); + if (ret == null) { + throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner); } return ret; } diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/util/ZeroCollidingReferenceStateTable.java b/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/util/ZeroCollidingReferenceStateTable.java index d275c602..1660f7bd 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/util/ZeroCollidingReferenceStateTable.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/util/ZeroCollidingReferenceStateTable.java @@ -128,6 +128,28 @@ public > S set(final long index, final Property prope return this.lookup[(int)newIndex]; } + public > S trySet(final long index, final Property property, final T with, final S dfl) { + final Indexer indexer = this.propertyToIndexer.get(((PropertyAccess)property).moonrise$getId()); + if (indexer == null) { + return dfl; + } + + final int newValueId = ((PropertyAccess)property).moonrise$getIdFor(with); + if (newValueId < 0) { + return null; + } + + final long divided = (index * indexer.multipleDivMagic) >>> 32; + final long modded = (((divided * indexer.modMagic) & 0xFFFFFFFFL) * indexer.totalValues) >>> 32; + // equiv to: divided = index / multiple + // modded = divided % totalValues + + // subtract out the old value, add in the new + final long newIndex = (((long)newValueId - modded) * indexer.multiple) + index; + + return this.lookup[(int)newIndex]; + } + private static final record Indexer( int totalValues, int multiple, long multipleDivMagic, long modMagic ) {}