diff --git a/src/main/java/de/ellpeck/prettypipes/items/IModule.java b/src/main/java/de/ellpeck/prettypipes/items/IModule.java index d6dc6f1..13e0c50 100644 --- a/src/main/java/de/ellpeck/prettypipes/items/IModule.java +++ b/src/main/java/de/ellpeck/prettypipes/items/IModule.java @@ -10,6 +10,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraftforge.items.IItemHandler; import java.util.List; +import java.util.function.Predicate; public interface IModule { @@ -33,7 +34,9 @@ public interface IModule { boolean canPipeWork(ItemStack module, PipeTileEntity tile); - List getCraftables(ItemStack module, PipeTileEntity tile, boolean onlyReturnPossible); + List getAllCraftables(ItemStack module, PipeTileEntity tile); - ItemStack craft(ItemStack module, PipeTileEntity tile, BlockPos destPipe, BlockPos destInventory, ItemStack stack, ItemEqualityType... equalityTypes); + int getCraftableAmount(ItemStack module, PipeTileEntity tile, ItemStack stack, ItemEqualityType... equalityTypes); + + ItemStack craft(ItemStack module, PipeTileEntity tile, BlockPos destPipe, ItemStack stack, ItemEqualityType... equalityTypes); } diff --git a/src/main/java/de/ellpeck/prettypipes/items/ModuleItem.java b/src/main/java/de/ellpeck/prettypipes/items/ModuleItem.java index 140c813..0c819de 100644 --- a/src/main/java/de/ellpeck/prettypipes/items/ModuleItem.java +++ b/src/main/java/de/ellpeck/prettypipes/items/ModuleItem.java @@ -78,12 +78,17 @@ public abstract class ModuleItem extends Item implements IModule { } @Override - public List getCraftables(ItemStack module, PipeTileEntity tile, boolean onlyReturnPossible) { + public List getAllCraftables(ItemStack module, PipeTileEntity tile) { return Collections.emptyList(); } @Override - public ItemStack craft(ItemStack module, PipeTileEntity tile, BlockPos destPipe, BlockPos destInventory, ItemStack stack, ItemEqualityType... equalityTypes) { + public int getCraftableAmount(ItemStack module, PipeTileEntity tile, ItemStack stack, ItemEqualityType... equalityTypes) { + return 0; + } + + @Override + public ItemStack craft(ItemStack module, PipeTileEntity tile, BlockPos destPipe, ItemStack stack, ItemEqualityType... equalityTypes) { return stack; } } diff --git a/src/main/java/de/ellpeck/prettypipes/network/PipeItem.java b/src/main/java/de/ellpeck/prettypipes/network/PipeItem.java index c255213..9e78320 100644 --- a/src/main/java/de/ellpeck/prettypipes/network/PipeItem.java +++ b/src/main/java/de/ellpeck/prettypipes/network/PipeItem.java @@ -188,7 +188,7 @@ public class PipeItem implements INBTSerializable, ILiquidContainer Direction dir = Utility.getDirectionFromOffset(this.destInventory, this.getDestPipe()); IPipeConnectable connectable = currPipe.getPipeConnectable(dir); if (connectable != null) - return connectable.insertItem(currPipe.getWorld(), currPipe.getPos(), dir, this); + return connectable.insertItem(currPipe.getWorld(), currPipe.getPos(), dir, this.stack, false); IItemHandler handler = currPipe.getItemHandler(dir); if (handler != null) return ItemHandlerHelper.insertItemStacked(handler, this.stack, false); diff --git a/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java b/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java index 18ec101..3b1cc20 100644 --- a/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java +++ b/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java @@ -188,37 +188,36 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL ItemStack remain = stack.copy(); // check existing items for (NetworkLocation location : this.getOrderedNetworkItems(destPipe)) { - remain = this.requestExistingItem(location, destPipe, destInventory, remain, equalityTypes); + remain = this.requestExistingItem(location, destPipe, destInventory, null, remain, equalityTypes); if (remain.isEmpty()) return remain; } // check craftable items - return this.requestCraftedItem(destPipe, destInventory, remain, equalityTypes); + return this.requestCraftedItem(destPipe, remain, equalityTypes); } - public ItemStack requestCraftedItem(BlockPos destPipe, BlockPos destInventory, ItemStack stack, ItemEqualityType... equalityTypes) { - for (Pair craftable : this.getOrderedCraftables(destPipe, true)) { + public ItemStack requestCraftedItem(BlockPos destPipe, ItemStack stack, ItemEqualityType... equalityTypes) { + for (Pair craftable : this.getAllCraftables(destPipe)) { if (!ItemEqualityType.compareItems(stack, craftable.getRight(), equalityTypes)) continue; PipeTileEntity pipe = this.getPipe(craftable.getLeft()); if (pipe == null) continue; - stack = pipe.craft(destPipe, destInventory, stack, equalityTypes); + stack = pipe.craft(destPipe, stack, equalityTypes); if (stack.isEmpty()) break; } return stack; } - public ItemStack requestExistingItem(NetworkLocation location, BlockPos destPipe, BlockPos destInventory, ItemStack stack, ItemEqualityType... equalityTypes) { + public ItemStack requestExistingItem(NetworkLocation location, BlockPos destPipe, BlockPos destInventory, NetworkLock ignoredLock, ItemStack stack, ItemEqualityType... equalityTypes) { if (location.getPos().equals(destInventory)) return stack; // make sure we don't pull any locked items int amount = location.getItemAmount(this.world, stack, equalityTypes); if (amount <= 0) return stack; - // we ignore locks on the destination inventory, since we're probably the ones trying to solve those locks - amount -= this.getLockedAmount(location.getPos(), stack, destInventory, equalityTypes); + amount -= this.getLockedAmount(location.getPos(), stack, ignoredLock, equalityTypes); if (amount <= 0) return stack; ItemStack remain = stack.copy(); @@ -249,25 +248,36 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL return tile; } - public List> getOrderedCraftables(BlockPos node, boolean onlyReturnPossible) { + public List> getAllCraftables(BlockPos node) { if (!this.isNode(node)) return Collections.emptyList(); - this.startProfile("get_craftables"); + this.startProfile("get_all_craftables"); List> craftables = new ArrayList<>(); for (BlockPos dest : this.getOrderedNetworkNodes(node)) { - // don't try to collect recipes for ourselves, since we need these recipes for that - if (dest.equals(node)) - continue; if (!this.world.isBlockLoaded(dest)) continue; PipeTileEntity pipe = this.getPipe(dest); - for (ItemStack stack : pipe.getCraftables(onlyReturnPossible)) + for (ItemStack stack : pipe.getAllCraftables()) craftables.add(Pair.of(pipe.getPos(), stack)); } this.endProfile(); return craftables; } + public int getCraftableAmount(BlockPos node, ItemStack stack, ItemEqualityType... equalityTypes) { + int total = 0; + for (Pair pair : this.getAllCraftables(node)) { + if (!ItemEqualityType.compareItems(pair.getRight(), stack, equalityTypes)) + continue; + if (!this.world.isBlockLoaded(pair.getLeft())) + continue; + PipeTileEntity pipe = this.getPipe(pair.getLeft()); + if (pipe != null) + total += pipe.getCraftableAmount(stack, equalityTypes); + } + return total; + } + public List getOrderedNetworkItems(BlockPos node) { if (!this.isNode(node)) return Collections.emptyList(); @@ -307,9 +317,9 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL return this.networkLocks.get(pos); } - public int getLockedAmount(BlockPos pos, ItemStack stack, BlockPos ignoredLock, ItemEqualityType... equalityTypes) { + public int getLockedAmount(BlockPos pos, ItemStack stack, NetworkLock ignoredLock, ItemEqualityType... equalityTypes) { return this.getNetworkLocks(pos).stream() - .filter(l -> ItemEqualityType.compareItems(l.stack, stack, equalityTypes) && (ignoredLock == null || !ignoredLock.equals(l.location.getPos()))) + .filter(l -> !l.equals(ignoredLock) && ItemEqualityType.compareItems(l.stack, stack, equalityTypes)) .mapToInt(l -> l.stack.getCount()).sum(); } diff --git a/src/main/java/de/ellpeck/prettypipes/pipe/IPipeConnectable.java b/src/main/java/de/ellpeck/prettypipes/pipe/IPipeConnectable.java index 88338fc..f5cd89e 100644 --- a/src/main/java/de/ellpeck/prettypipes/pipe/IPipeConnectable.java +++ b/src/main/java/de/ellpeck/prettypipes/pipe/IPipeConnectable.java @@ -12,8 +12,8 @@ public interface IPipeConnectable { ConnectionType getConnectionType(World world, BlockPos pipePos, Direction direction); - default ItemStack insertItem(World world, BlockPos pipePos, Direction direction, PipeItem item) { - return item.stack; + default ItemStack insertItem(World world, BlockPos pipePos, Direction direction, ItemStack stack, boolean simulate) { + return stack; } default boolean allowsModules(World world, BlockPos pipePos, Direction direction) { diff --git a/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java b/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java index f1768cd..d0c4ba0 100644 --- a/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java +++ b/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java @@ -63,7 +63,7 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide } }; public final Queue craftIngredientRequests = new ArrayDeque<>(); - public final List> craftResultRequests = new ArrayList<>(); + public final List> craftResultRequests = new ArrayList<>(); public PressurizerTileEntity pressurizer; public int moduleDropCheck; protected List items; @@ -84,10 +84,9 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide compound.putInt("module_drop_check", this.moduleDropCheck); compound.put("requests", Utility.serializeAll(this.craftIngredientRequests)); ListNBT results = new ListNBT(); - for (Triple triple : this.craftResultRequests) { + for (Pair triple : this.craftResultRequests) { CompoundNBT nbt = new CompoundNBT(); nbt.putLong("dest_pipe", triple.getLeft().toLong()); - nbt.putLong("dest_inv", triple.getMiddle().toLong()); nbt.put("item", triple.getRight().serializeNBT()); results.add(nbt); } @@ -105,9 +104,8 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide ListNBT results = compound.getList("craft_results", NBT.TAG_COMPOUND); for (int i = 0; i < results.size(); i++) { CompoundNBT nbt = results.getCompound(i); - this.craftResultRequests.add(Triple.of( + this.craftResultRequests.add(Pair.of( BlockPos.fromLong(nbt.getLong("dest_pipe")), - BlockPos.fromLong(nbt.getLong("dest_inv")), ItemStack.read(nbt.getCompound("item")))); } super.read(state, compound); @@ -260,17 +258,23 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide return this.streamModules().allMatch(m -> m.getRight().canPipeWork(m.getLeft(), this)); } - public List getCraftables(boolean onlyReturnPossible) { + public List getAllCraftables() { return this.streamModules() - .flatMap(m -> m.getRight().getCraftables(m.getLeft(), this, onlyReturnPossible).stream()) + .flatMap(m -> m.getRight().getAllCraftables(m.getLeft(), this).stream()) .collect(Collectors.toList()); } - public ItemStack craft(BlockPos destPipe, BlockPos destInventory, ItemStack stack, ItemEqualityType... equalityTypes) { + public int getCraftableAmount(ItemStack stack, ItemEqualityType... equalityTypes) { + return this.streamModules() + .mapToInt(m -> m.getRight().getCraftableAmount(m.getLeft(), this, stack, equalityTypes)) + .sum(); + } + + public ItemStack craft(BlockPos destPipe, ItemStack stack, ItemEqualityType... equalityTypes) { Iterator> modules = this.streamModules().iterator(); while (modules.hasNext()) { Pair module = modules.next(); - stack = module.getRight().craft(module.getLeft(), this, destPipe, destInventory, stack, equalityTypes); + stack = module.getRight().craft(module.getLeft(), this, destPipe, stack, equalityTypes); if (stack.isEmpty()) break; } diff --git a/src/main/java/de/ellpeck/prettypipes/pipe/modules/craft/CraftingModuleItem.java b/src/main/java/de/ellpeck/prettypipes/pipe/modules/craft/CraftingModuleItem.java index 2297e32..edd06d5 100644 --- a/src/main/java/de/ellpeck/prettypipes/pipe/modules/craft/CraftingModuleItem.java +++ b/src/main/java/de/ellpeck/prettypipes/pipe/modules/craft/CraftingModuleItem.java @@ -10,6 +10,7 @@ import de.ellpeck.prettypipes.network.NetworkLocation; import de.ellpeck.prettypipes.network.NetworkLock; import de.ellpeck.prettypipes.network.PipeItem; import de.ellpeck.prettypipes.network.PipeNetwork; +import de.ellpeck.prettypipes.pipe.IPipeConnectable; import de.ellpeck.prettypipes.pipe.PipeTileEntity; import de.ellpeck.prettypipes.pipe.containers.AbstractPipeContainer; import de.ellpeck.prettypipes.terminal.CraftingTerminalTileEntity; @@ -37,14 +38,12 @@ public class CraftingModuleItem extends ModuleItem { public final int inputSlots; public final int outputSlots; private final int speed; - private final int maxExtraction; public CraftingModuleItem(String name, ModuleTier tier) { super(name); this.inputSlots = tier.forTier(1, 4, 9); this.outputSlots = tier.forTier(1, 2, 4); this.speed = tier.forTier(20, 10, 5); - this.maxExtraction = tier.forTier(1, 16, 32); } @Override @@ -79,19 +78,19 @@ public class CraftingModuleItem extends ModuleItem { PipeNetwork network = PipeNetwork.get(tile.getWorld()); // process crafting ingredient requests if (!tile.craftIngredientRequests.isEmpty()) { - NetworkLock request = tile.craftIngredientRequests.remove(); + NetworkLock request = tile.craftIngredientRequests.peek(); Pair dest = tile.getAvailableDestination(request.stack, true, true); if (dest != null) { - network.requestExistingItem(request.location, tile.getPos(), dest.getLeft(), dest.getRight(), ItemEqualityType.NBT); - network.resolveNetworkLock(request); - - // if we couldn't fit all items into the destination, create another request for the rest - ItemStack remain = request.stack.copy(); - remain.shrink(dest.getRight().getCount()); - if (!remain.isEmpty()) { - NetworkLock remainRequest = new NetworkLock(request.location, remain); - tile.craftIngredientRequests.add(remainRequest); - network.createNetworkLock(remainRequest); + ItemStack remain = network.requestExistingItem(request.location, tile.getPos(), dest.getLeft(), request, dest.getRight(), ItemEqualityType.NBT); + if (remain.getCount() != request.stack.getCount()) { + network.resolveNetworkLock(request); + tile.craftIngredientRequests.remove(); + // if we couldn't fit all items into the destination, create another request for the rest + if (!remain.isEmpty()) { + NetworkLock remainRequest = new NetworkLock(request.location, remain); + tile.craftIngredientRequests.add(remainRequest); + network.createNetworkLock(remainRequest); + } } } } @@ -99,93 +98,108 @@ public class CraftingModuleItem extends ModuleItem { if (!tile.craftResultRequests.isEmpty()) { List items = network.getOrderedNetworkItems(tile.getPos()); ItemEqualityType[] equalityTypes = ItemFilter.getEqualityTypes(tile); - for (Triple request : tile.craftResultRequests) { + for (Pair request : tile.craftResultRequests) { ItemStack remain = request.getRight().copy(); - for (NetworkLocation item : items) { - remain = network.requestExistingItem(item, request.getLeft(), request.getMiddle(), remain, equalityTypes); - if (remain.isEmpty()) - break; - } - if (remain.getCount() != request.getRight().getCount()) { - tile.craftResultRequests.remove(request); - // if we couldn't pull everything, log a new request - if (!remain.isEmpty()) - tile.craftResultRequests.add(Triple.of(request.getLeft(), request.getMiddle(), remain)); - return; + PipeTileEntity destPipe = network.getPipe(request.getLeft()); + if (destPipe != null) { + Pair dest = destPipe.getAvailableDestination(remain, true, true); + if (dest == null) { + // if there's no available destination, try inserting into terminals etc. + for (Direction dir : Direction.values()) { + IPipeConnectable connectable = destPipe.getPipeConnectable(dir); + if (connectable == null) + continue; + ItemStack connectableRemain = connectable.insertItem(tile.getWorld(), destPipe.getPos(), dir, remain, true); + if (connectableRemain.getCount() != remain.getCount()) { + ItemStack inserted = remain.copy(); + inserted.shrink(connectableRemain.getCount()); + dest = Pair.of(destPipe.getPos().offset(dir), inserted); + break; + } + } + } + for (NetworkLocation item : items) { + ItemStack requestRemain = network.requestExistingItem(item, request.getLeft(), dest.getLeft(), null, dest.getRight(), equalityTypes); + remain.shrink(dest.getRight().getCount() - requestRemain.getCount()); + if (remain.isEmpty()) + break; + } + if (remain.getCount() != request.getRight().getCount()) { + tile.craftResultRequests.remove(request); + // if we couldn't pull everything, log a new request + if (!remain.isEmpty()) + tile.craftResultRequests.add(Pair.of(request.getLeft(), remain)); + return; + } } } } } @Override - public List getCraftables(ItemStack module, PipeTileEntity tile, boolean onlyReturnPossible) { - ItemStackHandler output = this.getOutput(module); - if (!onlyReturnPossible) { - // if we only need to return the ones we *could* craft, it's easy - List ret = new ArrayList<>(); - for (int i = 0; i < output.getSlots(); i++) { - ItemStack stack = output.getStackInSlot(i); - if (!stack.isEmpty()) - ret.add(stack); - } - return ret; - } - - PipeNetwork network = PipeNetwork.get(tile.getWorld()); - List items = network.getOrderedNetworkItems(tile.getPos()); - List> craftables = network.getOrderedCraftables(tile.getPos(), true); - ItemEqualityType[] equalityTypes = ItemFilter.getEqualityTypes(tile); - ItemStackHandler input = this.getInput(module); - + public List getAllCraftables(ItemStack module, PipeTileEntity tile) { List ret = new ArrayList<>(); + ItemStackHandler output = this.getOutput(module); for (int i = 0; i < output.getSlots(); i++) { ItemStack stack = output.getStackInSlot(i); - if (!stack.isEmpty()) { - // figure out how many crafting operations we can actually do with the input items we have in the network - int availableCrafts = CraftingTerminalTileEntity.getAvailableCrafts(tile.getWorld(), input.getSlots(), input::getStackInSlot, k -> false, s -> items, craftables, null, equalityTypes); - if (availableCrafts > 0) { - ItemStack copy = stack.copy(); - copy.setCount(stack.getCount() * availableCrafts); - ret.add(copy); - } - } + if (!stack.isEmpty()) + ret.add(stack); } return ret; } @Override - public ItemStack craft(ItemStack module, PipeTileEntity tile, BlockPos destPipe, BlockPos destInventory, ItemStack stack, ItemEqualityType... equalityTypes) { - // check if we can craft the required amount of items - List craftables = this.getCraftables(module, tile, true); - int craftableAmount = craftables.stream() - .filter(c -> ItemEqualityType.compareItems(c, stack, equalityTypes)) - .mapToInt(ItemStack::getCount).sum(); - if (craftableAmount > 0) { - PipeNetwork network = PipeNetwork.get(tile.getWorld()); - List items = network.getOrderedNetworkItems(tile.getPos()); - List> allCraftables = network.getOrderedCraftables(tile.getPos(), true); + public int getCraftableAmount(ItemStack module, PipeTileEntity tile, ItemStack stack, ItemEqualityType... equalityTypes) { + PipeNetwork network = PipeNetwork.get(tile.getWorld()); + List items = network.getOrderedNetworkItems(tile.getPos()); + ItemStackHandler input = this.getInput(module); - int resultAmount = this.getResultAmountPerCraft(module, stack, equalityTypes); - int requiredCrafts = MathHelper.ceil(stack.getCount() / (float) resultAmount); - - ItemStackHandler input = this.getInput(module); - for (int i = 0; i < input.getSlots(); i++) { - ItemStack in = input.getStackInSlot(i); - if (in.isEmpty()) - continue; - ItemStack copy = in.copy(); - copy.setCount(in.getCount() * requiredCrafts); - Pair, ItemStack> ret = ItemTerminalTileEntity.requestItemLater(tile.getWorld(), destPipe, destInventory, copy, items, allCraftables, equalityTypes); - tile.craftIngredientRequests.addAll(ret.getLeft()); - tile.craftResultRequests.add(Triple.of(destPipe, destInventory, stack)); + int craftable = 0; + ItemStackHandler output = this.getOutput(module); + for (int i = 0; i < output.getSlots(); i++) { + ItemStack out = output.getStackInSlot(i); + if (!out.isEmpty() && ItemEqualityType.compareItems(out, stack, equalityTypes)) { + // figure out how many crafting operations we can actually do with the input items we have in the network + int availableCrafts = CraftingTerminalTileEntity.getAvailableCrafts(tile, input.getSlots(), input::getStackInSlot, k -> true, s -> items, null, equalityTypes); + if (availableCrafts > 0) + craftable += out.getCount() * availableCrafts; } - - ItemStack remain = stack.copy(); - remain.shrink(craftableAmount); - return remain; - } else { - return stack; } + return craftable; + } + + @Override + public ItemStack craft(ItemStack module, PipeTileEntity tile, BlockPos destPipe, ItemStack stack, ItemEqualityType... equalityTypes) { + // check if we can craft the required amount of items + int craftableAmount = this.getCraftableAmount(module, tile, stack, equalityTypes); + if (craftableAmount <= 0) + return stack; + + PipeNetwork network = PipeNetwork.get(tile.getWorld()); + List items = network.getOrderedNetworkItems(tile.getPos()); + + int resultAmount = this.getResultAmountPerCraft(module, stack, equalityTypes); + int requiredCrafts = MathHelper.ceil(stack.getCount() / (float) resultAmount); + int toCraft = Math.min(craftableAmount, requiredCrafts); + + ItemStackHandler input = this.getInput(module); + for (int i = 0; i < input.getSlots(); i++) { + ItemStack in = input.getStackInSlot(i); + if (in.isEmpty()) + continue; + ItemStack copy = in.copy(); + copy.setCount(in.getCount() * toCraft); + Pair, ItemStack> ret = ItemTerminalTileEntity.requestItemLater(tile.getWorld(), tile.getPos(), copy, items, equalityTypes); + tile.craftIngredientRequests.addAll(ret.getLeft()); + } + + ItemStack result = stack.copy(); + result.setCount(resultAmount * toCraft); + tile.craftResultRequests.add(Pair.of(destPipe, result)); + + ItemStack remain = stack.copy(); + remain.shrink(toCraft); + return remain; } public ItemStackHandler getInput(ItemStack module) { diff --git a/src/main/java/de/ellpeck/prettypipes/terminal/CraftingTerminalBlock.java b/src/main/java/de/ellpeck/prettypipes/terminal/CraftingTerminalBlock.java index f7bb62d..43fba1a 100644 --- a/src/main/java/de/ellpeck/prettypipes/terminal/CraftingTerminalBlock.java +++ b/src/main/java/de/ellpeck/prettypipes/terminal/CraftingTerminalBlock.java @@ -23,11 +23,10 @@ public class CraftingTerminalBlock extends ItemTerminalBlock { } @Override - public ItemStack insertItem(World world, BlockPos pipePos, Direction direction, PipeItem item) { + public ItemStack insertItem(World world, BlockPos pipePos, Direction direction, ItemStack remain, boolean simulate) { BlockPos pos = pipePos.offset(direction); CraftingTerminalTileEntity tile = Utility.getTileEntity(CraftingTerminalTileEntity.class, world, pos); if (tile != null) { - ItemStack remain = item.stack; int lowestSlot = -1; do { for (int i = 0; i < tile.craftItems.getSlots(); i++) { @@ -41,15 +40,15 @@ public class CraftingTerminalBlock extends ItemTerminalBlock { if (lowestSlot >= 0) { ItemStack copy = remain.copy(); copy.setCount(1); - remain.shrink(1 - tile.craftItems.insertItem(lowestSlot, copy, false).getCount()); + remain.shrink(1 - tile.craftItems.insertItem(lowestSlot, copy, simulate).getCount()); if (remain.isEmpty()) return ItemStack.EMPTY; } } while (lowestSlot >= 0); - return ItemHandlerHelper.insertItemStacked(tile.items, remain, false); + return ItemHandlerHelper.insertItemStacked(tile.items, remain, simulate); } - return item.stack; + return remain; } } diff --git a/src/main/java/de/ellpeck/prettypipes/terminal/CraftingTerminalTileEntity.java b/src/main/java/de/ellpeck/prettypipes/terminal/CraftingTerminalTileEntity.java index e3286dd..78c7d88 100644 --- a/src/main/java/de/ellpeck/prettypipes/terminal/CraftingTerminalTileEntity.java +++ b/src/main/java/de/ellpeck/prettypipes/terminal/CraftingTerminalTileEntity.java @@ -12,6 +12,7 @@ import de.ellpeck.prettypipes.network.NetworkLock; import de.ellpeck.prettypipes.network.PipeNetwork; import de.ellpeck.prettypipes.packets.PacketGhostSlot; import de.ellpeck.prettypipes.packets.PacketHandler; +import de.ellpeck.prettypipes.pipe.PipeTileEntity; import de.ellpeck.prettypipes.terminal.containers.CraftingTerminalContainer; import de.ellpeck.prettypipes.terminal.containers.ItemTerminalContainer; import net.minecraft.block.BlockState; @@ -100,14 +101,17 @@ public class CraftingTerminalTileEntity extends ItemTerminalTileEntity { } public void requestCraftingItems(PlayerEntity player, int maxAmount) { + PipeTileEntity pipe = this.getConnectedPipe(); + if (pipe == null) + return; PipeNetwork network = PipeNetwork.get(this.world); network.startProfile("terminal_request_crafting"); this.updateItems(); // get the amount of crafts that we can do - int lowestAvailable = getAvailableCrafts(this.world, this.craftItems.getSlots(), this::getRequestedCraftItem, this::isGhostItem, s -> { + int lowestAvailable = getAvailableCrafts(pipe, this.craftItems.getSlots(), this::getRequestedCraftItem, this::isGhostItem, s -> { NetworkItem item = this.networkItems.get(s); return item != null ? item.getLocations() : Collections.emptyList(); - }, this.craftables, s -> player.sendMessage(new TranslationTextComponent("info." + PrettyPipes.ID + ".not_found", s.getDisplayName()).setStyle(Style.EMPTY.setFormatting(TextFormatting.RED)), UUID.randomUUID()), ItemEqualityType.NBT); + }, s -> player.sendMessage(new TranslationTextComponent("info." + PrettyPipes.ID + ".not_found", s.getDisplayName()).setStyle(Style.EMPTY.setFormatting(TextFormatting.RED)), UUID.randomUUID()), ItemEqualityType.NBT); if (lowestAvailable > 0) { // if we're limiting the amount, pretend we only have that amount available if (maxAmount < lowestAvailable) @@ -148,8 +152,8 @@ public class CraftingTerminalTileEntity extends ItemTerminalTileEntity { return new CraftingTerminalContainer(Registry.craftingTerminalContainer, window, player, this.pos); } - public static int getAvailableCrafts(World world, int slots, Function inputFunction, Predicate isGhost, Function> locationsFunction, List> craftables, Consumer unavailableConsumer, ItemEqualityType... equalityTypes) { - PipeNetwork network = PipeNetwork.get(world); + public static int getAvailableCrafts(PipeTileEntity tile, int slots, Function inputFunction, Predicate isGhost, Function> locationsFunction, Consumer unavailableConsumer, ItemEqualityType... equalityTypes) { + PipeNetwork network = PipeNetwork.get(tile.getWorld()); // the highest amount we can craft with the items we have int lowestAvailable = Integer.MAX_VALUE; // this is the amount of items required for each ingredient when crafting ONE @@ -170,7 +174,7 @@ public class CraftingTerminalTileEntity extends ItemTerminalTileEntity { // total amount of available items of this type int available = 0; for (NetworkLocation location : locationsFunction.apply(stack)) { - int amount = location.getItemAmount(world, stack.stack, equalityTypes); + int amount = location.getItemAmount(tile.getWorld(), stack.stack, equalityTypes); if (amount <= 0) continue; amount -= network.getLockedAmount(location.getPos(), stack.stack, null, equalityTypes); @@ -180,12 +184,11 @@ public class CraftingTerminalTileEntity extends ItemTerminalTileEntity { // we have available for each crafting slot that contains this item available /= entry.getValue().intValue(); - // check how many craftable items we have and add those on - if (!craftables.isEmpty()) { - int craftable = craftables.stream().map(Pair::getRight) - .filter(c -> ItemEqualityType.compareItems(c, stack.stack)) - .mapToInt(ItemStack::getCount).sum(); - available += craftable / entry.getValue().intValue(); + // check how many craftable items we have and add those on if we need to + if (available < lowestAvailable) { + int craftable = network.getCraftableAmount(tile.getPos(), stack.stack, equalityTypes); + if (craftable > 0) + available += craftable / entry.getValue().intValue(); } // clamp to lowest available diff --git a/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalBlock.java b/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalBlock.java index 1841643..22e3802 100644 --- a/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalBlock.java +++ b/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalBlock.java @@ -69,12 +69,12 @@ public class ItemTerminalBlock extends ContainerBlock implements IPipeConnectabl } @Override - public ItemStack insertItem(World world, BlockPos pipePos, Direction direction, PipeItem item) { + public ItemStack insertItem(World world, BlockPos pipePos, Direction direction, ItemStack stack, boolean simulate) { BlockPos pos = pipePos.offset(direction); ItemTerminalTileEntity tile = Utility.getTileEntity(ItemTerminalTileEntity.class, world, pos); if (tile != null) - return ItemHandlerHelper.insertItemStacked(tile.items, item.stack, false); - return item.stack; + return ItemHandlerHelper.insertItemStacked(tile.items, stack, simulate); + return stack; } @Override diff --git a/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalTileEntity.java b/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalTileEntity.java index ec219ea..0cad7c0 100644 --- a/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalTileEntity.java +++ b/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalTileEntity.java @@ -52,8 +52,7 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine return true; } }; - public Map networkItems; - public List> craftables; + protected Map networkItems; private final Queue existingRequests = new ArrayDeque<>(); protected ItemTerminalTileEntity(TileEntityType tileEntityTypeIn) { @@ -90,7 +89,7 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine if (!this.existingRequests.isEmpty()) { NetworkLock request = this.existingRequests.remove(); network.resolveNetworkLock(request); - network.requestExistingItem(request.location, pipe.getPos(), this.pos, request.stack, ItemEqualityType.NBT); + network.requestExistingItem(request.location, pipe.getPos(), this.pos, request, request.stack, ItemEqualityType.NBT); update = true; } } @@ -124,13 +123,10 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine PipeTileEntity pipe = this.getConnectedPipe(); if (pipe == null) return; - PipeNetwork network = PipeNetwork.get(this.world); this.networkItems = this.collectItems(); - this.craftables = network.getOrderedCraftables(pipe.getPos(), true); if (playersToSync.length > 0) { - // the craftables we display should be displayed even if they can't be crafted! - List clientCraftables = network.getOrderedCraftables(pipe.getPos(), false).stream().map(Pair::getRight).collect(Collectors.toList()); List clientItems = this.networkItems.values().stream().map(NetworkItem::asStack).collect(Collectors.toList()); + List clientCraftables = PipeNetwork.get(this.world).getAllCraftables(pipe.getPos()).stream().map(Pair::getRight).collect(Collectors.toList()); for (PlayerEntity player : playersToSync) { if (!(player.openContainer instanceof ItemTerminalContainer)) continue; @@ -158,7 +154,7 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine public int requestItemImpl(ItemStack stack) { NetworkItem item = this.networkItems.get(new EquatableItemStack(stack)); Collection locations = item == null ? Collections.emptyList() : item.getLocations(); - Pair, ItemStack> ret = requestItemLater(this.world, this.getConnectedPipe().getPos(), this.pos, stack, locations, this.craftables, ItemEqualityType.NBT); + Pair, ItemStack> ret = requestItemLater(this.world, this.getConnectedPipe().getPos(), stack, locations, ItemEqualityType.NBT); this.existingRequests.addAll(ret.getLeft()); return stack.getCount() - ret.getRight().getCount(); } @@ -212,7 +208,7 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine return new ItemTerminalContainer(Registry.itemTerminalContainer, window, player, this.pos); } - public static Pair, ItemStack> requestItemLater(World world, BlockPos destPipe, BlockPos destInventory, ItemStack stack, Collection locations, List> craftables, ItemEqualityType... equalityTypes) { + public static Pair, ItemStack> requestItemLater(World world, BlockPos destPipe, ItemStack stack, Collection locations, ItemEqualityType... equalityTypes) { List requests = new ArrayList<>(); ItemStack remain = stack.copy(); PipeNetwork network = PipeNetwork.get(world); @@ -221,7 +217,7 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine int amount = location.getItemAmount(world, stack, ItemEqualityType.NBT); if (amount <= 0) continue; - amount -= network.getLockedAmount(location.getPos(), stack, destInventory, ItemEqualityType.NBT); + amount -= network.getLockedAmount(location.getPos(), stack, null, ItemEqualityType.NBT); if (amount > 0) { if (remain.getCount() < amount) amount = remain.getCount(); @@ -240,7 +236,7 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine } // check for craftable items if (!remain.isEmpty()) - network.requestCraftedItem(destPipe, destInventory, remain, equalityTypes); + remain = network.requestCraftedItem(destPipe, remain, equalityTypes); return Pair.of(requests, remain); } }