From 07046ce948e716b0b23dcac9f269ba5db30924f3 Mon Sep 17 00:00:00 2001 From: Integer Limit <103940576+IntegerLimit@users.noreply.github.com> Date: Wed, 23 Oct 2024 22:35:40 +1100 Subject: [PATCH 1/3] Fix Duplication Glitch with ME Storage Hatches/Buses --- .../capability/impl/MultiblockRecipeLogic.java | 8 ++++++++ .../interfaces/IRefreshBeforeConsumption.java | 13 +++++++++++++ .../RecipeMapMultiblockController.java | 16 ++++++++++++++++ .../generator/LargeTurbineWorkableHandler.java | 1 + .../appeng/MetaTileEntityMEStockingBus.java | 11 ++++++++++- .../appeng/MetaTileEntityMEStockingHatch.java | 11 ++++++++++- 6 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 src/main/java/gregtech/api/metatileentity/interfaces/IRefreshBeforeConsumption.java diff --git a/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java index ff95f0fbb0c..d0d780c85dc 100644 --- a/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java @@ -257,6 +257,8 @@ protected boolean checkPreviousRecipeDistinct(IItemHandlerModifiable previousBus } protected boolean prepareRecipeDistinct(Recipe recipe) { + ((RecipeMapMultiblockController) metaTileEntity).refreshAllBeforeConsumption(); + recipe = Recipe.trimRecipeOutputs(recipe, getRecipeMap(), metaTileEntity.getItemOutputLimit(), metaTileEntity.getFluidOutputLimit()); @@ -280,6 +282,12 @@ protected boolean prepareRecipeDistinct(Recipe recipe) { return false; } + @Override + public boolean prepareRecipe(Recipe recipe) { + ((RecipeMapMultiblockController) metaTileEntity).refreshAllBeforeConsumption(); + return super.prepareRecipe(recipe); + } + @Override protected void modifyOverclockPre(@NotNull OCParams ocParams, @NotNull RecipePropertyStorage storage) { super.modifyOverclockPre(ocParams, storage); diff --git a/src/main/java/gregtech/api/metatileentity/interfaces/IRefreshBeforeConsumption.java b/src/main/java/gregtech/api/metatileentity/interfaces/IRefreshBeforeConsumption.java new file mode 100644 index 00000000000..a6fd4b619e9 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/interfaces/IRefreshBeforeConsumption.java @@ -0,0 +1,13 @@ +package gregtech.api.metatileentity.interfaces; + +/** + * This Interface represents a MultiblockPart that should be refreshed before final recipe validation and input + * consumption. + */ +public interface IRefreshBeforeConsumption { + + /** + * Called Server Side Only. + */ + void refreshBeforeConsumption(); +} diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java b/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java index 4949074c91a..c6c8a75d0c8 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java @@ -10,6 +10,7 @@ import gregtech.api.capability.impl.MultiblockRecipeLogic; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.IDataInfoProvider; +import gregtech.api.metatileentity.interfaces.IRefreshBeforeConsumption; import gregtech.api.pattern.PatternMatchContext; import gregtech.api.pattern.TraceabilityPredicate; import gregtech.api.recipes.Recipe; @@ -32,11 +33,13 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; import com.google.common.collect.Lists; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; public abstract class RecipeMapMultiblockController extends MultiblockWithDisplayBase implements IDataInfoProvider, ICleanroomReceiver, IDistinctBusController { @@ -48,6 +51,7 @@ public abstract class RecipeMapMultiblockController extends MultiblockWithDispla protected IMultipleTankHandler inputFluidInventory; protected IMultipleTankHandler outputFluidInventory; protected IEnergyContainer energyContainer; + protected List refreshBeforeConsumptions; private boolean isDistinct = false; @@ -84,6 +88,12 @@ public MultiblockRecipeLogic getRecipeMapWorkable() { return recipeMapWorkable; } + public void refreshAllBeforeConsumption() { + for (var refresh : refreshBeforeConsumptions) { + refresh.refreshBeforeConsumption(); + } + } + /** * Performs extra checks for validity of given recipe before multiblock * will start it's processing. @@ -129,6 +139,11 @@ protected void initializeAbilities() { inputEnergy.addAll(getAbilities(MultiblockAbility.SUBSTATION_INPUT_ENERGY)); inputEnergy.addAll(getAbilities(MultiblockAbility.INPUT_LASER)); this.energyContainer = new EnergyContainerList(inputEnergy); + + this.refreshBeforeConsumptions = getMultiblockParts().stream() + .filter(p -> p instanceof IRefreshBeforeConsumption) + .map(p -> (IRefreshBeforeConsumption) p) + .collect(Collectors.toList()); } private void resetTileAbilities() { @@ -137,6 +152,7 @@ private void resetTileAbilities() { this.outputInventory = new GTItemStackHandler(this, 0); this.outputFluidInventory = new FluidTankList(true); this.energyContainer = new EnergyContainerList(Lists.newArrayList()); + this.refreshBeforeConsumptions = new ObjectArrayList<>(0); } protected boolean allowSameFluidFillForOutputs() { diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java index 46edc9619e7..685918509f6 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java @@ -149,6 +149,7 @@ public boolean prepareRecipe(Recipe recipe) { parallel = getParallel(recipe, holderEfficiency, turbineMaxVoltage); // Null check fluid here, since it can return null on first join into world or first form + ((RecipeMapMultiblockController) metaTileEntity).refreshAllBeforeConsumption(); FluidStack inputFluid = getInputFluidStack(); if (inputFluid == null || getInputFluidStack().amount < recipeFluidStack.amount * parallel) { return false; diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java index 640f7869617..1ea3a15bc29 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java @@ -6,6 +6,7 @@ import gregtech.api.gui.widgets.ImageCycleButtonWidget; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.interfaces.IRefreshBeforeConsumption; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; import gregtech.api.metatileentity.multiblock.RecipeMapMultiblockController; @@ -37,7 +38,7 @@ import static gregtech.api.capability.GregtechDataCodes.UPDATE_AUTO_PULL; -public class MetaTileEntityMEStockingBus extends MetaTileEntityMEInputBus { +public class MetaTileEntityMEStockingBus extends MetaTileEntityMEInputBus implements IRefreshBeforeConsumption { private static final int CONFIG_SIZE = 16; private boolean autoPull; @@ -391,6 +392,14 @@ protected void readConfigFromTag(NBTTagCompound tag) { super.readConfigFromTag(tag); } + @Override + public void refreshBeforeConsumption() { + if (isWorkingEnabled() && updateMEStatus()) { + if (autoPull) refreshList(); + syncME(); + } + } + private static class ExportOnlyAEStockingItemList extends ExportOnlyAEItemList { private final MetaTileEntityMEStockingBus holder; diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java index 30e28eff54b..3de38e5d889 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java @@ -6,6 +6,7 @@ import gregtech.api.gui.widgets.ImageCycleButtonWidget; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.interfaces.IRefreshBeforeConsumption; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidList; @@ -37,7 +38,7 @@ import static gregtech.api.capability.GregtechDataCodes.UPDATE_AUTO_PULL; -public class MetaTileEntityMEStockingHatch extends MetaTileEntityMEInputHatch { +public class MetaTileEntityMEStockingHatch extends MetaTileEntityMEInputHatch implements IRefreshBeforeConsumption { private static final int CONFIG_SIZE = 16; private boolean autoPull; @@ -294,6 +295,14 @@ protected void readConfigFromTag(NBTTagCompound tag) { super.readConfigFromTag(tag); } + @Override + public void refreshBeforeConsumption() { + if (isWorkingEnabled() && autoPull) { + refreshList(); + syncME(); + } + } + private static class ExportOnlyAEStockingFluidSlot extends ExportOnlyAEFluidSlot { public ExportOnlyAEStockingFluidSlot(MetaTileEntityMEStockingHatch holder, IAEFluidStack config, From a750894619f227eb664a6838162e7cb9b8b51dfc Mon Sep 17 00:00:00 2001 From: Integer Limit <103940576+IntegerLimit@users.noreply.github.com> Date: Mon, 11 Nov 2024 18:27:16 +1100 Subject: [PATCH 2/3] Review --- .../multiblock/RecipeMapMultiblockController.java | 12 +++++++----- .../appeng/MetaTileEntityMEStockingHatch.java | 4 ++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java b/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java index c6c8a75d0c8..4d5fa36787d 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java @@ -61,6 +61,7 @@ public RecipeMapMultiblockController(ResourceLocation metaTileEntityId, RecipeMa super(metaTileEntityId); this.recipeMap = recipeMap; this.recipeMapWorkable = new MultiblockRecipeLogic(this); + this.refreshBeforeConsumptions = new ArrayList<>(); resetTileAbilities(); } @@ -140,10 +141,11 @@ protected void initializeAbilities() { inputEnergy.addAll(getAbilities(MultiblockAbility.INPUT_LASER)); this.energyContainer = new EnergyContainerList(inputEnergy); - this.refreshBeforeConsumptions = getMultiblockParts().stream() - .filter(p -> p instanceof IRefreshBeforeConsumption) - .map(p -> (IRefreshBeforeConsumption) p) - .collect(Collectors.toList()); + for (IMultiblockPart part : getMultiblockParts()) { + if (part instanceof IRefreshBeforeConsumption refresh) { + refreshBeforeConsumptions.add(refresh); + } + } } private void resetTileAbilities() { @@ -152,7 +154,7 @@ private void resetTileAbilities() { this.outputInventory = new GTItemStackHandler(this, 0); this.outputFluidInventory = new FluidTankList(true); this.energyContainer = new EnergyContainerList(Lists.newArrayList()); - this.refreshBeforeConsumptions = new ObjectArrayList<>(0); + this.refreshBeforeConsumptions.clear(); } protected boolean allowSameFluidFillForOutputs() { diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java index 3de38e5d889..70ca03c18ff 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java @@ -297,8 +297,8 @@ protected void readConfigFromTag(NBTTagCompound tag) { @Override public void refreshBeforeConsumption() { - if (isWorkingEnabled() && autoPull) { - refreshList(); + if (isWorkingEnabled() && updateMEStatus()) { + if (autoPull) refreshList(); syncME(); } } From 3a03d0803d8d1d691870e281a99693606c0de2fe Mon Sep 17 00:00:00 2001 From: Integer Limit <103940576+IntegerLimit@users.noreply.github.com> Date: Mon, 11 Nov 2024 18:33:11 +1100 Subject: [PATCH 3/3] Spotless --- .../multiblock/RecipeMapMultiblockController.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java b/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java index 4d5fa36787d..57fdcf9b1c7 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java @@ -33,13 +33,11 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; import com.google.common.collect.Lists; -import it.unimi.dsi.fastutil.objects.ObjectArrayList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; public abstract class RecipeMapMultiblockController extends MultiblockWithDisplayBase implements IDataInfoProvider, ICleanroomReceiver, IDistinctBusController {