Applied-Energistics-2-tiler.../util/item/AEFluidStack.java
AlgorithmX2 ee99dce791 Removed All Incomplete Items From Build.
Fixed Security GUI leaking into other Guis.
Fixed Bug in AE Fluid Stacks.
Fixed Power Drain in Matter Cannon if there is no ammo.
Fixed Not being able to store empty storage cells in Portable Cell.
Fixed Red Background on Upgrade Slots.
2014-02-01 12:13:12 -06:00

346 lines
8.2 KiB
Java

package appeng.util.item;
import java.io.ByteArrayOutputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagByte;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagLong;
import net.minecraft.nbt.NBTTagString;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import appeng.api.config.FuzzyMode;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAETagCompound;
import appeng.util.Platform;
import com.google.common.io.ByteStreams;
public final class AEFluidStack extends AEStack<IAEFluidStack> implements IAEFluidStack, Comparable<AEFluidStack>
{
public int myHash;
Fluid fluid;
protected IAETagCompound tagCompound;
@Override
public IAETagCompound getTagCompound()
{
return tagCompound;
}
@Override
public void add(IAEFluidStack option)
{
if ( option == null )
return;
// if ( priority < ((AEFluidStack) option).priority )
// priority = ((AEFluidStack) option).priority;
incStackSize( option.getStackSize() );
setCountRequestable( getCountRequestable() + option.getCountRequestable() );
setCraftable( isCraftable() || option.isCraftable() );
}
private AEFluidStack(AEFluidStack is) {
fluid = is.fluid;
stackSize = is.stackSize;
// priority = is.priority;
setCraftable( is.isCraftable() );
setCountRequestable( is.getCountRequestable() );
this.myHash = is.myHash;
}
protected AEFluidStack(FluidStack is) {
if ( is == null )
throw new RuntimeException( "Invalid Itemstack." );
fluid = is.getFluid();
if ( fluid == null )
throw new RuntimeException( "Fluid is null." );
stackSize = is.amount;
setCraftable( false );
setCountRequestable( 0 );
myHash = fluid.hashCode() ^ (tagCompound == null ? 0 : System.identityHashCode( tagCompound ));
}
public static AEFluidStack create(Object a)
{
if ( a == null )
return null;
if ( a instanceof AEFluidStack )
((AEFluidStack) a).copy();
if ( a instanceof FluidStack )
return new AEFluidStack( (FluidStack) a );
return null;
}
@Override
public boolean equals(Object ia)
{
if ( ia instanceof AEFluidStack )
{
return ((AEFluidStack) ia).fluid == fluid && tagCompound == ((AEFluidStack) ia).tagCompound;
}
else if ( ia instanceof FluidStack )
{
FluidStack is = (FluidStack) ia;
if ( is.fluidID == this.fluid.getID() )
{
NBTTagCompound ta = (NBTTagCompound) tagCompound;
NBTTagCompound tb = is.tag;
if ( ta == tb )
return true;
if ( (ta == null && tb == null) || (ta != null && ta.hasNoTags() && tb == null) || (tb != null && tb.hasNoTags() && ta == null)
|| (ta != null && ta.hasNoTags() && tb != null && tb.hasNoTags()) )
return true;
if ( (ta == null && tb != null) || (ta != null && tb == null) )
return false;
if ( AESharedNBT.isShared( tb ) )
return ta == tb;
return Platform.NBTEqualityTest( ta, tb );
}
}
return false;
}
@Override
public FluidStack getFluidStack()
{
FluidStack is = new FluidStack( fluid, (int) Math.min( Integer.MAX_VALUE, stackSize ) );
if ( tagCompound != null )
is.tag = tagCompound.getNBTTagCompoundCopy();
return is;
}
@Override
public IAEFluidStack copy()
{
return new AEFluidStack( this );
}
@Override
public void writeToNBT(NBTTagCompound i)
{
/*
* Ugly Yes, but it saves a lot in the memory department.
*/
NBTBase FluidName = i.getTag( "FluidName" );
NBTBase Count = i.getTag( "Count" );
// NBTBase Priority = i.getTag( "Priority" );
NBTBase Cnt = i.getTag( "Cnt" );
NBTBase Req = i.getTag( "Req" );
NBTBase Craft = i.getTag( "Craft" );
if ( FluidName != null && FluidName instanceof NBTTagString )
((NBTTagString) FluidName).data = (String) this.fluid.getName();
else
i.setString( "FluidName", (String) this.fluid.getName() );
// if ( Priority != null && Priority instanceof NBTTagInt )
// ((NBTTagInt) Priority).data = this.priority;
// else
// i.setInteger( "Priority", this.priority );
if ( Count != null && Count instanceof NBTTagByte )
((NBTTagByte) Count).data = (byte) 0;
else
i.setByte( "Count", (byte) 0 );
if ( Cnt != null && Cnt instanceof NBTTagLong )
((NBTTagLong) Cnt).data = this.stackSize;
else
i.setLong( "Cnt", this.stackSize );
if ( Req != null && Req instanceof NBTTagLong )
((NBTTagLong) Req).data = this.stackSize;
else
i.setLong( "Req", this.getCountRequestable() );
if ( Craft != null && Craft instanceof NBTTagByte )
((NBTTagByte) Craft).data = (byte) (this.isCraftable() ? 1 : 0);
else
i.setBoolean( "Craft", this.isCraftable() );
if ( tagCompound != null )
i.setTag( "tag", (NBTTagCompound) tagCompound );
else
i.removeTag( "tag" );
}
public static IAEFluidStack loadFluidStackFromNBT(NBTTagCompound i)
{
ItemStack itemstack = ItemStack.loadItemStackFromNBT( i );
if ( itemstack == null )
return null;
AEFluidStack aeis = AEFluidStack.create( itemstack );
// aeis.priority = i.getInteger( "Priority" );
aeis.stackSize = i.getLong( "Cnt" );
aeis.setCountRequestable( i.getLong( "Req" ) );
aeis.setCraftable( i.getBoolean( "Craft" ) );
return aeis;
}
@Override
public boolean hasTagCompound()
{
return tagCompound != null;
}
@Override
public int hashCode()
{
return myHash;
}
@Override
public int compareTo(AEFluidStack b)
{
int diff = hashCode() - b.hashCode();
return diff > 0 ? 1 : (diff < 0 ? -1 : 0);
}
@Override
void writeIdentity(DataOutputStream i) throws IOException
{
byte[] name = fluid.getName().getBytes( "UTF-8" );
i.writeByte( (byte) name.length );
i.write( name );
}
@Override
void readNBT(DataOutputStream i) throws IOException
{
if ( hasTagCompound() )
{
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
DataOutputStream data = new DataOutputStream( bytes );
CompressedStreamTools.write( (NBTTagCompound) getTagCompound(), data );
byte[] tagBytes = bytes.toByteArray();
int size = tagBytes.length;
i.writeInt( size );
i.write( tagBytes );
}
}
public static IAEFluidStack loadFluidStackFromPacket(DataInputStream data) throws IOException
{
byte mask = data.readByte();
// byte PriorityType = (byte) (mask & 0x03);
byte StackType = (byte) ((mask & 0x0C) >> 2);
byte CountReqType = (byte) ((mask & 0x30) >> 4);
boolean isCraftable = (mask & 0x40) > 0;
boolean hasTagCompound = (mask & 0x80) > 0;
// don't send this...
NBTTagCompound d = new NBTTagCompound();
byte len2 = data.readByte();
byte name[] = new byte[len2];
data.read( name, 0, len2 );
d.setString( "FluidName", new String( name, "UTF-8" ) );
d.setByte( "Count", (byte) 0 );
if ( hasTagCompound )
{
int len = data.readInt();
byte[] bd = new byte[len];
data.readFully( bd );
DataInput di = ByteStreams.newDataInput( bd );
d.setCompoundTag( "tag", CompressedStreamTools.read( di ) );
}
// long priority = getPacketValue( PriorityType, data );
long stackSize = getPacketValue( StackType, data );
long countRequestable = getPacketValue( CountReqType, data );
FluidStack fluidStack = FluidStack.loadFluidStackFromNBT( d );
if ( fluidStack == null )
return null;
AEFluidStack aeis = AEFluidStack.create( fluidStack );
// aeis.priority = (int) priority;
aeis.stackSize = stackSize;
aeis.setCountRequestable( countRequestable );
aeis.setCraftable( isCraftable );
return aeis;
}
@Override
public Fluid getFluid()
{
return fluid;
}
@Override
public IAEFluidStack empty()
{
IAEFluidStack dup = copy();
dup.reset();
return dup;
}
@Override
public boolean fuzzyComparison(Object st, FuzzyMode mode)
{
if ( st instanceof FluidStack )
{
return ((FluidStack) st).getFluid() == getFluid();
}
if ( st instanceof IAEFluidStack )
{
return ((IAEFluidStack) st).getFluid() == getFluid();
}
return false;
}
@Override
public boolean isItem()
{
return false;
}
@Override
public boolean isFluid()
{
return true;
}
@Override
public StorageChannel getChannel()
{
return StorageChannel.FLUIDS;
}
}