diff options
| author | BlueWeabo <ilia.iliev2005@gmail.com> | 2023-07-28 13:13:57 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-07-28 12:13:57 +0200 |
| commit | 4647e2e8be384582ad09c4f97a4c50dff4e05e4b (patch) | |
| tree | 24093c64b1c8f8e700b12efedb0c197ca8a1a62e /src/main/java/gregtech | |
| parent | c82e45b0aa87ba9e982a770fab08040d9e6d9459 (diff) | |
| download | GT5-Unofficial-4647e2e8be384582ad09c4f97a4c50dff4e05e4b.tar.gz GT5-Unofficial-4647e2e8be384582ad09c4f97a4c50dff4e05e4b.tar.bz2 GT5-Unofficial-4647e2e8be384582ad09c4f97a4c50dff4e05e4b.zip | |
Add more API to ParallelHelper and rework OverclockCalculator (#2185)
* refactor OC calc
* somewhat refactor parallel helper
* fix PA not OCing correctly
no clue why it wasn't using super and then setting the duration again.
* make use of new api to make fusion cleaner
* make batch mode actually dynamic
* add another reason for 0 parallel
* move variables around to try and group them together
* address reviews
* add overclocking past 1 tick by adding parallels
* add null check and make a basic calculator to prevent npe
* check null recipeMap supplier
* address reviews
* addressing of reviews
* make it possible to call some OverclockCalculator methods through static methods
* address reviews
* make sure one doesn't get too many OCs when calculatin under 1 tick
* add api for custom duration under one tick and fix batch mode doing 0 ticking
* fix not calculating duration under 1 tick correctly
* spotless
* try to have correct eut consumption
* address review
* make sure mk5 fusion is said in nei
* fix eutCalculating under one tick way too much and address reviews
* remove roundUp voltage
Diffstat (limited to 'src/main/java/gregtech')
16 files changed, 714 insertions, 372 deletions
diff --git a/src/main/java/gregtech/api/logic/ComplexParallelProcessingLogic.java b/src/main/java/gregtech/api/logic/ComplexParallelProcessingLogic.java index 65d7ea5397..05d39cd02c 100644 --- a/src/main/java/gregtech/api/logic/ComplexParallelProcessingLogic.java +++ b/src/main/java/gregtech/api/logic/ComplexParallelProcessingLogic.java @@ -126,8 +126,8 @@ public class ComplexParallelProcessingLogic { .setFluidInputs(inputFluids[index]) .setAvailableEUt(availableEut[index]) .setMachine(tileEntity, isItemVoidProtected[index], isFluidVoidProtected[index]) - .enableConsumption() - .enableOutputCalculation(); + .setConsumption(true) + .setOutputCalculation(true); helper.build(); diff --git a/src/main/java/gregtech/api/logic/ProcessingLogic.java b/src/main/java/gregtech/api/logic/ProcessingLogic.java index cf3bef97e8..2a2e0e5137 100644 --- a/src/main/java/gregtech/api/logic/ProcessingLogic.java +++ b/src/main/java/gregtech/api/logic/ProcessingLogic.java @@ -53,6 +53,7 @@ public class ProcessingLogic { protected int batchSize = 1; protected float euModifier = 1.0f; protected float speedBoost = 1.0f; + protected boolean amperageOC = true; public ProcessingLogic() {} @@ -228,6 +229,14 @@ public class ProcessingLogic { } /** + * Sets wether the multi should use amperage to OC or not + */ + public ProcessingLogic setAmperageOC(boolean amperageOC) { + this.amperageOC = amperageOC; + return this; + } + + /** * Clears calculated results and provided machine inputs to prepare for the next machine operation. */ public ProcessingLogic clear() { @@ -301,16 +310,17 @@ public class ProcessingLogic { } GT_ParallelHelper helper = createParallelHelper(recipe); - + GT_OverclockCalculator calculator = createOverclockCalculator(recipe); + helper.setCalculator(calculator); helper.build(); - if (helper.getCurrentParallel() <= 0) return CheckRecipeResultRegistry.OUTPUT_FULL; + if (!helper.getResult() + .wasSuccessful()) { + return helper.getResult(); + } calculatedParallels = helper.getCurrentParallel(); - GT_OverclockCalculator calculator = createOverclockCalculator(recipe, helper); - - calculator.calculate(); if (calculator.getConsumption() == Long.MAX_VALUE) { return CheckRecipeResultRegistry.POWER_OVERFLOW; } @@ -346,8 +356,14 @@ public class ProcessingLogic { @Nonnull protected FindRecipeResult findRecipe(@Nullable GT_Recipe_Map map) { if (map == null) return FindRecipeResult.NOT_FOUND; - return map - .findRecipeWithResult(lastRecipe, false, false, availableVoltage, inputFluids, specialSlotItem, inputItems); + return map.findRecipeWithResult( + lastRecipe, + false, + false, + amperageOC ? availableVoltage * availableAmperage : availableVoltage, + inputFluids, + specialSlotItem, + inputItems); } /** @@ -364,8 +380,8 @@ public class ProcessingLogic { .setMaxParallel(maxParallel) .setEUtModifier(euModifier) .enableBatchMode(batchSize) - .enableConsumption() - .enableOutputCalculation(); + .setConsumption(true) + .setOutputCalculation(true); } /** @@ -377,18 +393,31 @@ public class ProcessingLogic { } /** - * Override to tweak overclock logic if needed. + * Use {@link #createOverclockCalculator(GT_Recipe)} */ @Nonnull + @Deprecated protected GT_OverclockCalculator createOverclockCalculator(@Nonnull GT_Recipe recipe, - @Nonnull GT_ParallelHelper helper) { + @Nullable GT_ParallelHelper helper) { + return createOverclockCalculator(recipe); + } + + /** + * Override to tweak overclock logic if needed. + */ + @Nonnull + protected GT_OverclockCalculator createOverclockCalculator(@Nonnull GT_Recipe recipe) { return new GT_OverclockCalculator().setRecipeEUt(recipe.mEUt) - .setParallel((int) Math.floor(helper.getCurrentParallel() / helper.getDurationMultiplierDouble())) - .setDuration(recipe.mDuration) + .setRecipeAmperage( + recipeMapSupplier != null && recipeMapSupplier.get() != null + ? Math.max(recipeMapSupplier.get().mAmperage, 1) + : 1) .setAmperage(availableAmperage) .setEUt(availableVoltage) + .setDuration(recipe.mDuration) .setSpeedBoost(speedBoost) .setEUtDiscount(euModifier) + .setAmperageOC(amperageOC) .setDurationDecreasePerOC(overClockTimeReduction) .setEUtIncreasePerOC(overClockPowerIncrease); } diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_ExtendedPowerMultiBlockBase.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_ExtendedPowerMultiBlockBase.java index 938423012c..5b5c848ad5 100644 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_ExtendedPowerMultiBlockBase.java +++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_ExtendedPowerMultiBlockBase.java @@ -210,8 +210,9 @@ public abstract class GT_MetaTileEntity_ExtendedPowerMultiBlockBase<T extends GT @Override protected void setProcessingLogicPower(ProcessingLogic logic) { - logic.setAvailableVoltage(GT_Utility.roundDownVoltage(getAverageInputVoltage())); + logic.setAvailableVoltage(getAverageInputVoltage()); logic.setAvailableAmperage(getMaxInputAmps()); + logic.setAmperageOC(true); } @Override @@ -295,14 +296,17 @@ public abstract class GT_MetaTileEntity_ExtendedPowerMultiBlockBase<T extends GT return GT_ExoticEnergyInputHelper.getMaxInputVoltageMulti(getExoticAndNormalEnergyHatchList()); } + @Override public long getAverageInputVoltage() { return GT_ExoticEnergyInputHelper.getAverageInputVoltageMulti(getExoticAndNormalEnergyHatchList()); } + @Override public long getMaxInputAmps() { return GT_ExoticEnergyInputHelper.getMaxWorkingInputAmpsMulti(getExoticAndNormalEnergyHatchList()); } + @Override public long getMaxInputEu() { return GT_ExoticEnergyInputHelper.getTotalEuMulti(getExoticAndNormalEnergyHatchList()); } diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java index d427e99d4e..2f84151af9 100644 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java +++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java @@ -786,8 +786,9 @@ public abstract class GT_MetaTileEntity_MultiBlockBase extends MetaTileEntity } protected void setProcessingLogicPower(ProcessingLogic logic) { - logic.setAvailableVoltage(GT_Utility.roundDownVoltage(getMaxInputVoltage())); - logic.setAvailableAmperage(1); + logic.setAvailableVoltage(getAverageInputVoltage()); + logic.setAvailableAmperage(getMaxInputAmps()); + logic.setAmperageOC(mEnergyHatches.size() != 1); } protected int getMaxBatchSize() { @@ -1010,6 +1011,18 @@ public abstract class GT_MetaTileEntity_MultiBlockBase extends MetaTileEntity return rVoltage; } + public long getAverageInputVoltage() { + return GT_ExoticEnergyInputHelper.getAverageInputVoltageMulti(mEnergyHatches); + } + + public long getMaxInputAmps() { + return GT_ExoticEnergyInputHelper.getMaxWorkingInputAmpsMulti(mEnergyHatches); + } + + public long getMaxInputEu() { + return GT_ExoticEnergyInputHelper.getTotalEuMulti(mEnergyHatches); + } + /** * Sums up max input EU/t of energy hatches, amperage included. */ diff --git a/src/main/java/gregtech/api/recipe/check/CheckRecipeResultRegistry.java b/src/main/java/gregtech/api/recipe/check/CheckRecipeResultRegistry.java index 7a2d8661dd..aa129bab86 100644 --- a/src/main/java/gregtech/api/recipe/check/CheckRecipeResultRegistry.java +++ b/src/main/java/gregtech/api/recipe/check/CheckRecipeResultRegistry.java @@ -80,6 +80,10 @@ public final class CheckRecipeResultRegistry { * Progress time overflowed. */ public static final CheckRecipeResult DURATION_OVERFLOW = SimpleCheckRecipeResult.ofFailure("duration_overflow"); + /** + * Machine had an internal error + */ + public static final CheckRecipeResult INTERNAL_ERROR = SimpleCheckRecipeResult.ofFailure("internal_error"); /** * Cannot process recipe because the machine cannot handle required EUt. diff --git a/src/main/java/gregtech/api/util/GT_OverclockCalculator.java b/src/main/java/gregtech/api/util/GT_OverclockCalculator.java index d8948fc265..5b4380028f 100644 --- a/src/main/java/gregtech/api/util/GT_OverclockCalculator.java +++ b/src/main/java/gregtech/api/util/GT_OverclockCalculator.java @@ -1,51 +1,123 @@ package gregtech.api.util; +import java.util.function.Supplier; + import javax.annotation.Nonnull; public class GT_OverclockCalculator { + private static final double LOG4 = Math.log(4); + /** - * 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 + * Voltage the recipe will run at */ - private long mAmps = 1, mEUt = 0, mRecipeEUt = 0, mRecipeAmps = 1; + private long recipeVoltage = 0; + /* + * The amount of amps the recipe needs + */ + private long recipeAmperage = 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 beginning of calculating overclocks, like - * GT++ machines - * mHeatDiscountAmount - The value used for discount final eut per 900 heat + * Voltage of the machine */ - private double mEUtDiscount = 1, mSpeedBoost = 1, mHeatDiscountAmount = 0.95f; + private long machineVoltage = 0; /** - * 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) + * Amperage of the machine */ - private int mEUtIncreasePerOC = 2, mDurationDecreasePerOC = 1, mDuration = 0, mParallel = 1, mRecipeHeat = 0, - mMultiHeat = 0, mHeatPerfectOC = 2; + private long machineAmperage = 1; /** - * mHeatOC - Whether to enable overclocking with heat like the EBF every 1800 heat difference - * mOneTickDiscount - Whether to give EUt Discount when the duration goes below one tick - * calculates - variable to check whether the overclocks have been calculated - * mHeatDiscount - Whether to enable heat discounts every 900 heat difference + * Duration of the recipe */ - private boolean mHeatOC, mOneTickDiscount, calculated, mHeatDiscount; + private int duration = 0; + /** + * The parallel the machine has when trying to overclock + */ + private int parallel = 1; - /** If the OC calculator should only do a given amount of overclocks. Mainly used in fusion reactors */ + /** + * 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 bits should be moved to the right for each 1800 above recipe heat (Used for duration) + */ + private int durationDecreasePerHeatOC = 2; + /** + * 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; + + /** + * Discount for EUt at the beginning of calculating overclocks, like GT++ machines + */ + private double eutDiscount = 1; + /** + * Speeding/Slowing up/down the duration of a recipe at the beginning of calculating overclocks, like + * GT++ machines + */ + private double speedBoost = 1; + + /** + * How much the bits should be moved to the left when it is overclocking (Going up, 2 meaning it is multiplied with + * 4x)- + */ + private int eutIncreasePerOC = 2; + /** + * How much the bits should be moved to the right when its overclocking (Going down, 1 meaning it is halved) + */ + private int durationDecreasePerOC = 1; + /** + * Whether to give EUt Discount when the duration goes below one tick + */ + private boolean oneTickDiscount; + /** + * Whether the multi should use amperage to overclock with an exponent. Incompatible with amperageOC + */ + private boolean laserOC; + /** + * Laser OC's penalty for using high amp lasers for overclocking. Like what the Adv. Assline is doing + */ + private double laserOCPenalty = 0.3; + /** + * Whether the multi should use amperage to overclock normally. Incompatible with laserOC + */ + private boolean amperageOC; + /** + * If the OC calculator should only do a given amount of overclocks. Mainly used in fusion reactors + */ private boolean limitOverclocks; - /** Maximum amount of overclocks to perform, when limitOverclocks = true */ + /** + * Maximum amount of overclocks to perform, when limitOverclocks = true + */ private int maxOverclocks; - /** How many overclocks have been performed */ + /** + * How many overclocks have been performed + */ private int overclockCount; + /** + * How many overclocks were performed with heat out of the overclocks we had + */ + private int heatOverclockCount; + /** + * A supplier, which is used for machines which have a custom way of calculating duration, like Neutron Activator + */ + private Supplier<Double> durationUnderOneTickSupplier; + + /** + * variable to check whether the overclocks have been calculated + */ + private boolean calculated; private static final int HEAT_DISCOUNT_THRESHOLD = 900; private static final int HEAT_PERFECT_OVERCLOCK_THRESHOLD = 1800; @@ -72,42 +144,73 @@ public class GT_OverclockCalculator { public GT_OverclockCalculator() {} /** - * @param aRecipeEUt Sets the Recipe's starting voltage + * Constructor for creating a new calculator with the save values + * + * @param calculator Calculator to copy over + */ + public GT_OverclockCalculator(@Nonnull GT_OverclockCalculator calculator) { + this(); + setRecipeEUt(calculator.recipeVoltage); + setRecipeAmperage(calculator.recipeAmperage); + setEUt(calculator.machineVoltage); + setAmperage(calculator.machineAmperage); + setDuration(calculator.duration); + setParallel(calculator.parallel); + setRecipeHeat(calculator.recipeHeat); + setMachineHeat(calculator.machineHeat); + setHeatPerfectOC(calculator.durationDecreasePerHeatOC); + setHeatOC(calculator.heatOC); + setHeatDiscount(calculator.heatDiscount); + setHeatDiscountMultiplier((float) calculator.heatDiscountExponent); + setEUtDiscount((float) calculator.eutDiscount); + setSpeedBoost((float) calculator.speedBoost); + setEUtIncreasePerOC(calculator.eutIncreasePerOC); + setDurationDecreasePerOC(calculator.durationDecreasePerOC); + setOneTickDiscount(calculator.oneTickDiscount); + setLaserOC(calculator.laserOC); + setLaserOCPenalty(calculator.laserOCPenalty); + setAmperageOC(calculator.amperageOC); + maxOverclocks = calculator.maxOverclocks; + limitOverclocks = calculator.limitOverclocks; + } + + /** + * @param recipeEUt Sets the Recipe's starting voltage */ - public GT_OverclockCalculator setRecipeEUt(long aRecipeEUt) { - mRecipeEUt = aRecipeEUt; + public GT_OverclockCalculator setRecipeEUt(long recipeEUt) { + this.recipeVoltage = recipeEUt; return this; } /** - * @param aEUt Sets the EUt that the multiblock can use. This is the voltage of the multi + * @param machineVoltage Sets the EUt that the machine can use. This is the voltage of the machine */ - public GT_OverclockCalculator setEUt(long aEUt) { - mEUt = aEUt; + public GT_OverclockCalculator setEUt(long machineVoltage) { + this.machineVoltage = machineVoltage; return this; } /** - * @param aDuration Sets the duration of the recipe + * @param duration Sets the duration of the recipe */ - public GT_OverclockCalculator setDuration(int aDuration) { - mDuration = aDuration; + public GT_OverclockCalculator setDuration(int duration) { + this.duration = duration; return this; } /** - * @param aAmps Sets the Amperage that the multi can support + * @param machineAmperage Sets the Amperage that the machine can support */ - public GT_OverclockCalculator setAmperage(long aAmps) { - mAmps = aAmps; + public GT_OverclockCalculator setAmperage(long machineAmperage) { + this.machineAmperage = machineAmperage; return this; } /** - * @param aRecipeAmps Sets the Amperage of the recipe + * @param recipeAmperage Sets the Amperage of the recipe */ - public GT_OverclockCalculator setRecipeAmperage(long aRecipeAmps) { - mRecipeAmps = aRecipeAmps; + public GT_OverclockCalculator setRecipeAmperage(long recipeAmperage) { + this.recipeAmperage = recipeAmperage; return this; } @@ -115,39 +218,63 @@ public class GT_OverclockCalculator { * Enables Perfect OC in calculation */ public GT_OverclockCalculator enablePerfectOC() { - mDurationDecreasePerOC = 2; + this.durationDecreasePerOC = 2; return this; } /** - * Enables calculating overclocking using EBF's perfectOC + * Use {@link #setHeatOC(boolean)} */ + @Deprecated public GT_OverclockCalculator enableHeatOC() { - mHeatOC = true; + return setHeatOC(true); + } + + /** + * Set if we should be calculating overclocking using EBF's perfectOC + */ + public GT_OverclockCalculator setHeatOC(boolean heatOC) { + this.heatOC = heatOC; return this; } /** - * Enables adding a heat discount at the end of calculating an overclock, just like the EBF + * Use {@link #setHeatDiscount(boolean)} */ + @Deprecated public GT_OverclockCalculator enableHeatDiscount() { - mHeatDiscount = true; + return setHeatDiscount(true); + } + + /** + * Sets if we should add a heat discount at the end of calculating an overclock, just like the EBF + */ + public GT_OverclockCalculator setHeatDiscount(boolean heatDiscount) { + this.heatDiscount = heatDiscount; return this; } /** * Sets the starting heat of the recipe */ - public GT_OverclockCalculator setRecipeHeat(int aRecipeHeat) { - mRecipeHeat = aRecipeHeat; + public GT_OverclockCalculator setRecipeHeat(int recipeHeat) { + this.recipeHeat = recipeHeat; return this; } /** - * Sets the heat of the coils on the multi + * Use {@link #setMachineHeat(int)} */ - public GT_OverclockCalculator setMultiHeat(int aMultiHeat) { - mMultiHeat = aMultiHeat; + @Deprecated + public GT_OverclockCalculator setMultiHeat(int machineHeat) { + return setMachineHeat(machineHeat); + } + + /** + * Sets the heat of the coils on the machine + */ + public GT_OverclockCalculator setMachineHeat(int machineHeat) { + this.machineHeat = machineHeat; return this; } @@ -155,7 +282,7 @@ public class GT_OverclockCalculator { * Sets an EUtDiscount. 0.9 is 10% less energy. 1.1 is 10% more energy */ public GT_OverclockCalculator setEUtDiscount(float aEUtDiscount) { - mEUtDiscount = aEUtDiscount; + this.eutDiscount = aEUtDiscount; return this; } @@ -163,7 +290,7 @@ public class GT_OverclockCalculator { * Sets a Speed Boost for the multiblock. 0.9 is 10% faster. 1.1 is 10% slower */ public GT_OverclockCalculator setSpeedBoost(float aSpeedBoost) { - mSpeedBoost = aSpeedBoost; + this.speedBoost = aSpeedBoost; return this; } @@ -171,7 +298,7 @@ public class GT_OverclockCalculator { * Sets the parallel that the multiblock uses */ public GT_OverclockCalculator setParallel(int aParallel) { - mParallel = aParallel; + this.parallel = aParallel; return this; } @@ -179,8 +306,8 @@ public class GT_OverclockCalculator { * 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; + public GT_OverclockCalculator setHeatDiscountMultiplier(float heatDiscountExponent) { + this.heatDiscountExponent = heatDiscountExponent; return this; } @@ -188,8 +315,8 @@ public class GT_OverclockCalculator { * 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; + public GT_OverclockCalculator setHeatPerfectOC(int heatPerfectOC) { + this.durationDecreasePerHeatOC = heatPerfectOC; return this; } @@ -197,7 +324,7 @@ public class GT_OverclockCalculator { * 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) { - mEUtIncreasePerOC = aEUtIncreasePerOC; + this.eutIncreasePerOC = aEUtIncreasePerOC; return this; } @@ -205,17 +332,25 @@ public class GT_OverclockCalculator { * 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; + public GT_OverclockCalculator setDurationDecreasePerOC(int durationDecreasePerOC) { + this.durationDecreasePerOC = durationDecreasePerOC; return this; } /** - * Enables One Tick Discount on EUt based on Duration Decrease Per Overclock. This functions the same as single - * blocks. + * Use {@link #setOneTickDiscount(boolean)} */ + @Deprecated public GT_OverclockCalculator enableOneTickDiscount() { - mOneTickDiscount = true; + return setOneTickDiscount(true); + } + + /** + * Set One Tick Discount on EUt based on Duration Decrease Per Overclock. This functions the same as single + * blocks. + */ + public GT_OverclockCalculator setOneTickDiscount(boolean oneTickDiscount) { + this.oneTickDiscount = oneTickDiscount; return this; } @@ -229,81 +364,137 @@ public class GT_OverclockCalculator { return this; } + public GT_OverclockCalculator setLaserOC(boolean laserOC) { + this.laserOC = laserOC; + return this; + } + + public GT_OverclockCalculator setAmperageOC(boolean amperageOC) { + this.amperageOC = amperageOC; + return this; + } + + 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 + */ + public GT_OverclockCalculator setDurationUnderOneTickSupplier(Supplier<Double> supplier) { + this.durationUnderOneTickSupplier = supplier; + return this; + } + /** * Call this when all values have been put it. */ public GT_OverclockCalculator calculate() { + if (calculated) { + throw new IllegalStateException("Tried to calculate overclocks twice"); + } calculateOverclock(); calculated = true; return this; } private void calculateOverclock() { - if (mRecipeEUt > mEUt || mRecipeHeat > mMultiHeat) { - mRecipeEUt = Long.MAX_VALUE; - mDuration = Integer.MAX_VALUE; - return; + if (laserOC && amperageOC) { + throw new IllegalStateException("Tried to calculate overclock with both laser and amperage overclocking"); } - int heatDiscounts = mHeatDiscount ? (mMultiHeat - mRecipeHeat) / HEAT_DISCOUNT_THRESHOLD : 0; - double heatDiscountMultiplier = Math.pow(mHeatDiscountAmount, heatDiscounts); - mDuration = (int) Math.ceil(mDuration * mSpeedBoost); - if (mHeatOC) { - while (mRecipeHeat + HEAT_PERFECT_OVERCLOCK_THRESHOLD <= mMultiHeat - && (long) Math.ceil(mRecipeEUt * mParallel * mRecipeAmps * mEUtDiscount * heatDiscountMultiplier) << 2 - < mEUt * mAmps) { - if (mDuration < 1) { - break; - } - mRecipeEUt <<= mEUtIncreasePerOC; - mDuration >>= mHeatPerfectOC; - mRecipeHeat += HEAT_PERFECT_OVERCLOCK_THRESHOLD; - } + double heatDiscountMultiplier = calculateHeatDiscountMultiplier(); + duration = (int) Math.ceil(duration * speedBoost); + if (heatOC) { + heatOverclockCount = calculateAmountOfHeatOverclocks(); } - int tRecipeTier = GT_Utility.getTier(mRecipeEUt); - if (tRecipeTier == 0) { - int tTier = GT_Utility.getTier(mEUt); - int tTierDifference = tTier - 1; - long tNextConsumption = ((long) Math - .ceil(mRecipeEUt * mParallel * mRecipeAmps * mEUtDiscount * heatDiscountMultiplier)) - << mEUtIncreasePerOC; - while (tTierDifference > 0 && tNextConsumption < mEUt * mAmps - && (!limitOverclocks || overclockCount++ < maxOverclocks)) { - if (mDuration <= 1) { - break; - } - mRecipeEUt <<= mEUtIncreasePerOC; - mDuration >>= mDurationDecreasePerOC; - tNextConsumption <<= mEUtIncreasePerOC; - tTierDifference--; - } - } else { - long tNextConsumption = ((long) Math - .ceil(mRecipeEUt * mParallel * mRecipeAmps * mEUtDiscount * heatDiscountMultiplier)) - << mEUtIncreasePerOC; - while (tNextConsumption < mEUt * mAmps && (!limitOverclocks || overclockCount++ < maxOverclocks)) { - if (mDuration <= 1) { - break; - } - mRecipeEUt <<= mEUtIncreasePerOC; - mDuration >>= mDurationDecreasePerOC; - tNextConsumption <<= mEUtIncreasePerOC; + double recipePowerTier = calculateRecipePowerTier(heatDiscountMultiplier); + double machinePowerTier = calculateMachinePowerTier(); + // Math.log(a) / Math.log(b) equals to log_b (a) + overclockCount = calculateAmountOfNeededOverclocks(machinePowerTier, recipePowerTier); + if (overclockCount < 0) { + recipeVoltage = Long.MAX_VALUE; + duration = Integer.MAX_VALUE; + return; + } + + overclockCount = limitOverclocks ? Math.min(maxOverclocks, overclockCount) : overclockCount; + heatOverclockCount = Math.min(heatOverclockCount, overclockCount); + recipeVoltage <<= eutIncreasePerOC * overclockCount; + duration >>= durationDecreasePerOC * (overclockCount - heatOverclockCount); + duration >>= durationDecreasePerHeatOC * heatOverclockCount; + if (oneTickDiscount) { + recipeVoltage >>= durationDecreasePerOC * ((int) (machinePowerTier - recipePowerTier - overclockCount)); + if (recipeVoltage < 1) { + recipeVoltage = 1; } } - if (mDuration < 1) { - mDuration = 1; + if (laserOC) { + calculateLaserOC(); } - if (mOneTickDiscount) { - int voltageDifference = GT_Utility.getTier(mEUt) - GT_Utility.getTier(mRecipeEUt); - mRecipeEUt >>= (long) voltageDifference * mDurationDecreasePerOC; - if (mRecipeEUt < 1) { - mRecipeEUt = 1; - } + if (duration < 1) { + duration = 1; } - mRecipeEUt = (long) Math.ceil(mRecipeEUt * mParallel * mRecipeAmps * mEUtDiscount * heatDiscountMult |
