diff --git a/src/main/java/codechicken/nei/BookmarkPanel.java b/src/main/java/codechicken/nei/BookmarkPanel.java index 3f26bdf51..f518789fd 100644 --- a/src/main/java/codechicken/nei/BookmarkPanel.java +++ b/src/main/java/codechicken/nei/BookmarkPanel.java @@ -1549,6 +1549,8 @@ public void addOrRemoveItem(ItemStack stackover, BookmarkRecipe recipe, boolean if (idx != -1) { BGrid.removeRecipe(idx, saveIngredients); } else if (saveIngredients && recipe != null) { + recipe.result = new ArrayList<>(); + recipe.result.add(stackover); addRecipe(recipe, saveSize); } else { final NBTTagCompound nbTag = StackInfo.itemStackToNBT(stackover); @@ -1615,8 +1617,8 @@ public void addRecipe(BookmarkRecipe recipe, boolean saveSize, int groupId) { final NBTTagCompound nbTag = uniqueIngredients.get(GUID); final ItemStack normalized = StackInfo.loadFromNBT(nbTag, saveSize ? nbTag.getInteger("Count") : 0); final ItemStackMetadata metadata = new ItemStackMetadata(recipeId.copy(), nbTag, true, groupId); - BGrid.addItem(normalized, metadata); metadata.fullRecipe = recipe; + BGrid.addItem(normalized, metadata); } } @@ -1626,8 +1628,8 @@ public void addRecipe(BookmarkRecipe recipe, boolean saveSize, int groupId) { final NBTTagCompound nbTag = uniqueResults.get(GUID); final ItemStack normalized = StackInfo.loadFromNBT(nbTag, saveSize ? nbTag.getInteger("Count") : 0); final ItemStackMetadata metadata = new ItemStackMetadata(recipeId, nbTag, false, groupId); - BGrid.addItem(normalized, metadata); metadata.fullRecipe = recipe; + BGrid.addItem(normalized, metadata); } fixCountOfNamespaces(); diff --git a/src/main/java/codechicken/nei/bookmarks/crafts/BookmarkCraftingChain.java b/src/main/java/codechicken/nei/bookmarks/crafts/BookmarkCraftingChain.java index 841e2c1c9..aa9f4926d 100644 --- a/src/main/java/codechicken/nei/bookmarks/crafts/BookmarkCraftingChain.java +++ b/src/main/java/codechicken/nei/bookmarks/crafts/BookmarkCraftingChain.java @@ -6,14 +6,17 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; import codechicken.nei.BookmarkPanel; import codechicken.nei.bookmarks.crafts.graph.CraftingGraph; import codechicken.nei.bookmarks.crafts.graph.ItemGraphNode; import codechicken.nei.bookmarks.crafts.graph.RecipeGraphNode; import codechicken.nei.recipe.BookmarkRecipeId; +import codechicken.nei.recipe.StackInfo; public class BookmarkCraftingChain { @@ -59,11 +62,27 @@ public void refresh(ArrayList groupItems, boolean skipCal itemsWithoutRecipe.addAll(outputs); } else { BookmarkPanel.BookmarkRecipe recipe = recipes.get(entry.getKey()); - if (recipe != null) { - RecipeGraphNode node = new RecipeGraphNode(recipe, inputs, outputs); - for (ItemStackWithMetadata output : outputs) { - graph.addNode(output, node); - } + // Fallback to pinned items + if (recipe == null) { + recipe = new BookmarkPanel.BookmarkRecipe(); + recipe.ingredients = inputs.stream().map(it -> { + NBTTagCompound tagCompound = StackInfo.itemStackToNBT(it.getStack()); + return StackInfo.loadFromNBT(tagCompound, it.getMeta().factor); + }).collect(Collectors.toList()); + + recipe.allIngredients = recipe.ingredients.stream().map(Collections::singletonList) + .collect(Collectors.toList()); + + recipe.result = outputs.stream().map(it -> { + NBTTagCompound tagCompound = StackInfo.itemStackToNBT(it.getStack()); + return StackInfo.loadFromNBT(tagCompound, it.getMeta().factor); + }).collect(Collectors.toList()); + recipe.recipeId = entry.getKey(); + } + + RecipeGraphNode node = new RecipeGraphNode(recipe, inputs, outputs); + for (ItemStackWithMetadata output : outputs) { + graph.addNode(output, node); } } } diff --git a/src/main/java/codechicken/nei/bookmarks/crafts/graph/CraftingGraph.java b/src/main/java/codechicken/nei/bookmarks/crafts/graph/CraftingGraph.java index 8b4621fb9..c14e8dda2 100644 --- a/src/main/java/codechicken/nei/bookmarks/crafts/graph/CraftingGraph.java +++ b/src/main/java/codechicken/nei/bookmarks/crafts/graph/CraftingGraph.java @@ -26,6 +26,7 @@ public class CraftingGraph { private final Map nodes = new HashMap<>(); private final Map> allNodes = new HashMap<>(); + private final List fluidConversionNodes = new ArrayList<>(); private final Map requestedItems = new HashMap<>(); @@ -50,8 +51,12 @@ public void addNode(ItemStackWithMetadata output, CraftingGraphNode node) { String key = StackInfo.getItemStackGUID(output.getStack()); if (!nodes.containsKey(key) || !(nodes.get(key) instanceof RecipeGraphNode)) { nodes.put(key, node); - if (output.getMeta().requestedAmount != 0) { - requestedItems.put(key, output.getMeta().requestedAmount); + int requestedAmount = output.getMeta().requestedAmount; + if (requestedAmount != 0) { + requestedItems.put(key, requestedAmount); + } + if (node instanceof RecipeGraphNode recipeNode && requestedAmount > 0) { + recipeNode.setChainOutputs(key, requestedAmount); } } else { conflictingSlots.add(output.getGridIdx()); @@ -76,7 +81,7 @@ public void runAll() { } for (Map.Entry entry : requestedItems.entrySet()) { if (entry.getValue() > 0) { - dfs(entry.getKey(), entry.getValue(), new HashSet<>(), true); + dfs(entry.getKey(), entry.getValue(), new HashSet<>()); } } postProcess(); @@ -130,6 +135,7 @@ public void preProcess() { } allNodes.get(outputKey).add(node); } + fluidConversionNodes.add(node); } } @@ -150,7 +156,7 @@ private void tryAddFluid(ItemStackWithMetadata pinnedItem, } } - public int dfs(String requestedKey, int requestedAmount, HashSet history, boolean keepOutputs) { + public int dfs(String requestedKey, int requestedAmount, HashSet history) { CraftingGraphNode node = this.nodes.get(requestedKey); if (node == null) { return 0; @@ -167,9 +173,9 @@ public int dfs(String requestedKey, int requestedAmount, HashSet producedEmptyContainers = fluidConversionGraphNode.getProducedEmptyContainers(); + Integer availableContainers = producedEmptyContainers.get(requestedKey); + if (availableContainers != null) { + int n = Math.min(availableContainers, requestedAmount - availableAmount); + producedEmptyContainers.put(requestedKey, producedEmptyContainers.get(requestedKey) - n); + availableAmount += n; + } + } int amountToRequest = requestedAmount - availableAmount; BookmarkRecipeId recipeId = recipeNode.getRecipeId(); @@ -204,9 +220,6 @@ public int dfs(String requestedKey, int requestedAmount, HashSet outputItemStack : recipeNode.getRecipeOutputs().entrySet()) { if (recipeNode.getPinnedOutputKeys().containsKey(outputItemStack.getKey())) { recipeNode.addToRemainders(outputItemStack.getKey(), outputItemStack.getValue() * crafts); @@ -264,7 +276,7 @@ public int dfs(String requestedKey, int requestedAmount, HashSet entry : ingredientsToRequest.entrySet()) { history.add(recipeId); - int provided = dfs(entry.getKey(), entry.getValue(), history, false); + int provided = dfs(entry.getKey(), entry.getValue(), history); int chainInputs = entry.getValue() - provided; recipeNode.addToChainInputs(entry.getKey(), chainInputs); history.remove(recipeId); @@ -323,7 +335,9 @@ public void postProcess() { .put(pinnedOutput.getGridIdx(), withStackSize(pinnedOutput.getStack(), calculatedCount)); this.calculatedRemainders.put( pinnedOutput.getGridIdx(), - withStackSize(pinnedOutput.getStack(), recipeNode.getRemainder(key))); + withStackSize( + pinnedOutput.getStack(), + recipeNode.getRemainder(key) + recipeNode.getChainOutput(key))); this.calculatedCraftCounts.put(pinnedOutput.getGridIdx(), recipeNode.getCrafts()); } @@ -350,10 +364,13 @@ public void postProcess() { for (Map.Entry entry : recipeNode.getRemainders().entrySet()) { int slotIdx = recipeNode.getPinnedOutputKeys().get(entry.getKey()); this.outputSlots.add(slotIdx); - int output = Math.min(entry.getValue(), requestedItems.getOrDefault(entry.getKey(), 0)); - int remainder = Math.max(0, entry.getValue() - requestedItems.getOrDefault(entry.getKey(), 0)); - remainders.compute(entry.getKey(), (k, v) -> (v == null ? 0 : v) + remainder); - outputs.compute(entry.getKey(), (k, v) -> (v == null ? 0 : v) + output); + remainders.compute(entry.getKey(), (k, v) -> (v == null ? 0 : v) + entry.getValue()); + } + + for (Map.Entry entry : recipeNode.getChainOutputs().entrySet()) { + int slotIdx = recipeNode.getPinnedOutputKeys().get(entry.getKey()); + this.outputSlots.add(slotIdx); + outputs.compute(entry.getKey(), (k, v) -> (v == null ? 0 : v) + entry.getValue()); } for (Map.Entry entry : recipeNode.getChainInputs().entrySet()) { diff --git a/src/main/java/codechicken/nei/bookmarks/crafts/graph/FluidConversionGraphNode.java b/src/main/java/codechicken/nei/bookmarks/crafts/graph/FluidConversionGraphNode.java index 423ca51e4..19d185aad 100644 --- a/src/main/java/codechicken/nei/bookmarks/crafts/graph/FluidConversionGraphNode.java +++ b/src/main/java/codechicken/nei/bookmarks/crafts/graph/FluidConversionGraphNode.java @@ -84,23 +84,24 @@ public String getInputKey() { return conversionInputs.entrySet().stream().findFirst().get().getKey(); } - public int processResults(String outputKey, String inputKey, int outputItemRequested, int inputItemReturned) { + public int processResults(String outputKey, String inputKey, int inputItemReturned) { int outputFluidSize = conversionOutputs.get(outputKey); int inputFluidSize = conversionInputs.get(inputKey); - int fluidRequested = outputItemRequested * outputFluidSize; int fluidReturned = inputItemReturned * inputFluidSize; - this.fluidRemainder += fluidRequested - fluidReturned; + int outputItemReturned = fluidReturned / outputFluidSize; + + this.fluidRemainder += Math.max(0, fluidReturned - outputItemReturned * outputFluidSize); if (keyToEmptyContainer.containsKey(outputKey)) { String containerKey = keyToEmptyContainer.get(outputKey); - consumedEmptyContainers.compute(containerKey, (k, v) -> (v == null ? 0 : v) + outputItemRequested); + consumedEmptyContainers.compute(containerKey, (k, v) -> (v == null ? 0 : v) + outputItemReturned); } if (keyToEmptyContainer.containsKey(inputKey)) { String containerKey = keyToEmptyContainer.get(inputKey); producedEmptyContainers.compute(containerKey, (k, v) -> (v == null ? 0 : v) + inputItemReturned); } - return fluidReturned / outputFluidSize; + return outputItemReturned; } public Map getConsumedEmptyContainers() { diff --git a/src/main/java/codechicken/nei/bookmarks/crafts/graph/RecipeGraphNode.java b/src/main/java/codechicken/nei/bookmarks/crafts/graph/RecipeGraphNode.java index b127652cf..21d1b7f5f 100644 --- a/src/main/java/codechicken/nei/bookmarks/crafts/graph/RecipeGraphNode.java +++ b/src/main/java/codechicken/nei/bookmarks/crafts/graph/RecipeGraphNode.java @@ -27,6 +27,7 @@ public class RecipeGraphNode implements CraftingGraphNode { private int crafts = 0; private final Map remainders = new HashMap<>(); private final Map chainInputs = new HashMap<>(); + private final Map chainOutputs = new HashMap<>(); public RecipeGraphNode(BookmarkRecipe recipe, List pinnedInputs, List pinnedOutputs) { @@ -120,6 +121,18 @@ public void addToChainInputs(String itemKey, int size) { }); } + public Map getChainOutputs() { + return chainOutputs; + } + + public int getChainOutput(String itemKey) { + return chainOutputs.getOrDefault(itemKey, 0); + } + + public void setChainOutputs(String itemKey, int size) { + chainOutputs.put(itemKey, size); + } + public Map getChainInputs() { return chainInputs; }