2014-11-27 03:56:35 +00:00
package net.minecraftforge.common.property ;
import java.util.Collection ;
import java.util.Collections ;
import java.util.HashMap ;
import java.util.Map ;
import net.minecraft.block.Block ;
import net.minecraft.block.properties.IProperty ;
2016-03-01 12:58:03 +00:00
import net.minecraft.block.state.BlockStateContainer ;
2014-11-27 03:56:35 +00:00
import net.minecraft.block.state.IBlockState ;
import com.google.common.base.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 ;
2015-11-13 16:29:44 +00:00
import com.google.common.collect.Maps ;
2014-11-27 03:56:35 +00:00
2016-03-01 12:58:03 +00:00
public class ExtendedBlockState extends BlockStateContainer
2014-11-27 03:56:35 +00:00
{
private final ImmutableSet < IUnlistedProperty < ? > > unlistedProperties ;
2016-03-02 17:00:32 +00:00
public ExtendedBlockState ( Block blockIn , IProperty < ? > [ ] properties , IUnlistedProperty < ? > [ ] unlistedProperties )
2014-11-27 03:56:35 +00:00
{
super ( blockIn , properties , buildUnlistedMap ( unlistedProperties ) ) ;
2016-03-23 14:34:48 +00:00
ImmutableSet . Builder < IUnlistedProperty < ? > > builder = ImmutableSet . builder ( ) ;
2014-11-27 03:56:35 +00:00
for ( IUnlistedProperty < ? > property : unlistedProperties )
{
builder . add ( property ) ;
}
this . unlistedProperties = builder . build ( ) ;
}
2016-03-01 12:58:03 +00:00
2015-11-27 03:38:21 +00:00
public Collection < IUnlistedProperty < ? > > getUnlistedProperties ( )
{
return unlistedProperties ;
}
2014-11-27 03:56:35 +00:00
private static ImmutableMap < IUnlistedProperty < ? > , Optional < ? > > buildUnlistedMap ( IUnlistedProperty < ? > [ ] unlistedProperties )
{
2016-03-23 14:34:48 +00:00
ImmutableMap . Builder < IUnlistedProperty < ? > , Optional < ? > > builder = ImmutableMap . builder ( ) ;
2014-11-27 03:56:35 +00:00
for ( IUnlistedProperty < ? > p : unlistedProperties )
{
builder . put ( p , Optional . absent ( ) ) ;
}
return builder . build ( ) ;
}
@Override
2016-03-02 17:00:32 +00:00
protected StateImplementation createState ( Block block , ImmutableMap < IProperty < ? > , Comparable < ? > > properties , ImmutableMap < IUnlistedProperty < ? > , Optional < ? > > unlistedProperties )
2014-11-27 03:56:35 +00:00
{
2015-07-21 04:24:02 +00:00
if ( unlistedProperties = = null | | unlistedProperties . isEmpty ( ) ) return super . createState ( block , properties , unlistedProperties ) ;
2014-11-27 03:56:35 +00:00
return new ExtendedStateImplementation ( block , properties , unlistedProperties , null ) ;
}
protected static class ExtendedStateImplementation extends StateImplementation implements IExtendedBlockState
{
private final ImmutableMap < IUnlistedProperty < ? > , Optional < ? > > unlistedProperties ;
2016-03-02 17:00:32 +00:00
private Map < Map < IProperty < ? > , Comparable < ? > > , BlockStateContainer . StateImplementation > normalMap ;
2014-11-27 03:56:35 +00:00
2016-03-02 17:00:32 +00:00
protected ExtendedStateImplementation ( Block block , ImmutableMap < IProperty < ? > , Comparable < ? > > properties , ImmutableMap < IUnlistedProperty < ? > , Optional < ? > > unlistedProperties , ImmutableTable < IProperty < ? > , Comparable < ? > , IBlockState > table )
2014-11-27 03:56:35 +00:00
{
super ( block , properties ) ;
this . unlistedProperties = unlistedProperties ;
this . propertyValueTable = table ;
}
@Override
2015-11-09 21:42:56 +00:00
public < T extends Comparable < T > , V extends T > IBlockState withProperty ( IProperty < T > property , V value )
2014-11-27 03:56:35 +00:00
{
if ( ! this . getProperties ( ) . containsKey ( property ) )
{
throw new IllegalArgumentException ( " Cannot set property " + property + " as it does not exist in " + getBlock ( ) . getBlockState ( ) ) ;
}
else
{
2016-03-23 14:34:48 +00:00
if ( ! property . getAllowedValues ( ) . contains ( value ) )
2014-11-27 03:56:35 +00:00
{
2016-05-18 12:11:56 +00:00
throw new IllegalArgumentException ( " Cannot set property " + property + " to " + value + " on block " + Block . REGISTRY . getNameForObject ( getBlock ( ) ) + " , it is not an allowed value " ) ;
2016-03-23 14:34:48 +00:00
} else
{
if ( this . getProperties ( ) . get ( property ) = = value )
{
return this ;
}
Map < IProperty < ? > , Comparable < ? > > map = Maps . newHashMap ( getProperties ( ) ) ;
map . put ( property , value ) ;
if ( Iterables . all ( unlistedProperties . values ( ) , Predicates . < Optional < ? > > equalTo ( Optional . absent ( ) ) ) )
{ // no dynamic properties present, looking up in the normal table
return normalMap . get ( map ) ;
}
ImmutableTable < IProperty < ? > , Comparable < ? > , IBlockState > table = propertyValueTable ;
table = ( ( StateImplementation ) table . get ( property , value ) ) . getPropertyValueTable ( ) ;
return new ExtendedStateImplementation ( getBlock ( ) , ImmutableMap . copyOf ( map ) , unlistedProperties , table ) . setMap ( this . normalMap ) ;
2014-11-27 03:56:35 +00:00
}
}
}
public < V > IExtendedBlockState withProperty ( IUnlistedProperty < V > property , V value )
{
if ( ! this . unlistedProperties . containsKey ( property ) )
{
throw new IllegalArgumentException ( " Cannot set unlisted property " + property + " as it does not exist in " + getBlock ( ) . getBlockState ( ) ) ;
}
if ( ! property . isValid ( value ) )
{
2016-05-18 12:11:56 +00:00
throw new IllegalArgumentException ( " Cannot set unlisted property " + property + " to " + value + " on block " + Block . REGISTRY . getNameForObject ( getBlock ( ) ) + " , it is not an allowed value " ) ;
2014-11-27 03:56:35 +00:00
}
Map < IUnlistedProperty < ? > , Optional < ? > > newMap = new HashMap < IUnlistedProperty < ? > , Optional < ? > > ( unlistedProperties ) ;
newMap . put ( property , Optional . fromNullable ( value ) ) ;
if ( Iterables . all ( newMap . values ( ) , Predicates . < Optional < ? > > equalTo ( Optional . absent ( ) ) ) )
{ // no dynamic properties, lookup normal state
return ( IExtendedBlockState ) normalMap . get ( getProperties ( ) ) ;
}
2015-07-21 04:24:02 +00:00
return new ExtendedStateImplementation ( getBlock ( ) , getProperties ( ) , ImmutableMap . copyOf ( newMap ) , propertyValueTable ) . setMap ( this . normalMap ) ;
2014-11-27 03:56:35 +00:00
}
public Collection < IUnlistedProperty < ? > > getUnlistedNames ( )
{
return Collections . unmodifiableCollection ( unlistedProperties . keySet ( ) ) ;
}
public < V > V getValue ( IUnlistedProperty < V > property )
{
if ( ! this . unlistedProperties . containsKey ( property ) )
{
throw new IllegalArgumentException ( " Cannot get unlisted property " + property + " as it does not exist in " + getBlock ( ) . getBlockState ( ) ) ;
}
return property . getType ( ) . cast ( this . unlistedProperties . get ( property ) . orNull ( ) ) ;
}
public ImmutableMap < IUnlistedProperty < ? > , Optional < ? > > getUnlistedProperties ( )
{
return unlistedProperties ;
}
@Override
2016-03-02 17:00:32 +00:00
public void buildPropertyValueTable ( Map < Map < IProperty < ? > , Comparable < ? > > , BlockStateContainer . StateImplementation > map )
2014-11-27 03:56:35 +00:00
{
this . normalMap = map ;
super . buildPropertyValueTable ( map ) ;
}
2016-03-01 12:58:03 +00:00
2016-03-02 17:00:32 +00:00
private ExtendedStateImplementation setMap ( Map < Map < IProperty < ? > , Comparable < ? > > , BlockStateContainer . StateImplementation > map )
2015-07-21 04:24:02 +00:00
{
this . normalMap = map ;
return this ;
}
2016-03-01 12:58:03 +00:00
2015-07-21 04:24:02 +00:00
public IBlockState getClean ( )
{
return this . normalMap . get ( getProperties ( ) ) ;
}
2014-11-27 03:56:35 +00:00
}
2015-07-28 21:23:34 +00:00
}