From 90de9deee87c8c129963ebac36129fe375450318 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sun, 29 Jun 2025 22:37:38 +0800 Subject: Close #1732, Close #1826, Close #1842, Close #1877, Close #1870 --- .../rei/api/common/transfer/ItemRecipeFinder.java | 47 +++++++++++++++++----- .../rei/api/common/transfer/RecipeFinder.java | 23 ++++++----- 2 files changed, 50 insertions(+), 20 deletions(-) (limited to 'api/src/main') diff --git a/api/src/main/java/me/shedaniel/rei/api/common/transfer/ItemRecipeFinder.java b/api/src/main/java/me/shedaniel/rei/api/common/transfer/ItemRecipeFinder.java index 00646b72a..59480aaba 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/transfer/ItemRecipeFinder.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/transfer/ItemRecipeFinder.java @@ -33,12 +33,14 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.List; +import java.util.function.BiConsumer; import java.util.function.Consumer; public class ItemRecipeFinder { private final Interner keys = Interners.newWeakInterner(); - private final RecipeFinder finder = new RecipeFinder<>(); + private final RecipeFinder finder = new RecipeFinder<>(); public boolean contains(ItemStack item) { return finder.contains(ofKey(item)); @@ -74,27 +76,54 @@ public class ItemRecipeFinder { } public boolean findRecipe(List> list, int maxCrafts, @Nullable Consumer output) { - return finder.findRecipe(CollectionUtils.map(list, this::ofKeys), maxCrafts, itemKey -> { + return finder.findRecipe(toIngredients(list), maxCrafts, flatten(itemStack -> { if (output != null) { - output.accept(new ItemStack(itemKey.item(), 1, itemKey.patch())); + output.accept(itemStack); } - }); + })); } public int countRecipeCrafts(List> list, int maxCrafts, @Nullable Consumer output) { - return finder.countRecipeCrafts(CollectionUtils.map(list, this::ofKeys), maxCrafts, itemKey -> { + return finder.countRecipeCrafts(toIngredients(list), maxCrafts, flatten(itemStack -> { if (output != null) { - output.accept(new ItemStack(itemKey.item(), 1, itemKey.patch())); + output.accept(itemStack); } - }); + })); } private ItemKey ofKey(ItemStack itemStack) { return keys.intern(new ItemKey(itemStack.getItemHolder(), itemStack.getComponentsPatch())); } - private RecipeFinder.Ingredient ofKeys(List itemStack) { - return new RecipeFinder.Ingredient<>(CollectionUtils.map(itemStack, this::ofKey)); + private Ingredient ofKeys(int index, List itemStack) { + return new Ingredient(index, CollectionUtils.map(itemStack, this::ofKey)); + } + + private List toIngredients(List> list) { + List ingredients = new ArrayList<>(); + + for (int i = 0; i < list.size(); i++) { + List stacks = list.get(i); + if (!stacks.isEmpty()) { + ingredients.add(ofKeys(i, stacks)); + } + } + + return ingredients; + } + + private static BiConsumer flatten(Consumer consumer) { + int[] lastIndex = {-1}; + return (itemKey, ingredient) -> { + for (int i = lastIndex[0] + 1; i < ingredient.index(); i++) { + consumer.accept(ItemStack.EMPTY); + } + consumer.accept(new ItemStack(itemKey.item(), 1, itemKey.patch())); + lastIndex[0] = ingredient.index(); + }; + } + + private record Ingredient(int index, List elements) implements RecipeFinder.Ingredient { } private record ItemKey(Holder item, DataComponentPatch patch) { diff --git a/api/src/main/java/me/shedaniel/rei/api/common/transfer/RecipeFinder.java b/api/src/main/java/me/shedaniel/rei/api/common/transfer/RecipeFinder.java index 9b260594c..c19d12ae1 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/transfer/RecipeFinder.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/transfer/RecipeFinder.java @@ -32,9 +32,9 @@ import org.jetbrains.annotations.Nullable; import java.util.BitSet; import java.util.List; import java.util.Set; -import java.util.function.Consumer; +import java.util.function.BiConsumer; -public class RecipeFinder { +public class RecipeFinder> { public final Reference2IntOpenHashMap amounts = new Reference2IntOpenHashMap<>(); public boolean contains(T item) { @@ -56,11 +56,11 @@ public class RecipeFinder { this.amounts.addTo(item, amount); } - public boolean findRecipe(List> list, int maxCrafts, @Nullable Consumer output) { + public boolean findRecipe(List list, int maxCrafts, @Nullable BiConsumer output) { return new Filter(list).tryPick(maxCrafts, output); } - public int countRecipeCrafts(List> list, int maxCrafts, @Nullable Consumer output) { + public int countRecipeCrafts(List list, int maxCrafts, @Nullable BiConsumer output) { return new Filter(list).tryPickAll(maxCrafts, output); } @@ -69,14 +69,14 @@ public class RecipeFinder { } class Filter { - private final List> ingredients; + private final List ingredients; private final int ingredientCount; private final List items; private final int itemCount; private final BitSet data; private final IntList path = new IntArrayList(); - public Filter(final List> list) { + public Filter(final List list) { this.ingredients = list; this.ingredientCount = this.ingredients.size(); this.items = this.getUniqueAvailableIngredientItems(); @@ -87,7 +87,7 @@ public class RecipeFinder { private void setInitialConnections() { for (int i = 0; i < this.ingredientCount; i++) { - List list = ((Ingredient) this.ingredients.get(i)).elements(); + List list = this.ingredients.get(i).elements(); for (int j = 0; j < this.itemCount; j++) { if (list.contains(this.items.get(j))) { @@ -97,7 +97,7 @@ public class RecipeFinder { } } - public boolean tryPick(int maxCrafts, @Nullable Consumer output) { + public boolean tryPick(int maxCrafts, @Nullable BiConsumer output) { if (maxCrafts <= 0) { return true; } else { @@ -117,7 +117,7 @@ public class RecipeFinder { this.unassign(m, l); put(this.items.get(m), maxCrafts); if (bl2) { - output.accept(this.items.get(m)); + output.accept(this.items.get(m), this.ingredients.get(l)); } break; } @@ -362,7 +362,7 @@ public class RecipeFinder { this.data.clear(i, i + j); } - public int tryPickAll(int i, @Nullable Consumer output) { + public int tryPickAll(int i, @Nullable BiConsumer output) { int j = 0; int k = Math.min(i, this.getMinIngredientCount()) + 1; @@ -403,6 +403,7 @@ public class RecipeFinder { } } - public record Ingredient(List elements) { + public interface Ingredient { + List elements(); } } -- cgit