diff --git a/src/main/java/net/minecraftforge/common/property/ExtendedBlockState.java b/src/main/java/net/minecraftforge/common/property/ExtendedBlockState.java index 63d5ee31e..09a56db49 100644 --- a/src/main/java/net/minecraftforge/common/property/ExtendedBlockState.java +++ b/src/main/java/net/minecraftforge/common/property/ExtendedBlockState.java @@ -22,15 +22,12 @@ package net.minecraftforge.common.property; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.Optional; -import com.google.common.base.Predicates; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableTable; -import com.google.common.collect.Iterables; import net.minecraft.block.Block; import net.minecraft.block.properties.IProperty; import net.minecraft.block.state.BlockStateContainer; @@ -95,7 +92,7 @@ public class ExtendedBlockState extends BlockStateContainer return this; } - if (unlistedProperties.values().stream().noneMatch(Optional::isPresent)) + if (this == this.cleanState) { // no dynamic properties present, looking up in the normal table return clean; } @@ -104,39 +101,53 @@ public class ExtendedBlockState extends BlockStateContainer } @Override - public IExtendedBlockState withProperty(IUnlistedProperty property, V value) + public IExtendedBlockState withProperty(IUnlistedProperty property, @Nullable V value) { - if(!this.unlistedProperties.containsKey(property)) + Optional oldValue = unlistedProperties.get(property); + if (oldValue == null) { throw new IllegalArgumentException("Cannot set unlisted property " + property + " as it does not exist in " + getBlock().getBlockState()); } - if(!property.isValid(value)) + if (Objects.equals(oldValue.orElse(null), value)) + { + return this; + } + if (!property.isValid(value)) { throw new IllegalArgumentException("Cannot set unlisted property " + property + " to " + value + " on block " + Block.REGISTRY.getNameForObject(getBlock()) + ", it is not an allowed value"); } - Map, Optional> newMap = new HashMap, Optional>(unlistedProperties); - newMap.put(property, Optional.ofNullable(value)); - if(Iterables.all(newMap.values(), Predicates.>equalTo(Optional.empty()))) - { // no dynamic properties, lookup normal state - return (IExtendedBlockState)cleanState; + boolean clean = true; + ImmutableMap.Builder, Optional> builder = ImmutableMap.builder(); + for (Map.Entry, Optional> entry : unlistedProperties.entrySet()) + { + IUnlistedProperty key = entry.getKey(); + Optional newValue = key.equals(property) ? Optional.ofNullable(value) : entry.getValue(); + if (newValue.isPresent()) clean = false; + builder.put(key, newValue); } - return new ExtendedStateImplementation(getBlock(), getProperties(), ImmutableMap.copyOf(newMap), propertyValueTable, this.cleanState); + if (clean) + { // no dynamic properties, lookup normal state + return (IExtendedBlockState) cleanState; + } + return new ExtendedStateImplementation(getBlock(), getProperties(), builder.build(), propertyValueTable, this.cleanState); } @Override public Collection> getUnlistedNames() { - return Collections.unmodifiableCollection(unlistedProperties.keySet()); + return unlistedProperties.keySet(); } @Override - public V getValue(IUnlistedProperty property) + @Nullable + public V getValue(IUnlistedProperty property) { - if(!this.unlistedProperties.containsKey(property)) + Optional value = unlistedProperties.get(property); + if (value == null) { throw new IllegalArgumentException("Cannot get unlisted property " + property + " as it does not exist in " + getBlock().getBlockState()); } - return property.getType().cast(this.unlistedProperties.get(property).orElse(null)); + return property.getType().cast(value.orElse(null)); } public ImmutableMap, Optional> getUnlistedProperties()