e85acf2bee
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
351 lines
9.8 KiB
Java
351 lines
9.8 KiB
Java
/*
|
|
* This file is part of Applied Energistics 2.
|
|
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
|
*
|
|
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
|
*/
|
|
|
|
package appeng.items.parts;
|
|
|
|
|
|
import java.lang.reflect.InvocationTargetException;
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.Comparator;
|
|
import java.util.EnumSet;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Map.Entry;
|
|
import java.util.Set;
|
|
import javax.annotation.Nonnull;
|
|
import javax.annotation.Nullable;
|
|
|
|
import net.minecraft.client.renderer.texture.IIconRegister;
|
|
import net.minecraft.creativetab.CreativeTabs;
|
|
import net.minecraft.entity.player.EntityPlayer;
|
|
import net.minecraft.item.Item;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.util.IIcon;
|
|
import net.minecraft.world.World;
|
|
|
|
import cpw.mods.fml.relauncher.Side;
|
|
import cpw.mods.fml.relauncher.SideOnly;
|
|
|
|
import com.google.common.base.Preconditions;
|
|
|
|
import appeng.api.AEApi;
|
|
import appeng.api.implementations.items.IItemGroup;
|
|
import appeng.api.parts.IPart;
|
|
import appeng.api.parts.IPartHelper;
|
|
import appeng.api.parts.IPartItem;
|
|
import appeng.api.util.AEColor;
|
|
import appeng.core.AEConfig;
|
|
import appeng.core.features.AEFeature;
|
|
import appeng.core.features.ItemStackSrc;
|
|
import appeng.core.features.NameResolver;
|
|
import appeng.core.localization.GuiText;
|
|
import appeng.integration.IntegrationRegistry;
|
|
import appeng.integration.IntegrationType;
|
|
import appeng.items.AEBaseItem;
|
|
|
|
|
|
public final class ItemMultiPart extends AEBaseItem implements IPartItem, IItemGroup
|
|
{
|
|
public static ItemMultiPart instance;
|
|
private final NameResolver nameResolver;
|
|
private final Map<Integer, PartTypeWithVariant> registered;
|
|
private final Map<Integer, PartTypeWithVariant> unregistered;
|
|
|
|
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.setFeature( EnumSet.of( AEFeature.Core ) );
|
|
partHelper.setItemBusRenderer( this );
|
|
this.setHasSubtypes( true );
|
|
|
|
instance = this;
|
|
}
|
|
|
|
@Nonnull
|
|
public final ItemStackSrc createPart( PartType mat )
|
|
{
|
|
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
|
|
for( PartTypeWithVariant p : this.registered.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 );
|
|
|
|
for( IntegrationType integrationType : mat.getIntegrations() )
|
|
enabled &= IntegrationRegistry.INSTANCE.isEnabled( integrationType );
|
|
|
|
final int partDamage = mat.baseDamage + varID;
|
|
final ItemStackSrc output = new ItemStackSrc( this, partDamage );
|
|
|
|
final PartTypeWithVariant pti = new PartTypeWithVariant( mat, varID );
|
|
|
|
this.processMetaOverlap( enabled, partDamage, mat, pti );
|
|
|
|
return output;
|
|
}
|
|
|
|
private void processMetaOverlap( boolean enabled, int partDamage, PartType mat, PartTypeWithVariant pti )
|
|
{
|
|
assert partDamage >= 0;
|
|
assert mat != null;
|
|
assert pti != null;
|
|
|
|
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." );
|
|
|
|
reference.put( partDamage, pti );
|
|
}
|
|
|
|
public int getDamageByType( PartType t )
|
|
{
|
|
Preconditions.checkNotNull( t );
|
|
|
|
for( Entry<Integer, PartTypeWithVariant> pt : this.registered.entrySet() )
|
|
{
|
|
if( pt.getValue().part == t )
|
|
return pt.getKey();
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
@Override
|
|
@SideOnly( Side.CLIENT )
|
|
public int getSpriteNumber()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public IIcon getIconFromDamage( int dmg )
|
|
{
|
|
return this.registered.get( dmg ).ico;
|
|
}
|
|
|
|
@Override
|
|
public boolean onItemUse( ItemStack is, EntityPlayer player, World w, int x, int y, int z, int side, float hitX, float hitY, float hitZ )
|
|
{
|
|
return AEApi.instance().partHelper().placeBus( is, x, y, z, side, player, w );
|
|
}
|
|
|
|
@Override
|
|
public String getUnlocalizedName( ItemStack is )
|
|
{
|
|
return "item.appliedenergistics2." + this.getName( is );
|
|
}
|
|
|
|
@Override
|
|
public String getItemStackDisplayName( ItemStack is )
|
|
{
|
|
final PartType pt = this.getTypeByStack( is );
|
|
|
|
if( pt.isCable() )
|
|
{
|
|
final AEColor[] variants = AEColor.values();
|
|
|
|
return super.getItemStackDisplayName( is ) + " - " + variants[this.registered.get( is.getItemDamage() ).variant].toString();
|
|
}
|
|
|
|
if( pt.getExtraName() != null )
|
|
return super.getItemStackDisplayName( is ) + " - " + pt.getExtraName().getLocal();
|
|
|
|
return super.getItemStackDisplayName( is );
|
|
}
|
|
|
|
@Override
|
|
public void getSubItems( Item number, CreativeTabs tab, List cList )
|
|
{
|
|
List<Entry<Integer, PartTypeWithVariant>> types = new ArrayList<Entry<Integer, PartTypeWithVariant>>( this.registered.entrySet() );
|
|
Collections.sort( types, new Comparator<Entry<Integer, PartTypeWithVariant>>()
|
|
{
|
|
|
|
@Override
|
|
public int compare( Entry<Integer, PartTypeWithVariant> o1, Entry<Integer, PartTypeWithVariant> o2 )
|
|
{
|
|
return o1.getValue().part.name().compareTo( o2.getValue().part.name() );
|
|
}
|
|
} );
|
|
|
|
for( Entry<Integer, PartTypeWithVariant> part : types )
|
|
cList.add( new ItemStack( this, 1, part.getKey() ) );
|
|
}
|
|
|
|
@Override
|
|
public void registerIcons( IIconRegister par1IconRegister )
|
|
{
|
|
for( Entry<Integer, PartTypeWithVariant> part : this.registered.entrySet() )
|
|
{
|
|
String tex = "appliedenergistics2:" + this.getName( new ItemStack( this, 1, part.getKey() ) );
|
|
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
|
|
public IPart createPartFromItemStack( ItemStack is )
|
|
{
|
|
final PartType type = this.getTypeByStack( is );
|
|
final Class<? extends IPart> part = type.getPart();
|
|
|
|
try
|
|
{
|
|
if( type.constructor == null )
|
|
type.constructor = part.getConstructor( ItemStack.class );
|
|
|
|
return type.constructor.newInstance( is );
|
|
}
|
|
catch( InstantiationException 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 );
|
|
}
|
|
}
|
|
|
|
public int variantOf( int itemDamage )
|
|
{
|
|
if( this.registered.containsKey( itemDamage ) )
|
|
return this.registered.get( itemDamage ).variant;
|
|
return 0;
|
|
}
|
|
|
|
@Nullable
|
|
@Override
|
|
public String getUnlocalizedGroupName( Set<ItemStack> others, ItemStack is )
|
|
{
|
|
boolean importBus = false;
|
|
boolean exportBus = false;
|
|
boolean group = false;
|
|
|
|
PartType u = this.getTypeByStack( is );
|
|
|
|
for( ItemStack stack : others )
|
|
{
|
|
if( stack.getItem() == this )
|
|
{
|
|
PartType pt = this.getTypeByStack( stack );
|
|
switch( pt )
|
|
{
|
|
case ImportBus:
|
|
importBus = true;
|
|
if( u == pt )
|
|
group = true;
|
|
break;
|
|
case ExportBus:
|
|
exportBus = true;
|
|
if( u == pt )
|
|
group = true;
|
|
break;
|
|
default:
|
|
}
|
|
}
|
|
}
|
|
|
|
if( group && importBus && exportBus )
|
|
return GuiText.IOBuses.getUnlocalized();
|
|
|
|
return null;
|
|
}
|
|
|
|
private static final class PartTypeWithVariant
|
|
{
|
|
private final PartType part;
|
|
private final int variant;
|
|
|
|
@SideOnly( Side.CLIENT )
|
|
private IIcon ico;
|
|
|
|
private PartTypeWithVariant( PartType part, int variant )
|
|
{
|
|
assert part != null;
|
|
assert variant >= 0;
|
|
|
|
this.part = part;
|
|
this.variant = variant;
|
|
}
|
|
}
|
|
}
|