From e833aa1e613fd14f284d816b1dd9574252b110ff Mon Sep 17 00:00:00 2001 From: zeng-git <95841646+zeng-github01@users.noreply.github.com> Date: Mon, 10 Mar 2025 15:40:11 +0800 Subject: [PATCH] Further crafting lock improvements (#507) --- .../appeng/api/config/LockCraftingMode.java | 10 +- .../java/appeng/client/gui/AEBaseGui.java | 6 + .../gui/implementations/GuiInterface.java | 22 ++- .../client/gui/widgets/GuiImgButton.java | 2 +- .../client/gui/widgets/GuiImgLabel.java | 142 ++++++++++++++++++ .../implementations/ContainerInterface.java | 11 ++ .../appeng/core/localization/GuiText.java | 9 ++ .../java/appeng/helpers/DualityInterface.java | 11 +- .../appliedenergistics2/lang/en_us.lang | 6 + .../appliedenergistics2/lang/zh_cn.lang | 6 + 10 files changed, 211 insertions(+), 14 deletions(-) create mode 100644 src/main/java/appeng/client/gui/widgets/GuiImgLabel.java diff --git a/src/api/java/appeng/api/config/LockCraftingMode.java b/src/api/java/appeng/api/config/LockCraftingMode.java index 17e7f5d58..6ec6a1176 100644 --- a/src/api/java/appeng/api/config/LockCraftingMode.java +++ b/src/api/java/appeng/api/config/LockCraftingMode.java @@ -6,21 +6,21 @@ public enum LockCraftingMode { */ NONE, /** - * After pushing a pattern to an adjacent machine, the pattern provider will not accept further crafts until a + * After pushing a pattern to an adjacent machine, the interface will not accept further crafts until a * redstone pulse is received. */ LOCK_UNTIL_PULSE, /** - * Crafting is locked while the pattern provider is receiving a redstone signal. + * Crafting is locked while the interface is receiving a redstone signal. */ LOCK_WHILE_HIGH, /** - * Crafting is locked while the pattern provider is not receiving a redstone signal. + * Crafting is locked while the interface is not receiving a redstone signal. */ LOCK_WHILE_LOW, /** - * After pushing a pattern to an adjacent machine, the pattern provider will not accept further crafts until the - * primary pattern result is returned to the network through the pattern provider. + * After pushing a pattern to an adjacent machine, the interface will not accept further crafts until the + * primary pattern result is returned to the network through the interface. */ LOCK_UNTIL_RESULT } diff --git a/src/main/java/appeng/client/gui/AEBaseGui.java b/src/main/java/appeng/client/gui/AEBaseGui.java index 4c2beb8c0..aa9c57b0b 100644 --- a/src/main/java/appeng/client/gui/AEBaseGui.java +++ b/src/main/java/appeng/client/gui/AEBaseGui.java @@ -183,6 +183,12 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain this.drawTooltip((ITooltip) c, mouseX, mouseY); } } + + for (final Object o : this.labelList) { + if (o instanceof ITooltip) { + this.drawTooltip((ITooltip) o, mouseX, mouseY); + } + } GlStateManager.enableDepth(); if (Platform.isModLoaded("jei")) { bookmarkedJEIghostItem(mouseX, mouseY); diff --git a/src/main/java/appeng/client/gui/implementations/GuiInterface.java b/src/main/java/appeng/client/gui/implementations/GuiInterface.java index 6c8c4d6fe..a01a42c85 100644 --- a/src/main/java/appeng/client/gui/implementations/GuiInterface.java +++ b/src/main/java/appeng/client/gui/implementations/GuiInterface.java @@ -23,6 +23,7 @@ import appeng.api.config.LockCraftingMode; import appeng.api.config.Settings; import appeng.api.config.YesNo; import appeng.client.gui.widgets.GuiImgButton; +import appeng.client.gui.widgets.GuiImgLabel; import appeng.client.gui.widgets.GuiTabButton; import appeng.client.gui.widgets.GuiToggleButton; import appeng.container.implementations.ContainerInterface; @@ -45,12 +46,19 @@ public class GuiInterface extends GuiUpgradeable { private GuiImgButton UnlockMode; private GuiImgButton BlockMode; private GuiToggleButton interfaceMode; + private GuiImgLabel lockReason; public GuiInterface(final InventoryPlayer inventoryPlayer, final IInterfaceHost te) { super(new ContainerInterface(inventoryPlayer, te)); this.ySize = 256; } + @Override + public void initGui() { + super.initGui(); + this.addLabel(); + } + @Override protected void addButtons() { this.priority = new GuiTabButton(this.guiLeft + 154, this.guiTop, 2 + 4 * 16, GuiText.Priority.getLocal(), this.itemRender); @@ -59,13 +67,21 @@ public class GuiInterface extends GuiUpgradeable { this.BlockMode = new GuiImgButton(this.guiLeft - 18, this.guiTop + 8, Settings.BLOCK, YesNo.NO); this.buttonList.add(this.BlockMode); - this.UnlockMode = new GuiImgButton(this.guiLeft - 18,this.guiTop + 26 ,Settings.UNLOCK, LockCraftingMode.NONE); + this.UnlockMode = new GuiImgButton(this.guiLeft - 18, this.guiTop + 26, Settings.UNLOCK, LockCraftingMode.NONE); this.buttonList.add(this.UnlockMode); this.interfaceMode = new GuiToggleButton(this.guiLeft - 18, this.guiTop + 44, 84, 85, GuiText.InterfaceTerminal.getLocal(), GuiText.InterfaceTerminalHint.getLocal()); this.buttonList.add(this.interfaceMode); } + protected void addLabel() { + if (lockReason != null) { + labelList.remove(this.lockReason); + } + this.lockReason = new GuiImgLabel(this.fontRenderer, guiLeft + 40, guiTop + 12, Settings.UNLOCK, LockCraftingMode.NONE); + labelList.add(lockReason); + } + @Override public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) { if (this.BlockMode != null) { @@ -80,6 +96,10 @@ public class GuiInterface extends GuiUpgradeable { this.interfaceMode.setState(((ContainerInterface) this.cvb).getInterfaceTerminalMode() == YesNo.YES); } + if (this.lockReason != null) { + this.lockReason.set(((ContainerInterface) this.cvb).getCraftingLockedReason()); + } + this.fontRenderer.drawString(this.getGuiDisplayName(GuiText.Interface.getLocal()), 8, 6, 4210752); this.fontRenderer.drawString(GuiText.Config.getLocal(), 8, 6 + 11 + 7, 4210752); diff --git a/src/main/java/appeng/client/gui/widgets/GuiImgButton.java b/src/main/java/appeng/client/gui/widgets/GuiImgButton.java index 4c242adab..0c0b13365 100644 --- a/src/main/java/appeng/client/gui/widgets/GuiImgButton.java +++ b/src/main/java/appeng/client/gui/widgets/GuiImgButton.java @@ -345,7 +345,7 @@ public class GuiImgButton extends GuiButton implements ITooltip { this.fillVar = fillVar; } - private static final class EnumPair { + public static final class EnumPair { final Enum setting; final Enum value; diff --git a/src/main/java/appeng/client/gui/widgets/GuiImgLabel.java b/src/main/java/appeng/client/gui/widgets/GuiImgLabel.java new file mode 100644 index 000000000..ffba24eba --- /dev/null +++ b/src/main/java/appeng/client/gui/widgets/GuiImgLabel.java @@ -0,0 +1,142 @@ +package appeng.client.gui.widgets; + +import appeng.api.config.LockCraftingMode; +import appeng.api.config.Settings; +import appeng.core.localization.GuiText; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.GuiLabel; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.translation.I18n; + +import java.util.HashMap; +import java.util.Map; + +public class GuiImgLabel extends GuiLabel implements ITooltip { + public GuiImgLabel(FontRenderer fontRendererObj, final int x, final int y, final Enum idx, final Enum val) { + super(fontRendererObj, 0, x, y, 16, 16, 0); + this.currentValue = val; + this.labelSetting = idx; + this.fontRenderer = fontRendererObj; + + if (appearances == null) { + appearances = new HashMap<>(); + registerApp(10, Settings.UNLOCK, LockCraftingMode.NONE, GuiText.NoneLock, null, 0x00FF00); + registerApp(9, Settings.UNLOCK, LockCraftingMode.LOCK_WHILE_LOW, GuiText.CraftingLock, GuiText.LowRedstoneLock, 0xFF0000); + registerApp(9, Settings.UNLOCK, LockCraftingMode.LOCK_WHILE_HIGH, GuiText.CraftingLock, GuiText.HighRedstoneLock, 0xFF0000); + registerApp(9, Settings.UNLOCK, LockCraftingMode.LOCK_UNTIL_PULSE, GuiText.CraftingLock, GuiText.UntilPulseUnlock, 0xFF0000); + registerApp(9, Settings.UNLOCK, LockCraftingMode.LOCK_UNTIL_RESULT, GuiText.CraftingLock, GuiText.ResultLock, 0xFF0000); + } + } + + private final Enum labelSetting; + private Enum currentValue; + private static Map appearances; + private final FontRenderer fontRenderer; + + public void setVisibility(final boolean vis) { + this.visible = vis; + } + + @Override + public void drawLabel(Minecraft mc, int mouseX, int mouseY) { + if (this.visible) { + final int iconIndex = this.getIconIndex(); + if (iconIndex == -1) { + return; + } + mc.renderEngine.bindTexture(new ResourceLocation("appliedenergistics2", "textures/guis/states.png")); + GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f); + final int uv_y = (int) Math.floor(iconIndex / 16); + final int uv_x = iconIndex - uv_y * 16; + + + this.drawTexturedModalRect(this.x, this.y, uv_x * 16, uv_y * 16, 16, 16); + + if (labelSetting != null && currentValue != null) { + LabelAppearance labelAppearance = appearances.get(new GuiImgButton.EnumPair(this.labelSetting, this.currentValue)); + String translated = I18n.translateToLocal(labelAppearance.displayLabel); + fontRenderer.drawString(translated, x + 16, y + 5, labelAppearance.color); + width = 16 + fontRenderer.getStringWidth(translated); + } + } + } + + private int getIconIndex() { + if (this.labelSetting != null && this.currentValue != null) { + final LabelAppearance app = appearances.get(new GuiImgButton.EnumPair(this.labelSetting, this.currentValue)); + if (app == null) { + return -1; + } + return app.index; + } + return -1; + } + + private void registerApp(final int iconIndex, final Settings setting, final Enum val, final GuiText label, final Object hint, int color) { + final LabelAppearance a = new LabelAppearance(); + if (hint != null) { + a.hiddenValue = (String) (hint instanceof String ? hint : ((GuiText) hint).getUnlocalized()); + } else { + a.hiddenValue = null; + } + a.index = iconIndex; + a.displayLabel = label.getUnlocalized(); + a.color = color; + appearances.put(new GuiImgButton.EnumPair(setting, val), a); + } + + @Override + public String getMessage() { + if (labelSetting != null && this.currentValue != null) { + LabelAppearance labelAppearance = appearances.get(new GuiImgButton.EnumPair(this.labelSetting, this.currentValue)); + if (labelAppearance == null) { + return "No Such Message"; + } + + if (labelAppearance.hiddenValue != null) { + return I18n.translateToLocal(labelAppearance.hiddenValue); + } + } + return null; + } + + public void set(final Enum e) { + if (this.currentValue != e) { + this.currentValue = e; + } + } + + @Override + public int xPos() { + return x; + } + + @Override + public int yPos() { + return y; + } + + @Override + public int getWidth() { + return width; + } + + @Override + public int getHeight() { + return height; + } + + @Override + public boolean isVisible() { + return visible; + } + + private static class LabelAppearance { + public int index; + public String displayLabel; + public String hiddenValue; + public int color; + } +} diff --git a/src/main/java/appeng/container/implementations/ContainerInterface.java b/src/main/java/appeng/container/implementations/ContainerInterface.java index 87ad42a18..01e5b0139 100644 --- a/src/main/java/appeng/container/implementations/ContainerInterface.java +++ b/src/main/java/appeng/container/implementations/ContainerInterface.java @@ -45,6 +45,9 @@ public class ContainerInterface extends ContainerUpgradeable implements IOptiona @GuiSync(8) public YesNo iTermMode = YesNo.YES; + @GuiSync(9) + public LockCraftingMode lockReason = LockCraftingMode.NONE; + public ContainerInterface(final InventoryPlayer ip, final IInterfaceHost te) { super(ip, te.getInterfaceDuality().getHost()); @@ -94,6 +97,10 @@ public class ContainerInterface extends ContainerUpgradeable implements IOptiona patternExpansions = getPatternUpgrades(); this.myDuality.dropExcessPatterns(); } + + if (Platform.isServer()){ + lockReason = myDuality.getCraftingLockedReason(); + } super.detectAndSendChanges(); } @@ -134,4 +141,8 @@ public class ContainerInterface extends ContainerUpgradeable implements IOptiona public int getPatternUpgrades() { return this.myDuality.getInstalledUpgrades(Upgrades.PATTERN_EXPANSION); } + + public LockCraftingMode getCraftingLockedReason() { + return lockReason; + } } diff --git a/src/main/java/appeng/core/localization/GuiText.java b/src/main/java/appeng/core/localization/GuiText.java index 67f2eeb20..72265f0a4 100644 --- a/src/main/java/appeng/core/localization/GuiText.java +++ b/src/main/java/appeng/core/localization/GuiText.java @@ -211,6 +211,15 @@ public enum GuiText { CraftingToastDone, CraftingToastCancelled, + //Used in Lock Crafting, + CraftingLock, + NoneLock, + LowRedstoneLock, + HighRedstoneLock, + ResultLock, + UntilPulseUnlock, + + // Used in Annihilation Planes CanBeEnchanted, IncreasedEnergyUseFromEnchants, Deprecated; diff --git a/src/main/java/appeng/helpers/DualityInterface.java b/src/main/java/appeng/helpers/DualityInterface.java index 3a34c68ef..4017cbc29 100644 --- a/src/main/java/appeng/helpers/DualityInterface.java +++ b/src/main/java/appeng/helpers/DualityInterface.java @@ -64,7 +64,6 @@ import appeng.parts.automation.UpgradeInventory; import appeng.parts.misc.PartInterface; import appeng.tile.inventory.AppEngInternalAEInventory; import appeng.tile.inventory.AppEngInternalInventory; -import appeng.tile.inventory.AppEngInternalOversizedInventory; import appeng.tile.inventory.AppEngNetworkInventory; import appeng.tile.networking.TileCableBus; import appeng.util.ConfigManager; @@ -96,9 +95,7 @@ import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; -import net.minecraftforge.items.wrapper.RangedWrapper; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.*; @@ -1161,7 +1158,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn } case LOCK_UNTIL_RESULT -> { unlockEvent = UnlockCraftingEvent.RESULT; - unlockStack = pattern.getPrimaryOutput(); + unlockStack = pattern.getPrimaryOutput().copy(); saveChanges(); } } @@ -1170,7 +1167,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn /** * Gets if the crafting lock is in effect and why. * - * @return null if the lock isn't in effect + * @return {@link LockCraftingMode#NONE} if the lock isn't in effect */ public LockCraftingMode getCraftingLockedReason() { var lockMode = cm.getSetting(Settings.UNLOCK); @@ -1526,7 +1523,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn /** * @return Null if {@linkplain #getCraftingLockedReason()} is not {@link LockCraftingMode#LOCK_UNTIL_RESULT}. */ - @org.jetbrains.annotations.Nullable + @Nullable public IAEItemStack getUnlockStack() { return unlockStack; } @@ -1540,7 +1537,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn // Actually an error state... AELog.error("MEInterface was waiting for RESULT, but no result was set"); unlockEvent = null; - } else if (unlockStack.getItem().equals(stack.getItem())) { + } else if (unlockStack.isSameType(stack)) { var remainingAmount = unlockStack.getStackSize() - stack.getStackSize(); if (remainingAmount <= 0) { unlockEvent = null; diff --git a/src/main/resources/assets/appliedenergistics2/lang/en_us.lang b/src/main/resources/assets/appliedenergistics2/lang/en_us.lang index 943601763..c03cce576 100644 --- a/src/main/resources/assets/appliedenergistics2/lang/en_us.lang +++ b/src/main/resources/assets/appliedenergistics2/lang/en_us.lang @@ -258,6 +258,12 @@ gui.appliedenergistics2.CraftingToastDone=Crafting Done! gui.appliedenergistics2.CraftingToastCancelled=Crafting Cancelled! gui.appliedenergistics2.Sticky=Sticky gui.appliedenergistics2.FluidTerminal=Fluid Terminal +gui.appliedenergistics2.CraftingLock=Crafting is locked +gui.appliedenergistics2.NoneLock=Crafting is unlocked +gui.appliedenergistics2.HighRedstoneLock=Locked by redstone signal +gui.appliedenergistics2.LowRedstoneLock=Locked by lack of redstone signal +gui.appliedenergistics2.ResultLock=Waiting for pattern output to unlock +gui.appliedenergistics2.UntilPulseUnlock=Waiting for redstone pulse to unlock gui.appliedenergistics2.CanBeEnchanted=Can be enchanted gui.appliedenergistics2.IncreasedEnergyUseFromEnchants=Enchants increase energy use gui.appliedenergistics2.Deprecated=Deprecated diff --git a/src/main/resources/assets/appliedenergistics2/lang/zh_cn.lang b/src/main/resources/assets/appliedenergistics2/lang/zh_cn.lang index d6d96b397..962b080e4 100644 --- a/src/main/resources/assets/appliedenergistics2/lang/zh_cn.lang +++ b/src/main/resources/assets/appliedenergistics2/lang/zh_cn.lang @@ -258,6 +258,12 @@ gui.appliedenergistics2.CraftingToastDone=合成已完成! gui.appliedenergistics2.CraftingToastCancelled=合成已取消! gui.appliedenergistics2.Sticky=粘滞 gui.appliedenergistics2.FluidTerminal=流体终端 +gui.appliedenergistics2.NoneLock=合成已解锁 +gui.appliedenergistics2.CraftingLock=合成已锁定 +gui.appliedenergistics2.LowRedstoneLock=由于缺少红石信号而锁定 +gui.appliedenergistics2.HighRedstoneLock=由于红石信号而锁定 +gui.appliedenergistics2.ResultLock=等待样板输出解锁 +gui.appliedenergistics2.UntilPulseUnlock=等待红石脉冲解锁 gui.appliedenergistics2.CanBeEnchanted=可被附魔 gui.appliedenergistics2.IncreasedEnergyUseFromEnchants=附魔会增加能耗 gui.appliedenergistics2.Deprecated=已弃用