Blast furnace QoL tweak
- add perfect smelt batch ratio display in tooltip - fix undersmelting at perfect ratios - fix height 10 reinforcement not being detected
This commit is contained in:
@@ -465,6 +465,9 @@
|
|||||||
"create.fe": "%1$s :ƎℲ",
|
"create.fe": "%1$s :ƎℲ",
|
||||||
"create.goggles.ammeter": ":ɹǝʇǝɯɯⱯ",
|
"create.goggles.ammeter": ":ɹǝʇǝɯɯⱯ",
|
||||||
"create.goggles.ammeter.amps": "Λ %1$s :sdɯⱯ pǝɹnsɐǝW ",
|
"create.goggles.ammeter.amps": "Λ %1$s :sdɯⱯ pǝɹnsɐǝW ",
|
||||||
|
"create.goggles.blast_furnace.batch_header": ":oıʇɐᴚ ɥɔʇɐᗺ ʇןǝɯS",
|
||||||
|
"create.goggles.blast_furnace.batch_ratio": ")xnןℲ:ǝɹO:ןǝnℲ( %s:%s:%s",
|
||||||
|
"create.goggles.blast_furnace.batch_warning": "˙ǝzıs ɥɔʇɐq ǝbɹɐꞀ :buıuɹɐM",
|
||||||
"create.goggles.blast_furnace.fuel_amount": "%1$s : ןǝnℲ ",
|
"create.goggles.blast_furnace.fuel_amount": "%1$s : ןǝnℲ ",
|
||||||
"create.goggles.blast_furnace.height": "%1$s :ʇɥbıǝH ",
|
"create.goggles.blast_furnace.height": "%1$s :ʇɥbıǝH ",
|
||||||
"create.goggles.blast_furnace.modifier": "%1$s :ǝɯı⟘ uoıʇɔnpoɹԀ",
|
"create.goggles.blast_furnace.modifier": "%1$s :ǝɯı⟘ uoıʇɔnpoɹԀ",
|
||||||
@@ -1062,4 +1065,4 @@
|
|||||||
"tfmg.ponder.tag.oil_processing.description": "ןıo buıuıɯ puɐ buıuıɟǝɹ ɹoɟ pǝsn ʞɔoןᗺ",
|
"tfmg.ponder.tag.oil_processing.description": "ןıo buıuıɯ puɐ buıuıɟǝɹ ɹoɟ pǝsn ʞɔoןᗺ",
|
||||||
"tfmg.subtitle.diesel_engine_sounds": "spunoS ǝuıbuƎ ןǝsǝıᗡ",
|
"tfmg.subtitle.diesel_engine_sounds": "spunoS ǝuıbuƎ ןǝsǝıᗡ",
|
||||||
"tfmg.subtitle.engine_sounds": "spunoS ǝuıbuƎ"
|
"tfmg.subtitle.engine_sounds": "spunoS ǝuıbuƎ"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -465,6 +465,9 @@
|
|||||||
"create.fe": "FE: %1$s",
|
"create.fe": "FE: %1$s",
|
||||||
"create.goggles.ammeter": "Ammeter:",
|
"create.goggles.ammeter": "Ammeter:",
|
||||||
"create.goggles.ammeter.amps": " Measured Amps: %1$s V",
|
"create.goggles.ammeter.amps": " Measured Amps: %1$s V",
|
||||||
|
"create.goggles.blast_furnace.batch_header": "Smelt Batch Ratio:",
|
||||||
|
"create.goggles.blast_furnace.batch_ratio": "%s:%s:%s (Fuel:Ore:Flux)",
|
||||||
|
"create.goggles.blast_furnace.batch_warning": "Warning: Large batch size.",
|
||||||
"create.goggles.blast_furnace.fuel_amount": " Fuel : %1$s",
|
"create.goggles.blast_furnace.fuel_amount": " Fuel : %1$s",
|
||||||
"create.goggles.blast_furnace.height": " Height: %1$s",
|
"create.goggles.blast_furnace.height": " Height: %1$s",
|
||||||
"create.goggles.blast_furnace.modifier": "Production Time: %1$s",
|
"create.goggles.blast_furnace.modifier": "Production Time: %1$s",
|
||||||
@@ -1062,4 +1065,4 @@
|
|||||||
"tfmg.ponder.tag.oil_processing.description": "Block used for refining and mining oil",
|
"tfmg.ponder.tag.oil_processing.description": "Block used for refining and mining oil",
|
||||||
"tfmg.subtitle.diesel_engine_sounds": "Diesel Engine Sounds",
|
"tfmg.subtitle.diesel_engine_sounds": "Diesel Engine Sounds",
|
||||||
"tfmg.subtitle.engine_sounds": "Engine Sounds"
|
"tfmg.subtitle.engine_sounds": "Engine Sounds"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
|||||||
|
|
||||||
public SmartInventory inputInventory;
|
public SmartInventory inputInventory;
|
||||||
public SmartInventory fluxInventory;
|
public SmartInventory fluxInventory;
|
||||||
|
public SmartInventory fuelInventory;
|
||||||
public FluidTank primaryTank;
|
public FluidTank primaryTank;
|
||||||
public FluidTank secondaryTank;
|
public FluidTank secondaryTank;
|
||||||
protected LazyOptional<IFluidHandler> fluidCapability;
|
protected LazyOptional<IFluidHandler> fluidCapability;
|
||||||
@@ -79,12 +80,16 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
|||||||
.forbidExtraction()
|
.forbidExtraction()
|
||||||
.withMaxStackSize(64).whenContentsChanged(i -> this.onContentsChanged());
|
.withMaxStackSize(64).whenContentsChanged(i -> this.onContentsChanged());
|
||||||
|
|
||||||
|
fuelInventory = new SmartInventory(1, this)
|
||||||
|
.forbidInsertion()
|
||||||
|
.withMaxStackSize(64).whenContentsChanged(i -> this.onContentsChanged());
|
||||||
|
|
||||||
primaryTank = new SmartFluidTank(4000, this::onFluidChanged);
|
primaryTank = new SmartFluidTank(4000, this::onFluidChanged);
|
||||||
|
|
||||||
secondaryTank = new SmartFluidTank(4000, this::onFluidChanged);
|
secondaryTank = new SmartFluidTank(4000, this::onFluidChanged);
|
||||||
|
|
||||||
|
|
||||||
itemCapability = LazyOptional.of(() -> new CombinedInvWrapper(inputInventory, fluxInventory));
|
itemCapability = LazyOptional.of(() -> new CombinedInvWrapper(inputInventory, fluxInventory, fuelInventory));
|
||||||
fluidCapability = LazyOptional.of(() -> new CombinedTankWrapper(primaryTank, secondaryTank));
|
fluidCapability = LazyOptional.of(() -> new CombinedTankWrapper(primaryTank, secondaryTank));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,6 +112,51 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int gcd(int a, int b) {
|
||||||
|
return b == 0 ? a : gcd(b, a % b);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int calculateProcessingTime(IndustrialBlastingRecipe recipe) {
|
||||||
|
int baseDuration = recipe.getProcessingDuration() * 20;
|
||||||
|
double timeModifier = TFMGConfigs.common().machines.blastFurnaceMaxHeight.get() /
|
||||||
|
((baseDuration / 2) * TFMGConfigs.common().machines.blastFurnaceHeightSpeedModifier.get());
|
||||||
|
|
||||||
|
int actualTicks = (int)(baseDuration - (getSize() / timeModifier));
|
||||||
|
return isReinforced ? actualTicks / 2 : actualTicks;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] findCleanRatio(IndustrialBlastingRecipe recipe) {
|
||||||
|
// Get all values from config
|
||||||
|
int ticksPerFuel = TFMGConfigs.common().machines.blastFurnaceFuelConsumption.get();
|
||||||
|
int actualTicks = calculateProcessingTime(recipe);
|
||||||
|
|
||||||
|
// Calculate the exact decimal ratio
|
||||||
|
float exactRatio = (float)ticksPerFuel / actualTicks;
|
||||||
|
|
||||||
|
// Find the smallest integer ratio that approximates this
|
||||||
|
int maxIterations = 1000; // Prevents infinite loops
|
||||||
|
float tolerance = 0.0001f; // How close we need to be
|
||||||
|
|
||||||
|
int a = 1, b = 1;
|
||||||
|
float currentError = Math.abs(exactRatio - ((float)a/b));
|
||||||
|
|
||||||
|
// Farey sequence approximation
|
||||||
|
for (int i = 0; i < maxIterations && currentError > tolerance; i++) {
|
||||||
|
if ((float)a/b < exactRatio) {
|
||||||
|
a++;
|
||||||
|
} else {
|
||||||
|
b++;
|
||||||
|
}
|
||||||
|
currentError = Math.abs(exactRatio - ((float)a/b));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if recipe needs flux
|
||||||
|
boolean needsFlux = recipe.getIngredients().size() > 1;
|
||||||
|
|
||||||
|
// Return as [fuel, ore, flux]
|
||||||
|
return new int[]{b, a, needsFlux ? a : 0};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
|
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
|
||||||
|
|
||||||
@@ -130,11 +180,37 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
|||||||
.style(ChatFormatting.GREEN)
|
.style(ChatFormatting.GREEN)
|
||||||
.forGoggles(tooltip);
|
.forGoggles(tooltip);
|
||||||
|
|
||||||
|
// Dynamic batch ratio calculation for current input
|
||||||
|
if (!inputInventory.isEmpty()) {
|
||||||
|
Optional<IndustrialBlastingRecipe> recipeOpt = TFMGRecipeTypes.INDUSTRIAL_BLASTING
|
||||||
|
.find(new RecipeWrapper(inputInventory), level);
|
||||||
|
|
||||||
|
if (recipeOpt.isPresent()) {
|
||||||
|
IndustrialBlastingRecipe recipe = recipeOpt.get();
|
||||||
|
int[] batch = findCleanRatio(recipe); // Uses the corrected method
|
||||||
|
|
||||||
|
CreateLang.translate("goggles.blast_furnace.batch_header")
|
||||||
|
.style(ChatFormatting.GRAY)
|
||||||
|
.forGoggles(tooltip);
|
||||||
|
|
||||||
|
CreateLang.translate("goggles.blast_furnace.batch_ratio",
|
||||||
|
batch[0], batch[1], batch[2])
|
||||||
|
.style(ChatFormatting.AQUA)
|
||||||
|
.forGoggles(tooltip);
|
||||||
|
|
||||||
|
if (batch[1] > 64) {
|
||||||
|
CreateLang.translate("goggles.blast_furnace.batch_warning")
|
||||||
|
.style(ChatFormatting.YELLOW)
|
||||||
|
.forGoggles(tooltip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TFMGUtils.createFluidTooltip(this, tooltip);
|
TFMGUtils.createFluidTooltip(this, tooltip);
|
||||||
TFMGUtils.createItemTooltip(this, tooltip);
|
TFMGUtils.createItemTooltip(this, tooltip);
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void executeRecipe() {
|
public void executeRecipe() {
|
||||||
@@ -178,6 +254,17 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
|||||||
if (getSize() < 3)
|
if (getSize() < 3)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (fuel <= 0 && !fuelInventory.getItem(0).isEmpty()) {
|
||||||
|
ItemStack fuelStack = fuelInventory.getItem(0);
|
||||||
|
if (fuelStack.is(TFMGTags.TFMGItemTags.BLAST_FURNACE_FUEL.tag)) {
|
||||||
|
int fuelValue = 1;
|
||||||
|
int toConsume = Math.min(fuelStack.getCount(), STORAGE_SPACE - fuel);
|
||||||
|
fuel += toConsume * fuelValue;
|
||||||
|
fuelStack.shrink(toConsume);
|
||||||
|
setChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (fuelConsumeTimer >= TFMGConfigs.common().machines.blastFurnaceFuelConsumption.get() && fuel > 0) {
|
if (fuelConsumeTimer >= TFMGConfigs.common().machines.blastFurnaceFuelConsumption.get() && fuel > 0) {
|
||||||
fuelConsumeTimer = 0;
|
fuelConsumeTimer = 0;
|
||||||
fuel--;
|
fuel--;
|
||||||
@@ -232,8 +319,8 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
|||||||
tuyereBE.tank.getFluidInTank(0).setAmount(Math.max(tuyereBE.tank.getFluidInTank(0).getAmount() - recipe.hotAirUsage, 0));
|
tuyereBE.tank.getFluidInTank(0).setAmount(Math.max(tuyereBE.tank.getFluidInTank(0).getAmount() - recipe.hotAirUsage, 0));
|
||||||
|
|
||||||
if (!recipe.getGasByproduct().isEmpty()) {
|
if (!recipe.getGasByproduct().isEmpty()) {
|
||||||
if (level.getBlockEntity(getBlockPos().relative(getBlockState().getValue(FACING).getOpposite()).above(getSize())) instanceof BlastFurnaceHatchBlockEntity be) {
|
if (level.getBlockEntity(getBlockPos().relative(getBlockState().getValue(FACING).getOpposite()).above(getSize())) instanceof BlastFurnaceHatchBlockEntity chargeHatchBE) {
|
||||||
be.tank.fill(recipe.getGasByproduct(), IFluidHandler.FluidAction.EXECUTE);
|
chargeHatchBE.tank.fill(recipe.getGasByproduct(), IFluidHandler.FluidAction.EXECUTE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (level.isClientSide())
|
if (level.isClientSide())
|
||||||
@@ -261,8 +348,8 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean canProcess(IndustrialBlastingRecipe recipe) {
|
private boolean canProcess(IndustrialBlastingRecipe recipe) {
|
||||||
if (fuel == 0)
|
//if (fuel == 0)
|
||||||
return false;
|
// return false;
|
||||||
|
|
||||||
if (!primaryTank.getFluid().isEmpty() && !primaryTank.getFluid().getFluid().isSame(recipe.getPrimaryResult().getFluid()))
|
if (!primaryTank.getFluid().isEmpty() && !primaryTank.getFluid().getFluid().isSame(recipe.getPrimaryResult().getFluid()))
|
||||||
return false;
|
return false;
|
||||||
@@ -312,12 +399,32 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
|||||||
if (itemStack.isEmpty())
|
if (itemStack.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (itemStack.is(TFMGTags.TFMGItemTags.BLAST_FURNACE_FUEL.tag) && fuel < STORAGE_SPACE) {
|
if (itemStack.is(TFMGTags.TFMGItemTags.BLAST_FURNACE_FUEL.tag)) {
|
||||||
|
// If fuel storage is full, try to add to fuel inventory slot
|
||||||
|
if (fuel >= STORAGE_SPACE) {
|
||||||
|
if (fuelInventory.getItem(0).isEmpty() ||
|
||||||
|
(fuelInventory.getItem(0).is(itemStack.getItem()) &&
|
||||||
|
fuelInventory.getItem(0).getCount() < fuelInventory.getItem(0).getMaxStackSize())) {
|
||||||
|
|
||||||
fuel++;
|
int added = Math.min(itemStack.getCount(),
|
||||||
itemStack.shrink(1);
|
fuelInventory.getItem(0).getMaxStackSize() - fuelInventory.getItem(0).getCount());
|
||||||
continue;
|
if (fuelInventory.getItem(0).isEmpty()) {
|
||||||
|
fuelInventory.setItem(0, new ItemStack(itemStack.getItem(), added));
|
||||||
|
} else {
|
||||||
|
fuelInventory.getItem(0).grow(added);
|
||||||
|
}
|
||||||
|
itemStack.shrink(added);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Add to fuel storage if not full
|
||||||
|
int toAdd = Math.min(itemStack.getCount(), STORAGE_SPACE - fuel);
|
||||||
|
fuel += toAdd;
|
||||||
|
itemStack.shrink(toAdd);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itemStack.is(TFMGTags.TFMGItemTags.FLUX.tag) && fluxInventory.getItem(0).getCount() < itemStack.getMaxStackSize()) {
|
if (itemStack.is(TFMGTags.TFMGItemTags.FLUX.tag) && fluxInventory.getItem(0).getCount() < itemStack.getMaxStackSize()) {
|
||||||
if (fluxInventory.isEmpty() || fluxInventory.getItem(0).is(itemStack.getItem())) {
|
if (fluxInventory.isEmpty() || fluxInventory.getItem(0).is(itemStack.getItem())) {
|
||||||
fluxInventory.setItem(0, new ItemStack(itemStack.getItem(), fluxInventory.getItem(0).getCount() + 1));
|
fluxInventory.setItem(0, new ItemStack(itemStack.getItem(), fluxInventory.getItem(0).getCount() + 1));
|
||||||
@@ -329,7 +436,6 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
|||||||
if (inputInventory.isEmpty() || inputInventory.getItem(0).is(itemStack.getItem())) {
|
if (inputInventory.isEmpty() || inputInventory.getItem(0).is(itemStack.getItem())) {
|
||||||
inputInventory.setItem(0, new ItemStack(itemStack.getItem(), inputInventory.getItem(0).getCount() + 1));
|
inputInventory.setItem(0, new ItemStack(itemStack.getItem(), inputInventory.getItem(0).getCount() + 1));
|
||||||
itemStack.shrink(1);
|
itemStack.shrink(1);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -341,6 +447,7 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
|||||||
isReinforced = compound.getBoolean("IsReinforce");
|
isReinforced = compound.getBoolean("IsReinforce");
|
||||||
inputInventory.deserializeNBT(compound.getCompound("InputItems"));
|
inputInventory.deserializeNBT(compound.getCompound("InputItems"));
|
||||||
fluxInventory.deserializeNBT(compound.getCompound("Flux"));
|
fluxInventory.deserializeNBT(compound.getCompound("Flux"));
|
||||||
|
fuelInventory.deserializeNBT(compound.getCompound("FuelItems"));
|
||||||
timer = compound.getInt("Timer");
|
timer = compound.getInt("Timer");
|
||||||
fuel = compound.getInt("Fuel");
|
fuel = compound.getInt("Fuel");
|
||||||
fuelConsumeTimer = compound.getInt("FuelConsumeTimer");
|
fuelConsumeTimer = compound.getInt("FuelConsumeTimer");
|
||||||
@@ -354,6 +461,7 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
|||||||
compound.putBoolean("IsReinforce", isReinforced);
|
compound.putBoolean("IsReinforce", isReinforced);
|
||||||
compound.put("InputItems", inputInventory.serializeNBT());
|
compound.put("InputItems", inputInventory.serializeNBT());
|
||||||
compound.put("Flux", fluxInventory.serializeNBT());
|
compound.put("Flux", fluxInventory.serializeNBT());
|
||||||
|
compound.put("FuelItems", fuelInventory.serializeNBT());
|
||||||
compound.putInt("Timer", timer);
|
compound.putInt("Timer", timer);
|
||||||
compound.putInt("Fuel", fuel);
|
compound.putInt("Fuel", fuel);
|
||||||
compound.putInt("FuelConsumeTimer", fuelConsumeTimer);
|
compound.putInt("FuelConsumeTimer", fuelConsumeTimer);
|
||||||
@@ -366,6 +474,7 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
|||||||
super.destroy();
|
super.destroy();
|
||||||
ItemHelper.dropContents(level, worldPosition, inputInventory);
|
ItemHelper.dropContents(level, worldPosition, inputInventory);
|
||||||
ItemHelper.dropContents(level, worldPosition, fluxInventory);
|
ItemHelper.dropContents(level, worldPosition, fluxInventory);
|
||||||
|
ItemHelper.dropContents(level, worldPosition, fuelInventory);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSize() {
|
public int getSize() {
|
||||||
@@ -382,7 +491,7 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
|||||||
int normalAmount = 0;
|
int normalAmount = 0;
|
||||||
int reinforcedAmount = 0;
|
int reinforcedAmount = 0;
|
||||||
|
|
||||||
for (int i = 0; i < TFMGConfigs.common().machines.blastFurnaceMaxHeight.get(); i++) {
|
for (int i = 0; i <= TFMGConfigs.common().machines.blastFurnaceMaxHeight.get(); i++) {
|
||||||
|
|
||||||
BlockPos checkedPos = middlePos.above(i).east().south();
|
BlockPos checkedPos = middlePos.above(i).east().south();
|
||||||
|
|
||||||
@@ -470,4 +579,4 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
|||||||
REINFORCED
|
REINFORCED
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,9 @@
|
|||||||
"create.goggles.blast_furnace.reinforced": "Reinforced",
|
"create.goggles.blast_furnace.reinforced": "Reinforced",
|
||||||
"create.goggles.blast_furnace.timer": "Time Left: %1$s",
|
"create.goggles.blast_furnace.timer": "Time Left: %1$s",
|
||||||
"create.goggles.blast_furnace.modifier": "Production Time: %1$s",
|
"create.goggles.blast_furnace.modifier": "Production Time: %1$s",
|
||||||
|
"create.goggles.blast_furnace.batch_header": "Smelt Batch Ratio:",
|
||||||
|
"create.goggles.blast_furnace.batch_ratio": "%s:%s:%s (Fuel:Ore:Flux)",
|
||||||
|
"create.goggles.blast_furnace.batch_warning": "Warning: Large batch size.",
|
||||||
|
|
||||||
"create.goggles.blast_stove.header": "Blast Stove: ",
|
"create.goggles.blast_stove.header": "Blast Stove: ",
|
||||||
"create.goggles.blast_stove.tank1": "Input Tank 1: ",
|
"create.goggles.blast_stove.tank1": "Input Tank 1: ",
|
||||||
|
|||||||
Reference in New Issue
Block a user