@@ -290,7 +290,10 @@ public void fillCraftingJobBufferFromStorage(CraftingJob craftingJob, Function<I
290290 throw new IllegalStateException ("Re-filling a non-empty crafting job buffer is illegal" );
291291 }
292292 // Determine the ingredients to extract. We can not reuse the ingredientsStorage value from the crafting job, as this may have been modified due to job splitting.
293- Pair <Map <IngredientComponent <?, ?>, List <?>>, Map <IngredientComponent <?, ?>, MissingIngredients <?, ?>>> inputResult = CraftingHelpers .getRecipeInputs (storageGetter , craftingJob .getRecipe (), false , Maps .newIdentityHashMap (), Maps .newIdentityHashMap (), true , craftingJob .getAmount ());
293+ // If this job has dependencies, skip reusable ingredients so that they remain available for other jobs.
294+ // They will be lazily extracted in the update loop once the dependencies have finished.
295+ boolean skipReusableIngredients = !craftingJob .getDependencyCraftingJobs ().isEmpty ();
296+ Pair <Map <IngredientComponent <?, ?>, List <?>>, Map <IngredientComponent <?, ?>, MissingIngredients <?, ?>>> inputResult = CraftingHelpers .getRecipeInputs (storageGetter , craftingJob .getRecipe (), false , Maps .newIdentityHashMap (), Maps .newIdentityHashMap (), true , craftingJob .getAmount (), skipReusableIngredients );
294297 IMixedIngredients buffer = new MixedIngredients (inputResult .getLeft ());
295298 craftingJob .setIngredientsStorageBuffer (CraftingHelpers .compressMixedIngredients (buffer ));
296299 craftingJob .setLastMissingIngredients (inputResult .getRight ());
@@ -503,35 +506,33 @@ public void update(INetwork network, int channel, PartPos targetPos) {
503506 // trigger a crafting job for them if no job is running yet.
504507 // This special case is needed because reusable ingredients are usually durability-based,
505508 // and may be consumed _during_ a bulk crafting job.
506- if (pendingCraftingJob .getLastMissingIngredients ().isEmpty ()) {
507- for (IngredientComponent <?, ?> component : inputs .getRight ().keySet ()) {
508- MissingIngredients <?, ?> missingIngredients = inputs .getRight ().get (component );
509- for (MissingIngredients .Element <?, ?> element : missingIngredients .getElements ()) {
510- if (element .isInputReusable ()) {
511- IIngredientComponentStorage storage = CraftingHelpers .getNetworkStorage (network , channel , component , true );
512- for (MissingIngredients .PrototypedWithRequested alternative : element .getAlternatives ()) {
513- // First check if we can extract it from storage.
514- Object extractedFromStorage = storage .extract (alternative .getRequestedPrototype ().getPrototype (), alternative .getRequestedPrototype ().getCondition (), false );
515- if (!((IIngredientMatcher ) component .getMatcher ()).isEmpty (extractedFromStorage )) {
516- pendingCraftingJob .addToIngredientsStorageBuffer ((IngredientComponent <? super Object , ? extends Object >) component , extractedFromStorage );
517- break ;
518- }
519-
520- // Try to start crafting jobs for each alternative until one of them succeeds.
521- if (CraftingHelpers .isCrafting (craftingNetwork , channel ,
522- alternative .getRequestedPrototype ().getComponent (), alternative .getRequestedPrototype ().getPrototype (), alternative .getRequestedPrototype ().getCondition ())) {
523- // Break loop if we have found an existing job for our dependency
524- // This may occur if a crafting job was triggered in a parallelized job
525- break ;
526- }
527- CraftingJob craftingJob = CraftingHelpers .calculateAndScheduleCraftingJob (network , channel ,
528- alternative .getRequestedPrototype ().getComponent (), alternative .getRequestedPrototype ().getPrototype (), alternative .getRequestedPrototype ().getCondition (), true , true ,
529- CraftingHelpers .getGlobalCraftingJobIdentifier (), null );
530- if (craftingJob != null ) {
531- pendingCraftingJob .addDependency (craftingJob );
532- // Break loop once we have found a valid job
533- break ;
534- }
509+ for (IngredientComponent <?, ?> component : inputs .getRight ().keySet ()) {
510+ MissingIngredients <?, ?> missingIngredients = inputs .getRight ().get (component );
511+ for (MissingIngredients .Element <?, ?> element : missingIngredients .getElements ()) {
512+ if (element .isInputReusable ()) {
513+ IIngredientComponentStorage storage = CraftingHelpers .getNetworkStorage (network , channel , component , true );
514+ for (MissingIngredients .PrototypedWithRequested alternative : element .getAlternatives ()) {
515+ // First check if we can extract it from storage.
516+ Object extractedFromStorage = storage .extract (alternative .getRequestedPrototype ().getPrototype (), alternative .getRequestedPrototype ().getCondition (), false );
517+ if (!((IIngredientMatcher ) component .getMatcher ()).isEmpty (extractedFromStorage )) {
518+ pendingCraftingJob .addToIngredientsStorageBuffer ((IngredientComponent <? super Object , ? extends Object >) component , extractedFromStorage );
519+ break ;
520+ }
521+
522+ // Try to start crafting jobs for each alternative until one of them succeeds.
523+ if (CraftingHelpers .isCrafting (craftingNetwork , channel ,
524+ alternative .getRequestedPrototype ().getComponent (), alternative .getRequestedPrototype ().getPrototype (), alternative .getRequestedPrototype ().getCondition ())) {
525+ // Break loop if we have found an existing job for our dependency
526+ // This may occur if a crafting job was triggered in a parallelized job
527+ break ;
528+ }
529+ CraftingJob craftingJob = CraftingHelpers .calculateAndScheduleCraftingJob (network , channel ,
530+ alternative .getRequestedPrototype ().getComponent (), alternative .getRequestedPrototype ().getPrototype (), alternative .getRequestedPrototype ().getCondition (), true , true ,
531+ CraftingHelpers .getGlobalCraftingJobIdentifier (), null );
532+ if (craftingJob != null ) {
533+ pendingCraftingJob .addDependency (craftingJob );
534+ // Break loop once we have found a valid job
535+ break ;
535536 }
536537 }
537538 }
0 commit comments