Skip to content

Commit

Permalink
Limit multiblock recipe tier by energy hatches (#2139)
Browse files Browse the repository at this point in the history
  • Loading branch information
serenibyss authored Nov 26, 2023
1 parent 0e716f8 commit 91aa525
Show file tree
Hide file tree
Showing 21 changed files with 180 additions and 120 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public AbstractRecipeLogic(MetaTileEntity tileEntity, RecipeMap<?> recipeMap, bo
/**
* @return the maximum voltage the machine can use/handle for recipe searching
*/
protected abstract long getMaxVoltage();
public abstract long getMaxVoltage();

/**
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ protected boolean drawEnergy(int recipeEUt, boolean simulate) {
}

@Override
protected long getMaxVoltage() {
public long getMaxVoltage() {
GTLog.logger.error("Large Boiler called getMaxVoltage(), this should not be possible!");
return 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,32 @@ public class EnergyContainerList implements IEnergyContainer {
private final long inputAmperage;
private final long outputAmperage;

/** The highest single energy container's input voltage in the list. */
private final long highestInputVoltage;
/** The number of energy containers at the highest input voltage in the list. */
private final int numHighestInputContainers;

public EnergyContainerList(@Nonnull List<IEnergyContainer> energyContainerList) {
this.energyContainerList = energyContainerList;
long totalInputVoltage = 0;
long totalOutputVoltage = 0;
long inputAmperage = 0;
long outputAmperage = 0;
long highestInputVoltage = 0;
int numHighestInputContainers = 0;
for (IEnergyContainer container : energyContainerList) {
totalInputVoltage += container.getInputVoltage() * container.getInputAmperage();
totalOutputVoltage += container.getOutputVoltage() * container.getOutputAmperage();
inputAmperage += container.getInputAmperage();
outputAmperage += container.getOutputAmperage();
if (container.getInputVoltage() > highestInputVoltage) {
highestInputVoltage = container.getInputVoltage();
}
}
for (IEnergyContainer container : energyContainerList) {
if (container.getInputVoltage() == highestInputVoltage) {
numHighestInputContainers++;
}
}

long[] voltageAmperage = calculateVoltageAmperage(totalInputVoltage, inputAmperage);
Expand All @@ -33,6 +48,8 @@ public EnergyContainerList(@Nonnull List<IEnergyContainer> energyContainerList)
voltageAmperage = calculateVoltageAmperage(totalOutputVoltage, outputAmperage);
this.outputVoltage = voltageAmperage[0];
this.outputAmperage = voltageAmperage[1];
this.highestInputVoltage = highestInputVoltage;
this.numHighestInputContainers = numHighestInputContainers;
}

/**
Expand Down Expand Up @@ -163,6 +180,16 @@ public long getEnergyCapacity() {
return energyCapacity;
}

/** The highest single voltage of an energy container in this list. */
public long getHighestInputVoltage() {
return highestInputVoltage;
}

/** The number of parts with voltage specified in {@link EnergyContainerList#getHighestInputVoltage()} in this list. */
public int getNumHighestInputContainers() {
return numHighestInputContainers;
}

/**
* Always < 4. A list with amps > 4 will always be compacted into more voltage at fewer amps.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,31 @@ protected void modifyOverclockPost(int[] overclockResults, @Nonnull IRecipePrope

@Override
public long getMaximumOverclockVoltage() {
return getMaxVoltage();
IEnergyContainer energyContainer = getEnergyContainer();
if (energyContainer instanceof EnergyContainerList) {
long voltage;
long amperage;
if (energyContainer.getInputVoltage() > energyContainer.getOutputVoltage()) {
voltage = energyContainer.getInputVoltage();
amperage = energyContainer.getInputAmperage();
} else {
voltage = energyContainer.getOutputVoltage();
amperage = energyContainer.getOutputAmperage();
}

if (amperage == 1) {
// amperage is 1 when the energy is not exactly on a tier

// the voltage for recipe search is always on tier, so take the closest lower tier
return GTValues.V[GTUtility.getFloorTierByVoltage(voltage)];
} else {
// amperage != 1 means the voltage is exactly on a tier
// ignore amperage, since only the voltage is relevant for recipe search
// amps are never > 3 in an EnergyContainerList
return voltage;
}
}
return Math.max(energyContainer.getInputVoltage(), energyContainer.getOutputVoltage());
}

@Nonnull
Expand Down Expand Up @@ -370,32 +394,35 @@ protected boolean drawEnergy(int recipeEUt, boolean simulate) {
}

@Override
protected long getMaxVoltage() {
public long getMaxVoltage() {
IEnergyContainer energyContainer = getEnergyContainer();
if (energyContainer instanceof EnergyContainerList) {
long voltage;
long amperage;
if (energyContainer.getInputVoltage() > energyContainer.getOutputVoltage()) {
voltage = energyContainer.getInputVoltage();
amperage = energyContainer.getInputAmperage();
} else {
voltage = energyContainer.getOutputVoltage();
amperage = energyContainer.getOutputAmperage();
}

if (amperage == 1) {
// amperage is 1 when the energy is not exactly on a tier

// the voltage for recipe search is always on tier, so take the closest lower tier
if (!consumesEnergy()) {
// Generators
long voltage = energyContainer.getOutputVoltage();
long amperage = energyContainer.getOutputAmperage();
if (energyContainer instanceof EnergyContainerList && amperage == 1) {
// Amperage is 1 when the energy is not exactly on a tier.
// The voltage for recipe search is always on tier, so take the closest lower tier.
// List check is done because single hatches will always be a "clean voltage," no need
// for any additional checks.
return GTValues.V[GTUtility.getFloorTierByVoltage(voltage)];
}
return voltage;
} else {
// Machines
if (energyContainer instanceof EnergyContainerList energyList) {
long highestVoltage = energyList.getHighestInputVoltage();
if (energyList.getNumHighestInputContainers() > 1) {
// allow tier + 1 if there are multiple hatches present at the highest tier
int tier = GTUtility.getTierByVoltage(highestVoltage);
return GTValues.V[Math.min(tier + 1, GTValues.MAX)];
} else {
return highestVoltage;
}
} else {
// amperage != 1 means the voltage is exactly on a tier
// ignore amperage, since only the voltage is relevant for recipe search
// amps are never > 3 in an EnergyContainerList
return voltage;
return energyContainer.getInputVoltage();
}
}
return Math.max(energyContainer.getInputVoltage(), energyContainer.getOutputVoltage());
}

@Nullable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ protected boolean drawEnergy(int recipeEUt, boolean simulate) {
}

@Override
protected long getMaxVoltage() {
public long getMaxVoltage() {
return GTValues.LV;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ protected boolean drawEnergy(int recipeEUt, boolean simulate) {
}

@Override
protected long getMaxVoltage() {
public long getMaxVoltage() {
return Math.max(energyContainer.get().getInputVoltage(),
energyContainer.get().getOutputVoltage());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ protected boolean drawEnergy(int recipeEUt, boolean simulate) {
}

@Override
protected long getMaxVoltage() {
public long getMaxVoltage() {
return GTValues.V[GTValues.LV];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ protected boolean drawEnergy(int recipeEUt, boolean simulate) {
}

@Override
protected long getMaxVoltage() {
public long getMaxVoltage() {
return GTValues.V[GTValues.LV];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,35 @@ public Builder addEnergyUsageLine(IEnergyContainer energyContainer) {
// wrap in text component to keep it from being formatted
ITextComponent voltageName = new TextComponentString(GTValues.VNF[GTUtility.getFloorTierByVoltage(maxVoltage)]);

textList.add(TextComponentUtil.translationWithColor(
ITextComponent bodyText = TextComponentUtil.translationWithColor(
TextFormatting.GRAY,
"gregtech.multiblock.max_energy_per_tick",
energyFormatted, voltageName));
energyFormatted, voltageName);
ITextComponent hoverText = TextComponentUtil.translationWithColor(TextFormatting.GRAY, "gregtech.multiblock.max_energy_per_tick_hover");
textList.add(TextComponentUtil.setHover(bodyText, hoverText));
}
return this;
}

/**
* Adds the max Recipe Tier that this multiblock can use for recipe lookup.
* <br>
* Added if the structure is formed and if the passed tier is a valid energy tier index for {@link GTValues#VNF}.
*/
public Builder addEnergyTierLine(int tier) {
if (!isStructureFormed) return this;
if (tier < GTValues.ULV || tier > GTValues.MAX) return this;

ITextComponent voltageName = new TextComponentString(GTValues.VNF[tier]);
ITextComponent bodyText = TextComponentUtil.translationWithColor(
TextFormatting.GRAY,
"gregtech.multiblock.max_recipe_tier",
voltageName);
ITextComponent hoverText = TextComponentUtil.translationWithColor(TextFormatting.GRAY, "gregtech.multiblock.max_recipe_tier_hover");
textList.add(TextComponentUtil.setHover(bodyText, hoverText));
return this;
}

/**
* Adds the exact EU/t that this multiblock needs to run.
* <br>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ protected void addDisplayText(List<ITextComponent> textList) {
MultiblockDisplayText.builder(textList, isStructureFormed())
.setWorkingStatus(recipeMapWorkable.isWorkingEnabled(), recipeMapWorkable.isActive())
.addEnergyUsageLine(recipeMapWorkable.getEnergyContainer())
.addEnergyTierLine(GTUtility.getTierByVoltage(recipeMapWorkable.getMaxVoltage()))
.addParallelsLine(recipeMapWorkable.getParallelLimit())
.addWorkingStatusLine()
.addProgressLine(recipeMapWorkable.getProgressPercent());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import gregtech.api.pattern.PatternMatchContext;
import gregtech.api.recipes.RecipeMaps;
import gregtech.api.recipes.recipeproperties.IRecipePropertyStorage;
import gregtech.api.util.GTUtility;
import gregtech.api.util.TextComponentUtil;
import gregtech.client.renderer.ICubeRenderer;
import gregtech.client.renderer.texture.Textures;
Expand Down Expand Up @@ -80,6 +81,7 @@ protected void addDisplayText(List<ITextComponent> textList) {
MultiblockDisplayText.builder(textList, isStructureFormed())
.setWorkingStatus(recipeMapWorkable.isWorkingEnabled(), recipeMapWorkable.isActive())
.addEnergyUsageLine(getEnergyContainer())
.addEnergyTierLine(GTUtility.getTierByVoltage(recipeMapWorkable.getMaxVoltage()))
.addCustom(tl -> {
// Coil energy discount line
if (isStructureFormed()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ protected void addDisplayText(List<ITextComponent> textList) {
MultiblockDisplayText.builder(textList, isStructureFormed())
.setWorkingStatus(recipeMapWorkable.isWorkingEnabled(), recipeMapWorkable.isActive())
.addEnergyUsageLine(getEnergyContainer())
.addEnergyTierLine(GTUtility.getTierByVoltage(recipeMapWorkable.getMaxVoltage()))
.addCustom(tl -> {
// Coil heat capacity line
if (isStructureFormed()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ protected double getOverclockingVoltageMultiplier() {
}

@Override
protected long getMaxVoltage() {
public long getMaxVoltage() {
return Math.min(GTValues.V[tier], super.getMaxVoltage());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import gregtech.api.recipes.RecipeBuilder;
import gregtech.api.recipes.RecipeMaps;
import gregtech.api.recipes.machines.RecipeMapFurnace;
import gregtech.api.util.GTUtility;
import gregtech.api.util.TextComponentUtil;
import gregtech.api.util.TextFormattingUtil;
import gregtech.client.renderer.ICubeRenderer;
Expand Down Expand Up @@ -50,6 +51,7 @@ protected void addDisplayText(List<ITextComponent> textList) {
MultiblockDisplayText.builder(textList, isStructureFormed())
.setWorkingStatus(recipeMapWorkable.isWorkingEnabled(), recipeMapWorkable.isActive())
.addEnergyUsageLine(recipeMapWorkable.getEnergyContainer())
.addEnergyTierLine(GTUtility.getTierByVoltage(recipeMapWorkable.getMaxVoltage()))
.addCustom(tl -> {
if (isStructureFormed()) {
// Heating coil discount
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,14 @@ public ICubeRenderer getBaseTexture(IMultiblockPart sourcePart) {

@Override
protected void addDisplayText(List<ITextComponent> textList) {
ProcessingArrayWorkable logic = (ProcessingArrayWorkable) recipeMapWorkable;

MultiblockDisplayText.builder(textList, isStructureFormed())
.setWorkingStatus(recipeMapWorkable.isWorkingEnabled(), recipeMapWorkable.isActive())
.addEnergyUsageLine(recipeMapWorkable.getEnergyContainer())
.addEnergyTierLine(logic.currentMachineStack == ItemStack.EMPTY ? -1 : logic.machineTier)
.addCustom(tl -> {
if (isStructureFormed()) {
ProcessingArrayWorkable logic = (ProcessingArrayWorkable) recipeMapWorkable;

// Machine mode text
// Shared text components for both states
Expand Down Expand Up @@ -357,6 +359,13 @@ protected Recipe findRecipe(long maxVoltage, IItemHandlerModifiable inputs, IMul
return super.findRecipe(Math.min(super.getMaxVoltage(), this.machineVoltage), inputs, fluidInputs);
}

@Override
public long getMaxVoltage() {
// Allow the PA to use as much power as provided, since tier is gated by the machine anyway.
// UI text uses the machine stack's tier instead of the getMaxVoltage() tier as well.
return super.getMaximumOverclockVoltage();
}

@Override
protected int getNumberOfOCs(int recipeEUt) {
if (!isAllowOverclocking()) return 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import gregtech.api.pattern.PatternMatchContext;
import gregtech.api.recipes.RecipeMaps;
import gregtech.api.recipes.recipeproperties.IRecipePropertyStorage;
import gregtech.api.util.GTUtility;
import gregtech.api.util.TextComponentUtil;
import gregtech.client.renderer.ICubeRenderer;
import gregtech.client.renderer.texture.Textures;
Expand Down Expand Up @@ -99,6 +100,7 @@ protected void addDisplayText(List<ITextComponent> textList) {
MultiblockDisplayText.builder(textList, isStructureFormed())
.setWorkingStatus(recipeMapWorkable.isWorkingEnabled(), recipeMapWorkable.isActive())
.addEnergyUsageLine(recipeMapWorkable.getEnergyContainer())
.addEnergyTierLine(GTUtility.getTierByVoltage(recipeMapWorkable.getMaxVoltage()))
.addCustom(tl -> {
if (isStructureFormed()) {
int processingSpeed = coilTier == 0 ? 75 : 50 * (coilTier + 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import gregtech.api.pattern.PatternMatchContext;
import gregtech.api.recipes.Recipe;
import gregtech.api.recipes.RecipeMaps;
import gregtech.api.util.GTUtility;
import gregtech.client.renderer.ICubeRenderer;
import gregtech.client.renderer.texture.Textures;
import gregtech.common.ConfigHolder;
Expand Down Expand Up @@ -221,6 +222,7 @@ protected void addDisplayText(List<ITextComponent> textList) {
"gregtech.multiblock.work_paused",
"gregtech.machine.research_station.researching")
.addEnergyUsageLine(recipeMapWorkable.getEnergyContainer())
.addEnergyTierLine(GTUtility.getTierByVoltage(recipeMapWorkable.getMaxVoltage()))
.addComputationUsageExactLine(getRecipeMapWorkable().getCurrentDrawnCWUt())
.addParallelsLine(recipeMapWorkable.getParallelLimit())
.addWorkingStatusLine()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ protected boolean shouldSearchForRecipes() {
}

@Override
protected long getMaxVoltage() {
public long getMaxVoltage() {
//this multiplies consumption through parallel
if (isOxygenBoosted)
return GTValues.V[tier] * 2;
Expand Down
Loading

0 comments on commit 91aa525

Please sign in to comment.