diff options
Diffstat (limited to 'src/main/java')
6 files changed, 202 insertions, 43 deletions
diff --git a/src/main/java/gregtech/api/items/GT_MetaGenerated_Tool.java b/src/main/java/gregtech/api/items/GT_MetaGenerated_Tool.java index 19295c2c43..10b2abe682 100644 --- a/src/main/java/gregtech/api/items/GT_MetaGenerated_Tool.java +++ b/src/main/java/gregtech/api/items/GT_MetaGenerated_Tool.java @@ -354,23 +354,38 @@ public abstract class GT_MetaGenerated_Tool extends GT_MetaBase_Item implements int aBaseEff=(int)(5+getToolCombatDamage(aStack))*1000; int aOptFlow=GT_Utility.safeInt((long)Math.max(Float.MIN_NORMAL, ((GT_MetaGenerated_Tool) aStack.getItem()).getToolStats(aStack).getSpeedMultiplier() * ((GT_MetaGenerated_Tool) aStack.getItem()).getPrimaryMaterial(aStack).mToolSpeed * 50)); - aList.add(tOffset + 0, EnumChatFormatting.WHITE + String.format(transItem("001", "Durability: %s/%s"), "" + EnumChatFormatting.GREEN + (tMaxDamage - getToolDamage(aStack)) + " ", " " + tMaxDamage) + EnumChatFormatting.GRAY); - aList.add(tOffset + 1, EnumChatFormatting.WHITE + String.format(transItem("002", "%s lvl %s"), tMaterial.mLocalizedName + EnumChatFormatting.YELLOW, "" + getHarvestLevel(aStack, "")) + EnumChatFormatting.GRAY); - aList.add(tOffset + 2, EnumChatFormatting.WHITE + String.format(transItem("005", "Turbine Efficiency: %s"), "" + EnumChatFormatting.BLUE + (50.0F + (10.0F * getToolCombatDamage(aStack)))) + EnumChatFormatting.GRAY); - aList.add(tOffset + 3, EnumChatFormatting.WHITE + String.format(transItem("006", "Optimal Steam flow: %sL/t"), "" + EnumChatFormatting.GOLD + Math.max(Float.MIN_NORMAL, tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed * (1000 / 20)) + EnumChatFormatting.GRAY)); - aList.add(tOffset + 4, EnumChatFormatting.WHITE + String.format(transItem("900", "Energy from Optimal Steam Flow: %sEU/t"), "" + EnumChatFormatting.GOLD + Math.max(Float.MIN_NORMAL, tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed * (1000 / 20)) * (50.0F + (10.0F * getToolCombatDamage(aStack))) / 200 + EnumChatFormatting.GRAY)); + aList.add(tOffset + 0, EnumChatFormatting.GRAY + String.format(transItem("001", "Durability: %s/%s"), "" + EnumChatFormatting.GREEN + (tMaxDamage - getToolDamage(aStack)) + " ", " " + tMaxDamage) + EnumChatFormatting.GRAY); + aList.add(tOffset + 1, EnumChatFormatting.GRAY + String.format(transItem("002", "%s lvl %s"), tMaterial.mLocalizedName + EnumChatFormatting.YELLOW, "" + getHarvestLevel(aStack, "")) + EnumChatFormatting.GRAY); + aList.add(tOffset + 2, EnumChatFormatting.WHITE + String.format(transItem("005", "Turbine Efficiency: %s"), "" + EnumChatFormatting.BLUE + (50.0F + (10.0F * getToolCombatDamage(aStack)))) + "%" + EnumChatFormatting.GRAY); + aList.add(tOffset + 3, EnumChatFormatting.WHITE + String.format(transItem("006", "Optimal Steam flow: %s L/t"), "" + EnumChatFormatting.GOLD + GT_Utility.safeInt((long) (Math.max(Float.MIN_NORMAL, tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed * (1000 / 20)))) + EnumChatFormatting.GRAY)); + aList.add(tOffset + 4, EnumChatFormatting.WHITE + String.format(transItem("900", "Energy from Optimal Steam Flow: %s EU/t"), "" + EnumChatFormatting.GOLD + GT_Utility.safeInt((long) (Math.max(Float.MIN_NORMAL, tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed * (1000 / 20)) * (50.0F + (10.0F * getToolCombatDamage(aStack))) / 200)) + EnumChatFormatting.GRAY)); { long[] calculatedFlow = calculateLooseFlow(aOptFlow, aBaseEff); - long aOptFlowLoose = calculatedFlow[0]; - long aBaseEffLoose = calculatedFlow[1]; + int aOptFlowLoose = (int) calculatedFlow[0]; + int aBaseEffLoose = (int) calculatedFlow[1]; + + aList.add(tOffset + 5, EnumChatFormatting.AQUA + String.format(transItem("500", "Turbine Efficiency (Loose): %s"), "" + EnumChatFormatting.BLUE + aBaseEffLoose / 100 + "%" + EnumChatFormatting.GRAY)); + aList.add(tOffset + 6, EnumChatFormatting.AQUA + String.format(transItem("501", "Optimal Steam flow (Loose): %s L/t"), "" + EnumChatFormatting.GOLD + aOptFlowLoose + EnumChatFormatting.GRAY)); + aList.add(tOffset + 7, EnumChatFormatting.AQUA + String.format(transItem("901", "Energy from Optimal Steam Flow (Loose): %s EU/t"), "" + EnumChatFormatting.GOLD + (aOptFlowLoose / 10000) * (aBaseEffLoose / 2) + EnumChatFormatting.GRAY)); + aList.add(tOffset + 8, EnumChatFormatting.GRAY + "(Superheated Steam EU values are 2x those of Steam)"); - aList.add(tOffset + 5, EnumChatFormatting.GRAY + String.format(transItem("500", "Turbine Efficiency (Loose): %s"), "" + EnumChatFormatting.BLUE + aBaseEffLoose / 100 + EnumChatFormatting.DARK_GRAY)); - aList.add(tOffset + 6, EnumChatFormatting.GRAY + String.format(transItem("501", "Optimal Steam flow (Loose): %s L/t"), "" + EnumChatFormatting.GOLD + aOptFlowLoose + EnumChatFormatting.DARK_GRAY)); - aList.add(tOffset + 7, EnumChatFormatting.GRAY + String.format(transItem("901", "Energy from Optimal Steam Flow (Loose): %s EU/t"), "" + EnumChatFormatting.GOLD + (aOptFlowLoose / 10000) * (aBaseEffLoose / 2) + EnumChatFormatting.DARK_GRAY)); } - aList.add(tOffset + 8, EnumChatFormatting.WHITE + String.format(transItem("007", "Energy from Optimal Gas Flow: %sEU/t"), "" + EnumChatFormatting.GOLD + Math.max(Float.MIN_NORMAL, tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed * 50) * (50.0F + (10.0F * getToolCombatDamage(aStack))) / 100 + EnumChatFormatting.GRAY)); - aList.add(tOffset + 9, EnumChatFormatting.WHITE + String.format(transItem("008", "Energy from Optimal Plasma Flow: %sEU/t"), "" + EnumChatFormatting.GOLD + Math.max(Float.MIN_NORMAL, tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed * 2000) * (50.0F + (10.0F * getToolCombatDamage(aStack))) * (1.05 / 100) + EnumChatFormatting.GRAY)); + aList.add(tOffset + 9, EnumChatFormatting.LIGHT_PURPLE + String.format(transItem("007", "Energy from Optimal Gas Flow: %s EU/t"), "" + EnumChatFormatting.GOLD + GT_Utility.safeInt((long) (Math.max(Float.MIN_NORMAL, tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed * 50) * (50.0F + (10.0F * getToolCombatDamage(aStack))) / 100)) + EnumChatFormatting.GRAY)); + aList.add(tOffset + 10, EnumChatFormatting.LIGHT_PURPLE + String.format(transItem("008", "Energy from Optimal Plasma Flow: %s EU/t"), "" + EnumChatFormatting.GOLD + GT_Utility.safeInt((long) (Math.max(Float.MIN_NORMAL, tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed * 2000) * (50.0F + (10.0F * getToolCombatDamage(aStack))) * (1.05 / 100))) + EnumChatFormatting.GRAY)); + aList.add(tOffset + 12, EnumChatFormatting.GRAY + "(EU/t values include efficiency and are not 100% accurate)"); + int toolQualityLevel = GT_MetaGenerated_Tool.getPrimaryMaterial(aStack).mToolQuality; + int overflowMultiplier = 0; + if (toolQualityLevel >= 6) { + overflowMultiplier = 3; + } + else if (toolQualityLevel >= 3) { + overflowMultiplier = 2; + } + else { + overflowMultiplier = 1; + } + aList.add(tOffset + 11, EnumChatFormatting.LIGHT_PURPLE + String.format(transItem("502", "Overflow Efficiency Tier: %s"), "" + EnumChatFormatting.GOLD + overflowMultiplier + EnumChatFormatting.GRAY)); } else { aList.add(tOffset + 0, EnumChatFormatting.WHITE + String.format(transItem("001", "Durability: %s/%s"), "" + EnumChatFormatting.GREEN + (tMaxDamage - getToolDamage(aStack)) + " ", " " + tMaxDamage) + EnumChatFormatting.GRAY); diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_LargeTurbine.java b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_LargeTurbine.java index 2678c3ac72..b5e1db0e6b 100644 --- a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_LargeTurbine.java +++ b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_LargeTurbine.java @@ -58,6 +58,7 @@ public abstract class GT_MetaTileEntity_LargeTurbine extends GT_MetaTileEntity_E protected int storedFluid = 0; protected int counter = 0; protected boolean looseFit = false; + protected int overflowMultiplier = 0; public GT_MetaTileEntity_LargeTurbine(int aID, String aName, String aNameRegional) { super(aID, aName, aNameRegional); @@ -116,6 +117,7 @@ public abstract class GT_MetaTileEntity_LargeTurbine extends GT_MetaTileEntity_E } ArrayList<FluidStack> tFluids = getStoredFluids(); if (tFluids.size() > 0) { + if (baseEff == 0 || optFlow == 0 || counter >= 512 || this.getBaseMetaTileEntity().hasWorkJustBeenEnabled() || this.getBaseMetaTileEntity().hasInventoryBeenModified()) { counter = 0; @@ -124,6 +126,18 @@ public abstract class GT_MetaTileEntity_LargeTurbine extends GT_MetaTileEntity_E ((GT_MetaGenerated_Tool) aStack.getItem()).getToolStats(aStack).getSpeedMultiplier() * GT_MetaGenerated_Tool.getPrimaryMaterial(aStack).mToolSpeed * 50)); + + int toolQualityLevel = GT_MetaGenerated_Tool.getPrimaryMaterial(aStack).mToolQuality; + if (toolQualityLevel >= 6) { + overflowMultiplier = 3; + } + else if (toolQualityLevel >= 3) { + overflowMultiplier = 2; + } + else { + overflowMultiplier = 1; + } + if(optFlow<=0 || baseEff<=0){ stopMachine();//in case the turbine got removed return false; @@ -133,7 +147,7 @@ public abstract class GT_MetaTileEntity_LargeTurbine extends GT_MetaTileEntity_E } } - int newPower = fluidIntoPower(tFluids, optFlow, baseEff); // How much the turbine should be producing with this flow + int newPower = fluidIntoPower(tFluids, optFlow, baseEff, overflowMultiplier); // How much the turbine should be producing with this flow int difference = newPower - this.mEUt; // difference between current output and new output // Magic numbers: can always change by at least 10 eu/t, but otherwise by at most 1 percent of the difference in power level (per tick) @@ -159,7 +173,21 @@ public abstract class GT_MetaTileEntity_LargeTurbine extends GT_MetaTileEntity_E } } - abstract int fluidIntoPower(ArrayList<FluidStack> aFluids, int aOptFlow, int aBaseEff); + abstract int fluidIntoPower(ArrayList<FluidStack> aFluids, int aOptFlow, int aBaseEff, int overflowMultiplier); + + abstract float getOverflowEfficiency(int totalFlow, int actualOptimalFlow, int overflowMultiplier); + + // Gets the maximum output that the turbine currently can handle. Going above this will cause the turbine to explode + public long getMaximumOutput() { + long aTotal = 0; + for (GT_MetaTileEntity_Hatch_Dynamo aDynamo : mDynamoHatches) { + if (isValidMetaTileEntity(aDynamo)) { + long aVoltage = aDynamo.maxEUOutput(); + aTotal = aDynamo.maxAmperesOut() * aVoltage; + } + } + return aTotal; + } @Override public int getDamageToComponent(ItemStack aStack) { diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_LargeTurbine_Gas.java b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_LargeTurbine_Gas.java index 6cd1cd567c..f537fbebb8 100644 --- a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_LargeTurbine_Gas.java +++ b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_LargeTurbine_Gas.java @@ -88,7 +88,7 @@ public class GT_MetaTileEntity_LargeTurbine_Gas extends GT_MetaTileEntity_LargeT } @Override - int fluidIntoPower(ArrayList<FluidStack> aFluids, int aOptFlow, int aBaseEff) { + int fluidIntoPower(ArrayList<FluidStack> aFluids, int aOptFlow, int aBaseEff, int overflowMultiplier) { if (aFluids.size() >= 1) { int tEU = 0; int actualOptimalFlow = 0; @@ -109,14 +109,21 @@ public class GT_MetaTileEntity_LargeTurbine_Gas extends GT_MetaTileEntity_LargeT actualOptimalFlow = GT_Utility.safeInt((long) aOptFlow / fuelValue); this.realOptFlow = actualOptimalFlow; - int remainingFlow = GT_Utility.safeInt((long) (actualOptimalFlow * 1.25f)); // Allowed to use up to 125% of optimal flow. Variable required outside of loop for multi-hatch scenarios. + // Allowed to use up to 450% optimal flow rate, depending on the value of overflowMultiplier. + // This value is chosen because the highest EU/t possible depends on the overflowMultiplier, and the formula used + // makes it so the flow rate for that max, per value of overflowMultiplier, is (percentage of optimal flow rate): + // - 150% if it is 1 + // - 300% if it is 2 + // - 450% if it is 3 + // Variable required outside of loop for multi-hatch scenarios. + int remainingFlow = GT_Utility.safeInt((long) (actualOptimalFlow * (1.5f * overflowMultiplier))); int flow = 0; int totalFlow = 0; storedFluid = 0; for (FluidStack aFluid : aFluids) { if (aFluid.isFluidEqual(firstFuelType)) { - flow = Math.min(aFluid.amount, remainingFlow); // try to use up to 125% of optimal flow w/o exceeding remainingFlow + flow = Math.min(aFluid.amount, remainingFlow); // try to use up to the max flow defined just above depleteInput(new FluidStack(aFluid, flow)); // deplete that amount this.storedFluid += aFluid.amount; remainingFlow -= flow; // track amount we're allowed to continue depleting from hatches @@ -129,16 +136,38 @@ public class GT_MetaTileEntity_LargeTurbine_Gas extends GT_MetaTileEntity_LargeT if (totalFlow == actualOptimalFlow) { tEU = GT_Utility.safeInt((long) tEU * (long) aBaseEff / 10000L); } else { - float efficiency = 1.0f - Math.abs((totalFlow - actualOptimalFlow) / (float) actualOptimalFlow); + float efficiency = getOverflowEfficiency(totalFlow, actualOptimalFlow, overflowMultiplier); tEU *= efficiency; tEU = GT_Utility.safeInt((long) tEU * (long) aBaseEff / 10000L); } + // If next output is above the maximum the dynamo can handle, set it to the maximum instead of exploding the turbine + // Raising the maximum allowed flow rate to account for the efficiency changes beyond the optimal flow rate can explode turbines on world load + if (tEU > getMaximumOutput()){ + tEU = GT_Utility.safeInt(getMaximumOutput()); + } return tEU; } return 0; } + @Override + float getOverflowEfficiency(int totalFlow, int actualOptimalFlow, int overflowMultiplier) { + // overflowMultiplier changes how quickly the turbine loses efficiency after flow goes beyond the optimal value + // At the default value of 1, any flow will generate less EU/t than optimal flow, regardless of the amount of fuel used + // The bigger this number is, the slower efficiency loss happens as flow moves beyond the optimal value + // Gases are the second most efficient in this regard, with plasma being the most efficient + float efficiency = 0; + + if (totalFlow > actualOptimalFlow) { + efficiency = 1.0f - Math.abs((totalFlow - actualOptimalFlow)) / ((float) actualOptimalFlow * ((overflowMultiplier * 3) - 1)); + } + else { + efficiency = 1.0f - Math.abs((totalFlow - actualOptimalFlow) / (float) actualOptimalFlow); + } + + return efficiency; + } } diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_LargeTurbine_HPSteam.java b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_LargeTurbine_HPSteam.java index 69e5a784a0..ab7c08513f 100644 --- a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_LargeTurbine_HPSteam.java +++ b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_LargeTurbine_HPSteam.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import static gregtech.api.enums.Textures.BlockIcons.*; import static gregtech.api.objects.XSTR.XSTR_INSTANCE; +import static gregtech.common.tileentities.machines.multi.GT_MetaTileEntity_LargeTurbine_Steam.calculateLooseFlow; public class GT_MetaTileEntity_LargeTurbine_HPSteam extends GT_MetaTileEntity_LargeTurbine { @@ -83,30 +84,31 @@ public class GT_MetaTileEntity_LargeTurbine_HPSteam extends GT_MetaTileEntity_La } @Override - int fluidIntoPower(ArrayList<FluidStack> aFluids, int aOptFlow, int aBaseEff) { + int fluidIntoPower(ArrayList<FluidStack> aFluids, int aOptFlow, int aBaseEff, int overflowEfficiency) { if (looseFit) { - aOptFlow *= 4; - if (aBaseEff > 10000) { - aOptFlow *= Math.pow(1.1f, ((aBaseEff - 7500) / 10000F) * 20f); - aBaseEff = 7500; - } else if (aBaseEff > 7500) { - aOptFlow *= Math.pow(1.1f, ((aBaseEff - 7500) / 10000F) * 20f); - aBaseEff *= 0.75f; - } else { - aBaseEff *= 0.75f; - } + long[] calculatedFlow = calculateLooseFlow(aOptFlow, aBaseEff); + aOptFlow = GT_Utility.safeInt(calculatedFlow[0]); + aBaseEff = GT_Utility.safeInt(calculatedFlow[1]); } int tEU = 0; int totalFlow = 0; // Byproducts are based on actual flow int flow = 0; - int remainingFlow = GT_Utility.safeInt((long) (aOptFlow * 1.25f)); // Allowed to use up to 125% of optimal flow. Variable required outside of loop for multi-hatch scenarios. + + // Allowed to use up to 300% optimal flow rate, depending on the value of overflowMultiplier. + // This value is chosen because the highest EU/t possible depends on the overflowMultiplier, and the formula used + // makes it so the flow rate for that max, per value of overflowMultiplier, is (percentage of optimal flow rate): + // - 200% if it is 1 + // - 250% if it is 2 + // - 300% if it is 3 + // Variable required outside of loop for multi-hatch scenarios. + int remainingFlow = GT_Utility.safeInt((long) (aOptFlow * (0.5f * overflowMultiplier + 1.5))); this.realOptFlow = aOptFlow; storedFluid = 0; for (int i = 0; i < aFluids.size() && remainingFlow > 0; i++) { final FluidStack aFluidStack = aFluids.get(i); if (GT_ModHandler.isSuperHeatedSteam(aFluidStack)) { - flow = Math.min(aFluidStack.amount, remainingFlow); // try to use up w/o exceeding remainingFlow + flow = Math.min(aFluidStack.amount, remainingFlow); // try to use up to the max flow defined just above depleteInput(new FluidStack(aFluidStack, flow)); // deplete that amount this.storedFluid += aFluidStack.amount; remainingFlow -= flow; // track amount we're allowed to continue depleting from hatches @@ -128,16 +130,39 @@ public class GT_MetaTileEntity_LargeTurbine_HPSteam extends GT_MetaTileEntity_La if (totalFlow == aOptFlow) { tEU = GT_Utility.safeInt((long) tEU * (long) aBaseEff / 10000L); } else { - float efficiency = 1.0f - Math.abs((totalFlow - aOptFlow) / (float) aOptFlow); - //if(totalFlow>aOptFlow){efficiency = 1.0f;} + float efficiency = getOverflowEfficiency(totalFlow, aOptFlow, overflowMultiplier); tEU *= efficiency; tEU = Math.max(1, GT_Utility.safeInt((long) tEU * (long) aBaseEff / 10000L)); } + // If next output is above the maximum the dynamo can handle, set it to the maximum instead of exploding the turbine + // Raising the maximum allowed flow rate to account for the efficiency changes beyond the optimal flow rate can explode turbines on world load + if (tEU > getMaximumOutput()){ + tEU = GT_Utility.safeInt(getMaximumOutput()); + } + return tEU; } @Override + float getOverflowEfficiency(int totalFlow, int actualOptimalFlow, int overflowMultiplier) { + // overflowMultiplier changes how quickly the turbine loses efficiency after flow goes beyond the optimal value + // At the default value of 1, any flow will generate less EU/t than optimal flow, regardless of the amount of fuel used + // The bigger this number is, the slower efficiency loss happens as flow moves beyond the optimal value + // Superheated steam is the second least efficient out of all turbine fuels in this regard, with steam being the least efficient + float efficiency = 0; + + if (totalFlow > actualOptimalFlow) { + efficiency = 1.0f - Math.abs((totalFlow - actualOptimalFlow)) / ((float) actualOptimalFlow * (overflowMultiplier + 2)); + } + else { + efficiency = 1.0f - Math.abs((totalFlow - actualOptimalFlow) / (float) actualOptimalFlow); + } + + return efficiency; + } + + @Override public void onScrewdriverRightClick(byte aSide, EntityPlayer aPlayer, float aX, float aY, float aZ) { if (aSide == getBaseMetaTileEntity().getFrontFacing()) { looseFit ^= true; diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_LargeTurbine_Plasma.java b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_LargeTurbine_Plasma.java index 8a5616dafd..17cba19242 100644 --- a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_LargeTurbine_Plasma.java +++ b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_LargeTurbine_Plasma.java @@ -89,7 +89,7 @@ public class GT_MetaTileEntity_LargeTurbine_Plasma extends GT_MetaTileEntity_Lar } @Override - int fluidIntoPower(ArrayList<FluidStack> aFluids, int aOptFlow, int aBaseEff) { + int fluidIntoPower(ArrayList<FluidStack> aFluids, int aOptFlow, int aBaseEff, int overflowMultiplier) { if (aFluids.size() >= 1) { aOptFlow *= 800;//CHANGED THINGS HERE, check recipe runs once per 20 ticks int tEU = 0; @@ -101,14 +101,21 @@ public class GT_MetaTileEntity_LargeTurbine_Plasma extends GT_MetaTileEntity_Lar actualOptimalFlow = GT_Utility.safeInt((long) Math.ceil((double) aOptFlow / (double) fuelValue)); this.realOptFlow = actualOptimalFlow; // For scanner info - int remainingFlow = GT_Utility.safeInt((long) (actualOptimalFlow * 1.25f)); // Allowed to use up to 125% of optimal flow. Variable required outside of loop for multi-hatch scenarios. + // Allowed to use up to 550% optimal flow rate, depending on the value of overflowMultiplier. + // This value is chosen because the highest EU/t possible depends on the overflowMultiplier, and the formula used + // makes it so the flow rate for that max, per value of overflowMultiplier, is (percentage of optimal flow rate): + // - 250% if it is 1 + // - 400% if it is 2 + // - 550% if it is 3 + // Variable required outside of loop for multi-hatch scenarios. + int remainingFlow = GT_Utility.safeInt((long) (actualOptimalFlow * (1.5f * overflowMultiplier + 1))); int flow = 0; int totalFlow = 0; storedFluid = 0; for (FluidStack aFluid : aFluids) { if (aFluid.isFluidEqual(firstFuelType)) { - flow = Math.min(aFluid.amount, remainingFlow); // try to use up w/o exceeding remainingFlow + flow = Math.min(aFluid.amount, remainingFlow); // try to use up to the max flow defined just above depleteInput(new FluidStack(aFluid, flow)); // deplete that amount this.storedFluid += aFluid.amount; remainingFlow -= flow; // track amount we're allowed to continue depleting from hatches @@ -135,12 +142,17 @@ public class GT_MetaTileEntity_LargeTurbine_Plasma extends GT_MetaTileEntity_Lar if (totalFlow == actualOptimalFlow) { tEU = GT_Utility.safeInt((long) (aBaseEff / 10000D * tEU)); } else { - double efficiency = 1.0D - Math.abs((totalFlow - actualOptimalFlow) / (float) actualOptimalFlow); - + float efficiency = getOverflowEfficiency(totalFlow, actualOptimalFlow, overflowMultiplier); tEU = (int) (tEU * efficiency); tEU = GT_Utility.safeInt((long) (aBaseEff / 10000D * tEU)); } + // If next output is above the maximum the dynamo can handle, set it to the maximum instead of exploding the turbine + // Raising the maximum allowed flow rate to account for the efficiency changes beyond the optimal flow rate can explode turbines on world load + if (tEU > getMaximumOutput()){ + tEU = GT_Utility.safeInt(getMaximumOutput()); + } + return tEU; } @@ -148,6 +160,24 @@ public class GT_MetaTileEntity_LargeTurbine_Plasma extends GT_MetaTileEntity_Lar } @Override + float getOverflowEfficiency(int totalFlow, int actualOptimalFlow, int overflowMultiplier) { + // overflowMultiplier changes how quickly the turbine loses efficiency after flow goes beyond the optimal value + // At the default value of 1, any flow will generate less EU/t than optimal flow, regardless of the amount of fuel used + // The bigger this number is, the slower efficiency loss happens as flow moves beyond the optimal value + // Plasmas are the most efficient out of all turbine fuels in this regard + float efficiency = 0; + + if (totalFlow > actualOptimalFlow) { + efficiency = 1.0f - Math.abs((totalFlow - actualOptimalFlow)) / ((float) actualOptimalFlow * ((overflowMultiplier * 3) + 1)); + } + else { + efficiency = 1.0f - Math.abs((totalFlow - actualOptimalFlow) / (float) actualOptimalFlow); + } + + return efficiency; + } + + @Override public boolean checkRecipe(ItemStack aStack) { if ((counter & 7) == 0 && (aStack == null || !(aStack.getItem() instanceof GT_MetaGenerated_Tool) || aStack.getItemDamage() < 170 || aStack.getItemDamage() > 179)) { stopMachine(); @@ -173,7 +203,7 @@ public class GT_MetaTileEntity_LargeTurbine_Plasma extends GT_MetaTileEntity_Lar return false; } - int newPower = fluidIntoPower(tFluids, optFlow, baseEff); // How much the turbine should be producing with this flow + int newPower = fluidIntoPower(tFluids, optFlow, baseEff, overflowMultiplier); // How much the turbine should be producing with this flow int difference = newPower - this.mEUt; // difference between current output and new output diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_LargeTurbine_Steam.java b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_LargeTurbine_Steam.java index 86ed51e879..bf9f3bfdbf 100644 --- a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_LargeTurbine_Steam.java +++ b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_LargeTurbine_Steam.java @@ -93,7 +93,7 @@ public class GT_MetaTileEntity_LargeTurbine_Steam extends GT_MetaTileEntity_Larg } @Override - int fluidIntoPower(ArrayList<FluidStack> aFluids, int aOptFlow, int aBaseEff) { + int fluidIntoPower(ArrayList<FluidStack> aFluids, int aOptFlow, int aBaseEff, int overflowEfficiency) { if (looseFit) { long[] calculatedFlow = calculateLooseFlow(aOptFlow, aBaseEff); aOptFlow = GT_Utility.safeInt(calculatedFlow[0]); @@ -102,14 +102,22 @@ public class GT_MetaTileEntity_LargeTurbine_Steam extends GT_MetaTileEntity_Larg int tEU = 0; int totalFlow = 0; // Byproducts are based on actual flow int flow = 0; - int remainingFlow = GT_Utility.safeInt((long) (aOptFlow * 1.25f)); // Allowed to use up to 125% of optimal flow. Variable required outside of loop for multi-hatch scenarios. + + // Allowed to use up to 250% optimal flow rate, depending on the value of overflowMultiplier. + // This value is chosen because the highest EU/t possible depends on the overflowMultiplier, and the formula used + // makes it so the flow rate for that max, per value of overflowMultiplier, is (percentage of optimal flow rate): + // - 150% if it is 1 + // - 200% if it is 2 + // - 250% if it is 3 + // Variable required outside of loop for multi-hatch scenarios. + int remainingFlow = GT_Utility.safeInt((long) (aOptFlow * (0.5f * overflowMultiplier + 1))); this.realOptFlow = aOptFlow; storedFluid = 0; for (int i = 0; i < aFluids.size() && remainingFlow > 0; i++) { // loop through each hatch; extract inputs and track totals. final FluidStack aFluidStack = aFluids.get(i); if (GT_ModHandler.isAnySteam(aFluidStack)) { - flow = Math.min(aFluidStack.amount, remainingFlow); // try to use up w/o exceeding remainingFlow + flow = Math.min(aFluidStack.amount, remainingFlow); // try to use up to the max flow defined just above depleteInput(new FluidStack(aFluidStack, flow)); // deplete that amount this.storedFluid += aFluidStack.amount; remainingFlow -= flow; // track amount we're allowed to continue depleting from hatches @@ -129,14 +137,38 @@ public class GT_MetaTileEntity_LargeTurbine_Steam extends GT_MetaTileEntity_Larg if (totalFlow == aOptFlow) { tEU = GT_Utility.safeInt((long) tEU * (long) aBaseEff / 20000L); } else { - float efficiency = 1.0f - Math.abs((totalFlow - aOptFlow) / (float) aOptFlow); + float efficiency = getOverflowEfficiency(totalFlow, aOptFlow, overflowMultiplier); tEU *= efficiency; tEU = Math.max(1, GT_Utility.safeInt((long) tEU * (long) aBaseEff / 20000L)); } + // If next output is above the maximum the dynamo can handle, set it to the maximum instead of exploding the turbine + // Raising the maximum allowed flow rate to account for the efficiency changes beyond the optimal flow rate can explode turbines on world load + if (tEU > getMaximumOutput()){ + tEU = GT_Utility.safeInt(getMaximumOutput()); + } + return tEU; } + @Override + float getOverflowEfficiency(int totalFlow, int actualOptimalFlow, int overflowMultiplier) { + // overflowMultiplier changes how quickly the turbine loses efficiency after flow goes beyond the optimal value + // At the default value of 1, any flow will generate less EU/t than optimal flow, regardless of the amount of fuel used + // The bigger this number is, the slower efficiency loss happens as flow moves beyond the optimal value + // Steam is the least efficient out of all turbine fuels in this regard + float efficiency = 0; + + if (totalFlow > actualOptimalFlow) { + efficiency = 1.0f - Math.abs((totalFlow - actualOptimalFlow)) / ((float) actualOptimalFlow * (overflowMultiplier + 1)); + } + else { + efficiency = 1.0f - Math.abs((totalFlow - actualOptimalFlow) / (float) actualOptimalFlow); + } + + return efficiency; + } + public static long[] calculateLooseFlow(int aOptFlow, int aBaseEff) { aOptFlow *= 4; if(aBaseEff>=26000) { |