@@ -177,25 +177,64 @@ public ITerminalCraftingPlanFlat<I> flatten() {
177177 }
178178
179179 public static class IndexedEntries {
180- private final Map <IPrototypedIngredient <?, ?>, TerminalCraftingPlanFlatStatic .Entry > indexedEntries ;
180+ /**
181+ * Entries indexed by a canonical list of prototype ingredients.
182+ * <p>
183+ * Each key is a list of {@link IPrototypedIngredient} where:
184+ * <ul>
185+ * <li>Every element has quantity 1.</li>
186+ * <li>Every element uses the exact-match-no-quantity condition.</li>
187+ * </ul>
188+ * The original (possibly non-normalized) alternatives list is stored inside the
189+ * {@link TerminalCraftingPlanFlatStatic.Entry} for rendering purposes.
190+ */
191+ private final Map <List <IPrototypedIngredient <?, ?>>, TerminalCraftingPlanFlatStatic .Entry > indexedEntries ;
181192
182193 public IndexedEntries () {
183194 this .indexedEntries = Maps .newHashMap ();
184195 }
185196
186- public TerminalCraftingPlanFlatStatic .Entry get (IPrototypedIngredient <?, ?> prototypedIngredient ) {
187- IPrototypedIngredient <?, ?> prototype = getPrototype (prototypedIngredient );
188- return indexedEntries .computeIfAbsent (prototype , k -> new TerminalCraftingPlanFlatStatic .Entry (new PrototypedIngredient (prototypedIngredient .getComponent (), prototype .getPrototype (), prototypedIngredient .getCondition ())));
189- }
190-
191- protected <T , M > IPrototypedIngredient <T , M > getPrototype (IPrototypedIngredient <T , M > prototypedIngredient ) {
192- IIngredientMatcher <T , M > matcher = prototypedIngredient .getComponent ().getMatcher ();
193- return new PrototypedIngredient (prototypedIngredient .getComponent (), matcher .withQuantity (prototypedIngredient .getPrototype (), 1L ), matcher .getExactMatchNoQuantityCondition ());
194- }
195-
196- public static long getQuantity (IPrototypedIngredient <?, ?> prototypedIngredient ) {
197- IIngredientMatcher matcher = prototypedIngredient .getComponent ().getMatcher ();
198- return matcher .getQuantity (prototypedIngredient .getPrototype ());
197+ /**
198+ * Get (or create) the entry corresponding to the given list of alternative ingredients.
199+ *
200+ * @param prototypedIngredients A non-empty list of alternatives.
201+ * @return The corresponding flat plan entry.
202+ */
203+ public TerminalCraftingPlanFlatStatic .Entry get (List <IPrototypedIngredient <?, ?>> prototypedIngredients ) {
204+ List <IPrototypedIngredient <?, ?>> key = getPrototypes (prototypedIngredients );
205+ return indexedEntries .computeIfAbsent (key ,
206+ k -> new TerminalCraftingPlanFlatStatic .Entry (k ));
207+ }
208+
209+ /**
210+ * Build a canonical list of prototype ingredients for the given alternatives.
211+ * Quantities are normalized to 1 and the exact-match-no-quantity condition is used.
212+ */
213+ protected List <IPrototypedIngredient <?, ?>> getPrototypes (List <IPrototypedIngredient <?, ?>> prototypedIngredients ) {
214+ List <IPrototypedIngredient <?, ?>> result = new ArrayList <>(prototypedIngredients .size ());
215+ for (IPrototypedIngredient <?, ?> ingredient : prototypedIngredients ) {
216+ IIngredientMatcher matcher = ingredient .getComponent ().getMatcher ();
217+ result .add (new PrototypedIngredient (
218+ ingredient .getComponent (),
219+ matcher .withQuantity (ingredient .getPrototype (), 1L ),
220+ matcher .getExactMatchNoQuantityCondition ()));
221+ }
222+ return result ;
223+ }
224+
225+ /**
226+ * Get the quantity associated with the given alternatives list.
227+ * <p>
228+ * This is derived from the first element, which is consistent with prior behaviour
229+ * when only a single prototype was available.
230+ */
231+ public static long getQuantity (List <IPrototypedIngredient <?, ?>> prototypedIngredients ) {
232+ if (prototypedIngredients .isEmpty ()) {
233+ return 0 ;
234+ }
235+ IPrototypedIngredient <?, ?> first = prototypedIngredients .get (0 );
236+ IIngredientMatcher matcher = first .getComponent ().getMatcher ();
237+ return matcher .getQuantity (first .getPrototype ());
199238 }
200239
201240 public Collection <TerminalCraftingPlanFlatStatic .Entry > getEntries () {
@@ -212,8 +251,9 @@ protected static <I> void groupDependenciesByPrototype(IndexedEntries indexedEnt
212251
213252 // Determine outputs that are invalid or will be crafted
214253 for (IPrototypedIngredient <?, ?> output : plan .getOutputs ()) {
215- TerminalCraftingPlanFlatStatic .Entry entry = indexedEntries .get (output );
216- long quantity = IndexedEntries .getQuantity (output );
254+ List <IPrototypedIngredient <?, ?>> outputs = List .of (output );
255+ TerminalCraftingPlanFlatStatic .Entry entry = indexedEntries .get (outputs );
256+ long quantity = IndexedEntries .getQuantity (outputs );
217257
218258 if (plan .getStatus () == TerminalCraftingJobStatus .ERROR
219259 || plan .getStatus () == TerminalCraftingJobStatus .INVALID
@@ -238,16 +278,16 @@ protected static <I> void groupDependenciesByPrototype(IndexedEntries indexedEnt
238278
239279 // Determine storage ingredients
240280 for (IPrototypedIngredient <?, ?> output : plan .getBufferedIngredients ()) {
241- TerminalCraftingPlanFlatStatic .Entry entry = indexedEntries .get (output );
242- long quantity = IndexedEntries .getQuantity (output );
281+ List <IPrototypedIngredient <?, ?>> outputs = List .of (output );
282+ TerminalCraftingPlanFlatStatic .Entry entry = indexedEntries .get (outputs );
283+ long quantity = IndexedEntries .getQuantity (outputs );
243284 entry .setQuantityInStorage (entry .getQuantityInStorage () + quantity );
244285 }
245286
246287 // Determine missing ingredients
247288 for (List <IPrototypedIngredient <?, ?>> outputVariants : plan .getLastMissingIngredients ()) {
248- IPrototypedIngredient <?, ?> output = outputVariants .stream ().findFirst ().get ();
249- TerminalCraftingPlanFlatStatic .Entry entry = indexedEntries .get (output );
250- long quantity = IndexedEntries .getQuantity (output );
289+ TerminalCraftingPlanFlatStatic .Entry entry = indexedEntries .get (outputVariants );
290+ long quantity = IndexedEntries .getQuantity (outputVariants );
251291 entry .setQuantityMissing (entry .getQuantityMissing () + quantity * plan .getCraftingQuantity ());
252292 }
253293
0 commit comments