aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/gregtech/api/util/GT_ParallelHelper.java28
-rw-r--r--src/main/java/gregtech/api/util/GT_Recipe.java147
2 files changed, 95 insertions, 80 deletions
diff --git a/src/main/java/gregtech/api/util/GT_ParallelHelper.java b/src/main/java/gregtech/api/util/GT_ParallelHelper.java
index 8430f28fa0..e848d87092 100644
--- a/src/main/java/gregtech/api/util/GT_ParallelHelper.java
+++ b/src/main/java/gregtech/api/util/GT_ParallelHelper.java
@@ -456,26 +456,23 @@ public class GT_ParallelHelper {
maxParallelBeforeBatchMode = Math.min(maxParallel, maxParallelBeforeBatchMode);
- // Consume inputs to determine normal parallel
+ // determine normal parallel
+ int actualMaxParallel = (int) Math.min(maxParallelBeforeBatchMode, availableEUt / tRecipeEUt);
if (recipeCheck != null) {
- int actualMaxParallel = (int) Math.min(maxParallelBeforeBatchMode, availableEUt / tRecipeEUt);
currentParallel = recipeCheck.checkRecipeInputs(true, actualMaxParallel, itemInputs, fluidInputs);
} else {
- long tCurrentUsage = 0;
- boolean builtRecipeCheck = false;
- for (; currentParallel < maxParallelBeforeBatchMode
- && tCurrentUsage < (availableEUt - tRecipeEUt); currentParallel++) {
- if (!tryConsumeRecipeInputs(recipe, fluidInputs, itemInputs)) {
- break;
- }
- tCurrentUsage += tRecipeEUt;
- if (tSingleRecipeCheckBuilder != null && !builtRecipeCheck) {
+ currentParallel = (int) recipe.maxParallelCalculatedByInputs(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);
SingleRecipeCheck builtCheck = tSingleRecipeCheckBuilder.setAfter(itemInputs, fluidInputs)
.setRecipe(recipe)
.build();
singleRecipeMachine.setSingleRecipeCheck(builtCheck);
- builtRecipeCheck = true;
+ recipe.consumeInput(currentParallel - 1, fluidInputs, itemInputs);
+ } else {
+ recipe.consumeInput(currentParallel, fluidInputs, itemInputs);
}
}
}
@@ -502,10 +499,9 @@ public class GT_ParallelHelper {
if (recipeCheck != null) {
tExtraParallels = recipeCheck.checkRecipeInputs(true, maxExtraParallels, itemInputs, fluidInputs);
} else {
- while (tExtraParallels < maxExtraParallels
- && tryConsumeRecipeInputs(recipe, fluidInputs, itemInputs, currentParallel)) {
- tExtraParallels += currentParallel;
- }
+ tExtraParallels = (int) recipe
+ .maxParallelCalculatedByInputs(maxExtraParallels, fluidInputs, itemInputs);
+ recipe.consumeInput(tExtraParallels, fluidInputs, itemInputs);
}
durationMultiplier = 1.0f + (float) tExtraParallels / currentParallel;
currentParallel += tExtraParallels;
diff --git a/src/main/java/gregtech/api/util/GT_Recipe.java b/src/main/java/gregtech/api/util/GT_Recipe.java
index e25316c6dd..5cbd54b2f3 100644
--- a/src/main/java/gregtech/api/util/GT_Recipe.java
+++ b/src/main/java/gregtech/api/util/GT_Recipe.java
@@ -657,65 +657,53 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
*/
public boolean isRecipeInputEqual(boolean aDecreaseStacksizeBySuccess, boolean aDontCheckStackSizes,
int amountMultiplier, FluidStack[] aFluidInputs, ItemStack... aInputs) {
- if (mInputs.length > 0 && aInputs == null) return false;
- if (mFluidInputs.length > 0 && aFluidInputs == null) return false;
+ double maxParallel = maxParallelCalculatedByInputs(amountMultiplier, aFluidInputs, aInputs);
+ if (aDontCheckStackSizes) {
+ return maxParallel > 0;
+ } else if (maxParallel >= amountMultiplier) {
+ if (aDecreaseStacksizeBySuccess) {
+ consumeInput(amountMultiplier, aFluidInputs, aInputs);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * WARNING: ensure that the inputs and fluid inputs are enough to be consumed!
+ */
+ public void consumeInput(int amountMultiplier, FluidStack[] aFluidInputs, ItemStack... aInputs) {
+ if (amountMultiplier <= 0) return;
- // We need to handle 0-size recipe inputs. These are for inputs that don't get consumed.
- boolean inputFound;
int remainingCost;
- // Array tracking modified fluid amounts. For efficiency, we will lazily initialize this array.
- // We use Integer so that we can have null as the default value, meaning unchanged.
- Integer[] newFluidAmounts = null;
if (aFluidInputs != null) {
- newFluidAmounts = new Integer[aFluidInputs.length];
-
for (FluidStack recipeFluidCost : mFluidInputs) {
if (recipeFluidCost != null) {
- inputFound = false;
remainingCost = recipeFluidCost.amount * amountMultiplier;
- for (int i = 0; i < aFluidInputs.length; i++) {
- FluidStack providedFluid = aFluidInputs[i];
+ for (FluidStack providedFluid : aFluidInputs) {
if (providedFluid != null && providedFluid.isFluidEqual(recipeFluidCost)) {
- inputFound = true;
- if (newFluidAmounts[i] == null) {
- newFluidAmounts[i] = providedFluid.amount;
- }
-
- if (aDontCheckStackSizes || newFluidAmounts[i] >= remainingCost) {
- newFluidAmounts[i] -= remainingCost;
- remainingCost = 0;
+ if (providedFluid.amount >= remainingCost) {
+ providedFluid.amount -= remainingCost;
break;
} else {
- remainingCost -= newFluidAmounts[i];
- newFluidAmounts[i] = 0;
+ remainingCost -= providedFluid.amount;
+ providedFluid.amount = 0;
}
}
}
-
- if (remainingCost > 0 || !inputFound) {
- // Cost not satisfied, or for non-consumed inputs, input not found.
- return false;
- }
}
}
}
- // Array tracking modified item stack sizes. For efficiency, we will lazily initialize this array.
- // We use Integer so that we can have null as the default value, meaning unchanged.
- Integer[] newItemAmounts = null;
if (aInputs != null) {
- newItemAmounts = new Integer[aInputs.length];
-
for (ItemStack recipeItemCost : mInputs) {
ItemStack unifiedItemCost = GT_OreDictUnificator.get_nocopy(true, recipeItemCost);
if (unifiedItemCost != null) {
- inputFound = false;
remainingCost = recipeItemCost.stackSize * amountMultiplier;
- for (int i = 0; i < aInputs.length; i++) {
- ItemStack providedItem = aInputs[i];
+ for (ItemStack providedItem : aInputs) {
if (isNBTSensitive && !GT_Utility.areStacksEqual(providedItem, unifiedItemCost, false)) {
continue;
} else if (!isNBTSensitive
@@ -731,49 +719,80 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
}
}
- inputFound = true;
- if (newItemAmounts[i] == null) {
- newItemAmounts[i] = providedItem.stackSize;
- }
-
- if (aDontCheckStackSizes || newItemAmounts[i] >= remainingCost) {
- newItemAmounts[i] -= remainingCost;
- remainingCost = 0;
+ if (providedItem.stackSize >= remainingCost) {
+ providedItem.stackSize -= remainingCost;
break;
} else {
- remainingCost -= newItemAmounts[i];
- newItemAmounts[i] = 0;
+ remainingCost -= providedItem.stackSize;
+ providedItem.stackSize = 0;
}
}
-
- if (remainingCost > 0 || !inputFound) {
- // Cost not satisfied, or for non-consumed inputs, input not found.
- return false;
- }
}
}
}
+ }
- if (aDecreaseStacksizeBySuccess) {
- // Copy modified amounts into the input stacks.
- if (aFluidInputs != null) {
- for (int i = 0; i < aFluidInputs.length; i++) {
- if (newFluidAmounts[i] != null) {
- aFluidInputs[i].amount = newFluidAmounts[i];
- }
- }
+ /**
+ * Returns the number of parallel recipes, or 0 if recipe is not satisfied at all. 0 < number < 1 means that inputs
+ * are found but not enough. Refer to SingleRecipeCheck#checkRecipeInputs.
+ */
+ public double maxParallelCalculatedByInputs(int maxParallel, FluidStack[] aFluidInputs, ItemStack... aInputs) {
+ if (mInputs.length > 0 && aInputs == null) return 0;
+ if (mFluidInputs.length > 0 && aFluidInputs == null) return 0;
+
+ double currentParallel = maxParallel;
+
+ if (aFluidInputs != null) {
+ // Create map for fluid -> stored amount
+ Map<Fluid, Integer> fluidMap = new HashMap<>();
+ Map<Fluid, Integer> fluidCost = new HashMap<>();
+ for (FluidStack fluidStack : aFluidInputs) {
+ if (fluidStack == null) continue;
+ fluidMap.merge(fluidStack.getFluid(), fluidStack.amount, Integer::sum);
+ }
+ for (FluidStack fluidStack : mFluidInputs) {
+ if (fluidStack == null) continue;
+ fluidCost.merge(fluidStack.getFluid(), fluidStack.amount, Integer::sum);
}
- if (aInputs != null) {
- for (int i = 0; i < aInputs.length; i++) {
- if (newItemAmounts[i] != null) {
- aInputs[i].stackSize = newItemAmounts[i];
- }
+ // Check how many parallels can it perform for each fluid
+ for (Map.Entry<Fluid, Integer> costEntry : fluidCost.entrySet()) {
+ if (costEntry.getValue() > 0) {
+ currentParallel = Math.min(
+ currentParallel,
+ (double) fluidMap.getOrDefault(costEntry.getKey(), 0) / costEntry.getValue());
+ }
+ if (currentParallel <= 0) {
+ return 0;
}
}
}
- return true;
+ 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) {
+ if (itemStack == null) continue;
+ itemMap.merge(GT_Utility.ItemId.createNoCopy(itemStack), itemStack.stackSize, Integer::sum);
+ }
+ for (ItemStack itemStack : mInputs) {
+ if (itemStack == null) continue;
+ itemCost.merge(GT_Utility.ItemId.createNoCopy(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());
+ }
+ if (currentParallel <= 0) {
+ return 0;
+ }
+ }
+ }
+ return currentParallel;
}
@Override