Skip to content

Commit

Permalink
Support slotless item handlers for item transfer
Browse files Browse the repository at this point in the history
  • Loading branch information
rubensworks committed Jan 16, 2017
1 parent 68c11cb commit 034c933
Show file tree
Hide file tree
Showing 9 changed files with 190 additions and 42 deletions.
6 changes: 3 additions & 3 deletions build.properties
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
mod_version=1.0.3
minecraft_version=1.10.2
forge_version=12.18.1.2091
forge_version=12.18.2.2116
mcp_mappings_version=snapshot_20160701
cyclopscore_version=0.9.0-464
cyclopscore_version=0.9.0-470
integrateddynamics_version=0.6.6-396
release_type=release

commoncapabilities_version=1.2.0-44
commoncapabilities_version=1.2.2-74
teslaapi_version=1.2.1.46
3 changes: 3 additions & 0 deletions src/main/java/org/cyclops/integratedtunnels/Capabilities.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject;
import org.cyclops.commoncapabilities.api.capability.inventorystate.IInventoryState;
import org.cyclops.commoncapabilities.api.capability.itemhandler.ISlotlessItemHandler;
import org.cyclops.integrateddynamics.api.network.IEnergyNetwork;

/**
Expand All @@ -17,6 +18,8 @@ public class Capabilities {
public static Capability<IEnergyNetwork> NETWORK_ENERGY = null;
@CapabilityInject(IInventoryState.class)
public static Capability<IInventoryState> INVENTORY_STATE = null;
@CapabilityInject(ISlotlessItemHandler.class)
public static Capability<ISlotlessItemHandler> SLOTLESS_ITEMHANDLER = null;

@CapabilityInject(ITeslaConsumer.class)
public static Capability<ITeslaConsumer> TESLA_CONSUMER = null;
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/cyclops/integratedtunnels/Reference.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class Reference {
// MOD ID's
public static final String MOD_FORGE = "Forge";
public static final String MOD_FORGE_VERSION = "@FORGE_VERSION@";
public static final String MOD_FORGE_VERSION_MIN = "12.18.1.2091";
public static final String MOD_FORGE_VERSION_MIN = "12.18.2.2116";
public static final String MOD_CYCLOPSCORE = "cyclopscore";
public static final String MOD_CYCLOPSCORE_VERSION = "@CYCLOPSCORE_VERSION@";
public static final String MOD_CYCLOPSCORE_VERSION_MIN = "0.9.0";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package org.cyclops.integratedtunnels.api.network;

import net.minecraftforge.items.IItemHandler;
import org.cyclops.commoncapabilities.api.capability.itemhandler.ISlotlessItemHandler;
import org.cyclops.integrateddynamics.api.network.IPositionedAddonsNetwork;

/**
* A network capability that holds items.
* @author rubensworks
*/
public interface IItemNetwork extends IPositionedAddonsNetwork, IItemHandler {
public interface IItemNetwork extends IPositionedAddonsNetwork, IItemHandler, ISlotlessItemHandler {

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import org.cyclops.commoncapabilities.api.capability.inventorystate.IInventoryState;
import org.cyclops.commoncapabilities.api.capability.itemhandler.ISlotlessItemHandler;
import org.cyclops.cyclopscore.modcompat.capabilities.DefaultCapabilityProvider;
import org.cyclops.integrateddynamics.Reference;
import org.cyclops.integrateddynamics.api.network.AttachCapabilitiesEventNetwork;
Expand All @@ -31,6 +32,8 @@ public void onNetworkLoad(AttachCapabilitiesEventNetwork event) {
new DefaultCapabilityProvider<IItemHandler>(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, itemNetwork));
event.addCapability(new ResourceLocation(Reference.MOD_ID, "inventoryStateItemNetwork"),
new DefaultCapabilityProvider<IInventoryState>(Capabilities.INVENTORY_STATE, itemNetwork));
event.addCapability(new ResourceLocation(Reference.MOD_ID, "itemStorageSlotlessNetwork"),
new DefaultCapabilityProvider<ISlotlessItemHandler>(Capabilities.SLOTLESS_ITEMHANDLER, itemNetwork));

FluidNetwork fluidNetwork = new FluidNetwork();
event.addCapability(new ResourceLocation(Reference.MOD_ID, "fluidNetwork"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.cyclops.integratedtunnels.core;

import com.google.common.base.Predicate;
import net.minecraft.item.ItemStack;

/**
* A predicate for matching ItemStacks.
* @author rubensworks
*/
public abstract class ItemStackPredicate implements Predicate<ItemStack> {

private final ItemStack itemStack;
private final int matchFlags;

public ItemStackPredicate(ItemStack itemStack, int matchFlags) {
this.itemStack = itemStack;
this.matchFlags = matchFlags;
}

public ItemStackPredicate() {
this(null, -1);
}

public ItemStack getItemStack() {
return itemStack;
}

public int getMatchFlags() {
return matchFlags;
}

public boolean hasMatchFlags() {
return getMatchFlags() >= 0;
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package org.cyclops.integratedtunnels.core;

import com.google.common.base.Objects;
import com.google.common.base.Predicate;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
import org.cyclops.commoncapabilities.api.capability.inventorystate.IInventoryState;
import org.cyclops.commoncapabilities.api.capability.itemhandler.ISlotlessItemHandler;
import org.cyclops.commoncapabilities.api.capability.itemhandler.ItemMatch;
import org.cyclops.cyclopscore.helper.L10NHelpers;
import org.cyclops.cyclopscore.helper.MinecraftHelpers;
import org.cyclops.integrateddynamics.api.evaluate.EvaluationException;
Expand All @@ -30,7 +31,7 @@
*/
public class TunnelItemHelpers {

public static final Predicate<ItemStack> MATCH_ALL = new Predicate<ItemStack>() {
public static final ItemStackPredicate MATCH_ALL = new ItemStackPredicate(null, ItemMatch.ANY) {
@Override
public boolean apply(@Nullable ItemStack input) {
return true;
Expand All @@ -47,22 +48,42 @@ public boolean apply(@Nullable ItemStack input) {
* Move items from source to target.
* @param source The source item handler.
* @param sourceSlot The source slot.
* @param sourceSlotless The slotless source item handler.
* @param target The target item handler.
* @param targetSlot The target slot.
* @param targetSlotless The slotless target item handler.
* @param amount The maximum item amount to transfer.
* @param itemStackMatcher Only itemstack matching this predicate will be moved.
* @param simulate If the transfer should be simulated.
* @return The moved itemstack.
*/
public static ItemStack moveItemsSingle(IItemHandler source, int sourceSlot, IItemHandler target, int targetSlot,
int amount, Predicate<ItemStack> itemStackMatcher, boolean simulate) {
public static ItemStack moveItemsSingle(IItemHandler source, int sourceSlot, @Nullable ISlotlessItemHandler sourceSlotless,
IItemHandler target, int targetSlot, @Nullable ISlotlessItemHandler targetSlotless,
int amount, ItemStackPredicate itemStackMatcher, boolean simulate) {
boolean loopSourceSlots = sourceSlot < 0;
boolean loopTargetSlots = targetSlot < 0;

if (!loopSourceSlots && !loopTargetSlots) {
ItemStack extracted = source.extractItem(sourceSlot, amount, simulate);
if (extracted != null && (!simulate || itemStackMatcher.apply(extracted))) {
ItemStack remaining = target.insertItem(targetSlot, extracted, simulate);
if ((!loopSourceSlots || (sourceSlotless != null && itemStackMatcher.hasMatchFlags())) // Only use slotless source for match flags
&& (!loopTargetSlots || targetSlotless != null)) {
ItemStack extracted;
boolean appliedMatcher = false;
if (loopSourceSlots && itemStackMatcher.hasMatchFlags()) { // In this case it is implied that sourceSlotless != null
if (itemStackMatcher.getItemStack() == null) {
extracted = sourceSlotless.extractItem(amount, simulate);
appliedMatcher = true;
} else {
ItemStack itemStack = itemStackMatcher.getItemStack();
if (itemStack != null && itemStack.stackSize != amount) {
itemStack.stackSize = amount;
}
extracted = sourceSlotless.extractItem(itemStack, itemStackMatcher.getMatchFlags(), simulate);
appliedMatcher = true;
}
} else {
extracted = source.extractItem(sourceSlot, amount, simulate);
}
if (extracted != null && (!simulate || appliedMatcher || itemStackMatcher.apply(extracted))) {
ItemStack remaining = !loopTargetSlots ? target.insertItem(targetSlot, extracted, simulate) : targetSlotless.insertItem(extracted, simulate);
if (remaining == null) {
return extracted;
} else {
Expand All @@ -77,21 +98,21 @@ public static ItemStack moveItemsSingle(IItemHandler source, int sourceSlot, IIt
if (source.getStackInSlot(sourceSlot) != null) {
for (targetSlot = 0; targetSlot < target.getSlots(); targetSlot++) {
if (!simulate) {
ItemStack movedSimulated = moveItemsSingle(source, sourceSlot, target, targetSlot, amount, itemStackMatcher, true);
ItemStack movedSimulated = moveItemsSingle(source, sourceSlot, sourceSlotless, target, targetSlot, targetSlotless, amount, itemStackMatcher, true);
if (movedSimulated == null) continue;
}
ItemStack moved = moveItemsSingle(source, sourceSlot, target, targetSlot, amount, itemStackMatcher, simulate);
ItemStack moved = moveItemsSingle(source, sourceSlot, sourceSlotless, target, targetSlot, targetSlotless, amount, itemStackMatcher, simulate);
if (moved != null) {
return moved;
}
}
}
} else {
if (!simulate) {
ItemStack movedSimulated = moveItemsSingle(source, sourceSlot, target, targetSlot, amount, itemStackMatcher, true);
ItemStack movedSimulated = moveItemsSingle(source, sourceSlot, sourceSlotless, target, targetSlot, targetSlotless, amount, itemStackMatcher, true);
if (movedSimulated == null) continue;
}
ItemStack moved = moveItemsSingle(source, sourceSlot, target, targetSlot, amount, itemStackMatcher, simulate);
ItemStack moved = moveItemsSingle(source, sourceSlot, sourceSlotless, target, targetSlot, targetSlotless, amount, itemStackMatcher, simulate);
if (moved != null) {
return moved;
}
Expand All @@ -100,10 +121,10 @@ public static ItemStack moveItemsSingle(IItemHandler source, int sourceSlot, IIt
} else if (loopTargetSlots) {
for (targetSlot = 0; targetSlot < target.getSlots(); targetSlot++) {
if (!simulate) {
ItemStack movedSimulated = moveItemsSingle(source, sourceSlot, target, targetSlot, amount, itemStackMatcher, true);
ItemStack movedSimulated = moveItemsSingle(source, sourceSlot, sourceSlotless, target, targetSlot, targetSlotless, amount, itemStackMatcher, true);
if (movedSimulated == null) continue;
}
ItemStack moved = moveItemsSingle(source, sourceSlot, target, targetSlot, amount, itemStackMatcher, simulate);
ItemStack moved = moveItemsSingle(source, sourceSlot, sourceSlotless, target, targetSlot, targetSlotless, amount, itemStackMatcher, simulate);
if (moved != null) {
return moved;
}
Expand Down Expand Up @@ -160,17 +181,21 @@ public static int calculateInventoryState(IItemHandler itemHandler, @Nullable II
* Move items from source to target.
* @param source The source item handler.
* @param sourceSlot The source slot.
* @param sourceSlotless The slotless source item handler.
* @param target The target item handler.
* @param targetSlot The target slot.
* @param targetSlotless The slotless target item handler.
* @param amount The maximum item amount to transfer.
* @return The moved itemstack.
*/
public static ItemStack moveItems(IItemHandler source, int sourceSlot, IItemHandler target, int targetSlot, int amount) {
ItemStack simulatedTransfer = moveItemsSingle(source, sourceSlot, target, targetSlot, amount, MATCH_ALL, true);
public static ItemStack moveItems(IItemHandler source, int sourceSlot, @Nullable ISlotlessItemHandler sourceSlotless,
IItemHandler target, int targetSlot, @Nullable ISlotlessItemHandler targetSlotless,
int amount) {
ItemStack simulatedTransfer = moveItemsSingle(source, sourceSlot, sourceSlotless, target, targetSlot, targetSlotless, amount, MATCH_ALL, true);
if (simulatedTransfer == null) {
return null;
}
return moveItemsSingle(source, sourceSlot, target, targetSlot, simulatedTransfer.stackSize, MATCH_ALL, false);
return moveItemsSingle(source, sourceSlot, sourceSlotless, target, targetSlot, targetSlotless, simulatedTransfer.stackSize, MATCH_ALL, false);
}

/**
Expand All @@ -179,17 +204,19 @@ public static ItemStack moveItems(IItemHandler source, int sourceSlot, IItemHand
* @param sourceHandler The source item handler.
* @param sourceInvState Optional inventory state of the source.
* @param sourceSlot The source slot.
* @param sourceSlotless The slotless source item handler.
* @param targetHandler The target item handler.
* @param targetInvState Optional inventory state of the target.
* @param targetSlot The target slot.
* @param targetSlotless The slotless target item handler.
* @param amount The maximum item amount to transfer.
* @param itemStackMatcher Only itemstack matching this predicate will be moved.
* @return The moved itemstack.
*/
public static ItemStack moveItemsStateOptimized(int connectionHash,
IItemHandler sourceHandler, @Nullable IInventoryState sourceInvState, int sourceSlot,
IItemHandler targetHandler, @Nullable IInventoryState targetInvState, int targetSlot,
int amount, Predicate<ItemStack> itemStackMatcher) {
IItemHandler sourceHandler, @Nullable IInventoryState sourceInvState, int sourceSlot, @Nullable ISlotlessItemHandler sourceSlotless,
IItemHandler targetHandler, @Nullable IInventoryState targetInvState, int targetSlot, @Nullable ISlotlessItemHandler targetSlotless,
int amount, ItemStackPredicate itemStackMatcher) {
Integer cachedState = getCachedState(connectionHash);

boolean calculatedStates = false;
Expand All @@ -206,7 +233,7 @@ public static ItemStack moveItemsStateOptimized(int connectionHash,

// If cache miss or a cache state is different
if (shouldMoveItems) {
ItemStack simulatedTransfer = moveItemsSingle(sourceHandler, sourceSlot, targetHandler, targetSlot, amount, itemStackMatcher, true);
ItemStack simulatedTransfer = moveItemsSingle(sourceHandler, sourceSlot, sourceSlotless, targetHandler, targetSlot, targetSlotless, amount, itemStackMatcher, true);

// If transfer failed, cache the current states and return
if (simulatedTransfer == null) {
Expand All @@ -218,24 +245,28 @@ public static ItemStack moveItemsStateOptimized(int connectionHash,
}

invalidateCachedState(connectionHash);
return moveItemsSingle(sourceHandler, sourceSlot, targetHandler, targetSlot, simulatedTransfer.stackSize, itemStackMatcher, false);
return moveItemsSingle(sourceHandler, sourceSlot, sourceSlotless, targetHandler, targetSlot, targetSlotless, simulatedTransfer.stackSize, itemStackMatcher, false);
}
return null;
}

public static Predicate<ItemStack> matchItemStack(final ItemStack itemStack, final boolean checkStackSize,
public static ItemStackPredicate matchItemStack(final ItemStack itemStack, final boolean checkStackSize,
final boolean checkDamage, final boolean checkNbt) {
return new Predicate<ItemStack>() {
int matchFlags = ItemMatch.ANY;
if (checkDamage) matchFlags = matchFlags | ItemMatch.DAMAGE;
if (checkNbt) matchFlags = matchFlags | ItemMatch.NBT;
if (checkStackSize) matchFlags = matchFlags | ItemMatch.STACKSIZE;
return new ItemStackPredicate(itemStack, matchFlags) {
@Override
public boolean apply(@Nullable ItemStack input) {
return areItemStackEqual(input, itemStack, checkStackSize, true, checkDamage, checkNbt);
}
};
}

public static Predicate<ItemStack> matchItemStacks(final IValueTypeListProxy<ValueObjectTypeItemStack, ValueObjectTypeItemStack.ValueItemStack> itemStacks,
public static ItemStackPredicate matchItemStacks(final IValueTypeListProxy<ValueObjectTypeItemStack, ValueObjectTypeItemStack.ValueItemStack> itemStacks,
final boolean checkStackSize, final boolean checkDamage, final boolean checkNbt) {
return new Predicate<ItemStack>() {
return new ItemStackPredicate() {
@Override
public boolean apply(@Nullable ItemStack input) {
for (ValueObjectTypeItemStack.ValueItemStack itemStack : itemStacks) {
Expand All @@ -249,8 +280,8 @@ && areItemStackEqual(input, itemStack.getRawValue().get(), checkStackSize, true,
};
}

public static Predicate<ItemStack> matchPredicate(final PartTarget partTarget, final IOperator predicate) {
return new Predicate<ItemStack>() {
public static ItemStackPredicate matchPredicate(final PartTarget partTarget, final IOperator predicate) {
return new ItemStackPredicate() {
@Override
public boolean apply(@Nullable ItemStack input) {
ValueObjectTypeItemStack.ValueItemStack valueItemStack = ValueObjectTypeItemStack.ValueItemStack.of(input);
Expand Down
Loading

0 comments on commit 034c933

Please sign in to comment.