From 05b9a6ab7dd887fe65d052df9c9de5665f99df64 Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 27 Feb 2026 22:08:10 -0500 Subject: [PATCH 01/10] Prevent recipe start when energy buffer is full Add check to prevent recipe start if energy buffer is full. --- .../multi/electric/RotationGeneratorController.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/supersymmetry/common/metatileentities/multi/electric/RotationGeneratorController.java b/src/main/java/supersymmetry/common/metatileentities/multi/electric/RotationGeneratorController.java index 2b2e6645c..8d6c6af1e 100644 --- a/src/main/java/supersymmetry/common/metatileentities/multi/electric/RotationGeneratorController.java +++ b/src/main/java/supersymmetry/common/metatileentities/multi/electric/RotationGeneratorController.java @@ -194,6 +194,10 @@ public boolean checkRecipe(@NotNull Recipe recipe) { if (proposedEUt > getMaximumAllowedVoltage()) { return false; } + // Prevent recipe from starting if energy buffer is full, and we're not voiding energy + if (isFull && !voidEnergy) { + return false; + } return sufficientFluids; } From 69c9bc2b536318786668d13ee231e8490f5e2a1f Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 27 Feb 2026 22:43:25 -0500 Subject: [PATCH 02/10] Add SuSyFluidTankWidget class for fluid handling --- .../api/fluids/SuSyFluidTankWidget.java | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/main/java/supersymmetry/api/fluids/SuSyFluidTankWidget.java diff --git a/src/main/java/supersymmetry/api/fluids/SuSyFluidTankWidget.java b/src/main/java/supersymmetry/api/fluids/SuSyFluidTankWidget.java new file mode 100644 index 000000000..19173765b --- /dev/null +++ b/src/main/java/supersymmetry/api/fluids/SuSyFluidTankWidget.java @@ -0,0 +1,74 @@ +package supersymmetry.api.fluids; + +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.capability.IFluidTankProperties; + +import gregtech.api.capability.impl.NotifiableFilteredFluidHandler; +import gregtech.api.metatileentity.MetaTileEntity; + +public class SuSyFluidTankWidget extends NotifiableFilteredFluidHandler { + + public SuSyFluidTankWidget(int capacity, MetaTileEntity entityToNotify, boolean isExport) { + super(capacity, entityToNotify, isExport); + } + + @Override + public int fill(FluidStack resource, boolean doFill) { + if (resource == null || !canFillFluidType(resource)) { + return 0; + } + return super.fill(resource, doFill); + } + + @Override + public boolean canFillFluidType(FluidStack fluid) { + boolean result = super.canFillFluidType(fluid); + System.out.println("[SuSyFilteredFluidTank] canFillFluidType() called with: " + + (fluid != null ? fluid.getFluid().getName() : "null") + ", result: " + result); + return result; + } + + @Override + public IFluidTankProperties[] getTankProperties() { + IFluidTankProperties[] properties = super.getTankProperties(); + return new IFluidTankProperties[] { + new IFluidTankProperties() { + + @Override + public FluidStack getContents() { + return properties[0].getContents(); + } + + @Override + public int getCapacity() { + return properties[0].getCapacity(); + } + + @Override + public boolean canFill() { + return properties[0].canFill(); + } + + @Override + public boolean canDrain() { + return properties[0].canDrain(); + } + + @Override + public boolean canFillFluidType(FluidStack fluidStack) { + boolean result = fluidStack != null && SuSyFluidTankWidget.this.canFillFluidType(fluidStack); + System.out.println("[SuSyFilteredFluidTank] getTankProperties().canFillFluidType() with: " + + (fluidStack != null ? fluidStack.getFluid().getName() : "null") + ", result: " + + result); + return result; + } + + @Override + public boolean canDrainFluidType(FluidStack fluidStack) { + return properties[0].canDrainFluidType(fluidStack); + } + } + // gross + }; + } +} From daff849a9692d868068efeec1fb87cbced00503c Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 27 Feb 2026 22:44:57 -0500 Subject: [PATCH 03/10] FilteredTankWidget --- .../api/fluids/FilteredTankWidget.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/main/java/supersymmetry/api/fluids/FilteredTankWidget.java diff --git a/src/main/java/supersymmetry/api/fluids/FilteredTankWidget.java b/src/main/java/supersymmetry/api/fluids/FilteredTankWidget.java new file mode 100644 index 000000000..f3d09542a --- /dev/null +++ b/src/main/java/supersymmetry/api/fluids/FilteredTankWidget.java @@ -0,0 +1,41 @@ +package supersymmetry.api.fluids; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandlerItem; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import gregtech.api.gui.widgets.TankWidget; + +public class FilteredTankWidget extends TankWidget { + + public FilteredTankWidget(IFluidTank fluidTank, int x, int y, int width, int height) { + super(fluidTank, x, y, width, height); + } + + @Override + @SideOnly(Side.CLIENT) + public boolean mouseClicked(int mouseX, int mouseY, int button) { + if (isMouseOverElement(mouseX, mouseY) && fluidTank instanceof IFluidHandler) { + ItemStack held = gui.entityPlayer.inventory.getItemStack(); + if (!held.isEmpty()) { + IFluidHandlerItem itemHandler = held.getCapability( + CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null); + if (itemHandler != null) { + FluidStack heldFluid = itemHandler.drain(Integer.MAX_VALUE, false); + if (heldFluid != null && heldFluid.amount > 0) { + // Simulate: would the tank accept this fluid? + if (((IFluidHandler) fluidTank).fill(heldFluid, false) <= 0) { + return false; // block the click entirely — no packet sent + } + } + } + } + } + return super.mouseClicked(mouseX, mouseY, button); + } +} From a17ceb314e5ecc35eef6d3eae626eb37b0d2132e Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 27 Feb 2026 22:45:48 -0500 Subject: [PATCH 04/10] stop SuSyMetaTileEntitySingleCombustion from destroying incorrect fluids/ It no longer destroys fluids when you click a fluid input with the wrong bucket. --- .../SuSyMetaTileEntitySingleCombustion.java | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/main/java/supersymmetry/common/metatileentities/single/electric/SuSyMetaTileEntitySingleCombustion.java b/src/main/java/supersymmetry/common/metatileentities/single/electric/SuSyMetaTileEntitySingleCombustion.java index d117ab133..828aabf10 100644 --- a/src/main/java/supersymmetry/common/metatileentities/single/electric/SuSyMetaTileEntitySingleCombustion.java +++ b/src/main/java/supersymmetry/common/metatileentities/single/electric/SuSyMetaTileEntitySingleCombustion.java @@ -19,13 +19,11 @@ import gregtech.api.capability.IEnergyContainer; import gregtech.api.capability.impl.FluidTankList; import gregtech.api.capability.impl.FuelRecipeLogic; -import gregtech.api.capability.impl.NotifiableFilteredFluidHandler; import gregtech.api.capability.impl.NotifiableFluidTank; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; import gregtech.api.gui.widgets.ImageWidget; import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.gui.widgets.TankWidget; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.recipes.Recipe; @@ -33,6 +31,8 @@ import gregtech.client.renderer.ICubeRenderer; import gregtech.common.metatileentities.electric.MetaTileEntitySingleCombustion; import supersymmetry.api.capability.impl.SuSyFluidFilters; +import supersymmetry.api.fluids.FilteredTankWidget; +import supersymmetry.api.fluids.SuSyFluidTankWidget; import supersymmetry.api.util.SuSyUtility; public class SuSyMetaTileEntitySingleCombustion extends MetaTileEntitySingleCombustion { @@ -45,8 +45,8 @@ public class SuSyMetaTileEntitySingleCombustion extends MetaTileEntitySingleComb private boolean sufficientFluids; - private FluidTank lubricantTank; - private FluidTank coolantTank; + private SuSyFluidTankWidget lubricantTank; + private SuSyFluidTankWidget coolantTank; private FluidTankList displayedTankList; @@ -63,24 +63,24 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { } @Override - // Handle fluid imports protected FluidTankList createImportFluidHandler() { if (workable == null) return new FluidTankList(false); - FluidTank[] fluidImports = new FluidTank[workable.getRecipeMap().getMaxFluidInputs() + 2]; + + // Only recipe fluid inputs go here — no lubricant/coolant + FluidTank[] fluidImports = new FluidTank[workable.getRecipeMap().getMaxFluidInputs()]; FluidTank[] displayedTanks = new FluidTank[workable.getRecipeMap().getMaxFluidInputs()]; - for (int i = 0; i < fluidImports.length - 2; i++) { - NotifiableFluidTank filteredFluidHandler = new NotifiableFluidTank( + for (int i = 0; i < fluidImports.length; i++) { + NotifiableFluidTank tank = new NotifiableFluidTank( this.getTankScalingFunction().apply(this.getTier()), this, false); - fluidImports[i] = filteredFluidHandler; - displayedTanks[i] = filteredFluidHandler; + fluidImports[i] = tank; + displayedTanks[i] = tank; } - this.lubricantTank = new NotifiableFilteredFluidHandler(1000, this, false) + // Lubricant/coolant tanks are standalone — NOT part of the import handler + this.lubricantTank = (SuSyFluidTankWidget) new SuSyFluidTankWidget(1000, this, false) .setFilter(SuSyFluidFilters.LUBRICANT); - fluidImports[fluidImports.length - 2] = lubricantTank; - - this.coolantTank = new NotifiableFilteredFluidHandler(1000, this, false).setFilter(SuSyFluidFilters.COOLANT); - fluidImports[fluidImports.length - 1] = coolantTank; + this.coolantTank = (SuSyFluidTankWidget) new SuSyFluidTankWidget(1000, this, false) + .setFilter(SuSyFluidFilters.COOLANT); this.displayedTankList = new FluidTankList(false, displayedTanks); return new FluidTankList(false, fluidImports); @@ -97,7 +97,7 @@ public void update() { super.update(); if (!getWorld().isRemote) { updateSufficientFluids(); - isFull = energyContainer.getEnergyStored() - energyContainer.getEnergyCapacity() == 0; + isFull = energyContainer.getEnergyStored() >= energyContainer.getEnergyCapacity(); if (workable.isWorking() && !isFull) workCounter += 1; if (workCounter == 600) { @@ -138,14 +138,14 @@ protected ModularUI.Builder createGuiTemplate(EntityPlayer player) { builder.widget(new LabelWidget(6, 6, getMetaFullName())) .bindPlayerInventory(player.inventory, GuiTextures.SLOT, yOffset); - builder.widget(new TankWidget(lubricantTank, 110, 21, 10, 54) + builder.widget(new FilteredTankWidget(lubricantTank, 110, 21, 10, 54) .setBackgroundTexture(GuiTextures.PROGRESS_BAR_BOILER_EMPTY.get(true)) .setAlwaysShowFull(false) - .setContainerClicking(true, true)); // Enable container clicking - builder.widget(new TankWidget(coolantTank, 124, 21, 10, 54) + .setContainerClicking(true, true)); // both directions, filter guards filling + builder.widget(new FilteredTankWidget(coolantTank, 124, 21, 10, 54) .setBackgroundTexture(GuiTextures.PROGRESS_BAR_BOILER_EMPTY.get(true)) .setAlwaysShowFull(false) - .setContainerClicking(true, true)); // Enable container clicking + .setContainerClicking(true, true)); builder.widget(new ImageWidget(152, 63 + yOffset, 17, 17, GTValues.XMAS.get() ? GuiTextures.GREGTECH_LOGO_XMAS : GuiTextures.GREGTECH_LOGO) .setIgnoreColor(true)); @@ -169,12 +169,12 @@ public CombustionRecipeLogic(SuSyMetaTileEntitySingleCombustion metaTileEntity, @Override public boolean checkRecipe(@NotNull Recipe recipe) { - return sufficientFluids; + return sufficientFluids && !isFull; } @Override public boolean isWorking() { - return sufficientFluids && super.isWorking(); + return sufficientFluids && !isFull && super.isWorking(); } @Override From 1d863fb5b9d151e28d8f10a2e750e2efeb65bf9b Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 27 Feb 2026 23:28:30 -0500 Subject: [PATCH 05/10] Speed based turbine energy output. --- .../electric/RotationGeneratorController.java | 59 ++++++++++--------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/src/main/java/supersymmetry/common/metatileentities/multi/electric/RotationGeneratorController.java b/src/main/java/supersymmetry/common/metatileentities/multi/electric/RotationGeneratorController.java index 8d6c6af1e..553a4e41d 100644 --- a/src/main/java/supersymmetry/common/metatileentities/multi/electric/RotationGeneratorController.java +++ b/src/main/java/supersymmetry/common/metatileentities/multi/electric/RotationGeneratorController.java @@ -83,13 +83,24 @@ public void update() { if (!getWorld().isRemote) { setLubricantStack(tanks); updateSufficientFluids(); - isFull = energyContainer.getEnergyStored() - energyContainer.getEnergyCapacity() == 0; - generatingPower = !isFull && recipeMapWorkable.isWorking(); - - if (recipeMapWorkable.isWorking() && ((SuSyTurbineRecipeLogic) recipeMapWorkable).tryDrawEnergy()) { - speed += getRotationAcceleration(); + isFull = energyContainer.getEnergyStored() >= energyContainer.getEnergyCapacity(); + generatingPower = speed > 0 && sufficientFluids; + + // Speed control: ramp up during startup, hold steady when buffer full, + // decel only when no recipe or no fluids. Mirrors steam turbine governor behavior — + // a full buffer doesn't stall the turbine, it just stops adding energy. + boolean hasActiveRecipe = recipeMapWorkable.isActive(); + boolean canSpin = hasActiveRecipe && sufficientFluids; + + if (canSpin) { + if (speed < maxSpeed) { + // Still spinning up + speed += getRotationAcceleration(); + } + // At or above maxSpeed: hold governor keeps rated RPM regardless of buffer state lubricantCounter += speed; } else { + // No fuel or no recipe: coast down speed -= getRotationDeceleration(); } @@ -106,7 +117,6 @@ public void update() { } protected void updateSufficientFluids() { - // Check lubricant levels if (lubricantStack == null) { sufficientFluids = false; return; @@ -132,12 +142,10 @@ protected void setLubricantStack(IMultipleTankHandler tanks) { return; } } - this.lubricantStack = null; } @Override - // Save temperature to NBT data public NBTTagCompound writeToNBT(NBTTagCompound data) { super.writeToNBT(data); data.setInteger("Speed", this.speed); @@ -147,7 +155,6 @@ public NBTTagCompound writeToNBT(NBTTagCompound data) { } @Override - // Retrieve temperature from NBT data public void readFromNBT(NBTTagCompound data) { super.readFromNBT(data); this.speed = data.getInteger("Speed"); @@ -168,16 +175,19 @@ protected void addErrorText(List textList) { @Override protected long getMaxVoltage() { - if (!isFull && speed > 0 && ((SuSyTurbineRecipeLogic) recipeMapWorkable).tryDrawEnergy()) { + // Output is purely a function of speed; no isFull gate. + // The energy container's own capacity caps what actually gets stored. + // This mirrors governor behavior: the turbine always produces at rated voltage + // when spinning; downstream load and buffer state don't affect shaft speed. + if (speed > 0 && ((SuSyTurbineRecipeLogic) recipeMapWorkable).tryDrawEnergy()) { return ((SuSyTurbineRecipeLogic) recipeMapWorkable).getActualVoltage(); - } else { - return 0L; } + return 0L; } public class SuSyTurbineRecipeLogic extends MultiblockFuelRecipeLogic { - private RotationGeneratorController tileEntity; + private final RotationGeneratorController tileEntity; private int proposedEUt; protected boolean voidEnergy = false; @@ -189,31 +199,26 @@ public SuSyTurbineRecipeLogic(RotationGeneratorController tileEntity) { @Override public boolean checkRecipe(@NotNull Recipe recipe) { - // Hack to get the recipeEUt early proposedEUt = recipe.getEUt(); if (proposedEUt > getMaximumAllowedVoltage()) { return false; } - // Prevent recipe from starting if energy buffer is full, and we're not voiding energy - if (isFull && !voidEnergy) { - return false; - } + // Allow recipe to keep running when full; turbine stays on, + // drawEnergy will void if voidEnergy is set, or simply not store if buffer is full. return sufficientFluids; } @Override public int getInfoProviderEUt() { - if (!isFull && speed > 0 && tryDrawEnergy()) { + if (speed > 0 && tryDrawEnergy()) { return (int) getActualVoltage(); - } else { - return 0; } + return 0; } @Override protected void updateRecipeProgress() { if (canRecipeProgress && drawEnergy(recipeEUt, true)) { - // as recipe starts with progress on 1 this has to be > only not => to compensate for it if (++progressTime > getMaxProgress()) { completeRecipe(); } @@ -235,19 +240,18 @@ public boolean isWorking() { @Override protected boolean drawEnergy(int recipeEUt, boolean simulate) { - long euToDraw = -getActualVoltage(); // Will be negative + long euToDraw = -getActualVoltage(); // negative = generation long resultEnergy = getEnergyStored() - euToDraw; if (resultEnergy >= 0L && getEnergyStored() < getEnergyCapacity()) { - if (!simulate) getEnergyContainer().changeEnergy(-euToDraw); // So this is positive + if (!simulate) getEnergyContainer().changeEnergy(-euToDraw); return true; } - // Turbine voids excess fuel to keep spinning in any case. + // Void excess to keep spinning when buffer is full return voidEnergy; } public boolean tryDrawEnergy() { - return drawEnergy((int) getMaxParallelVoltage(), true); // have energy draw only tied to speed? (ignore - // recipe EUt entirely) + return drawEnergy((int) getMaxParallelVoltage(), true); } public boolean doDrawEnergy() { @@ -260,7 +264,6 @@ public int getMaxProgress() { if (lubricantStack != null) { return (int) (baseDuration * lubricantInfo.boost); } - return baseDuration; } From 7bcae5652a9c448633e468f7613fb8f38491aa16 Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 27 Feb 2026 23:39:36 -0500 Subject: [PATCH 06/10] undo --- .../electric/RotationGeneratorController.java | 56 +++++++++---------- 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/src/main/java/supersymmetry/common/metatileentities/multi/electric/RotationGeneratorController.java b/src/main/java/supersymmetry/common/metatileentities/multi/electric/RotationGeneratorController.java index 553a4e41d..01fd3d88f 100644 --- a/src/main/java/supersymmetry/common/metatileentities/multi/electric/RotationGeneratorController.java +++ b/src/main/java/supersymmetry/common/metatileentities/multi/electric/RotationGeneratorController.java @@ -1,3 +1,4 @@ + package supersymmetry.common.metatileentities.multi.electric; import java.util.List; @@ -83,24 +84,13 @@ public void update() { if (!getWorld().isRemote) { setLubricantStack(tanks); updateSufficientFluids(); - isFull = energyContainer.getEnergyStored() >= energyContainer.getEnergyCapacity(); - generatingPower = speed > 0 && sufficientFluids; - - // Speed control: ramp up during startup, hold steady when buffer full, - // decel only when no recipe or no fluids. Mirrors steam turbine governor behavior — - // a full buffer doesn't stall the turbine, it just stops adding energy. - boolean hasActiveRecipe = recipeMapWorkable.isActive(); - boolean canSpin = hasActiveRecipe && sufficientFluids; - - if (canSpin) { - if (speed < maxSpeed) { - // Still spinning up - speed += getRotationAcceleration(); - } - // At or above maxSpeed: hold governor keeps rated RPM regardless of buffer state + isFull = energyContainer.getEnergyStored() - energyContainer.getEnergyCapacity() == 0; + generatingPower = !isFull && recipeMapWorkable.isWorking(); + + if (recipeMapWorkable.isWorking() && ((SuSyTurbineRecipeLogic) recipeMapWorkable).tryDrawEnergy()) { + speed += getRotationAcceleration(); lubricantCounter += speed; } else { - // No fuel or no recipe: coast down speed -= getRotationDeceleration(); } @@ -117,6 +107,7 @@ public void update() { } protected void updateSufficientFluids() { + // Check lubricant levels if (lubricantStack == null) { sufficientFluids = false; return; @@ -142,10 +133,12 @@ protected void setLubricantStack(IMultipleTankHandler tanks) { return; } } + this.lubricantStack = null; } @Override + // Save temperature to NBT data public NBTTagCompound writeToNBT(NBTTagCompound data) { super.writeToNBT(data); data.setInteger("Speed", this.speed); @@ -155,6 +148,7 @@ public NBTTagCompound writeToNBT(NBTTagCompound data) { } @Override + // Retrieve temperature from NBT data public void readFromNBT(NBTTagCompound data) { super.readFromNBT(data); this.speed = data.getInteger("Speed"); @@ -175,19 +169,16 @@ protected void addErrorText(List textList) { @Override protected long getMaxVoltage() { - // Output is purely a function of speed; no isFull gate. - // The energy container's own capacity caps what actually gets stored. - // This mirrors governor behavior: the turbine always produces at rated voltage - // when spinning; downstream load and buffer state don't affect shaft speed. - if (speed > 0 && ((SuSyTurbineRecipeLogic) recipeMapWorkable).tryDrawEnergy()) { + if (!isFull && speed > 0 && ((SuSyTurbineRecipeLogic) recipeMapWorkable).tryDrawEnergy()) { return ((SuSyTurbineRecipeLogic) recipeMapWorkable).getActualVoltage(); + } else { + return 0L; } - return 0L; } public class SuSyTurbineRecipeLogic extends MultiblockFuelRecipeLogic { - private final RotationGeneratorController tileEntity; + private RotationGeneratorController tileEntity; private int proposedEUt; protected boolean voidEnergy = false; @@ -199,26 +190,27 @@ public SuSyTurbineRecipeLogic(RotationGeneratorController tileEntity) { @Override public boolean checkRecipe(@NotNull Recipe recipe) { + // Hack to get the recipeEUt early proposedEUt = recipe.getEUt(); if (proposedEUt > getMaximumAllowedVoltage()) { return false; } - // Allow recipe to keep running when full; turbine stays on, - // drawEnergy will void if voidEnergy is set, or simply not store if buffer is full. return sufficientFluids; } @Override public int getInfoProviderEUt() { - if (speed > 0 && tryDrawEnergy()) { + if (!isFull && speed > 0 && tryDrawEnergy()) { return (int) getActualVoltage(); + } else { + return 0; } - return 0; } @Override protected void updateRecipeProgress() { if (canRecipeProgress && drawEnergy(recipeEUt, true)) { + // as recipe starts with progress on 1 this has to be > only not => to compensate for it if (++progressTime > getMaxProgress()) { completeRecipe(); } @@ -240,18 +232,19 @@ public boolean isWorking() { @Override protected boolean drawEnergy(int recipeEUt, boolean simulate) { - long euToDraw = -getActualVoltage(); // negative = generation + long euToDraw = -getActualVoltage(); // Will be negative long resultEnergy = getEnergyStored() - euToDraw; if (resultEnergy >= 0L && getEnergyStored() < getEnergyCapacity()) { - if (!simulate) getEnergyContainer().changeEnergy(-euToDraw); + if (!simulate) getEnergyContainer().changeEnergy(-euToDraw); // So this is positive return true; } - // Void excess to keep spinning when buffer is full + // Turbine voids excess fuel to keep spinning in any case. return voidEnergy; } public boolean tryDrawEnergy() { - return drawEnergy((int) getMaxParallelVoltage(), true); + return drawEnergy((int) getMaxParallelVoltage(), true); // have energy draw only tied to speed? (ignore + // recipe EUt entirely) } public boolean doDrawEnergy() { @@ -264,6 +257,7 @@ public int getMaxProgress() { if (lubricantStack != null) { return (int) (baseDuration * lubricantInfo.boost); } + return baseDuration; } From e072ccb85a8910f84b721fe00572e48ec82b6846 Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 27 Feb 2026 23:56:45 -0500 Subject: [PATCH 07/10] Prevent recipe start when energy buffer is full Add check to prevent recipe start if energy buffer is full. --- .../multi/electric/RotationGeneratorController.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/supersymmetry/common/metatileentities/multi/electric/RotationGeneratorController.java b/src/main/java/supersymmetry/common/metatileentities/multi/electric/RotationGeneratorController.java index 01fd3d88f..9a4e2948d 100644 --- a/src/main/java/supersymmetry/common/metatileentities/multi/electric/RotationGeneratorController.java +++ b/src/main/java/supersymmetry/common/metatileentities/multi/electric/RotationGeneratorController.java @@ -195,6 +195,11 @@ public boolean checkRecipe(@NotNull Recipe recipe) { if (proposedEUt > getMaximumAllowedVoltage()) { return false; } + // Prevent recipe from starting if energy buffer is full, and we're not voiding energy + if (isFull && !voidEnergy) { + return false; + } + return sufficientFluids; } From a55d9b9c193df06782e871e7315169704708fdf7 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 5 Mar 2026 14:49:34 -0500 Subject: [PATCH 08/10] no comment --- src/main/java/supersymmetry/api/fluids/FilteredTankWidget.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/supersymmetry/api/fluids/FilteredTankWidget.java b/src/main/java/supersymmetry/api/fluids/FilteredTankWidget.java index f3d09542a..2a605c84b 100644 --- a/src/main/java/supersymmetry/api/fluids/FilteredTankWidget.java +++ b/src/main/java/supersymmetry/api/fluids/FilteredTankWidget.java @@ -28,9 +28,8 @@ public boolean mouseClicked(int mouseX, int mouseY, int button) { if (itemHandler != null) { FluidStack heldFluid = itemHandler.drain(Integer.MAX_VALUE, false); if (heldFluid != null && heldFluid.amount > 0) { - // Simulate: would the tank accept this fluid? if (((IFluidHandler) fluidTank).fill(heldFluid, false) <= 0) { - return false; // block the click entirely — no packet sent + return false; } } } From b8c40d4b02772111a651c35cefb8fb4bba4c7b54 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 5 Mar 2026 17:38:14 -0500 Subject: [PATCH 09/10] Name change for bruberu --- ...yFluidTankWidget.java => SuSyFluidTankHandler.java} | 6 +++--- .../multi/electric/RotationGeneratorController.java | 3 +-- .../electric/SuSyMetaTileEntitySingleCombustion.java | 10 +++++----- 3 files changed, 9 insertions(+), 10 deletions(-) rename src/main/java/supersymmetry/api/fluids/{SuSyFluidTankWidget.java => SuSyFluidTankHandler.java} (91%) diff --git a/src/main/java/supersymmetry/api/fluids/SuSyFluidTankWidget.java b/src/main/java/supersymmetry/api/fluids/SuSyFluidTankHandler.java similarity index 91% rename from src/main/java/supersymmetry/api/fluids/SuSyFluidTankWidget.java rename to src/main/java/supersymmetry/api/fluids/SuSyFluidTankHandler.java index 19173765b..e4ffe0e9c 100644 --- a/src/main/java/supersymmetry/api/fluids/SuSyFluidTankWidget.java +++ b/src/main/java/supersymmetry/api/fluids/SuSyFluidTankHandler.java @@ -6,9 +6,9 @@ import gregtech.api.capability.impl.NotifiableFilteredFluidHandler; import gregtech.api.metatileentity.MetaTileEntity; -public class SuSyFluidTankWidget extends NotifiableFilteredFluidHandler { +public class SuSyFluidTankHandler extends NotifiableFilteredFluidHandler { - public SuSyFluidTankWidget(int capacity, MetaTileEntity entityToNotify, boolean isExport) { + public SuSyFluidTankHandler(int capacity, MetaTileEntity entityToNotify, boolean isExport) { super(capacity, entityToNotify, isExport); } @@ -56,7 +56,7 @@ public boolean canDrain() { @Override public boolean canFillFluidType(FluidStack fluidStack) { - boolean result = fluidStack != null && SuSyFluidTankWidget.this.canFillFluidType(fluidStack); + boolean result = fluidStack != null && SuSyFluidTankHandler.this.canFillFluidType(fluidStack); System.out.println("[SuSyFilteredFluidTank] getTankProperties().canFillFluidType() with: " + (fluidStack != null ? fluidStack.getFluid().getName() : "null") + ", result: " + result); diff --git a/src/main/java/supersymmetry/common/metatileentities/multi/electric/RotationGeneratorController.java b/src/main/java/supersymmetry/common/metatileentities/multi/electric/RotationGeneratorController.java index e3051ec13..606c36df9 100644 --- a/src/main/java/supersymmetry/common/metatileentities/multi/electric/RotationGeneratorController.java +++ b/src/main/java/supersymmetry/common/metatileentities/multi/electric/RotationGeneratorController.java @@ -1,4 +1,3 @@ - package supersymmetry.common.metatileentities.multi.electric; import java.util.List; @@ -199,7 +198,7 @@ public boolean checkRecipe(@NotNull Recipe recipe) { if (isFull && !voidEnergy) { return false; } - + return sufficientFluids; } diff --git a/src/main/java/supersymmetry/common/metatileentities/single/electric/SuSyMetaTileEntitySingleCombustion.java b/src/main/java/supersymmetry/common/metatileentities/single/electric/SuSyMetaTileEntitySingleCombustion.java index 828aabf10..275a96410 100644 --- a/src/main/java/supersymmetry/common/metatileentities/single/electric/SuSyMetaTileEntitySingleCombustion.java +++ b/src/main/java/supersymmetry/common/metatileentities/single/electric/SuSyMetaTileEntitySingleCombustion.java @@ -32,7 +32,7 @@ import gregtech.common.metatileentities.electric.MetaTileEntitySingleCombustion; import supersymmetry.api.capability.impl.SuSyFluidFilters; import supersymmetry.api.fluids.FilteredTankWidget; -import supersymmetry.api.fluids.SuSyFluidTankWidget; +import supersymmetry.api.fluids.SuSyFluidTankHandler; import supersymmetry.api.util.SuSyUtility; public class SuSyMetaTileEntitySingleCombustion extends MetaTileEntitySingleCombustion { @@ -45,8 +45,8 @@ public class SuSyMetaTileEntitySingleCombustion extends MetaTileEntitySingleComb private boolean sufficientFluids; - private SuSyFluidTankWidget lubricantTank; - private SuSyFluidTankWidget coolantTank; + private SuSyFluidTankHandler lubricantTank; + private SuSyFluidTankHandler coolantTank; private FluidTankList displayedTankList; @@ -77,9 +77,9 @@ protected FluidTankList createImportFluidHandler() { } // Lubricant/coolant tanks are standalone — NOT part of the import handler - this.lubricantTank = (SuSyFluidTankWidget) new SuSyFluidTankWidget(1000, this, false) + this.lubricantTank = (SuSyFluidTankHandler) new SuSyFluidTankHandler(1000, this, false) .setFilter(SuSyFluidFilters.LUBRICANT); - this.coolantTank = (SuSyFluidTankWidget) new SuSyFluidTankWidget(1000, this, false) + this.coolantTank = (SuSyFluidTankHandler) new SuSyFluidTankHandler(1000, this, false) .setFilter(SuSyFluidFilters.COOLANT); this.displayedTankList = new FluidTankList(false, displayedTanks); From af327456559a8cc54051960c595fe96ca93d9fe1 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 5 Mar 2026 18:09:32 -0500 Subject: [PATCH 10/10] Implement NBT read/write for tanks in SuSyMetaTileEntity Add NBT serialization for lubricant and coolant tanks --- .../SuSyMetaTileEntitySingleCombustion.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/main/java/supersymmetry/common/metatileentities/single/electric/SuSyMetaTileEntitySingleCombustion.java b/src/main/java/supersymmetry/common/metatileentities/single/electric/SuSyMetaTileEntitySingleCombustion.java index 275a96410..b0f90fd08 100644 --- a/src/main/java/supersymmetry/common/metatileentities/single/electric/SuSyMetaTileEntitySingleCombustion.java +++ b/src/main/java/supersymmetry/common/metatileentities/single/electric/SuSyMetaTileEntitySingleCombustion.java @@ -7,6 +7,7 @@ import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraftforge.fluids.FluidStack; @@ -62,6 +63,25 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { this.getTankScalingFunction()); } + @Override + public NBTTagCompound writeToNBT(NBTTagCompound data) { + super.writeToNBT(data); + if (lubricantTank != null) + data.setTag("LubricantTank", lubricantTank.writeToNBT(new NBTTagCompound())); + if (coolantTank != null) + data.setTag("CoolantTank", coolantTank.writeToNBT(new NBTTagCompound())); + return data; + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + if (lubricantTank != null && data.hasKey("LubricantTank")) + lubricantTank.readFromNBT(data.getCompoundTag("LubricantTank")); + if (coolantTank != null && data.hasKey("CoolantTank")) + coolantTank.readFromNBT(data.getCompoundTag("CoolantTank")); + } + @Override protected FluidTankList createImportFluidHandler() { if (workable == null) return new FluidTankList(false);