From 78b7416cba4b396d9d913ae20b3c051e6861777a Mon Sep 17 00:00:00 2001 From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com> Date: Mon, 2 Sep 2024 11:58:20 -0600 Subject: [PATCH] Various Recipe Logic fixes (#1880) Co-authored-by: YoungOnionMC --- .../recipe/FluidRecipeCapability.java | 31 +++---- .../api/machine/SimpleGeneratorMachine.java | 5 +- .../api/machine/steam/SimpleSteamMachine.java | 5 -- .../api/machine/steam/SteamBoilerMachine.java | 3 +- .../gtceu/api/recipe/RecipeHelper.java | 1 + .../recipe/modifier/RecipeModifierList.java | 9 +- .../gtceu/common/data/GTRecipeModifiers.java | 4 +- .../LargeCombustionEngineMachine.java | 8 +- .../generator/LargeTurbineMachine.java | 6 +- .../steam/SteamParallelMultiblockMachine.java | 10 +-- .../ae2/machine/MEOutputBusPartMachine.java | 80 ++++++++++++++++-- .../ae2/machine/MEOutputHatchPartMachine.java | 83 ++++++++++++++++++- .../gtceu/utils/OverlayedFluidHandler.java | 4 +- 13 files changed, 192 insertions(+), 57 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/FluidRecipeCapability.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/FluidRecipeCapability.java index 3bff033d1b..9411da91bf 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/FluidRecipeCapability.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/FluidRecipeCapability.java @@ -157,34 +157,35 @@ public int limitParallel(GTRecipe recipe, IRecipeCapabilityHolder holder, int mu .map(IFluidTransfer.class::cast) .toList())); + List recipeOutputs = recipe.getOutputContents(FluidRecipeCapability.CAP) + .stream() + .map(content -> FluidRecipeCapability.CAP.of(content.getContent())) + .filter(ingredient -> !ingredient.isEmpty()) + .map(ingredient -> ingredient.getStacks()[0]) + .toList(); + while (minMultiplier != maxMultiplier) { overlayedFluidHandler.reset(); - long amountLeft = 0; + long returnedAmount = 0; + long amountToInsert = 0; - for (FluidStack fluidStack : recipe.getOutputContents(FluidRecipeCapability.CAP) - .stream() - .map(FluidRecipeCapability.CAP::of) - .filter(ingredient -> !ingredient.isEmpty()) - .map(ingredient -> ingredient.getStacks()[0]) - .toList()) { + for (FluidStack fluidStack : recipeOutputs) { if (fluidStack.getAmount() <= 0) continue; + if (fluidStack.isEmpty()) continue; // Since multiplier starts at Int.MAX, check here for integer overflow if (multiplier > Integer.MAX_VALUE / fluidStack.getAmount()) { - amountLeft = Integer.MAX_VALUE; + amountToInsert = Integer.MAX_VALUE; } else { - amountLeft = fluidStack.getAmount() * multiplier; - } - long inserted = overlayedFluidHandler.insertFluid(fluidStack, amountLeft); - if (inserted > 0) { - amountLeft -= inserted; + amountToInsert = fluidStack.getAmount() * multiplier; } - if (amountLeft > 0) { + returnedAmount = amountToInsert - overlayedFluidHandler.insertFluid(fluidStack, amountToInsert); + if (returnedAmount > 0) { break; } } - int[] bin = ParallelLogic.adjustMultiplier(amountLeft == 0, minMultiplier, multiplier, maxMultiplier); + int[] bin = ParallelLogic.adjustMultiplier(returnedAmount == 0, minMultiplier, multiplier, maxMultiplier); minMultiplier = bin[0]; multiplier = bin[1]; maxMultiplier = bin[2]; diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/SimpleGeneratorMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/SimpleGeneratorMachine.java index e6b0b59dbc..f14dae966f 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/SimpleGeneratorMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/SimpleGeneratorMachine.java @@ -101,7 +101,10 @@ public static GTRecipe recipeModifier(MetaMachine machine, @NotNull GTRecipe rec if (EUt > 0) { var maxParallel = (int) (Math.min(generator.getOverclockVoltage(), GTValues.V[generator.getOverclockTier()]) / EUt); - return GTRecipeModifiers.fastParallel(generator, recipe, maxParallel, false).getFirst(); + var paraRecipe = GTRecipeModifiers.fastParallel(generator, recipe, maxParallel, false); + result.init(-RecipeHelper.getOutputEUt(paraRecipe.getFirst()), paraRecipe.getFirst().duration, + paraRecipe.getSecond()); + return paraRecipe.getFirst(); } } return null; diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SimpleSteamMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SimpleSteamMachine.java index 1ba9225179..fd5337be50 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SimpleSteamMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SimpleSteamMachine.java @@ -143,11 +143,6 @@ public static GTRecipe recipeModifier(MetaMachine machine, @NotNull GTRecipe rec result.init(RecipeHelper.getInputEUt(recipe), modified.duration * 2); } - if (!steamMachine.isHighPressure) { - modified.duration *= 2; - RecipeHelper.setInputEUt(modified, RecipeHelper.getInputEUt(recipe) / 2); - } - return modified; } return null; diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamBoilerMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamBoilerMachine.java index 13332a9c60..7082636dfa 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamBoilerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamBoilerMachine.java @@ -12,6 +12,7 @@ import com.gregtechceu.gtceu.api.machine.feature.IUIMachine; import com.gregtechceu.gtceu.api.machine.trait.NotifiableFluidTank; import com.gregtechceu.gtceu.api.recipe.GTRecipe; +import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.recipe.logic.OCParams; import com.gregtechceu.gtceu.api.recipe.logic.OCResult; import com.gregtechceu.gtceu.common.data.GTMaterials; @@ -260,10 +261,10 @@ public static GTRecipe recipeModifier(MetaMachine machine, @NotNull GTRecipe rec @NotNull OCResult result) { if (machine instanceof SteamBoilerMachine boilerMachine) { recipe = recipe.copy(); + result.init(RecipeHelper.getInputEUt(recipe), recipe.duration); if (boilerMachine.isHighPressure) result.setDuration(result.getDuration() / 2); // recipe.duration *= 12; // maybe? - recipe.duration = boilerMachine.isHighPressure ? recipe.duration / 2 : recipe.duration; return recipe; } return null; diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java index 1e9a30c042..d726432aae 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java @@ -55,6 +55,7 @@ public static int getRecipeEUtTier(GTRecipe recipe) { if (EUt == 0) { EUt = getOutputEUt(recipe); } + if (recipe.parallels > 1) EUt /= recipe.parallels; return GTUtil.getTierByVoltage(EUt); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/modifier/RecipeModifierList.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/modifier/RecipeModifierList.java index 6db0c8c333..de3ca61e6d 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/modifier/RecipeModifierList.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/modifier/RecipeModifierList.java @@ -40,8 +40,13 @@ public GTRecipe apply(MetaMachine machine, @NotNull GTRecipe recipe, @NotNull OC if (modifiedRecipe != null) { modifiedRecipe.duration = result.getDuration(); - modifiedRecipe.tickInputs.put(EURecipeCapability.CAP, List.of(new Content(result.getEut(), - ChanceLogic.getMaxChancedValue(), ChanceLogic.getMaxChancedValue(), 0, null, null))); + if (result.getEut() > 0) { + modifiedRecipe.tickInputs.put(EURecipeCapability.CAP, List.of(new Content(result.getEut(), + ChanceLogic.getMaxChancedValue(), ChanceLogic.getMaxChancedValue(), 0, null, null))); + } else { + modifiedRecipe.tickOutputs.put(EURecipeCapability.CAP, List.of(new Content(-result.getEut(), + ChanceLogic.getMaxChancedValue(), ChanceLogic.getMaxChancedValue(), 0, null, null))); + } if (result.getParallel() > 1) { modifiedRecipe = ParallelLogic.applyParallel(machine, modifiedRecipe, result.getParallel(), false) diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeModifiers.java b/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeModifiers.java index 4692d891bd..44958e0446 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeModifiers.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeModifiers.java @@ -225,9 +225,9 @@ public static GTRecipe pyrolyseOvenOverclock(MetaMachine machine, @NotNull GTRec if (coilMachine.getCoilTier() == 0) { // 75% speed with cupro coils - result.setDuration(Math.max(1, (int) recipe.duration * 4 / 3)); + result.setDuration(Math.max(1, (int) result.getDuration() * 4 / 3)); } else { - result.setDuration(Math.max(1, (int) (recipe.duration * 2.0 / (tier + 1)))); + result.setDuration(Math.max(1, (int) (result.getDuration() * 2.0 / (tier + 1)))); } return re; } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeCombustionEngineMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeCombustionEngineMachine.java index abd08fd155..38bf3e956f 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeCombustionEngineMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeCombustionEngineMachine.java @@ -1,7 +1,6 @@ package com.gregtechceu.gtceu.common.machine.multiblock.generator; import com.gregtechceu.gtceu.api.GTValues; -import com.gregtechceu.gtceu.api.capability.recipe.EURecipeCapability; import com.gregtechceu.gtceu.api.capability.recipe.IO; import com.gregtechceu.gtceu.api.fluids.store.FluidStorageKeys; import com.gregtechceu.gtceu.api.gui.GuiTextures; @@ -13,8 +12,6 @@ import com.gregtechceu.gtceu.api.machine.multiblock.WorkableElectricMultiblockMachine; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.RecipeHelper; -import com.gregtechceu.gtceu.api.recipe.chance.logic.ChanceLogic; -import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.api.recipe.logic.OCParams; import com.gregtechceu.gtceu.api.recipe.logic.OCResult; import com.gregtechceu.gtceu.common.data.GTMaterials; @@ -122,11 +119,12 @@ public static GTRecipe recipeModifier(MetaMachine machine, @NotNull GTRecipe rec if (engineMachine.isOxygenBoosted) { // boost production recipe = parallelResult.getFirst() == recipe ? recipe.copy() : parallelResult.getFirst(); long eut = (long) (EUt * parallelResult.getSecond() * (engineMachine.isExtreme() ? 2 : 1.5)); - recipe.tickOutputs.put(EURecipeCapability.CAP, List.of(new Content(eut, - ChanceLogic.getMaxChancedValue(), ChanceLogic.getMaxChancedValue(), 0, null, null))); + result.init(-eut, recipe.duration, parallelResult.getSecond()); } else { recipe = parallelResult.getFirst(); + result.init(-RecipeHelper.getOutputEUt(recipe), recipe.duration, parallelResult.getSecond()); } + return recipe; } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeTurbineMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeTurbineMachine.java index 2e0d296179..c26c127f73 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeTurbineMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeTurbineMachine.java @@ -11,8 +11,6 @@ import com.gregtechceu.gtceu.api.machine.multiblock.WorkableElectricMultiblockMachine; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.RecipeHelper; -import com.gregtechceu.gtceu.api.recipe.chance.logic.ChanceLogic; -import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.api.recipe.logic.OCParams; import com.gregtechceu.gtceu.api.recipe.logic.OCResult; import com.gregtechceu.gtceu.common.data.GTRecipeModifiers; @@ -116,8 +114,8 @@ public static GTRecipe recipeModifier(MetaMachine machine, @NotNull GTRecipe rec recipe = parallelResult.getFirst() == recipe ? recipe.copy() : parallelResult.getFirst(); long eut = turbineMachine.boostProduction((long) (EUt * holderEfficiency * parallelResult.getSecond())); - recipe.tickOutputs.put(EURecipeCapability.CAP, List.of(new Content(eut, - ChanceLogic.getMaxChancedValue(), ChanceLogic.getMaxChancedValue(), 0, null, null))); + + result.init(-eut, recipe.duration, parallelResult.getSecond()); return recipe; } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java index 245b98a3f9..26dce288da 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java @@ -13,8 +13,6 @@ import com.gregtechceu.gtceu.api.machine.trait.NotifiableFluidTank; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.RecipeHelper; -import com.gregtechceu.gtceu.api.recipe.chance.logic.ChanceLogic; -import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.api.recipe.logic.OCParams; import com.gregtechceu.gtceu.api.recipe.logic.OCResult; import com.gregtechceu.gtceu.common.data.GTMaterials; @@ -81,15 +79,11 @@ public static GTRecipe recipeModifier(MetaMachine machine, @NotNull GTRecipe rec int duration = recipe.duration; var eut = RecipeHelper.getInputEUt(recipe); var parallelRecipe = GTRecipeModifiers.accurateParallel(machine, recipe, MAX_PARALLELS, false); - recipe = parallelRecipe.getFirst() == recipe ? parallelRecipe.getFirst().copy() : parallelRecipe.getFirst(); + recipe = parallelRecipe.getFirst() == recipe ? recipe : parallelRecipe.getFirst(); // we remove tick inputs, as our "cost" is just steam now, just stored as EU/t // also set the duration to just 1.5x the original, instead of fully multiplied - result.setDuration((int) (duration * 1.5)); - result.setEut((long) Math.min(32, Math.ceil(eut * 1.33))); - result.setParallel(parallelRecipe.getSecond()); - recipe.tickInputs.put(EURecipeCapability.CAP, List.of(new Content(eut, - ChanceLogic.getMaxChancedValue(), ChanceLogic.getMaxChancedValue(), 0, null, null))); + result.init((long) Math.min(32, Math.ceil(eut * 1.33)), (int) (duration * 1.5), parallelRecipe.getSecond()); return recipe; } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEOutputBusPartMachine.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEOutputBusPartMachine.java index c0aa936c2f..5b26de1738 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEOutputBusPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEOutputBusPartMachine.java @@ -11,9 +11,11 @@ import com.gregtechceu.gtceu.integration.ae2.utils.KeyStorage; import com.lowdragmc.lowdraglib.gui.widget.LabelWidget; +import com.lowdragmc.lowdraglib.gui.widget.SlotWidget; import com.lowdragmc.lowdraglib.gui.widget.Widget; import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; import com.lowdragmc.lowdraglib.misc.ItemStackTransfer; +import com.lowdragmc.lowdraglib.syncdata.ISubscription; import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; @@ -23,6 +25,8 @@ import appeng.api.config.Actionable; import appeng.api.stacks.AEItemKey; +import appeng.items.materials.StorageComponentItem; +import lombok.Getter; import lombok.NoArgsConstructor; import org.jetbrains.annotations.Nullable; @@ -44,6 +48,14 @@ public class MEOutputBusPartMachine extends MEBusPartMachine implements IMachine @Persisted private KeyStorage internalBuffer; // Do not use KeyCounter, use our simple implementation + @Getter + @Persisted + protected NotifiableItemStackHandler storageSlot; + + @Nullable + protected ISubscription storageSub; + + private long capacitySize = 0; public MEOutputBusPartMachine(IMachineBlockEntity holder, Object... args) { super(holder, IO.OUT, args); @@ -56,9 +68,41 @@ public MEOutputBusPartMachine(IMachineBlockEntity holder, Object... args) { @Override protected NotifiableItemStackHandler createInventory(Object... args) { this.internalBuffer = new KeyStorage(); + this.storageSlot = new NotifiableItemStackHandler(this, 1, io); + this.storageSlot.setFilter(item -> canInsertCell(item)); return new InaccessibleInfiniteHandler(this); } + @Override + public void onLoad() { + super.onLoad(); + if (isRemote()) return; + + storageSub = storageSlot.addChangedListener(this::updateStorageSize); + updateStorageSize(); + } + + private boolean canInsertCell(ItemStack item) { + var grid = getMainNode().getGrid(); + if (item.getItem() instanceof StorageComponentItem compItem) { + long newSize = (long) compItem.getBytes(item) * 8L; + if (newSize >= capacitySize) { + return true; + } else { + return ((InaccessibleInfiniteHandler) (getInventory())).getCachedAmount() >= newSize; + } + } + return false; + } + + private void updateStorageSize() { + if (this.storageSlot.getStackInSlot(0).getItem() instanceof StorageComponentItem compItem) { + capacitySize = (compItem.getBytes(this.storageSlot.getStackInSlot(0)) * 8L); + } else if (this.storageSlot.getStackInSlot(0).isEmpty()) { + capacitySize = 64L; + } + } + @Override public void onMachineRemoved() { var grid = getMainNode().getGrid(); @@ -110,6 +154,7 @@ public Widget createUIWidget() { "gtceu.gui.me_network.offline")); group.addWidget(new LabelWidget(5, 10, "gtceu.gui.waiting_list")); // display list + group.addWidget(new SlotWidget(storageSlot.storage, 0, 140, 0)); group.addWidget(new AEListGridWidget.Item(5, 20, 3, this.internalBuffer)); return group; @@ -136,9 +181,25 @@ public int getSize() { return Integer.MAX_VALUE; } + private long getCachedAmount() { + long itemAmount = 0; + var grid = getMainNode().getGrid(); + if (grid != null && !internalBuffer.isEmpty()) { + for (var slot : internalBuffer) { + itemAmount += grid.getStorageService().getInventory().getAvailableStacks() + .get(slot.getKey()); + } + } + return itemAmount; + } + + private boolean canInsertItem() { + return getCachedAmount() < capacitySize; + } + @Override public int getSlotLimit(int slot) { - return Integer.MAX_VALUE; // todo add me components for sizing + return Integer.MAX_VALUE; } @Override @@ -177,15 +238,18 @@ public ItemStack insertItem( int count = stack.getCount(); long oldValue = internalBuffer.storage.getOrDefault(key, 0); long changeValue = Math.min(Long.MAX_VALUE - oldValue, count); - if (changeValue > 0) { - if (!simulate) { - internalBuffer.storage.put(key, oldValue + changeValue); - internalBuffer.onChanged(); + if (canInsertItem()) { + if (changeValue > 0) { + if (!simulate) { + internalBuffer.storage.put(key, oldValue + changeValue); + internalBuffer.onChanged(); + } + return stack.copyWithCount((int) (count - changeValue)); + } else { + return ItemStack.EMPTY; } - return stack.copyWithCount((int) (count - changeValue)); - } else { - return ItemStack.EMPTY; } + return ItemStack.EMPTY; } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEOutputHatchPartMachine.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEOutputHatchPartMachine.java index 4c956a4e2e..4e175847d3 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEOutputHatchPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEOutputHatchPartMachine.java @@ -5,23 +5,29 @@ import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.machine.feature.IMachineLife; import com.gregtechceu.gtceu.api.machine.trait.NotifiableFluidTank; +import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.ingredient.FluidIngredient; import com.gregtechceu.gtceu.integration.ae2.gui.widget.list.AEListGridWidget; import com.gregtechceu.gtceu.integration.ae2.utils.KeyStorage; import com.lowdragmc.lowdraglib.gui.widget.LabelWidget; +import com.lowdragmc.lowdraglib.gui.widget.SlotWidget; import com.lowdragmc.lowdraglib.gui.widget.Widget; import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; import com.lowdragmc.lowdraglib.misc.FluidStorage; import com.lowdragmc.lowdraglib.side.fluid.FluidStack; +import com.lowdragmc.lowdraglib.syncdata.ISubscription; import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; import net.minecraft.MethodsReturnNonnullByDefault; +import net.minecraft.world.item.ItemStack; import appeng.api.config.Actionable; import appeng.api.stacks.AEFluidKey; +import appeng.items.materials.StorageComponentItem; +import lombok.Getter; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -38,6 +44,15 @@ public class MEOutputHatchPartMachine extends MEHatchPartMachine implements IMac @Persisted private KeyStorage internalBuffer; // Do not use KeyCounter, use our simple implementation + @Getter + @Persisted + protected NotifiableItemStackHandler storageSlot; + + @Nullable + protected ISubscription storageSub; + + private long capacitySize = 0; + public MEOutputHatchPartMachine(IMachineBlockEntity holder, Object... args) { super(holder, IO.IN, args); } @@ -47,12 +62,43 @@ public MEOutputHatchPartMachine(IMachineBlockEntity holder, Object... args) { ///////////////////////////////// @Override - protected NotifiableFluidTank createTank(long initialCapacity, int slots, Object... args) { this.internalBuffer = new KeyStorage(); + this.storageSlot = new NotifiableItemStackHandler(this, 1, io); + this.storageSlot.setFilter(item -> canInsertCell(item)); return new InaccessibleInfiniteTank(this); } + @Override + public void onLoad() { + super.onLoad(); + if (isRemote()) return; + + storageSub = storageSlot.addChangedListener(this::updateStorageSize); + updateStorageSize(); + } + + private boolean canInsertCell(ItemStack item) { + var grid = getMainNode().getGrid(); + if (item.getItem() instanceof StorageComponentItem compItem) { + long newSize = (long) compItem.getBytes(item) * 8L; + if (newSize >= capacitySize) { + return true; + } else { + return ((MEOutputHatchPartMachine.InaccessibleInfiniteTank) (tank)).getCachedAmount() >= newSize; + } + } + return false; + } + + private void updateStorageSize() { + if (this.storageSlot.getStackInSlot(0).getItem() instanceof StorageComponentItem compItem) { + capacitySize = (compItem.getBytes(this.storageSlot.getStackInSlot(0)) * 8L); + } else if (this.storageSlot.getStackInSlot(0).isEmpty()) { + capacitySize = 64L; + } + } + @Override public void onMachineRemoved() { var grid = getMainNode().getGrid(); @@ -105,6 +151,7 @@ public Widget createUIWidget() { "gtceu.gui.me_network.offline")); group.addWidget(new LabelWidget(5, 10, "gtceu.gui.waiting_list")); // display list + group.addWidget(new SlotWidget(storageSlot.storage, 0, 140, 0)); group.addWidget(new AEListGridWidget.Fluid(5, 20, 3, this.internalBuffer)); return group; @@ -127,6 +174,27 @@ public FluidStorage[] getStorages() { return this.fluidStorages; } + @Override + public int getSize() { + return Integer.MAX_VALUE; + } + + private long getCachedAmount() { + long fluidAmount = 0; + var grid = getMainNode().getGrid(); + if (grid != null && internalBuffer.isEmpty()) { + for (var tank : internalBuffer) { + fluidAmount += grid.getStorageService().getInventory().getAvailableStacks() + .get(tank.getKey()); + } + } + return fluidAmount; + } + + private boolean canInsertFluid() { + return getCachedAmount() < capacitySize; + } + @Override public @Nullable List handleRecipeInner(IO io, GTRecipe recipe, List left, @Nullable String slotName, boolean simulate) { @@ -139,6 +207,11 @@ public FluidStorageDelegate() { super(0L); } + @Override + public long getCapacity() { + return Long.MAX_VALUE; + } + @Override public void setFluid(FluidStack fluid) { // NO-OP @@ -150,9 +223,11 @@ public long fill(int tank, FluidStack resource, boolean simulate, boolean notify long amount = resource.getAmount(); long oldValue = internalBuffer.storage.getOrDefault(key, 0); long changeValue = Math.min(Long.MAX_VALUE - oldValue, amount); - if (changeValue > 0 && !simulate) { - internalBuffer.storage.put(key, oldValue + changeValue); - internalBuffer.onChanged(); + if (canInsertFluid()) { + if (changeValue > 0 && !simulate) { + internalBuffer.storage.put(key, oldValue + changeValue); + internalBuffer.onChanged(); + } } return changeValue; } diff --git a/src/main/java/com/gregtechceu/gtceu/utils/OverlayedFluidHandler.java b/src/main/java/com/gregtechceu/gtceu/utils/OverlayedFluidHandler.java index f485f5fe04..1f987e01cc 100644 --- a/src/main/java/com/gregtechceu/gtceu/utils/OverlayedFluidHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/utils/OverlayedFluidHandler.java @@ -59,7 +59,7 @@ public long insertFluid(@NotNull FluidStack fluid, long amountToInsert) { // search for tanks with same fluid type first for (OverlayedTank overlayedTank : this.overlayedTanks) { // if the fluid to insert matches the tank, insert the fluid - if (overlayedTank.fluid != null && fluid.isFluidEqual(overlayedTank.fluid)) { + if (!overlayedTank.isEmpty() && overlayedTank.fluid != null && fluid.isFluidEqual(overlayedTank.fluid)) { long inserted = overlayedTank.tryInsert(fluid, amountToInsert); if (inserted > 0) { totalInserted += inserted; @@ -152,7 +152,7 @@ public boolean isEmpty() { * @return Amount of fluid inserted into this tank */ public long tryInsert(@NotNull FluidStack fluid, long amount) { - if (this.fluid == FluidStack.empty()) { + if (this.fluid.isEmpty()) { this.fluid = fluid.copy(); this.fluid.setAmount(Math.min(this.property.getCapacity(), amount)); return this.fluid.getAmount();