Allow extraction for Condenser (#3179)

fixes #2960, fixes #2017, fixes #2602
This commit is contained in:
fscan
2017-10-27 15:49:40 +02:00
committed by GitHub
parent 3749742231
commit 2c07acfe81
2 changed files with 114 additions and 19 deletions
@@ -19,23 +19,37 @@
package appeng.tile.misc;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import net.minecraft.item.ItemStack;
import appeng.api.AEApi;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.networking.security.IActionSource;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.IMEMonitorHandlerReceiver;
import appeng.api.storage.IStorageChannel;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.me.helpers.BaseActionSource;
import appeng.me.storage.ITickingMonitor;
import appeng.util.item.AEItemStack;
import appeng.util.item.ItemList;
class CondenserItemInventory implements IMEMonitor<IAEItemStack>
class CondenserItemInventory implements IMEMonitor<IAEItemStack>, ITickingMonitor
{
private final HashMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap<>();
private final TileCondenser target;
private boolean hasChanged = true;
private final ItemList cachedList = new ItemList();
private IActionSource actionSource = new BaseActionSource();
private ItemList changeSet = new ItemList();
CondenserItemInventory( final TileCondenser te )
{
@@ -49,30 +63,46 @@ class CondenserItemInventory implements IMEMonitor<IAEItemStack>
{
this.target.addPower( input.getStackSize() );
}
return null;
}
@Override
public IAEItemStack extractItems( final IAEItemStack request, final Actionable mode, final IActionSource src )
{
return null;
AEItemStack ret = null;
ItemStack slotItem = target.getOutputSlot().getStackInSlot( 0 );
if( !slotItem.isEmpty() && request.isSameType( slotItem ) )
{
int count = (int) Math.min( request.getStackSize(), Integer.MAX_VALUE );
ret = AEItemStack.fromItemStack( target.getOutputSlot().extractItem( 0, count, mode == Actionable.SIMULATE ) );
}
return ret;
}
@Override
public IItemList<IAEItemStack> getAvailableItems( final IItemList out )
public IItemList<IAEItemStack> getAvailableItems( final IItemList<IAEItemStack> out )
{
if( !target.getOutputSlot().getStackInSlot( 0 ).isEmpty() )
{
out.add( AEItemStack.fromItemStack( target.getOutputSlot().getStackInSlot( 0 ) ) );
}
return out;
}
@Override
public IItemList<IAEItemStack> getStorageList()
{
return new ItemList();
if( this.hasChanged )
{
this.hasChanged = false;
this.cachedList.resetStatus();
return this.getAvailableItems( this.cachedList );
}
return this.cachedList;
}
@Override
public IStorageChannel getChannel()
public IStorageChannel<IAEItemStack> getChannel()
{
return AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class );
}
@@ -80,7 +110,7 @@ class CondenserItemInventory implements IMEMonitor<IAEItemStack>
@Override
public AccessRestriction getAccess()
{
return AccessRestriction.WRITE;
return AccessRestriction.READ_WRITE;
}
@Override
@@ -114,14 +144,62 @@ class CondenserItemInventory implements IMEMonitor<IAEItemStack>
}
@Override
public void addListener( IMEMonitorHandlerReceiver<IAEItemStack> l, Object verificationToken )
public void addListener( final IMEMonitorHandlerReceiver<IAEItemStack> l, final Object verificationToken )
{
// Not implemented since the Condenser automatically voids everything, and there are no updates
this.listeners.put( l, verificationToken );
}
@Override
public void removeListener( IMEMonitorHandlerReceiver<IAEItemStack> l )
public void removeListener( final IMEMonitorHandlerReceiver<IAEItemStack> l )
{
// Not implemented since we don't remember registered listeners anyway
this.listeners.remove( l );
}
public void updateOutput( ItemStack added, ItemStack removed )
{
this.hasChanged = true;
if( !added.isEmpty() )
{
this.changeSet.add( AEItemStack.fromItemStack( added ) );
}
if( !removed.isEmpty() )
{
this.changeSet.add( AEItemStack.fromItemStack( removed ).setStackSize( -removed.getCount() ) );
}
}
@Override
public TickRateModulation onTick()
{
final ItemList currentChanges = this.changeSet;
if( currentChanges.isEmpty() )
{
return TickRateModulation.IDLE;
}
this.changeSet = new ItemList();
final Iterator<Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
while( i.hasNext() )
{
final Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> l = i.next();
final IMEMonitorHandlerReceiver<IAEItemStack> key = l.getKey();
if( key.isValid( l.getValue() ) )
{
key.postChange( this, currentChanges, this.actionSource );
}
else
{
i.remove();
}
}
return TickRateModulation.URGENT;
}
@Override
public void setActionSource( IActionSource actionSource )
{
this.actionSource = actionSource;
}
}
@@ -55,6 +55,8 @@ import appeng.util.ConfigManager;
import appeng.util.IConfigManagerHost;
import appeng.util.inv.InvOperation;
import appeng.util.inv.WrapperChainedItemHandler;
import appeng.util.inv.WrapperFilteredItemHandler;
import appeng.util.inv.filter.AEItemFilters;
public class TileCondenser extends AEBaseInvTile implements IConfigManagerHost, IConfigurableObject
@@ -62,14 +64,16 @@ public class TileCondenser extends AEBaseInvTile implements IConfigManagerHost,
public static final int BYTE_MULTIPLIER = 8;
private final AppEngInternalInventory inv = new AppEngInternalInventory( this, 2 );
private final ConfigManager cm = new ConfigManager( this );
private final AppEngInternalInventory outputSlot = new AppEngInternalInventory( this, 1 );
private final AppEngInternalInventory storageSlot = new AppEngInternalInventory( this, 1 );
private final IItemHandler inputSlot = new CondenseItemHandler();
private final IFluidHandler fluidHandler = new FluidHandler();
private final MEHandler meHandler = new MEHandler();
private final IItemHandler combinedInv = new WrapperChainedItemHandler( this.inputSlot, this.inv );
private final IItemHandler externalInv = new WrapperChainedItemHandler( this.inputSlot, new WrapperFilteredItemHandler( this.outputSlot, AEItemFilters.EXTRACT_ONLY ) );
private final IItemHandler combinedInv = new WrapperChainedItemHandler( this.inputSlot, this.outputSlot, this.storageSlot );
private double storedPower = 0;
@@ -97,7 +101,7 @@ public class TileCondenser extends AEBaseInvTile implements IConfigManagerHost,
public double getStorage()
{
final ItemStack is = this.inv.getStackInSlot( 1 );
final ItemStack is = this.storageSlot.getStackInSlot( 0 );
if( !is.isEmpty() )
{
if( is.getItem() instanceof IStorageComponent )
@@ -135,7 +139,7 @@ public class TileCondenser extends AEBaseInvTile implements IConfigManagerHost,
private boolean canAddOutput( final ItemStack output )
{
return this.inv.insertItem( 0, output, true ).isEmpty();
return this.outputSlot.insertItem( 0, output, true ).isEmpty();
}
/**
@@ -145,7 +149,12 @@ public class TileCondenser extends AEBaseInvTile implements IConfigManagerHost,
*/
private void addOutput( final ItemStack output )
{
this.inv.insertItem( 0, output, false );
this.outputSlot.insertItem( 0, output, false );
}
IItemHandler getOutputSlot()
{
return this.outputSlot;
}
private ItemStack getOutput()
@@ -180,7 +189,10 @@ public class TileCondenser extends AEBaseInvTile implements IConfigManagerHost,
@Override
public void onChangeInventory( final IItemHandler inv, final int slot, final InvOperation mc, final ItemStack removed, final ItemStack added )
{
// nothing
if( inv == this.outputSlot )
{
this.meHandler.outputChanged( added, removed );
}
}
@Override
@@ -225,7 +237,7 @@ public class TileCondenser extends AEBaseInvTile implements IConfigManagerHost,
{
if( capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY )
{
return (T) this.inputSlot;
return (T) this.externalInv;
}
else if( capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY )
{
@@ -336,6 +348,11 @@ public class TileCondenser extends AEBaseInvTile implements IConfigManagerHost,
private final CondenserItemInventory itemInventory = new CondenserItemInventory( TileCondenser.this );
void outputChanged( ItemStack added, ItemStack removed )
{
itemInventory.updateOutput( added, removed );
}
@Nullable
@Override
public IStorageMonitorable getInventory( IActionSource src )