diff options
author | miozune <miozune@gmail.com> | 2023-11-14 10:39:03 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-14 10:39:03 +0900 |
commit | af3ef0e96b1522f1953e62164cf2bcd0a5291475 (patch) | |
tree | 3f600bb5bd8dce0f70bc9fcb865c511e0c6956cb /src/main/java/gregtech/api/util | |
parent | 4f6577fdc1a18cf06461fbf24d43bdacbb773bea (diff) | |
download | GT5-Unofficial-af3ef0e96b1522f1953e62164cf2bcd0a5291475.tar.gz GT5-Unofficial-af3ef0e96b1522f1953e62164cf2bcd0a5291475.tar.bz2 GT5-Unofficial-af3ef0e96b1522f1953e62164cf2bcd0a5291475.zip |
Fix recipe check after previous PR (#2364)
* Fix wildcard recipes not working
* Fix recipe can be run without non-consumed item second time
* Add API for addons to modify input consumption behavior
* Fix recipes falsely being sensitive to NBT
Diffstat (limited to 'src/main/java/gregtech/api/util')
-rw-r--r-- | src/main/java/gregtech/api/util/GT_ModHandler.java | 5 | ||||
-rw-r--r-- | src/main/java/gregtech/api/util/GT_ParallelHelper.java | 70 | ||||
-rw-r--r-- | src/main/java/gregtech/api/util/GT_Recipe.java | 47 | ||||
-rw-r--r-- | src/main/java/gregtech/api/util/GT_Utility.java | 14 |
4 files changed, 103 insertions, 33 deletions
diff --git a/src/main/java/gregtech/api/util/GT_ModHandler.java b/src/main/java/gregtech/api/util/GT_ModHandler.java index eb5aa271f9..e16e559360 100644 --- a/src/main/java/gregtech/api/util/GT_ModHandler.java +++ b/src/main/java/gregtech/api/util/GT_ModHandler.java @@ -51,7 +51,6 @@ import net.minecraft.tileentity.TileEntityFurnace; import net.minecraft.world.World; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.oredict.OreDictionary; import net.minecraftforge.oredict.ShapedOreRecipe; import net.minecraftforge.oredict.ShapelessOreRecipe; @@ -2097,11 +2096,11 @@ public class GT_ModHandler { } private static boolean searchRecyclerCache(ItemStack stack, Set<GT_Utility.ItemId> set) { - if (set.contains(GT_Utility.ItemId.createNoCopy(stack.getItem(), stack.getItemDamage(), null))) { + if (set.contains(GT_Utility.ItemId.createWithoutNBT(stack))) { return true; } // ic2.api.recipe.RecipeInputItemStack#matches expects item with wildcard meta to accept arbitrary meta - return set.contains(GT_Utility.ItemId.createNoCopy(stack.getItem(), OreDictionary.WILDCARD_VALUE, null)); + return set.contains(GT_Utility.ItemId.createAsWildcard(stack)); } /** diff --git a/src/main/java/gregtech/api/util/GT_ParallelHelper.java b/src/main/java/gregtech/api/util/GT_ParallelHelper.java index e848d87092..d3921b613d 100644 --- a/src/main/java/gregtech/api/util/GT_ParallelHelper.java +++ b/src/main/java/gregtech/api/util/GT_ParallelHelper.java @@ -86,8 +86,7 @@ public class GT_ParallelHelper { */ private boolean batchMode; /** - * Should the Parallel Helper automatically calculate the outputs of the recipe with current - * parallel + * Should the Parallel Helper automatically calculate the outputs of the recipe with current parallel? */ private boolean calculateOutputs; /** @@ -102,6 +101,14 @@ public class GT_ParallelHelper { * Modifier which is applied on the recipe eut. Useful for GT++ machines */ private float eutModifier = 1; + /** + * Method for calculating max parallel from given inputs. + */ + private MaxParallelCalculator maxParallelCalculator = GT_Recipe::maxParallelCalculatedByInputs; + /** + * Method for consuming inputs after determining how many parallels it can execute. + */ + private InputConsumer inputConsumer = GT_Recipe::consumeInput; /** * Calculator to use for overclocking @@ -278,6 +285,22 @@ public class GT_ParallelHelper { } /** + * Sets method for calculating max parallel from given inputs. + */ + public GT_ParallelHelper setMaxParallelCalculator(MaxParallelCalculator maxParallelCalculator) { + this.maxParallelCalculator = maxParallelCalculator; + return this; + } + + /** + * Sets method for consuming inputs after determining how many parallels it can execute. + */ + public GT_ParallelHelper setInputConsumer(InputConsumer inputConsumer) { + this.inputConsumer = inputConsumer; + return this; + } + + /** * Finishes the GT_ParallelHelper. Anything changed after this will not effect anything */ public GT_ParallelHelper build() { @@ -359,25 +382,20 @@ public class GT_ParallelHelper { } /** - * Use {@link #tryConsumeRecipeInputs(GT_Recipe, FluidStack[], ItemStack[], int)} + * @deprecated Use {@link #setMaxParallelCalculator} and {@link #setInputConsumer} */ @Deprecated protected boolean tryConsumeRecipeInputs(GT_Recipe recipe, FluidStack[] fluids, ItemStack[] items) { - return tryConsumeRecipeInputs(recipe, fluids, items, 1); + return false; } /** - * Try to consume the inputs of the recipe - * - * @param recipe Processed recipe - * @param fluids fluid inputs that will be consumed - * @param items item inputs that will be consumed - * @param minParallel minimum amount of parallels to do with this check - * @return True if recipe was satisfied, else false + * @deprecated Use {@link #setMaxParallelCalculator} and {@link #setInputConsumer} */ + @Deprecated protected boolean tryConsumeRecipeInputs(GT_Recipe recipe, FluidStack[] fluids, ItemStack[] items, int minParallel) { - return recipe.isRecipeInputEqual(true, false, minParallel, fluids, items); + return false; } /** @@ -461,18 +479,18 @@ public class GT_ParallelHelper { if (recipeCheck != null) { currentParallel = recipeCheck.checkRecipeInputs(true, actualMaxParallel, itemInputs, fluidInputs); } else { - currentParallel = (int) recipe.maxParallelCalculatedByInputs(actualMaxParallel, fluidInputs, itemInputs); + currentParallel = (int) maxParallelCalculator.calculate(recipe, actualMaxParallel, fluidInputs, itemInputs); if (currentParallel > 0) { if (tSingleRecipeCheckBuilder != null) { // If recipe checker is not built yet, build and set it - recipe.consumeInput(1, fluidInputs, itemInputs); + inputConsumer.consume(recipe, 1, fluidInputs, itemInputs); SingleRecipeCheck builtCheck = tSingleRecipeCheckBuilder.setAfter(itemInputs, fluidInputs) .setRecipe(recipe) .build(); singleRecipeMachine.setSingleRecipeCheck(builtCheck); - recipe.consumeInput(currentParallel - 1, fluidInputs, itemInputs); + inputConsumer.consume(recipe, currentParallel - 1, fluidInputs, itemInputs); } else { - recipe.consumeInput(currentParallel, fluidInputs, itemInputs); + inputConsumer.consume(recipe, currentParallel, fluidInputs, itemInputs); } } } @@ -490,7 +508,7 @@ public class GT_ParallelHelper { } // If Batch Mode is enabled determine how many extra parallels we can get if (batchMode && currentParallel > 0 && calculator.getDuration() < MAX_BATCH_MODE_TICK_TIME) { - int tExtraParallels = 0; + int tExtraParallels; double batchMultiplierMax = MAX_BATCH_MODE_TICK_TIME / calculator.getDuration(); final int maxExtraParallels = (int) Math.floor( Math.min( @@ -499,9 +517,9 @@ public class GT_ParallelHelper { if (recipeCheck != null) { tExtraParallels = recipeCheck.checkRecipeInputs(true, maxExtraParallels, itemInputs, fluidInputs); } else { - tExtraParallels = (int) recipe - .maxParallelCalculatedByInputs(maxExtraParallels, fluidInputs, itemInputs); - recipe.consumeInput(tExtraParallels, fluidInputs, itemInputs); + tExtraParallels = (int) maxParallelCalculator + .calculate(recipe, maxExtraParallels, fluidInputs, itemInputs); + inputConsumer.consume(recipe, tExtraParallels, fluidInputs, itemInputs); } durationMultiplier = 1.0f + (float) tExtraParallels / currentParallel; currentParallel += tExtraParallels; @@ -583,4 +601,16 @@ public class GT_ParallelHelper { } } } + + @FunctionalInterface + public interface MaxParallelCalculator { + + double calculate(GT_Recipe recipe, int maxParallel, FluidStack[] fluids, ItemStack[] items); + } + + @FunctionalInterface + public interface InputConsumer { + + void consume(GT_Recipe recipe, int amountMultiplier, FluidStack[] aFluidInputs, ItemStack[] aInputs); + } } diff --git a/src/main/java/gregtech/api/util/GT_Recipe.java b/src/main/java/gregtech/api/util/GT_Recipe.java index 5cbd54b2f3..61cd2134a3 100644 --- a/src/main/java/gregtech/api/util/GT_Recipe.java +++ b/src/main/java/gregtech/api/util/GT_Recipe.java @@ -670,7 +670,8 @@ public class GT_Recipe implements Comparable<GT_Recipe> { } /** - * WARNING: ensure that the inputs and fluid inputs are enough to be consumed! + * WARNING: Ensure that item inputs and fluid inputs are enough to be consumed with + * {@link #maxParallelCalculatedByInputs} before calling this method! */ public void consumeInput(int amountMultiplier, FluidStack[] aFluidInputs, ItemStack... aInputs) { if (amountMultiplier <= 0) return; @@ -770,22 +771,48 @@ public class GT_Recipe implements Comparable<GT_Recipe> { if (aInputs != null) { // Create map for item -> stored amount - Map<GT_Utility.ItemId, Integer> itemMap = new HashMap<>(); Map<GT_Utility.ItemId, Integer> itemCost = new HashMap<>(); - for (ItemStack itemStack : aInputs) { + Map<GT_Utility.ItemId, Integer> itemMap = new HashMap<>(); + Map<GT_Utility.ItemId, Integer> itemMapWildcard = new HashMap<>(); // Used only when wildcard input is found + boolean foundWildcard = false; + for (ItemStack itemStack : mInputs) { if (itemStack == null) continue; - itemMap.merge(GT_Utility.ItemId.createNoCopy(itemStack), itemStack.stackSize, Integer::sum); + if (itemStack.getItemDamage() == W) { + foundWildcard = true; + } + if (isNBTSensitive) { + itemCost.merge(GT_Utility.ItemId.createNoCopy(itemStack), itemStack.stackSize, Integer::sum); + } else { + itemCost.merge(GT_Utility.ItemId.createWithoutNBT(itemStack), itemStack.stackSize, Integer::sum); + } } - for (ItemStack itemStack : mInputs) { + for (ItemStack itemStack : aInputs) { if (itemStack == null) continue; - itemCost.merge(GT_Utility.ItemId.createNoCopy(itemStack), itemStack.stackSize, Integer::sum); + if (isNBTSensitive) { + itemMap.merge(GT_Utility.ItemId.createNoCopy(itemStack), itemStack.stackSize, Integer::sum); + } else { + itemMap.merge(GT_Utility.ItemId.createWithoutNBT(itemStack), itemStack.stackSize, Integer::sum); + } + if (foundWildcard) { + itemMapWildcard + .merge(GT_Utility.ItemId.createAsWildcard(itemStack), itemStack.stackSize, Integer::sum); + } } // Check how many parallels can it perform for each item for (Map.Entry<GT_Utility.ItemId, Integer> costEntry : itemCost.entrySet()) { - if (costEntry.getValue() > 0) { - currentParallel = Math.min( - currentParallel, - (double) itemMap.getOrDefault(costEntry.getKey(), 0) / costEntry.getValue()); + GT_Utility.ItemId costItem = costEntry.getKey(); + int costValue = costEntry.getValue(); + Map<GT_Utility.ItemId, Integer> mapToUse = costItem.metaData() == W ? itemMapWildcard : itemMap; + if (costValue > 0) { + currentParallel = Math + .min(currentParallel, (double) mapToUse.getOrDefault(costItem, 0) / costValue); + } else { + // Non-consumed input + // We need to distinguish null and 0 here, since not having item + // and having 0-sized item (ghost circuit) are different. + if (!mapToUse.containsKey(costItem)) { + currentParallel = 0; + } } if (currentParallel <= 0) { return 0; diff --git a/src/main/java/gregtech/api/util/GT_Utility.java b/src/main/java/gregtech/api/util/GT_Utility.java index 998947e5d6..755dc0286e 100644 --- a/src/main/java/gregtech/api/util/GT_Utility.java +++ b/src/main/java/gregtech/api/util/GT_Utility.java @@ -4814,6 +4814,20 @@ public class GT_Utility { } /** + * This method stores metadata as wildcard and NBT as null. + */ + public static ItemId createAsWildcard(ItemStack itemStack) { + return new AutoValue_GT_Utility_ItemId(itemStack.getItem(), W, null); + } + + /** + * This method stores NBT as null. + */ + public static ItemId createWithoutNBT(ItemStack itemStack) { + return new AutoValue_GT_Utility_ItemId(itemStack.getItem(), itemStack.getItemDamage(), null); + } + + /** * This method does not copy NBT in order to save time. Make sure not to mutate it! */ public static ItemId createNoCopy(ItemStack itemStack) { |