From a231e671672cf314e18b5e0cb09f5cfcd37d659c Mon Sep 17 00:00:00 2001 From: Jakub <53441451+kuba6000@users.noreply.github.com> Date: Fri, 22 Mar 2024 17:05:44 +0100 Subject: [PATCH] Add full pattern optimizer support to dual interface and wireless terminal (#200) * New buttons in dual interface + wireless terminal fix * Update dependencies.gradle --- .../github/client/gui/GuiDualInterface.java | 69 +++++++++++++++++-- .../client/gui/GuiFluidOptimizePatterns.java | 49 +++++++++++++ .../container/ContainerFluidCraftConfirm.java | 36 ++++++++++ .../ContainerFluidOptimizePatterns.java | 69 +++++++++++++++++++ .../github/inventory/gui/GuiType.java | 28 ++++++++ .../com/glodblock/github/util/Ae2Reflect.java | 18 +++++ 6 files changed, 263 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/glodblock/github/client/gui/GuiFluidOptimizePatterns.java create mode 100644 src/main/java/com/glodblock/github/client/gui/container/ContainerFluidOptimizePatterns.java diff --git a/src/main/java/com/glodblock/github/client/gui/GuiDualInterface.java b/src/main/java/com/glodblock/github/client/gui/GuiDualInterface.java index e8fcf374..337c0838 100644 --- a/src/main/java/com/glodblock/github/client/gui/GuiDualInterface.java +++ b/src/main/java/com/glodblock/github/client/gui/GuiDualInterface.java @@ -4,6 +4,7 @@ import net.minecraft.client.gui.GuiButton; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.util.StatCollector; +import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; import com.glodblock.github.client.gui.container.ContainerDualInterface; @@ -24,12 +25,16 @@ import appeng.api.config.Upgrades; import appeng.api.config.YesNo; import appeng.client.gui.implementations.GuiUpgradeable; import appeng.client.gui.widgets.GuiImgButton; +import appeng.client.gui.widgets.GuiSimpleImgButton; import appeng.client.gui.widgets.GuiTabButton; import appeng.client.gui.widgets.GuiToggleButton; import appeng.container.implementations.ContainerInterface; +import appeng.core.AELog; +import appeng.core.localization.ButtonToolTips; import appeng.core.localization.GuiText; import appeng.core.sync.network.NetworkHandler; import appeng.core.sync.packets.PacketConfigButton; +import appeng.core.sync.packets.PacketValueConfig; import appeng.helpers.IInterfaceHost; public class GuiDualInterface extends GuiUpgradeable { @@ -40,6 +45,8 @@ public class GuiDualInterface extends GuiUpgradeable { private GuiToggleButton interfaceMode; private GuiImgButton insertionMode; private GuiImgButton sidelessMode; + private GuiSimpleImgButton doublePatterns; + private GuiToggleButton patternOptimization; private GuiImgButton advancedBlockingMode; private GuiImgButton lockCraftingMode; private final IInterfaceHost host; @@ -70,45 +77,74 @@ public class GuiDualInterface extends GuiUpgradeable { itemRender); this.buttonList.add(this.switcher); - this.BlockMode = new GuiImgButton(this.guiLeft - 18, this.guiTop + 8, Settings.BLOCK, YesNo.NO); + int offset = 8; + + this.BlockMode = new GuiImgButton(this.guiLeft - 18, this.guiTop + offset, Settings.BLOCK, YesNo.NO); this.buttonList.add(this.BlockMode); + offset += 18; + this.interfaceMode = new GuiToggleButton( this.guiLeft - 18, - this.guiTop + 26, + this.guiTop + offset, 84, 85, GuiText.InterfaceTerminal.getLocal(), GuiText.InterfaceTerminalHint.getLocal()); this.buttonList.add(this.interfaceMode); + offset += 18; + this.insertionMode = new GuiImgButton( this.guiLeft - 18, - this.guiTop + 44, + this.guiTop + offset, Settings.INSERTION_MODE, InsertionMode.DEFAULT); this.buttonList.add(this.insertionMode); + offset += 18; + + this.doublePatterns = new GuiSimpleImgButton(this.guiLeft - 18, this.guiTop + offset, 71, ""); + this.doublePatterns.enabled = false; + this.buttonList.add(this.doublePatterns); + + offset += 18; + + this.patternOptimization = new GuiToggleButton( + this.guiLeft - 18, + this.guiTop + offset, + 178, + 194, + GuiText.PatternOptimization.getLocal(), + GuiText.PatternOptimizationHint.getLocal()); + this.buttonList.add(this.patternOptimization); + + offset += 18; + this.advancedBlockingMode = new GuiImgButton( this.guiLeft - 18, - this.guiTop + 62, + this.guiTop + offset, Settings.ADVANCED_BLOCKING_MODE, AdvancedBlockingMode.DEFAULT); this.buttonList.add(this.advancedBlockingMode); this.advancedBlockingMode.visible = this.bc.getInstalledUpgrades(Upgrades.ADVANCED_BLOCKING) > 0; + offset += 18; + if (isTile()) { this.sidelessMode = new GuiImgButton( this.guiLeft - 18, - this.guiTop + 80, + this.guiTop + offset, Settings.SIDELESS_MODE, SidelessMode.SIDELESS); this.buttonList.add(this.sidelessMode); + + offset += 18; } this.lockCraftingMode = new GuiImgButton( this.guiLeft - 18, - this.guiTop + 98, + this.guiTop + offset, Settings.LOCK_CRAFTING_MODE, LockCraftingMode.NONE); this.lockCraftingMode.visible = this.bc.getInstalledUpgrades(Upgrades.LOCK_CRAFTING) > 0; @@ -127,6 +163,16 @@ public class GuiDualInterface extends GuiUpgradeable { if (this.insertionMode != null) { this.insertionMode.set(((ContainerInterface) this.cvb).getInsertionMode()); } + if (this.doublePatterns != null) { + this.doublePatterns.enabled = ((ContainerInterface) this.cvb).isAllowedToMultiplyPatterns; + if (this.doublePatterns.enabled) this.doublePatterns.setTooltip( + ButtonToolTips.DoublePatterns.getLocal() + "\n" + ButtonToolTips.DoublePatternsHint.getLocal()); + else this.doublePatterns.setTooltip( + ButtonToolTips.DoublePatterns.getLocal() + "\n" + ButtonToolTips.OptimizePatternsNoReq.getLocal()); + } + if (this.patternOptimization != null) { + this.patternOptimization.setState(((ContainerInterface) this.cvb).getPatternOptimization() == YesNo.YES); + } if (this.sidelessMode != null) { this.sidelessMode.set(((ContainerDualInterface) this.cvb).getSidelessMode()); } @@ -169,6 +215,17 @@ public class GuiDualInterface extends GuiUpgradeable { NetworkHandler.instance.sendToServer(new PacketConfigButton(this.BlockMode.getSetting(), backwards)); } else if (btn == this.insertionMode) { NetworkHandler.instance.sendToServer(new PacketConfigButton(this.insertionMode.getSetting(), backwards)); + } else if (btn == this.doublePatterns) { + try { + int val = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) ? 1 : 0; + if (backwards) val |= 0b10; + NetworkHandler.instance + .sendToServer(new PacketValueConfig("Interface.DoublePatterns", String.valueOf(val))); + } catch (final Throwable e) { + AELog.debug(e); + } + } else if (btn == this.patternOptimization) { + NetworkHandler.instance.sendToServer(new PacketConfigButton(Settings.PATTERN_OPTIMIZATION, backwards)); } else if (btn == this.sidelessMode) { NetworkHandler.instance.sendToServer(new PacketConfigButton(this.sidelessMode.getSetting(), backwards)); } else if (btn == this.advancedBlockingMode) { diff --git a/src/main/java/com/glodblock/github/client/gui/GuiFluidOptimizePatterns.java b/src/main/java/com/glodblock/github/client/gui/GuiFluidOptimizePatterns.java new file mode 100644 index 00000000..ddd97789 --- /dev/null +++ b/src/main/java/com/glodblock/github/client/gui/GuiFluidOptimizePatterns.java @@ -0,0 +1,49 @@ +package com.glodblock.github.client.gui; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.entity.player.InventoryPlayer; + +import com.glodblock.github.common.item.ItemWirelessUltraTerminal; +import com.glodblock.github.common.parts.PartFluidPatternTerminal; +import com.glodblock.github.common.parts.PartFluidPatternTerminalEx; +import com.glodblock.github.common.parts.PartLevelTerminal; +import com.glodblock.github.inventory.InventoryHandler; +import com.glodblock.github.inventory.gui.GuiType; +import com.glodblock.github.inventory.item.IWirelessTerminal; +import com.glodblock.github.inventory.item.WirelessLevelTerminalInventory; +import com.glodblock.github.inventory.item.WirelessPatternTerminalInventory; + +import appeng.api.storage.ITerminalHost; +import appeng.client.gui.implementations.GuiOptimizePatterns; +import appeng.core.localization.GuiText; + +public class GuiFluidOptimizePatterns extends GuiOptimizePatterns { + + private GuiType originalGui; + + public GuiFluidOptimizePatterns(InventoryPlayer inventoryPlayer, ITerminalHost te) { + super(inventoryPlayer, te); + if (te instanceof PartFluidPatternTerminal) { + this.originalGui = GuiType.FLUID_PATTERN_TERMINAL; + } else if (te instanceof PartFluidPatternTerminalEx) { + this.originalGui = GuiType.FLUID_PATTERN_TERMINAL_EX; + } else if (te instanceof PartLevelTerminal) { + originalGui = GuiType.LEVEL_TERMINAL; + } else if (te instanceof IWirelessTerminal terminal && terminal.isUniversal(te)) { + this.originalGui = ItemWirelessUltraTerminal.readMode(terminal.getItemStack()); + } else if (te instanceof WirelessPatternTerminalInventory) { + this.originalGui = GuiType.FLUID_TERMINAL; + } else if (te instanceof WirelessLevelTerminalInventory) { + originalGui = GuiType.WIRELESS_LEVEL_TERMINAL; + } + } + + @Override + protected void actionPerformed(GuiButton btn) { + if (btn.displayString.equals(GuiText.Cancel.getLocal())) { + InventoryHandler.switchGui(originalGui); + return; + } + super.actionPerformed(btn); + } +} diff --git a/src/main/java/com/glodblock/github/client/gui/container/ContainerFluidCraftConfirm.java b/src/main/java/com/glodblock/github/client/gui/container/ContainerFluidCraftConfirm.java index 878cd9f4..f4509f6c 100644 --- a/src/main/java/com/glodblock/github/client/gui/container/ContainerFluidCraftConfirm.java +++ b/src/main/java/com/glodblock/github/client/gui/container/ContainerFluidCraftConfirm.java @@ -13,11 +13,17 @@ import com.glodblock.github.common.parts.PartLevelTerminal; import com.glodblock.github.inventory.InventoryHandler; import com.glodblock.github.inventory.gui.GuiType; import com.glodblock.github.inventory.item.IWirelessTerminal; +import com.glodblock.github.util.Ae2Reflect; import com.glodblock.github.util.BlockPos; +import appeng.api.networking.IGrid; +import appeng.api.networking.crafting.ICraftingJob; import appeng.api.networking.security.IActionHost; import appeng.api.storage.ITerminalHost; import appeng.container.implementations.ContainerCraftConfirm; +import appeng.container.implementations.ContainerOptimizePatterns; +import appeng.crafting.v2.CraftingJobV2; +import appeng.tile.misc.TilePatternOptimizationMatrix; public class ContainerFluidCraftConfirm extends ContainerCraftConfirm { @@ -61,4 +67,34 @@ public class ContainerFluidCraftConfirm extends ContainerCraftConfirm { originalGui); } } + + @Override + public void optimizePatterns() { + // only V2 supported + IGrid grid = Ae2Reflect.getGrid(this); + ICraftingJob result = Ae2Reflect.getResult(this); + if (result instanceof CraftingJobV2 && !this.isSimulation() + && grid != null + && !grid.getMachines(TilePatternOptimizationMatrix.class).isEmpty()) { + final IActionHost ah = this.getActionHost(); + if (ah instanceof IWirelessTerminal) { + InventoryHandler.openGui( + this.getInventoryPlayer().player, + getWorld(), + new BlockPos(((IWirelessTerminal) ah).getInventorySlot(), 0, 0), + ForgeDirection.UNKNOWN, + GuiType.FLUID_OPTIMIZE_PATTERNS_ITEM); + } else if (this.getOpenContext() != null) { + InventoryHandler.openGui( + this.getInventoryPlayer().player, + getWorld(), + new BlockPos(this.getOpenContext().getTile()), + Objects.requireNonNull(this.getOpenContext().getSide()), + GuiType.FLUID_OPTIMIZE_PATTERNS); + } + if (this.getPlayerInv().player.openContainer instanceof ContainerOptimizePatterns cop) { + cop.setResult(result); + } + } + } } diff --git a/src/main/java/com/glodblock/github/client/gui/container/ContainerFluidOptimizePatterns.java b/src/main/java/com/glodblock/github/client/gui/container/ContainerFluidOptimizePatterns.java new file mode 100644 index 00000000..dbe7654d --- /dev/null +++ b/src/main/java/com/glodblock/github/client/gui/container/ContainerFluidOptimizePatterns.java @@ -0,0 +1,69 @@ +package com.glodblock.github.client.gui.container; + +import java.util.Objects; + +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +import com.glodblock.github.common.item.ItemBaseWirelessTerminal; +import com.glodblock.github.common.parts.PartFluidPatternTerminal; +import com.glodblock.github.common.parts.PartFluidPatternTerminalEx; +import com.glodblock.github.common.parts.PartLevelTerminal; +import com.glodblock.github.inventory.InventoryHandler; +import com.glodblock.github.inventory.gui.GuiType; +import com.glodblock.github.inventory.item.IWirelessTerminal; +import com.glodblock.github.util.BlockPos; + +import appeng.api.networking.security.IActionHost; +import appeng.api.storage.ITerminalHost; +import appeng.container.implementations.ContainerOptimizePatterns; + +public class ContainerFluidOptimizePatterns extends ContainerOptimizePatterns { + + public ContainerFluidOptimizePatterns(InventoryPlayer ip, ITerminalHost te) { + super(ip, te); + } + + public World getWorld() { + return this.getPlayerInv().player.worldObj; + } + + @Override + public void switchToOriginalGUI() { + GuiType originalGui = null; + + final IActionHost ah = this.getActionHost(); + if (ah instanceof PartFluidPatternTerminal) { + originalGui = GuiType.FLUID_PATTERN_TERMINAL; + } + if (ah instanceof PartFluidPatternTerminalEx) { + originalGui = GuiType.FLUID_PATTERN_TERMINAL_EX; + } + if (ah instanceof PartLevelTerminal) { + originalGui = GuiType.LEVEL_TERMINAL; + } + if (ah instanceof IWirelessTerminal) { + ItemStack terminal = ((IWirelessTerminal) ah).getItemStack(); + if (terminal.getItem() instanceof ItemBaseWirelessTerminal) { + originalGui = ((ItemBaseWirelessTerminal) terminal.getItem()).guiGuiType(terminal); + } + } + if (ah instanceof IWirelessTerminal) { + InventoryHandler.openGui( + this.getInventoryPlayer().player, + getWorld(), + new BlockPos(((IWirelessTerminal) ah).getInventorySlot(), 0, 0), + ForgeDirection.UNKNOWN, + originalGui); + } else if (this.getOpenContext() != null) { + InventoryHandler.openGui( + this.getInventoryPlayer().player, + getWorld(), + new BlockPos(this.getOpenContext().getTile()), + Objects.requireNonNull(this.getOpenContext().getSide()), + originalGui); + } + } +} 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 45bd8593..824aaaed 100644 --- a/src/main/java/com/glodblock/github/inventory/gui/GuiType.java +++ b/src/main/java/com/glodblock/github/inventory/gui/GuiType.java @@ -17,6 +17,7 @@ import com.glodblock.github.client.gui.GuiFluidCraftingWireless; import com.glodblock.github.client.gui.GuiFluidIO; import com.glodblock.github.client.gui.GuiFluidInterface; import com.glodblock.github.client.gui.GuiFluidLevelEmitter; +import com.glodblock.github.client.gui.GuiFluidOptimizePatterns; import com.glodblock.github.client.gui.GuiFluidPacketDecoder; import com.glodblock.github.client.gui.GuiFluidPatternEncoder; import com.glodblock.github.client.gui.GuiFluidPatternExWireless; @@ -44,6 +45,7 @@ import com.glodblock.github.client.gui.container.ContainerFluidIO; import com.glodblock.github.client.gui.container.ContainerFluidInterface; import com.glodblock.github.client.gui.container.ContainerFluidLevelEmitter; import com.glodblock.github.client.gui.container.ContainerFluidMonitor; +import com.glodblock.github.client.gui.container.ContainerFluidOptimizePatterns; import com.glodblock.github.client.gui.container.ContainerFluidPacketDecoder; import com.glodblock.github.client.gui.container.ContainerFluidPatternEncoder; import com.glodblock.github.client.gui.container.ContainerFluidPatternExWireless; @@ -447,6 +449,32 @@ public enum GuiType { } }), + FLUID_OPTIMIZE_PATTERNS(new PartGuiFactory<>(FCPart.class) { + + @Override + protected Object createServerGui(EntityPlayer player, FCPart inv) { + return new ContainerFluidOptimizePatterns(player.inventory, inv); + } + + @Override + protected Object createClientGui(EntityPlayer player, FCPart inv) { + return new GuiFluidOptimizePatterns(player.inventory, inv); + } + }), + + FLUID_OPTIMIZE_PATTERNS_ITEM(new ItemGuiFactory<>(IWirelessTerminal.class) { + + @Override + protected Object createServerGui(EntityPlayer player, IWirelessTerminal inv) { + return new ContainerFluidOptimizePatterns(player.inventory, inv); + } + + @Override + protected Object createClientGui(EntityPlayer player, IWirelessTerminal inv) { + return new GuiFluidOptimizePatterns(player.inventory, inv); + } + }), + FLUID_CRAFTING_AMOUNT(new PartOrItemGuiFactory<>(ITerminalHost.class) { @Override diff --git a/src/main/java/com/glodblock/github/util/Ae2Reflect.java b/src/main/java/com/glodblock/github/util/Ae2Reflect.java index c6052780..d6b39e41 100644 --- a/src/main/java/com/glodblock/github/util/Ae2Reflect.java +++ b/src/main/java/com/glodblock/github/util/Ae2Reflect.java @@ -9,10 +9,12 @@ import net.minecraftforge.fluids.IFluidHandler; import appeng.api.implementations.IUpgradeableHost; import appeng.api.networking.IGrid; import appeng.api.networking.crafting.ICraftingCPU; +import appeng.api.networking.crafting.ICraftingJob; import appeng.api.networking.security.BaseActionSource; import appeng.api.networking.security.MachineSource; import appeng.api.storage.IMEInventory; import appeng.api.storage.data.IAEItemStack; +import appeng.container.implementations.ContainerCraftConfirm; import appeng.container.implementations.ContainerUpgradeable; import appeng.container.implementations.CraftingCPURecord; import appeng.crafting.MECraftingInventory; @@ -38,11 +40,13 @@ public class Ae2Reflect { private static final Field fCPU_machineSrc; private static final Field fContainerUpgradeable_upgradeable; private static final Field fDualInterface_gridProxy; + private static final Field fCraftConfirm_result; private static final Method mItemSlot_setExtractable; private static final Method mCPU_getGrid; private static final Method mCPU_postChange; private static final Method mCPU_markDirty; private static final Method mP2PLiquids_getTarget; + private static final Method mCraftConfirm_getGrid; static { try { @@ -66,6 +70,8 @@ public class Ae2Reflect { BaseActionSource.class); mCPU_markDirty = reflectMethod(CraftingCPUCluster.class, "markDirty"); mP2PLiquids_getTarget = reflectMethod(PartP2PLiquids.class, "getTarget"); + fCraftConfirm_result = reflectField(ContainerCraftConfirm.class, "result"); + mCraftConfirm_getGrid = reflectMethod(ContainerCraftConfirm.class, "getGrid"); } catch (Exception e) { throw new IllegalStateException("Failed to initialize AE2 reflection hacks!", e); } @@ -154,6 +160,18 @@ public class Ae2Reflect { } } + public static IGrid getGrid(ContainerCraftConfirm ccc) { + try { + return (IGrid) mCraftConfirm_getGrid.invoke(ccc); + } catch (Exception e) { + throw new IllegalStateException("Failed to invoke method: " + mCPU_getGrid, e); + } + } + + public static ICraftingJob getResult(ContainerCraftConfirm ccc) { + return Ae2Reflect.readField(ccc, fCraftConfirm_result); + } + public static MECraftingInventory getCPUInventory(CraftingCPUCluster cpu) { return Ae2Reflect.readField(cpu, fCPU_inventory); }