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