Merge pull request #196 from Daniel366Cobra/qol-tweaks-blast-furnace
Blast furnace QoL tweak
This commit is contained in:
@@ -52,6 +52,7 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
||||
|
||||
public SmartInventory inputInventory;
|
||||
public SmartInventory fluxInventory;
|
||||
public SmartInventory fuelInventory;
|
||||
public FluidTank primaryTank;
|
||||
public FluidTank secondaryTank;
|
||||
protected LazyOptional<IFluidHandler> fluidCapability;
|
||||
@@ -79,12 +80,16 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
||||
.forbidExtraction()
|
||||
.withMaxStackSize(64).whenContentsChanged(i -> this.onContentsChanged());
|
||||
|
||||
fuelInventory = new SmartInventory(1, this)
|
||||
.forbidInsertion()
|
||||
.withMaxStackSize(64).whenContentsChanged(i -> this.onContentsChanged());
|
||||
|
||||
primaryTank = 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));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
|
||||
|
||||
@@ -130,11 +180,37 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
||||
.style(ChatFormatting.GREEN)
|
||||
.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.createItemTooltip(this, tooltip);
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public void executeRecipe() {
|
||||
@@ -178,6 +254,17 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
||||
if (getSize() < 3)
|
||||
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) {
|
||||
fuelConsumeTimer = 0;
|
||||
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));
|
||||
|
||||
if (!recipe.getGasByproduct().isEmpty()) {
|
||||
if (level.getBlockEntity(getBlockPos().relative(getBlockState().getValue(FACING).getOpposite()).above(getSize())) instanceof BlastFurnaceHatchBlockEntity be) {
|
||||
be.tank.fill(recipe.getGasByproduct(), IFluidHandler.FluidAction.EXECUTE);
|
||||
if (level.getBlockEntity(getBlockPos().relative(getBlockState().getValue(FACING).getOpposite()).above(getSize())) instanceof BlastFurnaceHatchBlockEntity chargeHatchBE) {
|
||||
chargeHatchBE.tank.fill(recipe.getGasByproduct(), IFluidHandler.FluidAction.EXECUTE);
|
||||
}
|
||||
}
|
||||
if (level.isClientSide())
|
||||
@@ -261,8 +348,8 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
||||
}
|
||||
|
||||
private boolean canProcess(IndustrialBlastingRecipe recipe) {
|
||||
if (fuel == 0)
|
||||
return false;
|
||||
//if (fuel == 0)
|
||||
// return false;
|
||||
|
||||
if (!primaryTank.getFluid().isEmpty() && !primaryTank.getFluid().getFluid().isSame(recipe.getPrimaryResult().getFluid()))
|
||||
return false;
|
||||
@@ -312,12 +399,32 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
||||
if (itemStack.isEmpty())
|
||||
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++;
|
||||
itemStack.shrink(1);
|
||||
continue;
|
||||
int added = Math.min(itemStack.getCount(),
|
||||
fuelInventory.getItem(0).getMaxStackSize() - fuelInventory.getItem(0).getCount());
|
||||
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 (fluxInventory.isEmpty() || fluxInventory.getItem(0).is(itemStack.getItem())) {
|
||||
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())) {
|
||||
inputInventory.setItem(0, new ItemStack(itemStack.getItem(), inputInventory.getItem(0).getCount() + 1));
|
||||
itemStack.shrink(1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -341,6 +447,7 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
||||
isReinforced = compound.getBoolean("IsReinforce");
|
||||
inputInventory.deserializeNBT(compound.getCompound("InputItems"));
|
||||
fluxInventory.deserializeNBT(compound.getCompound("Flux"));
|
||||
fuelInventory.deserializeNBT(compound.getCompound("FuelItems"));
|
||||
timer = compound.getInt("Timer");
|
||||
fuel = compound.getInt("Fuel");
|
||||
fuelConsumeTimer = compound.getInt("FuelConsumeTimer");
|
||||
@@ -354,6 +461,7 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
||||
compound.putBoolean("IsReinforce", isReinforced);
|
||||
compound.put("InputItems", inputInventory.serializeNBT());
|
||||
compound.put("Flux", fluxInventory.serializeNBT());
|
||||
compound.put("FuelItems", fuelInventory.serializeNBT());
|
||||
compound.putInt("Timer", timer);
|
||||
compound.putInt("Fuel", fuel);
|
||||
compound.putInt("FuelConsumeTimer", fuelConsumeTimer);
|
||||
@@ -366,6 +474,7 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
||||
super.destroy();
|
||||
ItemHelper.dropContents(level, worldPosition, inputInventory);
|
||||
ItemHelper.dropContents(level, worldPosition, fluxInventory);
|
||||
ItemHelper.dropContents(level, worldPosition, fuelInventory);
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
@@ -382,7 +491,7 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
||||
int normalAmount = 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();
|
||||
|
||||
@@ -470,4 +579,4 @@ public class BlastFurnaceOutputBlockEntity extends SmartBlockEntity implements I
|
||||
REINFORCED
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
"create.goggles.blast_furnace.reinforced": "Reinforced",
|
||||
"create.goggles.blast_furnace.timer": "Time Left: %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.tank1": "Input Tank 1: ",
|
||||
|
||||
Reference in New Issue
Block a user