diff options
author | BlueWeabo <76872108+BlueWeabo@users.noreply.github.com> | 2023-01-01 23:58:14 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-01 22:58:14 +0100 |
commit | 744834083d4504108be1715d36acd94d71c31a84 (patch) | |
tree | b20bf8c21ec8149aa0988fb7d0125d1944cf6373 /src/main/java/gregtech/api/util | |
parent | 988fd7962d5dbb39980ca248d41317594c2d53c4 (diff) | |
download | GT5-Unofficial-744834083d4504108be1715d36acd94d71c31a84.tar.gz GT5-Unofficial-744834083d4504108be1715d36acd94d71c31a84.tar.bz2 GT5-Unofficial-744834083d4504108be1715d36acd94d71c31a84.zip |
Add a Overclock Calculator for multis and the like to use (#1617)
* add calculator and unit tests
* use math.ceil
* math.ceil everywhere
* add some more unit tests and add onetick discount possibility
* add an exception when trying to get the consumption before calculating
* spotless oops
* convert PCB Factory to use the OC calculator
* fix tests trying for wrong values
* fix copy paste error
* address reviews
* this should be there too.
Diffstat (limited to 'src/main/java/gregtech/api/util')
-rw-r--r-- | src/main/java/gregtech/api/util/GT_OverclockCalculator.java | 269 |
1 files changed, 269 insertions, 0 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; + } +} |