aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/gregtech/api/util/GT_OverclockCalculator.java455
-rw-r--r--src/main/java/gregtech/api/util/GT_ParallelHelper.java10
-rw-r--r--src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_IntegratedOreFactory.java12
-rw-r--r--src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_MultiFurnace.java34
-rw-r--r--src/test/java/gregtech/overclock/GT_OverclockCalculator_UnitTest.java166
5 files changed, 370 insertions, 307 deletions
diff --git a/src/main/java/gregtech/api/util/GT_OverclockCalculator.java b/src/main/java/gregtech/api/util/GT_OverclockCalculator.java
index 91cdf865ad..5dda0b5c01 100644
--- a/src/main/java/gregtech/api/util/GT_OverclockCalculator.java
+++ b/src/main/java/gregtech/api/util/GT_OverclockCalculator.java
@@ -1,23 +1,18 @@
package gregtech.api.util;
+import java.util.function.Function;
import java.util.function.Supplier;
import javax.annotation.Nonnull;
-import gregtech.api.enums.GT_Values;
-
public class GT_OverclockCalculator {
- private static final double LOG2 = Math.log(2);
-
+ // region variables
+ // region basic properties
/**
- * Voltage the recipe will run at
+ * EUt the recipe originally runs at
*/
- private long recipeVoltage = 0;
- /*
- * The amount of amps the recipe needs
- */
- private long recipeAmperage = 1;
+ private long recipeEUt = 0;
/**
* Voltage of the machine
*/
@@ -31,35 +26,15 @@ public class GT_OverclockCalculator {
*/
private int duration = 0;
/**
- * The parallel the machine has when trying to overclock
- */
- private int parallel = 1;
-
- /**
- * The min heat required for the recipe
- */
- private int recipeHeat = 0;
- /**
- * The heat the machine has when starting the recipe
- */
- private int machineHeat = 0;
- /**
- * How much the duration should be divided by for each 1800K above recipe heat
- */
- private double durationDecreasePerHeatOC = 4;
- /**
- * Whether to enable overclocking with heat like the EBF every 1800 heat difference
+ * A supplier used for machines which have a custom way of calculating base duration, like Neutron Activator
*/
- private boolean heatOC;
- /**
- * Whether to enable heat discounts every 900 heat difference
- */
- private boolean heatDiscount;
+ private Supplier<Double> durationUnderOneTickSupplier;
/**
- * The value used for discount final eut per 900 heat
+ * The parallel the machine has when trying to overclock
*/
- private double heatDiscountExponent = 0.95;
-
+ private int parallel = 1;
+ // endregion
+ // region extra factors
/**
* Discount for EUt at the beginning of calculating overclocks, like GT++ machines
*/
@@ -68,29 +43,36 @@ public class GT_OverclockCalculator {
* Speeding/Slowing up/down the duration of a recipe at the beginning of calculating overclocks, like GT++ machines
*/
private double speedBoost = 1;
-
+ // endregion
+ // region overclock parameters
/**
* How much the energy would be multiplied by per overclock available
*/
private double eutIncreasePerOC = 4;
/**
+ * A supplier used for machines which have a custom way of calculating energy increase multipliers for every
+ * overclock, like Advanced Assembling Line
+ */
+ private Function<Integer, Double> eutIncreasePerOCSupplier = getDefaultEutIncreasePerOCSupplier();
+ /**
* How much the duration would be divided by per overclock made that isn't an overclock from HEAT
*/
private double durationDecreasePerOC = 2;
/**
- * Whether to give EUt Discount when the duration goes below one tick
+ * A supplier used for machines which have a custom way of calculating duration decrease multipliers for every
+ * overclock
*/
- private boolean oneTickDiscount;
+ private Function<Integer, Double> durationDecreasePerOCSupplier = getDefaultDurationDecreasePerOCSupplier();
/**
- * Whether the multi should use amperage to overclock with an exponent. Incompatible with amperageOC
+ * Whether at least one of {@link #eutIncreasePerOCSupplier} and {@link #durationDecreasePerOCSupplier} has been set
*/
- private boolean laserOC;
+ private boolean hasAtLeastOneSupplierBeenSet;
/**
- * Laser OC's penalty for using high amp lasers for overclocking. Like what the Adv. Assline is doing
+ * Whether to give EUt Discount when the duration goes below one tick
*/
- private double laserOCPenalty = 0.3;
+ private boolean oneTickDiscount;
/**
- * Whether the multi should use amperage to overclock normally. Incompatible with laserOC
+ * Whether the multi should use amperage to overclock normally.
*/
private boolean amperageOC;
/**
@@ -106,24 +88,60 @@ public class GT_OverclockCalculator {
*/
private int overclockCount;
/**
- * How many overclocks were performed with heat out of the overclocks we had
+ * Should we actually try to calculate overclocking
*/
- private int heatOverclockCount;
+ private boolean noOverclock;
/**
- * A supplier, which is used for machines which have a custom way of calculating duration, like Neutron Activator
+ * The parallel the machine actually used.
*/
- private Supplier<Double> durationUnderOneTickSupplier;
+ private int currentParallel;
+ // endregion
+ // region heat overclock
/**
- * Should we actually try to calculate overclocking
+ * The min heat required for the recipe
*/
- private boolean noOverclock;
+ private int recipeHeat = 0;
+ /**
+ * The heat the machine has when starting the recipe
+ */
+ private int machineHeat = 0;
+ /**
+ * How much the duration should be divided by for each 1800K above recipe heat
+ */
+ private double durationDecreasePerHeatOC = 4;
+ /**
+ * Whether to enable overclocking with heat like the EBF every 1800 heat difference
+ */
+ private boolean heatOC;
+ /**
+ * Whether to enable heat discounts every 900 heat difference
+ */
+ private boolean heatDiscount;
+ /**
+ * The value used for discount final eut per 900 heat
+ */
+ private double heatDiscountExponent = 0.95;
+ // endregion
+ // region result
/**
* variable to check whether the overclocks have been calculated
*/
private boolean calculated;
-
+ /**
+ * The calculated duration result.
+ */
+ private int calculatedDuration;
+ /**
+ * The calculated energy consumption result.
+ */
+ private long calculatedConsumption;
+ // endregion
+ // region constants
private static final int HEAT_DISCOUNT_THRESHOLD = 900;
private static final int HEAT_PERFECT_OVERCLOCK_THRESHOLD = 1800;
+ private static final double LOG2 = Math.log(2);
+ // endregion
+ // endregion
/**
* Creates calculator that doesn't do OC at all. Will use recipe duration.
@@ -147,12 +165,13 @@ public class GT_OverclockCalculator {
*/
public GT_OverclockCalculator() {}
+ // region setters
/**
* @param recipeEUt Sets the Recipe's starting voltage
*/
@Nonnull
public GT_OverclockCalculator setRecipeEUt(long recipeEUt) {
- this.recipeVoltage = recipeEUt;
+ this.recipeEUt = recipeEUt;
return this;
}
@@ -184,15 +203,6 @@ public class GT_OverclockCalculator {
}
/**
- * @param recipeAmperage Sets the Amperage of the recipe
- */
- @Nonnull
- public GT_OverclockCalculator setRecipeAmperage(long recipeAmperage) {
- this.recipeAmperage = recipeAmperage;
- return this;
- }
-
- /**
* Enables Perfect OC in calculation
*/
@Nonnull
@@ -275,16 +285,6 @@ public class GT_OverclockCalculator {
}
/**
- * @deprecated Deprecated in favor of {@link #setHeatPerfectOC(double)}. Calls {@link #setHeatPerfectOC(double)}
- * where the given value is 2^heatPerfectOC
- */
- @Deprecated
- @Nonnull
- public GT_OverclockCalculator setHeatPerfectOC(int heatPerfectOC) {
- return setHeatPerfectOC(Math.pow(2, heatPerfectOC));
- }
-
- /**
* Sets the Overclock that should be calculated when a heat OC is applied.
*/
@Nonnull
@@ -339,23 +339,11 @@ public class GT_OverclockCalculator {
}
@Nonnull
- public GT_OverclockCalculator setLaserOC(boolean laserOC) {
- this.laserOC = laserOC;
- return this;
- }
-
- @Nonnull
public GT_OverclockCalculator setAmperageOC(boolean amperageOC) {
this.amperageOC = amperageOC;
return this;
}
- @Nonnull
- public GT_OverclockCalculator setLaserOCPenalty(double laserOCPenalty) {
- this.laserOCPenalty = laserOCPenalty;
- return this;
- }
-
/**
* Set a supplier for calculating custom duration for when its needed under one tick
*/
@@ -375,6 +363,37 @@ public class GT_OverclockCalculator {
}
/**
+ * Set a supplier for calculating custom EUt increase multipliers for every overclock
+ */
+ public GT_OverclockCalculator setEutIncreasePerOCSupplier(Function<Integer, Double> eutIncreasePerOCSupplier) {
+ this.eutIncreasePerOCSupplier = eutIncreasePerOCSupplier;
+ this.hasAtLeastOneSupplierBeenSet = true;
+ return this;
+ }
+
+ /**
+ * Set a supplier for calculating custom duration decrease multipliers for every overclock
+ */
+ public GT_OverclockCalculator setDurationDecreasePerOCSupplier(
+ Function<Integer, Double> durationDecreasePerOCSupplier) {
+ this.durationDecreasePerOCSupplier = durationDecreasePerOCSupplier;
+ this.hasAtLeastOneSupplierBeenSet = true;
+ return this;
+ }
+
+ /**
+ * Set actually performed parallel
+ */
+ public GT_OverclockCalculator setCurrentParallel(int currentParallel) {
+ this.currentParallel = currentParallel;
+ // Sets parallel to the actually performed one if machine's parallel is underused.
+ this.parallel = Math.min(parallel, currentParallel);
+ return this;
+ }
+
+ // endregion
+ // region calculate
+ /**
* Call this when all values have been put it.
*/
@Nonnull
@@ -388,68 +407,93 @@ public class GT_OverclockCalculator {
}
private void calculateOverclock() {
- duration = (int) Math.ceil(duration * speedBoost);
- if (noOverclock) {
- recipeVoltage = calculateFinalRecipeEUt(calculateHeatDiscountMultiplier());
- return;
- }
- if (laserOC && amperageOC) {
- throw new IllegalStateException("Tried to calculate overclock with both laser and amperage overclocking");
- }
+ double durationInDouble = durationUnderOneTickSupplier != null ? durationUnderOneTickSupplier.get()
+ : duration * speedBoost;
+ calculatedConsumption = recipeEUt;
double heatDiscountMultiplier = calculateHeatDiscountMultiplier();
- if (heatOC) {
- heatOverclockCount = calculateAmountOfHeatOverclocks();
- }
-
- double recipePowerTier = calculateRecipePowerTier(heatDiscountMultiplier);
- double machinePowerTier = calculateMachinePowerTier();
+ // Usually a safeguard when currentParallel is not set: We assume parallel is fully used.
+ currentParallel = Math.max(currentParallel, parallel);
- overclockCount = calculateAmountOfNeededOverclocks(machinePowerTier, recipePowerTier);
- if (!amperageOC) {
- overclockCount = Math.min(overclockCount, calculateRecipeToMachineVoltageDifference());
+ if (noOverclock) {
+ calculatedConsumption = calculateFinalRecipeEUt(heatDiscountMultiplier);
+ calculatedDuration = (int) Math.ceil(durationInDouble);
+ return;
}
- // Not just a safeguard. This also means that you can run a 1.2A recipe on a single hatch for a regular gt
- // multi.
- // This is intended, including the fact that you don't get an OC with a one tier upgrade in that case.
- overclockCount = Math.max(overclockCount, 0);
-
- overclockCount = limitOverclocks ? Math.min(maxOverclocks, overclockCount) : overclockCount;
- heatOverclockCount = Math.min(heatOverclockCount, overclockCount);
- recipeVoltage = (long) Math.floor(recipeVoltage * Math.pow(eutIncreasePerOC, overclockCount));
- duration = (int) Math.floor(duration / Math.pow(durationDecreasePerOC, overclockCount - heatOverclockCount));
- duration = (int) Math.floor(duration / Math.pow(durationDecreasePerHeatOC, heatOverclockCount));
- if (oneTickDiscount) {
- recipeVoltage = (long) Math.floor(
- recipeVoltage
- / Math.pow(durationDecreasePerOC, ((int) (machinePowerTier - recipePowerTier - overclockCount))));
- if (recipeVoltage < 1) {
- recipeVoltage = 1;
+ // First we need to overclock to reach 1 tick.
+ // Then we need to overclock under one tick to get more extra parallels.
+ // We stop overclocking if we've already reached 1 tick and got enough parallels to actually perform.
+ double requiredUnderOneTickMultiplier = durationInDouble * currentParallel / parallel;
+ if (hasAtLeastOneSupplierBeenSet) { // custom overclock
+ double currentEutIncrease = eutIncreasePerOCSupplier.apply(overclockCount + 1);
+ double currentDurationDecrease = durationDecreasePerOCSupplier.apply(overclockCount + 1);
+ double machinePower = calculateMachinePower();
+ double currentConsumption = calculateRecipePower(heatDiscountMultiplier);
+ double currentUnderOneTickMultiplier = 1;
+ // Whether we have enough power for the next overclock;
+ // whether we need more overclock to reach 1 tick and get enough extra parallel;
+ // whether we have reached the overclock limit
+ while (machinePower > currentConsumption * currentEutIncrease
+ && requiredUnderOneTickMultiplier > currentUnderOneTickMultiplier
+ && (!limitOverclocks || overclockCount < maxOverclocks)) {
+ currentConsumption *= currentEutIncrease;
+ durationInDouble /= currentDurationDecrease;
+ overclockCount++;
+ currentEutIncrease = eutIncreasePerOCSupplier.apply(overclockCount + 1);
+ currentDurationDecrease = durationDecreasePerOCSupplier.apply(overclockCount + 1);
}
+ calculatedConsumption = (long) Math.max(currentConsumption, 1);
+ calculatedDuration = (int) Math.max(durationInDouble, 1);
+ } else { // general overclock
+ double recipePowerTier = calculateRecipePowerTier(heatDiscountMultiplier);
+ double machinePowerTier = calculateMachinePowerTier();
+
+ int maxOverclockCount = calculateAmountOfOverclocks(machinePowerTier, recipePowerTier);
+ if (limitOverclocks) maxOverclockCount = Math.min(maxOverclocks, maxOverclockCount);
+ if (!amperageOC) {
+ // Limit overclocks by voltage tier.
+ maxOverclockCount = Math.min(maxOverclockCount, calculateRecipeToMachineVoltageDifference());
+ }
+ overclockCount = calculateAmountOfNeededOverclocks(maxOverclockCount, requiredUnderOneTickMultiplier);
+
+ // If triggered, it indicates that recipe power > machine power.
+ // Not just a safeguard. This also means that you can run a 1.2A recipe on a single hatch for a regular gt
+ // multi.
+ // This is intended, including the fact that you don't get an OC with a one tier upgrade in that case.
+ overclockCount = Math.max(overclockCount, 0);
+
+ int heatOverclockCount = Math.min(calculateMaxAmountOfHeatOverclocks(), overclockCount);
+ calculatedConsumption = (long) Math.floor(recipeEUt * Math.pow(eutIncreasePerOC, overclockCount));
+ durationInDouble /= Math.pow(durationDecreasePerHeatOC, heatOverclockCount)
+ * Math.pow(durationDecreasePerOC, overclockCount - heatOverclockCount);
+ if (oneTickDiscount) {
+ calculatedConsumption = (long) Math
+ .floor(calculatedConsumption / Math.pow(durationDecreasePerOC, maxOverclockCount - overclockCount));
+ calculatedConsumption = Math.max(calculatedConsumption, 1);
+ }
+ calculatedConsumption = calculateFinalRecipeEUt(heatDiscountMultiplier);
+ calculatedDuration = (int) Math.max(durationInDouble, 1);
}
+ }
- if (laserOC) {
- calculateLaserOC();
- }
-
- if (duration < 1) {
- duration = 1;
- }
-
- recipeVoltage = calculateFinalRecipeEUt(heatDiscountMultiplier);
+ private double calculateRecipePower(double heatDiscountMultiplier) {
+ return recipeEUt * parallel * eutDiscount * heatDiscountMultiplier;
}
private double calculateRecipePowerTier(double heatDiscountMultiplier) {
- return calculatePowerTier(recipeVoltage * parallel * eutDiscount * heatDiscountMultiplier * recipeAmperage);
+ return calculatePowerTier(calculateRecipePower(heatDiscountMultiplier));
+ }
+
+ private double calculateMachinePower() {
+ return machineVoltage * (amperageOC ? machineAmperage : Math.min(machineAmperage, parallel));
}
private double calculateMachinePowerTier() {
- return calculatePowerTier(
- machineVoltage * (amperageOC ? machineAmperage : Math.min(machineAmperage, parallel)));
+ return calculatePowerTier(calculateMachinePower());
}
private int calculateRecipeToMachineVoltageDifference() {
- return (int) (Math.ceil(calculatePowerTier(machineVoltage)) - Math.ceil(calculatePowerTier(recipeVoltage)));
+ return (int) (Math.ceil(calculatePowerTier(machineVoltage)) - Math.ceil(calculatePowerTier(recipeEUt)));
}
private double calculatePowerTier(double voltage) {
@@ -457,15 +501,11 @@ public class GT_OverclockCalculator {
}
private long calculateFinalRecipeEUt(double heatDiscountMultiplier) {
- return (long) Math.ceil(recipeVoltage * eutDiscount * heatDiscountMultiplier * parallel * recipeAmperage);
+ return (long) Math.ceil(calculatedConsumption * eutDiscount * heatDiscountMultiplier * parallel);
}
- private int calculateAmountOfHeatOverclocks() {
- return Math.min(
- (machineHeat - recipeHeat) / HEAT_PERFECT_OVERCLOCK_THRESHOLD,
- calculateAmountOfOverclocks(
- calculateMachinePowerTier(),
- calculateRecipePowerTier(calculateHeatDiscountMultiplier())));
+ private int calculateMaxAmountOfHeatOverclocks() {
+ return heatOC ? (machineHeat - recipeHeat) / HEAT_PERFECT_OVERCLOCK_THRESHOLD : 0;
}
/**
@@ -475,28 +515,16 @@ public class GT_OverclockCalculator {
return (int) (machinePowerTier - recipePowerTier);
}
- /**
- * Calculates the amount of overclocks needed to reach 1 ticking
- *
- * Here we limit "the tier difference overclock" amount to a number of overclocks needed to reach 1 tick duration,
- * for example:
- *
- * recipe initial duration = 250 ticks (12,5 seconds LV(1))
- * we have LCR with IV(5) energy hatch, which overclocks at 4/4 rate
- *
- * log_4 (250) ~ 3,98 is the number of overclocks needed to reach 1 tick
- *
- * to calculate log_a(b) we can use the log property:
- * log_a(b) = log_c(b) / log_c(a)
- * in our case we use natural log base as 'c'
- *
- * as a final step we apply Math.ceil(),
- * otherwise for fractional nums like 3,98 we will never reach 1 tick
- */
- private int calculateAmountOfNeededOverclocks(double machinePowerTier, double recipePowerTier) {
- return (int) Math.min(
- calculateAmountOfOverclocks(machinePowerTier, recipePowerTier),
- Math.ceil(Math.log(duration) / Math.log(durationDecreasePerOC)));
+ private int calculateAmountOfNeededOverclocks(int maxOverclockCount, double requiredUnderOneTickMultiplier) {
+ int neededHeatOC = (int) Math.min(
+ calculateMaxAmountOfHeatOverclocks(),
+ Math.ceil(Math.log(requiredUnderOneTickMultiplier) / Math.log(durationDecreasePerHeatOC)));
+ neededHeatOC = Math.max(neededHeatOC, 0);
+ int neededNormalOC = (int) Math.ceil(
+ (Math.log(requiredUnderOneTickMultiplier) - Math.log(durationDecreasePerHeatOC) * neededHeatOC)
+ / Math.log(durationDecreasePerOC));
+ neededNormalOC = Math.max(neededNormalOC, 0);
+ return Math.min(maxOverclockCount, neededHeatOC + neededNormalOC);
}
private double calculateHeatDiscountMultiplier() {
@@ -504,16 +532,8 @@ public class GT_OverclockCalculator {
return Math.pow(heatDiscountExponent, heatDiscounts);
}
- private void calculateLaserOC() {
- long inputEut = machineVoltage * machineAmperage;
- double currentPenalty = eutIncreasePerOC + laserOCPenalty;
- while (inputEut > recipeVoltage * currentPenalty && recipeVoltage * currentPenalty > 0 && duration > 1) {
- duration /= durationDecreasePerOC;
- recipeVoltage *= currentPenalty;
- currentPenalty += laserOCPenalty;
- }
- }
-
+ // endregion
+ // region result getters
/**
* @return The consumption after overclock has been calculated
*/
@@ -521,7 +541,7 @@ public class GT_OverclockCalculator {
if (!calculated) {
throw new IllegalStateException("Tried to get consumption before calculating");
}
- return recipeVoltage;
+ return calculatedConsumption;
}
/**
@@ -531,7 +551,7 @@ public class GT_OverclockCalculator {
if (!calculated) {
throw new IllegalStateException("Tried to get duration before calculating");
}
- return duration;
+ return calculatedDuration;
}
/**
@@ -551,68 +571,51 @@ public class GT_OverclockCalculator {
return calculated;
}
+ // endregion
+ // region misc
/**
* Returns duration as a double to show how much it is overclocking too much to determine extra parallel. This
* doesn't count as calculating
*/
public double calculateDurationUnderOneTick() {
- if (durationUnderOneTickSupplier != null) return durationUnderOneTickSupplier.get();
- if (noOverclock) return duration;
- int normalOverclocks = calculateAmountOfOverclocks(
- calculateMachinePowerTier(),
- calculateRecipePowerTier(calculateHeatDiscountMultiplier()));
- normalOverclocks = limitOverclocks ? Math.min(normalOverclocks, maxOverclocks) : normalOverclocks;
- int heatOverclocks = Math.min(calculateAmountOfHeatOverclocks(), normalOverclocks);
- return (duration * speedBoost) / (Math.pow(durationDecreasePerOC, normalOverclocks - heatOverclocks)
- * Math.pow(durationDecreasePerHeatOC, heatOverclocks));
- }
-
- /**
- * Returns the EUt consumption one would get from overclocking under 1 tick
- * This Doesn't count as calculating
- *
- * @param originalMaxParallel Parallels which are of the actual machine before the overclocking extra ones
- */
- public long calculateEUtConsumptionUnderOneTick(int originalMaxParallel, int currentParallel) {
- if (noOverclock) return recipeVoltage;
+ double durationInDouble = durationUnderOneTickSupplier != null ? durationUnderOneTickSupplier.get()
+ : duration * speedBoost;
+ if (noOverclock) return durationInDouble;
double heatDiscountMultiplier = calculateHeatDiscountMultiplier();
- // So what we need to do here is as follows:
- // - First we need to figure out what out parallel multiplier for getting to that OC was
- // - Second we need to find how many of those were from heat overclocks
- // - Third we need to find how many were from normal overclocking.
- // = For that we need to find how much better heat overclocks are compared to normal ones
- // = Then remove that many from our normal overclocks
- // - Fourth we find how many total overclocks we have
- // - Fifth we find how many of those are needed to one tick
- // - Finally we calculate the formula
- // = The energy increase from our overclocks for parallel
- // = The energy increase from our overclock to reach maximum under one tick potential
- // =- NOTE: This will always cause machine to use full power no matter what. Otherwise it creates many
- // anomalies.
- // = Everything else for recipe voltage is also calculated here.
-
- double parallelMultiplierFromOverclocks = (double) currentParallel / originalMaxParallel;
- double amountOfParallelHeatOverclocks = Math.min(
- Math.log(parallelMultiplierFromOverclocks) / Math.log(durationDecreasePerHeatOC),
- calculateAmountOfHeatOverclocks());
- double amountOfParallelOverclocks = Math.log(parallelMultiplierFromOverclocks) / Math.log(durationDecreasePerOC)
- - amountOfParallelHeatOverclocks * (durationDecreasePerHeatOC - durationDecreasePerOC);
- double machineTier = calculateMachinePowerTier();
- double recipeTier = calculateRecipePowerTier(heatDiscountMultiplier);
- double amountOfTotalOverclocks = calculateAmountOfOverclocks(machineTier, recipeTier);
- if (recipeVoltage <= GT_Values.V[0]) {
- amountOfTotalOverclocks = Math.min(amountOfTotalOverclocks, calculateRecipeToMachineVoltageDifference());
+ if (hasAtLeastOneSupplierBeenSet) {
+ int overclockCount = 0;
+ double currentEutIncrease = eutIncreasePerOCSupplier.apply(overclockCount + 1);
+ double currentDurationDecrease = durationDecreasePerOCSupplier.apply(overclockCount + 1);
+ double machinePower = calculateMachinePower();
+ double recipePower = calculateRecipePower(heatDiscountMultiplier);
+ while (machinePower > recipePower * currentEutIncrease
+ && (!limitOverclocks || overclockCount < maxOverclocks)) {
+ recipePower *= currentEutIncrease;
+ durationInDouble /= currentDurationDecrease;
+ overclockCount++;
+ currentEutIncrease = eutIncreasePerOCSupplier.apply(overclockCount + 1);
+ currentDurationDecrease = durationDecreasePerOCSupplier.apply(overclockCount + 1);
+ }
+ } else {
+ int maxOverclockCount = calculateAmountOfOverclocks(
+ calculateMachinePowerTier(),
+ calculateRecipePowerTier(heatDiscountMultiplier));
+ if (limitOverclocks) maxOverclockCount = Math.min(maxOverclocks, maxOverclockCount);
+ int heatOverclocks = Math.min(calculateMaxAmountOfHeatOverclocks(), maxOverclockCount);
+ durationInDouble /= Math.pow(durationDecreasePerOC, maxOverclockCount - heatOverclocks)
+ * Math.pow(durationDecreasePerHeatOC, heatOverclocks);
}
- amountOfTotalOverclocks = limitOverclocks ? Math.min(amountOfTotalOverclocks, maxOverclocks)
- : amountOfTotalOverclocks;
- return (long) Math.ceil(
- recipeVoltage * Math.pow(eutIncreasePerOC, amountOfParallelOverclocks + amountOfParallelHeatOverclocks)
- * Math.pow(
- eutIncreasePerOC,
- amountOfTotalOverclocks - (amountOfParallelOverclocks + amountOfParallelHeatOverclocks))
- * originalMaxParallel
- * eutDiscount
- * recipeAmperage
- * heatDiscountMultiplier);
+ return durationInDouble;
+ }
+
+ private Function<Integer, Double> getDefaultEutIncreasePerOCSupplier() {
+ return overclockCount -> eutIncreasePerOC;
+ }
+
+ private Function<Integer, Double> getDefaultDurationDecreasePerOCSupplier() {
+ return overclockCount -> overclockCount <= calculateMaxAmountOfHeatOverclocks() ? durationDecreasePerHeatOC
+ : durationDecreasePerOC;
}
+
+ // endregion
}
diff --git a/src/main/java/gregtech/api/util/GT_ParallelHelper.java b/src/main/java/gregtech/api/util/GT_ParallelHelper.java
index 141ea35e9e..157488a8ca 100644
--- a/src/main/java/gregtech/api/util/GT_ParallelHelper.java
+++ b/src/main/java/gregtech/api/util/GT_ParallelHelper.java
@@ -469,8 +469,8 @@ public class GT_ParallelHelper {
// Save the original max parallel before calculating our overclocking under 1 tick
int originalMaxParallel = maxParallel;
- double tickTimeAfterOC = calculator.setParallel(originalMaxParallel)
- .calculateDurationUnderOneTick();
+ calculator.setParallel(originalMaxParallel);
+ double tickTimeAfterOC = calculator.calculateDurationUnderOneTick();
if (tickTimeAfterOC < 1) {
maxParallel = GT_Utility.safeInt((long) (maxParallel / tickTimeAfterOC), 0);
}
@@ -559,12 +559,8 @@ public class GT_ParallelHelper {
return;
}
- long eutUseAfterOC = calculator.calculateEUtConsumptionUnderOneTick(originalMaxParallel, currentParallel);
- calculator.setParallel(Math.min(currentParallel, originalMaxParallel))
+ calculator.setCurrentParallel(currentParallel)
.calculate();
- if (currentParallel > originalMaxParallel) {
- calculator.setRecipeEUt(eutUseAfterOC);
- }
// 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;
diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_IntegratedOreFactory.java b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_IntegratedOreFactory.java
index 48ab5a10f5..af55829f6c 100644
--- a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_IntegratedOreFactory.java
+++ b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_IntegratedOreFactory.java
@@ -273,10 +273,10 @@ public class GT_MetaTileEntity_IntegratedOreFactory
GT_OverclockCalculator calculator = new GT_OverclockCalculator().setEUt(availableEUt)
.setRecipeEUt(RECIPE_EUT)
- .setDuration(getTime(sMode));
+ .setDuration(getTime(sMode))
+ .setParallel(originalMaxParallel);
- double tickTimeAfterOC = calculator.setParallel(originalMaxParallel)
- .calculateDurationUnderOneTick();
+ double tickTimeAfterOC = calculator.calculateDurationUnderOneTick();
if (tickTimeAfterOC < 1) {
maxParallel = GT_Utility.safeInt((long) (maxParallel / tickTimeAfterOC), 0);
@@ -325,9 +325,7 @@ public class GT_MetaTileEntity_IntegratedOreFactory
currentParallel = itemParallel;
int currentParallelBeforeBatchMode = Math.min(currentParallel, maxParallelBeforeBatchMode);
- long eutUseAfterOC = calculator
- .calculateEUtConsumptionUnderOneTick(originalMaxParallel, currentParallelBeforeBatchMode);
- calculator.setParallel(Math.min(currentParallelBeforeBatchMode, originalMaxParallel))
+ calculator.setCurrentParallel(currentParallelBeforeBatchMode)
.calculate();
double batchMultiplierMax = 1;
@@ -407,7 +405,7 @@ public class GT_MetaTileEntity_IntegratedOreFactory
this.mEfficiencyIncrease = 10000;
this.mOutputItems = sMidProduct;
this.mMaxProgresstime = (int) (calculator.getDuration() * batchMultiplierMax);
- this.lEUt = eutUseAfterOC;
+ this.lEUt = calculator.getConsumption();
if (this.lEUt > 0) {
this.lEUt = -this.lEUt;
}
diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_MultiFurnace.java b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_MultiFurnace.java
index b7b34add0b..5d611b270d 100644
--- a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_MultiFurnace.java
+++ b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_MultiFurnace.java
@@ -156,11 +156,14 @@ public class GT_MetaTileEntity_MultiFurnace
ArrayList<ItemStack> tInputList = getAllStoredInputs();
if (tInputList.isEmpty()) return CheckRecipeResultRegistry.NO_RECIPE;
- int mVoltage = GT_Utility.safeInt(getMaxInputVoltage());
+ long inputVoltage = getMaxInputVoltage();
- GT_OverclockCalculator calculator = new GT_OverclockCalculator().setEUt(mVoltage)
+ int fakeOriginalMaxParallel = 1;
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator().setEUt(inputVoltage)
.setRecipeEUt(RECIPE_EUT)
- .setDuration(RECIPE_DURATION);
+ .setDuration(RECIPE_DURATION)
+ .setParallel(fakeOriginalMaxParallel);
+
int maxParallel = this.mLevel;
int originalMaxParallel = maxParallel;
double tickTimeAfterOC = calculator.calculateDurationUnderOneTick();
@@ -174,35 +177,32 @@ public class GT_MetaTileEntity_MultiFurnace
}
// Calculate parallel
- int tCurrentParallel = 0;
+ int currentParallel = 0;
for (ItemStack item : tInputList) {
ItemStack smeltedOutput = GT_ModHandler.getSmeltingOutput(item, false, null);
if (smeltedOutput != null) {
- if (item.stackSize <= (maxParallel - tCurrentParallel)) {
- tCurrentParallel += item.stackSize;
+ if (item.stackSize <= (maxParallel - currentParallel)) {
+ currentParallel += item.stackSize;
} else {
- tCurrentParallel = maxParallel;
+ currentParallel = maxParallel;
break;
}
}
}
- if (tCurrentParallel <= 0) {
+ if (currentParallel <= 0) {
return CheckRecipeResultRegistry.NO_RECIPE;
}
- int currentParallelBeforeBatchMode = Math.min(tCurrentParallel, maxParallelBeforeBatchMode);
+ int currentParallelBeforeBatchMode = Math.min(currentParallel, maxParallelBeforeBatchMode);
+ int fakeCurrentParallel = (int) Math.ceil((double) currentParallelBeforeBatchMode / originalMaxParallel);
- long eutUseAfterOC = calculator.calculateEUtConsumptionUnderOneTick(
- 1,
- (int) Math.ceil((double) currentParallelBeforeBatchMode / originalMaxParallel));
- calculator
- .setParallel(Math.min((int) Math.ceil((double) currentParallelBeforeBatchMode / originalMaxParallel), 1))
+ calculator.setCurrentParallel(fakeCurrentParallel)
.calculate();
double batchMultiplierMax = 1;
// In case batch mode enabled
- if (tCurrentParallel > maxParallelBeforeBatchMode && calculator.getDuration() < getMaxBatchSize()) {
+ if (currentParallel > maxParallelBeforeBatchMode && calculator.getDuration() < getMaxBatchSize()) {
batchMultiplierMax = (double) getMaxBatchSize() / calculator.getDuration();
- batchMultiplierMax = Math.min(batchMultiplierMax, (double) tCurrentParallel / maxParallelBeforeBatchMode);
+ batchMultiplierMax = Math.min(batchMultiplierMax, (double) currentParallel / maxParallelBeforeBatchMode);
}
int finalParallel = (int) (batchMultiplierMax * maxParallelBeforeBatchMode);
@@ -230,7 +230,7 @@ public class GT_MetaTileEntity_MultiFurnace
this.mEfficiency = 10000 - (getIdealStatus() - getRepairStatus()) * 1000;
this.mEfficiencyIncrease = 10000;
this.mMaxProgresstime = (int) (calculator.getDuration() * batchMultiplierMax);
- this.lEUt = eutUseAfterOC;
+ this.lEUt = calculator.getConsumption();
if (this.lEUt > 0) this.lEUt = -this.lEUt;
diff --git a/src/test/java/gregtech/overclock/GT_OverclockCalculator_UnitTest.java b/src/test/java/gregtech/overclock/GT_OverclockCalculator_UnitTest.java
index e1560b27cb..6056b00c73 100644
--- a/src/test/java/gregtech/overclock/GT_OverclockCalculator_UnitTest.java
+++ b/src/test/java/gregtech/overclock/GT_OverclockCalculator_UnitTest.java
@@ -4,6 +4,8 @@ import static gregtech.api.enums.GT_Values.V;
import static gregtech.api.enums.GT_Values.VP;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import java.util.function.Function;
+
import org.junit.jupiter.api.Test;
import gregtech.api.enums.TierEU;
@@ -26,7 +28,7 @@ class GT_OverclockCalculator_UnitTest {
.setRecipeHeat(1800)
.setMachineHeat(1800 * 5)
.calculate();
- assertEquals(1024 >> 8, calculator.getDuration(), messageDuration);
+ assertEquals(1024 / Math.pow(4, 4), calculator.getDuration(), messageDuration);
assertEquals(correctConsumption, calculator.getConsumption(), messageEUt);
}
@@ -42,7 +44,7 @@ class GT_OverclockCalculator_UnitTest {
.setRecipeHeat(1800)
.setMachineHeat(2700)
.calculate();
- assertEquals(1024 >> 4, calculator.getDuration(), messageDuration);
+ assertEquals(1024 / Math.pow(2, 4), calculator.getDuration(), messageDuration);
assertEquals(correctConsumption, calculator.getConsumption(), messageEUt);
}
@@ -56,7 +58,7 @@ class GT_OverclockCalculator_UnitTest {
.setRecipeHeat(1800)
.setMachineHeat(1800)
.calculate();
- assertEquals(1024 >> 4, calculator.getDuration(), messageDuration);
+ assertEquals(1024 / Math.pow(2, 4), calculator.getDuration(), messageDuration);
assertEquals(VP[5], calculator.getConsumption(), messageEUt);
}
@@ -72,7 +74,7 @@ class GT_OverclockCalculator_UnitTest {
.setRecipeHeat(1800)
.setMachineHeat(3600)
.calculate();
- assertEquals(1024 >> 5, calculator.getDuration(), messageDuration);
+ assertEquals(1024 / (Math.pow(4, 1) * Math.pow(2, 3)), calculator.getDuration(), messageDuration);
assertEquals(correctConsumption, calculator.getConsumption(), messageEUt);
}
@@ -82,7 +84,7 @@ class GT_OverclockCalculator_UnitTest {
.setEUt(V[6])
.setDuration(1024)
.calculate();
- assertEquals(1024 >> 5, calculator.getDuration(), messageDuration);
+ assertEquals(1024 / Math.pow(2, 5), calculator.getDuration(), messageDuration);
assertEquals(VP[6], calculator.getConsumption(), messageEUt);
}
@@ -93,7 +95,7 @@ class GT_OverclockCalculator_UnitTest {
.setDuration(2048)
.enablePerfectOC()
.calculate();
- assertEquals(2048 >> 10, calculator.getDuration(), messageDuration);
+ assertEquals(2048 / Math.pow(4, 5), calculator.getDuration(), messageDuration);
assertEquals(VP[6], calculator.getConsumption(), messageEUt);
}
@@ -109,7 +111,7 @@ class GT_OverclockCalculator_UnitTest {
.setRecipeHeat(486)
.setMachineHeat(3900)
.calculate();
- assertEquals(2048 >> 6, calculator.getDuration(), messageDuration);
+ assertEquals(2048 / (Math.pow(4, 1) * Math.pow(2, 4)), calculator.getDuration(), messageDuration);
assertEquals(correctConsumption, calculator.getConsumption(), messageEUt);
}
@@ -121,7 +123,7 @@ class GT_OverclockCalculator_UnitTest {
.setDuration(1024)
.setAmperageOC(true)
.calculate();
- assertEquals(1024 >> 6, calculator.getDuration(), messageDuration);
+ assertEquals(1024 / Math.pow(2, 6), calculator.getDuration(), messageDuration);
assertEquals(VP[7], calculator.getConsumption(), messageEUt);
}
@@ -133,8 +135,8 @@ class GT_OverclockCalculator_UnitTest {
.setDuration(1024)
.setAmperageOC(true)
.calculate();
- assertEquals(1024 >> 6, calculator.getDuration(), messageDuration);
- assertEquals(VP[0] << 12, calculator.getConsumption(), messageEUt);
+ assertEquals(1024 / Math.pow(2, 6), calculator.getDuration(), messageDuration);
+ assertEquals(VP[0] * Math.pow(4, 6), calculator.getConsumption(), messageEUt);
}
@Test
@@ -145,7 +147,7 @@ class GT_OverclockCalculator_UnitTest {
.setDuration(1024)
.setAmperageOC(true)
.calculate();
- assertEquals(1024 >> 9, calculator.getDuration(), messageDuration);
+ assertEquals(1024 / Math.pow(2, 9), calculator.getDuration(), messageDuration);
assertEquals(VP[10], calculator.getConsumption(), messageEUt);
}
@@ -157,7 +159,7 @@ class GT_OverclockCalculator_UnitTest {
.setDuration(1024)
.setAmperageOC(true)
.calculate();
- assertEquals(1024 >> 9, calculator.getDuration(), messageDuration);
+ assertEquals(1024 / Math.pow(2, 9), calculator.getDuration(), messageDuration);
assertEquals(VP[10], calculator.getConsumption(), messageEUt);
}
@@ -170,7 +172,7 @@ class GT_OverclockCalculator_UnitTest {
.setParallel(16)
.setAmperageOC(true)
.calculate();
- assertEquals(1024 >> 6, calculator.getDuration(), messageDuration);
+ assertEquals(1024 / Math.pow(2, 6), calculator.getDuration(), messageDuration);
assertEquals(VP[9], calculator.getConsumption(), messageEUt);
}
@@ -184,7 +186,7 @@ class GT_OverclockCalculator_UnitTest {
.setAmperageOC(true)
.enablePerfectOC()
.calculate();
- assertEquals(4096 >> 12, calculator.getDuration(), messageDuration);
+ assertEquals(4096 / Math.pow(4, 6), calculator.getDuration(), messageDuration);
assertEquals(VP[9], calculator.getConsumption(), messageEUt);
}
@@ -197,7 +199,7 @@ class GT_OverclockCalculator_UnitTest {
.setParallel(16)
.setAmperageOC(true)
.calculate();
- assertEquals(1024 >> 7, calculator.getDuration(), messageDuration);
+ assertEquals(1024 / Math.pow(2, 7), calculator.getDuration(), messageDuration);
assertEquals(VP[10], calculator.getConsumption(), messageEUt);
}
@@ -208,7 +210,7 @@ class GT_OverclockCalculator_UnitTest {
.setDuration(1024)
.setParallel(8)
.calculate();
- assertEquals(1024 >> 5, calculator.getDuration(), messageDuration);
+ assertEquals(1024 / Math.pow(2, 5), calculator.getDuration(), messageDuration);
assertEquals(VP[6] * 8, calculator.getConsumption(), messageEUt);
}
@@ -221,7 +223,7 @@ class GT_OverclockCalculator_UnitTest {
.setParallel(8)
.setAmperageOC(true)
.calculate();
- assertEquals(1024 >> 9, calculator.getDuration(), messageDuration);
+ assertEquals(1024 / Math.pow(2, 9), calculator.getDuration(), messageDuration);
assertEquals(VP[6] * 8 * 256, calculator.getConsumption(), messageEUt);
}
@@ -231,7 +233,7 @@ class GT_OverclockCalculator_UnitTest {
.setEUt(V[6])
.setDuration(77)
.calculate();
- assertEquals(77 >> 5, calculator.getDuration(), messageDuration);
+ assertEquals((int) (77 / Math.pow(2, 5)), calculator.getDuration(), messageDuration);
assertEquals(VP[6], calculator.getConsumption(), messageEUt);
}
@@ -253,7 +255,7 @@ class GT_OverclockCalculator_UnitTest {
.setEUtDiscount(0.9f)
.setDuration(1024)
.calculate();
- assertEquals(1024 >> 5, calculator.getDuration(), messageDuration);
+ assertEquals(1024 / Math.pow(2, 5), calculator.getDuration(), messageDuration);
assertEquals(correctConsumption, calculator.getConsumption(), messageEUt);
}
@@ -266,7 +268,7 @@ class GT_OverclockCalculator_UnitTest {
.setDuration(1024)
.enablePerfectOC()
.calculate();
- assertEquals(1024 >> 10, calculator.getDuration(), messageDuration);
+ assertEquals(1024 / Math.pow(4, 5), calculator.getDuration(), messageDuration);
assertEquals(correctConsumption, calculator.getConsumption(), messageEUt);
}
@@ -277,7 +279,7 @@ class GT_OverclockCalculator_UnitTest {
.setSpeedBoost(0.9f)
.setDuration(1024)
.calculate();
- assertEquals((int) (1024 * 0.9f) >> 5, calculator.getDuration(), messageDuration);
+ assertEquals((int) (1024 * 0.9f / Math.pow(2, 5)), calculator.getDuration(), messageDuration);
assertEquals(VP[6], calculator.getConsumption(), messageEUt);
}
@@ -289,7 +291,7 @@ class GT_OverclockCalculator_UnitTest {
.setDuration(2048)
.enablePerfectOC()
.calculate();
- assertEquals((int) (2048 * 0.9f) >> 10, calculator.getDuration(), messageDuration);
+ assertEquals((int) ((2048 * 0.9f) / Math.pow(4, 5)), calculator.getDuration(), messageDuration);
assertEquals(VP[6], calculator.getConsumption(), messageEUt);
}
@@ -326,17 +328,17 @@ class GT_OverclockCalculator_UnitTest {
assertEquals(1, calculator.getDuration(), messageDuration);
/*
- * duration with speedboost = 5
- * log_2(5) ~ 2.3;
+ * duration with speedboost = 4.4
+ * log_2(5) ~ 2.14;
* round up to 3 to reach one tick duration
*/
int overclocksTillOneTick = 3;
int overclocksBeyondOneTick = 2;
// 3 overclocks, each gives 4x consumption growth per tick (1920)
- long targetEUt = VP[1] << 2 * overclocksTillOneTick;
+ long targetEUt = (long) (VP[1] * Math.pow(4, overclocksTillOneTick));
// 2 remaining overclocks are beyond 1 tick, each provides 2x comsumption discount (480)
- targetEUt >>= overclocksBeyondOneTick;
+ targetEUt /= Math.pow(2, overclocksBeyondOneTick);
assertEquals(targetEUt, calculator.getConsumption(), messageEUt);
}
@@ -352,17 +354,17 @@ class GT_OverclockCalculator_UnitTest {
.calculate();
/*
- * duration with speedboost = 18
- * log_4(18) ~ 2.08;
+ * duration with speedboost = 17.6
+ * log_4(18) ~ 2.06;
* round up to 3 to reach one tick duration
*/
int overclocksTillOneTick = 3;
int overclocksBeyondOneTick = 2;
// 3 overclocks, each gives 4x consumption growth per tick (1920)
- long targetEUt = VP[1] << 2 * overclocksTillOneTick;
+ long targetEUt = (long) (VP[1] * Math.pow(4, overclocksTillOneTick));
// 2 remaining overclocks are beyond 1 tick, each provides 4x comsumption discount (120)
- targetEUt >>= 2 * overclocksBeyondOneTick;
+ targetEUt /= Math.pow(4, overclocksBeyondOneTick);
assertEquals(targetEUt, calculator.getConsumption(), messageEUt);
assertEquals(1, calculator.getDuration(), messageDuration);
@@ -376,7 +378,7 @@ class GT_OverclockCalculator_UnitTest {
.setEUtDiscount(0.9f)
.setDuration(1024)
.calculate();
- assertEquals(1024 >> 5, calculator.getDuration(), messageDuration);
+ assertEquals(1024 / Math.pow(2, 5), calculator.getDuration(), messageDuration);
assertEquals(correctConsumption, calculator.getConsumption(), messageEUt);
}
@@ -389,7 +391,7 @@ class GT_OverclockCalculator_UnitTest {
.setParallel(14)
.setDuration(1024)
.calculate();
- assertEquals(1024 >> 3, calculator.getDuration(), messageDuration);
+ assertEquals(1024 / Math.pow(2, 3), calculator.getDuration(), messageDuration);
assertEquals(correctConsumption, calculator.getConsumption(), messageEUt);
}
@@ -413,7 +415,7 @@ class GT_OverclockCalculator_UnitTest {
.setDuration(30)
.calculate();
assertEquals(1, calculator.getDuration(), messageDuration);
- assertEquals(16 << 14, calculator.getConsumption(), messageEUt);
+ assertEquals(16 * Math.pow(4, 7), calculator.getConsumption(), messageEUt);
}
@Test
@@ -422,10 +424,12 @@ class GT_OverclockCalculator_UnitTest {
.setParallel(56)
.setAmperage(1)
.setAmperageOC(true)
- .setSpeedBoost(1f / 6f)
- .setEUt(V[14])
- .setDuration(56);
- assertEquals((24 * 56) << 20, calculator.calculateEUtConsumptionUnderOneTick(56, 6144));
+ .setSpeedBoost(1f / 6.01f) // If we set this to 1/6 we will get 11 overclocks because of float imprecision.
+ .setEUt(V[14] * 1_048_576)
+ .setDuration(56)
+ .setCurrentParallel(6144)
+ .calculate();
+ assertEquals((24 * 56) * Math.pow(4, 10), calculator.getConsumption());
}
@Test
@@ -441,10 +445,36 @@ class GT_OverclockCalculator_UnitTest {
.setMachineHeat(15500)
.setEUt(V[12] * 1_048_576)
.setDuration(250);
- assertEquals(
- Math.ceil((((long) 1920 * 256) << 28) * heatDiscount),
- calculator
- .calculateEUtConsumptionUnderOneTick(256, (int) (256 / calculator.calculateDurationUnderOneTick())));
+ calculator.setCurrentParallel((int) (256 / calculator.calculateDurationUnderOneTick()))
+ .calculate();
+ assertEquals(Math.ceil((((long) 1920 * 256) * Math.pow(4, 14)) * heatDiscount), calculator.getConsumption());
+ }
+
+ @Test
+ void testCorrectOverclockWhenCurrentParallelLessThanOriginalParallel() {
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator().setRecipeEUt(24)
+ .setParallel(64)
+ .setAmperage(1)
+ .setAmperageOC(true)
+ .setEUt(V[6])
+ .setDuration(56)
+ .setCurrentParallel(16)
+ .calculate();
+ assertEquals(56 / Math.pow(2, 3), calculator.getDuration());
+ assertEquals((24 * 16) * Math.pow(4, 3), calculator.getConsumption());
+ }
+
+ @Test
+ void stopsCorrectlyWhenOverclockingUnderOneTick() {
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator().setRecipeEUt(VP[2])
+ .setEUt(V[9])
+ .setParallel(4)
+ .setDuration(10)
+ .setAmperageOC(false)
+ .setAmperage(16)
+ .setCurrentParallel(16)
+ .calculate();
+ assertEquals((VP[2] * 4) * Math.pow(4, 6), calculator.getConsumption());
}
@Test
@@ -475,7 +505,7 @@ class GT_OverclockCalculator_UnitTest {
.setAmperageOC(false)
.setAmperage(16)
.calculate();
- assertEquals((32 * 64), calculator.getConsumption(), messageEUt);
+ assertEquals(32 * 64, calculator.getConsumption(), messageEUt);
}
@Test
@@ -499,7 +529,7 @@ class GT_OverclockCalculator_UnitTest {
.setAmperageOC(false)
.setAmperage(16)
.calculate();
- assertEquals((8 << 4) * 16, calculator.getConsumption(), messageEUt);
+ assertEquals((8 * 16) * Math.pow(4, 2), calculator.getConsumption(), messageEUt);
}
@Test
@@ -510,7 +540,7 @@ class GT_OverclockCalculator_UnitTest {
.setDuration(20)
.setAmperageOC(false)
.calculate();
- assertEquals((8 << 2) * 16, calculator.getConsumption(), messageEUt);
+ assertEquals((8 * 16) * Math.pow(4, 1), calculator.getConsumption(), messageEUt);
}
@Test
@@ -522,7 +552,7 @@ class GT_OverclockCalculator_UnitTest {
.setAmperage(64)
.setAmperageOC(false)
.calculate();
- assertEquals((7 << 4) * 64, calculator.getConsumption(), messageEUt);
+ assertEquals((7 * 64) * Math.pow(4, 2), calculator.getConsumption(), messageEUt);
}
@Test
@@ -534,7 +564,7 @@ class GT_OverclockCalculator_UnitTest {
.setAmperage(19)
.setAmperageOC(false)
.calculate();
- assertEquals((7 << 4) * 19, calculator.getConsumption(), messageEUt);
+ assertEquals((7 * 19) * Math.pow(4, 2), calculator.getConsumption(), messageEUt);
}
@Test
@@ -546,7 +576,7 @@ class GT_OverclockCalculator_UnitTest {
.setAmperage(25)
.setAmperageOC(false)
.calculate();
- assertEquals((7 << 4) * 29, calculator.getConsumption(), messageEUt);
+ assertEquals((7 * 29) * Math.pow(4, 2), calculator.getConsumption(), messageEUt);
}
@Test
@@ -556,8 +586,9 @@ class GT_OverclockCalculator_UnitTest {
.setParallel(64)
.setDuration(300)
.setAmperage(64)
- .setAmperageOC(false);
- assertEquals(TierEU.LuV * 64, calculator.calculateEUtConsumptionUnderOneTick(64, 64), messageEUt);
+ .setAmperageOC(false)
+ .calculate();
+ assertEquals(TierEU.LuV * 64, calculator.getConsumption(), messageEUt);
}
@Test
@@ -568,7 +599,7 @@ class GT_OverclockCalculator_UnitTest {
.setDuration(1024)
.setEUtIncreasePerOC(4.1)
.calculate();
- assertEquals(1024 >> 5, calculator.getDuration(), messageDuration);
+ assertEquals(1024 / Math.pow(2, 5), calculator.getDuration(), messageDuration);
assertEquals(expectedEUt, calculator.getConsumption(), messageEUt);
}
@@ -585,6 +616,41 @@ class GT_OverclockCalculator_UnitTest {
}
@Test
+ void overclockWithCustomEutIncreasePerOCSupplier() {
+ Function<Integer, Double> laserOC = overclockCount -> overclockCount <= 5 ? 4
+ : (4 + 0.3 * (overclockCount - 5));
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator().setRecipeEUt(VP[1])
+ .setEUt(V[6])
+ .setAmperageOC(true)
+ .setAmperage(1024)
+ .setDuration(1024)
+ .setEutIncreasePerOCSupplier(laserOC)
+ .calculate();
+ assertEquals(5 + 4, calculator.getPerformedOverclocks());
+ assertEquals(1024 / Math.pow(2, 9), calculator.getDuration());
+ assertEquals((int) (VP[1] * Math.pow(4, 5) * 4.3 * 4.6 * 4.9 * 5.2), calculator.getConsumption());
+ }
+
+ @Test
+ void overclockUnderOneTickWithCustomEutIncreasePerOCSupplier() {
+ Function<Integer, Double> laserOC = overclockCount -> overclockCount <= 5 ? 4
+ : (4 + 0.3 * (overclockCount - 5));
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator().setRecipeEUt(VP[1])
+ .setEUt(V[6])
+ .setAmperageOC(true)
+ .setAmperage(4000)
+ .setDuration(64)
+ .setEutIncreasePerOCSupplier(laserOC);
+
+ assertEquals(Math.pow(2, 10) / 64, (int) (1 / calculator.calculateDurationUnderOneTick()));
+
+ calculator.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 slightlyOverOneAmpRecipeWorksWithSingleEnergyHatch() {
GT_OverclockCalculator calculator = new GT_OverclockCalculator().setRecipeEUt(614400)
.setEUt(TierEU.UV)