From f7be92adcf934b2bbca8af8b8c7d02851bae4f46 Mon Sep 17 00:00:00 2001 From: PrototypeTrousers Date: Tue, 11 Oct 2022 23:04:10 -0300 Subject: [PATCH] Upgrade fluid interfaces 9 tanks, with up to 64B/fluid with 2 capacity cards --- src/main/java/appeng/core/Registration.java | 4 ++ .../fluids/client/gui/GuiFluidInterface.java | 8 +-- .../client/gui/widgets/GuiFluidTank.java | 3 +- .../container/ContainerFluidInterface.java | 25 ++++++++- .../fluids/helper/DualityFluidInterface.java | 50 +++++++++++++++--- .../fluids/parts/PartFluidInterface.java | 6 +++ .../fluids/tile/TileFluidInterface.java | 8 +++ .../appeng/fluids/util/AEFluidInventory.java | 10 ++-- .../textures/guis/interfacefluid.png | Bin 1987 -> 12752 bytes 9 files changed, 98 insertions(+), 16 deletions(-) diff --git a/src/main/java/appeng/core/Registration.java b/src/main/java/appeng/core/Registration.java index 40ecd7901..c26497d82 100644 --- a/src/main/java/appeng/core/Registration.java +++ b/src/main/java/appeng/core/Registration.java @@ -323,6 +323,10 @@ final class Registration { Upgrades.PATTERN_EXPANSION.registerItem(parts.iface(), 3); Upgrades.PATTERN_EXPANSION.registerItem(blocks.iface(), 3); + // Fluid Interface + Upgrades.CAPACITY.registerItem(parts.fluidIface(), 2); + Upgrades.CAPACITY.registerItem(blocks.fluidIface(), 2); + // IO Port! Upgrades.SPEED.registerItem(blocks.iOPort(), 3); Upgrades.REDSTONE.registerItem(blocks.iOPort(), 1); diff --git a/src/main/java/appeng/fluids/client/gui/GuiFluidInterface.java b/src/main/java/appeng/fluids/client/gui/GuiFluidInterface.java index 682d421de..7867dd519 100644 --- a/src/main/java/appeng/fluids/client/gui/GuiFluidInterface.java +++ b/src/main/java/appeng/fluids/client/gui/GuiFluidInterface.java @@ -63,8 +63,8 @@ public class GuiFluidInterface extends GuiUpgradeable implements IConfigManagerH final IAEFluidTank fluidTank = this.host.getDualityFluidInterface().getTanks(); for (int i = 0; i < DualityFluidInterface.NUMBER_OF_TANKS; ++i) { - this.guiSlots.add(new GuiFluidTank(fluidTank, i, DualityFluidInterface.NUMBER_OF_TANKS + i, 35 + 18 * i, 53, 16, 68)); - this.guiSlots.add(new GuiFluidSlot(configFluids, i, i, 35 + 18 * i, 35)); + this.guiSlots.add(new GuiFluidTank(fluidTank, i, DualityFluidInterface.NUMBER_OF_TANKS + i, 8 + 18 * i, 53, 16, 68)); + this.guiSlots.add(new GuiFluidSlot(configFluids, i, i, 8 + 18 * i, 35)); } this.priority = new GuiTabButton(this.getGuiLeft() + 154, this.getGuiTop(), 2 + 4 * 16, GuiText.Priority.getLocal(), this.itemRender); @@ -78,8 +78,8 @@ public class GuiFluidInterface extends GuiUpgradeable implements IConfigManagerH @Override public void drawFG(int offsetX, int offsetY, int mouseX, int mouseY) { this.fontRenderer.drawString(this.getGuiDisplayName(GuiText.FluidInterface.getLocal()), 8, 6, 4210752); - this.fontRenderer.drawString(GuiText.Config.getLocal(), 35, 6 + 11 + 7, 4210752); - this.fontRenderer.drawString(GuiText.StoredFluids.getLocal(), 35, 6 + 112 + 7, 4210752); + this.fontRenderer.drawString(GuiText.Config.getLocal(), 8, 6 + 11 + 7, 4210752); + this.fontRenderer.drawString(GuiText.StoredFluids.getLocal(), 8, 6 + 112 + 7, 4210752); this.fontRenderer.drawString(GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752); } diff --git a/src/main/java/appeng/fluids/client/gui/widgets/GuiFluidTank.java b/src/main/java/appeng/fluids/client/gui/widgets/GuiFluidTank.java index 8a4b1689a..ee9a3e530 100644 --- a/src/main/java/appeng/fluids/client/gui/widgets/GuiFluidTank.java +++ b/src/main/java/appeng/fluids/client/gui/widgets/GuiFluidTank.java @@ -87,9 +87,8 @@ public class GuiFluidTank extends GuiCustomSlot implements ITooltip { final IAEFluidStack fluid = this.tank.getFluidInSlot(this.slot); if (fluid != null && fluid.getStackSize() > 0) { String desc = fluid.getFluid().getLocalizedName(fluid.getFluidStack()); - String amountToText = fluid.getStackSize() + "mB"; - return desc + "\n" + amountToText; + return desc + "\n" + fluid.getStackSize() + "/" + this.tank.getTankProperties()[this.slot].getCapacity() + "mB"; } return null; } diff --git a/src/main/java/appeng/fluids/container/ContainerFluidInterface.java b/src/main/java/appeng/fluids/container/ContainerFluidInterface.java index a30cc4f22..d1b410daa 100644 --- a/src/main/java/appeng/fluids/container/ContainerFluidInterface.java +++ b/src/main/java/appeng/fluids/container/ContainerFluidInterface.java @@ -20,14 +20,18 @@ package appeng.fluids.container; import appeng.api.config.SecurityPermissions; +import appeng.api.config.Upgrades; import appeng.api.storage.data.IAEFluidStack; import appeng.api.util.IConfigManager; +import appeng.container.guisync.GuiSync; import appeng.core.sync.network.NetworkHandler; import appeng.core.sync.packets.PacketTargetFluidStack; import appeng.fluids.helper.DualityFluidInterface; import appeng.fluids.helper.FluidSyncHelper; import appeng.fluids.helper.IFluidInterfaceHost; +import appeng.fluids.util.AEFluidInventory; import appeng.fluids.util.AEFluidStack; +import appeng.fluids.util.IAEFluidInventory; import appeng.fluids.util.IAEFluidTank; import appeng.helpers.InventoryAction; import appeng.util.IConfigManagerHost; @@ -35,10 +39,13 @@ import appeng.util.Platform; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.IContainerListener; +import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fluids.capability.IFluidHandlerItem; +import org.lwjgl.input.Mouse; import javax.annotation.Nonnull; import java.util.Collections; @@ -52,6 +59,9 @@ public class ContainerFluidInterface extends ContainerFluidConfigurable implemen // Holds the fluid the client wishes to extract, or null for insert private IAEFluidStack clientRequestedTargetFluid = null; + @GuiSync(7) + public int capacityUpgrades = 0; + public ContainerFluidInterface(final InventoryPlayer ip, final IFluidInterfaceHost te) { super(ip, te.getDualityFluidInterface().getHost()); @@ -82,13 +92,26 @@ public class ContainerFluidInterface extends ContainerFluidConfigurable implemen if (Platform.isServer()) { this.tankSync.sendDiff(this.listeners); + if (capacityUpgrades != getUpgradeable().getInstalledUpgrades(Upgrades.CAPACITY)) { + capacityUpgrades = getUpgradeable().getInstalledUpgrades(Upgrades.CAPACITY); + } } super.detectAndSendChanges(); } + @Override + public void onUpdate(final String field, final Object oldValue, final Object newValue) { + super.onUpdate(field, oldValue, newValue); + if (Platform.isClient() && field.equals("capacityUpgrades")) { + this.capacityUpgrades = (int) newValue; + ((AEFluidInventory) this.myDuality.getTanks()).setCapacity((int) (Math.pow(4, this.capacityUpgrades + 1) * Fluid.BUCKET_VOLUME)); + } + } + @Override protected void setupConfig() { + this.setupUpgrades(); } @Override @@ -209,7 +232,7 @@ public class ContainerFluidInterface extends ContainerFluidConfigurable implemen @Override public int availableUpgrades() { - return 0; + return 2; } @Override diff --git a/src/main/java/appeng/fluids/helper/DualityFluidInterface.java b/src/main/java/appeng/fluids/helper/DualityFluidInterface.java index 17e8e4491..086c7e9ed 100644 --- a/src/main/java/appeng/fluids/helper/DualityFluidInterface.java +++ b/src/main/java/appeng/fluids/helper/DualityFluidInterface.java @@ -59,10 +59,14 @@ import appeng.me.helpers.MachineSource; import appeng.me.storage.MEMonitorIFluidHandler; import appeng.me.storage.MEMonitorPassThrough; import appeng.me.storage.NullInventory; +import appeng.parts.automation.StackUpgradeInventory; +import appeng.parts.automation.UpgradeInventory; import appeng.util.ConfigManager; import appeng.util.IConfigManagerHost; import appeng.util.InventoryAdaptor; import appeng.util.Platform; +import appeng.util.inv.IAEAppEngInventory; +import appeng.util.inv.InvOperation; import gregtech.api.block.machines.BlockMachine; import gregtech.api.metatileentity.MetaTileEntity; import net.minecraft.block.Block; @@ -88,11 +92,12 @@ import net.minecraftforge.items.IItemHandler; import java.util.Collection; import java.util.EnumSet; import java.util.HashSet; +import java.util.List; import java.util.Optional; -public class DualityFluidInterface implements IGridTickable, IStorageMonitorable, IAEFluidInventory, IUpgradeableHost, IConfigManagerHost, IConfigurableFluidInventory { - public static final int NUMBER_OF_TANKS = 6; +public class DualityFluidInterface implements IGridTickable, IStorageMonitorable, IAEFluidInventory, IAEAppEngInventory, IUpgradeableHost, IConfigManagerHost, IConfigurableFluidInventory { + public static final int NUMBER_OF_TANKS = 9; public static final int TANK_CAPACITY = Fluid.BUCKET_VOLUME * 4; private static final Collection BAD_BLOCKS = new HashSet<>(100); private final ConfigManager cm = new ConfigManager(this); @@ -100,6 +105,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable private final IFluidInterfaceHost iHost; private final IActionSource mySource; private final IActionSource interfaceRequestSource; + 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); @@ -117,6 +123,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable this.gridProxy = networkProxy; this.gridProxy.setFlags(GridFlags.REQUIRE_CHANNEL); + this.upgrades = new StackUpgradeInventory(this.gridProxy.getMachineRepresentation(), this, 2); this.cm.registerSetting(Settings.INTERFACE_TERMINAL, YesNo.YES); this.iHost = ih; @@ -382,16 +389,17 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable this.requireWork[slot] = work.setStackSize(-work.getStackSize()); return; } else if (req != null) { + int tankSize = (int) (Math.pow(4, this.getInstalledUpgrades(Upgrades.CAPACITY) + 1) * Fluid.BUCKET_VOLUME); if (stored == null || stored.getStackSize() == 0) // need to add stuff! { this.requireWork[slot] = req.copy(); - this.requireWork[slot].setStackSize(TANK_CAPACITY); + this.requireWork[slot].setStackSize(tankSize); return; } else if (req.equals(stored)) // same type ( qty different? )! { - if (stored.getStackSize() < TANK_CAPACITY) { + if (stored.getStackSize() != tankSize) { this.requireWork[slot] = req.copy(); - this.requireWork[slot].setStackSize(TANK_CAPACITY - stored.getStackSize()); + this.requireWork[slot].setStackSize(tankSize - stored.getStackSize()); return; } } else @@ -512,12 +520,14 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable data.setInteger("priority", this.priority); this.tanks.writeToNBT(data, "storage"); this.config.writeToNBT(data, "config"); + this.upgrades.writeToNBT(data, "upgrades"); } public void readFromNBT(final NBTTagCompound data) { this.config.readFromNBT(data, "config"); this.tanks.readFromNBT(data, "storage"); this.priority = data.getInteger("priority"); + this.upgrades.readFromNBT(data, "upgrades"); this.readConfig(); } @@ -589,6 +599,20 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable this.iHost.saveChanges(); } + @Override + public void onChangeInventory(IItemHandler inv, int slot, InvOperation mc, ItemStack removedStack, ItemStack newStack) { + if (inv == this.upgrades) { + this.tanks.setCapacity((int) (Math.pow(4, this.getInstalledUpgrades(Upgrades.CAPACITY) + 1) * Fluid.BUCKET_VOLUME)); + try { + this.gridProxy.getTick().alertDevice(this.gridProxy.getNode()); + } catch (GridAccessException ignored) { + } + for (int x = 0; x < NUMBER_OF_TANKS; x++) { + this.updatePlan(x); + } + } + } + @Override public IConfigManager getConfigManager() { return this.cm; @@ -596,6 +620,9 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable @Override public IItemHandler getInventoryByName(String name) { + if (name.equals("upgrades")) { + return this.upgrades; + } return null; } @@ -609,7 +636,18 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable @Override public int getInstalledUpgrades(Upgrades u) { - return 0; + if (this.upgrades == null) { + return 0; + } + return this.upgrades.getInstalledUpgrades(u); + } + + public void addDrops(final List drops) { + for (final ItemStack is : this.upgrades) { + if (!is.isEmpty()) { + drops.add(is); + } + } } @Override diff --git a/src/main/java/appeng/fluids/parts/PartFluidInterface.java b/src/main/java/appeng/fluids/parts/PartFluidInterface.java index be7519d86..ec9b9456a 100644 --- a/src/main/java/appeng/fluids/parts/PartFluidInterface.java +++ b/src/main/java/appeng/fluids/parts/PartFluidInterface.java @@ -60,6 +60,7 @@ import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.items.IItemHandler; import java.util.EnumSet; +import java.util.List; public class PartFluidInterface extends PartBasicState implements IGridTickable, IStorageMonitorable, IFluidInterfaceHost, IPriorityHost, IConfigurableFluidInventory { @@ -121,6 +122,11 @@ public class PartFluidInterface extends PartBasicState implements IGridTickable, this.duality.writeToNBT(data); } + @Override + public void getDrops(final List drops, final boolean wrenched) { + this.duality.addDrops(drops); + } + @Override public float getCableConnectionLength(AECableType cable) { return 4; diff --git a/src/main/java/appeng/fluids/tile/TileFluidInterface.java b/src/main/java/appeng/fluids/tile/TileFluidInterface.java index eb730730e..c11871b1b 100644 --- a/src/main/java/appeng/fluids/tile/TileFluidInterface.java +++ b/src/main/java/appeng/fluids/tile/TileFluidInterface.java @@ -42,12 +42,15 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.items.IItemHandler; import javax.annotation.Nullable; import java.util.EnumSet; +import java.util.List; public class TileFluidInterface extends AENetworkTile implements IGridTickable, IFluidInterfaceHost, IPriorityHost, IConfigurableFluidInventory { @@ -83,6 +86,11 @@ public class TileFluidInterface extends AENetworkTile implements IGridTickable, return this; } + @Override + public void getDrops(final World w, final BlockPos pos, final List drops) { + this.duality.addDrops(drops); + } + @Override public void gridChanged() { this.duality.gridChanged(); diff --git a/src/main/java/appeng/fluids/util/AEFluidInventory.java b/src/main/java/appeng/fluids/util/AEFluidInventory.java index 5944ad92f..64650e92d 100644 --- a/src/main/java/appeng/fluids/util/AEFluidInventory.java +++ b/src/main/java/appeng/fluids/util/AEFluidInventory.java @@ -14,7 +14,7 @@ import java.util.Objects; public class AEFluidInventory implements IAEFluidTank { private final IAEFluidStack[] fluids; private final IAEFluidInventory handler; - private final int capacity; + private int capacity; private IFluidTankProperties[] props = null; public AEFluidInventory(final IAEFluidInventory handler, final int slots, final int capcity) { @@ -23,6 +23,10 @@ public class AEFluidInventory implements IAEFluidTank { this.capacity = capcity; } + public void setCapacity(int capacity) { + this.capacity = capacity; + } + public AEFluidInventory(final IAEFluidInventory handler, final int slots) { this(handler, slots, Integer.MAX_VALUE); } @@ -32,7 +36,7 @@ public class AEFluidInventory implements IAEFluidTank { if (slot >= 0 && slot < this.getSlots()) { if (Objects.equals(this.fluids[slot], fluid)) { if (fluid != null && fluid.getStackSize() != this.fluids[slot].getStackSize()) { - this.fluids[slot].setStackSize(Math.min(fluid.getStackSize(), this.capacity)); + this.fluids[slot].setStackSize(fluid.getStackSize()); this.onContentChanged(slot); } } else { @@ -40,7 +44,7 @@ public class AEFluidInventory implements IAEFluidTank { this.fluids[slot] = null; } else { this.fluids[slot] = fluid.copy(); - this.fluids[slot].setStackSize(Math.min(fluid.getStackSize(), this.capacity)); + this.fluids[slot].setStackSize(fluid.getStackSize()); } this.onContentChanged(slot); diff --git a/src/main/resources/assets/appliedenergistics2/textures/guis/interfacefluid.png b/src/main/resources/assets/appliedenergistics2/textures/guis/interfacefluid.png index 41ed69fd69bb99d45c08704ccc486c8eb08b768c..551a405ac8148f26d757ac6382fc6faf48b1ebdf 100644 GIT binary patch literal 12752 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

c-g^`>U~?of8|^jO&#R>u$QM=qZ9yy)t+M_+SG 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 VlgoO~x=sdJ<>~6@vd$@?2>^~XZ1MmA