From 6632344f877f8f1b0640f390ebba52b233e15d8f Mon Sep 17 00:00:00 2001 From: Yang Xizhi <60341015+GlodBlock@users.noreply.github.com> Date: Sun, 9 Jun 2024 12:53:20 +0800 Subject: [PATCH] Make ME Interfaces insert items/fluids directly into storage if possible (#448) --- .../fluids/helper/DualityFluidInterface.java | 15 +++++- .../fluids/util/AENetworkFluidInventory.java | 47 ++++++++++++++++++ .../java/appeng/helpers/DualityInterface.java | 14 +++++- .../inventory/AppEngNetworkInventory.java | 48 +++++++++++++++++++ 4 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 src/main/java/appeng/fluids/util/AENetworkFluidInventory.java create mode 100644 src/main/java/appeng/tile/inventory/AppEngNetworkInventory.java diff --git a/src/main/java/appeng/fluids/helper/DualityFluidInterface.java b/src/main/java/appeng/fluids/helper/DualityFluidInterface.java index e9edb98a006..0c49bf82f0e 100644 --- a/src/main/java/appeng/fluids/helper/DualityFluidInterface.java +++ b/src/main/java/appeng/fluids/helper/DualityFluidInterface.java @@ -32,6 +32,7 @@ import appeng.api.networking.energy.IEnergySource; import appeng.api.networking.security.IActionHost; import appeng.api.networking.security.IActionSource; +import appeng.api.networking.storage.IStorageGrid; import appeng.api.networking.ticking.IGridTickable; import appeng.api.networking.ticking.TickRateModulation; import appeng.api.networking.ticking.TickingRequest; @@ -49,6 +50,7 @@ import appeng.core.settings.TickRates; import appeng.fluids.util.AEFluidInventory; import appeng.fluids.util.AEFluidStack; +import appeng.fluids.util.AENetworkFluidInventory; import appeng.fluids.util.IAEFluidInventory; import appeng.fluids.util.IAEFluidTank; import appeng.helpers.ICustomNameObject; @@ -90,6 +92,7 @@ import net.minecraftforge.fml.common.Loader; import net.minecraftforge.items.IItemHandler; +import javax.annotation.Nullable; import java.util.Collection; import java.util.EnumSet; import java.util.HashSet; @@ -109,7 +112,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable private final UpgradeInventory upgrades; private boolean hasConfig = false; private final IStorageMonitorableAccessor accessor = this::getMonitorable; - private final AEFluidInventory tanks = new AEFluidInventory(this, NUMBER_OF_TANKS, TANK_CAPACITY); + private final AEFluidInventory tanks; private final AEFluidInventory config = new AEFluidInventory(this, NUMBER_OF_TANKS); private final IAEFluidStack[] requireWork; private int isWorking = -1; @@ -131,6 +134,7 @@ public DualityFluidInterface(final AENetworkProxy networkProxy, final IFluidInte this.mySource = new MachineSource(this.iHost); this.interfaceRequestSource = new InterfaceRequestSource(this.iHost); + this.tanks = new AENetworkFluidInventory(this::getStorageGrid, this.mySource, this, NUMBER_OF_TANKS, TANK_CAPACITY); this.fluids.setChangeSource(this.mySource); this.items.setChangeSource(this.mySource); @@ -141,6 +145,15 @@ public DualityFluidInterface(final AENetworkProxy networkProxy, final IFluidInte } } + @Nullable + private IStorageGrid getStorageGrid() { + try { + return this.gridProxy.getStorage(); + } catch (GridAccessException e) { + return null; + } + } + public IUpgradeableHost getHost() { return this.iHost; } diff --git a/src/main/java/appeng/fluids/util/AENetworkFluidInventory.java b/src/main/java/appeng/fluids/util/AENetworkFluidInventory.java new file mode 100644 index 00000000000..bf5906d02ad --- /dev/null +++ b/src/main/java/appeng/fluids/util/AENetworkFluidInventory.java @@ -0,0 +1,47 @@ +package appeng.fluids.util; + +import appeng.api.AEApi; +import appeng.api.config.Actionable; +import appeng.api.networking.security.IActionSource; +import appeng.api.networking.storage.IStorageGrid; +import appeng.api.storage.IMEInventory; +import appeng.api.storage.channels.IFluidStorageChannel; +import appeng.api.storage.data.IAEFluidStack; +import net.minecraftforge.fluids.FluidStack; + +import java.util.function.Supplier; + +public class AENetworkFluidInventory extends AEFluidInventory { + + private final Supplier supplier; + private final IActionSource source; + + public AENetworkFluidInventory(Supplier networkSupplier, IActionSource source, IAEFluidInventory handler, int slots, int capcity) { + super(handler, slots, capcity); + this.supplier = networkSupplier; + this.source = source; + } + + @Override + public int fill(final FluidStack fluid, final boolean doFill) { + if (fluid == null || fluid.amount <= 0) { + return 0; + } + IStorageGrid storage = supplier.get(); + if (storage != null) { + int originAmt = fluid.amount; + IMEInventory dest = storage.getInventory(AEApi.instance().storage().getStorageChannel(IFluidStorageChannel.class)); + IAEFluidStack overflow = dest.injectItems(AEFluidStack.fromFluidStack(fluid), doFill ? Actionable.MODULATE : Actionable.SIMULATE, this.source); + if (overflow != null && overflow.getStackSize() == originAmt) { + return super.fill(fluid, doFill); + } else if (overflow != null) { + return (int) (originAmt - overflow.getStackSize()); + } else { + return originAmt; + } + } else { + return super.fill(fluid, doFill); + } + } + +} diff --git a/src/main/java/appeng/helpers/DualityInterface.java b/src/main/java/appeng/helpers/DualityInterface.java index cb40534e123..26b716cfafc 100644 --- a/src/main/java/appeng/helpers/DualityInterface.java +++ b/src/main/java/appeng/helpers/DualityInterface.java @@ -35,6 +35,7 @@ import appeng.api.networking.events.MENetworkCraftingPatternChange; import appeng.api.networking.security.IActionHost; import appeng.api.networking.security.IActionSource; +import appeng.api.networking.storage.IStorageGrid; import appeng.api.networking.ticking.IGridTickable; import appeng.api.networking.ticking.TickRateModulation; import appeng.api.networking.ticking.TickingRequest; @@ -64,6 +65,7 @@ import appeng.tile.inventory.AppEngInternalAEInventory; import appeng.tile.inventory.AppEngInternalInventory; import appeng.tile.inventory.AppEngInternalOversizedInventory; +import appeng.tile.inventory.AppEngNetworkInventory; import appeng.tile.networking.TileCableBus; import appeng.util.ConfigManager; import appeng.util.IConfigManagerHost; @@ -118,7 +120,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn private final IActionSource interfaceRequestSource; private final ConfigManager cm = new ConfigManager(this); private final AppEngInternalAEInventory config = new AppEngInternalAEInventory(this, NUMBER_OF_CONFIG_SLOTS, 512); - private final AppEngInternalInventory storage = new AppEngInternalOversizedInventory(this, NUMBER_OF_STORAGE_SLOTS, 512); + private final AppEngInternalInventory storage; private final AppEngInternalInventory patterns = new AppEngInternalInventory(this, NUMBER_OF_PATTERN_SLOTS, 1); private final MEMonitorPassThrough items = new MEMonitorPassThrough<>(new NullInventory(), AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)); private final MEMonitorPassThrough fluids = new MEMonitorPassThrough<>(new NullInventory(), AEApi.instance().storage().getStorageChannel(IFluidStorageChannel.class)); @@ -156,12 +158,22 @@ public DualityInterface(final AENetworkProxy networkProxy, final IInterfaceHost final MachineSource actionSource = new MachineSource(this.iHost); this.mySource = actionSource; + this.storage = new AppEngNetworkInventory(this::getStorageGrid, this.mySource, this, NUMBER_OF_STORAGE_SLOTS, 512); this.fluids.setChangeSource(actionSource); this.items.setChangeSource(actionSource); this.interfaceRequestSource = new InterfaceRequestSource(this.iHost); } + @Nullable + private IStorageGrid getStorageGrid() { + try { + return this.gridProxy.getStorage(); + } catch (GridAccessException e) { + return null; + } + } + private static boolean invIsCustomBlocking(BlockingInventoryAdaptor inv) { return (inv.containsBlockingItems()); } diff --git a/src/main/java/appeng/tile/inventory/AppEngNetworkInventory.java b/src/main/java/appeng/tile/inventory/AppEngNetworkInventory.java new file mode 100644 index 00000000000..1237e8ac5fb --- /dev/null +++ b/src/main/java/appeng/tile/inventory/AppEngNetworkInventory.java @@ -0,0 +1,48 @@ +package appeng.tile.inventory; + +import appeng.api.AEApi; +import appeng.api.config.Actionable; +import appeng.api.networking.security.IActionSource; +import appeng.api.networking.storage.IStorageGrid; +import appeng.api.storage.IMEInventory; +import appeng.api.storage.channels.IItemStorageChannel; +import appeng.api.storage.data.IAEItemStack; +import appeng.util.inv.IAEAppEngInventory; +import appeng.util.item.AEItemStack; +import net.minecraft.item.ItemStack; + +import javax.annotation.Nonnull; +import java.util.function.Supplier; + +public class AppEngNetworkInventory extends AppEngInternalOversizedInventory { + + private final Supplier supplier; + private final IActionSource source; + + public AppEngNetworkInventory(Supplier networkSupplier, IActionSource source, IAEAppEngInventory inventory, int size, int maxStack) { + super(inventory, size, maxStack); + this.supplier = networkSupplier; + this.source = source; + } + + @Override + @Nonnull + public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) { + IStorageGrid storage = supplier.get(); + if (storage != null) { + int originAmt = stack.getCount(); + IMEInventory dest = storage.getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)); + IAEItemStack overflow = dest.injectItems(AEItemStack.fromItemStack(stack), simulate ? Actionable.SIMULATE : Actionable.MODULATE, this.source); + if (overflow != null && overflow.getStackSize() == originAmt) { + return super.insertItem(slot, stack, simulate); + } else if (overflow != null) { + return overflow.createItemStack(); + } else { + return ItemStack.EMPTY; + } + } else { + return super.insertItem(slot, stack, simulate); + } + } + +}