Compare commits

..

1 Commits

Author SHA1 Message Date
Salomão 76ae078d24 push patterns in round-robin 2021-04-29 21:19:07 -03:00
13 changed files with 490 additions and 474 deletions
@@ -164,6 +164,7 @@ public enum AEFeature
PATTERNS( "Patterns", Constants.CATEGORY_CRAFTING_FEATURES ), PATTERNS( "Patterns", Constants.CATEGORY_CRAFTING_FEATURES ),
CRAFTING_CPU( "CraftingCPU", Constants.CATEGORY_CRAFTING_FEATURES ), CRAFTING_CPU( "CraftingCPU", Constants.CATEGORY_CRAFTING_FEATURES ),
CRAFTING_MANAGER_FALLBACK( "CraftingManagerFallback", Constants.CATEGORY_CRAFTING_FEATURES, "Use CraftingManager to find an alternative recipe, after a pattern rejected an ingredient. Should be enabled to avoid issues, but can have a minor performance impact." ), CRAFTING_MANAGER_FALLBACK( "CraftingManagerFallback", Constants.CATEGORY_CRAFTING_FEATURES, "Use CraftingManager to find an alternative recipe, after a pattern rejected an ingredient. Should be enabled to avoid issues, but can have a minor performance impact." ),
INSANE_BLOCKING_MODE( "InsaneBlockingMode", Constants.CATEGORY_CRAFTING_FEATURES, "Use the default AE2 blocking mode that doesn't work on any machines" ),
BASIC_CARDS( "BasicCards", Constants.CATEGORY_UPGRADES ), BASIC_CARDS( "BasicCards", Constants.CATEGORY_UPGRADES ),
ADVANCED_CARDS( "AdvancedCards", Constants.CATEGORY_UPGRADES ), ADVANCED_CARDS( "AdvancedCards", Constants.CATEGORY_UPGRADES ),
@@ -19,14 +19,18 @@
package appeng.helpers; package appeng.helpers;
import java.util.*; import java.util.ArrayList;
import java.util.stream.Collectors; import java.util.Collection;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import appeng.integration.modules.gregtech.GTCEInventoryAdaptor; import appeng.integration.modules.gregtech.GTCEInventoryAdaptor;
import appeng.util.*; import appeng.util.*;
import appeng.util.inv.*;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import gregtech.api.block.machines.BlockMachine; import gregtech.api.block.machines.BlockMachine;
@@ -89,6 +93,8 @@ import appeng.api.util.AEPartLocation;
import appeng.api.util.DimensionalCoord; import appeng.api.util.DimensionalCoord;
import appeng.api.util.IConfigManager; import appeng.api.util.IConfigManager;
import appeng.capabilities.Capabilities; import appeng.capabilities.Capabilities;
import appeng.core.AEConfig;
import appeng.core.features.AEFeature;
import appeng.core.settings.TickRates; import appeng.core.settings.TickRates;
import appeng.me.GridAccessException; import appeng.me.GridAccessException;
import appeng.me.helpers.AENetworkProxy; import appeng.me.helpers.AENetworkProxy;
@@ -100,6 +106,10 @@ import appeng.parts.automation.StackUpgradeInventory;
import appeng.parts.automation.UpgradeInventory; import appeng.parts.automation.UpgradeInventory;
import appeng.tile.inventory.AppEngInternalAEInventory; import appeng.tile.inventory.AppEngInternalAEInventory;
import appeng.tile.inventory.AppEngInternalInventory; import appeng.tile.inventory.AppEngInternalInventory;
import appeng.util.inv.AdaptorItemHandler;
import appeng.util.inv.IAEAppEngInventory;
import appeng.util.inv.IInventoryDestination;
import appeng.util.inv.InvOperation;
import appeng.util.item.AEItemStack; import appeng.util.item.AEItemStack;
import static gregtech.api.block.machines.BlockMachine.getMetaTileEntity; import static gregtech.api.block.machines.BlockMachine.getMetaTileEntity;
@@ -107,6 +117,8 @@ import static gregtech.api.block.machines.BlockMachine.getMetaTileEntity;
public class DualityInterface implements IGridTickable, IStorageMonitorable, IInventoryDestination, IAEAppEngInventory, IConfigManagerHost, ICraftingProvider, IUpgradeableHost public class DualityInterface implements IGridTickable, IStorageMonitorable, IInventoryDestination, IAEAppEngInventory, IConfigManagerHost, ICraftingProvider, IUpgradeableHost
{ {
private int[] failedCraftTriesSlot = {0,0,0,0,0,0,0,0,0};
public static final int NUMBER_OF_STORAGE_SLOTS = 9; public static final int NUMBER_OF_STORAGE_SLOTS = 9;
public static final int NUMBER_OF_CONFIG_SLOTS = 9; public static final int NUMBER_OF_CONFIG_SLOTS = 9;
public static final int NUMBER_OF_PATTERN_SLOTS = 9; public static final int NUMBER_OF_PATTERN_SLOTS = 9;
@@ -136,9 +148,8 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
private IMEInventory<IAEItemStack> destination; private IMEInventory<IAEItemStack> destination;
private int isWorking = -1; private int isWorking = -1;
private final Accessor accessor = new Accessor(); private final Accessor accessor = new Accessor();
private EnumSet<EnumFacing> visitedFaces = EnumSet.noneOf( EnumFacing.class );
private EnumMap<EnumFacing,List<ItemStack>> waitingToSendFacing = new EnumMap<>(EnumFacing.class);
private GTCEInventoryAdaptor GTad; private GTCEInventoryAdaptor GTad;
EnumSet<EnumFacing> visitedFaces = EnumSet.noneOf( EnumFacing.class );
public DualityInterface( final AENetworkProxy networkProxy, final IInterfaceHost ih ) public DualityInterface( final AENetworkProxy networkProxy, final IInterfaceHost ih )
{ {
@@ -232,27 +243,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
} }
} }
data.setTag( "waitingToSend", waitingToSend ); data.setTag( "waitingToSend", waitingToSend );
NBTTagCompound sidedWaitList = new NBTTagCompound();
if (this.waitingToSendFacing != null)
{
for( EnumFacing s : this.iHost.getTargets() )
{
NBTTagList waitingListSided = new NBTTagList();
if (this.waitingToSendFacing.containsKey( s ))
{
for( final ItemStack is : this.waitingToSendFacing.get( s ) )
{
final NBTTagCompound item = new NBTTagCompound();
is.writeToNBT( item );
waitingListSided.appendTag( item );
}
sidedWaitList.setTag( s.name(), waitingListSided );
}
}
}
data.setTag( "sidedWaitList", sidedWaitList );
} }
public void readFromNBT( final NBTTagCompound data ) public void readFromNBT( final NBTTagCompound data )
@@ -272,23 +262,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
} }
} }
this.waitingToSendFacing = null;
final NBTTagCompound waitingListSided = data.getCompoundTag("sidedWaitList");
for (EnumFacing s : EnumFacing.values())
if (waitingListSided.hasKey( s.name() )) {
NBTTagList w = waitingListSided.getTagList( s.name(), 10 );
for( int x = 0; x < w.tagCount(); x++ )
{
final NBTTagCompound c = w.getCompoundTagAt( x );
if( c != null )
{
final ItemStack is = new ItemStack( c );
this.addToSendListFacing( is , EnumFacing.getFront( s.getIndex() ) );
}
}
}
this.craftingTracker.readFromNBT( data ); this.craftingTracker.readFromNBT( data );
this.upgrades.readFromNBT( data, "upgrades" ); this.upgrades.readFromNBT( data, "upgrades" );
this.config.readFromNBT( data, "config" ); this.config.readFromNBT( data, "config" );
@@ -324,30 +297,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
} }
} }
private void addToSendListFacing( final ItemStack is, EnumFacing f )
{
if( is.isEmpty() )
{
return;
}
if (this.waitingToSendFacing == null){
this.waitingToSendFacing = new EnumMap<>(EnumFacing.class);
}
this.waitingToSendFacing.computeIfAbsent( f, k -> new ArrayList<>() );
this.waitingToSendFacing.get( f ).add( is );
try
{
this.gridProxy.getTick().wakeDevice( this.gridProxy.getNode() );
}
catch( final GridAccessException e )
{
// :P
}
}
private void readConfig() private void readConfig()
{ {
this.hasConfig = false; this.hasConfig = false;
@@ -445,22 +394,24 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
} }
} }
private boolean hasWorkToDo() { private boolean hasWorkToDo()
{
if (hasItemsToSend()){ if( this.hasItemsToSend() )
{
return true; return true;
} }
else
if(hasItemsToSendFacing()){ {
return true; for( final IAEItemStack requiredWork : this.requireWork )
} {
if( requiredWork != null )
for (final IAEItemStack requiredWork : this.requireWork) { {
if (requiredWork != null) { return true;
return true; }
} }
return false;
} }
return false;
} }
private void updatePlan( final int slot ) private void updatePlan( final int slot )
@@ -565,21 +516,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
return this.waitingToSend != null && !this.waitingToSend.isEmpty(); return this.waitingToSend != null && !this.waitingToSend.isEmpty();
} }
private boolean hasItemsToSendFacing()
{
if (waitingToSendFacing != null)
{
for( EnumFacing enumFacing : waitingToSendFacing.keySet() )
{
if( !waitingToSendFacing.get( enumFacing ).isEmpty() )
{
return true;
}
}
}
return false;
}
@Override @Override
public boolean canInsert( final ItemStack stack ) public boolean canInsert( final ItemStack stack )
{ {
@@ -651,21 +587,11 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
return TickRateModulation.SLEEP; return TickRateModulation.SLEEP;
} }
//Previous version might have items saved in this list
//recover them
if( this.hasItemsToSend() ) if( this.hasItemsToSend() )
{ {
this.pushItemsOut( this.iHost.getTargets() ); this.pushItemsOut( this.iHost.getTargets() );
} }
if (hasItemsToSendFacing())
{
for( EnumFacing enumFacing : waitingToSendFacing.keySet() )
{
this.pushItemsOut( enumFacing );
}
}
final boolean couldDoWork = this.updateStorage(); final boolean couldDoWork = this.updateStorage();
return this.hasWorkToDo() ? ( couldDoWork ? TickRateModulation.URGENT : TickRateModulation.SLOWER ) : TickRateModulation.SLEEP; return this.hasWorkToDo() ? ( couldDoWork ? TickRateModulation.URGENT : TickRateModulation.SLOWER ) : TickRateModulation.SLEEP;
} }
@@ -726,47 +652,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
} }
} }
private void pushItemsOut( final EnumFacing s )
{
if (!this.waitingToSendFacing.containsKey(s) ||
(this.waitingToSendFacing.containsKey(s) && this.waitingToSendFacing.get( s ).isEmpty())) {
return;
}
final TileEntity tile = this.iHost.getTileEntity();
final World w = tile.getWorld();
final TileEntity te = w.getTileEntity( tile.getPos().offset( s ) );
if( te == null )
{
return;
}
final Iterator<ItemStack> i = this.waitingToSendFacing.get( s ).iterator();
while ( i.hasNext() )
{
ItemStack whatToSend = i.next();
final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
if( ad != null )
{
final ItemStack result = ad.addItems( whatToSend );
if( !result.isEmpty() )
{
whatToSend.setCount( whatToSend.getCount() - ( whatToSend.getCount() - result.getCount() ) );
}
else
{
i.remove();
}
}
}
if( this.waitingToSendFacing.get( s ).isEmpty() )
{
this.waitingToSendFacing.remove( s );
}
}
private boolean updateStorage() private boolean updateStorage()
{ {
boolean didSomething = false; boolean didSomething = false;
@@ -886,8 +771,17 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
{ {
if( this.getInstalledUpgrades( Upgrades.CRAFTING ) > 0 && itemStack != null ) if( this.getInstalledUpgrades( Upgrades.CRAFTING ) > 0 && itemStack != null )
{ {
return this.craftingTracker.handleCrafting( x, itemStack.getStackSize(), itemStack, d, this.iHost.getTileEntity().getWorld(), if (this.failedCraftTriesSlot[x] <= 0)
{
boolean crafted = this.craftingTracker.handleCrafting( x, itemStack.getStackSize(), itemStack, d, this.iHost.getTileEntity().getWorld(),
this.gridProxy.getGrid(), this.gridProxy.getCrafting(), this.mySource ); this.gridProxy.getGrid(), this.gridProxy.getCrafting(), this.mySource );
if (crafted) this.failedCraftTriesSlot[x] = 0;
else{
this.failedCraftTriesSlot[x] += 2;
}
}
this.failedCraftTriesSlot[x] -= 1;
} }
} }
catch( final GridAccessException e ) catch( final GridAccessException e )
@@ -1020,9 +914,13 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}; };
} }
private boolean invIsBlocked( InventoryAdaptor inv ) private static boolean invIsBlocked( InventoryAdaptor inv )
{ {
return (inv.containsItems()); if( AEConfig.instance().isFeatureEnabled( AEFeature.INSANE_BLOCKING_MODE ) )
{
return !inv.simulateRemove( 1, ItemStack.EMPTY, null ).isEmpty();
}
else return inv.containsItems();
} }
private static boolean invIsBlockedGTCE( GTCEInventoryAdaptor inv ) private static boolean invIsBlockedGTCE( GTCEInventoryAdaptor inv )
@@ -1033,7 +931,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
@Override @Override
public boolean pushPattern( final ICraftingPatternDetails patternDetails, final InventoryCrafting table ) public boolean pushPattern( final ICraftingPatternDetails patternDetails, final InventoryCrafting table )
{ {
if( this.hasItemsToSend() || this.hasItemsToSendFacing() || !this.gridProxy.isActive() || !this.craftingList.contains( patternDetails ) ) if( this.hasItemsToSend() || !this.gridProxy.isActive() || !this.craftingList.contains( patternDetails ) )
{ {
return false; return false;
} }
@@ -1041,13 +939,13 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
final TileEntity tile = this.iHost.getTileEntity(); final TileEntity tile = this.iHost.getTileEntity();
final World w = tile.getWorld(); final World w = tile.getWorld();
if( this.visitedFaces.isEmpty() ) final EnumSet<EnumFacing> possibleDirections = this.iHost.getTargets();
{
this.visitedFaces = this.iHost.getTargets();
}
for( final EnumFacing s : visitedFaces ) for( final EnumFacing s : possibleDirections )
{ {
if (visitedFaces.contains( s ))
continue;
final TileEntity te = w.getTileEntity( tile.getPos().offset( s ) ); final TileEntity te = w.getTileEntity( tile.getPos().offset( s ) );
if( te instanceof IInterfaceHost ) if( te instanceof IInterfaceHost )
{ {
@@ -1055,7 +953,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
{ {
if( ( (IInterfaceHost) te ).getInterfaceDuality().sameGrid( this.gridProxy.getGrid() ) ) if( ( (IInterfaceHost) te ).getInterfaceDuality().sameGrid( this.gridProxy.getGrid() ) )
{ {
visitedFaces.remove( s );
continue; continue;
} }
} }
@@ -1070,9 +967,9 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
final ICraftingMachine cm = (ICraftingMachine) te; final ICraftingMachine cm = (ICraftingMachine) te;
if( cm.acceptsPlans() ) if( cm.acceptsPlans() )
{ {
visitedFaces.remove( s );
if( cm.pushPattern( patternDetails, table, s.getOpposite() ) ) if( cm.pushPattern( patternDetails, table, s.getOpposite() ) )
{ {
visitedFaces.add( s );
return true; return true;
} }
continue; continue;
@@ -1082,7 +979,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() ); final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
if( ad != null ) if( ad != null )
{ {
boolean isDrawer = te.getBlockType().getRegistryName().getResourceDomain().equals( "storagedrawers" );
if( this.isBlocking() ) if( this.isBlocking() )
{ {
if( te.getBlockType().getRegistryName().getResourceDomain().equals( "gregtech" ) ) if( te.getBlockType().getRegistryName().getResourceDomain().equals( "gregtech" ) )
@@ -1090,47 +986,50 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
GTad = GTCEInventoryAdaptor.getAdaptor( te, s.getOpposite() ); GTad = GTCEInventoryAdaptor.getAdaptor( te, s.getOpposite() );
if( invIsBlockedGTCE( GTad ) ) if( invIsBlockedGTCE( GTad ) )
{ {
visitedFaces.remove( s );
continue; continue;
} }
} }
else if ( invIsBlocked( ad ) ) else
{ {
visitedFaces.remove( s ); if( invIsBlocked( ad ) )
continue; {
continue;
}
} }
} }
if( this.acceptsItems( ad, patternDetails, isDrawer ) ) if( this.acceptsItems( ad, table ) )
{ {
visitedFaces.remove( s );
for( int x = 0; x < table.getSizeInventory(); x++ ) for( int x = 0; x < table.getSizeInventory(); x++ )
{ {
final ItemStack is = table.getStackInSlot( x ); final ItemStack is = table.getStackInSlot( x );
if( !is.isEmpty() ) if( !is.isEmpty() )
{ {
addToSendListFacing( is, s ); final ItemStack added = ad.addItems( is );
this.addToSendList( added );
} }
} }
pushItemsOut( s ); this.pushItemsOut( possibleDirections );
visitedFaces.add( s );
return true; return true;
} }
} }
visitedFaces.remove( s );
} }
visitedFaces.clear();
return false; return false;
} }
@Override @Override
public boolean isBusy() public boolean isBusy()
{ {
boolean busy = false; if( this.hasItemsToSend() )
if( this.hasItemsToSend() || hasItemsToSendFacing() )
{ {
return true; return true;
} }
boolean busy = false;
if( this.isBlocking() ) if( this.isBlocking() )
{ {
final EnumSet<EnumFacing> possibleDirections = this.iHost.getTargets(); final EnumSet<EnumFacing> possibleDirections = this.iHost.getTargets();
@@ -1155,10 +1054,14 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
break; break;
} }
} }
else if( !invIsBlocked( ad ) ) else
{ {
allAreBusy = false; if( !invIsBlocked( ad ) )
break; {
allAreBusy = false;
break;
}
} }
} }
} }
@@ -1177,75 +1080,23 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
return this.cm.getSetting( Settings.BLOCK ) == YesNo.YES; return this.cm.getSetting( Settings.BLOCK ) == YesNo.YES;
} }
private boolean acceptsItems( final InventoryAdaptor ad, final ICraftingPatternDetails patternDetails, boolean isDrawer ) private boolean acceptsItems( final InventoryAdaptor ad, final InventoryCrafting table )
{ {
List<ItemStack> patternedStacks = Arrays.stream( patternDetails.getCondensedInputs() ).map( IAEItemStack::createItemStack ).collect( Collectors.toList() ); for( int x = 0; x < table.getSizeInventory(); x++ )
List<ItemSlot> copiedItemSlots = new ArrayList<>();
if( patternedStacks.size() == 1 )
{ {
return ad.simulateAdd( patternedStacks.get( 0 ) ).isEmpty(); final ItemStack is = table.getStackInSlot( x );
} if( is.isEmpty() )
else
{
for ( ItemSlot itemSlot : ad )
{ {
//skip storage drawers slot 0 to avoid voiding items due to broken itemhandler implementation continue;
if( isDrawer && itemSlot.getSlot() == 0 ){
continue;
}
//some inventory may expose their special slots ( for upgrades, etc )
//if its empty AND we cant fit any of the items in the recipes, skip it.
ItemStack stackInSlot = itemSlot.getItemStack();
for ( IAEItemStack aeItemStack : patternDetails.getCondensedInputs() )
{
if( stackInSlot.isEmpty() )
{
if( itemSlot.simulateInsertItem( aeItemStack.getDefinition() ).isEmpty() )
{
copiedItemSlots.add( itemSlot.copy() );
break;
}
}
// copy partially filled slots for merging logic
else if( stackInSlot.getCount() < Math.min( itemSlot.getSlotLimit(), stackInSlot.getMaxStackSize() ) )
{
if( aeItemStack.isSameType( stackInSlot ) )
{
copiedItemSlots.add( itemSlot.copy() );
break;
}
}
}
} }
// start merging in order of slots, left to right. if( !ad.simulateAdd( is.copy() ).isEmpty() )
for ( ItemSlot copiedItemSlot : copiedItemSlots )
{ {
Iterator<ItemStack> patStackIterator = patternedStacks.iterator(); return false;
while ( patStackIterator.hasNext() )
{
ItemStack patStack = patStackIterator.next();
ItemStack remainder = copiedItemSlot.simulateInsertItem( patStack );
if( !remainder.isEmpty() )
{
patStack.setCount( patStack.getCount() - ( patStack.getCount() - remainder.getCount() ) );
}
else //entire stack got injected
{
patStackIterator.remove();
break;
}
}
// if we merged EVERYTHING successfully , return true.
if( patternedStacks.size() == 0 )
{
return true;
}
} }
return false;
} }
return true;
} }
@Override @Override
@@ -1274,20 +1125,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
} }
} }
if( this.waitingToSendFacing != null )
{
for (List<ItemStack> itemList : waitingToSendFacing.values())
{
for (final ItemStack is : itemList)
{
if (!is.isEmpty())
{
drops.add(is);
}
}
}
}
for( final ItemStack is : this.upgrades ) for( final ItemStack is : this.upgrades )
{ {
if( !is.isEmpty() ) if( !is.isEmpty() )
@@ -1,26 +1,26 @@
package appeng.integration.modules.gregtech; package appeng.integration.modules.gregtech;
import appeng.util.inv.ItemSlot; import appeng.util.inv.ItemSlot;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
public abstract class GTCEInventoryAdaptor implements Iterable<ItemSlot> public abstract class GTCEInventoryAdaptor implements Iterable<ItemSlot>
{ {
public static GTCEInventoryAdaptor getAdaptor(final TileEntity te, final EnumFacing d) public static GTCEInventoryAdaptor getAdaptor(final TileEntity te, final EnumFacing d)
{ {
if (te != null && te.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d)) if (te != null && te.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d))
{ {
// Attempt getting an IItemHandler for the given side via caps // Attempt getting an IItemHandler for the given side via caps
IItemHandler itemHandler = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d); IItemHandler itemHandler = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d);
if (itemHandler != null) if (itemHandler != null)
{ {
return new GTCEItemHandler(itemHandler); return new GTCEItemHandler(itemHandler);
} }
} }
return null; return null;
} }
public abstract boolean canRemoveAllExceptCircuits(); public abstract boolean canRemoveAllExceptCircuits();
} }
@@ -1,58 +1,57 @@
package appeng.integration.modules.gregtech; package appeng.integration.modules.gregtech;
import appeng.util.inv.ItemHandlerIterator; import appeng.util.inv.ItemSlot;
import appeng.util.inv.ItemSlot; import net.minecraft.item.Item;
import net.minecraft.item.Item; import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemStack; import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.IItemHandler;
import java.util.ArrayList;
import java.util.ArrayList; import java.util.Arrays;
import java.util.Arrays; import java.util.Iterator;
import java.util.Iterator;
public class GTCEItemHandler extends GTCEInventoryAdaptor
public class GTCEItemHandler extends GTCEInventoryAdaptor {
{ ArrayList<Integer> GTCElenses = new ArrayList<>(Arrays.asList(15085,15214,15092,15111,15113,15219,15218,15243,15244,15209,15117,15206,15216,15331,15212,15213,15154,15122,15157,15190,15247));
ArrayList<Integer> GTCElenses = new ArrayList<>(Arrays.asList(15085,15214,15092,15111,15113,15219,15218,15243,15244,15209,15117,15206,15216,15331,15212,15213,15154,15122,15157,15190,15247)); ArrayList<Integer> GTCEmolds = new ArrayList<>(Arrays.asList(32301,32303,32304,32305,32306,32307,32308,32309,32313,32314,32315,32317,32350,32351,32352,32353,32354,32355,32356,32358,32359,32360,32361,32363,32364,32365,32366,32367,32368,32369,32370,32371,32372,32373));
ArrayList<Integer> GTCEmolds = new ArrayList<>(Arrays.asList(32301,32303,32304,32305,32306,32307,32308,32309,32313,32314,32315,32317,32350,32351,32352,32353,32354,32355,32356,32358,32359,32360,32361,32363,32364,32365,32366,32367,32368,32369,32370,32371,32372,32373)); Item smallGearExtruderShape = Item.getByNameOrId("contenttweaker:smallgearextrudershape");
Item smallGearExtruderShape = Item.getByNameOrId("contenttweaker:smallgearextrudershape"); Item creativePortableTankMold = Item.getByNameOrId("contenttweaker:creativeportabletankmold");
Item creativePortableTankMold = Item.getByNameOrId("contenttweaker:creativeportabletankmold");
protected final IItemHandler itemHandler;
protected final IItemHandler itemHandler;
public GTCEItemHandler(IItemHandler itemHandler)
public GTCEItemHandler(IItemHandler itemHandler) {
{ this.itemHandler = itemHandler;
this.itemHandler = itemHandler; }
}
boolean isBlockableItem(ItemStack stack)
boolean isBlockableItem(ItemStack stack) {
{ if ( stack.getItem() == Item.getByNameOrId("gregtech:meta_item_1") ) {
if ( stack.getItem() == Item.getByNameOrId("gregtech:meta_item_1") ) { int metadata = stack.getItemDamage();
int metadata = stack.getItemDamage(); if ( metadata == 32766 || GTCElenses.contains(metadata) || GTCEmolds.contains(metadata)) {
if ( metadata == 32766 || GTCElenses.contains(metadata) || GTCEmolds.contains(metadata)) { return false;
return false; }
} }
} if ( stack.getItem() == smallGearExtruderShape ) return false;
if ( stack.getItem() == smallGearExtruderShape ) return false; if ( stack.getItem() == creativePortableTankMold) return false;
if ( stack.getItem() == creativePortableTankMold) return false; return true;
return true; }
}
@Override
@Override public boolean canRemoveAllExceptCircuits()
public boolean canRemoveAllExceptCircuits() {
{ int slots = this.itemHandler.getSlots();
int slots = this.itemHandler.getSlots(); for ( int slot = 0; slot < slots; slot++ ) {
for ( int slot = 0; slot < slots; slot++ ) { ItemStack is = this.itemHandler.getStackInSlot(slot);
ItemStack is = this.itemHandler.getStackInSlot(slot); if ( is.isEmpty() || !isBlockableItem(is) ) continue;
if ( is.isEmpty() || !isBlockableItem(is) ) continue;
return false;
return false; }
} return true;
return true; }
}
@Override
@Override public Iterator<ItemSlot> iterator()
public Iterator<ItemSlot> iterator() {
{ return null;
return new ItemHandlerIterator( this.itemHandler ); }
} }
}
@@ -19,9 +19,13 @@
package appeng.me.cluster.implementations; package appeng.me.cluster.implementations;
import java.util.*; import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.stream.Collectors;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@@ -30,6 +34,8 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagList;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.fml.common.FMLCommonHandler;
import appeng.api.AEApi; import appeng.api.AEApi;
import appeng.api.config.Actionable; import appeng.api.config.Actionable;
@@ -87,7 +93,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
private final List<TileCraftingTile> storage = new ArrayList<>(); private final List<TileCraftingTile> storage = new ArrayList<>();
private final List<TileCraftingMonitorTile> status = new ArrayList<>(); private final List<TileCraftingMonitorTile> status = new ArrayList<>();
private final HashMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap<>(); private final HashMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap<>();
private final Map<ICraftingPatternDetails, Queue<ICraftingMedium>> visitedMediums = new HashMap<>(); private final Map<ICraftingPatternDetails,List<ICraftingMedium>> visitedMediums = new HashMap<>();
private ICraftingLink myLastLink; private ICraftingLink myLastLink;
private String myName = ""; private String myName = "";
private boolean isDestroyed = false; private boolean isDestroyed = false;
@@ -641,22 +647,31 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
{ {
InventoryCrafting ic = null; InventoryCrafting ic = null;
if (!visitedMediums.containsKey( details ) || visitedMediums.get( details ).isEmpty()) for( final ICraftingMedium m : cc.getMediums( e.getKey() ) )
{ {
visitedMediums.put( details, new ArrayDeque<>( cc.getMediums( details ).stream().filter( Objects::nonNull ).collect( Collectors.toList()) ) );
}
while (!visitedMediums.get( details ).isEmpty())
{
ICraftingMedium m = visitedMediums.get( details ).poll();
if( e.getValue().value <= 0 ) if( e.getValue().value <= 0 )
{ {
continue; continue;
} }
if( m != null && !m.isBusy() ) if (visitedMediums.containsKey( details ))
{
if( visitedMediums.get( details ).containsAll( cc.getMediums( e.getKey() ) ) )
{
visitedMediums.clear();
visitedMediums.put( details, new ArrayList<>() );
}
}
visitedMediums.putIfAbsent( details, new ArrayList<>() );
if( visitedMediums.get( details ).contains( m ) )
{
continue;
}
visitedMediums.get( details ).add( m );
if( !m.isBusy() )
{ {
if( ic == null ) if( ic == null )
{ {
@@ -70,6 +70,8 @@ import appeng.util.item.AEItemStack;
public class PartExportBus extends PartSharedItemBus implements ICraftingRequester public class PartExportBus extends PartSharedItemBus implements ICraftingRequester
{ {
private final int[] failedCraftTriesSlot = {0,0,0,0,0,0,0,0,0};
public static final ResourceLocation MODEL_BASE = new ResourceLocation( AppEng.MOD_ID, "part/export_bus_base" ); public static final ResourceLocation MODEL_BASE = new ResourceLocation( AppEng.MOD_ID, "part/export_bus_base" );
@PartModels @PartModels
@@ -140,7 +142,7 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
if( destination != null ) if( destination != null )
{ {
int x; int x = 0;
for( x = 0; x < this.availableSlots() && this.itemToSend > 0; x++ ) for( x = 0; x < this.availableSlots() && this.itemToSend > 0; x++ )
{ {
@@ -151,8 +153,16 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
if( ais == null || this.itemToSend <= 0 ) continue; if( ais == null || this.itemToSend <= 0 ) continue;
if ( this.craftOnly() ) { if ( this.craftOnly() ) {
this.didSomething = this.craftingTracker.handleCrafting(slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(), if (this.failedCraftTriesSlot[x] <= 0) {
this.getProxy().getGrid(), cg, this.mySrc) || this.didSomething;
this.didSomething = this.craftingTracker.handleCrafting(slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(),
this.getProxy().getGrid(), cg, this.mySrc) || this.didSomething;
if (this.didSomething) this.failedCraftTriesSlot[x] = 0;
else this.failedCraftTriesSlot[x] += 2;
}
this.failedCraftTriesSlot[x] -= 1;
continue;
} }
final long before = this.itemToSend; final long before = this.itemToSend;
@@ -175,8 +185,15 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
if( this.itemToSend == before && this.isCraftingEnabled() ) if( this.itemToSend == before && this.isCraftingEnabled() )
{ {
this.didSomething = this.craftingTracker.handleCrafting(slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(), if (this.failedCraftTriesSlot[x] <= 0) {
this.didSomething = this.craftingTracker.handleCrafting(slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(),
this.getProxy().getGrid(), cg, this.mySrc) || this.didSomething; this.getProxy().getGrid(), cg, this.mySrc) || this.didSomething;
if (this.didSomething) this.failedCraftTriesSlot[x] = 0;
else this.failedCraftTriesSlot[x] += 2;
}
this.failedCraftTriesSlot[x] -= 1;
} }
} }
@@ -218,12 +218,6 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
private boolean importStuff( final InventoryAdaptor myAdaptor, final IAEItemStack whatToImport, final IMEMonitor<IAEItemStack> inv, final IEnergySource energy, final FuzzyMode fzMode ) private boolean importStuff( final InventoryAdaptor myAdaptor, final IAEItemStack whatToImport, final IMEMonitor<IAEItemStack> inv, final IEnergySource energy, final FuzzyMode fzMode )
{ {
final int toSend = this.calculateMaximumAmountToImport( myAdaptor, whatToImport, inv, fzMode ); final int toSend = this.calculateMaximumAmountToImport( myAdaptor, whatToImport, inv, fzMode );
if( toSend == 0 )
{
return true;
}
final ItemStack newItems; final ItemStack newItems;
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 ) if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
@@ -292,17 +286,8 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
itemAmountNotStorable = inv.injectItems( AEItemStack.fromItemStack( simResult ), Actionable.SIMULATE, this.source ); itemAmountNotStorable = inv.injectItems( AEItemStack.fromItemStack( simResult ), Actionable.SIMULATE, this.source );
} }
if( simResult.isEmpty() )
{
return 0;
}
if( itemAmountNotStorable != null ) if( itemAmountNotStorable != null )
{ {
if( simResult.getCount() == itemAmountNotStorable.getStackSize() )
{
return 0;
}
return (int) Math.min( simResult.getCount() - itemAmountNotStorable.getStackSize(), toSend ); return (int) Math.min( simResult.getCount() - itemAmountNotStorable.getStackSize(), toSend );
} }
@@ -19,7 +19,12 @@
package appeng.parts.misc; package appeng.parts.misc;
import java.util.*; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import appeng.api.config.Settings; import appeng.api.config.Settings;
import appeng.api.config.StorageFilter; import appeng.api.config.StorageFilter;
@@ -37,11 +42,11 @@ import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList; import appeng.api.storage.data.IItemList;
import appeng.core.AELog; import appeng.core.AELog;
import appeng.me.GridAccessException;
import appeng.me.helpers.IGridProxyable; import appeng.me.helpers.IGridProxyable;
import appeng.me.storage.ITickingMonitor; import appeng.me.storage.ITickingMonitor;
import appeng.util.Platform; import appeng.util.Platform;
import appeng.util.item.AEItemStack; import appeng.util.item.AEItemStack;
import org.apache.commons.lang3.tuple.Pair;
/** /**
@@ -76,19 +81,11 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
int slotCount = this.itemHandler.getSlots(); int slotCount = this.itemHandler.getSlots();
boolean simulate = ( type == Actionable.SIMULATE ); boolean simulate = ( type == Actionable.SIMULATE );
List<Pair<Integer,Integer>> injectedList = new ArrayList<>();
// This uses a brute force approach and tries to jam it in every slot the inventory exposes. // This uses a brute force approach and tries to jam it in every slot the inventory exposes.
for( int i = 0; i < slotCount && !remaining.isEmpty(); i++ ) for( int i = 0; i < slotCount && !remaining.isEmpty(); i++ )
{ {
int countPre = remaining.getCount();
remaining = this.itemHandler.insertItem( i, remaining, simulate ); remaining = this.itemHandler.insertItem( i, remaining, simulate );
int countPos = remaining.getCount();
if (remaining.isEmpty()){
injectedList.add( Pair.of( i,countPre ) );
}
else if (countPos > countPre) {
injectedList.add( Pair.of( i,countPos - countPre ) );
}
} }
// At this point, we still have some items left... // At this point, we still have some items left...
@@ -100,17 +97,13 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
if( type == Actionable.MODULATE ) if( type == Actionable.MODULATE )
{ {
if (this.cache.cachedAeStacks.length == 0) this.cache.update(); try
for ( Pair<Integer, Integer> pair : injectedList )
{ {
if( this.cache.cachedAeStacks[pair.getKey()] == null ) this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
{ }
this.cache.cachedAeStacks[pair.getKey()] = iox.copy().setStackSize( pair.getValue() ); catch( GridAccessException ex )
} {
else // meh
{
this.cache.cachedAeStacks[pair.getKey()].incStackSize( pair.getValue() );
}
} }
} }
@@ -128,10 +121,8 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
ItemStack gathered = ItemStack.EMPTY; ItemStack gathered = ItemStack.EMPTY;
final boolean simulate = ( mode == Actionable.SIMULATE ); final boolean simulate = ( mode == Actionable.SIMULATE );
List<Pair<Integer, Integer>> extractedList = new ArrayList<>();
for( int i = 0; i < this.itemHandler.getSlots(); i++ )
for ( int i = 0; i < this.itemHandler.getSlots(); i++ )
{ {
ItemStack stackInInventorySlot = this.itemHandler.getStackInSlot( i ); ItemStack stackInInventorySlot = this.itemHandler.getStackInSlot( i );
@@ -149,9 +140,16 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
do do
{ {
extracted = this.itemHandler.extractItem( i, remainingCurrentSlot, simulate ); extracted = this.itemHandler.extractItem( i, remainingCurrentSlot, simulate );
if( !extracted.isEmpty() ) if( !extracted.isEmpty() )
{ {
// In order to guard against broken IItemHandler implementations, we'll try to guess if the returned
// stack (especially in simulate mode) is the same that was returned by getStackInSlot. This is
// obviously not a precise science, but it would catch the previous Forge bug:
// https://github.com/MinecraftForge/MinecraftForge/pull/6580
if (extracted == stackInInventorySlot) {
extracted = extracted.copy();
}
if( extracted.getCount() > remainingCurrentSlot ) if( extracted.getCount() > remainingCurrentSlot )
{ {
// Something broke. It should never return more than we requested... // Something broke. It should never return more than we requested...
@@ -161,14 +159,17 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
extracted.setCount( remainingCurrentSlot ); extracted.setCount( remainingCurrentSlot );
} }
extractedList.add( Pair.of( i, extracted.getCount() ) ); // Heuristic for simulation: looping in case of simulations is pointless, since the state of the
// underlying inventory does not change after a simulated extraction. To still support inventories
// that report stacks that are larger than maxStackSize, we use this heuristic
if (simulate && extracted.getCount() == extracted.getMaxStackSize()
&& remainingCurrentSlot > extracted.getMaxStackSize()) {
extracted.setCount(remainingCurrentSlot);
}
// We're just gonna use the first stack we get our hands on as the template for the rest.
// In case some stupid itemhandler (aka forge) returns an internal state we have to do a second
// expensive copy again.
if( gathered.isEmpty() ) if( gathered.isEmpty() )
{ {
gathered = extracted.copy(); gathered = extracted;
} }
else else
{ {
@@ -177,7 +178,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
remainingCurrentSlot -= extracted.getCount(); remainingCurrentSlot -= extracted.getCount();
} }
} }
while ( !extracted.isEmpty() && remainingCurrentSlot > 0 ); while( !simulate && !extracted.isEmpty() && remainingCurrentSlot > 0 );
remainingSize -= stackSizeCurrentSlot - remainingCurrentSlot; remainingSize -= stackSizeCurrentSlot - remainingCurrentSlot;
@@ -192,14 +193,13 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
{ {
if( mode == Actionable.MODULATE ) if( mode == Actionable.MODULATE )
{ {
if (this.cache.cachedAeStacks.length == 0) this.cache.update(); try
for ( Pair<Integer, Integer> pair : extractedList )
{ {
this.cache.cachedAeStacks[pair.getKey()].decStackSize( pair.getValue() ); this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
if( this.cache.cachedAeStacks[pair.getKey()].getStackSize() == 0 ) }
{ catch( GridAccessException ex )
this.cache.cachedAeStacks[pair.getKey()] = null; {
} // meh
} }
} }
@@ -71,24 +71,13 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
if( type == Actionable.MODULATE ) if( type == Actionable.MODULATE )
{ {
if (this.cache.cachedAeStacks.length == 0) this.cache.update(); try
boolean found = false;
for (IAEItemStack iaeItemStack : this.cache.cachedAeStacks)
{ {
if( iaeItemStack == null ) this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
{
continue;
}
if( iaeItemStack.equals( iox ) )
{
found = true;
iaeItemStack.incStackSize( iox.getStackSize() );
}
} }
if (!found) catch( GridAccessException ex )
{ {
this.cache.cachedAeStacks = Arrays.copyOf( this.cache.cachedAeStacks, this.cache.cachedAeStacks.length + 1 ); // meh
this.cache.cachedAeStacks[this.cache.cachedAeStacks.length - 1] = iox.copy();
} }
} }
@@ -118,27 +107,15 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
if( !extracted.isEmpty() ) if( !extracted.isEmpty() )
{ {
if (this.cache.cachedAeStacks.length == 0) this.cache.update();
IAEItemStack iaeExtracted = AEItemStack.fromItemStack( extracted );
if( mode == Actionable.MODULATE ) if( mode == Actionable.MODULATE )
{ {
for ( int i = 0; i < this.cache.cachedAeStacks.length; i++ ) try
{ {
IAEItemStack iaeItemStack = this.cache.cachedAeStacks[i]; this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
if( iaeExtracted.equals( iaeItemStack ) ) }
{ catch( GridAccessException ex )
if( iaeExtracted.getStackSize() >= iaeItemStack.getStackSize() ) {
{ // meh
iaeExtracted.decStackSize( iaeItemStack.getStackSize() );
this.cache.cachedAeStacks[i] = null;
}
else
{
iaeItemStack.decStackSize( iaeExtracted.getStackSize() );
break;
}
}
} }
} }
@@ -20,10 +20,13 @@ package appeng.util;
import appeng.util.inv.*; import appeng.util.inv.*;
import com.jaquadro.minecraft.storagedrawers.api.capabilities.IItemRepository;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
@@ -37,12 +40,23 @@ import appeng.api.config.FuzzyMode;
*/ */
public abstract class InventoryAdaptor implements Iterable<ItemSlot> public abstract class InventoryAdaptor implements Iterable<ItemSlot>
{ {
@CapabilityInject( IItemRepository.class)
public static Capability<IItemRepository> ITEM_REPOSITORY_CAPABILITY = null;
public static InventoryAdaptor getAdaptor( final TileEntity te, final EnumFacing d ) public static InventoryAdaptor getAdaptor( final TileEntity te, final EnumFacing d )
{ {
if( te != null ) if( te != null )
{ {
if( te.hasCapability( CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d ) ) if( ITEM_REPOSITORY_CAPABILITY != null && te.hasCapability( ITEM_REPOSITORY_CAPABILITY, d ) )
{ {
IItemRepository itemRepository = te.getCapability( ITEM_REPOSITORY_CAPABILITY, d );
if (itemRepository != null){
return new AdaptorItemRepository( itemRepository );
}
}
else if( te.hasCapability( CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d ) )
{
// Attempt getting an IItemHandler for the given side via caps // Attempt getting an IItemHandler for the given side via caps
IItemHandler itemHandler = te.getCapability( CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d ); IItemHandler itemHandler = te.getCapability( CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d );
if( itemHandler != null ) if( itemHandler != null )
@@ -0,0 +1,208 @@
package appeng.util.inv;
import appeng.api.config.FuzzyMode;
import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import com.jaquadro.minecraft.storagedrawers.api.capabilities.IItemRepository;
import net.minecraft.item.ItemStack;
import java.util.Iterator;
public class AdaptorItemRepository extends InventoryAdaptor
{
protected final IItemRepository itemRepository;
public AdaptorItemRepository( IItemRepository itemRepository )
{
this.itemRepository = itemRepository;
}
@Override
public ItemStack removeItems( int amount, ItemStack filter, IInventoryDestination destination )
{
ItemStack rv = ItemStack.EMPTY;
ItemStack extracted = ItemStack.EMPTY;
if( !filter.isEmpty() )
{
extracted = this.itemRepository.extractItem( filter, amount, true );
}
else
{
for( IItemRepository.ItemRecord record : this.itemRepository.getAllItems() )
{
extracted = this.itemRepository.extractItem( record.itemPrototype, amount, true );
if( !extracted.isEmpty() )
{
break;
}
}
}
if( destination != null )
{
if( extracted.isEmpty() || !destination.canInsert( extracted ) )
{
return rv;
}
}
extracted = this.itemRepository.extractItem( filter, amount, false );
return extracted;
}
@Override
public ItemStack simulateRemove( int amount, ItemStack filter, IInventoryDestination destination )
{
ItemStack rv = ItemStack.EMPTY;
ItemStack extracted = ItemStack.EMPTY;
if( !filter.isEmpty() )
{
extracted = this.itemRepository.extractItem( filter, amount, true );
}
else
{
for( IItemRepository.ItemRecord record : this.itemRepository.getAllItems() )
{
extracted = this.itemRepository.extractItem( record.itemPrototype, amount, true );
if( !extracted.isEmpty() )
{
break;
}
}
}
if( destination != null )
{
if( extracted.isEmpty() || !destination.canInsert( extracted ) )
{
return rv;
}
}
return extracted;
}
@Override
public ItemStack removeSimilarItems( int amount, ItemStack filter, FuzzyMode fuzzyMode, IInventoryDestination destination )
{
ItemStack rv = ItemStack.EMPTY;
ItemStack extracted = ItemStack.EMPTY;
for( IItemRepository.ItemRecord record : this.itemRepository.getAllItems() )
{
if( Platform.itemComparisons().isFuzzyEqualItem( record.itemPrototype, filter, fuzzyMode ) )
{
extracted = this.itemRepository.extractItem( record.itemPrototype, amount, true );
}
if( !extracted.isEmpty() )
{
break;
}
}
if( destination != null )
{
if( extracted.isEmpty() || !destination.canInsert( extracted ) )
{
return rv;
}
}
extracted = this.itemRepository.extractItem( extracted, amount, false );
return extracted;
}
@Override
public ItemStack simulateSimilarRemove( int amount, ItemStack filter, FuzzyMode fuzzyMode, IInventoryDestination destination )
{
ItemStack rv = ItemStack.EMPTY;
ItemStack extracted = ItemStack.EMPTY;
for( IItemRepository.ItemRecord record : this.itemRepository.getAllItems() )
{
if( Platform.itemComparisons().isFuzzyEqualItem( record.itemPrototype, filter, fuzzyMode ) )
{
extracted = this.itemRepository.extractItem( record.itemPrototype, amount, true );
}
if( !extracted.isEmpty() )
{
break;
}
}
if( destination != null )
{
if( extracted.isEmpty() || !destination.canInsert( extracted ) )
{
return rv;
}
}
return extracted;
}
@Override
public ItemStack addItems( ItemStack toBeAdded )
{
return this.addItems( toBeAdded, false );
}
protected ItemStack addItems( final ItemStack itemsToAdd, final boolean simulate )
{
if( itemsToAdd.isEmpty() )
{
return ItemStack.EMPTY;
}
ItemStack left = itemsToAdd.copy();
left = this.itemRepository.insertItem( left, simulate );
if( left.isEmpty() )
{
return ItemStack.EMPTY;
}
return left;
}
@Override
public ItemStack simulateAdd( ItemStack toBeSimulated )
{
return this.addItems( toBeSimulated, true );
}
@Override
public boolean containsItems()
{
return !this.itemRepository.getAllItems().isEmpty();
}
@Override
public boolean hasSlots()
{
return true;
}
@Override
public Iterator<ItemSlot> iterator()
{
return null;
}
}
@@ -25,7 +25,7 @@ import java.util.NoSuchElementException;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
public class ItemHandlerIterator implements Iterator<ItemSlot> class ItemHandlerIterator implements Iterator<ItemSlot>
{ {
private final IItemHandler itemHandler; private final IItemHandler itemHandler;
@@ -34,7 +34,7 @@ public class ItemHandlerIterator implements Iterator<ItemSlot>
private int slot = 0; private int slot = 0;
public ItemHandlerIterator( IItemHandler itemHandler ) ItemHandlerIterator( IItemHandler itemHandler )
{ {
this.itemHandler = itemHandler; this.itemHandler = itemHandler;
} }
@@ -55,8 +55,6 @@ public class ItemHandlerIterator implements Iterator<ItemSlot>
this.itemSlot.setExtractable( !this.itemHandler.extractItem( this.slot, 1, true ).isEmpty() ); this.itemSlot.setExtractable( !this.itemHandler.extractItem( this.slot, 1, true ).isEmpty() );
this.itemSlot.setItemStack( this.itemHandler.getStackInSlot( this.slot ) ); this.itemSlot.setItemStack( this.itemHandler.getStackInSlot( this.slot ) );
this.itemSlot.setSlot( this.slot ); this.itemSlot.setSlot( this.slot );
this.itemSlot.setSlotLimit( this.itemHandler.getSlotLimit( this.slot ) );
this.itemSlot.setItemHandler( this.itemHandler );
this.slot++; this.slot++;
return this.itemSlot; return this.itemSlot;
} }
@@ -23,7 +23,6 @@ import net.minecraft.item.ItemStack;
import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IAEItemStack;
import appeng.util.item.AEItemStack; import appeng.util.item.AEItemStack;
import net.minecraftforge.items.IItemHandler;
public class ItemSlot public class ItemSlot
@@ -35,25 +34,6 @@ public class ItemSlot
private IAEItemStack aeItemStack; private IAEItemStack aeItemStack;
private ItemStack itemStack; private ItemStack itemStack;
public void setItemHandler( IItemHandler itemHandler )
{
this.itemHandler = itemHandler;
}
private IItemHandler itemHandler;
public int getSlotLimit()
{
return slotLimit;
}
public void setSlotLimit( int slotLimit )
{
this.slotLimit = slotLimit;
}
private int slotLimit;
public ItemStack getItemStack() public ItemStack getItemStack()
{ {
return this.itemStack return this.itemStack
@@ -97,19 +77,4 @@ public class ItemSlot
{ {
this.slot = slot; this.slot = slot;
} }
public ItemSlot copy()
{
ItemSlot copy = new ItemSlot();
copy.setSlot( this.slot );
copy.setSlotLimit( this.slotLimit );
copy.setItemStack( this.getItemStack() );
copy.setExtractable( this.isExtractable );
copy.setItemHandler( this.itemHandler );
return copy;
}
public ItemStack simulateInsertItem( ItemStack sourceItemStack){
return this.itemHandler.insertItem( this.slot, sourceItemStack , true );
}
} }