From 2c07acfe811960ed908f6f65caf0876d94eb0b4f Mon Sep 17 00:00:00 2001 From: fscan Date: Fri, 27 Oct 2017 15:49:40 +0200 Subject: [PATCH] Allow extraction for Condenser (#3179) fixes #2960, fixes #2017, fixes #2602 --- .../tile/misc/CondenserItemInventory.java | 102 +++++++++++++++--- .../java/appeng/tile/misc/TileCondenser.java | 31 ++++-- 2 files changed, 114 insertions(+), 19 deletions(-) diff --git a/src/main/java/appeng/tile/misc/CondenserItemInventory.java b/src/main/java/appeng/tile/misc/CondenserItemInventory.java index bbfc86c2e..226da905e 100644 --- a/src/main/java/appeng/tile/misc/CondenserItemInventory.java +++ b/src/main/java/appeng/tile/misc/CondenserItemInventory.java @@ -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 +class CondenserItemInventory implements IMEMonitor, ITickingMonitor { - + private final HashMap, 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 { 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 getAvailableItems( final IItemList out ) + public IItemList getAvailableItems( final IItemList out ) { + if( !target.getOutputSlot().getStackInSlot( 0 ).isEmpty() ) + { + out.add( AEItemStack.fromItemStack( target.getOutputSlot().getStackInSlot( 0 ) ) ); + } return out; } @Override public IItemList 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 getChannel() { return AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ); } @@ -80,7 +110,7 @@ class CondenserItemInventory implements IMEMonitor @Override public AccessRestriction getAccess() { - return AccessRestriction.WRITE; + return AccessRestriction.READ_WRITE; } @Override @@ -114,14 +144,62 @@ class CondenserItemInventory implements IMEMonitor } @Override - public void addListener( IMEMonitorHandlerReceiver l, Object verificationToken ) + public void addListener( final IMEMonitorHandlerReceiver 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 l ) + public void removeListener( final IMEMonitorHandlerReceiver 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, Object>> i = this.listeners.entrySet().iterator(); + while( i.hasNext() ) + { + final Entry, Object> l = i.next(); + final IMEMonitorHandlerReceiver 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; } } diff --git a/src/main/java/appeng/tile/misc/TileCondenser.java b/src/main/java/appeng/tile/misc/TileCondenser.java index f96fd0734..cfdba847f 100644 --- a/src/main/java/appeng/tile/misc/TileCondenser.java +++ b/src/main/java/appeng/tile/misc/TileCondenser.java @@ -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 )