diff --git a/src/main/java/de/ellpeck/prettypipes/network/NetworkLock.java b/src/main/java/de/ellpeck/prettypipes/network/NetworkLock.java index e0ffce9..19ba7fb 100644 --- a/src/main/java/de/ellpeck/prettypipes/network/NetworkLock.java +++ b/src/main/java/de/ellpeck/prettypipes/network/NetworkLock.java @@ -1,5 +1,6 @@ package de.ellpeck.prettypipes.network; +import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.ListNBT; import net.minecraftforge.common.util.INBTSerializable; @@ -9,13 +10,11 @@ import java.util.Collection; public class NetworkLock implements INBTSerializable { public NetworkLocation location; - public int slot; - public int amount; + public ItemStack stack; - public NetworkLock(NetworkLocation location, int slot, int amount) { + public NetworkLock(NetworkLocation location, ItemStack stack) { this.location = location; - this.slot = slot; - this.amount = amount; + this.stack = stack; } public NetworkLock(CompoundNBT nbt) { @@ -26,15 +25,13 @@ public class NetworkLock implements INBTSerializable { public CompoundNBT serializeNBT() { CompoundNBT nbt = new CompoundNBT(); nbt.put("location", this.location.serializeNBT()); - nbt.putInt("slot", this.slot); - nbt.putInt("amount", this.amount); + nbt.put("stack", this.stack.write(new CompoundNBT())); return nbt; } @Override public void deserializeNBT(CompoundNBT nbt) { this.location = new NetworkLocation(nbt.getCompound("location")); - this.slot = nbt.getInt("slot"); - this.amount = nbt.getInt("amount"); + this.stack = ItemStack.read(nbt.getCompound("stack")); } } diff --git a/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java b/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java index 8828638..3173188 100644 --- a/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java +++ b/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java @@ -177,6 +177,30 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL return true; } + public boolean requestItem(BlockPos destPipe, BlockPos destInventory, ItemStack stack, int amount, ItemEqualityType... equalityTypes) { + List locations = this.getOrderedNetworkItems(destPipe); + for (NetworkLocation location : locations) { + if (this.requestItem(location, destPipe, destInventory, stack, amount, equalityTypes)) + return true; + } + return false; + } + + public boolean requestItem(NetworkLocation location, BlockPos destPipe, BlockPos destInventory, ItemStack stack, int amount, ItemEqualityType... equalityTypes) { + if (location.pipePos.equals(destPipe)) + return false; + for (int slot : location.getStackSlots(this.world, stack, equalityTypes)) { + // try to extract from that location's inventory and send the item + IItemHandler handler = location.getItemHandler(this.world); + ItemStack extracted = handler.extractItem(slot, amount, true); + if (this.routeItemToLocation(location.pipePos, location.getPos(), destPipe, destInventory, speed -> new PipeItem(extracted, speed))) { + handler.extractItem(slot, extracted.getCount(), false); + return true; + } + } + return false; + } + public PipeTileEntity getPipe(BlockPos pos) { PipeTileEntity tile = this.tileCache.get(pos); if (tile == null || tile.isRemoved()) { @@ -223,10 +247,10 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL return this.networkLocks.get(pos); } - public int getLockedAmount(BlockPos pos, int slot) { + public int getLockedAmount(BlockPos pos, ItemStack stack, ItemEqualityType... equalityTypes) { return this.getNetworkLocks(pos).stream() - .filter(l -> l.slot == slot) - .mapToInt(l -> l.amount).sum(); + .filter(l -> ItemEqualityType.compareItems(l.stack, stack, equalityTypes)) + .mapToInt(l -> l.stack.getCount()).sum(); } private void refreshNode(BlockPos pos, BlockState state) { diff --git a/src/main/java/de/ellpeck/prettypipes/pipe/modules/retrieval/RetrievalModuleItem.java b/src/main/java/de/ellpeck/prettypipes/pipe/modules/retrieval/RetrievalModuleItem.java index 5e42202..e730fe6 100644 --- a/src/main/java/de/ellpeck/prettypipes/pipe/modules/retrieval/RetrievalModuleItem.java +++ b/src/main/java/de/ellpeck/prettypipes/pipe/modules/retrieval/RetrievalModuleItem.java @@ -4,6 +4,7 @@ import de.ellpeck.prettypipes.Registry; import de.ellpeck.prettypipes.items.IModule; import de.ellpeck.prettypipes.items.ModuleItem; import de.ellpeck.prettypipes.items.ModuleTier; +import de.ellpeck.prettypipes.misc.ItemEqualityType; import de.ellpeck.prettypipes.misc.ItemFilter; import de.ellpeck.prettypipes.network.NetworkLocation; import de.ellpeck.prettypipes.network.PipeItem; @@ -39,7 +40,6 @@ public class RetrievalModuleItem extends ModuleItem { if (!tile.canWork()) return; PipeNetwork network = PipeNetwork.get(tile.getWorld()); - List locations = null; ItemFilter filter = new ItemFilter(this.filterSlots, module, tile); filter.isWhitelist = true; @@ -53,22 +53,8 @@ public class RetrievalModuleItem extends ModuleItem { BlockPos dest = tile.getAvailableDestination(copy, true, this.preventOversending); if (dest == null) continue; - // loop through locations to find a location that has the item - if (locations == null) - locations = network.getOrderedNetworkItems(tile.getPos()); - for (NetworkLocation location : locations) { - if (location.pipePos.equals(tile.getPos())) - continue; - for (int slot : location.getStackSlots(tile.getWorld(), filtered, filter.getEqualityTypes())) { - // try to extract from that location's inventory and send the item - IItemHandler handler = location.getItemHandler(tile.getWorld()); - ItemStack stack = handler.extractItem(slot, this.maxExtraction, true); - if (network.routeItemToLocation(location.pipePos, location.getPos(), tile.getPos(), dest, speed -> new PipeItem(stack, speed))) { - handler.extractItem(slot, stack.getCount(), false); - return; - } - } - } + if (network.requestItem(tile.getPos(), dest, filtered, this.maxExtraction, filter.getEqualityTypes())) + break; } } diff --git a/src/main/java/de/ellpeck/prettypipes/terminal/CraftingTerminalTileEntity.java b/src/main/java/de/ellpeck/prettypipes/terminal/CraftingTerminalTileEntity.java index 6372745..1aa374d 100644 --- a/src/main/java/de/ellpeck/prettypipes/terminal/CraftingTerminalTileEntity.java +++ b/src/main/java/de/ellpeck/prettypipes/terminal/CraftingTerminalTileEntity.java @@ -118,13 +118,11 @@ public class CraftingTerminalTileEntity extends ItemTerminalTileEntity { int available = 0; if (item != null) { for (NetworkLocation location : item.getLocations()) { - for (int slot : location.getStackSlots(this.world, stack.stack, ItemEqualityType.NBT)) { - ItemStack inSlot = location.getItemHandler(this.world).extractItem(slot, Integer.MAX_VALUE, true); - if (inSlot.isEmpty()) - continue; - inSlot.shrink(network.getLockedAmount(location.getPos(), slot)); - available += inSlot.getCount(); - } + int amount = location.getItemAmount(this.world, stack.stack, ItemEqualityType.NBT); + if (amount <= 0) + continue; + amount -= network.getLockedAmount(location.getPos(), stack.stack, ItemEqualityType.NBT); + available += amount; } // divide the total by the amount required to get the amount that // we have available for each crafting slot that contains this item diff --git a/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalTileEntity.java b/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalTileEntity.java index 7f2fb08..9f96897 100644 --- a/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalTileEntity.java +++ b/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalTileEntity.java @@ -84,12 +84,8 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine if (!this.pendingRequests.isEmpty()) { NetworkLock request = this.pendingRequests.remove(); network.resolveNetworkLock(request); - IItemHandler handler = request.location.getItemHandler(this.world); - ItemStack extracted = handler.extractItem(request.slot, request.amount, true); - if (network.routeItemToLocation(request.location.pipePos, request.location.getPos(), pipe.getPos(), this.pos, speed -> new PipeItem(extracted, speed))) { - handler.extractItem(request.slot, extracted.getCount(), false); + if (network.requestItem(request.location, pipe.getPos(), this.pos, request.stack, request.stack.getCount(), ItemEqualityType.NBT)) update = true; - } } } @@ -154,22 +150,20 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine NetworkItem item = this.networkItems.get(equatable); if (item != null) { int remain = stack.getCount(); - locations: for (NetworkLocation location : item.getLocations()) { - for (int slot : location.getStackSlots(this.world, stack, ItemEqualityType.NBT)) { - ItemStack inSlot = location.getItemHandler(this.world).extractItem(slot, Integer.MAX_VALUE, true); - if (inSlot.isEmpty()) - continue; - inSlot.shrink(network.getLockedAmount(location.getPos(), slot)); - if (inSlot.getCount() > 0) { - int extract = Math.min(inSlot.getCount(), remain); - NetworkLock lock = new NetworkLock(location, slot, extract); - this.pendingRequests.add(lock); - network.createNetworkLock(lock); - remain -= extract; - if (remain <= 0) - break locations; - } + int amount = location.getItemAmount(this.world, stack, ItemEqualityType.NBT); + if (amount <= 0) + continue; + amount -= network.getLockedAmount(location.getPos(), stack, ItemEqualityType.NBT); + if (amount > 0) { + if (remain < amount) + amount = remain; + NetworkLock lock = new NetworkLock(location, stack); + this.pendingRequests.add(lock); + network.createNetworkLock(lock); + remain -= amount; + if (remain <= 0) + break; } } return stack.getCount() - remain;