diff --git a/src/main/java/com/glodblock/github/client/gui/GuiFluidPatternTerminalCraftingStatus.java b/src/main/java/com/glodblock/github/client/gui/GuiFluidPatternTerminalCraftingStatus.java index d590602e..f93c569c 100644 --- a/src/main/java/com/glodblock/github/client/gui/GuiFluidPatternTerminalCraftingStatus.java +++ b/src/main/java/com/glodblock/github/client/gui/GuiFluidPatternTerminalCraftingStatus.java @@ -13,7 +13,8 @@ import com.glodblock.github.common.parts.PartFluidPatternTerminalEx; import com.glodblock.github.common.parts.PartFluidTerminal; import com.glodblock.github.inventory.InventoryHandler; import com.glodblock.github.inventory.gui.GuiType; -import com.glodblock.github.inventory.item.WirelessTerminal; +import com.glodblock.github.inventory.item.WirelessFluidTerminal; +import com.glodblock.github.inventory.item.WirelessPatternTerminal; import com.glodblock.github.loader.ItemAndBlockHolder; import com.glodblock.github.util.Ae2ReflectClient; @@ -35,8 +36,10 @@ public class GuiFluidPatternTerminalCraftingStatus extends GuiCraftingStatus { Ae2ReflectClient.rewriteIcon(this, new ItemStack(ItemAndBlockHolder.FLUID_TERMINAL_EX, 1)); else if (host instanceof PartFluidTerminal) { Ae2ReflectClient.rewriteIcon(this, new ItemStack(ItemAndBlockHolder.FLUID_TERM, 1)); - } else if (host instanceof WirelessTerminal) { + } else if (host instanceof WirelessFluidTerminal) { Ae2ReflectClient.rewriteIcon(this, new ItemStack(ItemAndBlockHolder.WIRELESS_FLUID_TERM, 1)); + } else if (host instanceof WirelessPatternTerminal) { + Ae2ReflectClient.rewriteIcon(this, new ItemStack(ItemAndBlockHolder.WIRELESS_PATTERN_TERM, 1)); } super.initGui(); @@ -50,7 +53,9 @@ public class GuiFluidPatternTerminalCraftingStatus extends GuiCraftingStatus { else if (host instanceof PartFluidPatternTerminalEx) InventoryHandler.switchGui(GuiType.FLUID_PATTERN_TERMINAL_EX); else if (host instanceof PartFluidTerminal) InventoryHandler.switchGui(GuiType.FLUID_TERMINAL); - else if (host instanceof WirelessTerminal) InventoryHandler.switchGui(GuiType.WIRELESS_FLUID_TERMINAL); + else if (host instanceof WirelessFluidTerminal) InventoryHandler.switchGui(GuiType.WIRELESS_FLUID_TERMINAL); + else if (host instanceof WirelessPatternTerminal) + InventoryHandler.switchGui(GuiType.WIRELESS_FLUID_PATTERN_TERMINAL); } else { super.actionPerformed(btn); } diff --git a/src/main/java/com/glodblock/github/client/gui/GuiPatternPortableCell.java b/src/main/java/com/glodblock/github/client/gui/GuiPatternPortableCell.java new file mode 100644 index 00000000..aca7de2b --- /dev/null +++ b/src/main/java/com/glodblock/github/client/gui/GuiPatternPortableCell.java @@ -0,0 +1,12 @@ +package com.glodblock.github.client.gui; + +import net.minecraft.entity.player.InventoryPlayer; + +import com.glodblock.github.inventory.item.IWirelessTerminal; + +public class GuiPatternPortableCell extends GuiFluidPatternTerminal { + + public GuiPatternPortableCell(InventoryPlayer inventoryPlayer, IWirelessTerminal te) { + super(inventoryPlayer, te); + } +} diff --git a/src/main/java/com/glodblock/github/client/gui/container/ContainerPatternPortableCell.java b/src/main/java/com/glodblock/github/client/gui/container/ContainerPatternPortableCell.java new file mode 100644 index 00000000..319efe07 --- /dev/null +++ b/src/main/java/com/glodblock/github/client/gui/container/ContainerPatternPortableCell.java @@ -0,0 +1,69 @@ +package com.glodblock.github.client.gui.container; + +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.item.ItemStack; + +import appeng.api.config.Actionable; +import appeng.api.config.PowerMultiplier; +import appeng.util.Platform; + +import com.glodblock.github.inventory.item.IWirelessTerminal; + +public class ContainerPatternPortableCell extends ContainerFluidPatternTerminal { + + private double powerMultiplier = 0.5; + private final IWirelessTerminal civ; + private int ticks = 0; + private final int slot; + + public ContainerPatternPortableCell(InventoryPlayer ip, IWirelessTerminal monitorable) { + super(ip, monitorable); + if (monitorable != null) { + final int slotIndex = monitorable.getInventorySlot(); + this.lockPlayerInventorySlot(slotIndex); + this.slot = slotIndex; + } else { + this.slot = -1; + this.lockPlayerInventorySlot(ip.currentItem); + } + this.civ = monitorable; + } + + public void detectAndSendChanges() { + final ItemStack currentItem = this.slot < 0 ? this.getPlayerInv().getCurrentItem() + : this.getPlayerInv().getStackInSlot(this.slot); + if (this.civ != null) { + if (currentItem != this.civ.getItemStack()) { + if (currentItem != null) { + if (Platform.isSameItem(this.civ.getItemStack(), currentItem)) { + this.getPlayerInv() + .setInventorySlotContents(this.getPlayerInv().currentItem, this.civ.getItemStack()); + } else { + this.setValidContainer(false); + } + } else { + this.setValidContainer(false); + } + } + } else { + this.setValidContainer(false); + } + this.ticks++; + if (this.ticks > 10 && this.civ != null) { + this.civ.extractAEPower( + this.getPowerMultiplier() * this.ticks, + Actionable.MODULATE, + PowerMultiplier.CONFIG); + this.ticks = 0; + } + super.detectAndSendChanges(); + } + + private double getPowerMultiplier() { + return this.powerMultiplier; + } + + void setPowerMultiplier(final double powerMultiplier) { + this.powerMultiplier = powerMultiplier; + } +} diff --git a/src/main/java/com/glodblock/github/client/gui/container/base/FCContainerEncodeTerminal.java b/src/main/java/com/glodblock/github/client/gui/container/base/FCContainerEncodeTerminal.java index d51fb67b..b05db36e 100644 --- a/src/main/java/com/glodblock/github/client/gui/container/base/FCContainerEncodeTerminal.java +++ b/src/main/java/com/glodblock/github/client/gui/container/base/FCContainerEncodeTerminal.java @@ -36,8 +36,8 @@ import com.glodblock.github.client.gui.container.ContainerItemMonitor; import com.glodblock.github.common.item.ItemFluidDrop; import com.glodblock.github.common.item.ItemFluidEncodedPattern; import com.glodblock.github.common.item.ItemFluidPacket; -import com.glodblock.github.common.parts.base.FCFluidEncodeTerminal; import com.glodblock.github.inventory.IPatternConsumer; +import com.glodblock.github.inventory.item.PatternTerminal; import com.glodblock.github.loader.ItemAndBlockHolder; import com.glodblock.github.util.FluidPatternDetails; import com.glodblock.github.util.Util; @@ -45,7 +45,7 @@ import com.glodblock.github.util.Util; public abstract class FCContainerEncodeTerminal extends ContainerItemMonitor implements IAEAppEngInventory, IOptionalSlotHost, IContainerCraftingPacket, IPatternConsumer { - protected final FCFluidEncodeTerminal patternTerminal; + protected final PatternTerminal patternTerminal; protected final AppEngInternalInventory cOut = new AppEngInternalInventory(null, 1); protected final IInventory crafting; protected final SlotRestrictedInput patternSlotIN; @@ -77,7 +77,7 @@ public abstract class FCContainerEncodeTerminal extends ContainerItemMonitor public FCContainerEncodeTerminal(final InventoryPlayer ip, final ITerminalHost monitorable) { super(ip, monitorable); - this.patternTerminal = (FCFluidEncodeTerminal) monitorable; + this.patternTerminal = (PatternTerminal) monitorable; this.inverted = patternTerminal.isInverted(); final IInventory patternInv = this.patternTerminal.getInventoryByName("pattern"); this.crafting = this.patternTerminal.getInventoryByName("crafting"); @@ -170,7 +170,7 @@ public abstract class FCContainerEncodeTerminal extends ContainerItemMonitor } } - public FCFluidEncodeTerminal getPatternTerminal() { + public PatternTerminal getPatternTerminal() { return this.patternTerminal; } @@ -368,13 +368,11 @@ public abstract class FCContainerEncodeTerminal extends ContainerItemMonitor for (final ItemStack encodedPatternStack : AEApi.instance().definitions().items().encodedPattern() .maybeStack(1).asSet()) { output = encodedPatternStack; - this.patternSlotOUT.putStack(output); } } else if (output.getItem() instanceof ItemFluidEncodedPattern) { for (final ItemStack encodedPatternStack : AEApi.instance().definitions().items().encodedPattern() .maybeStack(1).asSet()) { output = encodedPatternStack; - this.patternSlotOUT.putStack(output); } } @@ -399,6 +397,7 @@ public abstract class FCContainerEncodeTerminal extends ContainerItemMonitor encodedValue.setBoolean("beSubstitute", this.beSubstitute); encodedValue.setBoolean("prioritize", this.prioritize); output.setTagCompound(encodedValue); + this.patternSlotOUT.putStack(output); } protected ItemStack[] getInputs() { diff --git a/src/main/java/com/glodblock/github/common/item/ItemBaseWirelessTerminal.java b/src/main/java/com/glodblock/github/common/item/ItemBaseWirelessTerminal.java new file mode 100644 index 00000000..025a32d2 --- /dev/null +++ b/src/main/java/com/glodblock/github/common/item/ItemBaseWirelessTerminal.java @@ -0,0 +1,85 @@ +package com.glodblock.github.common.item; + +import java.util.Optional; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +import appeng.api.AEApi; +import appeng.api.features.ILocatable; +import appeng.api.features.IWirelessTermHandler; +import appeng.api.features.IWirelessTermRegistry; +import appeng.core.localization.PlayerMessages; +import appeng.items.tools.powered.ToolWirelessTerminal; + +import com.glodblock.github.inventory.InventoryHandler; +import com.glodblock.github.inventory.gui.GuiType; +import com.glodblock.github.inventory.item.IItemInventory; +import com.glodblock.github.util.BlockPos; + +public class ItemBaseWirelessTerminal extends ToolWirelessTerminal implements IItemInventory { + + protected GuiType type; + + public ItemBaseWirelessTerminal(GuiType t) { + super(); + this.type = Optional.of(t).get(); + } + + @Override + public ItemStack onItemRightClick(final ItemStack item, final World w, final EntityPlayer player) { + IWirelessTermRegistry term = AEApi.instance().registries().wireless(); + if (!term.isWirelessTerminal(item)) { + player.addChatMessage(PlayerMessages.DeviceNotWirelessTerminal.get()); + return item; + } + final IWirelessTermHandler handler = term.getWirelessTerminalHandler(item); + final String unparsedKey = handler.getEncryptionKey(item); + if (unparsedKey.isEmpty()) { + player.addChatMessage(PlayerMessages.DeviceNotLinked.get()); + return item; + } + final long parsedKey = Long.parseLong(unparsedKey); + final ILocatable securityStation = AEApi.instance().registries().locatable().getLocatableBy(parsedKey); + if (securityStation == null) { + player.addChatMessage(PlayerMessages.StationCanNotBeLocated.get()); + return item; + } + if (handler.hasPower(player, 0.5, item)) { + InventoryHandler.openGui( + player, + w, + new BlockPos(player.inventory.currentItem, 0, 0), + ForgeDirection.UNKNOWN, + this.type); + } else { + player.addChatMessage(PlayerMessages.DeviceNotPowered.get()); + } + + return item; + } + + @Override + public boolean canHandle(final ItemStack is) { + return is.getItem() == this; + } + + public ItemStack stack() { + return new ItemStack(this, 1); + } + + @Override + public Object getInventory(ItemStack stack, World world, int x, int y, int z, EntityPlayer player) { + return null; + } + + public void setGuiType(GuiType type) { + this.type = type; + } + + public GuiType guiGuiType() { + return this.type; + } +} diff --git a/src/main/java/com/glodblock/github/common/item/ItemWirelessFluidTerminal.java b/src/main/java/com/glodblock/github/common/item/ItemWirelessFluidTerminal.java index 505df3fe..5a95384e 100644 --- a/src/main/java/com/glodblock/github/common/item/ItemWirelessFluidTerminal.java +++ b/src/main/java/com/glodblock/github/common/item/ItemWirelessFluidTerminal.java @@ -3,74 +3,31 @@ package com.glodblock.github.common.item; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; import appeng.api.AEApi; -import appeng.api.features.ILocatable; -import appeng.api.features.IWirelessTermHandler; -import appeng.api.features.IWirelessTermRegistry; +import appeng.api.networking.IGridNode; import appeng.core.localization.PlayerMessages; -import appeng.items.tools.powered.ToolWirelessTerminal; +import appeng.util.Platform; import com.glodblock.github.FluidCraft; import com.glodblock.github.common.tabs.FluidCraftingTabs; -import com.glodblock.github.inventory.InventoryHandler; import com.glodblock.github.inventory.gui.GuiType; -import com.glodblock.github.inventory.item.IItemInventory; -import com.glodblock.github.inventory.item.WirelessTerminal; +import com.glodblock.github.inventory.item.WirelessFluidTerminal; import com.glodblock.github.loader.IRegister; -import com.glodblock.github.util.BlockPos; import com.glodblock.github.util.NameConst; +import com.glodblock.github.util.Util; import cpw.mods.fml.common.registry.GameRegistry; -public class ItemWirelessFluidTerminal extends ToolWirelessTerminal - implements IItemInventory, IRegister { +public class ItemWirelessFluidTerminal extends ItemBaseWirelessTerminal + implements IRegister { public ItemWirelessFluidTerminal() { - super(); + super(GuiType.WIRELESS_FLUID_TERMINAL); AEApi.instance().registries().wireless().registerWirelessHandler(this); setUnlocalizedName(NameConst.ITEM_WIRELESS_FLUID_TERMINAL); setTextureName(FluidCraft.resource(NameConst.ITEM_WIRELESS_FLUID_TERMINAL).toString()); } - @Override - public ItemStack onItemRightClick(final ItemStack item, final World w, final EntityPlayer player) { - IWirelessTermRegistry term = AEApi.instance().registries().wireless(); - if (!term.isWirelessTerminal(item)) { - player.addChatMessage(PlayerMessages.DeviceNotWirelessTerminal.get()); - return item; - } - final IWirelessTermHandler handler = term.getWirelessTerminalHandler(item); - final String unparsedKey = handler.getEncryptionKey(item); - if (unparsedKey.isEmpty()) { - player.addChatMessage(PlayerMessages.DeviceNotLinked.get()); - return item; - } - final long parsedKey = Long.parseLong(unparsedKey); - final ILocatable securityStation = AEApi.instance().registries().locatable().getLocatableBy(parsedKey); - if (securityStation == null) { - player.addChatMessage(PlayerMessages.StationCanNotBeLocated.get()); - return item; - } - if (handler.hasPower(player, 0.5, item)) { - InventoryHandler.openGui( - player, - w, - new BlockPos((int) player.posX, (int) player.posY, (int) player.posZ), - ForgeDirection.UNKNOWN, - GuiType.WIRELESS_FLUID_TERMINAL); - } else { - player.addChatMessage(PlayerMessages.DeviceNotPowered.get()); - } - - return item; - } - - @Override - public boolean canHandle(final ItemStack is) { - return is.getItem() == this; - } - @Override public ItemWirelessFluidTerminal register() { GameRegistry.registerItem(this, NameConst.ITEM_WIRELESS_FLUID_TERMINAL, FluidCraft.MODID); @@ -81,14 +38,14 @@ public class ItemWirelessFluidTerminal extends ToolWirelessTerminal @Override public Object getInventory(ItemStack stack, World world, int x, int y, int z, EntityPlayer player) { try { - return new WirelessTerminal(stack, new BlockPos(x, y, z, world), player); + IGridNode gridNode = Util.getWirelessGrid(stack); + if (gridNode != null) { + return new WirelessFluidTerminal(stack, x, gridNode, player); + } } catch (Exception e) { - player.addChatMessage(PlayerMessages.OutOfRange.get()); - return null; + if (Platform.isClient()) player.addChatMessage(PlayerMessages.OutOfRange.get()); } + return null; } - public ItemStack stack() { - return new ItemStack(this, 1); - } } diff --git a/src/main/java/com/glodblock/github/common/item/ItemWirelessPatternTerminal.java b/src/main/java/com/glodblock/github/common/item/ItemWirelessPatternTerminal.java new file mode 100644 index 00000000..6caf4e22 --- /dev/null +++ b/src/main/java/com/glodblock/github/common/item/ItemWirelessPatternTerminal.java @@ -0,0 +1,50 @@ +package com.glodblock.github.common.item; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import appeng.api.AEApi; +import appeng.api.networking.IGridNode; +import appeng.core.localization.PlayerMessages; +import appeng.util.Platform; + +import com.glodblock.github.FluidCraft; +import com.glodblock.github.common.tabs.FluidCraftingTabs; +import com.glodblock.github.inventory.gui.GuiType; +import com.glodblock.github.inventory.item.WirelessPatternTerminal; +import com.glodblock.github.loader.IRegister; +import com.glodblock.github.util.NameConst; +import com.glodblock.github.util.Util; +import cpw.mods.fml.common.registry.GameRegistry; + +public class ItemWirelessPatternTerminal extends ItemBaseWirelessTerminal + implements IRegister { + + public ItemWirelessPatternTerminal() { + super(GuiType.WIRELESS_FLUID_PATTERN_TERMINAL); + AEApi.instance().registries().wireless().registerWirelessHandler(this); + setUnlocalizedName(NameConst.ITEM_WIRELESS_FLUID_PATTERN_TERMINAL); + setTextureName(FluidCraft.resource(NameConst.ITEM_WIRELESS_FLUID_PATTERN_TERMINAL).toString()); + } + + @Override + public ItemWirelessPatternTerminal register() { + GameRegistry.registerItem(this, NameConst.ITEM_WIRELESS_FLUID_PATTERN_TERMINAL, FluidCraft.MODID); + setCreativeTab(FluidCraftingTabs.INSTANCE); + return this; + } + + @Override + public Object getInventory(ItemStack stack, World world, int x, int y, int z, EntityPlayer player) { + try { + IGridNode gridNode = Util.getWirelessGrid(stack); + if (gridNode != null) { + return new WirelessPatternTerminal(stack, x, gridNode, player); + } + } catch (Exception e) { + if (Platform.isClient()) player.addChatMessage(PlayerMessages.OutOfRange.get()); + } + return null; + } +} diff --git a/src/main/java/com/glodblock/github/common/parts/base/FCFluidEncodeTerminal.java b/src/main/java/com/glodblock/github/common/parts/base/FCFluidEncodeTerminal.java index 75e6ff4f..dc8e9c36 100644 --- a/src/main/java/com/glodblock/github/common/parts/base/FCFluidEncodeTerminal.java +++ b/src/main/java/com/glodblock/github/common/parts/base/FCFluidEncodeTerminal.java @@ -11,8 +11,9 @@ import appeng.api.storage.data.IAEItemStack; import appeng.tile.inventory.AppEngInternalInventory; import com.glodblock.github.common.item.ItemFluidPacket; +import com.glodblock.github.inventory.item.PatternTerminal; -public abstract class FCFluidEncodeTerminal extends FCPart { +public abstract class FCFluidEncodeTerminal extends FCPart implements PatternTerminal { protected AppEngInternalInventory crafting; protected AppEngInternalInventory output; diff --git a/src/main/java/com/glodblock/github/inventory/ItemBiggerAppEngInventory.java b/src/main/java/com/glodblock/github/inventory/ItemBiggerAppEngInventory.java new file mode 100644 index 00000000..ab897af2 --- /dev/null +++ b/src/main/java/com/glodblock/github/inventory/ItemBiggerAppEngInventory.java @@ -0,0 +1,25 @@ +package com.glodblock.github.inventory; + +import net.minecraft.item.ItemStack; + +import appeng.tile.inventory.BiggerAppEngInventory; +import appeng.util.Platform; + +public class ItemBiggerAppEngInventory extends BiggerAppEngInventory { + + private final ItemStack is; + private final String name; + + public ItemBiggerAppEngInventory(ItemStack is, String name, int size) { + super(null, size); + this.name = name; + this.is = is; + this.readFromNBT(Platform.openNbtData(is), name); + } + + @Override + public void markDirty() { + this.writeToNBT(Platform.openNbtData(is), this.name); + } + +} diff --git a/src/main/java/com/glodblock/github/inventory/WirelessFluidPatternTerminalPatterns.java b/src/main/java/com/glodblock/github/inventory/WirelessFluidPatternTerminalPatterns.java new file mode 100644 index 00000000..b95cbdfa --- /dev/null +++ b/src/main/java/com/glodblock/github/inventory/WirelessFluidPatternTerminalPatterns.java @@ -0,0 +1,22 @@ +package com.glodblock.github.inventory; + +import net.minecraft.item.ItemStack; + +import appeng.tile.inventory.AppEngInternalInventory; +import appeng.util.Platform; + +public class WirelessFluidPatternTerminalPatterns extends AppEngInternalInventory { + + private final ItemStack is; + + public WirelessFluidPatternTerminalPatterns(final ItemStack is) { + super(null, 2); + this.is = is; + this.readFromNBT(Platform.openNbtData(is), "pattern"); + } + + @Override + public void markDirty() { + this.writeToNBT(Platform.openNbtData(is), "pattern"); + } +} 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 acae829e..540e9afc 100644 --- a/src/main/java/com/glodblock/github/inventory/gui/GuiType.java +++ b/src/main/java/com/glodblock/github/inventory/gui/GuiType.java @@ -220,6 +220,18 @@ public enum GuiType { return new GuiFluidPortableCell(player.inventory, inv); } }), + WIRELESS_FLUID_PATTERN_TERMINAL(new ItemGuiFactory(IWirelessTerminal.class) { + + @Override + protected Object createServerGui(EntityPlayer player, IWirelessTerminal inv) { + return new ContainerPatternPortableCell(player.inventory, inv); + } + + @Override + protected Object createClientGui(EntityPlayer player, IWirelessTerminal inv) { + return new GuiPatternPortableCell(player.inventory, inv); + } + }), FLUID_PATTERN_TERMINAL(new PartGuiFactory(ITerminalHost.class) { diff --git a/src/main/java/com/glodblock/github/inventory/gui/ItemGuiFactory.java b/src/main/java/com/glodblock/github/inventory/gui/ItemGuiFactory.java index 6017171a..a6e4cc98 100644 --- a/src/main/java/com/glodblock/github/inventory/gui/ItemGuiFactory.java +++ b/src/main/java/com/glodblock/github/inventory/gui/ItemGuiFactory.java @@ -2,6 +2,7 @@ package com.glodblock.github.inventory.gui; import javax.annotation.Nullable; +import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.world.World; @@ -60,6 +61,9 @@ public abstract class ItemGuiFactory implements IGuiFactory { return null; } T inv = getInventory(((IItemInventory) item.getItem()).getInventory(item, world, x, y, z, player)); + if (inv == null && Minecraft.getMinecraft().currentScreen != null) { + player.closeScreen(); + } return inv != null ? createClientGui(player, inv) : null; } diff --git a/src/main/java/com/glodblock/github/inventory/item/IWirelessPatternTerminal.java b/src/main/java/com/glodblock/github/inventory/item/IWirelessPatternTerminal.java new file mode 100644 index 00000000..cf845429 --- /dev/null +++ b/src/main/java/com/glodblock/github/inventory/item/IWirelessPatternTerminal.java @@ -0,0 +1,5 @@ +package com.glodblock.github.inventory.item; + +public interface IWirelessPatternTerminal extends IWirelessTerminal, PatternTerminal { + +} diff --git a/src/main/java/com/glodblock/github/inventory/item/PatternTerminal.java b/src/main/java/com/glodblock/github/inventory/item/PatternTerminal.java new file mode 100644 index 00000000..a2ea143b --- /dev/null +++ b/src/main/java/com/glodblock/github/inventory/item/PatternTerminal.java @@ -0,0 +1,44 @@ +package com.glodblock.github.inventory.item; + +import net.minecraft.inventory.IInventory; + +import appeng.api.storage.data.IAEItemStack; + +public interface PatternTerminal { + + boolean isInverted(); + + IInventory getInventoryByName(final String name); + + boolean canBeSubstitute(); + + boolean isPrioritize(); + + boolean isSubstitution(); + + boolean shouldCombine(); + + void onChangeCrafting(IAEItemStack[] newCrafting, IAEItemStack[] newOutput); + + void setCraftingRecipe(final boolean craftingMode); + + void setSubstitution(boolean canSubstitute); + + void setBeSubstitute(boolean canBeSubstitute); + + void setCombineMode(boolean shouldCombine); + + void setPrioritization(boolean canPrioritize); + + void setInverted(boolean inverted); + + int getActivePage(); + + void setActivePage(int activePage); + + boolean isCraftingRecipe(); + + void sortCraftingItems(); + + default void saveSettings() {} +} diff --git a/src/main/java/com/glodblock/github/inventory/item/WirelessTerminal.java b/src/main/java/com/glodblock/github/inventory/item/WirelessFluidTerminal.java similarity index 89% rename from src/main/java/com/glodblock/github/inventory/item/WirelessTerminal.java rename to src/main/java/com/glodblock/github/inventory/item/WirelessFluidTerminal.java index 268e9b16..4a1425fb 100644 --- a/src/main/java/com/glodblock/github/inventory/item/WirelessTerminal.java +++ b/src/main/java/com/glodblock/github/inventory/item/WirelessFluidTerminal.java @@ -26,29 +26,28 @@ import appeng.tile.inventory.InvOperation; import appeng.util.ConfigManager; import appeng.util.Platform; -import com.glodblock.github.util.BlockPos; import com.glodblock.github.util.Util; -public class WirelessTerminal extends MEMonitorHandler implements IWirelessTerminal { +public class WirelessFluidTerminal extends MEMonitorHandler implements IWirelessTerminal { private final ItemStack target; private final IAEItemPowerStorage ips; private final EntityPlayer p; private final int inventorySlot; private final AppEngInternalInventory viewCell; - private final BlockPos pos; private final StorageChannel channel; + private final IGridNode grid; @SuppressWarnings("unchecked") - public WirelessTerminal(final ItemStack is, BlockPos pos, EntityPlayer player) { + public WirelessFluidTerminal(final ItemStack is, final int slot, IGridNode gridNode, EntityPlayer player) { super( (IMEInventoryHandler) Objects - .requireNonNull(Util.getWirelessInv(is, pos, StorageChannel.FLUIDS))); + .requireNonNull(Util.getWirelessInv(is, player, StorageChannel.FLUIDS))); this.ips = (ToolWirelessTerminal) is.getItem(); + this.grid = gridNode; this.target = is; this.p = player; - this.pos = pos; - this.inventorySlot = p.inventory.currentItem; + this.inventorySlot = slot; this.viewCell = new WirelessTerminalViewCells(is); this.channel = StorageChannel.FLUIDS; } @@ -102,7 +101,7 @@ public class WirelessTerminal extends MEMonitorHandler implements @Override public IGridNode getGridNode(ForgeDirection dir) { - return Util.getWirelessGrid(this.target, this.pos, this.channel); + return this.grid; } @Override diff --git a/src/main/java/com/glodblock/github/inventory/item/WirelessPatternTerminal.java b/src/main/java/com/glodblock/github/inventory/item/WirelessPatternTerminal.java new file mode 100644 index 00000000..1c73e4c2 --- /dev/null +++ b/src/main/java/com/glodblock/github/inventory/item/WirelessPatternTerminal.java @@ -0,0 +1,309 @@ +package com.glodblock.github.inventory.item; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.util.ForgeDirection; + +import appeng.api.config.*; +import appeng.api.implementations.items.IAEItemPowerStorage; +import appeng.api.networking.IGridNode; +import appeng.api.storage.IMEInventoryHandler; +import appeng.api.storage.IMEMonitor; +import appeng.api.storage.MEMonitorHandler; +import appeng.api.storage.StorageChannel; +import appeng.api.storage.data.IAEFluidStack; +import appeng.api.storage.data.IAEItemStack; +import appeng.api.util.AECableType; +import appeng.api.util.IConfigManager; +import appeng.items.contents.WirelessTerminalViewCells; +import appeng.items.tools.powered.ToolWirelessTerminal; +import appeng.tile.inventory.AppEngInternalInventory; +import appeng.tile.inventory.InvOperation; +import appeng.util.ConfigManager; +import appeng.util.Platform; + +import com.glodblock.github.common.item.ItemFluidPacket; +import com.glodblock.github.inventory.ItemBiggerAppEngInventory; +import com.glodblock.github.inventory.WirelessFluidPatternTerminalPatterns; +import com.glodblock.github.util.Util; + +public class WirelessPatternTerminal extends MEMonitorHandler implements IWirelessPatternTerminal { + + private final ItemStack target; + private final IAEItemPowerStorage ips; + private final EntityPlayer p; + private final int inventorySlot; + private final AppEngInternalInventory viewCell; + private final StorageChannel channel; + private final IGridNode grid; + + protected AppEngInternalInventory crafting; + protected AppEngInternalInventory output; + protected final WirelessFluidPatternTerminalPatterns pattern; + + protected boolean craftingMode = true; + protected boolean substitute = false; + protected boolean combine = false; + protected boolean prioritize = false; + protected boolean inverted = false; + protected boolean beSubstitute = false; + protected int activePage = 0; + + @SuppressWarnings("unchecked") + public WirelessPatternTerminal(final ItemStack is, final int slot, IGridNode gridNode, EntityPlayer player) { + super( + (IMEInventoryHandler) Objects + .requireNonNull(Util.getWirelessInv(is, player, StorageChannel.ITEMS))); + this.ips = (ToolWirelessTerminal) is.getItem(); + this.grid = gridNode; + this.target = is; + this.p = player; + this.inventorySlot = slot; + this.viewCell = new WirelessTerminalViewCells(is); + this.channel = StorageChannel.ITEMS; + this.pattern = new WirelessFluidPatternTerminalPatterns(is); + this.crafting = new ItemBiggerAppEngInventory(is, "crafting", 9); + this.output = new ItemBiggerAppEngInventory(is, "output", 3); + } + + @Override + public ItemStack getItemStack() { + return this.target; + } + + @Override + public double extractAEPower(double amt, Actionable mode, PowerMultiplier usePowerMultiplier) { + amt = usePowerMultiplier.multiply(amt); + if (mode == Actionable.SIMULATE) { + return usePowerMultiplier.divide(Math.min(amt, this.ips.getAECurrentPower(this.target))); + } + return usePowerMultiplier.divide(this.ips.extractAEPower(this.target, amt)); + } + + @Override + public IMEMonitor getItemInventory() { + return this; + } + + @Override + public IMEMonitor getFluidInventory() { + return null; + } + + public void readFromNBT() { + NBTTagCompound data = Platform.openNbtData(this.target); + this.setCraftingRecipe(data.getBoolean("craftingMode")); + this.setSubstitution(data.getBoolean("substitute")); + this.setCombineMode(data.getBoolean("combine")); + this.setBeSubstitute(data.getBoolean("beSubstitute")); + this.setPrioritization(data.getBoolean("priorization")); + this.setInverted(data.getBoolean("inverted")); + this.setActivePage(data.getInteger("activePage")); + } + + public void writeToNBT() { + NBTTagCompound data = Platform.openNbtData(this.target); + data.setBoolean("craftingMode", this.craftingMode); + data.setBoolean("substitute", this.substitute); + data.setBoolean("combine", this.combine); + data.setBoolean("beSubstitute", this.beSubstitute); + data.setBoolean("priorization", this.prioritize); + data.setBoolean("inverted", this.inverted); + data.setInteger("activePage", this.activePage); + } + + @Override + public IConfigManager getConfigManager() { + final ConfigManager out = new ConfigManager((manager, settingName, newValue) -> { + final NBTTagCompound data = Platform.openNbtData(this.target); + manager.writeToNBT(data); + + }); + out.registerSetting(Settings.SORT_BY, SortOrder.NAME); + out.registerSetting(Settings.VIEW_MODE, ViewItems.ALL); + out.registerSetting(Settings.SORT_DIRECTION, SortDir.ASCENDING); + out.readFromNBT((NBTTagCompound) Platform.openNbtData(this.target).copy()); + this.readFromNBT(); + return out; + } + + @Override + public int getInventorySlot() { + return this.inventorySlot; + } + + @Override + public IInventory getViewCellStorage() { + return this.viewCell; + } + + @Override + public IGridNode getGridNode(ForgeDirection dir) { + return this.grid; + } + + @Override + public AECableType getCableConnectionType(ForgeDirection dir) { + return AECableType.NONE; + } + + @Override + public void securityBreak() { + this.getGridNode(ForgeDirection.UNKNOWN).getMachine().securityBreak(); + } + + @Override + public void saveChanges() { + + } + + @Override + public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removedStack, + ItemStack newStack) {} + + @Override + public boolean isInverted() { + return this.inverted; + } + + @Override + public IInventory getInventoryByName(String name) { + if (name.equals("crafting")) { + return this.crafting; + } + + if (name.equals("output")) { + return this.output; + } + + if (name.equals("pattern")) { + return this.pattern; + } + + return null; + } + + @Override + public boolean canBeSubstitute() { + return this.beSubstitute; + } + + @Override + public boolean isPrioritize() { + return this.prioritize; + } + + @Override + public boolean isSubstitution() { + return this.substitute; + } + + @Override + public boolean shouldCombine() { + return this.combine; + } + + @Override + public void onChangeCrafting(IAEItemStack[] newCrafting, IAEItemStack[] newOutput) { + IInventory crafting = this.getInventoryByName("crafting"); + IInventory output = this.getInventoryByName("output"); + if (crafting instanceof AppEngInternalInventory && output instanceof AppEngInternalInventory) { + for (int x = 0; x < crafting.getSizeInventory() && x < newCrafting.length; x++) { + final IAEItemStack item = newCrafting[x]; + crafting.setInventorySlotContents(x, item == null ? null : item.getItemStack()); + } + for (int x = 0; x < output.getSizeInventory() && x < newOutput.length; x++) { + final IAEItemStack item = newOutput[x]; + output.setInventorySlotContents(x, item == null ? null : item.getItemStack()); + } + } + } + + @Override + public void setCraftingRecipe(boolean craftingMode) { + this.craftingMode = craftingMode; + } + + @Override + public void setSubstitution(boolean canSubstitute) { + this.substitute = canSubstitute; + } + + @Override + public void setBeSubstitute(boolean canBeSubstitute) { + this.beSubstitute = canBeSubstitute; + } + + @Override + public void setCombineMode(boolean shouldCombine) { + this.combine = shouldCombine; + } + + @Override + public void setPrioritization(boolean canPrioritize) { + this.prioritize = canPrioritize; + } + + @Override + public void setInverted(boolean inverted) { + this.inverted = inverted; + } + + @Override + public int getActivePage() { + return this.activePage; + } + + @Override + public void setActivePage(int activePage) { + this.activePage = activePage; + } + + @Override + public boolean isCraftingRecipe() { + return this.craftingMode; + } + + @Override + public void sortCraftingItems() { + List items = new ArrayList(); + List fluids = new ArrayList(); + for (ItemStack is : this.crafting) { + if (is == null) continue; + if (is.getItem() instanceof ItemFluidPacket) { + fluids.add(is); + } else { + items.add(is); + } + } + if (this.prioritize) { + fluids.addAll(items); + items.clear(); + } else { + items.addAll(fluids); + fluids.clear(); + } + + for (int i = 0; i < this.crafting.getSizeInventory(); i++) { + if (this.crafting.getStackInSlot(i) == null) break; + if (items.isEmpty()) { + this.crafting.setInventorySlotContents(i, fluids.get(i)); + } else { + this.crafting.setInventorySlotContents(i, items.get(i)); + } + } + saveChanges(); + } + + @Override + public void saveSettings() { + this.writeToNBT(); + } + +} diff --git a/src/main/java/com/glodblock/github/loader/ItemAndBlockHolder.java b/src/main/java/com/glodblock/github/loader/ItemAndBlockHolder.java index cff959ab..114487c2 100644 --- a/src/main/java/com/glodblock/github/loader/ItemAndBlockHolder.java +++ b/src/main/java/com/glodblock/github/loader/ItemAndBlockHolder.java @@ -33,6 +33,7 @@ public class ItemAndBlockHolder { public static ItemFluidConversionMonitor FLUID_CONVERSION_MONITOR = new ItemFluidConversionMonitor().register(); public static ItemPortableFluidCell PORTABLE_FLUID_CELL = new ItemPortableFluidCell().register(); public static ItemWirelessFluidTerminal WIRELESS_FLUID_TERM = new ItemWirelessFluidTerminal().register(); + public static ItemWirelessPatternTerminal WIRELESS_PATTERN_TERM = new ItemWirelessPatternTerminal().register(); public static ItemFluidPacket PACKET = new ItemFluidPacket().register(); public static ItemBasicFluidStorageCell CELL1K = new ItemBasicFluidStorageCell(CellType.Cell1kPart, 1).register(); public static ItemBasicFluidStorageCell CELL4K = new ItemBasicFluidStorageCell(CellType.Cell4kPart, 4).register(); diff --git a/src/main/java/com/glodblock/github/nei/NEI_FC_Config.java b/src/main/java/com/glodblock/github/nei/NEI_FC_Config.java index 0f9c0358..d4e42279 100644 --- a/src/main/java/com/glodblock/github/nei/NEI_FC_Config.java +++ b/src/main/java/com/glodblock/github/nei/NEI_FC_Config.java @@ -6,6 +6,7 @@ import codechicken.nei.api.IConfigureNEI; import com.glodblock.github.FluidCraft; import com.glodblock.github.client.gui.GuiFluidPatternTerminal; import com.glodblock.github.client.gui.GuiFluidPatternTerminalEx; +import com.glodblock.github.client.gui.GuiPatternPortableCell; import com.glodblock.github.nei.recipes.FluidRecipe; public class NEI_FC_Config implements IConfigureNEI { @@ -15,6 +16,10 @@ public class NEI_FC_Config implements IConfigureNEI { API.registerNEIGuiHandler(new NEIGuiHandler()); for (String identifier : FluidRecipe.getSupportRecipes()) { + API.registerGuiOverlayHandler( + GuiPatternPortableCell.class, + FluidPatternTerminalRecipeTransferHandler.INSTANCE, + identifier); API.registerGuiOverlayHandler( GuiFluidPatternTerminal.class, FluidPatternTerminalRecipeTransferHandler.INSTANCE, diff --git a/src/main/java/com/glodblock/github/network/CPacketFluidPatternTermBtns.java b/src/main/java/com/glodblock/github/network/CPacketFluidPatternTermBtns.java index cb963008..1e20c96f 100644 --- a/src/main/java/com/glodblock/github/network/CPacketFluidPatternTermBtns.java +++ b/src/main/java/com/glodblock/github/network/CPacketFluidPatternTermBtns.java @@ -117,6 +117,7 @@ public class CPacketFluidPatternTermBtns implements IMessage { } break; } + cpt.getPatternTerminal().saveSettings(); } else if (Name.equals("Terminal.Cpu") && c instanceof ContainerFluidCraftConfirm) { final ContainerFluidCraftConfirm qk = (ContainerFluidCraftConfirm) c; qk.cycleCpu(Value.equals("Next")); diff --git a/src/main/java/com/glodblock/github/network/CPacketSwitchGuis.java b/src/main/java/com/glodblock/github/network/CPacketSwitchGuis.java index d4fc285e..94dc7004 100644 --- a/src/main/java/com/glodblock/github/network/CPacketSwitchGuis.java +++ b/src/main/java/com/glodblock/github/network/CPacketSwitchGuis.java @@ -73,9 +73,9 @@ public class CPacketSwitchGuis implements IMessage { player, player.worldObj, new BlockPos( - (int) player.posX, - Util.GuiHelper.encodeType((int) player.posY, Util.GuiHelper.GuiType.ITEM), - (int) player.posZ), + player.inventory.currentItem, + Util.GuiHelper.encodeType(0, Util.GuiHelper.GuiType.ITEM), + 0), Objects.requireNonNull(context.getSide()), message.guiType); } diff --git a/src/main/java/com/glodblock/github/util/NameConst.java b/src/main/java/com/glodblock/github/util/NameConst.java index 9b9c7d2a..a164ab25 100644 --- a/src/main/java/com/glodblock/github/util/NameConst.java +++ b/src/main/java/com/glodblock/github/util/NameConst.java @@ -37,6 +37,7 @@ public class NameConst { public static final String ITEM_FLUID_STORAGE = "fluid_storage"; public static final String ITEM_FLUID_PORTABLE_CELL = "portable_fluid_cell"; public static final String ITEM_WIRELESS_FLUID_TERMINAL = "wireless_fluid_terminal"; + public static final String ITEM_WIRELESS_FLUID_PATTERN_TERMINAL = "wireless_fluid_pattern_terminal"; public static final String ITEM_FLUID_PART = "fluid_part"; public static final String TT_KEY = FluidCraft.MODID + ".tooltip."; diff --git a/src/main/java/com/glodblock/github/util/Util.java b/src/main/java/com/glodblock/github/util/Util.java index ed4bb923..2cc4039e 100644 --- a/src/main/java/com/glodblock/github/util/Util.java +++ b/src/main/java/com/glodblock/github/util/Util.java @@ -27,13 +27,13 @@ import appeng.api.storage.StorageChannel; import appeng.api.storage.data.IAEFluidStack; import appeng.api.storage.data.IAEStack; import appeng.api.util.WorldCoord; +import appeng.items.tools.powered.ToolWirelessTerminal; import appeng.tile.networking.TileCableBus; import appeng.tile.networking.TileWireless; import appeng.util.item.AEFluidStack; import com.glodblock.github.common.item.ItemFluidDrop; import com.glodblock.github.common.item.ItemFluidPacket; -import com.glodblock.github.common.item.ItemWirelessFluidTerminal; import com.glodblock.github.inventory.IAEFluidTank; import cpw.mods.fml.common.ModContainer; @@ -42,24 +42,28 @@ import io.netty.buffer.ByteBuf; public final class Util { - public static IGridNode getWirelessGrid(ItemStack is, BlockPos pos, StorageChannel channel) { - String key = ((ItemWirelessFluidTerminal) is.getItem()).getEncryptionKey(is); - IGridHost securityTerminal = (IGridHost) AEApi.instance().registries().locatable() - .getLocatableBy(Long.parseLong(key)); - if (securityTerminal == null) return null; - return securityTerminal.getGridNode(ForgeDirection.UNKNOWN); + public static IGridNode getWirelessGrid(ItemStack is) { + if (is.getItem() instanceof ToolWirelessTerminal) { + String key = ((ToolWirelessTerminal) is.getItem()).getEncryptionKey(is); + IGridHost securityTerminal = (IGridHost) AEApi.instance().registries().locatable() + .getLocatableBy(Long.parseLong(key)); + if (securityTerminal == null) return null; + return securityTerminal.getGridNode(ForgeDirection.UNKNOWN); + } + return null; } @SuppressWarnings("unchecked") - public static IBaseMonitor>> getWirelessInv(ItemStack is, BlockPos pos, - StorageChannel channel) { - IGridNode gridNode = getWirelessGrid(is, pos, channel); + public static IBaseMonitor>> getWirelessInv(ItemStack is, + EntityPlayer player, StorageChannel channel) { + IGridNode gridNode = getWirelessGrid(is); if (gridNode == null) return null; IGrid grid = gridNode.getGrid(); if (grid == null) return null; for (IGridNode node : grid.getMachines(TileWireless.class)) { IWirelessAccessPoint accessPoint = (IWirelessAccessPoint) node.getMachine(); - WorldCoord distance = accessPoint.getLocation().subtract(pos.getX(), pos.getY(), pos.getZ()); + WorldCoord distance = accessPoint.getLocation() + .subtract((int) player.posX, (int) player.posY, (int) player.posZ); int squaredDistance = distance.x * distance.x + distance.y * distance.y + distance.z * distance.z; if (squaredDistance <= accessPoint.getRange() * accessPoint.getRange()) { IStorageGrid gridCache = grid.getCache(IStorageGrid.class); @@ -269,14 +273,14 @@ public final class Util { private static final int value = 1 << 30; public static int encodeType(int y, GuiType type) { - if (y > (1 << 28)) { + if (Math.abs(y) > (1 << 28)) { throw new IllegalArgumentException("out of range"); } return value | (type.ordinal() << 29) | y; } public static MutablePair decodeType(int y) { - if (y > (1 << 28)) { + if (Math.abs(y) > (1 << 28)) { return new MutablePair<>(GuiType.values()[y >> 29 & 1], y - (3 << 29 & y)); } else { return new MutablePair<>(GuiType.TILE, y); diff --git a/src/main/resources/assets/ae2fc/lang/en_US.lang b/src/main/resources/assets/ae2fc/lang/en_US.lang index 656ed926..ee866791 100644 --- a/src/main/resources/assets/ae2fc/lang/en_US.lang +++ b/src/main/resources/assets/ae2fc/lang/en_US.lang @@ -12,6 +12,7 @@ item.part_fluid_storage_monitor.name=ME Fluid Storage Monitor item.part_fluid_conversion_monitor.name=ME Fluid Conversion Monitor item.portable_fluid_cell.name=Portable Fluid Cell item.wireless_fluid_terminal.name=Wireless Fluid Terminal +item.wireless_fluid_pattern_terminal.name=Wireless Fluid Pattern Terminal item.fluid_packet.name=Fluid Packet item.fluid_storage.1.name=%s1k%s ME Fluid Storage Cell item.fluid_storage.4.name=%s4k%s ME Fluid Storage Cell diff --git a/src/main/resources/assets/ae2fc/lang/zh_CN.lang b/src/main/resources/assets/ae2fc/lang/zh_CN.lang index 1e1f56f8..8351d7aa 100644 --- a/src/main/resources/assets/ae2fc/lang/zh_CN.lang +++ b/src/main/resources/assets/ae2fc/lang/zh_CN.lang @@ -10,6 +10,9 @@ item.part_fluid_storage_bus.name=ME流体存储总线 item.part_fluid_level_emitter.name=ME流体发信器 item.part_fluid_storage_monitor.name=ME流体存储监控器 item.part_fluid_conversion_monitor.name=ME流体交换监控器 +item.portable_fluid_cell.name=便携流体单元 +item.wireless_fluid_terminal.name=无线流体终端 +item.wireless_fluid_pattern_terminal.name=无线样板终端 item.fluid_packet.name=流体封包 item.fluid_storage.1.name=%s1k%s-ME流体存储元件 item.fluid_storage.4.name=%s4k%s-ME流体存储元件 @@ -18,6 +21,7 @@ item.fluid_storage.64.name=%s64k%s-ME流体存储元件 item.fluid_storage.256.name=%s256k%s-ME流体存储元件 item.fluid_storage.1024.name=%s1024k%s-ME流体存储元件 item.fluid_storage.4096.name=%s4096k%s-ME流体存储元件 +item.fluid_storage.16384.name=%s16384k%s-ME流体存储元件 item.fluid_part.0.name=%s1k%s-ME流体存储组件 item.fluid_part.1.name=%s4k%s-ME流体存储组件 item.fluid_part.2.name=%s16k%s-ME流体存储组件 @@ -25,6 +29,7 @@ item.fluid_part.3.name=%s64k%s-ME流体存储组件 item.fluid_part.4.name=%s256k%s-ME流体存储组件 item.fluid_part.5.name=%s1024k%s-ME流体存储组件 item.fluid_part.6.name=%s4096k%s-ME流体存储组件 +item.fluid_part.7.name=%s16384k%s-ME流体存储组件 tile.fluid_discretizer.name=ME流体离散器 tile.fluid_pattern_encoder.name=流体适配型样板编码台 @@ -66,7 +71,8 @@ ae2fc.tooltip.level_maintainer.request_size=§6缓存量§r ae2fc.tooltip.level_maintainer.request_size.hint=数量定义了在请求器开始请求新合成之前应该保留多少物品。 ae2fc.tooltip.cell_contents=内含流体: -ae2fc.tooltip.cell_empty=Cell is empty +ae2fc.tooltip.cell_empty=空存储 +ae2fc.tooltip.cell_portable=右键打开GUI,它就像一个背包,但你需要在使用前给它充能。 ae2fc.tooltip.fluid_terminal=我们不再需要EC2了吗? ae2fc.tooltip.invalid_fluid=流体无效! ae2fc.tooltip.encode_pattern=编写样板 diff --git a/src/main/resources/assets/ae2fc/textures/items/wireless_fluid_pattern_terminal.png b/src/main/resources/assets/ae2fc/textures/items/wireless_fluid_pattern_terminal.png new file mode 100644 index 00000000..8b47dcbd Binary files /dev/null and b/src/main/resources/assets/ae2fc/textures/items/wireless_fluid_pattern_terminal.png differ