Merge branch 'rr-interfaces' into AE2-Omnifactory
This commit is contained in:
@@ -164,7 +164,6 @@ public enum AEFeature
|
||||
PATTERNS( "Patterns", 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." ),
|
||||
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 ),
|
||||
ADVANCED_CARDS( "AdvancedCards", Constants.CATEGORY_UPGRADES ),
|
||||
|
||||
@@ -19,18 +19,13 @@
|
||||
package appeng.helpers;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
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 java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import appeng.integration.modules.gregtech.GTCEInventoryAdaptor;
|
||||
import appeng.util.*;
|
||||
import appeng.util.inv.*;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import gregtech.api.block.machines.BlockMachine;
|
||||
@@ -93,8 +88,6 @@ import appeng.api.util.AEPartLocation;
|
||||
import appeng.api.util.DimensionalCoord;
|
||||
import appeng.api.util.IConfigManager;
|
||||
import appeng.capabilities.Capabilities;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.core.features.AEFeature;
|
||||
import appeng.core.settings.TickRates;
|
||||
import appeng.me.GridAccessException;
|
||||
import appeng.me.helpers.AENetworkProxy;
|
||||
@@ -106,10 +99,6 @@ import appeng.parts.automation.StackUpgradeInventory;
|
||||
import appeng.parts.automation.UpgradeInventory;
|
||||
import appeng.tile.inventory.AppEngInternalAEInventory;
|
||||
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 static gregtech.api.block.machines.BlockMachine.getMetaTileEntity;
|
||||
@@ -117,8 +106,6 @@ import static gregtech.api.block.machines.BlockMachine.getMetaTileEntity;
|
||||
|
||||
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_CONFIG_SLOTS = 9;
|
||||
public static final int NUMBER_OF_PATTERN_SLOTS = 9;
|
||||
@@ -148,8 +135,8 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
private IMEInventory<IAEItemStack> destination;
|
||||
private int isWorking = -1;
|
||||
private final Accessor accessor = new Accessor();
|
||||
private GTCEInventoryAdaptor GTad;
|
||||
EnumSet<EnumFacing> visitedFaces = EnumSet.noneOf( EnumFacing.class );
|
||||
private EnumSet<EnumFacing> visitedFaces = EnumSet.noneOf( EnumFacing.class );
|
||||
private EnumMap<EnumFacing,List<ItemStack>> waitingToSendFacing = new EnumMap<>(EnumFacing.class);
|
||||
|
||||
public DualityInterface( final AENetworkProxy networkProxy, final IInterfaceHost ih )
|
||||
{
|
||||
@@ -243,6 +230,27 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
}
|
||||
}
|
||||
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 )
|
||||
@@ -262,6 +270,23 @@ 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.upgrades.readFromNBT( data, "upgrades" );
|
||||
this.config.readFromNBT( data, "config" );
|
||||
@@ -297,6 +322,30 @@ 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()
|
||||
{
|
||||
this.hasConfig = false;
|
||||
@@ -394,24 +443,22 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasWorkToDo()
|
||||
{
|
||||
if( this.hasItemsToSend() )
|
||||
{
|
||||
private boolean hasWorkToDo() {
|
||||
|
||||
if (hasItemsToSend()){
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( final IAEItemStack requiredWork : this.requireWork )
|
||||
{
|
||||
if( requiredWork != null )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
if(hasItemsToSendFacing()){
|
||||
return true;
|
||||
}
|
||||
|
||||
for (final IAEItemStack requiredWork : this.requireWork) {
|
||||
if (requiredWork != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void updatePlan( final int slot )
|
||||
@@ -516,6 +563,21 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
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
|
||||
public boolean canInsert( final ItemStack stack )
|
||||
{
|
||||
@@ -587,11 +649,21 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
return TickRateModulation.SLEEP;
|
||||
}
|
||||
|
||||
//Previous version might have items saved in this list
|
||||
//recover them
|
||||
if( this.hasItemsToSend() )
|
||||
{
|
||||
this.pushItemsOut( this.iHost.getTargets() );
|
||||
}
|
||||
|
||||
if (hasItemsToSendFacing())
|
||||
{
|
||||
for( EnumFacing enumFacing : waitingToSendFacing.keySet() )
|
||||
{
|
||||
this.pushItemsOut( enumFacing );
|
||||
}
|
||||
}
|
||||
|
||||
final boolean couldDoWork = this.updateStorage();
|
||||
return this.hasWorkToDo() ? ( couldDoWork ? TickRateModulation.URGENT : TickRateModulation.SLOWER ) : TickRateModulation.SLEEP;
|
||||
}
|
||||
@@ -652,6 +724,47 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
}
|
||||
}
|
||||
|
||||
private void pushItemsOut( final EnumFacing s )
|
||||
{
|
||||
if( this.waitingToSendFacing.get(s) == null || 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.get( s ).clear();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean updateStorage()
|
||||
{
|
||||
boolean didSomething = false;
|
||||
@@ -771,17 +884,8 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
{
|
||||
if( this.getInstalledUpgrades( Upgrades.CRAFTING ) > 0 && itemStack != null )
|
||||
{
|
||||
if (this.failedCraftTriesSlot[x] <= 0)
|
||||
{
|
||||
boolean crafted = this.craftingTracker.handleCrafting( x, itemStack.getStackSize(), itemStack, d, this.iHost.getTileEntity().getWorld(),
|
||||
return this.craftingTracker.handleCrafting( x, itemStack.getStackSize(), itemStack, d, this.iHost.getTileEntity().getWorld(),
|
||||
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 )
|
||||
@@ -914,24 +1018,28 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
};
|
||||
}
|
||||
|
||||
private static boolean invIsBlocked( InventoryAdaptor inv )
|
||||
private boolean invIsBlocked( InventoryAdaptor inv )
|
||||
{
|
||||
if( AEConfig.instance().isFeatureEnabled( AEFeature.INSANE_BLOCKING_MODE ) )
|
||||
final Iterator<ICraftingPatternDetails> i = this.craftingList.iterator();
|
||||
ICraftingPatternDetails patt = i.next();
|
||||
for ( ItemSlot itemSlot : inv)
|
||||
{
|
||||
return !inv.simulateRemove( 1, ItemStack.EMPTY, null ).isEmpty();
|
||||
if (itemSlot.getItemStack().isEmpty()){
|
||||
continue;
|
||||
}
|
||||
for ( IAEItemStack iaeItemStack : patt.getCondensedInputs()){
|
||||
if (iaeItemStack.isSameType( itemSlot.getItemStack() )){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else return inv.containsItems();
|
||||
}
|
||||
|
||||
private static boolean invIsBlockedGTCE( GTCEInventoryAdaptor inv )
|
||||
{
|
||||
return ( !inv.canRemoveAllExceptCircuits() );
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pushPattern( final ICraftingPatternDetails patternDetails, final InventoryCrafting table )
|
||||
{
|
||||
if( this.hasItemsToSend() || !this.gridProxy.isActive() || !this.craftingList.contains( patternDetails ) )
|
||||
if( this.hasItemsToSend() || this.hasItemsToSendFacing() || !this.gridProxy.isActive() || !this.craftingList.contains( patternDetails ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -939,13 +1047,13 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
final TileEntity tile = this.iHost.getTileEntity();
|
||||
final World w = tile.getWorld();
|
||||
|
||||
final EnumSet<EnumFacing> possibleDirections = this.iHost.getTargets();
|
||||
|
||||
for( final EnumFacing s : possibleDirections )
|
||||
if( this.visitedFaces.isEmpty() )
|
||||
{
|
||||
if (visitedFaces.contains( s ))
|
||||
continue;
|
||||
this.visitedFaces = this.iHost.getTargets();
|
||||
}
|
||||
|
||||
for( final EnumFacing s : visitedFaces )
|
||||
{
|
||||
final TileEntity te = w.getTileEntity( tile.getPos().offset( s ) );
|
||||
if( te instanceof IInterfaceHost )
|
||||
{
|
||||
@@ -953,6 +1061,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
{
|
||||
if( ( (IInterfaceHost) te ).getInterfaceDuality().sameGrid( this.gridProxy.getGrid() ) )
|
||||
{
|
||||
visitedFaces.remove( s );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -969,9 +1078,10 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
{
|
||||
if( cm.pushPattern( patternDetails, table, s.getOpposite() ) )
|
||||
{
|
||||
visitedFaces.add( s );
|
||||
visitedFaces.remove( s );
|
||||
return true;
|
||||
}
|
||||
visitedFaces.remove( s );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -979,57 +1089,45 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
|
||||
if( ad != null )
|
||||
{
|
||||
boolean isDrawer = te.getBlockType().getRegistryName().getResourceDomain().equals( "storagedrawers" );
|
||||
if( this.isBlocking() )
|
||||
{
|
||||
if( te.getBlockType().getRegistryName().getResourceDomain().equals( "gregtech" ) )
|
||||
if( invIsBlocked( ad ) )
|
||||
{
|
||||
GTad = GTCEInventoryAdaptor.getAdaptor( te, s.getOpposite() );
|
||||
if( invIsBlockedGTCE( GTad ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( invIsBlocked( ad ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if( this.acceptsItems( ad, table ) )
|
||||
if( this.acceptsItems( ad, patternDetails, isDrawer ) )
|
||||
{
|
||||
for( int x = 0; x < table.getSizeInventory(); x++ )
|
||||
{
|
||||
final ItemStack is = table.getStackInSlot( x );
|
||||
if( !is.isEmpty() )
|
||||
{
|
||||
final ItemStack added = ad.addItems( is );
|
||||
this.addToSendList( added );
|
||||
addToSendListFacing( is, s );
|
||||
}
|
||||
pushItemsOut( s );
|
||||
}
|
||||
this.pushItemsOut( possibleDirections );
|
||||
visitedFaces.add( s );
|
||||
visitedFaces.remove( s );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
visitedFaces.remove( s );
|
||||
}
|
||||
visitedFaces.clear();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBusy()
|
||||
{
|
||||
if( this.hasItemsToSend() )
|
||||
boolean busy = false;
|
||||
|
||||
if( this.hasItemsToSend() || hasItemsToSendFacing() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean busy = false;
|
||||
|
||||
if( this.isBlocking() )
|
||||
{
|
||||
final EnumSet<EnumFacing> possibleDirections = this.iHost.getTargets();
|
||||
@@ -1045,23 +1143,10 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
|
||||
if( ad != null )
|
||||
{
|
||||
if( te.getBlockType().getRegistryName().getResourceDomain().equals( "gregtech" ) )
|
||||
if( !invIsBlocked( ad ) )
|
||||
{
|
||||
GTad = GTCEInventoryAdaptor.getAdaptor( te, s.getOpposite() );
|
||||
if( !invIsBlockedGTCE( GTad ) )
|
||||
{
|
||||
allAreBusy = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !invIsBlocked( ad ) )
|
||||
{
|
||||
allAreBusy = false;
|
||||
break;
|
||||
}
|
||||
|
||||
allAreBusy = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1080,23 +1165,85 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
return this.cm.getSetting( Settings.BLOCK ) == YesNo.YES;
|
||||
}
|
||||
|
||||
private boolean acceptsItems( final InventoryAdaptor ad, final InventoryCrafting table )
|
||||
private boolean acceptsItems( final InventoryAdaptor ad, final ICraftingPatternDetails patternDetails, boolean isDrawer )
|
||||
{
|
||||
for( int x = 0; x < table.getSizeInventory(); x++ )
|
||||
List<ItemStack> patternedStacks = Arrays.stream( patternDetails.getCondensedInputs() ).map( IAEItemStack::createItemStack ).collect( Collectors.toList() );
|
||||
List<ItemSlot> copiedItemSlots = new ArrayList<>();
|
||||
|
||||
if( patternedStacks.size() == 1 )
|
||||
{
|
||||
final ItemStack is = table.getStackInSlot( x );
|
||||
if( is.isEmpty() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !ad.simulateAdd( is.copy() ).isEmpty() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return ad.simulateAdd( patternedStacks.get( 0 ) ).isEmpty();
|
||||
}
|
||||
else
|
||||
{
|
||||
Iterator<ItemSlot> adit = ad.iterator();
|
||||
while ( adit.hasNext() )
|
||||
{
|
||||
ItemSlot is = adit.next();
|
||||
//skip storage drawers slot 0 to avoid voiding items due to broken itemhandler implementation
|
||||
if( isDrawer && is.getSlot() == 0 ) is = adit.next();
|
||||
|
||||
return true;
|
||||
//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.
|
||||
if( is.getItemStack().isEmpty() )
|
||||
{
|
||||
boolean validInputSlotForIngredients = false;
|
||||
for( IAEItemStack aeItemStack : patternDetails.getCondensedInputs() )
|
||||
{
|
||||
if( is.insertItem( aeItemStack.getDefinition() ).isEmpty() )
|
||||
{
|
||||
validInputSlotForIngredients = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( validInputSlotForIngredients )
|
||||
{
|
||||
copiedItemSlots.add( is.copy() );
|
||||
}
|
||||
}
|
||||
else if( !is.getItemStack().isEmpty() && is.getItemStack().getCount() < is.getSlotLimit() )
|
||||
{
|
||||
copiedItemSlots.add( is.copy() );
|
||||
}
|
||||
}
|
||||
Iterator<ItemSlot> copiedItemSlotIterator = copiedItemSlots.iterator();
|
||||
while ( copiedItemSlotIterator.hasNext() )
|
||||
{
|
||||
ItemSlot copiedItemSlot = copiedItemSlotIterator.next();
|
||||
|
||||
Iterator<ItemStack> psi = patternedStacks.iterator();
|
||||
while ( psi.hasNext() )
|
||||
{
|
||||
ItemStack patternedStack = psi.next();
|
||||
ItemStack remainder = copiedItemSlot.insertItem( patternedStack );
|
||||
|
||||
if( !remainder.isEmpty() )
|
||||
{
|
||||
patternedStack.setCount( patternedStack.getCount() - ( patternedStack.getCount() - remainder.getCount() ) );
|
||||
if( copiedItemSlot.getSlotLimit() == copiedItemSlot.getItemStack().getCount() )
|
||||
{
|
||||
copiedItemSlotIterator.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( copiedItemSlot.getSlotLimit() == copiedItemSlot.getItemStack().getCount() )
|
||||
{
|
||||
copiedItemSlotIterator.remove();
|
||||
}
|
||||
psi.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( patternedStacks.size() == 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
package appeng.integration.modules.gregtech;
|
||||
|
||||
import appeng.util.inv.ItemSlot;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
public abstract class GTCEInventoryAdaptor implements Iterable<ItemSlot>
|
||||
{
|
||||
public static GTCEInventoryAdaptor getAdaptor(final TileEntity te, final EnumFacing d)
|
||||
{
|
||||
if (te != null && te.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d))
|
||||
{
|
||||
// Attempt getting an IItemHandler for the given side via caps
|
||||
IItemHandler itemHandler = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d);
|
||||
if (itemHandler != null)
|
||||
{
|
||||
return new GTCEItemHandler(itemHandler);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract boolean canRemoveAllExceptCircuits();
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package appeng.integration.modules.gregtech;
|
||||
|
||||
import appeng.util.inv.ItemSlot;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
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> 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 creativePortableTankMold = Item.getByNameOrId("contenttweaker:creativeportabletankmold");
|
||||
|
||||
protected final IItemHandler itemHandler;
|
||||
|
||||
public GTCEItemHandler(IItemHandler itemHandler)
|
||||
{
|
||||
this.itemHandler = itemHandler;
|
||||
}
|
||||
|
||||
boolean isBlockableItem(ItemStack stack)
|
||||
{
|
||||
if ( stack.getItem() == Item.getByNameOrId("gregtech:meta_item_1") ) {
|
||||
int metadata = stack.getItemDamage();
|
||||
if ( metadata == 32766 || GTCElenses.contains(metadata) || GTCEmolds.contains(metadata)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ( stack.getItem() == smallGearExtruderShape ) return false;
|
||||
if ( stack.getItem() == creativePortableTankMold) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRemoveAllExceptCircuits()
|
||||
{
|
||||
int slots = this.itemHandler.getSlots();
|
||||
for ( int slot = 0; slot < slots; slot++ ) {
|
||||
ItemStack is = this.itemHandler.getStackInSlot(slot);
|
||||
if ( is.isEmpty() || !isBlockableItem(is) ) continue;
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<ItemSlot> iterator()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -19,13 +19,9 @@
|
||||
package appeng.me.cluster.implementations;
|
||||
|
||||
|
||||
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.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
@@ -34,8 +30,6 @@ import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.Actionable;
|
||||
@@ -93,7 +87,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
||||
private final List<TileCraftingTile> storage = new ArrayList<>();
|
||||
private final List<TileCraftingMonitorTile> status = new ArrayList<>();
|
||||
private final HashMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap<>();
|
||||
private final Map<ICraftingPatternDetails,List<ICraftingMedium>> visitedMediums = new HashMap<>();
|
||||
private final Map<ICraftingPatternDetails, Queue<ICraftingMedium>> visitedMediums = new HashMap<>();
|
||||
private ICraftingLink myLastLink;
|
||||
private String myName = "";
|
||||
private boolean isDestroyed = false;
|
||||
@@ -647,30 +641,22 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
||||
{
|
||||
InventoryCrafting ic = null;
|
||||
|
||||
for( final ICraftingMedium m : cc.getMediums( e.getKey() ) )
|
||||
if (!visitedMediums.containsKey( details ) || visitedMediums.get( details ).isEmpty())
|
||||
{
|
||||
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 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (visitedMediums.containsKey( details ))
|
||||
{
|
||||
if( visitedMediums.get( details ).containsAll( cc.getMediums( e.getKey() ) ) )
|
||||
{
|
||||
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( m != null && !m.isBusy() )
|
||||
{
|
||||
if( ic == null )
|
||||
{
|
||||
|
||||
@@ -70,8 +70,6 @@ import appeng.util.item.AEItemStack;
|
||||
|
||||
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" );
|
||||
|
||||
@PartModels
|
||||
@@ -142,7 +140,7 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
|
||||
|
||||
if( destination != null )
|
||||
{
|
||||
int x = 0;
|
||||
int x;
|
||||
|
||||
for( x = 0; x < this.availableSlots() && this.itemToSend > 0; x++ )
|
||||
{
|
||||
@@ -153,16 +151,8 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
|
||||
if( ais == null || this.itemToSend <= 0 ) continue;
|
||||
|
||||
if ( this.craftOnly() ) {
|
||||
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;
|
||||
|
||||
if (this.didSomething) this.failedCraftTriesSlot[x] = 0;
|
||||
else this.failedCraftTriesSlot[x] += 2;
|
||||
}
|
||||
this.failedCraftTriesSlot[x] -= 1;
|
||||
continue;
|
||||
this.didSomething = this.craftingTracker.handleCrafting(slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(),
|
||||
this.getProxy().getGrid(), cg, this.mySrc) || this.didSomething;
|
||||
}
|
||||
|
||||
final long before = this.itemToSend;
|
||||
@@ -185,15 +175,8 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
|
||||
|
||||
if( this.itemToSend == before && this.isCraftingEnabled() )
|
||||
{
|
||||
if (this.failedCraftTriesSlot[x] <= 0) {
|
||||
|
||||
this.didSomething = this.craftingTracker.handleCrafting(slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(),
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -142,14 +142,6 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
extracted = this.itemHandler.extractItem( i, remainingCurrentSlot, simulate );
|
||||
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 )
|
||||
{
|
||||
// Something broke. It should never return more than we requested...
|
||||
@@ -159,17 +151,12 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
extracted.setCount( remainingCurrentSlot );
|
||||
}
|
||||
|
||||
// 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() )
|
||||
{
|
||||
gathered = extracted;
|
||||
gathered = extracted.copy();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -178,7 +165,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
remainingCurrentSlot -= extracted.getCount();
|
||||
}
|
||||
}
|
||||
while( !simulate && !extracted.isEmpty() && remainingCurrentSlot > 0 );
|
||||
while( !extracted.isEmpty() && remainingCurrentSlot > 0 );
|
||||
|
||||
remainingSize -= stackSizeCurrentSlot - remainingCurrentSlot;
|
||||
|
||||
|
||||
@@ -20,13 +20,10 @@ package appeng.util;
|
||||
|
||||
|
||||
import appeng.util.inv.*;
|
||||
import com.jaquadro.minecraft.storagedrawers.api.capabilities.IItemRepository;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
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.IItemHandler;
|
||||
|
||||
@@ -40,23 +37,12 @@ import appeng.api.config.FuzzyMode;
|
||||
*/
|
||||
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 )
|
||||
{
|
||||
if( te != null )
|
||||
{
|
||||
if( ITEM_REPOSITORY_CAPABILITY != null && te.hasCapability( ITEM_REPOSITORY_CAPABILITY, d ) )
|
||||
if( te.hasCapability( CapabilityItemHandler.ITEM_HANDLER_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
|
||||
IItemHandler itemHandler = te.getCapability( CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d );
|
||||
if( itemHandler != null )
|
||||
|
||||
@@ -1,208 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,8 @@ class ItemHandlerIterator implements Iterator<ItemSlot>
|
||||
this.itemSlot.setExtractable( !this.itemHandler.extractItem( this.slot, 1, true ).isEmpty() );
|
||||
this.itemSlot.setItemStack( this.itemHandler.getStackInSlot( this.slot ) );
|
||||
this.itemSlot.setSlot( this.slot );
|
||||
this.itemSlot.setSlotLimit( this.itemHandler.getSlotLimit( this.slot ) );
|
||||
this.itemSlot.setItemHandler( this.itemHandler );
|
||||
this.slot++;
|
||||
return this.itemSlot;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import net.minecraft.item.ItemStack;
|
||||
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
|
||||
public class ItemSlot
|
||||
@@ -34,6 +35,25 @@ public class ItemSlot
|
||||
private IAEItemStack aeItemStack;
|
||||
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()
|
||||
{
|
||||
return this.itemStack
|
||||
@@ -77,4 +97,19 @@ public class ItemSlot
|
||||
{
|
||||
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 insertItem( ItemStack sourceItemStack){
|
||||
return this.itemHandler.insertItem( this.slot, sourceItemStack , true );
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user