aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/ggfab/mte/MTEAdvAssLine.java185
-rw-r--r--src/main/java/ggfab/util/OverclockHelper.java75
-rw-r--r--src/main/java/gregtech/api/util/OverclockCalculator.java1
-rw-r--r--src/main/java/gregtech/common/tileentities/machines/multi/MTEAssemblyLine.java112
-rw-r--r--src/main/java/gregtech/common/tileentities/machines/multi/MTEIntegratedOreFactory.java3
-rw-r--r--src/main/java/gregtech/common/tileentities/machines/multi/MTELargeChemicalReactor.java5
-rw-r--r--src/main/java/gregtech/common/tileentities/machines/multi/MTEMultiFurnace.java6
-rw-r--r--src/main/java/gregtech/common/tileentities/machines/multi/MTEOilCracker.java5
-rw-r--r--src/test/java/gregtech/overclock/GT_OverclockCalculator_UnitTest.java21
-rw-r--r--src/test/java/net/glease/ggfab/util/OverclockHelperTest.java49
10 files changed, 219 insertions, 243 deletions
diff --git a/src/main/java/ggfab/mte/MTEAdvAssLine.java b/src/main/java/ggfab/mte/MTEAdvAssLine.java
index a2fb0d2896..c1fd180b92 100644
--- a/src/main/java/ggfab/mte/MTEAdvAssLine.java
+++ b/src/main/java/ggfab/mte/MTEAdvAssLine.java
@@ -63,10 +63,8 @@ import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget;
import com.gtnewhorizons.modularui.common.widget.SlotWidget;
import com.gtnewhorizons.modularui.common.widget.TextWidget;
-import ggfab.ConfigurationHandler;
import ggfab.GGConstants;
import ggfab.mui.ClickableTextWidget;
-import ggfab.util.OverclockHelper;
import gregtech.api.GregTechAPI;
import gregtech.api.enums.GTValues;
import gregtech.api.enums.ItemList;
@@ -93,6 +91,7 @@ import gregtech.api.util.GTWaila;
import gregtech.api.util.IGTHatchAdder;
import gregtech.api.util.MultiblockTooltipBuilder;
import gregtech.api.util.OverclockCalculator;
+import gregtech.api.util.VoidProtectionHelper;
import gregtech.api.util.shutdown.ShutDownReason;
import gregtech.common.tileentities.machines.MTEHatchInputBusME;
import gregtech.common.tileentities.machines.MTEHatchInputME;
@@ -673,24 +672,30 @@ public class MTEAdvAssLine extends MTEExtendedPowerMultiBlockBase<MTEAdvAssLine>
return tRecipe;
}
- private boolean hasAllItems(GTRecipe.RecipeAssemblyLine tRecipe, int parallel) {
+ private int maxParallelCalculatedByInputItems(GTRecipe.RecipeAssemblyLine tRecipe, int maxParallel) {
int aItemCount = tRecipe.mInputs.length;
- if (mInputBusses.size() < aItemCount) return false;
+ if (mInputBusses.size() < aItemCount) return 0;
int[] itemConsumptions = GTRecipe.RecipeAssemblyLine.getItemConsumptionAmountArray(mInputBusses, tRecipe);
if (itemConsumptions == null || itemConsumptions.length == 0) {
- return false;
+ return 0;
}
- int maxParallel = (int) GTRecipe.RecipeAssemblyLine
- .maxParallelCalculatedByInputItems(mInputBusses, parallel, itemConsumptions, curBatchItemsFromME);
- return maxParallel >= parallel;
+ return (int) GTRecipe.RecipeAssemblyLine
+ .maxParallelCalculatedByInputItems(mInputBusses, maxParallel, itemConsumptions, curBatchItemsFromME);
}
- private boolean hasAllFluids(GTRecipe.RecipeAssemblyLine tRecipe, int parallel) {
+ private int maxParallelCalculatedByInputFluids(GTRecipe.RecipeAssemblyLine tRecipe, int maxParallel) {
int aFluidCount = tRecipe.mFluidInputs.length;
- if (mInputHatches.size() < aFluidCount) return false;
- int maxParallel = (int) GTRecipe.RecipeAssemblyLine
- .maxParallelCalculatedByInputFluids(mInputHatches, parallel, tRecipe.mFluidInputs, curBatchFluidsFromME);
- return maxParallel >= parallel;
+ if (mInputHatches.size() < aFluidCount) return 0;
+ return (int) GTRecipe.RecipeAssemblyLine
+ .maxParallelCalculatedByInputFluids(mInputHatches, maxParallel, tRecipe.mFluidInputs, curBatchFluidsFromME);
+ }
+
+ private boolean hasAllItems(GTRecipe.RecipeAssemblyLine tRecipe, int parallel) {
+ return maxParallelCalculatedByInputItems(tRecipe, parallel) >= parallel;
+ }
+
+ private boolean hasAllFluids(GTRecipe.RecipeAssemblyLine tRecipe, int parallel) {
+ return maxParallelCalculatedByInputFluids(tRecipe, parallel) >= parallel;
}
/**
@@ -747,10 +752,8 @@ public class MTEAdvAssLine extends MTEExtendedPowerMultiBlockBase<MTEAdvAssLine>
GT_FML_LOGGER.info("Stick accepted, " + tDataStickList.size() + " Data Sticks found");
}
- GTRecipe.RecipeAssemblyLine recipe = null;
-
for (ItemStack stack : tDataStickList) {
- recipe = findRecipe(stack);
+ GTRecipe.RecipeAssemblyLine recipe = findRecipe(stack);
if (recipe == null) {
result = CheckRecipeResultRegistry.NO_RECIPE;
continue;
@@ -760,70 +763,98 @@ public class MTEAdvAssLine extends MTEExtendedPowerMultiBlockBase<MTEAdvAssLine>
continue;
}
- setCurrentRecipe(stack, recipe);
- // first overclock normally
- // we use the new oc calculator instead
- // calculateOverclockedNessMulti from super class has a mysterious 5% cable loss thing at the moment
- // of writing
- OverclockCalculator ocCalc = new OverclockCalculator().setRecipeEUt(currentRecipe.mEUt)
- .setDuration(Math.max(recipe.mDuration / recipe.mInputs.length, 1))
- .setEUt(inputVoltage)
- .calculate();
- // since we already checked mEUt <= inputVoltage, no need to check if recipe is too OP
- lEUt = ocCalc.getConsumption();
- mMaxProgresstime = ocCalc.getDuration();
- // then laser overclock if needed
+ int originalMaxParallel = 1;
+ int maxParallel = originalMaxParallel;
+
+ OverclockCalculator calculator;
+
+ OverclockCalculator normalOCCalculator = new OverclockCalculator().setRecipeEUt(recipe.mEUt)
+ .setDurationUnderOneTickSupplier(() -> ((double) (recipe.mDuration) / recipe.mInputs.length))
+ .setParallel(originalMaxParallel)
+ .setEUt(inputVoltage);
+
if (!mExoticEnergyHatches.isEmpty()) {
- OverclockHelper.OverclockOutput laserOverclock = OverclockHelper.laserOverclock(
- lEUt,
- mMaxProgresstime,
- inputEUt / recipe.mInputs.length,
- ConfigurationHandler.INSTANCE.getLaserOCPenaltyFactor());
- if (laserOverclock != null) {
- lEUt = laserOverclock.getEUt();
- mMaxProgresstime = laserOverclock.getDuration();
- }
+ normalOCCalculator.setCurrentParallel((int) (1 / normalOCCalculator.calculateDurationUnderOneTick()))
+ .calculate();
+ int normalOverclockCount = normalOCCalculator.getPerformedOverclocks();
+
+ OverclockCalculator laserOCCalculator = new OverclockCalculator().setRecipeEUt(recipe.mEUt)
+ .setDurationUnderOneTickSupplier(() -> ((double) (recipe.mDuration) / recipe.mInputs.length))
+ .setEutIncreasePerOCSupplier(overclock -> 4 + 0.3 * Math.max(overclock - normalOverclockCount, 0))
+ .setParallel(originalMaxParallel)
+ .setEUt(inputEUt / recipe.mInputs.length);
+
+ calculator = laserOCCalculator;
+ } else {
+ calculator = normalOCCalculator;
}
- // Save this for batch mode parallel calculations
- int timePerSlice = mMaxProgresstime;
- // correct the recipe duration
- mMaxProgresstime *= recipe.mInputs.length;
-
- // Finally apply batch mode parallels if possible.
- // For this we need to verify the first item slot and all fluids slots have enough resources
- // to execute parallels.
- // Note that we skip this entirely if the time for each slice is more than
- // BATCH_MODE_DESIRED_TICKS_PER_SLICE ticks, since in this case the amount of batches will always be 1
- if (super.isBatchModeEnabled() && timePerSlice < BATCH_MODE_DESIRED_TICKS_PER_SLICE) {
- // Calculate parallel based on time per slice, and the amount of fluid in the first fluid slot.
- // We use fluid, since this way players can limit parallel by controlling how much fluid
- // ends up in each AAL. This way, batch mode will not slow down setups where multiple AAL
- // are connected to the same set of input items. Note that this will still suffer from the same
- // issue if using stocking hatch, but in this case increasing pattern size can help.
-
- // Note that every assline recipe has a fluid ingredient.
- FluidStack firstFluidSlot = getInputHatchContent(0);
- if (firstFluidSlot == null) {
- result = CheckRecipeResultRegistry.INTERNAL_ERROR;
- break;
+
+ // Disabled to disable overclocking under one tick.
+ /*
+ * double tickTimeAfterOC = calculator.calculateDurationUnderOneTick();
+ * if (tickTimeAfterOC < 1) {
+ * maxParallel = GTUtility.safeInt((long) (maxParallel / tickTimeAfterOC), 0);
+ * }
+ */
+
+ int maxParallelBeforeBatchMode = maxParallel;
+ if (isBatchModeEnabled()) {
+ maxParallel = GTUtility.safeInt((long) maxParallel * getMaxBatchSize(), 0);
+ }
+
+ if (protectsExcessItem()) {
+ VoidProtectionHelper voidProtectionHelper = new VoidProtectionHelper();
+ voidProtectionHelper.setMachine(this)
+ .setItemOutputs(new ItemStack[] { recipe.mOutput })
+ .setMaxParallel(maxParallel)
+ .build();
+ maxParallel = Math.min(voidProtectionHelper.getMaxParallel(), maxParallel);
+ if (voidProtectionHelper.isItemFull()) {
+ result = CheckRecipeResultRegistry.ITEM_OUTPUT_FULL;
+ continue;
}
- int recipesAvailable = Math.floorDiv(firstFluidSlot.amount, recipe.mFluidInputs[0].amount);
+ }
+
+ FluidStack firstFluidSlot = getInputHatchContent(0);
+ if (firstFluidSlot == null) {
+ result = CheckRecipeResultRegistry.INTERNAL_ERROR;
+ break;
+ }
+
+ int currentParallel = firstFluidSlot.amount / recipe.mFluidInputs[0].amount;
+ if (isBatchModeEnabled()) {
// Divide recipes available by the amount of slices in the recipe. This will prevent the AAL from
// batching instead of parallelizing, which would make it effectively slower.
- recipesAvailable = Math.floorDiv(recipesAvailable, recipe.mInputs.length);
- // Sanity check to avoid this being zero when there is only one recipe available.
- recipesAvailable = Math.max(recipesAvailable, 1);
- int desiredBatches = Math.floorDiv(BATCH_MODE_DESIRED_TICKS_PER_SLICE, timePerSlice);
- // Limit the amount of parallel to both the amount of recipes available and the maximum number
- // of batches we want to run. The latter is done to prevent batch mode from ever going above
- // BATCH_MODE_DESIRED_TICKS_PER_SLICE ticks per slice (see also where it is defined above).
- int parallel = Math.min(recipesAvailable, desiredBatches);
- if (hasAllFluids(recipe, parallel) && hasAllItems(recipe, parallel)) {
- this.currentRecipeParallel = parallel;
- // Update recipe duration with final batch mode multiplier
- mMaxProgresstime *= this.currentRecipeParallel;
- }
+ currentParallel /= recipe.mInputs.length;
}
+ currentParallel = Math.min(currentParallel, maxParallel);
+ // Sanity check to avoid this being zero when there is only one recipe available.
+ currentParallel = Math.max(currentParallel, 1);
+
+ currentParallel = Math.min(currentParallel, maxParallelCalculatedByInputItems(recipe, currentParallel));
+ currentParallel = Math.min(currentParallel, maxParallelCalculatedByInputFluids(recipe, currentParallel));
+
+ if (currentParallel <= 0) {
+ result = CheckRecipeResultRegistry.INTERNAL_ERROR;
+ continue;
+ }
+
+ int currentParallelBeforeBatchMode = Math.min(currentParallel, maxParallelBeforeBatchMode);
+
+ calculator.setCurrentParallel(currentParallelBeforeBatchMode)
+ .calculate();
+
+ double batchMultiplierMax = 1;
+ // In case batch mode enabled
+ if (currentParallel > maxParallelBeforeBatchMode && calculator.getDuration() < getMaxBatchSize()) {
+ batchMultiplierMax = (double) getMaxBatchSize() / calculator.getDuration();
+ batchMultiplierMax = Math
+ .min(batchMultiplierMax, (double) currentParallel / maxParallelBeforeBatchMode);
+ }
+ currentRecipeParallel = (int) (currentParallelBeforeBatchMode * batchMultiplierMax);
+ lEUt = calculator.getConsumption();
+ mMaxProgresstime = (int) (calculator.getDuration() * batchMultiplierMax) * recipe.mInputs.length;
+ setCurrentRecipe(stack, recipe);
result = CheckRecipeResultRegistry.SUCCESSFUL;
break;
}
@@ -831,7 +862,7 @@ public class MTEAdvAssLine extends MTEExtendedPowerMultiBlockBase<MTEAdvAssLine>
clearCurrentRecipe();
return result;
}
- if (recipe == null || !slices[0].start() || currentRecipeParallel <= 0) {
+ if (currentRecipe == null || !slices[0].start() || currentRecipeParallel <= 0) {
clearCurrentRecipe();
// something very very wrong...
return CheckRecipeResultRegistry.INTERNAL_ERROR;
@@ -840,10 +871,10 @@ public class MTEAdvAssLine extends MTEExtendedPowerMultiBlockBase<MTEAdvAssLine>
if (GTValues.D1) {
GT_FML_LOGGER.info("All checked start consuming inputs");
}
- drainAllFluids(recipe, this.currentRecipeParallel);
+ drainAllFluids(currentRecipe, this.currentRecipeParallel);
// Apply parallel
- mOutputItems = new ItemStack[] { recipe.mOutput.copy() };
+ mOutputItems = new ItemStack[] { currentRecipe.mOutput.copy() };
mOutputItems[0].stackSize *= this.currentRecipeParallel;
if (this.lEUt > 0) {
diff --git a/src/main/java/ggfab/util/OverclockHelper.java b/src/main/java/ggfab/util/OverclockHelper.java
deleted file mode 100644
index b0e42930e8..0000000000
--- a/src/main/java/ggfab/util/OverclockHelper.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package ggfab.util;
-
-import gregtech.api.util.GTUtility;
-
-public class OverclockHelper {
-
- public static OverclockOutput normalOverclock(long recipeEUt, int duration, long inputVoltage, boolean perfectOC) {
- if (recipeEUt > inputVoltage) return null;
- int recipeTier = Math.max(1, GTUtility.getTier(recipeEUt)); // ULV no overclock
- int machineTier = GTUtility.getTier(inputVoltage);
- int shift = perfectOC ? 2 : 1;
- while (recipeTier < machineTier && duration > 1) {
- duration >>= shift;
- recipeEUt <<= 2;
- recipeTier++;
- }
- return new OverclockOutput(recipeEUt, duration);
- }
-
- public static OverclockOutput laserOverclock(long recipeEUt, int duration, long inputEUt,
- float penaltyIncreaseFactor) {
- if (recipeEUt > inputEUt) return null;
- float currentPenalty = 4 + penaltyIncreaseFactor;
- // 2/(n+k) overclock until energy hatch is crying
- // must ensure it doesn't go to negative after overclock
- while (recipeEUt * currentPenalty > 0 && recipeEUt * currentPenalty < inputEUt && duration > 1) {
- duration >>= 1;
- recipeEUt *= currentPenalty;
- currentPenalty += penaltyIncreaseFactor;
- }
- return new OverclockOutput(recipeEUt, duration);
- }
-
- public static final class OverclockOutput {
-
- private final long mEUt;
- private final int mDuration;
-
- public OverclockOutput(long aEUt, int aDuration) {
- this.mEUt = aEUt;
- this.mDuration = aDuration;
- }
-
- public long getEUt() {
- return mEUt;
- }
-
- public int getDuration() {
- return mDuration;
- }
-
- @Override
- public String toString() {
- return mEUt + "@" + mDuration + "ticks";
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof OverclockOutput)) return false;
-
- OverclockOutput that = (OverclockOutput) o;
-
- if (mEUt != that.mEUt) return false;
- return mDuration == that.mDuration;
- }
-
- @Override
- public int hashCode() {
- int result = (int) (mEUt ^ (mEUt >>> 32));
- result = 31 * result + mDuration;
- return result;
- }
- }
-}
diff --git a/src/main/java/gregtech/api/util/OverclockCalculator.java b/src/main/java/gregtech/api/util/OverclockCalculator.java
index 55ac79f730..bd3b14bcc0 100644
--- a/src/main/java/gregtech/api/util/OverclockCalculator.java
+++ b/src/main/java/gregtech/api/util/OverclockCalculator.java
@@ -436,6 +436,7 @@ public class OverclockCalculator {
while (machinePower > currentConsumption * currentEutIncrease
&& requiredUnderOneTickMultiplier > currentUnderOneTickMultiplier
&& (!limitOverclocks || overclockCount < maxOverclocks)) {
+ currentUnderOneTickMultiplier *= currentDurationDecrease;
currentConsumption *= currentEutIncrease;
durationInDouble /= currentDurationDecrease;
overclockCount++;
diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/MTEAssemblyLine.java b/src/main/java/gregtech/common/tileentities/machines/multi/MTEAssemblyLine.java
index 31456825ba..33e75b7e00 100644
--- a/src/main/java/gregtech/common/tileentities/machines/multi/MTEAssemblyLine.java
+++ b/src/main/java/gregtech/common/tileentities/machines/multi/MTEAssemblyLine.java
@@ -60,6 +60,8 @@ import gregtech.api.util.GTRecipe.RecipeAssemblyLine;
import gregtech.api.util.GTUtility;
import gregtech.api.util.IGTHatchAdder;
import gregtech.api.util.MultiblockTooltipBuilder;
+import gregtech.api.util.OverclockCalculator;
+import gregtech.api.util.VoidProtectionHelper;
public class MTEAssemblyLine extends MTEExtendedPowerMultiBlockBase<MTEAssemblyLine> implements ISurvivalConstructable {
@@ -210,8 +212,8 @@ public class MTEAssemblyLine extends MTEExtendedPowerMultiBlockBase<MTEAssemblyL
int[] tStacks = new int[0];
FluidStack[] tFluids = new FluidStack[0];
long averageVoltage = getAverageInputVoltage();
- long maxAmp = mEnergyHatches.size() <= 1 ? 1 : getMaxInputAmps();
int maxParallel = 1;
+ long maxAmp = getMaxInputAmps();
Map<GTUtility.ItemId, ItemStack> inputsFromME = getStoredInputsFromME();
Map<Fluid, FluidStack> fluidsFromME = getStoredFluidsFromME();
@@ -235,16 +237,21 @@ public class MTEAssemblyLine extends MTEExtendedPowerMultiBlockBase<MTEAssemblyL
}
}
- // Void protection check.
- if (!canOutputAll(new ItemStack[] { tRecipe.mOutput })) {
- result = CheckRecipeResultRegistry.ITEM_OUTPUT_FULL;
+ // Recipe tier is limited to hatch tier + 1.
+ if (tRecipe.mEUt > averageVoltage * 4) {
+ result = CheckRecipeResultRegistry.insufficientPower(tRecipe.mEUt);
+ continue;
+ }
+
+ // Insufficient power check.
+ if (tRecipe.mEUt > maxAmp * averageVoltage) {
+ result = CheckRecipeResultRegistry.insufficientPower(tRecipe.mEUt);
continue;
}
// So here we check against the recipe found on the data stick.
// If we run into missing buses/hatches or bad inputs, we go to the next data stick.
// This check only happens if we have a valid up-to-date data stick.
-
// first validate we have enough input busses and input hatches for this recipe
if (mInputBusses.size() < tRecipe.mInputs.length || mInputHatches.size() < tRecipe.mFluidInputs.length) {
if (GTValues.D1) {
@@ -259,15 +266,48 @@ public class MTEAssemblyLine extends MTEExtendedPowerMultiBlockBase<MTEAssemblyL
continue;
}
+ int originalMaxParallel = 1;
+ maxParallel = originalMaxParallel;
+ OverclockCalculator calculator = new OverclockCalculator().setRecipeEUt(tRecipe.mEUt)
+ .setEUt(averageVoltage)
+ .setAmperage(maxAmp)
+ .setAmperageOC(mEnergyHatches.size() != 1)
+ .setDuration(tRecipe.mDuration)
+ .setParallel(originalMaxParallel);
+
+ double tickTimeAfterOC = calculator.calculateDurationUnderOneTick();
+ if (tickTimeAfterOC < 1) {
+ maxParallel = GTUtility.safeInt((long) (maxParallel / tickTimeAfterOC), 0);
+ }
+
+ int maxParallelBeforeBatchMode = maxParallel;
+ if (isBatchModeEnabled()) {
+ maxParallel = GTUtility.safeInt((long) maxParallel * getMaxBatchSize(), 0);
+ }
+
+ if (protectsExcessItem()) {
+ VoidProtectionHelper voidProtectionHelper = new VoidProtectionHelper();
+ voidProtectionHelper.setMachine(this)
+ .setItemOutputs(new ItemStack[] { tRecipe.mOutput })
+ .setMaxParallel(maxParallel)
+ .build();
+ maxParallel = Math.min(voidProtectionHelper.getMaxParallel(), maxParallel);
+ if (voidProtectionHelper.isItemFull()) {
+ result = CheckRecipeResultRegistry.ITEM_OUTPUT_FULL;
+ continue;
+ }
+ }
+
+ int currentParallel = maxParallel;
// Check Inputs allign
int[] itemConsumptions = GTRecipe.RecipeAssemblyLine.getItemConsumptionAmountArray(mInputBusses, tRecipe);
if (itemConsumptions == null || itemConsumptions.length == 0) {
result = CheckRecipeResultRegistry.NO_RECIPE;
continue;
}
- maxParallel = (int) GTRecipe.RecipeAssemblyLine
- .maxParallelCalculatedByInputItems(mInputBusses, maxParallel, itemConsumptions, inputsFromME);
- if (maxParallel <= 0) {
+ currentParallel = (int) GTRecipe.RecipeAssemblyLine
+ .maxParallelCalculatedByInputItems(mInputBusses, currentParallel, itemConsumptions, inputsFromME);
+ if (currentParallel <= 0) {
result = CheckRecipeResultRegistry.NO_RECIPE;
continue;
}
@@ -279,9 +319,12 @@ public class MTEAssemblyLine extends MTEExtendedPowerMultiBlockBase<MTEAssemblyL
// Check Fluid Inputs allign
if (tRecipe.mFluidInputs.length > 0) {
- maxParallel = (int) RecipeAssemblyLine
- .maxParallelCalculatedByInputFluids(mInputHatches, maxParallel, tRecipe.mFluidInputs, fluidsFromME);
- if (maxParallel <= 0) {
+ currentParallel = (int) RecipeAssemblyLine.maxParallelCalculatedByInputFluids(
+ mInputHatches,
+ currentParallel,
+ tRecipe.mFluidInputs,
+ fluidsFromME);
+ if (currentParallel <= 0) {
result = CheckRecipeResultRegistry.NO_RECIPE;
continue;
}
@@ -296,41 +339,29 @@ public class MTEAssemblyLine extends MTEExtendedPowerMultiBlockBase<MTEAssemblyL
GT_FML_LOGGER.info("Check overclock");
}
- // Recipe tier is limited to hatch tier + 1.
- if (tRecipe.mEUt > averageVoltage * 4) {
- result = CheckRecipeResultRegistry.insufficientPower(tRecipe.mEUt);
- continue;
- }
-
- // Insufficient power check.
- if (tRecipe.mEUt > maxAmp * averageVoltage) {
- result = CheckRecipeResultRegistry.insufficientPower(tRecipe.mEUt);
- continue;
- }
+ int currentParallelBeforeBatchMode = Math.min(currentParallel, maxParallelBeforeBatchMode);
- calculateOverclockedNessMultiInternal(tRecipe.mEUt, tRecipe.mDuration, (int) maxAmp, averageVoltage, false);
- // In case recipe is too OP for that machine
- if (lEUt == Long.MAX_VALUE) {
- if (GTValues.D1) {
- GT_FML_LOGGER.info("Recipe too OP");
- }
- result = CheckRecipeResultRegistry.POWER_OVERFLOW;
- continue;
- }
+ calculator.setCurrentParallel(currentParallelBeforeBatchMode)
+ .calculate();
- if (mMaxProgresstime == Integer.MAX_VALUE) {
- if (GTValues.D1) {
- GT_FML_LOGGER.info("Recipe too OP");
- }
- result = CheckRecipeResultRegistry.DURATION_OVERFLOW;
- continue;
+ double batchMultiplierMax = 1;
+ // In case batch mode enabled
+ if (currentParallel > maxParallelBeforeBatchMode && calculator.getDuration() < getMaxBatchSize()) {
+ batchMultiplierMax = (double) getMaxBatchSize() / calculator.getDuration();
+ batchMultiplierMax = Math
+ .min(batchMultiplierMax, (double) currentParallel / maxParallelBeforeBatchMode);
}
+ int finalParallel = (int) (batchMultiplierMax * maxParallelBeforeBatchMode);
+ lEUt = calculator.getConsumption();
+ mMaxProgresstime = (int) (calculator.getDuration() * batchMultiplierMax);
+ maxParallel = finalParallel;
if (GTValues.D1) {
GT_FML_LOGGER.info("Find available recipe");
}
result = CheckRecipeResultRegistry.SUCCESSFUL;
- mOutputItems = new ItemStack[] { tRecipe.mOutput };
+ mOutputItems = new ItemStack[] { tRecipe.mOutput.copy() };
+ mOutputItems[0].stackSize *= maxParallelBeforeBatchMode * batchMultiplierMax;
break;
}
@@ -472,6 +503,11 @@ public class MTEAssemblyLine extends MTEExtendedPowerMultiBlockBase<MTEAssemblyL
return VoidingMode.ITEM_ONLY_MODES;
}
+ @Override
+ public boolean supportsBatchMode() {
+ return true;
+ }
+
private enum DataHatchElement implements IHatchElement<MTEAssemblyLine> {
DataAccess;
diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/MTEIntegratedOreFactory.java b/src/main/java/gregtech/common/tileentities/machines/multi/MTEIntegratedOreFactory.java
index 25a54021fa..7de3fb8dbe 100644
--- a/src/main/java/gregtech/common/tileentities/machines/multi/MTEIntegratedOreFactory.java
+++ b/src/main/java/gregtech/common/tileentities/machines/multi/MTEIntegratedOreFactory.java
@@ -322,6 +322,9 @@ public class MTEIntegratedOreFactory extends MTEExtendedPowerMultiBlockBase<MTEI
}
}
currentParallel = itemParallel;
+ if (currentParallel <= 0) {
+ return CheckRecipeResultRegistry.NO_RECIPE;
+ }
int currentParallelBeforeBatchMode = Math.min(currentParallel, maxParallelBeforeBatchMode);
calculator.setCurrentParallel(currentParallelBeforeBatchMode)
diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/MTELargeChemicalReactor.java b/src/main/java/gregtech/common/tileentities/machines/multi/MTELargeChemicalReactor.java
index a7e94c9ea5..7279bf1107 100644
--- a/src/main/java/gregtech/common/tileentities/machines/multi/MTELargeChemicalReactor.java
+++ b/src/main/java/gregtech/common/tileentities/machines/multi/MTELargeChemicalReactor.java
@@ -288,4 +288,9 @@ public class MTELargeChemicalReactor extends MTEEnhancedMultiBlockBase<MTELargeC
return ret;
}
}
+
+ @Override
+ public boolean supportsBatchMode() {
+ return true;
+ }
}
diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/MTEMultiFurnace.java b/src/main/java/gregtech/common/tileentities/machines/multi/MTEMultiFurnace.java
index a11ef41dbd..6c4bb1d734 100644
--- a/src/main/java/gregtech/common/tileentities/machines/multi/MTEMultiFurnace.java
+++ b/src/main/java/gregtech/common/tileentities/machines/multi/MTEMultiFurnace.java
@@ -152,12 +152,12 @@ public class MTEMultiFurnace extends MTEAbstractMultiFurnace<MTEMultiFurnace> im
ArrayList<ItemStack> tInputList = getAllStoredInputs();
if (tInputList.isEmpty()) return CheckRecipeResultRegistry.NO_RECIPE;
- long inputVoltage = getMaxInputVoltage();
-
int fakeOriginalMaxParallel = 1;
- OverclockCalculator calculator = new OverclockCalculator().setEUt(inputVoltage)
+ OverclockCalculator calculator = new OverclockCalculator().setEUt(getAverageInputVoltage())
+ .setAmperage(getMaxInputAmps())
.setRecipeEUt(RECIPE_EUT)
.setDuration(RECIPE_DURATION)
+ .setAmperageOC(mEnergyHatches.size() != 1)
.setParallel(fakeOriginalMaxParallel);
int maxParallel = this.mLevel;
diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/MTEOilCracker.java b/src/main/java/gregtech/common/tileentities/machines/multi/MTEOilCracker.java
index 2aac2b5a2e..71c00cc9aa 100644
--- a/src/main/java/gregtech/common/tileentities/machines/multi/MTEOilCracker.java
+++ b/src/main/java/gregtech/common/tileentities/machines/multi/MTEOilCracker.java
@@ -392,6 +392,11 @@ public class MTEOilCracker extends MTEEnhancedMultiBlockBase<MTEOilCracker> impl
}
@Override
+ public boolean supportsBatchMode() {
+ return true;
+ }
+
+ @Override
protected void startRecipeProcessing() {
for (MTEHatchInput hatch : filterValidMTEs(mMiddleInputHatches)) {
if (hatch instanceof IRecipeProcessingAwareHatch aware) {
diff --git a/src/test/java/gregtech/overclock/GT_OverclockCalculator_UnitTest.java b/src/test/java/gregtech/overclock/GT_OverclockCalculator_UnitTest.java
index d6bbea4308..eb858de667 100644
--- a/src/test/java/gregtech/overclock/GT_OverclockCalculator_UnitTest.java
+++ b/src/test/java/gregtech/overclock/GT_OverclockCalculator_UnitTest.java
@@ -649,13 +649,32 @@ class GT_OverclockCalculator_UnitTest {
assertEquals(Math.pow(2, 10) / 64, (int) (1 / calculator.calculateDurationUnderOneTick()));
- calculator.calculate();
+ calculator.setCurrentParallel((int) (1 / calculator.calculateDurationUnderOneTick()))
+ .calculate();
assertEquals(5 + 5, calculator.getPerformedOverclocks());
assertEquals((int) (VP[1] * Math.pow(4, 5) * 4.3 * 4.6 * 4.9 * 5.2 * 5.5), calculator.getConsumption());
}
@Test
+ void stopsCorrectlyWhenOneTickingWithCustomEutIncreasePerOCSupplier() {
+ Function<Integer, Double> laserOC = overclockCount -> overclockCount <= 5 ? 4
+ : (4 + 0.3 * (overclockCount - 5));
+ OverclockCalculator calculator = new OverclockCalculator().setRecipeEUt(VP[1])
+ .setEUt(V[6])
+ .setAmperageOC(true)
+ .setAmperage(4000)
+ .setDuration(64)
+ .setEutIncreasePerOCSupplier(laserOC);
+
+ calculator.setCurrentParallel(1)
+ .calculate();
+
+ assertEquals(6, calculator.getPerformedOverclocks());
+ assertEquals((int) (VP[1] * Math.pow(4, 5) * 4.3), calculator.getConsumption());
+ }
+
+ @Test
void slightlyOverOneAmpRecipeWorksWithSingleEnergyHatch() {
OverclockCalculator calculator = new OverclockCalculator().setRecipeEUt(614400)
.setEUt(TierEU.UV)
diff --git a/src/test/java/net/glease/ggfab/util/OverclockHelperTest.java b/src/test/java/net/glease/ggfab/util/OverclockHelperTest.java
deleted file mode 100644
index 6e078fd002..0000000000
--- a/src/test/java/net/glease/ggfab/util/OverclockHelperTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package net.glease.ggfab.util;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
-
-import org.junit.jupiter.api.Test;
-
-import ggfab.util.OverclockHelper;
-
-class OverclockHelperTest {
-
- @Test
- void normalOverclockImperfect() {
- // fails recipe
- assertNull(OverclockHelper.normalOverclock(10000, 10000, 1, false));
- // no overclock
- assertEquals(new OverclockHelper.OverclockOutput(30, 64), OverclockHelper.normalOverclock(30, 64, 32, false));
- // imperfect overclock
- assertEquals(new OverclockHelper.OverclockOutput(120, 32), OverclockHelper.normalOverclock(30, 64, 128, false));
- // lots of overclock
- assertEquals(
- new OverclockHelper.OverclockOutput(30720, 2),
- OverclockHelper.normalOverclock(30, 64, 32768, false));
- // do not overclock beyond useful
- assertEquals(
- new OverclockHelper.OverclockOutput(122880, 1),
- OverclockHelper.normalOverclock(30, 64, 524288, false));
- }
-
- @Test
- void laserOverclock() {
- // fails recipe
- assertNull(OverclockHelper.laserOverclock(10000, 10000, 1, 5));
- // no overclock
- assertEquals(new OverclockHelper.OverclockOutput(30, 64), OverclockHelper.laserOverclock(30, 64, 32, 0.5f));
- // 0.3 amp overclock. 0.25 amp would be not in current tier so no point in testing that
- assertEquals(new OverclockHelper.OverclockOutput(10, 64), OverclockHelper.laserOverclock(10, 64, 32, 0.5f));
- // laser overclock
- assertEquals(
- new OverclockHelper.OverclockOutput(135, 32),
- OverclockHelper.laserOverclock(30, 64, 32 * 16, 0.5f));
- // lots of overclock
- assertEquals(
- new OverclockHelper.OverclockOutput(22272, 4),
- OverclockHelper.laserOverclock(30, 64, 32 * 1024, 0.5f));
- // do not overclock beyond useful
- assertEquals(new OverclockHelper.OverclockOutput(135, 1), OverclockHelper.laserOverclock(30, 2, 32 * 16, 0.5f));
- }
-}