aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/gregtech/api/util/GT_OverclockCalculator.java269
-rw-r--r--src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_PCBFactory.java25
-rw-r--r--src/test/java/gregtech/overclock/GT_OverclockCalculator_UnitTest.java453
3 files changed, 741 insertions, 6 deletions
diff --git a/src/main/java/gregtech/api/util/GT_OverclockCalculator.java b/src/main/java/gregtech/api/util/GT_OverclockCalculator.java
new file mode 100644
index 0000000000..7e3be7e3b0
--- /dev/null
+++ b/src/main/java/gregtech/api/util/GT_OverclockCalculator.java
@@ -0,0 +1,269 @@
+package gregtech.api.util;
+
+public class GT_OverclockCalculator {
+ /**
+ * @mAmps - Amperage of the multiblock
+ * @mEUt - Voltage of the multiblock
+ * @mRecipeEUt - Voltage the recipe will run at
+ * @mRecipeAmps - The amount of amps the recipe needs
+ */
+ private long mAmps = 1, mEUt = 0, mRecipeEUt = 0, mRecipeAmps = 1;
+ /**
+ * @mEUtDiscount - Discount for EUt at the beginning of calculating overclocks, like GT++ machines
+ * @mSpeedBoost - Speeding/Slowing up/down the duration of a recipe at the beginnign of calculating overclocks, like GT++ machines
+ * @mHeatDiscountAmont - The value used for discount final eut per 900 heat
+ */
+ private float mEUtDiscount = 1, mSpeedBoost = 1, mHeatDiscountAmount = 0.95f;
+ /**
+ * @mEUtIncreasePerOC - How much the bits should be moved to the left when it is overclocking (Going up, 2 meaning it is multiplied with 4x)
+ * @mDurationDecreasePerOC - How much the bits should be moved to the right when its overclocking (Going down, 1 meaning it is halved)
+ * @mDuration - Duration of the recipe
+ * @mParallel - The parallel the multi has when trying to overclock
+ * @mRecipeHeat - The min heat required for the recipe
+ * @mMultiHeat - The heat the multi has when starting the recipe
+ * @mHeatPerfectOC - How much the bits should be moved to the right for each 1800 above recipe heat (Used for duration)
+ */
+ private int mEUtIncrasePerOC = 2,
+ mDurationDecreasePerOC = 1,
+ mDuration = 0,
+ mParallel = 1,
+ mRecipeHeat = 0,
+ mMultiHeat = 0,
+ mHeatPerfectOC = 2;
+ /**
+ * @mHeatOC - Wheather to enable overlcocking with heat like the EBF every 1800 heat difference
+ * @mOneTickDiscount - Wheather to give EUt Discount when the duration goes below one tick
+ * @calculates - variable to check wheater the overclocks have been calculated
+ * @mHeatDiscount - Wheather to enable heat discounts every 900 heat difference
+ */
+ private boolean mHeatOC, mOneTickDiscount, calculated, mHeatDiscount;
+
+ private static final int HEAT_DISCOUNT_THRESHOLD = 900;
+ private static final int HEAT_PERFECT_OVERCLOCK_THRESHOLD = 1800;
+ /**
+ * An Overclock helper for calculating overclocks in many different situations
+ */
+ public GT_OverclockCalculator() {}
+
+ /**
+ * @param aRecipeEUt Sets the Recipe's starting voltage
+ */
+ public GT_OverclockCalculator setRecipeEUt(long aRecipeEUt) {
+ mRecipeEUt = aRecipeEUt;
+ return this;
+ }
+
+ /**
+ * @param aEUt Sets the EUt that the multiblock can use. This is the voltage of the multi
+ */
+ public GT_OverclockCalculator setEUt(long aEUt) {
+ mEUt = aEUt;
+ return this;
+ }
+
+ /**
+ * @param aDuration Sets the duration of the recipe
+ */
+ public GT_OverclockCalculator setDuration(int aDuration) {
+ mDuration = aDuration;
+ return this;
+ }
+
+ /**
+ * @param aAmps Sets the Amperage that the multi can support
+ */
+ public GT_OverclockCalculator setAmperage(long aAmps) {
+ mAmps = aAmps;
+ return this;
+ }
+
+ /**
+ * @param aRecipeAmps Sets the Amperage of the recipe
+ */
+ public GT_OverclockCalculator setRecipeAmperage(long aRecipeAmps) {
+ mRecipeAmps = aRecipeAmps;
+ return this;
+ }
+
+ /**
+ * Enables Perfect OC in calculation
+ */
+ public GT_OverclockCalculator enablePerfectOC() {
+ mDurationDecreasePerOC = 2;
+ return this;
+ }
+
+ /**
+ * Enables calculating overclocking using EBF's perfectOC
+ */
+ public GT_OverclockCalculator enableHeatOC() {
+ mHeatOC = true;
+ return this;
+ }
+
+ /**
+ * Enables adding a heat discount at the end of calculating an overclock, just like the EBF
+ */
+ public GT_OverclockCalculator enableHeatDiscount() {
+ mHeatDiscount = true;
+ return this;
+ }
+
+ /**
+ * Sets the starting heat of the recipe
+ */
+ public GT_OverclockCalculator setRecipeHeat(int aRecipeHeat) {
+ mRecipeHeat = aRecipeHeat;
+ return this;
+ }
+
+ /**
+ * Sets the heat of the coils on the multi
+ */
+ public GT_OverclockCalculator setMultiHeat(int aMultiHeat) {
+ mMultiHeat = aMultiHeat;
+ return this;
+ }
+
+ /**
+ * Sets an EUtDiscount. 0.9 is 10% less energy. 1.1 is 10% more energy
+ */
+ public GT_OverclockCalculator setEUtDiscount(float aEUtDiscount) {
+ mEUtDiscount = aEUtDiscount;
+ return this;
+ }
+
+ /**
+ * Sets a Speed Boost for the multiblock. 0.9 is 10% faser. 1.1 is 10% slower
+ */
+ public GT_OverclockCalculator setSpeedBoost(float aSpeedBoost) {
+ mSpeedBoost = aSpeedBoost;
+ return this;
+ }
+
+ /**
+ * Sets the parallel that the multiblock uses
+ */
+ public GT_OverclockCalculator setParallel(int aParallel) {
+ mParallel = aParallel;
+ return this;
+ }
+
+ /**
+ * Sets the heat discount during OC calculation if HeatOC is used. Default: 0.95 = 5% discount
+ * Used like a EU/t Discount
+ */
+ public GT_OverclockCalculator setHeatDiscount(float aHeatDiscount) {
+ mHeatDiscountAmount = aHeatDiscount;
+ return this;
+ }
+
+ /**
+ * Sets the Overclock that should be calculated when one. This uses BitShifting! Default is 2, which is a 4x decrease
+ */
+ public GT_OverclockCalculator setHeatPerfectOC(int aHeatPerfectOC) {
+ mHeatPerfectOC = aHeatPerfectOC;
+ return this;
+ }
+
+ /**
+ * Sets the amount that the EUt increases per overclock. This uses BitShifting! Default is 2, which is a 4x increase
+ */
+ public GT_OverclockCalculator setEUtIncreasePerOC(int aEUtIncreasePerOC) {
+ mEUtIncrasePerOC = aEUtIncreasePerOC;
+ return this;
+ }
+
+ /**
+ * Sets the amount that the duration decreases per overclock. This uses BitShifting! Default is 1, which halves the duration
+ */
+ public GT_OverclockCalculator setDurationDecreasePerOC(int aDurationDecreasePerOC) {
+ mDurationDecreasePerOC = aDurationDecreasePerOC;
+ return this;
+ }
+
+ /**
+ * Enables One Tick Discount on EUt based on Duration Decrease Per Overclock. This functions the same as single blocks.
+ */
+ public GT_OverclockCalculator enableOneTickDiscount() {
+ mOneTickDiscount = true;
+ return this;
+ }
+
+ /**
+ * Call this when all values have been put it.
+ */
+ public GT_OverclockCalculator calculate() {
+ calculateOverclock();
+ calculated = true;
+ return this;
+ }
+
+ private void calculateOverclock() {
+ if (mRecipeEUt > mEUt || mRecipeHeat > mMultiHeat) {
+ mRecipeEUt = Long.MAX_VALUE;
+ mDuration = Integer.MAX_VALUE;
+ return;
+ }
+ int heatDiscounts = (mMultiHeat - mRecipeHeat) / HEAT_DISCOUNT_THRESHOLD;
+ mRecipeEUt = (long) Math.ceil(mRecipeEUt * mEUtDiscount);
+ mDuration = (int) Math.ceil(mDuration * mSpeedBoost);
+ if (mHeatOC) {
+ while (mRecipeHeat + HEAT_PERFECT_OVERCLOCK_THRESHOLD <= mMultiHeat
+ && mRecipeEUt * mParallel * mRecipeAmps << 2 < mEUt * mAmps) {
+ if (mDuration < 1) {
+ break;
+ }
+ mRecipeEUt <<= mEUtIncrasePerOC;
+ mDuration >>= mHeatPerfectOC;
+ mRecipeHeat += HEAT_PERFECT_OVERCLOCK_THRESHOLD;
+ }
+ }
+
+ while ((mRecipeEUt * mParallel * mRecipeAmps) << mEUtIncrasePerOC < mEUt * mAmps) {
+ if (mDuration <= 1) {
+ break;
+ }
+ mRecipeEUt <<= mEUtIncrasePerOC;
+ mDuration >>= mDurationDecreasePerOC;
+ }
+
+ if (mDuration < 1) {
+ mDuration = 1;
+ }
+
+ if (mHeatDiscount) {
+ mRecipeEUt = (long) Math.ceil(mRecipeEUt * Math.pow(mHeatDiscountAmount, heatDiscounts));
+ }
+
+ if (mOneTickDiscount) {
+ int voltageDifferece = GT_Utility.getTier(mEUt) - GT_Utility.getTier(mRecipeEUt);
+ mRecipeEUt >>= voltageDifferece * mDurationDecreasePerOC;
+ if (mRecipeEUt < 1) {
+ mRecipeEUt = 1;
+ }
+ }
+
+ mRecipeEUt *= mParallel * mRecipeAmps;
+ }
+
+ /**
+ * @return The consumtipn after overclock has been calculated
+ */
+ public long getConsumption() throws Exception {
+ if (!calculated) {
+ throw new Exception("Tried to get consumption before calculating!");
+ }
+ return mRecipeEUt;
+ }
+
+ /**
+ * @return The duration of the recipe after overclock has been calculated
+ */
+ public int getDuration() throws Exception {
+ if (!calculated) {
+ throw new Exception("Tried to get duration before calculating!");
+ }
+ return mDuration;
+ }
+}
diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_PCBFactory.java b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_PCBFactory.java
index 6d7862909d..94f03f7fe5 100644
--- a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_PCBFactory.java
+++ b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_PCBFactory.java
@@ -48,6 +48,7 @@ import gregtech.api.render.TextureFactory;
import gregtech.api.util.GT_ModHandler;
import gregtech.api.util.GT_Multiblock_Tooltip_Builder;
import gregtech.api.util.GT_OreDictUnificator;
+import gregtech.api.util.GT_OverclockCalculator;
import gregtech.api.util.GT_Recipe;
import gregtech.api.util.GT_Utility;
import gregtech.common.blocks.GT_Block_Casings8;
@@ -527,6 +528,7 @@ public class GT_MetaTileEntity_PCBFactory
}
long voltage = getMaxInputVoltage();
+ long amps = getMaxInputAmps();
int tier = GT_Utility.getTier(voltage);
GT_Recipe tRecipe =
@@ -582,12 +584,23 @@ public class GT_MetaTileEntity_PCBFactory
this.mMaxProgresstime = (int) Math.ceil(tRecipe.mDuration * Math.pow(mRoughnessMultiplier, 2));
if (mOCTier1 || mOCTier2) {
- calculateOverclockedNessMultiInternal(
- (long) Math.ceil(tRecipe.mEUt * aExtraPower),
- (int) Math.ceil(tRecipe.mDuration * Math.pow(mRoughnessMultiplier, 2)),
- aCurrentParallel,
- V[tier],
- mOCTier2);
+ GT_OverclockCalculator calc = new GT_OverclockCalculator()
+ .setRecipeEUt(tRecipe.mEUt)
+ .setDuration(tRecipe.mDuration)
+ .setEUt(voltage)
+ .setAmperage(amps)
+ .setEUtDiscount(aExtraPower)
+ .setSpeedBoost((float) Math.pow(mRoughnessMultiplier, 2));
+ if (mOCTier2) {
+ calc.enablePerfectOC();
+ }
+ calc.calculate();
+ try {
+ this.lEUt = calc.getConsumption();
+ this.mMaxProgresstime = calc.getDuration();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
if (this.lEUt == Long.MAX_VALUE - 1 || this.mProgresstime == Integer.MAX_VALUE - 1) return false;
diff --git a/src/test/java/gregtech/overclock/GT_OverclockCalculator_UnitTest.java b/src/test/java/gregtech/overclock/GT_OverclockCalculator_UnitTest.java
new file mode 100644
index 0000000000..54097d882f
--- /dev/null
+++ b/src/test/java/gregtech/overclock/GT_OverclockCalculator_UnitTest.java
@@ -0,0 +1,453 @@
+package gregtech.overclock;
+
+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 static org.junit.jupiter.api.Assertions.fail;
+
+import gregtech.api.util.GT_OverclockCalculator;
+import org.junit.jupiter.api.Test;
+
+class GT_OverclockCalculator_UnitTest {
+
+ private static final String messageDuration = "Duration Calculated Wrong";
+ private static final String messageEUt = "EUt Calculated Wrong";
+
+ @Test
+ void fullPerfectOverclockEBF_Test() {
+ int heatDiscounts = (1800 * 4) / 900;
+ long correctConsumption = (long) Math.ceil(VP[5] * Math.pow(0.95, heatDiscounts));
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[5])
+ .setDuration(1024)
+ .enableHeatOC()
+ .enableHeatDiscount()
+ .setRecipeHeat(1800)
+ .setMultiHeat(1800 * 5)
+ .calculate();
+ try {
+ assertEquals(1024 >> 8, calculator.getDuration(), messageDuration);
+ assertEquals(correctConsumption, calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void imperfectOverclockEBFWithOneHeatDiscount_Test() {
+ int heatDiscounts = 1;
+ long correctConsumption = (long) Math.ceil(VP[5] * Math.pow(0.95, heatDiscounts));
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[5])
+ .setDuration(1024)
+ .enableHeatOC()
+ .enableHeatDiscount()
+ .setRecipeHeat(1800)
+ .setMultiHeat(2700)
+ .calculate();
+ try {
+ assertEquals(1024 >> 4, calculator.getDuration(), messageDuration);
+ assertEquals(correctConsumption, calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void imperfectOverclockEBFWithoutHeatDiscounts_Test() {
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[5])
+ .setDuration(1024)
+ .enableHeatOC()
+ .enableHeatDiscount()
+ .setRecipeHeat(1800)
+ .setMultiHeat(1800)
+ .calculate();
+ try {
+ assertEquals(1024 >> 4, calculator.getDuration(), messageDuration);
+ assertEquals(VP[5], calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void perfectAndImperfectOverclockEBFWithTwoHeatDiscounts_Test() {
+ int heatDiscounts = 2;
+ long correctConsumption = (long) Math.ceil(VP[5] * Math.pow(0.95, heatDiscounts));
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[5])
+ .setDuration(1024)
+ .enableHeatOC()
+ .enableHeatDiscount()
+ .setRecipeHeat(1800)
+ .setMultiHeat(3600)
+ .calculate();
+ try {
+ assertEquals(1024 >> 5, calculator.getDuration(), messageDuration);
+ assertEquals(correctConsumption, calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void generalImperfectOverclock_Test() {
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[6])
+ .setDuration(1024)
+ .calculate();
+ try {
+ assertEquals(1024 >> 5, calculator.getDuration(), messageDuration);
+ assertEquals(VP[6], calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void generalPerfectOverclock_Test() {
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[6])
+ .setDuration(2048)
+ .enablePerfectOC()
+ .calculate();
+ try {
+ assertEquals(2048 >> 10, calculator.getDuration(), messageDuration);
+ assertEquals(VP[6], calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void weirdHeatEBF_Test() {
+ int heatDiscounts = 3;
+ long correctConsumption = (long) Math.ceil(VP[6] * Math.pow(0.95, heatDiscounts));
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[6])
+ .setDuration(2048)
+ .enableHeatOC()
+ .enableHeatDiscount()
+ .setRecipeHeat(486)
+ .setMultiHeat(3900)
+ .calculate();
+ try {
+ assertEquals(2048 >> 6, calculator.getDuration(), messageDuration);
+ assertEquals(correctConsumption, calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void doubleEnergyHatchOC_Test() {
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[6] + V[6])
+ .setAmperage(2)
+ .setDuration(1024)
+ .calculate();
+ try {
+ assertEquals(1024 >> 6, calculator.getDuration(), messageDuration);
+ assertEquals(VP[7], calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void multiAmpHatchOC_Test() {
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[6])
+ .setAmperage(256)
+ .setDuration(1024)
+ .calculate();
+ try {
+ assertEquals(1024 >> 9, calculator.getDuration(), messageDuration);
+ assertEquals(VP[10], calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void weirdAmpHatchOC_Test() {
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[6])
+ .setAmperage(320)
+ .setDuration(1024)
+ .calculate();
+ try {
+ assertEquals(1024 >> 9, calculator.getDuration(), messageDuration);
+ assertEquals(VP[10], calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void parallelImperfectOC_Test() {
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[8])
+ .setAmperage(4)
+ .setDuration(1024)
+ .setParallel(16)
+ .calculate();
+ try {
+ assertEquals(1024 >> 6, calculator.getDuration(), messageDuration);
+ assertEquals(VP[9], calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void parallelPerfectOC_Test() {
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[8])
+ .setAmperage(4)
+ .setDuration(4096)
+ .setParallel(16)
+ .enablePerfectOC()
+ .calculate();
+ try {
+ assertEquals(4096 >> 12, calculator.getDuration(), messageDuration);
+ assertEquals(VP[9], calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void parallelMultiAmpOC_Test() {
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[6])
+ .setAmperage(320)
+ .setDuration(1024)
+ .setParallel(16)
+ .calculate();
+ try {
+ assertEquals(1024 >> 7, calculator.getDuration(), messageDuration);
+ assertEquals(VP[10], calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void weirdParallelOC_Test() {
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[8])
+ .setDuration(1024)
+ .setParallel(8)
+ .calculate();
+ try {
+ assertEquals(1024 >> 5, calculator.getDuration(), messageDuration);
+ assertEquals(VP[6] * 8, calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void weirdParallelAndAmpsOC_Test() {
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[8])
+ .setAmperage(320)
+ .setDuration(1024)
+ .setParallel(8)
+ .calculate();
+ try {
+ assertEquals(1024 >> 9, calculator.getDuration(), messageDuration);
+ assertEquals(VP[6] * 8 * 256, calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void weirdTimeOC_Test() {
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[6])
+ .setDuration(77)
+ .calculate();
+ try {
+ assertEquals(77 >> 5, calculator.getDuration(), messageDuration);
+ assertEquals(VP[6], calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void stopsCorrectlyWhenOneTicking_Test() {
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[6])
+ .setDuration(1)
+ .calculate();
+ try {
+ assertEquals(1, calculator.getDuration(), messageDuration);
+ assertEquals(VP[1], calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void imperfectOCWithEUtDiscount_Test() {
+ long correctConsumption = (long) Math.ceil(VP[1] * 0.9f) << 10;
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[6])
+ .setEUtDiscount(0.9f)
+ .setDuration(1024)
+ .calculate();
+ try {
+ assertEquals(1024 >> 5, calculator.getDuration(), messageDuration);
+ assertEquals(correctConsumption, calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void perfectOCWithEUtDiscount_Test() {
+ long correctConsumption = (long) Math.ceil(VP[1] * 0.9f) << 10;
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[6])
+ .setEUtDiscount(0.9f)
+ .setDuration(1024)
+ .enablePerfectOC()
+ .calculate();
+
+ try {
+ assertEquals(1024 >> 10, calculator.getDuration(), messageDuration);
+ assertEquals(correctConsumption, calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void imperfectOCWithSpeedBoost_Test() {
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[6])
+ .setSpeedBoost(0.9f)
+ .setDuration(1024)
+ .calculate();
+ try {
+ assertEquals((int) (1024 * 0.9f) >> 5, calculator.getDuration(), messageDuration);
+ assertEquals(VP[6], calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void perfectOCWithSpeedBoost_Test() {
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[6])
+ .setSpeedBoost(0.9f)
+ .setDuration(2048)
+ .enablePerfectOC()
+ .calculate();
+ try {
+ assertEquals((int) (2048 * 0.9f) >> 10, calculator.getDuration(), messageDuration);
+ assertEquals(VP[6], calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void oneTickDiscountTurnsToOne_Test() {
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[6])
+ .setDuration(1)
+ .enableOneTickDiscount()
+ .calculate();
+ try {
+ assertEquals(1, calculator.getDuration(), messageDuration);
+ assertEquals(1, calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void oneTickDiscountImperfectOC_Test() {
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[6])
+ .setSpeedBoost(1.1f)
+ .setDuration(4)
+ .enableOneTickDiscount()
+ .calculate();
+ try {
+ assertEquals(1, calculator.getDuration(), messageDuration);
+ assertEquals(480 >> 3, calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void oneTickDiscountPerfectOC_Test() {
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[6])
+ .setSpeedBoost(1.1f)
+ .setDuration(16)
+ .enablePerfectOC()
+ .enableOneTickDiscount()
+ .calculate();
+ try {
+ assertEquals(1, calculator.getDuration(), messageDuration);
+ assertEquals(480 >> 6, calculator.getConsumption(), messageEUt);
+ } catch (Exception e) {
+ assert fail("There was an exception") != null;
+ }
+ }
+
+ @Test
+ void correctExceptionsWhenNotCalculating_Test() {
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator()
+ .setRecipeEUt(VP[1])
+ .setEUt(V[6])
+ .setSpeedBoost(1.1f)
+ .setDuration(16);
+ try {
+ calculator.getDuration();
+ assert fail("There wasn't exception") != null;
+ } catch (Exception e) {
+ assertEquals("Tried to get duration before calculating!", e.getMessage());
+ }
+ try {
+ calculator.getConsumption();
+ assert fail("There wasn't exception") != null;
+ } catch (Exception e) {
+ assertEquals("Tried to get consumption before calculating!", e.getMessage());
+ }
+ }
+}