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