From 475c8ff5a10120ab8e61f84c046d4a92e4149439 Mon Sep 17 00:00:00 2001 From: Sebastian Hartte Date: Wed, 16 Sep 2020 17:44:49 +0200 Subject: [PATCH] Adapt the same sorting logic used for items stored in the network for items obtained from patterns, which fixes items from patterns not being able to be shift-clicked into new patterns. --- .../core/sync/packets/JEIRecipePacket.java | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/src/main/java/appeng/core/sync/packets/JEIRecipePacket.java b/src/main/java/appeng/core/sync/packets/JEIRecipePacket.java index 7c0ec908c..2cddc1772 100644 --- a/src/main/java/appeng/core/sync/packets/JEIRecipePacket.java +++ b/src/main/java/appeng/core/sync/packets/JEIRecipePacket.java @@ -19,6 +19,7 @@ package appeng.core.sync.packets; import java.util.Arrays; +import java.util.stream.Stream; import javax.annotation.Nullable; @@ -310,15 +311,10 @@ public class JEIRecipePacket extends BasePacket { */ private IAEItemStack findBestMatchingItemStack(Ingredient ingredients, IPartitionList filter, IMEMonitor storage, IContainerCraftingPacket cct) { - return Arrays.stream(ingredients.getMatchingStacks()).map(AEItemStack::fromItemStack) // - .filter(r -> r != null && (filter == null || filter.isListed(r))) // - .map(s -> { - // Determine the stored count - IAEItemStack stored = storage.extractItems(s.copy().setStackSize(Long.MAX_VALUE), - Actionable.SIMULATE, cct.getActionSource()); - return Pair.of(s, stored != null ? stored.getStackSize() : 0); - }).min((left, right) -> Long.compare(right.getSecond(), left.getSecond()))// - .map(Pair::getFirst).orElse(null); + Stream stacks = Arrays.stream(ingredients.getMatchingStacks())// + .map(AEItemStack::fromItemStack) // + .filter(r -> r != null && (filter == null || filter.isListed(r))); + return getMostStored(stacks, storage, cct); } /** @@ -329,16 +325,30 @@ public class JEIRecipePacket extends BasePacket { */ private IAEItemStack findBestMatchingPattern(Ingredient ingredients, IPartitionList filter, ICraftingGrid crafting, IMEMonitor storage, IContainerCraftingPacket cct) { - return Arrays.stream(ingredients.getMatchingStacks()).map(AEItemStack::fromItemStack) - .filter(r -> r != null && (filter == null || filter.isListed(r))) - .map(s -> s.setCraftable(!crafting.getCraftingFor(s, null, 0, null).isEmpty())) - .filter(IAEItemStack::isCraftable).map(s -> { - final IAEItemStack stored = storage.extractItems(s, Actionable.SIMULATE, cct.getActionSource()); - return s.setStackSize(stored != null ? stored.getStackSize() : 0); - }).min((left, right) -> { - final int craftable = Boolean.compare(left.isCraftable(), right.isCraftable()); - return craftable != 0 ? craftable : Long.compare(right.getStackSize(), left.getStackSize()); - }).orElse(null); + Stream stacks = Arrays.stream(ingredients.getMatchingStacks())// + .map(AEItemStack::fromItemStack)// + .filter(r -> r != null && (filter == null || filter.isListed(r)))// + .map(s -> s.setCraftable(!crafting.getCraftingFor(s, null, 0, null).isEmpty()))// + .filter(IAEItemStack::isCraftable); + return getMostStored(stacks, storage, cct); + } + + /** + * From a stream of AE item stacks, pick the one with the highest available + * amount in the network. Returns null if the stream is empty. + */ + private static IAEItemStack getMostStored(Stream stacks, IMEMonitor storage, + IContainerCraftingPacket cct) { + return stacks// + .map(s -> { + // Determine the stored count + IAEItemStack stored = storage.extractItems(s.copy().setStackSize(Long.MAX_VALUE), + Actionable.SIMULATE, cct.getActionSource()); + return Pair.of(s, stored != null ? stored.getStackSize() : 0); + })// + .min((left, right) -> Long.compare(right.getSecond(), left.getSecond()))// + .map(Pair::getFirst)// + .orElse(null); } private void handleProcessing(Container con, IContainerCraftingPacket cct, IRecipe recipe) {