1e20086799
* Extracts item comparison from Platform into their own helper. Renamed methods to be more more fitting for the actual comparison. Added documentation about each methods behaviour.
415 lines
10 KiB
Java
415 lines
10 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.tile.misc;
|
|
|
|
|
|
import javax.annotation.Nullable;
|
|
|
|
import net.minecraft.inventory.IInventory;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
import net.minecraft.util.EnumFacing;
|
|
import net.minecraftforge.common.capabilities.Capability;
|
|
import net.minecraftforge.fluids.FluidStack;
|
|
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
|
import net.minecraftforge.fluids.capability.FluidTankProperties;
|
|
import net.minecraftforge.fluids.capability.IFluidHandler;
|
|
import net.minecraftforge.fluids.capability.IFluidTankProperties;
|
|
import net.minecraftforge.items.CapabilityItemHandler;
|
|
import net.minecraftforge.items.IItemHandler;
|
|
|
|
import appeng.api.AEApi;
|
|
import appeng.api.config.CondenserOutput;
|
|
import appeng.api.config.Settings;
|
|
import appeng.api.definitions.IMaterials;
|
|
import appeng.api.implementations.items.IStorageComponent;
|
|
import appeng.api.networking.security.BaseActionSource;
|
|
import appeng.api.storage.IMEMonitor;
|
|
import appeng.api.storage.IStorageMonitorable;
|
|
import appeng.api.storage.IStorageMonitorableAccessor;
|
|
import appeng.api.storage.data.IAEFluidStack;
|
|
import appeng.api.storage.data.IAEItemStack;
|
|
import appeng.api.util.IConfigManager;
|
|
import appeng.api.util.IConfigurableObject;
|
|
import appeng.capabilities.Capabilities;
|
|
import appeng.tile.AEBaseInvTile;
|
|
import appeng.tile.TileEvent;
|
|
import appeng.tile.events.TileEventType;
|
|
import appeng.tile.inventory.AppEngInternalInventory;
|
|
import appeng.tile.inventory.InvOperation;
|
|
import appeng.util.ConfigManager;
|
|
import appeng.util.IConfigManagerHost;
|
|
import appeng.util.Platform;
|
|
|
|
|
|
public class TileCondenser extends AEBaseInvTile implements IConfigManagerHost, IConfigurableObject
|
|
{
|
|
|
|
public static final int BYTE_MULTIPLIER = 8;
|
|
|
|
private final int[] sides = {
|
|
0,
|
|
1
|
|
};
|
|
private final AppEngInternalInventory inv = new AppEngInternalInventory( this, 3 );
|
|
private final ConfigManager cm = new ConfigManager( this );
|
|
private final IItemHandler itemHandler = new ItemHandler();
|
|
private final IFluidHandler fluidHandler = new FluidHandler();
|
|
private final MEHandler meHandler = new MEHandler();
|
|
|
|
private double storedPower = 0;
|
|
|
|
public TileCondenser()
|
|
{
|
|
this.cm.registerSetting( Settings.CONDENSER_OUTPUT, CondenserOutput.TRASH );
|
|
}
|
|
|
|
@TileEvent( TileEventType.WORLD_NBT_WRITE )
|
|
public void writeToNBT_TileCondenser( final NBTTagCompound data )
|
|
{
|
|
this.cm.writeToNBT( data );
|
|
data.setDouble( "storedPower", this.getStoredPower() );
|
|
}
|
|
|
|
@TileEvent( TileEventType.WORLD_NBT_READ )
|
|
public void readFromNBT_TileCondenser( final NBTTagCompound data )
|
|
{
|
|
this.cm.readFromNBT( data );
|
|
this.setStoredPower( data.getDouble( "storedPower" ) );
|
|
}
|
|
|
|
public double getStorage()
|
|
{
|
|
final ItemStack is = this.inv.getStackInSlot( 2 );
|
|
if( is != null )
|
|
{
|
|
if( is.getItem() instanceof IStorageComponent )
|
|
{
|
|
final IStorageComponent sc = (IStorageComponent) is.getItem();
|
|
if( sc.isStorageComponent( is ) )
|
|
{
|
|
return sc.getBytes( is ) * BYTE_MULTIPLIER;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
public void addPower( final double rawPower )
|
|
{
|
|
this.setStoredPower( this.getStoredPower() + rawPower );
|
|
this.setStoredPower( Math.max( 0.0, Math.min( this.getStorage(), this.getStoredPower() ) ) );
|
|
|
|
final double requiredPower = this.getRequiredPower();
|
|
final ItemStack output = this.getOutput();
|
|
while( requiredPower <= this.getStoredPower() && output != null && requiredPower > 0 )
|
|
{
|
|
if( this.canAddOutput( output ) )
|
|
{
|
|
this.setStoredPower( this.getStoredPower() - requiredPower );
|
|
this.addOutput( output );
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private boolean canAddOutput( final ItemStack output )
|
|
{
|
|
final ItemStack outputStack = this.getStackInSlot( 1 );
|
|
return outputStack == null || ( Platform.itemComparisons().isEqualItem( outputStack, output ) && outputStack.stackSize < outputStack.getMaxStackSize() );
|
|
}
|
|
|
|
/**
|
|
* make sure you validate with canAddOutput prior to this.
|
|
*
|
|
* @param output to be added output
|
|
*/
|
|
private void addOutput( final ItemStack output )
|
|
{
|
|
final ItemStack outputStack = this.getStackInSlot( 1 );
|
|
if( outputStack == null )
|
|
{
|
|
this.setInventorySlotContents( 1, output.copy() );
|
|
}
|
|
else
|
|
{
|
|
outputStack.stackSize++;
|
|
this.setInventorySlotContents( 1, outputStack );
|
|
}
|
|
}
|
|
|
|
private ItemStack getOutput()
|
|
{
|
|
final IMaterials materials = AEApi.instance().definitions().materials();
|
|
|
|
switch( (CondenserOutput) this.cm.getSetting( Settings.CONDENSER_OUTPUT ) )
|
|
{
|
|
case MATTER_BALLS:
|
|
return materials.matterBall().maybeStack( 1 ).orElse( null );
|
|
|
|
case SINGULARITY:
|
|
return materials.singularity().maybeStack( 1 ).orElse( null );
|
|
|
|
case TRASH:
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public double getRequiredPower()
|
|
{
|
|
return ( (CondenserOutput) this.cm.getSetting( Settings.CONDENSER_OUTPUT ) ).requiredPower;
|
|
}
|
|
|
|
@Override
|
|
public IInventory getInternalInventory()
|
|
{
|
|
return this.inv;
|
|
}
|
|
|
|
@Override
|
|
public void setInventorySlotContents( final int i, final ItemStack itemstack )
|
|
{
|
|
if( i == 0 )
|
|
{
|
|
if( itemstack != null )
|
|
{
|
|
this.addPower( itemstack.stackSize );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.inv.setInventorySlotContents( 1, itemstack );
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean isItemValidForSlot( final int i, final ItemStack itemstack )
|
|
{
|
|
return i == 0;
|
|
}
|
|
|
|
@Override
|
|
public void onChangeInventory( final IInventory inv, final int slot, final InvOperation mc, final ItemStack removed, final ItemStack added )
|
|
{
|
|
if( slot == 0 )
|
|
{
|
|
final ItemStack is = inv.getStackInSlot( 0 );
|
|
if( is != null )
|
|
{
|
|
this.addPower( is.stackSize );
|
|
inv.setInventorySlotContents( 0, null );
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean canInsertItem( final int slotIndex, final ItemStack insertingItem, final EnumFacing side )
|
|
{
|
|
return slotIndex == 0;
|
|
}
|
|
|
|
@Override
|
|
public boolean canExtractItem( final int slotIndex, final ItemStack extractedItem, final EnumFacing side )
|
|
{
|
|
return slotIndex != 0;
|
|
}
|
|
|
|
@Override
|
|
public int[] getAccessibleSlotsBySide( final EnumFacing side )
|
|
{
|
|
return this.sides;
|
|
}
|
|
|
|
@Override
|
|
public void updateSetting( final IConfigManager manager, final Enum settingName, final Enum newValue )
|
|
{
|
|
this.addPower( 0 );
|
|
}
|
|
|
|
@Override
|
|
public IConfigManager getConfigManager()
|
|
{
|
|
return this.cm;
|
|
}
|
|
|
|
public double getStoredPower()
|
|
{
|
|
return this.storedPower;
|
|
}
|
|
|
|
private void setStoredPower( final double storedPower )
|
|
{
|
|
this.storedPower = storedPower;
|
|
}
|
|
|
|
@Override
|
|
public boolean hasCapability( Capability<?> capability, EnumFacing facing )
|
|
{
|
|
if( capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY )
|
|
{
|
|
return true;
|
|
}
|
|
else if( capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY )
|
|
{
|
|
return true;
|
|
}
|
|
else if( capability == Capabilities.STORAGE_MONITORABLE_ACCESSOR )
|
|
{
|
|
return true;
|
|
}
|
|
return super.hasCapability( capability, facing );
|
|
}
|
|
|
|
@SuppressWarnings( "unchecked" )
|
|
@Override
|
|
public <T> T getCapability( Capability<T> capability, @Nullable EnumFacing facing )
|
|
{
|
|
if( capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY )
|
|
{
|
|
return (T) itemHandler;
|
|
}
|
|
else if( capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY )
|
|
{
|
|
return (T) fluidHandler;
|
|
}
|
|
else if( capability == Capabilities.STORAGE_MONITORABLE_ACCESSOR )
|
|
{
|
|
return (T) meHandler;
|
|
}
|
|
return super.getCapability( capability, facing );
|
|
}
|
|
|
|
private class ItemHandler implements IItemHandler
|
|
{
|
|
|
|
@Override
|
|
public int getSlots()
|
|
{
|
|
// We only expose the void slot
|
|
return 1;
|
|
}
|
|
|
|
@Override
|
|
public ItemStack getStackInSlot( int slot )
|
|
{
|
|
// The void slot never has any content
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public ItemStack insertItem( int slot, ItemStack stack, boolean simulate )
|
|
{
|
|
if( slot != 0 )
|
|
{
|
|
return stack;
|
|
}
|
|
if( !simulate && stack != null )
|
|
{
|
|
addPower( stack.stackSize );
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public ItemStack extractItem( int slot, int amount, boolean simulate )
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
private static final IFluidTankProperties[] EMPTY = { new FluidTankProperties( null, 10, true, false ) };
|
|
|
|
|
|
/**
|
|
* A fluid handler that exposes a 10 bucket tank that can only be filled, and - when filled - will add power
|
|
* to this condenser.
|
|
*/
|
|
private class FluidHandler implements IFluidHandler
|
|
{
|
|
|
|
@Override
|
|
public IFluidTankProperties[] getTankProperties()
|
|
{
|
|
return EMPTY;
|
|
}
|
|
|
|
@Override
|
|
public int fill( FluidStack resource, boolean doFill )
|
|
{
|
|
if( doFill )
|
|
{
|
|
addPower( ( resource == null ? 0.0 : (double) resource.amount ) / 500.0 );
|
|
}
|
|
|
|
return resource == null ? 0 : resource.amount;
|
|
}
|
|
|
|
@Nullable
|
|
@Override
|
|
public FluidStack drain( FluidStack resource, boolean doDrain )
|
|
{
|
|
return null;
|
|
}
|
|
|
|
@Nullable
|
|
@Override
|
|
public FluidStack drain( int maxDrain, boolean doDrain )
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* This is used to expose a fake ME subnetwork that is only composed of this condenser tile. The purpose of this is to enable the condenser to
|
|
* override the {@link appeng.api.storage.IMEInventoryHandler#validForPass(int)} method to make sure a condenser is only ever used if an item
|
|
* can't go anywhere else.
|
|
*/
|
|
private class MEHandler implements IStorageMonitorableAccessor, IStorageMonitorable
|
|
{
|
|
private final CondenserFluidInventory fluidInventory = new CondenserFluidInventory( TileCondenser.this );
|
|
|
|
private final CondenserItemInventory itemInventory = new CondenserItemInventory( TileCondenser.this );
|
|
|
|
@Nullable
|
|
@Override
|
|
public IStorageMonitorable getInventory( BaseActionSource src )
|
|
{
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public IMEMonitor<IAEItemStack> getItemInventory()
|
|
{
|
|
return itemInventory;
|
|
}
|
|
|
|
@Override
|
|
public IMEMonitor<IAEFluidStack> getFluidInventory()
|
|
{
|
|
return fluidInventory;
|
|
}
|
|
}
|
|
}
|