Applied-Energistics-2-tiler.../src/main/java/appeng/items/materials/MultiItem.java
2015-09-30 11:34:16 +02:00

461 lines
11 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.materials;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.oredict.OreDictionary;
import appeng.api.config.Upgrades;
import appeng.api.implementations.IUpgradeableHost;
import appeng.api.implementations.items.IItemGroup;
import appeng.api.implementations.items.IStorageComponent;
import appeng.api.implementations.items.IUpgradeModule;
import appeng.api.implementations.tiles.ISegmentedInventory;
import appeng.api.parts.IPartHost;
import appeng.api.parts.SelectedPart;
import appeng.client.ClientHelper;
import appeng.core.AEConfig;
import appeng.core.features.AEFeature;
import appeng.core.features.IStackSrc;
import appeng.core.features.MaterialStackSrc;
import appeng.items.AEBaseItem;
import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
public final class MultiItem extends AEBaseItem implements IStorageComponent, IUpgradeModule
{
public static final int KILO_SCALAR = 1024;
public static MultiItem instance;
private final Map<Integer, MaterialType> dmgToMaterial = new HashMap<Integer, MaterialType>();
public MultiItem()
{
this.setFeature( EnumSet.of( AEFeature.Core ) );
this.setHasSubtypes( true );
instance = this;
}
@Override
public void addCheckedInformation( ItemStack stack, EntityPlayer player, List<String> lines, boolean displayMoreInfo )
{
super.addCheckedInformation( stack, player, lines, displayMoreInfo );
MaterialType mt = this.getTypeByStack( stack );
if( mt == null )
{
return;
}
if( mt == MaterialType.NamePress )
{
NBTTagCompound c = Platform.openNbtData( stack );
lines.add( c.getString( "InscribeName" ) );
}
Upgrades u = this.getType( stack );
if( u != null )
{
List<String> textList = new LinkedList<String>();
for( Entry<ItemStack, Integer> j : u.getSupported().entrySet() )
{
String name = null;
int limit = j.getValue();
if( j.getKey().getItem() instanceof IItemGroup )
{
IItemGroup ig = (IItemGroup) j.getKey().getItem();
String str = ig.getUnlocalizedGroupName( u.getSupported().keySet(), j.getKey() );
if( str != null )
{
name = Platform.gui_localize( str ) + ( limit > 1 ? " (" + limit + ')' : "" );
}
}
if( name == null )
{
name = j.getKey().getDisplayName() + ( limit > 1 ? " (" + limit + ')' : "" );
}
if( !textList.contains( name ) )
{
textList.add( name );
}
}
Pattern p = Pattern.compile( "(\\d+)[^\\d]" );
SlightlyBetterSort s = new SlightlyBetterSort( p );
Collections.sort( textList, s );
lines.addAll( textList );
}
}
@Override
@SideOnly( Side.CLIENT )
public void registerIcons( ClientHelper proxy, String name )
{
for( MaterialType type : MaterialType.values() )
{
if( type != MaterialType.InvalidType )
{
proxy.setIcon( this, type.damageValue, name + "." + type.name() );
}
}
}
public MaterialType getTypeByStack( ItemStack is )
{
if( this.dmgToMaterial.containsKey( is.getItemDamage() ) )
{
return this.dmgToMaterial.get( is.getItemDamage() );
}
return MaterialType.InvalidType;
}
@Override
public Upgrades getType( ItemStack itemstack )
{
switch( this.getTypeByStack( itemstack ) )
{
case CardCapacity:
return Upgrades.CAPACITY;
case CardFuzzy:
return Upgrades.FUZZY;
case CardRedstone:
return Upgrades.REDSTONE;
case CardSpeed:
return Upgrades.SPEED;
case CardInverter:
return Upgrades.INVERTER;
case CardCrafting:
return Upgrades.CRAFTING;
default:
return null;
}
}
public IStackSrc createMaterial( MaterialType mat )
{
Preconditions.checkState( !mat.isRegistered(), "Cannot create the same material twice." );
boolean enabled = true;
for( AEFeature f : mat.getFeature() )
{
enabled = enabled && AEConfig.instance.isFeatureEnabled( f );
}
mat.stackSrc = new MaterialStackSrc( mat );
if( enabled )
{
mat.itemInstance = this;
mat.markReady();
int newMaterialNum = mat.damageValue;
if( this.dmgToMaterial.get( newMaterialNum ) == null )
{
this.dmgToMaterial.put( newMaterialNum, mat );
}
else
{
throw new IllegalStateException( "Meta Overlap detected." );
}
}
return mat.stackSrc;
}
public void makeUnique()
{
for( MaterialType mt : ImmutableSet.copyOf( this.dmgToMaterial.values() ) )
{
if( mt.getOreName() != null )
{
ItemStack replacement = null;
String[] names = mt.getOreName().split( "," );
for( String name : names )
{
if( replacement != null )
{
break;
}
List<ItemStack> options = OreDictionary.getOres( name );
if( options != null && options.size() > 0 )
{
for( ItemStack is : options )
{
if( is != null && is.getItem() != null )
{
replacement = is.copy();
break;
}
}
}
}
if( replacement == null || AEConfig.instance.useAEVersion( mt ) )
{
// continue using the AE2 item.
for( String name : names )
{
OreDictionary.registerOre( name, mt.stack( 1 ) );
}
}
else
{
if( mt.itemInstance == this )
{
this.dmgToMaterial.remove( mt.damageValue );
}
mt.itemInstance = replacement.getItem();
mt.damageValue = replacement.getItemDamage();
}
}
}
}
@Override
public String getUnlocalizedName( ItemStack is )
{
return "item.appliedenergistics2." + this.nameOf( is );
}
@Override
public void getSubItems( Item par1, CreativeTabs par2CreativeTabs, List cList )
{
List<MaterialType> types = Arrays.asList( MaterialType.values() );
Collections.sort( types, new Comparator<MaterialType>()
{
@Override
public int compare( MaterialType o1, MaterialType o2 )
{
return o1.name().compareTo( o2.name() );
}
} );
for( MaterialType mat : types )
{
if( mat.damageValue >= 0 && mat.isRegistered() && mat.itemInstance == this )
{
cList.add( new ItemStack( this, 1, mat.damageValue ) );
}
}
}
@Override
public boolean onItemUseFirst( ItemStack is, EntityPlayer player, World world, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ )
{
if( player.isSneaking() )
{
TileEntity te = world.getTileEntity( pos );
IInventory upgrades = null;
if( te instanceof IPartHost )
{
SelectedPart sp = ( (IPartHost) te ).selectPart( new Vec3( hitX, hitY, hitZ ) );
if( sp.part instanceof IUpgradeableHost )
{
upgrades = ( (ISegmentedInventory) sp.part ).getInventoryByName( "upgrades" );
}
}
else if( te instanceof IUpgradeableHost )
{
upgrades = ( (ISegmentedInventory) te ).getInventoryByName( "upgrades" );
}
if( upgrades != null && is != null && is.getItem() instanceof IUpgradeModule )
{
IUpgradeModule um = (IUpgradeModule) is.getItem();
Upgrades u = um.getType( is );
if( u != null )
{
InventoryAdaptor ad = InventoryAdaptor.getAdaptor( upgrades, EnumFacing.UP );
if( ad != null )
{
if( player.worldObj.isRemote )
{
return false;
}
player.inventory.setInventorySlotContents( player.inventory.currentItem, ad.addItems( is ) );
return true;
}
}
}
}
return super.onItemUseFirst( is, player, world, pos, side, hitX, hitY, hitZ );
}
@Override
public boolean hasCustomEntity( ItemStack is )
{
return this.getTypeByStack( is ).hasCustomEntity();
}
@Override
public Entity createEntity( World w, Entity location, ItemStack itemstack )
{
Class<? extends Entity> droppedEntity = this.getTypeByStack( itemstack ).getCustomEntityClass();
Entity eqi;
try
{
eqi = droppedEntity.getConstructor( World.class, double.class, double.class, double.class, ItemStack.class ).newInstance( w, location.posX, location.posY, location.posZ, itemstack );
}
catch( Throwable t )
{
throw new IllegalStateException( t );
}
eqi.motionX = location.motionX;
eqi.motionY = location.motionY;
eqi.motionZ = location.motionZ;
if( location instanceof EntityItem && eqi instanceof EntityItem )
{
// TODO: Entity Pick up time?
// needs fixing?
// ( (EntityItem) eqi ).setPickupDelay( ( (EntityItem) location ).pick;
}
return eqi;
}
private String nameOf( ItemStack is )
{
if( is == null )
{
return "null";
}
MaterialType mt = this.getTypeByStack( is );
if( mt == null )
{
return "null";
}
return mt.name();
}
@Override
public int getBytes( ItemStack is )
{
switch( this.getTypeByStack( is ) )
{
case Cell1kPart:
return KILO_SCALAR;
case Cell4kPart:
return KILO_SCALAR * 4;
case Cell16kPart:
return KILO_SCALAR * 16;
case Cell64kPart:
return KILO_SCALAR * 64;
default:
}
return 0;
}
@Override
public boolean isStorageComponent( ItemStack is )
{
switch( this.getTypeByStack( is ) )
{
case Cell1kPart:
case Cell4kPart:
case Cell16kPart:
case Cell64kPart:
return true;
default:
}
return false;
}
private static class SlightlyBetterSort implements Comparator<String>
{
private final Pattern pattern;
public SlightlyBetterSort( Pattern pattern )
{
this.pattern = pattern;
}
@Override
public int compare( String o1, String o2 )
{
try
{
Matcher a = this.pattern.matcher( o1 );
Matcher b = this.pattern.matcher( o2 );
if( a.find() && b.find() )
{
int ia = Integer.parseInt( a.group( 1 ) );
int ib = Integer.parseInt( b.group( 1 ) );
return Integer.compare( ia, ib );
}
}
catch( Throwable t )
{
// ek!
}
return o1.compareTo( o2 );
}
}
}