aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api/util
diff options
context:
space:
mode:
authormiozune <miozune@gmail.com>2023-11-14 10:39:03 +0900
committerGitHub <noreply@github.com>2023-11-14 10:39:03 +0900
commitaf3ef0e96b1522f1953e62164cf2bcd0a5291475 (patch)
tree3f600bb5bd8dce0f70bc9fcb865c511e0c6956cb /src/main/java/gregtech/api/util
parent4f6577fdc1a18cf06461fbf24d43bdacbb773bea (diff)
downloadGT5-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.java5
-rw-r--r--src/main/java/gregtech/api/util/GT_ParallelHelper.java70
-rw-r--r--src/main/java/gregtech/api/util/GT_Recipe.java47
-rw-r--r--src/main/java/gregtech/api/util/GT_Utility.java14
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) {