From de63822afb855e12c05746a5267725167868a707 Mon Sep 17 00:00:00 2001 From: asdflj <854865755@qq.com> Date: Wed, 11 Jan 2023 17:56:04 +0800 Subject: [PATCH] update level_maintainer --- .../github/client/gui/FCGuiLineField.java | 29 +++ .../github/client/gui/FCGuiTextField.java | 14 +- .../github/client/gui/GuiFCImgButton.java | 41 ++-- .../github/client/gui/GuiLevelMaintainer.java | 175 +++++++++++++----- .../container/ContainerLevelMaintainer.java | 4 +- .../github/common/block/BlockFluidBuffer.java | 22 ++- .../common/block/BlockFluidDiscretizer.java | 26 ++- .../common/block/BlockFluidPacketDecoder.java | 24 ++- .../common/block/BlockLevelMaintainer.java | 25 ++- .../github/common/block/FCBaseBlock.java | 23 +++ .../github/common/item/FCBaseItemBlock.java | 30 +++ .../common/tile/TileLevelMaintainer.java | 56 +++++- .../network/CPacketLevelMaintainer.java | 12 +- .../com/glodblock/github/util/NameConst.java | 50 ++++- .../resources/assets/ae2fc/lang/en_US.lang | 22 ++- .../resources/assets/ae2fc/lang/zh_CN.lang | 24 ++- .../ae2fc/textures/gui/level_maintainer.png | Bin 9349 -> 1368 bytes .../assets/ae2fc/textures/gui/states.png | Bin 1695 -> 1688 bytes 18 files changed, 480 insertions(+), 97 deletions(-) create mode 100644 src/main/java/com/glodblock/github/client/gui/FCGuiLineField.java create mode 100644 src/main/java/com/glodblock/github/common/item/FCBaseItemBlock.java diff --git a/src/main/java/com/glodblock/github/client/gui/FCGuiLineField.java b/src/main/java/com/glodblock/github/client/gui/FCGuiLineField.java new file mode 100644 index 00000000..c3cd7bd2 --- /dev/null +++ b/src/main/java/com/glodblock/github/client/gui/FCGuiLineField.java @@ -0,0 +1,29 @@ +package com.glodblock.github.client.gui; + +import net.minecraft.client.gui.FontRenderer; + +public class FCGuiLineField extends FCGuiTextField { + private final int _xPos; + private final int _yPos; + private final int _width; + private final FontRenderer _fontRender; + + public FCGuiLineField(FontRenderer fontRenderer, int xPos, int yPos, int width) { + this(fontRenderer, xPos, yPos, width, 5); + } + + public FCGuiLineField(FontRenderer fontRenderer, int xPos, int yPos, int width, int height) { + super(fontRenderer, xPos, yPos, width, height); + this._xPos = xPos; + this._yPos = yPos; + this._width = width; + this._fontRender = fontRenderer; + } + + @Override + public void drawTextBox() { + if (this.getVisible()) { + drawRect(this._xPos, this._yPos, this.xPosition + this.width, this.yPosition + this.height, getColor()); + } + } +} diff --git a/src/main/java/com/glodblock/github/client/gui/FCGuiTextField.java b/src/main/java/com/glodblock/github/client/gui/FCGuiTextField.java index bf4bc141..3b5e3598 100644 --- a/src/main/java/com/glodblock/github/client/gui/FCGuiTextField.java +++ b/src/main/java/com/glodblock/github/client/gui/FCGuiTextField.java @@ -46,11 +46,11 @@ public class FCGuiTextField extends GuiTextField { public void drawTextBox() { super.drawTextBox(); if (this.getBorder() > 0 && this.getVisible()) { - GuiTextField.drawRect( - this._xPos - this.getBorder(), - this._yPos - this.getBorder(), - this._width - 2 * PADDING - this._fontRender.getCharWidth('_') + this.getBorder(), - this._height - 2 * PADDING + this.getBorder(), + drawRect( + this._xPos - getBorder(), + this._yPos - getBorder(), + this.xPosition + this.width + getBorder(), + this.yPosition + this.height + getBorder(), this.getColor()); } } @@ -109,6 +109,10 @@ public class FCGuiTextField extends GuiTextField { tooltip = t; } + public String getMessage() { + return tooltip; + } + public class TooltipProvider implements ITooltip { @Override public String getMessage() { diff --git a/src/main/java/com/glodblock/github/client/gui/GuiFCImgButton.java b/src/main/java/com/glodblock/github/client/gui/GuiFCImgButton.java index e109a087..eaae370d 100644 --- a/src/main/java/com/glodblock/github/client/gui/GuiFCImgButton.java +++ b/src/main/java/com/glodblock/github/client/gui/GuiFCImgButton.java @@ -20,11 +20,16 @@ public class GuiFCImgButton extends GuiButton implements ITooltip { private boolean halfSize = false; private String fillVar; private String currentValue; + private final boolean background; private static final String prefix = NameConst.TT_KEY; public GuiFCImgButton(final int x, final int y, final String idx, final String val) { - super(0, 0, 16, ""); + this(x, y, idx, val, true); + } + public GuiFCImgButton(final int x, final int y, final String idx, final String val, boolean background) { + super(0, 0, 16, ""); + this.background = background; this.buttonSetting = idx; this.currentValue = val; this.xPosition = x; @@ -198,14 +203,15 @@ public class GuiFCImgButton extends GuiButton implements ITooltip { final int uv_y = (int) Math.floor(iconIndex / 3.0); final int uv_x = iconIndex - uv_y * 3; - - this.drawTexturedModalRect( - 0, - 0, - Math.round(32F * 16F / 3F), - Math.round(32F * 16F / 3F), - Math.round(16F * 16F / 3F), - Math.round(16F * 16F / 3F)); + if (this.background) { + this.drawTexturedModalRect( + 0, + 0, + Math.round(32F * 16F / 3F), + Math.round(32F * 16F / 3F), + Math.round(16F * 16F / 3F), + Math.round(16F * 16F / 3F)); + } this.drawTexturedModalRect( 0, 0, @@ -234,14 +240,15 @@ public class GuiFCImgButton extends GuiButton implements ITooltip { final int uv_y = (int) Math.floor(iconIndex / 3.0); final int uv_x = iconIndex - uv_y * 3; - - this.drawTexturedModalRect( - 0, - 0, - Math.round(32F * 16F / 3F), - Math.round(32F * 16F / 3F), - Math.round(16F * 16F / 3F), - Math.round(16F * 16F / 3F)); + if (this.background) { + this.drawTexturedModalRect( + 0, + 0, + Math.round(32F * 16F / 3F), + Math.round(32F * 16F / 3F), + Math.round(16F * 16F / 3F), + Math.round(16F * 16F / 3F)); + } this.drawTexturedModalRect( 0, 0, diff --git a/src/main/java/com/glodblock/github/client/gui/GuiLevelMaintainer.java b/src/main/java/com/glodblock/github/client/gui/GuiLevelMaintainer.java index c2324ad8..68f576cf 100644 --- a/src/main/java/com/glodblock/github/client/gui/GuiLevelMaintainer.java +++ b/src/main/java/com/glodblock/github/client/gui/GuiLevelMaintainer.java @@ -9,6 +9,7 @@ import appeng.core.sync.packets.PacketNEIDragClick; import codechicken.nei.VisiblityData; import codechicken.nei.api.INEIGuiHandler; import codechicken.nei.api.TaggedInventoryArea; +import cofh.core.render.CoFHFontRenderer; import com.glodblock.github.FluidCraft; import com.glodblock.github.client.gui.container.ContainerLevelMaintainer; import com.glodblock.github.common.tile.TileLevelMaintainer; @@ -16,18 +17,19 @@ import com.glodblock.github.inventory.gui.MouseRegionManager; import com.glodblock.github.inventory.slot.SlotSingleItem; import com.glodblock.github.network.CPacketLevelMaintainer; import com.glodblock.github.util.Ae2ReflectClient; -import com.glodblock.github.util.ModAndClassUtil; import com.glodblock.github.util.NameConst; import cpw.mods.fml.common.Optional; import java.awt.*; -import java.util.Collections; +import java.util.*; import java.util.List; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.inventory.GuiContainer; -import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.MinecraftServer; import net.minecraft.util.ResourceLocation; import org.lwjgl.input.Keyboard; @@ -41,6 +43,9 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler { private final AppEngRenderItem stackSizeRenderer = Ae2ReflectClient.getStackSizeRenderer(this); private TileLevelMaintainer tile; private FCGuiTextField input; + private int lastWorkingTick; + private final int interval = 20; + private final CoFHFontRenderer render; public GuiLevelMaintainer(InventoryPlayer ipl, TileLevelMaintainer tile) { super(new ContainerLevelMaintainer(ipl, tile)); @@ -48,56 +53,74 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler { this.xSize = 195; this.ySize = 214; this.tile = tile; + this.render = new CoFHFontRenderer( + Minecraft.getMinecraft().gameSettings, + TEX_BG, + Minecraft.getMinecraft().getTextureManager(), + true); } public void postUpdate(List list) { + for (Slot slot : this.cont.getRequestSlots()) { + if (!slot.getHasStack()) { + component[slot.getSlotIndex()].setState(TileLevelMaintainer.State.Nothing); + } + } for (IAEItemStack is : list) { - long size = is.getItemStack().getTagCompound().getLong("Batch"); - int i = is.getItemStack().getTagCompound().getInteger("Index"); - boolean isEnable = is.getItemStack().getTagCompound().getBoolean("Enable"); + NBTTagCompound data = is.getItemStack().getTagCompound(); + long size = data.getLong("Batch"); + int i = data.getInteger("Index"); + boolean isEnable = data.getBoolean("Enable"); + TileLevelMaintainer.State state = TileLevelMaintainer.State.values()[data.getInteger("State")]; component[i].getQty().textField.setText(String.valueOf(is.getStackSize())); component[i].getBatch().textField.setText(String.valueOf(size)); component[i].setEnable(isEnable); - } - } - - public void drawScreen(final int mouseX, final int mouseY, final float btn) { - super.drawScreen(mouseX, mouseY, btn); - if (ModAndClassUtil.isSearchBar) { - for (Component com : this.component) { - handleTooltip(mouseX, mouseY, com.getQty().textField.new TooltipProvider()); - handleTooltip(mouseX, mouseY, com.getBatch().textField.new TooltipProvider()); - } + component[i].setState(state); } } public void initGui() { super.initGui(); + lastWorkingTick = MinecraftServer.getServer().getTickCounter(); for (int i = 0; i < TileLevelMaintainer.REQ_COUNT; i++) { component[i] = new Component( new Widget( - new FCGuiTextField(this.fontRendererObj, guiLeft + 37, guiTop + 21 + 20 * i, 52, 16), - new GuiFCImgButton(guiLeft + 37 + 47, guiTop + 20 + 20 * i, "SUBMIT", "SUBMIT"), - I18n.format(NameConst.TT_REQUEST_SIZE), + new FCGuiTextField(this.fontRendererObj, guiLeft + 46, guiTop + 19 + 19 * i, 52, 14), + NameConst.TT_LEVEL_MAINTAINER_REQUEST_SIZE, i, "TileLevelMaintainer.Quantity"), new Widget( - new FCGuiTextField(this.fontRendererObj, guiLeft + 100, guiTop + 21 + 20 * i, 52, 16), - new GuiFCImgButton(guiLeft + 100 + 47, guiTop + 20 + 20 * i, "SUBMIT", "SUBMIT"), - I18n.format(NameConst.TT_BATCH_SIZE), + new FCGuiTextField(this.fontRendererObj, guiLeft + 100, guiTop + 19 + 19 * i, 52, 14), + NameConst.TT_LEVEL_MAINTAINER_BATCH_SIZE, i, "TileLevelMaintainer.Batch"), - new GuiFCImgButton(guiLeft + 4, guiTop + 23 + 20 * i, "ENABLE", "ENABLE"), - new GuiFCImgButton(guiLeft + 4, guiTop + 23 + 20 * i, "DISABLE", "DISABLE"), + new GuiFCImgButton(guiLeft + 105 + 47, guiTop + 17 + 19 * i, "SUBMIT", "SUBMIT", false), + new GuiFCImgButton(guiLeft + 9, guiTop + 20 + 19 * i, "ENABLE", "ENABLE", false), + new GuiFCImgButton(guiLeft + 9, guiTop + 20 + 19 * i, "DISABLE", "DISABLE", false), + new FCGuiLineField(fontRendererObj, guiLeft + 47, guiTop + 33 + 19 * i, 125), this.buttonList); } FluidCraft.proxy.netHandler.sendToServer(new CPacketLevelMaintainer("TileLevelMaintainer.refresh")); } + public void drawScreen(final int mouseX, final int mouseY, final float btn) { + super.drawScreen(mouseX, mouseY, btn); + for (Component com : this.component) { + handleTooltip(mouseX, mouseY, com.getQty().textField.new TooltipProvider()); + handleTooltip(mouseX, mouseY, com.getBatch().textField.new TooltipProvider()); + handleTooltip(mouseX, mouseY, com.getLine().new TooltipProvider()); + } + } + @Override public void drawBG(int offsetX, int offsetY, int mouseX, int mouseY) { mc.getTextureManager().bindTexture(TEX_BG); drawTexturedModalRect(offsetX, offsetY, 0, 0, 176, ySize); + int tick = MinecraftServer.getServer().getTickCounter(); + if (tick > lastWorkingTick + interval && this.input == null) { + FluidCraft.proxy.netHandler.sendToServer(new CPacketLevelMaintainer("TileLevelMaintainer.refresh")); + lastWorkingTick = MinecraftServer.getServer().getTickCounter(); + } for (int i = 0; i < TileLevelMaintainer.REQ_COUNT; i++) { this.component[i].draw(); } @@ -105,7 +128,7 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler { @Override public void drawFG(int offsetX, int offsetY, int mouseX, int mouseY) { - fontRendererObj.drawString(getGuiDisplayName(I18n.format(NameConst.GUI_LEVEL_MAINTAINER)), 8, 6, 0x404040); + fontRendererObj.drawString(getGuiDisplayName(NameConst.i18n(NameConst.GUI_LEVEL_MAINTAINER)), 8, 6, 0x404040); mouseRegions.render(mouseX, mouseY); } @@ -253,25 +276,30 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler { private class Component { public boolean isEnable = true; - private Widget qty; - private Widget batch; - private GuiFCImgButton disable; - private GuiFCImgButton enable; + private final Widget qty; + private final Widget batch; + private final GuiFCImgButton disable; + private final GuiFCImgButton enable; + private final GuiFCImgButton submit; + private final FCGuiLineField line; + private TileLevelMaintainer.State state; public Component( Widget qtyInput, Widget batchInput, + GuiFCImgButton submitBtn, GuiFCImgButton enableBtn, GuiFCImgButton disableBtn, + FCGuiLineField line, List buttonList) { this.qty = qtyInput; this.batch = batchInput; this.enable = enableBtn; this.disable = disableBtn; - this.enable.setHalfSize(true); - this.disable.setHalfSize(true); - buttonList.add(this.qty.button); - buttonList.add(this.batch.button); + this.submit = submitBtn; + this.line = line; + this.state = TileLevelMaintainer.State.Nothing; + buttonList.add(this.submit); buttonList.add(this.enable); buttonList.add(this.disable); } @@ -303,20 +331,20 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler { } protected boolean sendToServer(GuiButton btn) { - if (this.getQty().button == btn) { - return this.send(this.getQty()); - } - if (this.getBatch().button == btn) { - return this.send(this.getBatch()); - } - if (this.enable == btn) { + boolean didSomething = false; + if (this.submit == btn) { + if (this.send(this.getQty())) this.send(this.getBatch()); + didSomething = true; + } else if (this.enable == btn) { FluidCraft.proxy.netHandler.sendToServer( new CPacketLevelMaintainer("TileLevelMaintainer.Enable", this.getIndex())); + didSomething = true; } else if (this.disable == btn) { FluidCraft.proxy.netHandler.sendToServer( new CPacketLevelMaintainer("TileLevelMaintainer.Disable", this.getIndex())); + didSomething = true; } - return false; + return didSomething; } public FCGuiTextField isMouseIn(final int xCoord, final int yCoord) { @@ -333,9 +361,50 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler { return this.batch; } + public FCGuiLineField getLine() { + return this.line; + } + public void draw() { this.getQty().draw(); this.getBatch().draw(); + ArrayList message = new ArrayList(); + message.add(NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_TITLE) + "\n"); + switch (this.state) { + case Idling: + this.line.setColor(0xFF55FF55); + message.add(NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_CURRENT) + + NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_IDLE)); + break; + case Crafting: + this.line.setColor(0xFFFFFF55); + message.add(NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_CURRENT) + + NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_LINK)); + break; + case Exporting: + this.line.setColor(0xFFAA00AA); + message.add(NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_CURRENT) + + NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_EXPORT)); + break; + default: + this.line.setColor(0); + message.add(NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_CURRENT) + + NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_NONE)); + } + message.add(""); + if (isShiftKeyDown()) { + message.add(NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_IDLE)); + message.add(NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_IDLE_DESC) + "\n"); + message.add(NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_LINK)); + message.add(NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_LINK_DESC) + "\n"); + message.add(NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_EXPORT)); + message.add(NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_EXPORT_DESC) + "\n"); + } else { + message.add(NameConst.i18n(NameConst.TT_SHIFT_FOR_MORE)); + } + this.line.setMessage( + render.wrapFormattedStringToWidth(String.join("\n", message), (int) Math.floor(xSize * 0.8))); + this.line.drawTextBox(); if (this.isEnable) { this.enable.visible = true; this.disable.visible = false; @@ -344,33 +413,39 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler { this.disable.visible = true; } } + + public void setState(TileLevelMaintainer.State state) { + this.state = state; + } } private class Widget { public final int idx; public final String action; - private FCGuiTextField textField; - private GuiFCImgButton button; + private final FCGuiTextField textField; + private final String tooltip; - public Widget(FCGuiTextField textField, GuiFCImgButton button, String tooltip, int idx, String action) { + public Widget(FCGuiTextField textField, String tooltip, int idx, String action) { this.textField = textField; - this.textField.setMessage(tooltip); this.textField.setEnableBackgroundDrawing(false); this.textField.setText("0"); this.textField.setMaxStringLength(10); // it's enough to useful - this.button = button; this.idx = idx; this.action = action; + this.tooltip = tooltip; } public void draw() { + if (isShiftKeyDown()) { + this.setTooltip(render.wrapFormattedStringToWidth(NameConst.i18n(this.tooltip), xSize / 2)); + } else { + this.setTooltip(render.wrapFormattedStringToWidth( + NameConst.i18n(this.tooltip, "\n", false) + "\n" + NameConst.i18n(NameConst.TT_SHIFT_FOR_MORE), + (int) Math.floor(xSize * 0.8))); + } this.textField.drawTextBox(); } - public GuiFCImgButton btn() { - return this.button; - } - public void setTooltip(String message) { this.textField.setMessage(message); } diff --git a/src/main/java/com/glodblock/github/client/gui/container/ContainerLevelMaintainer.java b/src/main/java/com/glodblock/github/client/gui/container/ContainerLevelMaintainer.java index 8f86c3a4..a867c32c 100644 --- a/src/main/java/com/glodblock/github/client/gui/container/ContainerLevelMaintainer.java +++ b/src/main/java/com/glodblock/github/client/gui/container/ContainerLevelMaintainer.java @@ -18,11 +18,11 @@ public class ContainerLevelMaintainer extends AEBaseContainer { this.tile = tile; AeItemStackHandler request = new AeItemStackHandler(tile.getRequestSlots()); for (int y = 0; y < TileLevelMaintainer.REQ_COUNT; y++) { - FakeSlot slot = new FakeSlot(request, y, 17, 19 + y * 20); + FakeSlot slot = new FakeSlot(request, y, 27, 20 + y * 19); addSlotToContainer(slot); requestSlots[y] = slot; } - bindPlayerInventory(ipl, 0, 132); + bindPlayerInventory(ipl, 0, 130); } public TileLevelMaintainer getTile() { diff --git a/src/main/java/com/glodblock/github/common/block/BlockFluidBuffer.java b/src/main/java/com/glodblock/github/common/block/BlockFluidBuffer.java index e3f60cdd..edc32888 100644 --- a/src/main/java/com/glodblock/github/common/block/BlockFluidBuffer.java +++ b/src/main/java/com/glodblock/github/common/block/BlockFluidBuffer.java @@ -1,9 +1,11 @@ package com.glodblock.github.common.block; +import static net.minecraft.client.gui.GuiScreen.isShiftKeyDown; + import appeng.api.storage.data.IAEFluidStack; -import appeng.block.AEBaseItemBlock; import appeng.util.Platform; import com.glodblock.github.client.render.RenderBlockFluidBuffer; +import com.glodblock.github.common.item.FCBaseItemBlock; import com.glodblock.github.common.tabs.FluidCraftingTabs; import com.glodblock.github.common.tile.TileFluidBuffer; import com.glodblock.github.crossmod.waila.Tooltip; @@ -12,6 +14,7 @@ import com.glodblock.github.util.Util; import cpw.mods.fml.common.registry.GameRegistry; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import java.util.List; import net.minecraft.block.material.Material; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; @@ -52,7 +55,7 @@ public class BlockFluidBuffer extends FCBaseBlock { } public BlockFluidBuffer register() { - GameRegistry.registerBlock(this, AEBaseItemBlock.class, NameConst.BLOCK_FLUID_BUFFER); + GameRegistry.registerBlock(this, FCBaseItemBlock.class, NameConst.BLOCK_FLUID_BUFFER); GameRegistry.registerTileEntity(TileFluidBuffer.class, NameConst.BLOCK_FLUID_BUFFER); setCreativeTab(FluidCraftingTabs.INSTANCE); return this; @@ -71,4 +74,19 @@ public class BlockFluidBuffer extends FCBaseBlock { public ItemStack stack() { return new ItemStack(this, 1); } + + @Override + @SideOnly(Side.CLIENT) + @SuppressWarnings("unchecked") + public void addInformation( + final ItemStack itemStack, + final EntityPlayer player, + final List toolTip, + final boolean advancedToolTips) { + if (isShiftKeyDown()) { + toolTip.add(NameConst.i18n(NameConst.TT_FLUID_BUFFER_DESC)); + } else { + toolTip.add(NameConst.i18n(NameConst.TT_SHIFT_FOR_MORE)); + } + } } diff --git a/src/main/java/com/glodblock/github/common/block/BlockFluidDiscretizer.java b/src/main/java/com/glodblock/github/common/block/BlockFluidDiscretizer.java index 03ea759d..62054abe 100644 --- a/src/main/java/com/glodblock/github/common/block/BlockFluidDiscretizer.java +++ b/src/main/java/com/glodblock/github/common/block/BlockFluidDiscretizer.java @@ -1,11 +1,17 @@ package com.glodblock.github.common.block; -import appeng.block.AEBaseItemBlock; +import static net.minecraft.client.gui.GuiScreen.isShiftKeyDown; + +import com.glodblock.github.common.item.FCBaseItemBlock; import com.glodblock.github.common.tabs.FluidCraftingTabs; import com.glodblock.github.common.tile.TileFluidDiscretizer; import com.glodblock.github.util.NameConst; import cpw.mods.fml.common.registry.GameRegistry; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import java.util.List; import net.minecraft.block.material.Material; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; public class BlockFluidDiscretizer extends FCBaseBlock { @@ -18,7 +24,7 @@ public class BlockFluidDiscretizer extends FCBaseBlock { } public BlockFluidDiscretizer register() { - GameRegistry.registerBlock(this, AEBaseItemBlock.class, NameConst.BLOCK_FLUID_DISCRETIZER); + GameRegistry.registerBlock(this, FCBaseItemBlock.class, NameConst.BLOCK_FLUID_DISCRETIZER); GameRegistry.registerTileEntity(TileFluidDiscretizer.class, NameConst.BLOCK_FLUID_DISCRETIZER); setCreativeTab(FluidCraftingTabs.INSTANCE); return this; @@ -31,4 +37,20 @@ public class BlockFluidDiscretizer extends FCBaseBlock { public ItemStack stack() { return new ItemStack(this, 1); } + + @Override + @SideOnly(Side.CLIENT) + @SuppressWarnings("unchecked") + public void addInformation( + final ItemStack itemStack, + final EntityPlayer player, + final List toolTip, + final boolean advancedToolTips) { + + if (isShiftKeyDown()) { + toolTip.addAll(this.listFormattedStringToWidth(NameConst.i18n(NameConst.TT_FLUID_DISCRETIZER_DESC))); + } else { + toolTip.add(NameConst.i18n(NameConst.TT_SHIFT_FOR_MORE)); + } + } } diff --git a/src/main/java/com/glodblock/github/common/block/BlockFluidPacketDecoder.java b/src/main/java/com/glodblock/github/common/block/BlockFluidPacketDecoder.java index d42f632b..84d9370f 100644 --- a/src/main/java/com/glodblock/github/common/block/BlockFluidPacketDecoder.java +++ b/src/main/java/com/glodblock/github/common/block/BlockFluidPacketDecoder.java @@ -1,6 +1,8 @@ package com.glodblock.github.common.block; -import appeng.block.AEBaseItemBlock; +import static net.minecraft.client.gui.GuiScreen.isShiftKeyDown; + +import com.glodblock.github.common.item.FCBaseItemBlock; import com.glodblock.github.common.tabs.FluidCraftingTabs; import com.glodblock.github.common.tile.TileFluidPacketDecoder; import com.glodblock.github.inventory.InventoryHandler; @@ -8,6 +10,9 @@ import com.glodblock.github.inventory.gui.GuiType; import com.glodblock.github.util.BlockPos; import com.glodblock.github.util.NameConst; import cpw.mods.fml.common.registry.GameRegistry; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import java.util.List; import net.minecraft.block.material.Material; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; @@ -45,7 +50,7 @@ public class BlockFluidPacketDecoder extends FCBaseBlock { } public BlockFluidPacketDecoder register() { - GameRegistry.registerBlock(this, AEBaseItemBlock.class, NameConst.BLOCK_FLUID_PACKET_DECODER); + GameRegistry.registerBlock(this, FCBaseItemBlock.class, NameConst.BLOCK_FLUID_PACKET_DECODER); GameRegistry.registerTileEntity(TileFluidPacketDecoder.class, NameConst.BLOCK_FLUID_PACKET_DECODER); setCreativeTab(FluidCraftingTabs.INSTANCE); return this; @@ -58,4 +63,19 @@ public class BlockFluidPacketDecoder extends FCBaseBlock { public ItemStack stack() { return new ItemStack(this, 1); } + + @Override + @SideOnly(Side.CLIENT) + @SuppressWarnings("unchecked") + public void addInformation( + final ItemStack itemStack, + final EntityPlayer player, + final List toolTip, + final boolean advancedToolTips) { + if (isShiftKeyDown()) { + toolTip.addAll(this.listFormattedStringToWidth(NameConst.i18n(NameConst.TT_FLUID_PACKET_DECODER_DESC))); + } else { + toolTip.add(NameConst.i18n(NameConst.TT_SHIFT_FOR_MORE)); + } + } } diff --git a/src/main/java/com/glodblock/github/common/block/BlockLevelMaintainer.java b/src/main/java/com/glodblock/github/common/block/BlockLevelMaintainer.java index abf099d0..9238051a 100644 --- a/src/main/java/com/glodblock/github/common/block/BlockLevelMaintainer.java +++ b/src/main/java/com/glodblock/github/common/block/BlockLevelMaintainer.java @@ -1,9 +1,12 @@ package com.glodblock.github.common.block; +import static net.minecraft.client.gui.GuiScreen.isCtrlKeyDown; +import static net.minecraft.client.gui.GuiScreen.isShiftKeyDown; + import appeng.api.config.SecurityPermissions; -import appeng.block.AEBaseItemBlock; import appeng.util.Platform; import com.glodblock.github.client.render.RenderBlockLevelMaintainer; +import com.glodblock.github.common.item.FCBaseItemBlock; import com.glodblock.github.common.tabs.FluidCraftingTabs; import com.glodblock.github.common.tile.TileLevelMaintainer; import com.glodblock.github.inventory.InventoryHandler; @@ -14,6 +17,7 @@ import com.glodblock.github.util.Util; import cpw.mods.fml.common.registry.GameRegistry; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import java.util.List; import net.minecraft.block.material.Material; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; @@ -31,7 +35,7 @@ public class BlockLevelMaintainer extends FCBaseBlock { } public BlockLevelMaintainer register() { - GameRegistry.registerBlock(this, AEBaseItemBlock.class, NameConst.BLOCK_LEVEL_MAINTAINER); + GameRegistry.registerBlock(this, FCBaseItemBlock.class, NameConst.BLOCK_LEVEL_MAINTAINER); GameRegistry.registerTileEntity(TileLevelMaintainer.class, NameConst.BLOCK_LEVEL_MAINTAINER); setCreativeTab(FluidCraftingTabs.INSTANCE); return this; @@ -75,4 +79,21 @@ public class BlockLevelMaintainer extends FCBaseBlock { public ItemStack stack() { return new ItemStack(this, 1); } + + @Override + @SideOnly(Side.CLIENT) + @SuppressWarnings("unchecked") + public void addInformation( + final ItemStack itemStack, + final EntityPlayer player, + final List toolTip, + final boolean advancedToolTips) { + if (isShiftKeyDown() && isCtrlKeyDown()) { + toolTip.add(NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_WHO_AM_I)); + } else if (isShiftKeyDown()) { + toolTip.addAll(this.listFormattedStringToWidth(NameConst.i18n(NameConst.TT_LEVEL_MAINTAINER_DESC))); + } else { + toolTip.add(NameConst.i18n(NameConst.TT_SHIFT_FOR_MORE)); + } + } } diff --git a/src/main/java/com/glodblock/github/common/block/FCBaseBlock.java b/src/main/java/com/glodblock/github/common/block/FCBaseBlock.java index 94a1e936..fceb4a57 100644 --- a/src/main/java/com/glodblock/github/common/block/FCBaseBlock.java +++ b/src/main/java/com/glodblock/github/common/block/FCBaseBlock.java @@ -3,8 +3,14 @@ package com.glodblock.github.common.block; import appeng.block.AEBaseTileBlock; import appeng.core.features.AEFeature; import com.glodblock.github.FluidCraft; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import java.util.EnumSet; +import java.util.List; import net.minecraft.block.material.Material; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; public class FCBaseBlock extends AEBaseTileBlock { @@ -32,4 +38,21 @@ public class FCBaseBlock extends AEBaseTileBlock { public void setFeature(final EnumSet f) { super.setFeature(f); } + + @SuppressWarnings("unchecked") + @SideOnly(Side.CLIENT) + public void addInformation( + final ItemStack itemStack, + final EntityPlayer player, + final List toolTip, + final boolean advancedToolTips) {} + + protected final List listFormattedStringToWidth(String str) { + return Minecraft.getMinecraft().fontRenderer.listFormattedStringToWidth(str, 150); + } + + public void addCheckedInformation( + ItemStack itemStack, EntityPlayer player, List toolTip, boolean advancedToolTips) { + this.addInformation(itemStack, player, toolTip, advancedToolTips); + } } diff --git a/src/main/java/com/glodblock/github/common/item/FCBaseItemBlock.java b/src/main/java/com/glodblock/github/common/item/FCBaseItemBlock.java new file mode 100644 index 00000000..7ebda51c --- /dev/null +++ b/src/main/java/com/glodblock/github/common/item/FCBaseItemBlock.java @@ -0,0 +1,30 @@ +package com.glodblock.github.common.item; + +import appeng.block.AEBaseItemBlock; +import com.glodblock.github.common.block.FCBaseBlock; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import java.util.List; +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +public class FCBaseItemBlock extends AEBaseItemBlock { + private final FCBaseBlock blockType; + + public FCBaseItemBlock(Block id) { + super(id); + blockType = (FCBaseBlock) id; + } + + @SideOnly(Side.CLIENT) + @SuppressWarnings("unchecked") + public void addCheckedInformation( + final ItemStack itemStack, + final EntityPlayer player, + final List toolTip, + final boolean advancedToolTips) { + blockType.addCheckedInformation(itemStack, player, toolTip, advancedToolTips); + super.addCheckedInformation(itemStack, player, toolTip, advancedToolTips); + } +} diff --git a/src/main/java/com/glodblock/github/common/tile/TileLevelMaintainer.java b/src/main/java/com/glodblock/github/common/tile/TileLevelMaintainer.java index 602d5ee6..ff9fa45c 100644 --- a/src/main/java/com/glodblock/github/common/tile/TileLevelMaintainer.java +++ b/src/main/java/com/glodblock/github/common/tile/TileLevelMaintainer.java @@ -69,6 +69,15 @@ public class TileLevelMaintainer extends AENetworkTile return ImmutableSet.copyOf(new NonNullArrayIterator(this.requests.getLinks())); } + private IAEItemStack setState(ICraftingLink link, IAEItemStack items) { + if (items != null) { + requests.setState(link, State.Exporting); + } else { + requests.setState(link, State.Crafting); + } + return items; + } + @Override public IAEItemStack injectCraftedItems(ICraftingLink link, IAEItemStack items, Actionable mode) { try { @@ -84,19 +93,21 @@ public class TileLevelMaintainer extends AENetworkTile .injectItems(ItemFluidDrop.getAeFluidStack(items), mode, this.source); if (notInserted != null) { items.setStackSize(notInserted.getStackSize()); - return items; + return setState(link, items); } else { return null; } } else { - return this.getProxy().getStorage().getItemInventory().injectItems(items, mode, this.source); + return setState( + link, + this.getProxy().getStorage().getItemInventory().injectItems(items, mode, this.source)); } } } } catch (GridAccessException e) { AELog.debug(e); } - return items; + return setState(link, items); } @Override @@ -135,6 +146,7 @@ public class TileLevelMaintainer extends AENetworkTile IAEItemStack is = requests.getRequestQtyStack(i); if (is != null && requests.getBatchSize(i) > 0) { IAEItemStack craftItem = requests.getCraftItem(i); + if (this.requests.isDone(i)) this.requests.setState(i, State.Idling); if (cg.canEmitFor(craftItem) || cg.isRequesting(craftItem) || (inv.findPrecise(is) != null @@ -145,13 +157,15 @@ public class TileLevelMaintainer extends AENetworkTile if (jobTask == null) { requests.getJobs()[i] = cg.beginCraftingJob(getWorldObj(), grid, this.source, craftItem, null); } else if (jobTask.isDone()) { + requests.setState(i, State.Idling); try { ICraftingJob job = jobTask.get(); if (job != null) { ICraftingLink link = cg.submitJob(job, this, null, false, this.source); - didSomething = true; requests.jobs[i] = null; if (link != null) { + didSomething = true; + requests.setState(i, State.Crafting); requests.getLinks()[i] = link; } } @@ -227,6 +241,7 @@ public class TileLevelMaintainer extends AENetworkTile this.requests.getLinks()[i] = null; } else { this.requests.getLinks()[i] = AEApi.instance().storage().loadCraftingLink(link, this); + if (!this.requests.isDone(i)) this.requests.setState(i, State.Crafting); } } } catch (Exception e) { @@ -294,19 +309,26 @@ public class TileLevelMaintainer extends AENetworkTile } catch (final GridAccessException ignored) { } - if (newState != this.isPowered) { this.isPowered = newState; this.markForUpdate(); } } + public enum State { + Nothing, + Idling, + Crafting, + Exporting + } + public static class InventoryRequest { private final AeStackInventoryImpl requestStacks; private final AeStackInventoryImpl requestBatches; private final AeStackInventoryImpl requestQtys; private final Future[] jobs; private final ICraftingLink[] links; + private final State[] state = new State[REQ_COUNT]; public InventoryRequest(TileLevelMaintainer tile) { this.requestStacks = new AeStackInventoryImpl<>(StorageChannel.ITEMS, REQ_COUNT, tile); @@ -330,6 +352,30 @@ public class TileLevelMaintainer extends AENetworkTile } } + public State getState(int idx) { + IAEItemStack ias = this.getRequestStacks().getStack(idx); + if (ias == null) { + return State.Nothing; + } else { + return this.state[idx] == null ? State.Idling : this.state[idx]; + } + } + + public void setState(ICraftingLink link, State state) { + int i = 0; + for (ICraftingLink link1 : this.getLinks()) { + if (link == link1) { + this.setState(i, state); + break; + } + i++; + } + } + + public void setState(int idx, State state) { + this.state[idx] = state; + } + public boolean isEnable(int idx) { IAEItemStack ias = this.getRequestBatches().getStack(idx); if (ias != null) { diff --git a/src/main/java/com/glodblock/github/network/CPacketLevelMaintainer.java b/src/main/java/com/glodblock/github/network/CPacketLevelMaintainer.java index 9b246582..927af1e6 100644 --- a/src/main/java/com/glodblock/github/network/CPacketLevelMaintainer.java +++ b/src/main/java/com/glodblock/github/network/CPacketLevelMaintainer.java @@ -46,12 +46,13 @@ public class CPacketLevelMaintainer implements IMessage { this.size = size.isEmpty() ? 0 : Long.parseLong(size); } - public static IAEItemStack setTag(IAEItemStack ias, long batch, int slotIndex, boolean enable) { + public static IAEItemStack setTag(IAEItemStack ias, long batch, int slotIndex, boolean enable, int state) { NBTTagCompound data = new NBTTagCompound(); ItemStack is = ias.getItemStack(); data.setLong("Batch", batch); data.setLong("Index", slotIndex); data.setBoolean("Enable", enable); + data.setInteger("State", state); is.setTagCompound(data); IAEItemStack iaeItemStack = AEItemStack.create(is); iaeItemStack.setStackSize(ias.getStackSize()); @@ -90,9 +91,14 @@ public class CPacketLevelMaintainer implements IMessage { if (is1 != null) { NBTTagCompound data; data = is1.getItemStack().getTagCompound(); - piu.appendItem(setTag(is, is1.getStackSize(), i, data.getBoolean("Enable"))); + piu.appendItem(setTag( + is, + is1.getStackSize(), + i, + data.getBoolean("Enable"), + cca.getTile().requests.getState(i).ordinal())); } else { - piu.appendItem(setTag(is, 0, i, true)); + piu.appendItem(setTag(is, 0, i, true, 0)); } } } diff --git a/src/main/java/com/glodblock/github/util/NameConst.java b/src/main/java/com/glodblock/github/util/NameConst.java index 6ae061d0..23a28d1f 100644 --- a/src/main/java/com/glodblock/github/util/NameConst.java +++ b/src/main/java/com/glodblock/github/util/NameConst.java @@ -1,6 +1,9 @@ package com.glodblock.github.util; import com.glodblock.github.FluidCraft; +import java.util.ArrayList; +import net.minecraft.client.resources.I18n; +import net.minecraft.util.StatCollector; public class NameConst { @@ -33,8 +36,27 @@ public class NameConst { public static final String TT_ENCODE_PATTERN = TT_KEY + "encode_pattern"; public static final String TT_EMPTY = TT_KEY + "empty"; public static final String TT_DUMP_TANK = TT_KEY + "dump_tank"; - public static final String TT_REQUEST_SIZE = TT_KEY + "request_size"; - public static final String TT_BATCH_SIZE = TT_KEY + "batch_size"; + public static final String TT_SHIFT_FOR_MORE = TT_KEY + "shift_for_more"; + public static final String TT_FLUID_BUFFER = TT_KEY + "fluid_buffer."; + public static final String TT_FLUID_PACKET_DECODER = TT_KEY + "fluid_packet_decoder."; + public static final String TT_FLUID_PACKET_DECODER_DESC = TT_FLUID_PACKET_DECODER + "desc"; + public static final String TT_FLUID_BUFFER_DESC = TT_FLUID_BUFFER + "desc"; + public static final String TT_FLUID_DISCRETIZER = TT_KEY + "discretizer."; + public static final String TT_FLUID_DISCRETIZER_DESC = TT_FLUID_DISCRETIZER + "desc"; + public static final String TT_LEVEL_MAINTAINER = TT_KEY + "level_maintainer."; + public static final String TT_LEVEL_MAINTAINER_DESC = TT_LEVEL_MAINTAINER + "desc"; + public static final String TT_LEVEL_MAINTAINER_WHO_AM_I = TT_LEVEL_MAINTAINER + "Who_Am_I"; + public static final String TT_LEVEL_MAINTAINER_TITLE = TT_LEVEL_MAINTAINER + "title"; + public static final String TT_LEVEL_MAINTAINER_CURRENT = TT_LEVEL_MAINTAINER + "current"; + public static final String TT_LEVEL_MAINTAINER_NONE = TT_LEVEL_MAINTAINER + "none"; + public static final String TT_LEVEL_MAINTAINER_REQUEST_SIZE = TT_LEVEL_MAINTAINER + "request_size"; + public static final String TT_LEVEL_MAINTAINER_BATCH_SIZE = TT_LEVEL_MAINTAINER + "batch_size"; + public static final String TT_LEVEL_MAINTAINER_IDLE = TT_LEVEL_MAINTAINER + "idle"; + public static final String TT_LEVEL_MAINTAINER_IDLE_DESC = TT_LEVEL_MAINTAINER + "idle_desc"; + public static final String TT_LEVEL_MAINTAINER_LINK = TT_LEVEL_MAINTAINER + "link"; + public static final String TT_LEVEL_MAINTAINER_LINK_DESC = TT_LEVEL_MAINTAINER + "link_desc"; + public static final String TT_LEVEL_MAINTAINER_EXPORT = TT_LEVEL_MAINTAINER + "export"; + public static final String TT_LEVEL_MAINTAINER_EXPORT_DESC = TT_LEVEL_MAINTAINER + "export_desc"; public static final String TT_CELL_CONTENTS = TT_KEY + "cell_contents"; public static final String WAILA_KEY = FluidCraft.MODID + ".waila."; @@ -56,4 +78,28 @@ public class NameConst { public static final String GUI_OC_PATTERN_EDITOR = GUI_KEY + BLOCK_OC_PATTERN_EDITOR; public static final String GUI_FLUID_IMPORT = GUI_KEY + ITEM_PART_FLUID_IMPORT; public static final String GUI_FLUID_EXPORT = GUI_KEY + ITEM_PART_FLUID_EXPORT; + + public static String i18n(String t, String delimiter, boolean hint) { + if (!hint) { + return I18n.format(t); + } + ArrayList arr = new ArrayList<>(); + arr.add(I18n.format(t)); + if (!StatCollector.translateToLocal(t + ".hint").equals(t + ".hint")) { + arr.add(I18n.format(t + ".hint")); + } + return String.join(delimiter, arr); + } + + public static String i18n(String t) { + return i18n(t, "\n", true); + } + + public static String i18n(String t, boolean warp) { + if (warp) { + return i18n(t); + } else { + return i18n(t, "", true); + } + } } diff --git a/src/main/resources/assets/ae2fc/lang/en_US.lang b/src/main/resources/assets/ae2fc/lang/en_US.lang index 7e404208..c375f83d 100644 --- a/src/main/resources/assets/ae2fc/lang/en_US.lang +++ b/src/main/resources/assets/ae2fc/lang/en_US.lang @@ -36,8 +36,26 @@ ae2fc.waila.speed=Speed ae2fc.waila.enable=Enable ae2fc.waila.disable=Disable -ae2fc.tooltip.request_size=Amount to Maintain -ae2fc.tooltip.batch_size=Crafting Batch Size +ae2fc.tooltip.shift_for_more=> Hold §3Shift§r for more information +ae2fc.tooltip.fluid_packet_decoder.desc=The Fluid Decoder can decode Fluid packets. It has to be connected to a ME System and a place to store the liquid in otherwise it won't work. +ae2fc.tooltip.discretizer.desc=When the ME Fluid Discretizer is attached to your ME System, it will represent the Fluids that are stored in your ME Fluid Storage Cells (Or Storage bus) as drops. They will be the item equivalent of fluids. Its just another way to show fluids, it won't actually convert your fluids to items. +ae2fc.tooltip.fluid_buffer.desc=This is a high speed fluid IO +ae2fc.tooltip.level_maintainer.Who_Am_I=Who Am I? +ae2fc.tooltip.level_maintainer.title=§6Request Status§r +ae2fc.tooltip.level_maintainer.desc=Automatically keeps items and fluids in stock by requesting new crafts when needed. Has to be connected to an ME network. +ae2fc.tooltip.level_maintainer.current=Currently: +ae2fc.tooltip.level_maintainer.none=No request configured. +ae2fc.tooltip.level_maintainer.idle=§aIdling§r +ae2fc.tooltip.level_maintainer.idle_desc=The Requester is idling when the requested amount is already reached, there is no crafting pattern for this item or fluid or if there are not enough ingredients to request more crafts. +ae2fc.tooltip.level_maintainer.link=§eCrafting§r +ae2fc.tooltip.level_maintainer.link_desc=The system is currently crafting the requested item or fluid. +ae2fc.tooltip.level_maintainer.export=§5Exporting§r +ae2fc.tooltip.level_maintainer.export_desc=The Requester is trying to export the crafting results to the system. If the Requester has this status for a long time, there is no available space for the export. +ae2fc.tooltip.level_maintainer.batch_size=§6Crafting Batch Size§r +ae2fc.tooltip.level_maintainer.batch_size.hint=When craft requests are emitted, the Requester will use the batch size for the request. Using larger batches will increase the speed of stocking up items but will require more crafting storage. +ae2fc.tooltip.level_maintainer.request_size=§6Amount to Maintain§r +ae2fc.tooltip.level_maintainer.request_size.hint=The count defines how many items should be held in stock before the Requester starts requesting new crafts. + ae2fc.tooltip.cell_contents=Contains Fluid: ae2fc.tooltip.fluid_terminal=uh So we don't need EC2 anymore? ae2fc.tooltip.invalid_fluid=Invalid fluid! diff --git a/src/main/resources/assets/ae2fc/lang/zh_CN.lang b/src/main/resources/assets/ae2fc/lang/zh_CN.lang index bada3ed2..19a3ba5f 100644 --- a/src/main/resources/assets/ae2fc/lang/zh_CN.lang +++ b/src/main/resources/assets/ae2fc/lang/zh_CN.lang @@ -29,15 +29,33 @@ tile.fluid_interface.name=ME二合一接口 tile.ingredient_buffer.name=原材料缓存仓 tile.large_ingredient_buffer.name=大型原材料缓存仓 tile.oc_pattern_editor.name=OC样板编辑器 -tile.level_maintainer.name=ME缓存指令器 +tile.level_maintainer.name=ME库存维持器 tile.fluid_buffer.name=ME流体缓存器 ae2fc.waila.speed=速度 ae2fc.waila.enable=启用 ae2fc.waila.disable=禁用 -ae2fc.tooltip.request_size=缓存量 -ae2fc.tooltip.batch_size=批量制作数量 +ae2fc.tooltip.shift_for_more=> 按 §3Shift§r 显示更多信息 +ae2fc.tooltip.fluid_packet_decoder.desc=流体解码器可以解码液体数据包。它必须与ME系统连接,并且网络内可以储存流体,否则它就无法工作。 +ae2fc.tooltip.discretizer.desc=当ME流体离散器连接到您的ME系统时,它将把存储在的ME流体存储单元(或存储总线)中的流体表现为物品液滴。它们将是流体的等价物。它只是显示流体的另一种方式,它不会真正把你的流体转换成物品。 +ae2fc.tooltip.fluid_buffer.desc=这就是一个高速的流体IO接口 +ae2fc.tooltip.level_maintainer.Who_Am_I=Who Am I? +ae2fc.tooltip.level_maintainer.title=§6请求状态§r +ae2fc.tooltip.level_maintainer.desc=通过在需要时请求合成,自动保持物品和流体的库存。必须连接到ME网络。 +ae2fc.tooltip.level_maintainer.current=目前: +ae2fc.tooltip.level_maintainer.none=没有配置任何请求。 +ae2fc.tooltip.level_maintainer.idle=§a空闲中§r +ae2fc.tooltip.level_maintainer.idle_desc=当请求的数量已经达到时,请求器处于空闲状态,该物品没有制作模板,或者没有足够的原料来请求更多的合成。 +ae2fc.tooltip.level_maintainer.link=§e合成中§r +ae2fc.tooltip.level_maintainer.link_desc=系统当前正在制作请求的物品或流体。 +ae2fc.tooltip.level_maintainer.export=§5输出中§r +ae2fc.tooltip.level_maintainer.export_desc=请求器正在尝试将制作结果导出到ME系统。如果请求器长期处于此状态,则说明没有可用的存储空间。 +ae2fc.tooltip.level_maintainer.batch_size=§6请求次数§r +ae2fc.tooltip.level_maintainer.batch_size.hint=当发出合成请求时,请求器发送合成请求次数的多少。更多的请求次数将提高储存物品的速度,但需要更多的合成存储空间。 +ae2fc.tooltip.level_maintainer.request_size=§6请求数量§r +ae2fc.tooltip.level_maintainer.request_size.hint=数量定义了在请求器开始请求新合成之前应该保留多少物品。 + ae2fc.tooltip.cell_contents=内含流体: ae2fc.tooltip.fluid_terminal=我们不再需要EC2了吗? ae2fc.tooltip.invalid_fluid=流体无效! diff --git a/src/main/resources/assets/ae2fc/textures/gui/level_maintainer.png b/src/main/resources/assets/ae2fc/textures/gui/level_maintainer.png index 85118334109b554840b8ec9bcc71ce8bedaf4537..8eab0fc5421f8dd331dbbb706570584787809e6d 100644 GIT binary patch literal 1368 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 }~T?BFvmgzCjI(0fG6m zc!M_@6KgnAU7zg1sO#}QLa)IKJWq+7I?2A!pu5+{S{w!qkIM(w+^04e<(yI|5hYwu z?>8xdZ__4d@j?l-@|f&)Mt=WZtjxV@OV0Ap@2@$U7nILFPC?^n96~YliY6M)0}u%O zgzEm34Jai(+`0N{Y*bo=P0sIpXwb*P7N7dEcw{9;6Suv^+xwXI4?*b^9WQ0O`f1UI>5L_g1{}h70 z54JDSLbyGW3F{AMqo9^Hin@Krx9z}#n!{gG%iZ)JG=nnXJ!*uClV9|>p+4l2LE*6UD$A$L~@ zj|aBBoG{aVahl!?3F;bCjFnH7`yZzFGV12jVZR=13DQdgx*)=CH3V!}O$Hjw0-m;2 zH8|ugZHldPgLo|$5Jil);@8x{2Mg{qmf-U#50=f%mT=FccLj^I^=o7w+wG9@zJTF_ zke25cW@A4UOQ-@tf+p!a%ZmYFQbXJsE3ch7k#%BXa%VYvFn8I%Z%> z)dANETL_R_+B@{oj*JUGu-PrQ5I_0zaxH`d~5b6#b{7` z{W)s9fSr+gqTdOFYMImy(bF59(EB@w$_-Ip%KcV_&(y&x0d%_6TmAv3{4}O$p(9R< zc>BLv7*#9vI}9zg#8Puag*r!L?i$k@K@(7NSkun?FlyGgfy>Cx9BBW8aAV9(-v z2!%9M@3UN4lW`OsrTXp4``)}QqKsTjs2-Xf+0lBzA$>V6qY1WWU*`Ur38K7KtN-p3)Nn?@OgHmjdRPOdyY%PKAa^Af4t@N z%lq^L*K2l9WsDf{sSaD1l!!59QULAlPKxOg&Grfp6EnLfJsC$_s*r(N+#p9wc4j?- zaBpLo*dt(P96m>FmeL@?kEoL~M<>=tV)x+JVpGE=HoO{;g+nR4^W68(1sIoKE77e# zkS_w4NG@)%+Cun81iA9?+OU3Y1XN8W{ad)}`zj);^(nZ{OIN0QuCkKd%mEs_M|Oq$dTlt-sc{k zLE$OfWjijH*qD;91e*_@cITsI>Tg%y)n#Ya#bAoV7D-R<>ee zywJl7)K%xe+G<}>WIsqX#VyW$CtC6O!$Qf##3wt~cSdo~urw>MhJ=@_o)7W$xg7ec z(&$+`1*+M-aU#ibW(b10YB1nw1#mI6&>k;nf1g9yb0mwBUd!Is4&COlql=9A%=L`p zO*w&88pb@2MdEZQ?Xc7P2P`p+=9K01nIFU&q3%A+rm_NyIxHd?9Y8IGnk~KXS5je3 zWqL-gkWuE_^?VA*m(`EcSb&>hnXXNdi=b#5DY&I};MTq(Y2FDHjad}YQP z@=Zq?CvupzrB`v1fx5pb9%a~u%=3^DcbP^zg3hR6j~ zwIzif2a52>C%YEk%Ib+;M%5<^sJuOrZu+(5hpobc*dE5@#h0NmYp&d@M_;~pAxQ-H z>NUOx9UN-B?D!dxE>m}`1NVwePq>3?MY-aX8m6ZwSsVNu3G6rhD!5dMSfY=1n+nbq1=?YqP_Ma#=o+f3=P;iZy# z9raMjM&U{MIl7hA#CpHxS3Xh;Ztzb;JW5rlYq9Tk!R%>|R-ucpV++b48Y7=S5Gu#5 zzhr*QkIqut_v6GrdUKT2aOl==Gr(!8A8o*{xuTiY?_)>LJnrgJU}|W64YJtu(k$*r73}vNyw#Z8lE?JvY2=8(RxZ;Gzjj1>=X}HY zD@|e@yRP#!N$@j|0AFgc+qYMU!?~me`xTy4^}0nkW9Vn`_f@xEk7;hM{xG)73OxfU zzaKNv9celwB#S**W65a&^gU+^kHM^Im_$X#k-_r`!4>#LD2wD zJC8T6?&bSo7!IhqL%j6Nm^^BtYNKb28Ym^3rDr2cK@acEmK7eYNrEor{sg8|DmBTSxUBuB8^p^!4P#g%T_(DysG3tYV;+y@&&` zyS@mAE&Ac%Au>`(Oe|(?Z7n4-a;C~;pr@xN_WP~ffPjF2xtEvMZr=BLM6Mg=`3kSQ zu&}U6){wX~EPa{$L}3I3;OoNdY^h|i+NRw=ZA36&x&vF9_$Mqr0L{;$I(^u!$;qJv z0Sv0AS%=e8Tg8;$C2pS69eUqDTXS-9-rQZhPr7cj$av8Om@@Na-0SKhXD~k1cV0Z! zqXsT;g8;;X#}c(w{diP>$@WolujVyjg2$=CH8U`zi~V<6_b#olAuxVBrHKP_ey>|) z%>Re(_95`xSG-E`k2j4adPqwJ@B|b}b~Q9?R1Ttm3<2BDWMZ%i4sbSWaIZcku=)7V z>NNkylBz8w7$~i*sv>ry<#e!PlW8CZMs^vRHHsr6w<>{2daLm|8oVBdBZ zIeECd(la#tWOBUZcr||1a{I=@NkHFbWhoe(Pq?+Ub%9WN7+(0ZG#A69(?80%N|&1V z(t1-^zwTj!CJ48bVT$MK{=WUs;{3cpd(flAuMR&!4yo4Y-6eZx z;DbTX;rcrL$jHd*&O}MS<0*Qul?kZb=ZsMz@SX%0ms-LsLEqIy{(zFnZj7`;N%NHGiP2GRCHOjekAz%1Y^E06Qcg#Gv zz7c^6E8=AJ>w6VRWNNI4i}*nuUEMSuAn<cC6wlI->8t~f+2AT!eyJ(2!kYGhT`CuVN_51qIRk={_?04tKKM!39K-c#D-L2l8?@as#2b&b*b8XEc0wSQKI3vJ$hocmq>-VfmArAbj zXn}gSzeN)`zY~2IVOY=;6s+D2w`fAlHwN$hZLyQ7E=Cq2_UwO1{qO2=01gle zKtubN>UgU_oGc{UW@WSxcN@DBD0hP3lR0IV?D+73eUSdo>}dcP7zcnz|2tjA&(Q%P zR1S_i_@7ByyY9(AD!czxi#F_p7Q9P77CvpbW#>zUUE%=xyP4;|jQsEFAb;&f2v&JI zD=M;9pRwKh*v9LaMi&y!{>x0Wbeeb5jE~FuRFc-#EQpB{KLa`ff`Uev(JP>3e^^H_ jepJUP0WJ|p|r7DLxPkTEfj2A>#puj z`L27$yEFIRopna&2gA<2Gv}V~oO|xM=gv}4)YjHIxB?4!5Pw!)hoXE+`ToL%3w-N5 zc<{gqN;-`Eo(%9RJ$v>n&Ck!1+-D*YR=!YJI;DWDSjN+*PpQAZpO{2g`A`Nx`I$3k zsHLUF?bIpm?Ci{G&(6+LX=y2ik)NKPHW<<95G9D{XYD&8grK~qr-y24YK%&&s;Ybh zqL9~-Z+iF*4Sz4bCi;>boe}ODfb#M2aq(+X3M?)z`uf7ktI+h`5z#wrct;q(Q(jh9 zMuUTc1uG3J@5he!DQm>=_g`seK^QPJG$b0wjvX^9-q_esPJ38+6+m2&f4ORWPZ%&U zF+tVU)wHm%;8O}rPEKO6(aDo1>HPWgqOY~JRkVZ3Gk;hf7#JAP5(DwT2Hd}YpH81X zEl8-8g8c7?57Y7KX+Z$wxm{aZn^#^Y%?5UKbhr-i<0otQ(}eT+!|$?-_*-oz5^1!% zyIV9aUAjbTYimlSF6s4k_ZKsOG#W%+o)wV)=(l(2*@@T0dyyKSW%n0-8Wjex=Mckl zb8}Q)UVpAtER#nL4=NAY=H_PV?d=UnJ{a7clu4x1X?pYKO^z_H0q+b1m6tspC3)gC zkloUqylWs!`uO^~lWk*)t$gx$=h=zZPSoUm1HqFV!-_55@x1SC=aW~;ghix-?F9}E zg*qb`&jW?PaSG>QSy}&$?@?(@ga%laRgeXa<9|fAh#4QBIO>v!#bVGx=}czlUc&4z ze<+o=wY3?Q!Q2kUNo@_CXdM)XO=A-C_w%$9LL5G*R%9TsUd z9*_xoW06i+|ra7oe8Q=7E1vf}oooo)IznbHo%3mG0yrBZ^t zZQE2)Q6VZ(?8Go;-wcRZM5o^0ZNp=UL_+GbXzbVg>mDRQ9tPnaby0C~F>P*c3WN5| z0J39rq%1CO)0-Ol36An%Ayf+woDvGmtx4 zCQY$)ijo^iag`O>;zA!TXDdy%VGUw|f*`KO#zt|(#5FTBSiB=Sd{RE(2o=AQGoGn1wXxRm`L)dqzM?M46z%OhGh8~eJpRQAQcg2L zRp@x1`3wNK*5S&MX8=M>Kz|hic<;`gJJi+H<+d?XH*ek)-iJIc^y@;9VTyaSwIKv= zai+m^<3&0C(bg4YkVS^U@exL_JY~OH%kriWWP+vzozo{bWRLR<$T^&{VWQi;@qT@M zy*QEKD>RIO_vJBF=K)n{m=?4)ggEmcRNy5LLTxXDzc}as8T{=E@_)dSCr{k5$&kT< zlK08U4c;l`njfLSUgzo8r9t*^GMN;|%5&$=i82ACP4Yp!t(v7A1F#D(FE4AoE9Z7q zCgQ^k%Y!h^!Ezcl$$N<_$(q&x;x-Jz%KL}~AnzIw_CsqJd4!m$urq>){sWl;E?BX@ S!5#nr002ovPDHLkU;%>FZ9NqL delta 1679 zcmV;A25|Y94WA8=B!6Z}L_t(&fz4T6YZO-)e$LG9X3cIA%!Mfhsg?SHg7ij8DHWS; zilrB&g0-bk5G)w+wtt{Ey(m>L1ceHMP$S7jDHLj&5FtUOqyZ_d8XG}dj7f@g*Zna2 zF>}g$X3y;G&YaoVoeAv&>&`hl@4U}*&iipDA}BJM45v?EgMSu;wO1k5&Z)dUe*Cz+ z-@c8D7cWAR2x}io069N= z_%KFCN9{?K?>ArpY zTm+)9SCKz*{eKHgEUf^afvZH=IY7>5W@f~$p@Zd2V}HdoK`iLH^;I?|nkR z?CdNK95{gc_wT!$66WUSDA}-o|9%`hc1+BjJb6-#gMZpfNPEJiOP7?yh6zp%>0V<QwF1zsQ17PEHtbkCi=D?DoQt_RUd${6-&@x0~!)^R&~Pn)oa^kLnA zV?5M5g75o4hj0^Np0llY05e^B9FA51#>U5>F@FuFX@W6keRyM&X-v3z^Cr%mITMM` zCIPSR-EOa!uIm8jFig|Bc3|PxKRiQ^n;f_1Z;47oLWn$x(KOBe=A7g45AOc$i-Lv!U=8SzS7h=>YWGXV{M z7JseJGc$#cN58}y?~P*lIY*%a8qE+IEYk9Uw>Z z4`jGhu>IgVR##W;IfK{myj)SbGHQkp!Q&i;ZXjVK#JIG%gi^YM{?&dlmbnnQ0G$B` zUulfj*49ug79Dd8KmO*E_a<$rhTKpNaep(8o+mvh4ir)9FCqO;8p&c3Opms5H?z@n zY#EG;OJltR{oz&Y(tt{zdPXXn!lv9NFq4UDM5JZt$TGVz0svf|El?439Ft_tW+MKpRdpY@apMM- zmzS+RQ18ahsv|=u%03WfN$7?Z6Mu)f|H)bCKRMY(dYJ1P?my@SMl8yB>;{xG-QvoX zE7lIEs)Cue;#wl-Je6;8r*?T6;W z9Kcx`VDDRF_N_&je`M{1c?}$SKr=!J`D+(PLI>7GId(nAYqgzXT)#O7f`5D;#5(}H z+;}*F^)ro_ zr;t&J5Wi(Q*o6S(ooEduuYZJgidDWJ`iTgP4#`XSCT%R{4k0R!d|I*EEh6|Q;B;?O zNqw|~V|5STw)%F%J_LCgLaKyrnzOIgy&p&-h`bQ-DLBJsKKSlwt*0;~5@lD}Tr(o(CrHML1|R zf-48|0M&W1;*M~lun}F3elNJ5VS$JeVZ*dOU6NN3R`!V|HPm6Vfcb-Ul(6G|(h8fl zM+qWKofhz{^Fh(BsVN26LWpRgE~L}LTnOS#!~&2P^Yo9;k=i;!M8QY_I*HP$vMT`i Z7hk5%b5KMeVE_OC00>D%PDHLkV1lJ!88QF>