From 0499adcc6f025063efb3a16be4c349b1feee5431 Mon Sep 17 00:00:00 2001 From: lc-1337 <62835225+lc-1337@users.noreply.github.com> Date: Sun, 22 Jun 2025 18:49:44 +0300 Subject: [PATCH] Add Super Stock Replenisher (#278) Co-authored-by: Maya <10861407+serenibyss@users.noreply.github.com> Co-authored-by: boubou19 Co-authored-by: lordIcocain <62835225+lordIcocain@users.noreply.github.com> --- .../client/gui/GuiPatternValueAmount.java | 7 +- .../client/gui/GuiSuperStockReplenisher.java | 116 +++++ .../ContainerPatternValueAmount.java | 3 +- .../ContainerSuperStockReplenisher.java | 154 ++++++ .../block/BlockSuperStockReplenisher.java | 66 +++ .../tile/TileSuperStockReplenisher.java | 463 ++++++++++++++++++ .../github/inventory/AEFluidInventory.java | 62 +++ .../github/inventory/gui/GuiType.java | 29 ++ .../inventory/slot/OptionalFluidSlotFake.java | 28 ++ .../github/loader/ChannelLoader.java | 6 + .../github/loader/ItemAndBlockHolder.java | 2 + .../network/CPacketInventoryAction.java | 12 +- .../network/CPacketPatternValueSet.java | 4 +- .../SPacketSuperStockReplenisherUpdate.java | 59 +++ .../com/glodblock/github/util/NameConst.java | 1 + .../java/com/glodblock/github/util/Util.java | 32 ++ .../resources/assets/ae2fc/lang/en_US.lang | 1 + .../blocks/super_stock_replenisher.png | Bin 0 -> 581 bytes .../textures/gui/superStockReplenisher.png | Bin 0 -> 1985 bytes 19 files changed, 1039 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/glodblock/github/client/gui/GuiSuperStockReplenisher.java create mode 100644 src/main/java/com/glodblock/github/client/gui/container/ContainerSuperStockReplenisher.java create mode 100644 src/main/java/com/glodblock/github/common/block/BlockSuperStockReplenisher.java create mode 100644 src/main/java/com/glodblock/github/common/tile/TileSuperStockReplenisher.java create mode 100644 src/main/java/com/glodblock/github/inventory/slot/OptionalFluidSlotFake.java create mode 100644 src/main/java/com/glodblock/github/network/SPacketSuperStockReplenisherUpdate.java create mode 100644 src/main/resources/assets/ae2fc/textures/blocks/super_stock_replenisher.png create mode 100644 src/main/resources/assets/ae2fc/textures/gui/superStockReplenisher.png diff --git a/src/main/java/com/glodblock/github/client/gui/GuiPatternValueAmount.java b/src/main/java/com/glodblock/github/client/gui/GuiPatternValueAmount.java index e14c9025..b73d099d 100644 --- a/src/main/java/com/glodblock/github/client/gui/GuiPatternValueAmount.java +++ b/src/main/java/com/glodblock/github/client/gui/GuiPatternValueAmount.java @@ -9,18 +9,18 @@ import com.glodblock.github.client.gui.container.ContainerPatternValueAmount; import com.glodblock.github.common.item.ItemWirelessUltraTerminal; import com.glodblock.github.common.parts.PartFluidPatternTerminal; import com.glodblock.github.common.parts.PartFluidPatternTerminalEx; +import com.glodblock.github.common.tile.TileSuperStockReplenisher; import com.glodblock.github.inventory.gui.GuiType; import com.glodblock.github.inventory.item.IWirelessTerminal; import com.glodblock.github.inventory.item.WirelessPatternTerminalInventory; import com.glodblock.github.loader.ItemAndBlockHolder; import com.glodblock.github.network.CPacketPatternValueSet; -import appeng.api.storage.ITerminalHost; import appeng.core.localization.GuiText; public class GuiPatternValueAmount extends FCGuiAmount { - public GuiPatternValueAmount(final InventoryPlayer inventoryPlayer, final ITerminalHost te) { + public GuiPatternValueAmount(final InventoryPlayer inventoryPlayer, final Object te) { super(new ContainerPatternValueAmount(inventoryPlayer, te)); } @@ -77,6 +77,9 @@ public class GuiPatternValueAmount extends FCGuiAmount { } else if (target instanceof WirelessPatternTerminalInventory) { this.myIcon = ItemAndBlockHolder.WIRELESS_PATTERN_TERM.stack(); this.originalGui = GuiType.WIRELESS_FLUID_PATTERN_TERMINAL; + } else if (target instanceof TileSuperStockReplenisher) { + this.myIcon = ItemAndBlockHolder.SUPER_STOCK_RERPLENISHER.stack(); + this.originalGui = GuiType.GUI_SUPER_STOCK_REPLENISHER; } } diff --git a/src/main/java/com/glodblock/github/client/gui/GuiSuperStockReplenisher.java b/src/main/java/com/glodblock/github/client/gui/GuiSuperStockReplenisher.java new file mode 100644 index 00000000..b9cd2607 --- /dev/null +++ b/src/main/java/com/glodblock/github/client/gui/GuiSuperStockReplenisher.java @@ -0,0 +1,116 @@ +package com.glodblock.github.client.gui; + +import java.util.HashMap; +import java.util.Map; + +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; + +import org.lwjgl.opengl.GL11; + +import com.glodblock.github.FluidCraft; +import com.glodblock.github.client.gui.container.ContainerSuperStockReplenisher; +import com.glodblock.github.common.item.ItemFluidPacket; +import com.glodblock.github.common.tile.TileSuperStockReplenisher; +import com.glodblock.github.network.CPacketInventoryAction; + +import appeng.api.storage.data.IAEItemStack; +import appeng.api.storage.data.IAEStack; +import appeng.client.gui.AEBaseGui; +import appeng.container.AEBaseContainer; +import appeng.container.slot.SlotFake; +import appeng.core.localization.GuiText; +import appeng.helpers.InventoryAction; +import appeng.util.item.AEItemStack; + +public class GuiSuperStockReplenisher extends AEBaseGui { + + private static final ResourceLocation TEX_BG = FluidCraft.resource("textures/gui/superStockReplenisher.png"); + private Map> list = new HashMap<>(); + + public GuiSuperStockReplenisher(InventoryPlayer ipl, TileSuperStockReplenisher tile) { + super(new ContainerSuperStockReplenisher(ipl, tile)); + this.ySize = 251; + this.xSize = 216; + } + + @Override + protected void handleMouseClick(Slot slot, int slotIdx, int ctrlDown, int mouseButton) { + if (mouseButton == 3) { + if (slot instanceof SlotFake) { + if (slot.getHasStack()) { + InventoryAction action = InventoryAction.SET_PATTERN_VALUE; + IAEItemStack stack = AEItemStack.create(slot.getStack()); + ((AEBaseContainer) this.inventorySlots).setTargetStack(stack); + for (int i = 0; i < this.inventorySlots.inventorySlots.size(); i++) { + if (slot.equals(this.inventorySlots.inventorySlots.get(i))) { + FluidCraft.proxy.netHandler.sendToServer(new CPacketInventoryAction(action, i, 0, stack)); + } + } + return; + } + } + } + super.handleMouseClick(slot, slotIdx, ctrlDown, mouseButton); + } + + @Override + public void func_146977_a(Slot s) { + if (s instanceof SlotFake) { + this.drawFillStatus(s); + } + super.func_146977_a(s); + } + + private void drawFillStatus(Slot slotIn) { + int offsetX = slotIn.xDisplayPosition - 8; + int offsetY = slotIn.yDisplayPosition - 11; + ItemStack itemstack = slotIn.getStack(); + int slotInt = slotIn.slotNumber; + if (itemstack != null) { + String s = "0%"; + if (slotInt > 0 && slotInt < 10) { + IAEStack aeStack = list.get(slotInt - 1); + if (aeStack != null) + s = (int) (((float) aeStack.getStackSize() / ItemFluidPacket.getFluidAmount(itemstack)) * 100) + + "%"; + } else if (slotInt > 9 && slotInt < 73) { + IAEStack aeStack = list.get(slotInt + 90); + if (aeStack != null && itemstack.stackSize > 0) { + long i = aeStack.getStackSize(); + s = (int) (((float) i / itemstack.stackSize) * 100) + "%"; + } + } + + float scale = 0.5f; + float shiftX = 2; + float shiftY = 1; + final float inverseScaleFactor = 1.0f / scale; + + final int X = (int) (((float) offsetX - shiftX + 10.0f) * inverseScaleFactor); + final int Y = (int) (((float) offsetY - shiftY + 16.0f - 7.0f * scale) * inverseScaleFactor); + GL11.glTranslatef(0.0f, 0.0f, 200.0f); + GL11.glScaled(scale, scale, scale); + this.fontRendererObj.drawStringWithShadow(s, X, Y, 16777215); + GL11.glScaled(inverseScaleFactor, inverseScaleFactor, inverseScaleFactor); + GL11.glTranslatef(0.0f, 0.0f, -200.0f); + } + } + + @Override + public void drawFG(int offsetX, int offsetY, int mouseX, int mouseY) { + fontRendererObj.drawString(GuiText.inventory.getLocal(), 8, ySize - 94, 0x404040); + } + + @Override + public void drawBG(int offsetX, int offsetY, int mouseX, int mouseY) { + this.bindTexture(TEX_BG); + this.drawTexturedModalRect(offsetX, offsetY, 0, 0, xSize, ySize); + } + + public void update(Map> map) { + this.list = map; + } +} diff --git a/src/main/java/com/glodblock/github/client/gui/container/ContainerPatternValueAmount.java b/src/main/java/com/glodblock/github/client/gui/container/ContainerPatternValueAmount.java index 525a3f22..27b38762 100644 --- a/src/main/java/com/glodblock/github/client/gui/container/ContainerPatternValueAmount.java +++ b/src/main/java/com/glodblock/github/client/gui/container/ContainerPatternValueAmount.java @@ -4,7 +4,6 @@ import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Slot; import appeng.api.config.SecurityPermissions; -import appeng.api.storage.ITerminalHost; import appeng.container.AEBaseContainer; import appeng.container.guisync.GuiSync; import appeng.container.slot.SlotInaccessible; @@ -17,7 +16,7 @@ public class ContainerPatternValueAmount extends AEBaseContainer { @GuiSync(11) public int valueIndex; - public ContainerPatternValueAmount(final InventoryPlayer ip, final ITerminalHost te) { + public ContainerPatternValueAmount(final InventoryPlayer ip, final Object te) { super(ip, te); this.patternValue = new SlotInaccessible(new AppEngInternalInventory(null, 1), 0, 34, 53); this.addSlotToContainer(patternValue); diff --git a/src/main/java/com/glodblock/github/client/gui/container/ContainerSuperStockReplenisher.java b/src/main/java/com/glodblock/github/client/gui/container/ContainerSuperStockReplenisher.java new file mode 100644 index 00000000..b8059ce0 --- /dev/null +++ b/src/main/java/com/glodblock/github/client/gui/container/ContainerSuperStockReplenisher.java @@ -0,0 +1,154 @@ +package com.glodblock.github.client.gui.container; + +import java.util.HashMap; +import java.util.Map; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; + +import com.glodblock.github.FluidCraft; +import com.glodblock.github.common.item.FCBaseItemCell; +import com.glodblock.github.common.tile.TileSuperStockReplenisher; +import com.glodblock.github.inventory.slot.OptionalFluidSlotFake; +import com.glodblock.github.network.SPacketSuperStockReplenisherUpdate; + +import appeng.api.storage.data.IAEStack; +import appeng.container.AEBaseContainer; +import appeng.container.slot.IOptionalSlotHost; +import appeng.container.slot.SlotPatternOutputs; +import appeng.container.slot.SlotRestrictedInput; +import appeng.items.storage.ItemBasicStorageCell; +import appeng.util.item.AEItemStack; + +public class ContainerSuperStockReplenisher extends AEBaseContainer implements IOptionalSlotHost { + + private final TileSuperStockReplenisher tile; + private final IInventory configFluids; + private final IInventory configItems; + private int lastUpdated = 0; + + public ContainerSuperStockReplenisher(InventoryPlayer ipl, TileSuperStockReplenisher tile) { + super(ipl, tile); + this.tile = tile; + configFluids = tile.getConfigFluid(); + configItems = tile.getConfigItems(); + final IInventory cell = tile.getCell(); + + final int x = 8; + final int fy = 8; + + this.addSlotToContainer( + new SlotRestrictedInput( + SlotRestrictedInput.PlacableItemType.WORKBENCH_CELL, + cell, + 0, + 173, + fy, + this.getInventoryPlayer())); + + for (int i = 0; i < 9; i++) { + addSlotToContainer(new OptionalFluidSlotFake(configFluids, this, i, x, fy, i, 0, 0)); + } + + final int io = 29; + for (int y = 0; y < 7; y++) { + for (int ix = 0; ix < 9; ix++) { + this.addSlotToContainer(new SlotPatternOutputs(configItems, this, y * 9 + ix, x, io, ix, y, y)); + } + } + + bindPlayerInventory(ipl, 0, 251 - 82); + } + + @Override + public ItemStack slotClick(int slotId, int clickedButton, int mode, EntityPlayer player) { + if (slotId == 0 && player.inventory.getItemStack() == null && isConfigurated()) { + return null; + } + return super.slotClick(slotId, clickedButton, mode, player); + } + + @Override + public boolean isSlotEnabled(int idx) { + return true; + } + + @Override + public void addCraftingToCrafters(ICrafting p_75132_1_) { + super.addCraftingToCrafters(p_75132_1_); + lastUpdated = 24; + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + if (lastUpdated > 20) { + lastUpdated = 0; + Map> tmp = new HashMap<>(); + + for (int i = 0; i < tile.getInternalFluid().getSlots(); i++) { + tmp.put(i, tile.getInternalFluid().getFluidInSlot(i)); + } + + for (int i = 0; i < tile.getInternalInventory().getSizeInventory(); i++) { + tmp.put(i + 100, AEItemStack.create(tile.getInternalInventory().getStackInSlot(i))); + } + + for (final Object g : this.crafters) { + if (g instanceof EntityPlayer) { + FluidCraft.proxy.netHandler.sendTo(new SPacketSuperStockReplenisherUpdate(tmp), (EntityPlayerMP) g); + } + } + } + lastUpdated++; + } + + private boolean isConfigurated() { + for (int i = 0; i < configItems.getSizeInventory(); i++) { + if (configItems.getStackInSlot(i) != null) { + return true; + } + } + for (int i = 0; i < configFluids.getSizeInventory(); i++) { + if (configFluids.getStackInSlot(i) != null) { + return true; + } + } + return false; + } + + @Override + public boolean isValidForSlot(Slot s, ItemStack is) { + if (s.slotNumber == 0 && s.getHasStack() && isConfigurated()) { + long currentBytes = 0; + long newBytes = -1; + + if (s.getStack().getItem() instanceof ItemBasicStorageCell ibsc) { + currentBytes = ibsc.getBytesLong(is); + } else if (s.getStack().getItem() instanceof FCBaseItemCell fcbic) { + currentBytes = fcbic.getBytes(is); + } + + if (is.getItem() instanceof ItemBasicStorageCell ibsc) { + newBytes = ibsc.getBytesLong(is); + } else if (is.getItem() instanceof FCBaseItemCell fcbic) { + newBytes = fcbic.getBytes(is); + } + + if (currentBytes > newBytes) { + return false; + } + } + return super.isValidForSlot(s, is); + } + + public TileSuperStockReplenisher getTile() { + return tile; + } +} diff --git a/src/main/java/com/glodblock/github/common/block/BlockSuperStockReplenisher.java b/src/main/java/com/glodblock/github/common/block/BlockSuperStockReplenisher.java new file mode 100644 index 00000000..f0488726 --- /dev/null +++ b/src/main/java/com/glodblock/github/common/block/BlockSuperStockReplenisher.java @@ -0,0 +1,66 @@ +package com.glodblock.github.common.block; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +import com.glodblock.github.common.tabs.FluidCraftingTabs; +import com.glodblock.github.common.tile.TileSuperStockReplenisher; +import com.glodblock.github.inventory.InventoryHandler; +import com.glodblock.github.inventory.gui.GuiType; +import com.glodblock.github.util.BlockPos; +import com.glodblock.github.util.NameConst; + +import appeng.block.AEBaseItemBlock; +import cpw.mods.fml.common.registry.GameRegistry; + +public class BlockSuperStockReplenisher extends FCBaseBlock { + + public BlockSuperStockReplenisher() { + super(Material.web, NameConst.BLOCK_SUPER_STOCK_REPLENISHER); + setTileEntity(TileSuperStockReplenisher.class); + setOpaque(true); + setFullBlock(true); + this.lightOpacity = 4; + } + + @Override + public boolean onActivated(World world, int x, int y, int z, EntityPlayer player, int facing, float hitX, + float hitY, float hitZ) { + if (player.isSneaking()) { + return false; + } + TileSuperStockReplenisher tile = getTileEntity(world, x, y, z); + if (tile != null) { + if (!world.isRemote) { + InventoryHandler.openGui( + player, + world, + new BlockPos(x, y, z), + ForgeDirection.getOrientation(facing), + GuiType.GUI_SUPER_STOCK_REPLENISHER); + } + return true; + } + return false; + } + + @Override + public void breakBlock(World w, int x, int y, int z, Block a, int b) { + final TileSuperStockReplenisher tss = this.getTileEntity(w, x, y, z); + if (tss != null) { + tss.fullRefund(); + } + super.breakBlock(w, x, y, z, a, b); + } + + @Override + public BlockSuperStockReplenisher register() { + GameRegistry.registerBlock(this, AEBaseItemBlock.class, NameConst.BLOCK_SUPER_STOCK_REPLENISHER); + GameRegistry.registerTileEntity(TileSuperStockReplenisher.class, NameConst.BLOCK_SUPER_STOCK_REPLENISHER); + setCreativeTab(FluidCraftingTabs.INSTANCE); + return this; + } +} diff --git a/src/main/java/com/glodblock/github/common/tile/TileSuperStockReplenisher.java b/src/main/java/com/glodblock/github/common/tile/TileSuperStockReplenisher.java new file mode 100644 index 00000000..0d4ec589 --- /dev/null +++ b/src/main/java/com/glodblock/github/common/tile/TileSuperStockReplenisher.java @@ -0,0 +1,463 @@ +package com.glodblock.github.common.tile; + +import java.util.List; +import java.util.stream.IntStream; + +import javax.annotation.Nonnull; + +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidHandler; + +import com.glodblock.github.common.item.FCBaseItemCell; +import com.glodblock.github.common.item.ItemFluidPacket; +import com.glodblock.github.inventory.AEFluidInventory; +import com.glodblock.github.inventory.IAEFluidInventory; +import com.glodblock.github.inventory.IAEFluidTank; + +import appeng.api.config.Actionable; +import appeng.api.config.PowerMultiplier; +import appeng.api.implementations.IPowerChannelState; +import appeng.api.networking.GridFlags; +import appeng.api.networking.IGridNode; +import appeng.api.networking.events.MENetworkBootingStatusChange; +import appeng.api.networking.events.MENetworkEventSubscribe; +import appeng.api.networking.events.MENetworkPowerStatusChange; +import appeng.api.networking.security.BaseActionSource; +import appeng.api.networking.security.MachineSource; +import appeng.api.networking.ticking.IGridTickable; +import appeng.api.networking.ticking.TickRateModulation; +import appeng.api.networking.ticking.TickingRequest; +import appeng.api.storage.data.IAEFluidStack; +import appeng.api.storage.data.IAEItemStack; +import appeng.api.util.AECableType; +import appeng.api.util.DimensionalCoord; +import appeng.core.AELog; +import appeng.items.storage.ItemBasicStorageCell; +import appeng.me.GridAccessException; +import appeng.tile.TileEvent; +import appeng.tile.events.TileEventType; +import appeng.tile.grid.AENetworkInvTile; +import appeng.tile.inventory.AppEngInternalAEInventory; +import appeng.tile.inventory.AppEngInternalInventory; +import appeng.tile.inventory.InvOperation; +import appeng.util.item.AEFluidStack; +import appeng.util.item.AEItemStack; +import io.netty.buffer.ByteBuf; + +public class TileSuperStockReplenisher extends AENetworkInvTile + implements IAEFluidInventory, IFluidHandler, IPowerChannelState, IGridTickable { + + private final AppEngInternalInventory cell = new AppEngInternalInventory(this, 1); + private final AppEngInternalInventory invItems = new AppEngInternalInventory(this, 63); + private final AEFluidInventory invFluids = new AEFluidInventory(this, 9, Integer.MAX_VALUE); + private final AppEngInternalAEInventory configFluids = new AppEngInternalAEInventory(this, 9); + private final AppEngInternalAEInventory configItems = new AppEngInternalAEInventory(this, 63); + private final BaseActionSource source; + private boolean isPowered; + private long totalBytes; + private long storedFluidCount; + private long storedItemCount; + + public TileSuperStockReplenisher() { + getProxy().setIdlePowerUsage(4D); + getProxy().setFlags(GridFlags.REQUIRE_CHANNEL); + this.source = new MachineSource(this); + invItems.setMaxStackSize(Integer.MAX_VALUE); + } + + private TickRateModulation doWork() { + for (int i = 0; i < 9; i++) { + IAEFluidStack invFluid = invFluids.getFluidInSlot(i); + IAEItemStack configFluid = configFluids.getAEStackInSlot(i); + if (configFluid != null) { + IAEFluidStack fs = AEFluidStack.create(ItemFluidPacket.getFluidStack(configFluid)); + if (invFluid == null) requestFluid(fs, i); + else if (invFluid.equals(fs)) { + long invSize = invFluid.getStackSize(); + long confSize = fs.getStackSize(); + if (invSize < confSize / 2f) { + fs.setStackSize(confSize - invSize); + requestFluid(fs, i); + } else if (invSize > confSize) { + returnFluid(i, invSize - confSize); + } + } else { + returnFluid(i, Long.MAX_VALUE); + } + } else if (invFluid != null) { + returnFluid(i, Long.MAX_VALUE); + } + } + + for (int i = 0; i < 63; i++) { + ItemStack invItem = invItems.getStackInSlot(i); + IAEItemStack configItem = configItems.getAEStackInSlot(i); + + if (configItem != null) { + IAEItemStack is = configItem.copy(); + if (invItem == null) requestItem(is, i); + else if (is.equals(invItem)) { + int confSize = (int) is.getStackSize(); + if (invItem.stackSize < confSize / 2f) { + is.setStackSize(confSize - invItem.stackSize); + requestItem(is, i); + } else if (invItem.stackSize > confSize) { + returnItem(i, invItem.stackSize - confSize); + } + } else { + returnItem(i, Integer.MAX_VALUE); + } + } else if (invItem != null) { + returnItem(i, Integer.MAX_VALUE); + } + } + + return TickRateModulation.SAME; + } + + private void returnFluid(int index, long amount) { + try { + IAEFluidStack ias = invFluids.drain(index, amount, true); + storedFluidCount -= ias.getStackSize(); + IAEFluidStack notInserted = this.getProxy().getStorage().getFluidInventory() + .injectItems(ias, Actionable.MODULATE, this.source); + if (notInserted != null) { + invFluids.fill(index, notInserted, true); + storedFluidCount += notInserted.getStackSize(); + } + } catch (final GridAccessException ignored) {} + } + + private void requestFluid(IAEFluidStack fs, int index) { + if (getRemainingFluidCount() == 0) return; + try { + long remFluid = getRemainingFluidCount(); + if (fs.getStackSize() > remFluid) fs.setStackSize(remFluid); + IAEFluidStack extracted = this.getProxy().getStorage().getFluidInventory() + .extractItems(fs, Actionable.MODULATE, this.source); + if (extracted != null) { + storedFluidCount += extracted.getStackSize(); + invFluids.fill(index, extracted, true); + } + } catch (final GridAccessException ignored) {} + } + + private void returnItem(int index, int amount) { + try { + ItemStack is = invItems.getStackInSlot(index); + if (amount != Integer.MAX_VALUE) { + is.stackSize = is.stackSize - amount; + is = is.copy(); + is.stackSize = amount; + storedItemCount -= is.stackSize; + } else { + invItems.setInventorySlotContents(index, null); + } + + IAEItemStack notInserted = this.getProxy().getStorage().getItemInventory() + .injectItems(AEItemStack.create(is), Actionable.MODULATE, this.source); + if (notInserted != null) { + ItemStack tempStack = invItems.getStackInSlot(index); + if (tempStack != null) { + tempStack.stackSize = tempStack.stackSize + (int) notInserted.getStackSize(); + storedItemCount += notInserted.getStackSize(); + } else invItems.setInventorySlotContents(index, notInserted.getItemStack()); + } + } catch (final GridAccessException ignored) {} + } + + private void requestItem(IAEItemStack is, int index) { + if (getRemainingItemCount() == 0) return; + try { + long remItem = getRemainingItemCount(); + if (is.getStackSize() > remItem) is.setStackSize(remItem); + IAEItemStack extracted = this.getProxy().getStorage().getItemInventory() + .extractItems(is, Actionable.MODULATE, this.source); + if (extracted != null) { + ItemStack tempStack = invItems.getStackInSlot(index); + if (tempStack != null) { + tempStack.stackSize = tempStack.stackSize + (int) extracted.getStackSize(); + storedItemCount += extracted.getStackSize(); + } else invItems.setInventorySlotContents(index, extracted.getItemStack()); + } + } catch (final GridAccessException ignored) {} + } + + @Override + public int[] getAccessibleSlotsBySide(ForgeDirection whichSide) { + return IntStream.rangeClosed(0, 62).toArray(); + } + + @Nonnull + @Override + public IInventory getInternalInventory() { + return invItems; + } + + public AppEngInternalAEInventory getConfigFluid() { + return configFluids; + } + + public AppEngInternalAEInventory getConfigItems() { + return configItems; + } + + public AppEngInternalInventory getCell() { + return cell; + } + + public long getFreeBytes() { + return totalBytes - (((storedItemCount + getUnusedItemCount()) / 8) + + ((storedFluidCount + getUnusedFluidCount()) / 2048)); + } + + public long getRemainingFluidCount() { + final double remaining = (double) getFreeBytes() * 2048 + this.getUnusedFluidCount(); + if (remaining > Long.MAX_VALUE) return Long.MAX_VALUE; + return remaining > 0 ? (long) remaining : 0; + } + + public int getUnusedFluidCount() { + final int div = (int) (storedFluidCount % 2048); + if (div == 0) { + return 0; + } + return 2048 - div; + } + + public long getRemainingItemCount() { + final long remaining = getFreeBytes() * 8 + this.getUnusedItemCount(); + + return remaining > 0 ? remaining : 0; + } + + public int getUnusedItemCount() { + final long div = storedItemCount % 8; + + if (div == 0) { + return 0; + } + + return (int) (8 - div); + } + + @Override + public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removed, ItemStack added) { + switch (mc) { + case setInventorySlotContents -> { + if (added != null) { + if (inv == cell) { + if (added.getItem() instanceof ItemBasicStorageCell ibsc) { + totalBytes = ibsc.getBytesLong(added); + } else if (added.getItem() instanceof FCBaseItemCell fcbic) { + totalBytes = fcbic.getBytes(added); + } + getProxy().setIdlePowerUsage(Math.sqrt(Math.pow(totalBytes, 0.576D))); + } else if (inv == invItems) { + storedItemCount += added.stackSize; + } + } + + if (removed != null) { + if (inv == cell) { + totalBytes = 0; + getProxy().setIdlePowerUsage(4d); + } else if (inv == invItems) { + storedItemCount -= removed.stackSize; + } + } + } + case decreaseStackSize -> { + if (inv == cell) { + totalBytes = 0; + getProxy().setIdlePowerUsage(4d); + } + if (inv == invItems) { + storedItemCount -= removed.stackSize; + } + } + case markDirty -> {} + } + + try { + getProxy().getTick().alertDevice(getProxy().getNode()); + } catch (GridAccessException e) { + AELog.error(e, "Couldn't wake up level emitter for delayed updates"); + } + + markForUpdate(); + } + + public void fullRefund() { + for (int i = 0; i < 9; i++) { + if (invFluids.getFluidStackInSlot(i) != null) { + returnFluid(i, Long.MAX_VALUE); + } + } + + for (int i = 0; i < 63; i++) { + if (invItems.getStackInSlot(i) != null) { + returnItem(i, Integer.MAX_VALUE); + } + } + } + + @Override + public void getDrops(World w, int x, int y, int z, List drops) { + if (cell.getStackInSlot(0) != null) drops.add(cell.getStackInSlot(0)); + for (int i = 0; i < 9; i++) { + ItemStack ifp = ItemFluidPacket.newStack(invFluids.getFluidStackInSlot(i)); + if (ifp != null) drops.add(ifp); + } + super.getDrops(w, x, y, z, drops); + } + + @Override + public boolean canInsertItem(int slotIndex, ItemStack insertingItem, int side) { + return false; + } + + @Override + public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { + return 0; + } + + @Override + public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) { + FluidStack fs = invFluids.drain(from, resource, doDrain); + if (doDrain && fs != null) storedFluidCount -= fs.amount; + return fs; + } + + @Override + public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) { + FluidStack fs = invFluids.drain(from, maxDrain, doDrain); + if (doDrain && fs != null) storedFluidCount -= fs.amount; + return fs; + } + + @Override + public boolean canFill(ForgeDirection from, Fluid fluid) { + return false; + } + + @Override + public boolean canDrain(ForgeDirection from, Fluid fluid) { + return invFluids.canDrain(from, fluid); + } + + @Override + public FluidTankInfo[] getTankInfo(ForgeDirection from) { + return invFluids.getTankInfo(from); + } + + @Override + public void onFluidInventoryChanged(IAEFluidTank inv, int slot) { + saveChanges(); + markForUpdate(); + } + + @Override + public AEFluidInventory getInternalFluid() { + return this.invFluids; + } + + @TileEvent(TileEventType.NETWORK_READ) + public boolean readFromStream_TileSuperStockReplenisher(final ByteBuf data) { + final boolean oldPower = isPowered; + isPowered = data.readBoolean(); + return isPowered != oldPower; + } + + @TileEvent(TileEventType.NETWORK_WRITE) + public void writeToStream_TileSuperStockReplenisher(final ByteBuf data) { + data.writeBoolean(isActive()); + } + + @TileEvent(TileEventType.WORLD_NBT_READ) + public void readFromNBTEvent(NBTTagCompound data) { + invItems.readFromNBT(data, "ItemInv"); + invFluids.readFromNBT(data, "FluidInv"); + configItems.readFromNBT(data, "configItems"); + configFluids.readFromNBT(data, "configFluids"); + cell.readFromNBT(data, "cellHolder"); + totalBytes = data.getLong("totalBytes"); + storedFluidCount = data.getLong("storedFluidCount"); + storedItemCount = data.getLong("storedItemCount"); + getProxy().setIdlePowerUsage(data.getDouble("powerDraw")); + } + + @TileEvent(TileEventType.WORLD_NBT_WRITE) + public NBTTagCompound writeToNBTEvent(NBTTagCompound data) { + invItems.writeToNBT(data, "ItemInv"); + invFluids.writeToNBT(data, "FluidInv"); + configItems.writeToNBT(data, "configItems"); + configFluids.writeToNBT(data, "configFluids"); + cell.writeToNBT(data, "cellHolder"); + data.setLong("totalBytes", totalBytes); + data.setLong("storedFluidCount", storedFluidCount); + data.setLong("storedItemCount", storedItemCount); + data.setDouble("powerDraw", getProxy().getIdlePowerUsage()); + return data; + } + + @MENetworkEventSubscribe + public void stateChange(final MENetworkPowerStatusChange p) { + this.updatePowerState(); + } + + @MENetworkEventSubscribe + public final void bootingRender(final MENetworkBootingStatusChange c) { + this.updatePowerState(); + } + + @Override + public boolean isPowered() { + return this.isPowered; + } + + @Override + public boolean isActive() { + return this.isPowered; + } + + private void updatePowerState() { + boolean newState = false; + try { + newState = this.getProxy().isActive() + && this.getProxy().getEnergy().extractAEPower(1, Actionable.SIMULATE, PowerMultiplier.CONFIG) + > 0.0001; + } catch (final GridAccessException ignored) {} + if (newState != this.isPowered) { + this.isPowered = newState; + this.markForUpdate(); + } + } + + @Override + public DimensionalCoord getLocation() { + return new DimensionalCoord(this); + } + + @Override + public AECableType getCableConnectionType(ForgeDirection dir) { + return AECableType.SMART; + } + + @Override + public TickingRequest getTickingRequest(IGridNode node) { + return new TickingRequest(120, 120, false, false); + } + + @Override + public TickRateModulation tickingRequest(IGridNode node, int TicksSinceLastCall) { + return doWork(); + } +} diff --git a/src/main/java/com/glodblock/github/inventory/AEFluidInventory.java b/src/main/java/com/glodblock/github/inventory/AEFluidInventory.java index 522096a0..a6353df7 100644 --- a/src/main/java/com/glodblock/github/inventory/AEFluidInventory.java +++ b/src/main/java/com/glodblock/github/inventory/AEFluidInventory.java @@ -22,12 +22,21 @@ public class AEFluidInventory implements IAEFluidTank { private final IAEFluidStack[] fluids; private final IAEFluidInventory handler; private final int capacity; + private final long capacityLong; public int lastIndex; public AEFluidInventory(final IAEFluidInventory handler, final int slots, final int capcity) { this.fluids = new IAEFluidStack[slots]; this.handler = handler; this.capacity = capcity; + this.capacityLong = capcity; + } + + public AEFluidInventory(final IAEFluidInventory handler, final int slots, final long capcity) { + this.fluids = new IAEFluidStack[slots]; + this.handler = handler; + this.capacity = Integer.MAX_VALUE; + this.capacityLong = capcity; } public AEFluidInventory(final IAEFluidInventory handler, final int slots) { @@ -122,6 +131,37 @@ public class AEFluidInventory implements IAEFluidTank { return amountToStore; } + public long fill(final int slot, final IAEFluidStack resource, final boolean doFill) { + if (resource == null || resource.getStackSize() <= 0) { + return 0; + } + + final IAEFluidStack fluid = this.fluids[slot]; + + if (fluid != null && !(fluid.getFluid() == resource.getFluid())) { + return 0; + } + + long amountToStore = this.capacityLong; + + if (fluid != null) { + amountToStore -= fluid.getStackSize(); + } + + amountToStore = Math.min(amountToStore, resource.getStackSize()); + + if (doFill) { + if (fluid == null) { + this.setFluidInSlot(slot, resource); + } else { + fluid.setStackSize(fluid.getStackSize() + amountToStore); + this.onContentChanged(slot); + } + } + + return amountToStore; + } + public FluidStack drain(final int slot, final FluidStack resource, final boolean doDrain) { final IAEFluidStack fluid = this.fluids[slot]; if (fluid == null || !fluid.getFluidStack().isFluidEqual(resource)) { @@ -152,6 +192,28 @@ public class AEFluidInventory implements IAEFluidTank { return stack; } + public IAEFluidStack drain(final int slot, final long maxDrain, boolean doDrain) { + final IAEFluidStack fluid = this.fluids[slot]; + if (fluid == null || maxDrain <= 0) { + return null; + } + + long drained = maxDrain; + if (fluid.getStackSize() < drained) { + drained = fluid.getStackSize(); + } + + IAEFluidStack stack = fluid.copy().setStackSize(drained); + if (doDrain) { + fluid.setStackSize(fluid.getStackSize() - drained); + if (fluid.getStackSize() <= 0) { + this.fluids[slot] = null; + } + this.onContentChanged(slot); + } + return stack; + } + @Override public int fill(ForgeDirection from, final FluidStack fluid, final boolean doFill) { if (fluid == null || fluid.amount <= 0) { diff --git a/src/main/java/com/glodblock/github/inventory/gui/GuiType.java b/src/main/java/com/glodblock/github/inventory/gui/GuiType.java index 53dda56c..2959f71e 100644 --- a/src/main/java/com/glodblock/github/inventory/gui/GuiType.java +++ b/src/main/java/com/glodblock/github/inventory/gui/GuiType.java @@ -5,6 +5,7 @@ import java.util.List; import javax.annotation.Nullable; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.tileentity.TileEntity; import com.glodblock.github.client.gui.GuiCraftingStatus; import com.glodblock.github.client.gui.GuiDualInterface; @@ -39,6 +40,7 @@ import com.glodblock.github.client.gui.GuiPatternItemRenamer; import com.glodblock.github.client.gui.GuiPatternMulti; import com.glodblock.github.client.gui.GuiPatternValueAmount; import com.glodblock.github.client.gui.GuiRenamer; +import com.glodblock.github.client.gui.GuiSuperStockReplenisher; import com.glodblock.github.client.gui.container.ContainerCraftingWireless; import com.glodblock.github.client.gui.container.ContainerDualInterface; import com.glodblock.github.client.gui.container.ContainerEssentiaMonitor; @@ -68,6 +70,7 @@ import com.glodblock.github.client.gui.container.ContainerOCPatternEditor; import com.glodblock.github.client.gui.container.ContainerPatternMulti; import com.glodblock.github.client.gui.container.ContainerPatternValueAmount; import com.glodblock.github.client.gui.container.ContainerRenamer; +import com.glodblock.github.client.gui.container.ContainerSuperStockReplenisher; import com.glodblock.github.common.parts.PartFluidLevelEmitter; import com.glodblock.github.common.parts.PartFluidStorageBus; import com.glodblock.github.common.parts.base.FCPart; @@ -79,6 +82,7 @@ import com.glodblock.github.common.tile.TileIngredientBuffer; import com.glodblock.github.common.tile.TileLargeIngredientBuffer; import com.glodblock.github.common.tile.TileLevelMaintainer; import com.glodblock.github.common.tile.TileOCPatternEditor; +import com.glodblock.github.common.tile.TileSuperStockReplenisher; import com.glodblock.github.inventory.IDualHost; import com.glodblock.github.inventory.item.IFluidPortableCell; import com.glodblock.github.inventory.item.IWirelessTerminal; @@ -519,6 +523,18 @@ public enum GuiType { return new GuiPatternValueAmount(player.inventory, inv); } }), + PATTERN_VALUE_SET_TILE(new TileGuiFactory<>(TileEntity.class) { + + @Override + protected Object createServerGui(EntityPlayer player, TileEntity inv) { + return new ContainerPatternValueAmount(player.inventory, inv); + } + + @Override + protected Object createClientGui(EntityPlayer player, TileEntity inv) { + return new GuiPatternValueAmount(player.inventory, inv); + } + }), GUI_PATTERN_MULTI(new PartOrItemGuiFactory<>(ITerminalHost.class) { @@ -557,6 +573,19 @@ public enum GuiType { protected Object createClientGui(EntityPlayer player, ITerminalHost inv) { return new GuiMagnetFilter(player.inventory, inv); } + }), + + GUI_SUPER_STOCK_REPLENISHER(new TileGuiFactory<>(TileSuperStockReplenisher.class) { + + @Override + protected Object createServerGui(EntityPlayer player, TileSuperStockReplenisher inv) { + return new ContainerSuperStockReplenisher(player.inventory, inv); + } + + @Override + protected Object createClientGui(EntityPlayer player, TileSuperStockReplenisher inv) { + return new GuiSuperStockReplenisher(player.inventory, inv); + } }); public static final List VALUES = ImmutableList.copyOf(values()); diff --git a/src/main/java/com/glodblock/github/inventory/slot/OptionalFluidSlotFake.java b/src/main/java/com/glodblock/github/inventory/slot/OptionalFluidSlotFake.java new file mode 100644 index 00000000..1e6c4ced --- /dev/null +++ b/src/main/java/com/glodblock/github/inventory/slot/OptionalFluidSlotFake.java @@ -0,0 +1,28 @@ +package com.glodblock.github.inventory.slot; + +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +import com.glodblock.github.common.item.ItemFluidPacket; +import com.glodblock.github.util.Util; + +import appeng.container.slot.IOptionalSlotHost; +import appeng.container.slot.OptionalSlotFake; + +public class OptionalFluidSlotFake extends OptionalSlotFake { + + public OptionalFluidSlotFake(final IInventory inv, final IOptionalSlotHost containerBus, final int idx, final int x, + final int y, final int offX, final int offY, final int groupNum) { + super(inv, containerBus, idx, x, y, offX, offY, groupNum); + } + + @Override + public void putStack(ItemStack is) { + if (is == null) super.putStack(null); + FluidStack fluidStack = Util.getFluidFromItem(is); + if (fluidStack != null) { + super.putStack(ItemFluidPacket.newStack(fluidStack)); + } + } +} diff --git a/src/main/java/com/glodblock/github/loader/ChannelLoader.java b/src/main/java/com/glodblock/github/loader/ChannelLoader.java index 87fd2f96..04a9d0aa 100644 --- a/src/main/java/com/glodblock/github/loader/ChannelLoader.java +++ b/src/main/java/com/glodblock/github/loader/ChannelLoader.java @@ -27,6 +27,7 @@ import com.glodblock.github.network.SPacketMEItemInvUpdate; import com.glodblock.github.network.SPacketPatternItemRenamer; import com.glodblock.github.network.SPacketSetItemAmount; import com.glodblock.github.network.SPacketStringUpdate; +import com.glodblock.github.network.SPacketSuperStockReplenisherUpdate; import com.glodblock.github.network.SPacketSwitchBack; import com.glodblock.github.network.wrapper.FCNetworkWrapper; @@ -61,6 +62,11 @@ public class ChannelLoader implements Runnable { netHandler.registerMessage(new CPacketTransferRecipe.Handler(), CPacketTransferRecipe.class, id++, Side.SERVER); netHandler.registerMessage(new CPacketDumpTank.Handler(), CPacketDumpTank.class, id++, Side.SERVER); netHandler.registerMessage(new SPacketFluidUpdate.Handler(), SPacketFluidUpdate.class, id++, Side.CLIENT); + netHandler.registerMessage( + new SPacketSuperStockReplenisherUpdate.Handler(), + SPacketSuperStockReplenisherUpdate.class, + id++, + Side.CLIENT); netHandler .registerMessage(new CPacketPatternValueSet.Handler(), CPacketPatternValueSet.class, id++, Side.SERVER); netHandler.registerMessage(new CPacketValueConfig.Handler(), CPacketValueConfig.class, id++, Side.SERVER); diff --git a/src/main/java/com/glodblock/github/loader/ItemAndBlockHolder.java b/src/main/java/com/glodblock/github/loader/ItemAndBlockHolder.java index 605107eb..98c9054f 100644 --- a/src/main/java/com/glodblock/github/loader/ItemAndBlockHolder.java +++ b/src/main/java/com/glodblock/github/loader/ItemAndBlockHolder.java @@ -14,6 +14,7 @@ import com.glodblock.github.common.block.BlockIngredientBuffer; import com.glodblock.github.common.block.BlockLargeIngredientBuffer; import com.glodblock.github.common.block.BlockLevelMaintainer; import com.glodblock.github.common.block.BlockOCPatternEditor; +import com.glodblock.github.common.block.BlockSuperStockReplenisher; import com.glodblock.github.common.block.BlockWalrus; import com.glodblock.github.common.item.ItemBasicFluidStorageCell; import com.glodblock.github.common.item.ItemBasicFluidStoragePart; @@ -65,6 +66,7 @@ public class ItemAndBlockHolder { public static BlockLargeIngredientBuffer LARGE_BUFFER = new BlockLargeIngredientBuffer().register(); public static BlockOCPatternEditor OC_EDITOR = new BlockOCPatternEditor().register(); public static BlockWalrus WALRUS = new BlockWalrus().register(); + public static BlockSuperStockReplenisher SUPER_STOCK_RERPLENISHER = new BlockSuperStockReplenisher().register(); public static ItemFluidDrop DROP = new ItemFluidDrop().register(); public static ItemFluidEncodedPattern PATTERN = new ItemFluidEncodedPattern().register(); public static ItemPartFluidTerminal FLUID_TERM = new ItemPartFluidTerminal().register(); diff --git a/src/main/java/com/glodblock/github/network/CPacketInventoryAction.java b/src/main/java/com/glodblock/github/network/CPacketInventoryAction.java index 8a58a53f..b95b3885 100644 --- a/src/main/java/com/glodblock/github/network/CPacketInventoryAction.java +++ b/src/main/java/com/glodblock/github/network/CPacketInventoryAction.java @@ -26,6 +26,7 @@ import appeng.container.ContainerOpenContext; import appeng.container.implementations.ContainerCraftAmount; import appeng.container.implementations.ContainerPatternItemRenamer; import appeng.helpers.InventoryAction; +import appeng.tile.networking.TileCableBus; import appeng.util.item.AEItemStack; import cpw.mods.fml.common.network.simpleimpl.IMessage; import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; @@ -131,12 +132,21 @@ public class CPacketInventoryAction implements IMessage { if (context != null && message.stack != null) { final TileEntity te = context.getTile(); if (te != null) { - InventoryHandler.openGui( + if (te instanceof TileCableBus) { + InventoryHandler.openGui( sender, te.getWorldObj(), new BlockPos(te), Objects.requireNonNull(baseContainer.getOpenContext().getSide()), GuiType.PATTERN_VALUE_SET); + } else { + InventoryHandler.openGui( + sender, + te.getWorldObj(), + new BlockPos(te), + Objects.requireNonNull(baseContainer.getOpenContext().getSide()), + GuiType.PATTERN_VALUE_SET_TILE); + } } else if (target instanceof IWirelessTerminal wt) { InventoryHandler.openGui( sender, diff --git a/src/main/java/com/glodblock/github/network/CPacketPatternValueSet.java b/src/main/java/com/glodblock/github/network/CPacketPatternValueSet.java index 7c3b6a49..e17557a9 100644 --- a/src/main/java/com/glodblock/github/network/CPacketPatternValueSet.java +++ b/src/main/java/com/glodblock/github/network/CPacketPatternValueSet.java @@ -9,6 +9,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraftforge.fluids.FluidStack; import com.glodblock.github.client.gui.container.ContainerPatternValueAmount; +import com.glodblock.github.client.gui.container.ContainerSuperStockReplenisher; import com.glodblock.github.client.gui.container.base.FCContainerEncodeTerminal; import com.glodblock.github.common.item.ItemFluidPacket; import com.glodblock.github.inventory.InventoryHandler; @@ -92,7 +93,8 @@ public class CPacketPatternValueSet implements IMessage { Objects.requireNonNull(context.getSide()), message.originGui); } - if (player.openContainer instanceof FCContainerEncodeTerminal) { + if (player.openContainer instanceof FCContainerEncodeTerminal + || player.openContainer instanceof ContainerSuperStockReplenisher) { Slot slot = player.openContainer.getSlot(message.valueIndex); if (slot instanceof SlotFake) { ItemStack stack = slot.getStack().copy(); diff --git a/src/main/java/com/glodblock/github/network/SPacketSuperStockReplenisherUpdate.java b/src/main/java/com/glodblock/github/network/SPacketSuperStockReplenisherUpdate.java new file mode 100644 index 00000000..e039fb70 --- /dev/null +++ b/src/main/java/com/glodblock/github/network/SPacketSuperStockReplenisherUpdate.java @@ -0,0 +1,59 @@ +package com.glodblock.github.network; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiScreen; + +import com.glodblock.github.client.gui.GuiSuperStockReplenisher; +import com.glodblock.github.util.Util; + +import appeng.api.storage.data.IAEStack; +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; +import io.netty.buffer.ByteBuf; + +public class SPacketSuperStockReplenisherUpdate implements IMessage { + + private Map> list; + + public SPacketSuperStockReplenisherUpdate() {} + + public SPacketSuperStockReplenisherUpdate(Map> data) { + this.list = data; + } + + @Override + public void fromBytes(ByteBuf buf) { + this.list = new HashMap<>(); + try { + Util.readAEStackMapFromBuf(this.list, buf); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void toBytes(ByteBuf buf) { + try { + Util.writeAEStackMapToBuf(this.list, buf); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static class Handler implements IMessageHandler { + + @Override + public IMessage onMessage(SPacketSuperStockReplenisherUpdate message, MessageContext ctx) { + final GuiScreen gs = Minecraft.getMinecraft().currentScreen; + if (gs instanceof GuiSuperStockReplenisher gss) { + gss.update(message.list); + } + return null; + } + } +} diff --git a/src/main/java/com/glodblock/github/util/NameConst.java b/src/main/java/com/glodblock/github/util/NameConst.java index ca421ebf..49353ea3 100644 --- a/src/main/java/com/glodblock/github/util/NameConst.java +++ b/src/main/java/com/glodblock/github/util/NameConst.java @@ -21,6 +21,7 @@ public class NameConst { public static final String BLOCK_OC_PATTERN_EDITOR = "oc_pattern_editor"; public static final String BLOCK_LEVEL_MAINTAINER = "level_maintainer"; public static final String BLOCK_WALRUS = "walrus"; + public static final String BLOCK_SUPER_STOCK_REPLENISHER = "super_stock_replenisher"; public static final String ITEM_FLUID_DROP = "fluid_drop"; public static final String ITEM_FLUID_ENCODED_PATTERN = "fluid_encoded_pattern"; public static final String ITEM_PART_FLUID_STORAGE_MONITOR = "part_fluid_storage_monitor"; diff --git a/src/main/java/com/glodblock/github/util/Util.java b/src/main/java/com/glodblock/github/util/Util.java index 35cc4c5a..ef4a0043 100644 --- a/src/main/java/com/glodblock/github/util/Util.java +++ b/src/main/java/com/glodblock/github/util/Util.java @@ -51,6 +51,7 @@ import appeng.api.parts.IPart; import appeng.api.storage.IMEInventoryHandler; import appeng.api.storage.StorageChannel; import appeng.api.storage.data.IAEFluidStack; +import appeng.api.storage.data.IAEStack; import appeng.api.util.DimensionalCoord; import appeng.api.util.WorldCoord; import appeng.container.AEBaseContainer; @@ -60,6 +61,7 @@ import appeng.tile.networking.TileCableBus; import appeng.tile.networking.TileWireless; import appeng.util.Platform; import appeng.util.item.AEFluidStack; +import appeng.util.item.AEItemStack; import baubles.api.BaublesApi; import codechicken.nei.recipe.StackInfo; import cpw.mods.fml.common.Loader; @@ -413,6 +415,36 @@ public final class Util { } } + public static void writeAEStackMapToBuf(Map> list, ByteBuf buf) throws IOException { + buf.writeInt(list.size()); + for (Map.Entry> as : list.entrySet()) { + buf.writeInt(as.getKey()); + if (as.getValue() == null) buf.writeBoolean(false); + else { + buf.writeBoolean(true); + as.getValue().writeToPacket(buf); + } + } + } + + public static void readAEStackMapFromBuf(Map> list, ByteBuf buf) throws IOException { + int size = buf.readInt(); + for (int i = 0; i < size; i++) { + int id = buf.readInt(); + boolean isNull = buf.readBoolean(); + if (!isNull) list.put(id, null); + else { + IAEStack as; + if (id > 99) { + as = AEItemStack.loadItemStackFromPacket(buf); + } else { + as = AEFluidStack.loadFluidStackFromPacket(buf); + } + list.put(id, as); + } + } + } + public static class GuiHelper { public enum GuiType { diff --git a/src/main/resources/assets/ae2fc/lang/en_US.lang b/src/main/resources/assets/ae2fc/lang/en_US.lang index 8a17a5ad..4ae7bcf7 100644 --- a/src/main/resources/assets/ae2fc/lang/en_US.lang +++ b/src/main/resources/assets/ae2fc/lang/en_US.lang @@ -75,6 +75,7 @@ tile.oc_pattern_editor.name=OC Pattern Editor tile.level_maintainer.name=ME Level Maintainer tile.fluid_buffer.name=ME Fluid Buffer tile.walrus.name=Walrus +tile.super_stock_replenisher.name=Super Stock Replenisher tile.fluid_auto_filler.name=ME Fluid Auto Filler tile.certus_quartz_tank.name=Certus Quartz Tank - %s tile.certus_quartz_tank_empty.name=Certus Quartz Tank diff --git a/src/main/resources/assets/ae2fc/textures/blocks/super_stock_replenisher.png b/src/main/resources/assets/ae2fc/textures/blocks/super_stock_replenisher.png new file mode 100644 index 0000000000000000000000000000000000000000..378a9d8bc90550487a638329ecf66d5475cd460f GIT binary patch literal 581 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucL5ULAh?3y^w370~qEv=}#LT=BJwMkF1yemk zJrkk(%bI~|wxvdRrg?g5F>nAmtPE0&tPG4mmKP99L)jqLXfQH^#hHL?Lq;aB>!N_{ z%yt&AcovWi0trA2(hsB2EM;J3V3@$pzyefZU}S8-xBy}*NC)czh)Gj`Y!F}qn!^NE z8DwbzWI=Tq8W@0NuRq(Zxc6E779jJBr;B5Vh5ypYwtP(v0&d6WpA(jtdhA}?u~PxB zL~~5kZaF^Z)Oq8ZGwq1+jf+zK3Hi-&2QO*dKe6UDSKA5gvYUzfjypKHYJOcHlyR_T z!vm+lLyI5n?MgM3n{>HvX8_9=CFTf&?2;b=E=snO5*am=HXd$Z4P1Y^JzmIKXQtJ9 z&Y+A>ULqBCJJ)$n{x_v*t^e8P<6k?jn@2IYEjNC@`*!QMllyjBtyfmi_!_(m#jJl+-8yYnLXV6Kj_Od71uO;JR8nX=Kqc*?ZUJfDO{5d*zUdZ#53Xo rm$Plut%%3XtsWP;c{F}n3)?b&F^PI9@b`=`C@ef({an^LB{Ts5Dxs^# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/ae2fc/textures/gui/superStockReplenisher.png b/src/main/resources/assets/ae2fc/textures/gui/superStockReplenisher.png new file mode 100644 index 0000000000000000000000000000000000000000..cd2a6b00526201cd89968a4abdcb97fe8846c4e8 GIT binary patch literal 1985 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|G!U;i$lZxy-8q?;Kn_c~qpu?a z!^VE@KZ&eBK4*bPWHAE+-yRTVoVusT6DTNA;u=vBoS#-wo>-L15RjOeSEA?V8lqsT zXQ*eGv^9tasAgMgglC$krxpVTki*I##mEY_+6%~&hO&XKVbEY?28%NR*@lcv3<5wp z3Wzh?S-|31KsE?Ol`%5BU`EhrmNEdPCa^QG096_o85=MzfS3yMEb9V@NmGDq5MTnD z%LG;#WN86pL3J4#7=UCIt|%+AcFsD$z`$1E>Eakt5%>1)Lto`^k+wvSQ0yADCZ$GC>=&6)nd*P&_P!{<=5Jo;~~S;-Bl*uRp)9_V>1Gv-y@= z|9_ry`t<3$n+uOWd3feYHiJ9!hwJwBe*N$3{?_jLzvBMC8-CyY>*vp{{rTzWoIcB~ zhb`NWr&_Ds=G=3nYF66-}6mw#Ox(D}Q$7*`Bt_TXqd64*_U+quH*Lbh z!!H+k6yHnpTYJ{BEcew1mAFHu3>Jod|58~RCSToO8(&l{R{qJH>40a|^Uc2}MXNAA zc(NpZhqNbyMWo-qr5WP6$4G`^?JTIhW<9Ga2+{!$JqySd?HxmH^xL_nGMI ztgL5O+|Iu2_m*xvwox!ctvE~h`3;UOa?*`yM$65L`g$E+7xH4n0J2f&b`<2wA6RmK zPg1ZiFvM3_{w>T@zF=X-bT$R(ei`Y;YstzNe1LYI1KMW0juCe(W3gl1Tjm*GW{2mj zS~)XV+H|?SUM`E&akm9CL7@ONwkn5Z*2y`yPFR{TtvzmvlwhzJg_gt)ZLMXPT=%)l z*VME)Yw@!$$CvgxJiftUGTCzL#Nr&5sQz9DW1yXuK-<3VV8fOuaoVwC8-K#3{J4!P zm!g1U^u{o7dh0g<4^eLc3l6)==1BWw%OGyzz~=POb2F6y}^1cjpt7| zO(?8k!I6E?O)2~G`r!0Wf4>8Lo_p@;)2Hula@X@(oV&=dCH{cW?YCvW=2bwFJusCp zN*s45Jz)P;->A*6g(iocH*=OnTbIT2B|h6U6cgO?7!IcS6I&G?|KNb71M6KPB`ddy zT)KAq`^@0%;vCkv^N`TncJJDmm0K;hF|8*j*y?_-%H0Y}k82M+p2F?;z<85Dii|uX zqf7B4&J@vQTu7nLf(X(f2|uncXxN+b^h^Z&Y$Ej_749eTZ11yVFy(^ cE9TDq%k6b#zRl!oN_HRtPgg&ebxsLQ03Z^?CjbBd literal 0 HcmV?d00001