diff --git a/src/main/java/gregtech/api/capability/impl/HeatingCoilRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/HeatingCoilRecipeLogic.java index c54dd77fa27..fd439abf2e6 100644 --- a/src/main/java/gregtech/api/capability/impl/HeatingCoilRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/HeatingCoilRecipeLogic.java @@ -2,12 +2,16 @@ import gregtech.api.capability.IHeatingCoil; import gregtech.api.metatileentity.multiblock.RecipeMapMultiblockController; +import gregtech.api.recipes.Recipe; +import gregtech.api.recipes.logic.OverclockingLogic; import gregtech.api.recipes.recipeproperties.IRecipePropertyStorage; import gregtech.api.recipes.recipeproperties.TemperatureProperty; +import gregtech.api.util.GTUtility; import net.minecraft.util.Tuple; import javax.annotation.Nonnull; +import static gregtech.api.GTValues.ULV; import static gregtech.api.recipes.logic.OverclockingLogic.heatingCoilOverclockingLogic; /** @@ -18,6 +22,36 @@ public class HeatingCoilRecipeLogic extends MultiblockRecipeLogic { public HeatingCoilRecipeLogic(RecipeMapMultiblockController metaTileEntity) { super(metaTileEntity); + if (!(metaTileEntity instanceof IHeatingCoil)) { + throw new IllegalArgumentException("MetaTileEntity must be instanceof IHeatingCoil"); + } + } + + @Override + protected int[] performOverclocking(@Nonnull Recipe recipe) { + // mostly duplicated from AbstractRecipeLogic#performOverclocking(Recipe) + int recipeTier = GTUtility.getTierByVoltage(recipe.getEUt()); + int maximumTier = getOverclockForTier(getMaximumOverclockVoltage()); + + // The maximum number of overclocks is determined by the difference between the tier the recipe is running at, + // and the maximum tier that the machine can overclock to. + int numberOfOCs = maximumTier - recipeTier; + if (recipeTier == ULV) numberOfOCs--; // no ULV overclocking + + // cannot overclock, so return the starting values, but with the EU/t discount + if (numberOfOCs <= 0) { + int requiredTemp = recipe.getProperty(TemperatureProperty.getInstance(), 0); + if (requiredTemp < OverclockingLogic.COIL_EUT_DISCOUNT_TEMPERATURE) { + return new int[]{recipe.getEUt(), recipe.getDuration()}; + } + + int currentTemp = ((IHeatingCoil) metaTileEntity).getCurrentTemperature(); + int amountEUtDiscount = OverclockingLogic.calculateAmountCoilEUtDiscount(currentTemp, requiredTemp); + int discounted = OverclockingLogic.applyCoilEUtDiscount(recipe.getEUt(), amountEUtDiscount); + return new int[]{discounted, recipe.getDuration()}; + } + + return runOverclockingLogic(recipe.getRecipePropertyStorage(), recipe.getEUt(), getMaximumOverclockVoltage(), recipe.getDuration(), numberOfOCs); } @Override @@ -34,6 +68,4 @@ protected int[] runOverclockingLogic(@Nonnull IRecipePropertyStorage propertySto propertyStorage.getRecipePropertyValue(TemperatureProperty.getInstance(), 0) ); } - - } diff --git a/src/main/java/gregtech/api/recipes/logic/OverclockingLogic.java b/src/main/java/gregtech/api/recipes/logic/OverclockingLogic.java index 98522561222..ea647466d53 100644 --- a/src/main/java/gregtech/api/recipes/logic/OverclockingLogic.java +++ b/src/main/java/gregtech/api/recipes/logic/OverclockingLogic.java @@ -13,6 +13,8 @@ public class OverclockingLogic { public static final double STANDARD_OVERCLOCK_DURATION_DIVISOR = ConfigHolder.machines.overclockDivisor; public static final double PERFECT_OVERCLOCK_DURATION_DIVISOR = 4.0; + public static final int COIL_EUT_DISCOUNT_TEMPERATURE = 900; + /** * applies standard logic for overclocking, where each overclock modifies energy and duration * @@ -51,13 +53,32 @@ public static int[] standardOverclockingLogic(int recipeEUt, long maxVoltage, in return new int[]{(int) resultVoltage, (int) resultDuration}; } + /** + * @param providedTemp the temperate provided by the machine + * @param requiredTemp the required temperature of the recipe + * @return the amount of EU/t discounts to apply + */ + public static int calculateAmountCoilEUtDiscount(int providedTemp, int requiredTemp) { + return Math.max(0, (providedTemp - requiredTemp) / COIL_EUT_DISCOUNT_TEMPERATURE); + } + + /** + * @param recipeEUt the EU/t of the recipe + * @param amountEUtDiscount the amount of discounts to apply + * @return the discounted EU/t + */ + public static int applyCoilEUtDiscount(int recipeEUt, int amountEUtDiscount) { + if (amountEUtDiscount < 1) return recipeEUt; + return (int) (recipeEUt * Math.min(1, Math.pow(0.95, amountEUtDiscount))); + } + @Nonnull public static int[] heatingCoilOverclockingLogic(int recipeEUt, long maximumVoltage, int recipeDuration, int maxOverclocks, int currentTemp, int recipeRequiredTemp) { - int amountEUDiscount = Math.max(0, (currentTemp - recipeRequiredTemp) / 900); - int amountPerfectOC = amountEUDiscount / 2; + int amountEUtDiscount = calculateAmountCoilEUtDiscount(currentTemp, recipeRequiredTemp); + int amountPerfectOC = amountEUtDiscount / 2; // apply a multiplicative 95% energy multiplier for every 900k over recipe temperature - recipeEUt *= Math.min(1, Math.pow(0.95, amountEUDiscount)); + recipeEUt = applyCoilEUtDiscount(recipeEUt, amountEUtDiscount); // perfect overclock for every 1800k over recipe temperature if (amountPerfectOC > 0) {