Fixes #1339: Was not able to retrieve the name of an unregistered part
Added an additional map to store all parts and be able to access them if needed. Added public preconditions Added private asserts Excluded public overridden methods, since behaviour can be unexpected
This commit is contained in:
@@ -3,8 +3,6 @@ package appeng.core.api.definitions;
|
|||||||
|
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
|
|
||||||
import com.google.common.base.Optional;
|
|
||||||
|
|
||||||
import appeng.api.definitions.IBlockDefinition;
|
import appeng.api.definitions.IBlockDefinition;
|
||||||
import appeng.api.definitions.IItemDefinition;
|
import appeng.api.definitions.IItemDefinition;
|
||||||
import appeng.api.definitions.ITileDefinition;
|
import appeng.api.definitions.ITileDefinition;
|
||||||
@@ -91,13 +89,9 @@ public class DefinitionConstructor
|
|||||||
|
|
||||||
for( AEColor color : AEColor.values() )
|
for( AEColor color : AEColor.values() )
|
||||||
{
|
{
|
||||||
ItemStackSrc multiPartSource = target.createPart( type, color );
|
final ItemStackSrc multiPartSource = target.createPart( type, color );
|
||||||
final Optional<ItemStackSrc> maybeSource = Optional.fromNullable( multiPartSource );
|
|
||||||
|
|
||||||
if( maybeSource.isPresent() )
|
definition.add( color, multiPartSource );
|
||||||
{
|
|
||||||
definition.add( color, multiPartSource );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return definition;
|
return definition;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
package appeng.items.parts;
|
package appeng.items.parts;
|
||||||
|
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
@@ -28,6 +29,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.texture.IIconRegister;
|
import net.minecraft.client.renderer.texture.IIconRegister;
|
||||||
@@ -41,6 +43,8 @@ import net.minecraft.world.World;
|
|||||||
import cpw.mods.fml.relauncher.Side;
|
import cpw.mods.fml.relauncher.Side;
|
||||||
import cpw.mods.fml.relauncher.SideOnly;
|
import cpw.mods.fml.relauncher.SideOnly;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
|
||||||
import appeng.api.AEApi;
|
import appeng.api.AEApi;
|
||||||
import appeng.api.implementations.items.IItemGroup;
|
import appeng.api.implementations.items.IItemGroup;
|
||||||
import appeng.api.parts.IPart;
|
import appeng.api.parts.IPart;
|
||||||
@@ -48,7 +52,6 @@ import appeng.api.parts.IPartHelper;
|
|||||||
import appeng.api.parts.IPartItem;
|
import appeng.api.parts.IPartItem;
|
||||||
import appeng.api.util.AEColor;
|
import appeng.api.util.AEColor;
|
||||||
import appeng.core.AEConfig;
|
import appeng.core.AEConfig;
|
||||||
import appeng.core.AELog;
|
|
||||||
import appeng.core.features.AEFeature;
|
import appeng.core.features.AEFeature;
|
||||||
import appeng.core.features.ItemStackSrc;
|
import appeng.core.features.ItemStackSrc;
|
||||||
import appeng.core.features.NameResolver;
|
import appeng.core.features.NameResolver;
|
||||||
@@ -58,27 +61,55 @@ import appeng.integration.IntegrationType;
|
|||||||
import appeng.items.AEBaseItem;
|
import appeng.items.AEBaseItem;
|
||||||
|
|
||||||
|
|
||||||
public class ItemMultiPart extends AEBaseItem implements IPartItem, IItemGroup
|
public final class ItemMultiPart extends AEBaseItem implements IPartItem, IItemGroup
|
||||||
{
|
{
|
||||||
public static ItemMultiPart instance;
|
public static ItemMultiPart instance;
|
||||||
private final NameResolver nameResolver;
|
private final NameResolver nameResolver;
|
||||||
private final Map<Integer, PartTypeIst> dmgToPart = new HashMap<Integer, PartTypeIst>();
|
private final Map<Integer, PartTypeWithVariant> registered;
|
||||||
|
private final Map<Integer, PartTypeWithVariant> unregistered;
|
||||||
|
|
||||||
public ItemMultiPart( IPartHelper partHelper )
|
public ItemMultiPart( IPartHelper partHelper )
|
||||||
{
|
{
|
||||||
|
Preconditions.checkNotNull( partHelper );
|
||||||
|
|
||||||
|
this.registered = new HashMap<Integer, PartTypeWithVariant>();
|
||||||
|
this.unregistered = new HashMap<Integer, PartTypeWithVariant>();
|
||||||
|
|
||||||
this.nameResolver = new NameResolver( this.getClass() );
|
this.nameResolver = new NameResolver( this.getClass() );
|
||||||
this.setFeature( EnumSet.of( AEFeature.Core ) );
|
this.setFeature( EnumSet.of( AEFeature.Core ) );
|
||||||
partHelper.setItemBusRenderer( this );
|
partHelper.setItemBusRenderer( this );
|
||||||
this.setHasSubtypes( true );
|
this.setHasSubtypes( true );
|
||||||
|
|
||||||
instance = this;
|
instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public final ItemStackSrc createPart( PartType mat )
|
public final ItemStackSrc createPart( PartType mat )
|
||||||
{
|
{
|
||||||
int varID = 0;
|
Preconditions.checkNotNull( mat );
|
||||||
|
|
||||||
|
return this.createPart( mat, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public ItemStackSrc createPart( PartType mat, AEColor color )
|
||||||
|
{
|
||||||
|
Preconditions.checkNotNull( mat );
|
||||||
|
Preconditions.checkNotNull( color );
|
||||||
|
|
||||||
|
final int varID = color.ordinal();
|
||||||
|
|
||||||
|
return this.createPart( mat, varID );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private ItemStackSrc createPart( PartType mat, int varID )
|
||||||
|
{
|
||||||
|
assert mat != null;
|
||||||
|
assert varID >= 0;
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
for( PartTypeIst p : this.dmgToPart.values() )
|
for( PartTypeWithVariant p : this.registered.values() )
|
||||||
{
|
{
|
||||||
if( p.part == mat && p.variant == varID )
|
if( p.part == mat && p.variant == varID )
|
||||||
throw new IllegalStateException( "Cannot create the same material twice..." );
|
throw new IllegalStateException( "Cannot create the same material twice..." );
|
||||||
@@ -91,81 +122,34 @@ public class ItemMultiPart extends AEBaseItem implements IPartItem, IItemGroup
|
|||||||
for( IntegrationType integrationType : mat.getIntegrations() )
|
for( IntegrationType integrationType : mat.getIntegrations() )
|
||||||
enabled &= IntegrationRegistry.INSTANCE.isEnabled( integrationType );
|
enabled &= IntegrationRegistry.INSTANCE.isEnabled( integrationType );
|
||||||
|
|
||||||
int newPartNum = mat.baseDamage + varID;
|
final int partDamage = mat.baseDamage + varID;
|
||||||
ItemStackSrc output = new ItemStackSrc( this, newPartNum );
|
final ItemStackSrc output = new ItemStackSrc( this, partDamage );
|
||||||
|
|
||||||
if( enabled )
|
final PartTypeWithVariant pti = new PartTypeWithVariant( mat, varID );
|
||||||
{
|
|
||||||
PartTypeIst pti = new PartTypeIst();
|
|
||||||
pti.part = mat;
|
|
||||||
pti.variant = varID;
|
|
||||||
|
|
||||||
if( this.dmgToPart.get( newPartNum ) == null )
|
this.processMetaOverlap( enabled, partDamage, mat, pti );
|
||||||
{
|
|
||||||
this.dmgToPart.put( newPartNum, pti );
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new IllegalStateException( "Meta Overlap detected." );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemStackSrc createPart( PartType mat, Enum variant )
|
private void processMetaOverlap( boolean enabled, int partDamage, PartType mat, PartTypeWithVariant pti )
|
||||||
{
|
{
|
||||||
try
|
assert partDamage >= 0;
|
||||||
{
|
assert mat != null;
|
||||||
// I think this still works?
|
assert pti != null;
|
||||||
ItemStack is = new ItemStack( this );
|
|
||||||
mat.getPart().getConstructor( ItemStack.class ).newInstance( is );
|
|
||||||
}
|
|
||||||
catch( Throwable e )
|
|
||||||
{
|
|
||||||
AELog.integration( e );
|
|
||||||
e.printStackTrace();
|
|
||||||
return null; // part not supported..
|
|
||||||
}
|
|
||||||
|
|
||||||
int varID = variant == null ? 0 : variant.ordinal();
|
final Map<Integer, PartTypeWithVariant> reference = ( enabled ) ? this.registered : this.unregistered;
|
||||||
|
if( reference.containsKey( partDamage ) )
|
||||||
|
throw new IllegalStateException( "Meta Overlap detected with type " + mat + " and damage " + partDamage + ". Found " + reference.get( partDamage ) + " there already." );
|
||||||
|
|
||||||
// verify
|
reference.put( partDamage, pti );
|
||||||
for( PartTypeIst p : this.dmgToPart.values() )
|
|
||||||
{
|
|
||||||
if( p.part == mat && p.variant == varID )
|
|
||||||
throw new IllegalStateException( "Cannot create the same material twice..." );
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean enabled = true;
|
|
||||||
for( AEFeature f : mat.getFeature() )
|
|
||||||
enabled = enabled && AEConfig.instance.isFeatureEnabled( f );
|
|
||||||
|
|
||||||
if( enabled )
|
|
||||||
{
|
|
||||||
int newPartNum = mat.baseDamage + varID;
|
|
||||||
ItemStackSrc output = new ItemStackSrc( this, newPartNum );
|
|
||||||
|
|
||||||
PartTypeIst pti = new PartTypeIst();
|
|
||||||
pti.part = mat;
|
|
||||||
pti.variant = varID;
|
|
||||||
|
|
||||||
if( this.dmgToPart.get( newPartNum ) == null )
|
|
||||||
{
|
|
||||||
this.dmgToPart.put( newPartNum, pti );
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throw new IllegalStateException( "Meta Overlap detected." );
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getDamageByType( PartType t )
|
public int getDamageByType( PartType t )
|
||||||
{
|
{
|
||||||
for( Entry<Integer, PartTypeIst> pt : this.dmgToPart.entrySet() )
|
Preconditions.checkNotNull( t );
|
||||||
|
|
||||||
|
for( Entry<Integer, PartTypeWithVariant> pt : this.registered.entrySet() )
|
||||||
{
|
{
|
||||||
if( pt.getValue().part == t )
|
if( pt.getValue().part == t )
|
||||||
return pt.getKey();
|
return pt.getKey();
|
||||||
@@ -183,7 +167,7 @@ public class ItemMultiPart extends AEBaseItem implements IPartItem, IItemGroup
|
|||||||
@Override
|
@Override
|
||||||
public IIcon getIconFromDamage( int dmg )
|
public IIcon getIconFromDamage( int dmg )
|
||||||
{
|
{
|
||||||
return this.dmgToPart.get( dmg ).ico;
|
return this.registered.get( dmg ).ico;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -198,36 +182,16 @@ public class ItemMultiPart extends AEBaseItem implements IPartItem, IItemGroup
|
|||||||
return "item.appliedenergistics2." + this.getName( is );
|
return "item.appliedenergistics2." + this.getName( is );
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName( ItemStack is )
|
|
||||||
{
|
|
||||||
return this.nameResolver.getName( this.getTypeByStack( is ).name() );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public PartType getTypeByStack( ItemStack is )
|
|
||||||
{
|
|
||||||
if( is == null )
|
|
||||||
return null;
|
|
||||||
|
|
||||||
PartTypeIst pt = this.dmgToPart.get( is.getItemDamage() );
|
|
||||||
if( pt != null )
|
|
||||||
return pt.part;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getItemStackDisplayName( ItemStack is )
|
public String getItemStackDisplayName( ItemStack is )
|
||||||
{
|
{
|
||||||
PartType pt = this.getTypeByStack( is );
|
final PartType pt = this.getTypeByStack( is );
|
||||||
if( pt == null )
|
|
||||||
return "Unnamed";
|
|
||||||
|
|
||||||
if( pt.isCable() )
|
if( pt.isCable() )
|
||||||
{
|
{
|
||||||
final AEColor[] variants = AEColor.values();
|
final AEColor[] variants = AEColor.values();
|
||||||
|
|
||||||
return super.getItemStackDisplayName( is ) + " - " + variants[this.dmgToPart.get( is.getItemDamage() ).variant].toString();
|
return super.getItemStackDisplayName( is ) + " - " + variants[this.registered.get( is.getItemDamage() ).variant].toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pt.getExtraName() != null )
|
if( pt.getExtraName() != null )
|
||||||
@@ -239,60 +203,96 @@ public class ItemMultiPart extends AEBaseItem implements IPartItem, IItemGroup
|
|||||||
@Override
|
@Override
|
||||||
public void getSubItems( Item number, CreativeTabs tab, List cList )
|
public void getSubItems( Item number, CreativeTabs tab, List cList )
|
||||||
{
|
{
|
||||||
List<Entry<Integer, PartTypeIst>> types = new ArrayList<Entry<Integer, PartTypeIst>>( this.dmgToPart.entrySet() );
|
List<Entry<Integer, PartTypeWithVariant>> types = new ArrayList<Entry<Integer, PartTypeWithVariant>>( this.registered.entrySet() );
|
||||||
Collections.sort( types, new Comparator<Entry<Integer, PartTypeIst>>()
|
Collections.sort( types, new Comparator<Entry<Integer, PartTypeWithVariant>>()
|
||||||
{
|
{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compare( Entry<Integer, PartTypeIst> o1, Entry<Integer, PartTypeIst> o2 )
|
public int compare( Entry<Integer, PartTypeWithVariant> o1, Entry<Integer, PartTypeWithVariant> o2 )
|
||||||
{
|
{
|
||||||
return o1.getValue().part.name().compareTo( o2.getValue().part.name() );
|
return o1.getValue().part.name().compareTo( o2.getValue().part.name() );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
for( Entry<Integer, PartTypeIst> part : types )
|
for( Entry<Integer, PartTypeWithVariant> part : types )
|
||||||
cList.add( new ItemStack( this, 1, part.getKey() ) );
|
cList.add( new ItemStack( this, 1, part.getKey() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerIcons( IIconRegister par1IconRegister )
|
public void registerIcons( IIconRegister par1IconRegister )
|
||||||
{
|
{
|
||||||
for( Entry<Integer, PartTypeIst> part : this.dmgToPart.entrySet() )
|
for( Entry<Integer, PartTypeWithVariant> part : this.registered.entrySet() )
|
||||||
{
|
{
|
||||||
String tex = "appliedenergistics2:" + this.getName( new ItemStack( this, 1, part.getKey() ) );
|
String tex = "appliedenergistics2:" + this.getName( new ItemStack( this, 1, part.getKey() ) );
|
||||||
part.getValue().ico = par1IconRegister.registerIcon( tex );
|
part.getValue().ico = par1IconRegister.registerIcon( tex );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getName( ItemStack is )
|
||||||
|
{
|
||||||
|
Preconditions.checkNotNull( is );
|
||||||
|
|
||||||
|
final PartType stackType = this.getTypeByStack( is );
|
||||||
|
final String typeName = stackType.name();
|
||||||
|
|
||||||
|
return this.nameResolver.getName( typeName );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public PartType getTypeByStack( ItemStack is )
|
||||||
|
{
|
||||||
|
Preconditions.checkNotNull( is );
|
||||||
|
|
||||||
|
final PartTypeWithVariant pt = this.registered.get( is.getItemDamage() );
|
||||||
|
if( pt != null )
|
||||||
|
return pt.part;
|
||||||
|
final PartTypeWithVariant unregisteredPartType = this.unregistered.get( is.getItemDamage() );
|
||||||
|
if( unregisteredPartType != null )
|
||||||
|
return unregisteredPartType.part;
|
||||||
|
|
||||||
|
throw new IllegalStateException( "ItemStack " + is + " has to be either registered or unregistered, but was not found in either." );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public IPart createPartFromItemStack( ItemStack is )
|
public IPart createPartFromItemStack( ItemStack is )
|
||||||
{
|
{
|
||||||
|
final PartType type = this.getTypeByStack( is );
|
||||||
|
final Class<? extends IPart> part = type.getPart();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
PartType t = this.getTypeByStack( is );
|
if( type.constructor == null )
|
||||||
if( t != null )
|
type.constructor = part.getConstructor( ItemStack.class );
|
||||||
{
|
|
||||||
if( t.constructor == null )
|
|
||||||
t.constructor = t.getPart().getConstructor( ItemStack.class );
|
|
||||||
|
|
||||||
return t.constructor.newInstance( is );
|
return type.constructor.newInstance( is );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch( Throwable e )
|
catch( InstantiationException e )
|
||||||
{
|
{
|
||||||
throw new IllegalStateException( "Unable to construct IBusPart from IBusItem : " + this.getTypeByStack( is ).getPart().getName() + " ; Possibly didn't have correct constructor( ItemStack )", e );
|
throw new IllegalStateException( "Unable to construct IBusPart from IBusItem : " + part.getName() + " ; Possibly didn't have correct constructor( ItemStack )", e );
|
||||||
|
}
|
||||||
|
catch( IllegalAccessException e )
|
||||||
|
{
|
||||||
|
throw new IllegalStateException( "Unable to construct IBusPart from IBusItem : " + part.getName() + " ; Possibly didn't have correct constructor( ItemStack )", e );
|
||||||
|
}
|
||||||
|
catch( InvocationTargetException e )
|
||||||
|
{
|
||||||
|
throw new IllegalStateException( "Unable to construct IBusPart from IBusItem : " + part.getName() + " ; Possibly didn't have correct constructor( ItemStack )", e );
|
||||||
|
}
|
||||||
|
catch( NoSuchMethodException e )
|
||||||
|
{
|
||||||
|
throw new IllegalStateException( "Unable to construct IBusPart from IBusItem : " + part.getName() + " ; Possibly didn't have correct constructor( ItemStack )", e );
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int variantOf( int itemDamage )
|
public int variantOf( int itemDamage )
|
||||||
{
|
{
|
||||||
if( this.dmgToPart.containsKey( itemDamage ) )
|
if( this.registered.containsKey( itemDamage ) )
|
||||||
return this.dmgToPart.get( itemDamage ).variant;
|
return this.registered.get( itemDamage ).variant;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public String getUnlocalizedGroupName( Set<ItemStack> others, ItemStack is )
|
public String getUnlocalizedGroupName( Set<ItemStack> others, ItemStack is )
|
||||||
{
|
{
|
||||||
@@ -307,22 +307,19 @@ public class ItemMultiPart extends AEBaseItem implements IPartItem, IItemGroup
|
|||||||
if( stack.getItem() == this )
|
if( stack.getItem() == this )
|
||||||
{
|
{
|
||||||
PartType pt = this.getTypeByStack( stack );
|
PartType pt = this.getTypeByStack( stack );
|
||||||
if ( pt != null )
|
switch( pt )
|
||||||
{
|
{
|
||||||
switch( pt )
|
case ImportBus:
|
||||||
{
|
importBus = true;
|
||||||
case ImportBus:
|
if( u == pt )
|
||||||
importBus = true;
|
group = true;
|
||||||
if( u == pt )
|
break;
|
||||||
group = true;
|
case ExportBus:
|
||||||
break;
|
exportBus = true;
|
||||||
case ExportBus:
|
if( u == pt )
|
||||||
exportBus = true;
|
group = true;
|
||||||
if( u == pt )
|
break;
|
||||||
group = true;
|
default:
|
||||||
break;
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -333,17 +330,21 @@ public class ItemMultiPart extends AEBaseItem implements IPartItem, IItemGroup
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemStack getStackFromTypeAndVariant( PartType mt, int variant )
|
private static final class PartTypeWithVariant
|
||||||
{
|
{
|
||||||
return new ItemStack( this, 1, mt.baseDamage + variant );
|
private final PartType part;
|
||||||
}
|
private final int variant;
|
||||||
|
|
||||||
private static class PartTypeIst
|
|
||||||
{
|
|
||||||
private PartType part;
|
|
||||||
private int variant;
|
|
||||||
|
|
||||||
@SideOnly( Side.CLIENT )
|
@SideOnly( Side.CLIENT )
|
||||||
private IIcon ico;
|
private IIcon ico;
|
||||||
|
|
||||||
|
private PartTypeWithVariant( PartType part, int variant )
|
||||||
|
{
|
||||||
|
assert part != null;
|
||||||
|
assert variant >= 0;
|
||||||
|
|
||||||
|
this.part = part;
|
||||||
|
this.variant = variant;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user