diff --git a/gradle/scripts/dependencies.gradle b/gradle/scripts/dependencies.gradle index dd9e51310..0e2a18185 100644 --- a/gradle/scripts/dependencies.gradle +++ b/gradle/scripts/dependencies.gradle @@ -85,7 +85,6 @@ configurations { } dependencies { - compileOnly "com.jaquadro.minecraft.storagedrawers:StorageDrawers:1.12.2-5.4.2:api" compileOnly "gregtechce:gregtech:1.12.2:1.12.0.662" // installable runtime dependencies @@ -106,8 +105,6 @@ dependencies { // at runtime, use the full JEI jar runtime "mezz.jei:jei_${minecraft_version}:${jei_version}" - runtime "com.jaquadro.minecraft.storagedrawers:StorageDrawers:1.12.2-5.4.2" - runtime "com.jaquadro.minecraft.chameleon:Chameleon:1.12-4.1.3" // unit test dependencies testCompile "junit:junit:4.12" diff --git a/src/api/java/jaquadro/storagedrawers/IItemRepository.java b/src/api/java/jaquadro/storagedrawers/IItemRepository.java new file mode 100644 index 000000000..750e63cfe --- /dev/null +++ b/src/api/java/jaquadro/storagedrawers/IItemRepository.java @@ -0,0 +1,143 @@ +package com.jaquadro.minecraft.storagedrawers.api.capabilities; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.NonNullList; + +import javax.annotation.Nonnull; +import java.util.function.Predicate; + +/** + * An interface for treating an inventory as a slotless, central repository of items. + * + * For all operations that accept a predicate, if a predicate is supplied, a stored ItemStack must pass the predicate + * in order to be considered for the given operation. + * + * An IItemRepository implementation MAY relax or eliminate its own internal tests when a predicate is supplied. If + * the predicate is derived from DefaultPredicate, then the implementation MUST apply any tests it would have applied + * had no predicate been provided at all, in addition to testing the predicate itself. + */ +public interface IItemRepository +{ + /** + * Gets a list of all items in the inventory. The same item may appear multiple times with varying counts. + + * @return A list of zero or more items in the inventory. + */ + @Nonnull + NonNullList getAllItems (); + + /** + * Inserts an ItemStack into the inventory and returns the remainder. + * + * @param stack ItemStack to insert. + * @param simulate If true, the insertion is only simulated + * @param predicate See interface notes about predicates. Passing null specifies default matching. + * @return The remaining ItemStack that was not inserted. If the entire stack was accepted, returns + * ItemStack.EMPTY instead. + */ + @Nonnull + ItemStack insertItem (@Nonnull ItemStack stack, boolean simulate, Predicate predicate); + + @Nonnull + default ItemStack insertItem (@Nonnull ItemStack stack, boolean simulate) { + return insertItem(stack, simulate, null); + } + + /** + * Tries to extract the given ItemStack from the inventory. The returned value will be a matching ItemStack + * with a stack size equal to or less than amount, or the empty ItemStack if the item could not be found at all. + * The returned stack size may exceed the ItemStack's getMaxStackSize() value. + + * @param stack The item to extract. The stack size is ignored. + * @param amount Amount to extract (may be greater than the stacks max limit) + * @param simulate If true, the extraction is only simulated + * @param predicate See interface notes about predicates. Passing null specifies default matching. + * @return ItemStack extracted from the inventory, or ItemStack.EMPTY if nothing could be extracted. + */ + @Nonnull + ItemStack extractItem (@Nonnull ItemStack stack, int amount, boolean simulate, Predicate predicate); + + @Nonnull + default ItemStack extractItem (@Nonnull ItemStack stack, int amount, boolean simulate) { + return extractItem(stack, amount, simulate, null); + } + + /** + * Gets the number of items matching the given ItemStack stored by the inventory. + + * @param stack ItemStack to query. + * @param predicate See interface notes about predicates. Passing null specifies default matching. + * @return The number of stored matching items. A value of Integer.MAX_VALUE may indicate an infinite item source. + */ + default int getStoredItemCount (@Nonnull ItemStack stack, Predicate predicate) { + ItemStack amount = extractItem(stack, Integer.MAX_VALUE, true, predicate); + return amount.getCount(); + } + + default int getStoredItemCount (@Nonnull ItemStack stack) { + return getStoredItemCount(stack, null); + } + + /** + * Gets the number items matching the given ItemStack that additionally still be stored by the inventory. + * Remaining capacity may include space that is internally empty or unassigned to any given item. + * + * @param stack ItemStack to query. + * @param predicate See interface notes about predicates. Passing null specifies default matching. + * @return The available remaining space for matching items. + */ + default int getRemainingItemCapacity (@Nonnull ItemStack stack, Predicate predicate) { + stack = stack.copy(); + stack.setCount(Integer.MAX_VALUE); + ItemStack remainder = insertItem(stack, true, predicate); + return Integer.MAX_VALUE - remainder.getCount(); + } + + default int getRemainingItemCapacity (@Nonnull ItemStack stack) { + return getRemainingItemCapacity(stack, null); + } + + /** + * Gets the total inventory capacity for items matching the given ItemStack. + * Total capacity may include space that is internally empty or unassigned to any given item. + * + * @param stack ItemStack to query. + * @param predicate See interface notes about predicates. Passing null specifies default matching. + * @return The total capacity for matching items. + */ + default int getItemCapacity (@Nonnull ItemStack stack, Predicate predicate) { + long capacity = getStoredItemCount(stack, predicate) + getRemainingItemCapacity(stack, predicate); + if (capacity > Integer.MAX_VALUE) + return Integer.MAX_VALUE; + return (int)capacity; + } + + default int getItemCapacity (@Nonnull ItemStack stack) { + return getItemCapacity(stack, null); + } + + /** + * An item record representing an item and the amount stored. + * + * The ItemStack held by itemPrototype always reports a stack size of 1. + * IT IS IMPORTANT THAT YOU NEVER MODIFY itemPrototype. + */ + class ItemRecord + { + @Nonnull + public final ItemStack itemPrototype; + public final int count; + + public ItemRecord (@Nonnull ItemStack itemPrototype, int count) { + this.itemPrototype = itemPrototype; + this.count = count; + } + } + + /** + * A variant of the standard Predicate interface that when passed to IItemRepository functions, will ask the + * internal default predicate to be tested in addition to the custom predicate. An IItemRepository function + * may choose to enforce its own predicate regardless. + */ + interface DefaultPredicate extends Predicate { } +} diff --git a/src/main/java/appeng/parts/misc/PartStorageBus.java b/src/main/java/appeng/parts/misc/PartStorageBus.java index 37372d1a3..9731f13a7 100644 --- a/src/main/java/appeng/parts/misc/PartStorageBus.java +++ b/src/main/java/appeng/parts/misc/PartStorageBus.java @@ -401,10 +401,13 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC } // Check via cap for IItemRepository - IItemRepository handlerRepo = target.getCapability( ITEM_REPOSITORY_CAPABILITY, targetSide ); - if( handlerRepo != null ) + if (ITEM_REPOSITORY_CAPABILITY != null && target.hasCapability( ITEM_REPOSITORY_CAPABILITY, targetSide )) { - return new ItemRepositoryAdapter( handlerRepo, this ); + IItemRepository handlerRepo = target.getCapability( ITEM_REPOSITORY_CAPABILITY, targetSide ); + if( handlerRepo != null ) + { + return new ItemRepositoryAdapter( handlerRepo, this ); + } } // Check via cap for IItemHandler IItemHandler handlerExt = target.getCapability( CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, targetSide ); @@ -431,11 +434,14 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC return Objects.hash( target, target.getCapability( Capabilities.STORAGE_MONITORABLE_ACCESSOR, targetSide ) ); } - final IItemRepository handlerRepo = target.getCapability( ITEM_REPOSITORY_CAPABILITY, targetSide ); - - if( handlerRepo != null ) + if (ITEM_REPOSITORY_CAPABILITY != null && target.hasCapability( ITEM_REPOSITORY_CAPABILITY, targetSide )) { - return Objects.hash( target, handlerRepo, handlerRepo.getAllItems().size() ); + final IItemRepository handlerRepo = target.getCapability( ITEM_REPOSITORY_CAPABILITY, targetSide ); + + if( handlerRepo != null ) + { + return Objects.hash( target, handlerRepo, handlerRepo.getAllItems().size() ); + } } final IItemHandler itemHandler = target.getCapability( CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, targetSide ); diff --git a/src/main/java/appeng/util/InventoryAdaptor.java b/src/main/java/appeng/util/InventoryAdaptor.java index 9733abd0f..21295f575 100644 --- a/src/main/java/appeng/util/InventoryAdaptor.java +++ b/src/main/java/appeng/util/InventoryAdaptor.java @@ -47,7 +47,7 @@ public abstract class InventoryAdaptor implements Iterable { if( te != null ) { - if( te.hasCapability( ITEM_REPOSITORY_CAPABILITY, d ) ) + if( ITEM_REPOSITORY_CAPABILITY != null && te.hasCapability( ITEM_REPOSITORY_CAPABILITY, d ) ) { IItemRepository itemRepository = te.getCapability( ITEM_REPOSITORY_CAPABILITY, d ); if (itemRepository != null){