diff options
author | SKProCH <29896317+SKProCH@users.noreply.github.com> | 2023-09-05 07:54:47 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-05 06:54:47 +0200 |
commit | 8beb872db7d19665a09518c5a5d90577b9f3f847 (patch) | |
tree | a024db315009e544c2ffc1a0a87dc9a82692d157 /src/main/java/gregtech/api/logic | |
parent | 1249b547f0813db813d1c12713b5dafbf46996df (diff) | |
download | GT5-Unofficial-8beb872db7d19665a09518c5a5d90577b9f3f847.tar.gz GT5-Unofficial-8beb872db7d19665a09518c5a5d90577b9f3f847.tar.bz2 GT5-Unofficial-8beb872db7d19665a09518c5a5d90577b9f3f847.zip |
Proper recipe selection for output overflow in LCR and other multiblocks (#2247)
* Implement Stream<FindRecipeResult> findRecipesWithResult for GT_RecipeMap
* Change ProcessingLogic.process to actually use new findRecipesWithResult
* Change ProcessingLogic.process to start finding something only for OUTPUT_FULL result
* Refactor ProcessingLogic.process to make logic more readable
* Replace while with for loop, remove NOT_FOUND return in end of findRecipesWithResult
* Apply spotless
* Make findRecipe use findRecipes, add annotation to GT_Recipe and FindRecipeResult for processRecipe and make method protected, replace wildcard imports
* Remake isRecipeWithOutputFullFound
* Add @Nonnull to methods
* Apply spotless
* Remove Stream version of findRecipeWithResult, replace with predicate one. Add GT_Predicated_Recipe_Map class for utilizing this method. Changes some existent recipe maps to inherit from base class.
* Remove GT_Predicated_Recipe_Map, add Predicate directly to GT_Recipe_Map#findRecipeWithResult. Add AdvancedRecipeValidatorPredicate and FindRecipeWithAdvancedValidatorResult to allow store validation calculations for further use and proper errors displaying.
* Fix InsufficientVoltage errors
* Changes according to review comments. Integrate FindRecipeWithAdvancedValidatorResult to FindRecipeResult, rename AdvancedRecipeValidatorPredicate, encapsulate AdvancedRecipeValidatorPredicate fields, fixes some typos, etc
* Moves InsufficientVoltage check to GT_ParallelHelper. Removes FindRecipeResult#State#INSUFFICIENT_VOLTAGE
* Return an old findRecipeWithResult
* Renames things, call old methods for singleblocks
* Renames things, makes FindRecipeResult ctor private
* Apply spotless
* Move RecipeValidator, fix comments typos
Diffstat (limited to 'src/main/java/gregtech/api/logic')
-rw-r--r-- | src/main/java/gregtech/api/logic/ProcessingLogic.java | 99 |
1 files changed, 72 insertions, 27 deletions
diff --git a/src/main/java/gregtech/api/logic/ProcessingLogic.java b/src/main/java/gregtech/api/logic/ProcessingLogic.java index 6fa25a6c40..345a3e59dd 100644 --- a/src/main/java/gregtech/api/logic/ProcessingLogic.java +++ b/src/main/java/gregtech/api/logic/ProcessingLogic.java @@ -9,12 +9,11 @@ import javax.annotation.Nullable; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; +import org.jetbrains.annotations.NotNull; + import gregtech.api.interfaces.tileentity.IRecipeLockable; import gregtech.api.interfaces.tileentity.IVoidable; -import gregtech.api.recipe.check.CheckRecipeResult; -import gregtech.api.recipe.check.CheckRecipeResultRegistry; -import gregtech.api.recipe.check.FindRecipeResult; -import gregtech.api.recipe.check.SingleRecipeCheck; +import gregtech.api.recipe.check.*; import gregtech.api.util.GT_OverclockCalculator; import gregtech.api.util.GT_ParallelHelper; import gregtech.api.util.GT_Recipe; @@ -275,7 +274,6 @@ public class ProcessingLogic { maxParallel = maxParallelSupplier.get(); } - FindRecipeResult findRecipeResult; if (isRecipeLocked && recipeLockableMachine != null && recipeLockableMachine.getSingleRecipeCheck() != null) { // Recipe checker is already built, we'll use it SingleRecipeCheck singleRecipeCheck = recipeLockableMachine.getSingleRecipeCheck(); @@ -284,45 +282,81 @@ public class ProcessingLogic { if (singleRecipeCheck.checkRecipeInputs(false, 1, inputItems, inputFluids) == 0) { return CheckRecipeResultRegistry.NO_RECIPE; } - findRecipeResult = FindRecipeResult.ofSuccess( + + return processRecipe( recipeLockableMachine.getSingleRecipeCheck() .getRecipe()); - } else { - findRecipeResult = findRecipe(recipeMap); } - GT_Recipe recipe; - CheckRecipeResult result; - if (findRecipeResult.isSuccessful()) { - recipe = findRecipeResult.getRecipeNonNull(); - result = validateRecipe(recipe); - if (!result.wasSuccessful()) { - return result; - } else { - if (recipe.mCanBeBuffered) { - lastRecipe = recipe; - } else { - lastRecipe = null; - } + FindRecipeResult findRecipeResult = findRecipe(recipeMap); + // If processRecipe is not overridden, advanced recipe validation logic is used, and we can reuse calculations. + if (findRecipeResult.hasRecipeValidator()) { + RecipeValidator recipeValidator = findRecipeResult.getRecipeValidator(); + + // There are two cases: + // 1 - there are actually no matching recipes + // 2 - there are some matching recipes, but we rejected it due to our advanced validation (e.g. OUTPUT_FULL) + if (findRecipeResult.getState() == FindRecipeResult.State.NOT_FOUND + && recipeValidator.getFirstCheckResult() != null) { + // Here we're handling case 2 + // If there are matching recipes but our validation rejected them, + // we should return a first one to display a proper error in the machine GUI + return recipeValidator.getFirstCheckResult(); } - } else { - if (findRecipeResult.getState() == FindRecipeResult.State.INSUFFICIENT_VOLTAGE) { - return CheckRecipeResultRegistry.insufficientPower(findRecipeResult.getRecipeNonNull().mEUt); - } else { - return CheckRecipeResultRegistry.NO_RECIPE; + + // If everything is ok, reuse our calculations + if (recipeValidator.isExecutedAtLeastOnce() && findRecipeResult.isSuccessful()) { + return applyRecipe( + findRecipeResult.getRecipeNonNull(), + recipeValidator.getLastParallelHelper(), + recipeValidator.getLastOverclockCalculator(), + recipeValidator.getLastCheckResult()); } } + if (!findRecipeResult.isSuccessful()) { + return CheckRecipeResultRegistry.NO_RECIPE; + } + + return processRecipe(findRecipeResult.getRecipeNonNull()); + } + + /** + * Checks if supplied recipe is valid for process. + * If so, additionally performs input consumption, output calculation with parallel, and overclock calculation. + * + * @param recipe The recipe which will be checked and processed + */ + @Nonnull + protected CheckRecipeResult processRecipe(@Nonnull GT_Recipe recipe) { + CheckRecipeResult result = validateRecipe(recipe); + if (!result.wasSuccessful()) { + return result; + } + GT_ParallelHelper helper = createParallelHelper(recipe); GT_OverclockCalculator calculator = createOverclockCalculator(recipe); helper.setCalculator(calculator); helper.build(); + return applyRecipe(recipe, helper, calculator, result); + } + + /** + * Applies the recipe and calculated parameters + */ + private CheckRecipeResult applyRecipe(@NotNull GT_Recipe recipe, GT_ParallelHelper helper, + GT_OverclockCalculator calculator, CheckRecipeResult result) { if (!helper.getResult() .wasSuccessful()) { return helper.getResult(); } + if (recipe.mCanBeBuffered) { + lastRecipe = recipe; + } else { + lastRecipe = null; + } calculatedParallels = helper.getCurrentParallel(); if (calculator.getConsumption() == Long.MAX_VALUE) { @@ -360,14 +394,25 @@ public class ProcessingLogic { @Nonnull protected FindRecipeResult findRecipe(@Nullable GT_Recipe_Map map) { if (map == null) return FindRecipeResult.NOT_FOUND; - return map.findRecipeWithResult( + + RecipeValidator recipeValidator = new RecipeValidator( + this::validateRecipe, + this::createParallelHelper, + this::createOverclockCalculator); + + FindRecipeResult findRecipeResult = map.findRecipeWithResult( lastRecipe, + recipeValidator, false, false, amperageOC ? availableVoltage * availableAmperage : availableVoltage, inputFluids, specialSlotItem, inputItems); + + findRecipeResult.setRecipeValidator(recipeValidator); + + return findRecipeResult; } /** |