diff --git a/libs/ExtendedAE-1.20-1.1.12-forge.jar b/libs/ExtendedAE-1.20-1.1.12-forge.jar new file mode 100644 index 0000000..067194a Binary files /dev/null and b/libs/ExtendedAE-1.20-1.1.12-forge.jar differ diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/AEBaseScreenMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/AEBaseScreenMixin.java index b741be3..70169aa 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/AEBaseScreenMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/AEBaseScreenMixin.java @@ -40,6 +40,38 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(AEBaseScreen.class) public abstract class AEBaseScreenMixin { + @Unique + private static int eap$getIntField(Object self, String name, int def) { + Class c = self.getClass(); + while (c != null && c != Object.class) { + try { + var f = c.getDeclaredField(name); + f.setAccessible(true); + Object v = f.get(self); + if (v instanceof Integer i) return i; + } catch (Throwable ignored) { + } + c = c.getSuperclass(); + } + return def; + } + + @Unique + private static Font eap$getFont(Object self) { + Class c = self.getClass(); + while (c != null && c != Object.class) { + try { + var f = c.getDeclaredField("font"); + f.setAccessible(true); + Object v = f.get(self); + if (v instanceof Font font) return font; + } catch (Throwable ignored) { + } + c = c.getSuperclass(); + } + return net.minecraft.client.Minecraft.getInstance().font; + } + @Unique private ScreenStyle eap$getStyle(Object self) { try { @@ -47,7 +79,8 @@ public abstract class AEBaseScreenMixin { f.setAccessible(true); Object v = f.get(self); if (v instanceof ScreenStyle s) return s; - } catch (Throwable ignored) {} + } catch (Throwable ignored) { + } return null; } @@ -78,7 +111,8 @@ public abstract class AEBaseScreenMixin { // Debug: 标记一次发送 try { LogUtils.getLogger().info("EAP: Send CraftingMonitorJumpC2SPacket: {}", key); - } catch (Throwable ignored2) {} + } catch (Throwable ignored2) { + } ModNetwork.CHANNEL.sendToServer(new CraftingMonitorJumpC2SPacket(key)); cir.setReturnValue(true); } catch (Throwable ignored) { @@ -112,43 +146,14 @@ public abstract class AEBaseScreenMixin { // Debug: 标记一次发送(打开供应器UI) try { LogUtils.getLogger().info("EAP: Send CraftingMonitorOpenProviderC2SPacket: {}", key); - } catch (Throwable ignored2) {} + } catch (Throwable ignored2) { + } ModNetwork.CHANNEL.sendToServer(new CraftingMonitorOpenProviderC2SPacket(key)); cir.setReturnValue(true); } catch (Throwable ignored) { } } - @Unique - private static int eap$getIntField(Object self, String name, int def) { - Class c = self.getClass(); - while (c != null && c != Object.class) { - try { - var f = c.getDeclaredField(name); - f.setAccessible(true); - Object v = f.get(self); - if (v instanceof Integer i) return i; - } catch (Throwable ignored) {} - c = c.getSuperclass(); - } - return def; - } - - @Unique - private static Font eap$getFont(Object self) { - Class c = self.getClass(); - while (c != null && c != Object.class) { - try { - var f = c.getDeclaredField("font"); - f.setAccessible(true); - Object v = f.get(self); - if (v instanceof Font font) return font; - } catch (Throwable ignored) {} - c = c.getSuperclass(); - } - return net.minecraft.client.Minecraft.getInstance().font; - } - /** * 重写renderSlot方法,为所有可见的样板槽位添加数量显示 */ @@ -184,17 +189,14 @@ public abstract class AEBaseScreenMixin { try { var details = PatternDetailsHelper.decodePattern(itemStack, Minecraft.getInstance().level, false); - try { - if (details != null && details.getOutputs() != null && details.getOutputs().length > 0) { - AEKey key = details.getOutputs()[0].what(); - if (key != null && ClientPatternHighlightStore.hasHighlight(key)) { - try { - GuiUtil.drawSlotRainbowHighlight(guiGraphics, s.x, s.y); - } catch (Throwable ignored) {} - } + if (details != null && details.getOutputs() != null && details.getOutputs().length > 0) { + AEKey key = details.getOutputs()[0].what(); + if (key != null && ClientPatternHighlightStore.hasHighlight(key)) { + GuiUtil.drawSlotRainbowHighlight(guiGraphics, s.x, s.y); } - } catch (Throwable ignore) {} - } catch (Throwable ignore) {} + } + } catch (Throwable ignore) { + } } // 在 AEBaseScreen.drawText 完成某个文本绘制后,若该文本为“样板”标签,则紧接着绘制页码。 @@ -313,18 +315,22 @@ public abstract class AEBaseScreenMixin { @Shadow - protected void setTextContent(String id, Component content) {}; + protected void setTextContent(String id, Component content) { + } + + ; @Inject(method = "updateBeforeRender", at = @At("RETURN"), remap = false) private void onUpdateBeforeRender(CallbackInfo ci) { try { AEBaseScreen self = (AEBaseScreen) (Object) this; - if (self instanceof PatternProviderScreen screen){ + if (self instanceof PatternProviderScreen screen) { Component t = screen.getTitle(); if (t != null && !t.getString().isEmpty()) { this.setTextContent(AEBaseScreen.TEXT_ID_DIALOG_TITLE, t); } } - } catch (Throwable ignored) {} + } catch (Throwable ignored) { + } } } diff --git a/src/main/java/com/extendedae_plus/mixin/gtceu/AEPatternViewSlotWidgetMixin.java b/src/main/java/com/extendedae_plus/mixin/gtceu/AEPatternViewSlotWidgetMixin.java new file mode 100644 index 0000000..9ab8018 --- /dev/null +++ b/src/main/java/com/extendedae_plus/mixin/gtceu/AEPatternViewSlotWidgetMixin.java @@ -0,0 +1,54 @@ +package com.extendedae_plus.mixin.gtceu; + +import appeng.api.crafting.PatternDetailsHelper; +import appeng.api.stacks.AEKey; +import com.extendedae_plus.content.ClientPatternHighlightStore; +import com.extendedae_plus.util.GuiUtil; +import com.gregtechceu.gtceu.integration.ae2.gui.widget.slot.AEPatternViewSlotWidget; +import com.lowdragmc.lowdraglib.gui.widget.SlotWidget; +import com.lowdragmc.lowdraglib.utils.Position; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@OnlyIn(Dist.CLIENT) +@Mixin(value = AEPatternViewSlotWidget.class, remap = false) +public abstract class AEPatternViewSlotWidgetMixin { + + /** + * 在 AEPatternViewSlotWidget.drawBackgroundTexture(...) 尾部注入绘制数字逻辑 + */ + @Inject(method = "drawBackgroundTexture", at = @At("TAIL")) + private void onDrawInBackgroundTail(GuiGraphics graphics, int mouseX, int mouseY, CallbackInfo ci) { + if (!AEPatternViewSlotWidget.class.isInstance(this)) return; + // 把 this 强转为 SlotWidget(目标类继承自 SlotWidget) + SlotWidget self = (SlotWidget) (Object) this; + + Slot handler = self.getHandler(); + if (handler == null) return; + + // 使用 getRealStack 来尊重 setItemHook 的渲染替换 + ItemStack displayStack = self.getRealStack(handler.getItem()); + if (displayStack == null || displayStack.isEmpty()) return; + + ItemStack stack = handler.getItem(); + Position pos = self.getPosition(); // 来自 Widget 的方法,继承可用 + try { + var details = PatternDetailsHelper.decodePattern(stack, Minecraft.getInstance().level, false); + if (details != null && details.getOutputs() != null && details.getOutputs().length > 0) { + AEKey key = details.getOutputs()[0].what(); + if (key != null && ClientPatternHighlightStore.hasHighlight(key)) { + GuiUtil.drawSlotRainbowHighlight(graphics, pos.x + 1, pos.y + 1); + } + } + } catch (Throwable ignore) { + } + } +} \ No newline at end of file diff --git a/src/main/java/com/extendedae_plus/mixin/gtceu/ModularUIContainerCloseMixin.java b/src/main/java/com/extendedae_plus/mixin/gtceu/ModularUIContainerCloseMixin.java new file mode 100644 index 0000000..cfebe95 --- /dev/null +++ b/src/main/java/com/extendedae_plus/mixin/gtceu/ModularUIContainerCloseMixin.java @@ -0,0 +1,19 @@ +package com.extendedae_plus.mixin.gtceu; + +import com.extendedae_plus.content.ClientPatternHighlightStore; +import com.lowdragmc.lowdraglib.gui.modular.ModularUIContainer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(value = ModularUIContainer.class, remap = false) +public class ModularUIContainerCloseMixin { + + @Inject(method = "removed", at = @At("HEAD")) + private void onRemoved(CallbackInfo ci) { + try { + ClientPatternHighlightStore.clearAll(); + } catch (Throwable ignored) {} + } +} \ No newline at end of file diff --git a/src/main/java/com/extendedae_plus/mixin/gtceu/SlotWidgetMixin.java b/src/main/java/com/extendedae_plus/mixin/gtceu/SlotWidgetMixin.java new file mode 100644 index 0000000..82e45f3 --- /dev/null +++ b/src/main/java/com/extendedae_plus/mixin/gtceu/SlotWidgetMixin.java @@ -0,0 +1,61 @@ +package com.extendedae_plus.mixin.gtceu; + +import com.extendedae_plus.util.GuiUtil; +import com.gregtechceu.gtceu.integration.ae2.gui.widget.slot.AEPatternViewSlotWidget; +import com.lowdragmc.lowdraglib.gui.util.DrawerHelper; +import com.lowdragmc.lowdraglib.gui.widget.SlotWidget; +import com.lowdragmc.lowdraglib.utils.Position; +import com.lowdragmc.lowdraglib.utils.Size; +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + + +@OnlyIn(Dist.CLIENT) +@Mixin(value = SlotWidget.class, remap = false) +public abstract class SlotWidgetMixin { + /** + * 在 SlotWidget.drawInBackground(...) 尾部注入绘制数字逻辑 + */ + @Inject(method = "drawInBackground(Lnet/minecraft/client/gui/GuiGraphics;IIF)V", at = @At("TAIL")) + private void onDrawInBackgroundTail(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks, CallbackInfo ci) { + if (!AEPatternViewSlotWidget.class.isInstance(this)) return; + // 把 this 强转为 SlotWidget(目标类继承自 SlotWidget) + SlotWidget self = (SlotWidget) (Object) this; + + Slot handler = self.getHandler(); + if (handler == null) return; + + // 使用 getRealStack 来尊重 setItemHook 的渲染替换 + ItemStack displayStack = self.getRealStack(handler.getItem()); + if (displayStack == null || displayStack.isEmpty()) return; + + ItemStack stack = handler.getItem(); + + String patternOutputText = GuiUtil.getPatternOutputText(stack); + + Position pos = self.getPosition(); // 来自 Widget 的方法,继承可用 + Size size = self.getSize(); // 同上 + + graphics.pose().pushPose(); + graphics.pose().translate(0.0F, 0.0F, 300.0F); + RenderSystem.disableDepthTest(); + DrawerHelper.drawStringFixedCorner( + graphics, + patternOutputText, + pos.x + size.width, + pos.y + size.height, + 0xFFFFFFFF, + true, + 0.75f); + RenderSystem.enableDepthTest(); + graphics.pose().popPose(); + } +} \ No newline at end of file diff --git a/src/main/java/com/extendedae_plus/network/CraftingMonitorOpenProviderC2SPacket.java b/src/main/java/com/extendedae_plus/network/CraftingMonitorOpenProviderC2SPacket.java index 6680f2f..76e38ba 100644 --- a/src/main/java/com/extendedae_plus/network/CraftingMonitorOpenProviderC2SPacket.java +++ b/src/main/java/com/extendedae_plus/network/CraftingMonitorOpenProviderC2SPacket.java @@ -15,6 +15,8 @@ import com.extendedae_plus.mixin.ae2.accessor.PatternProviderLogicAccessor; import com.extendedae_plus.util.PatternProviderDataUtil; import com.glodblock.github.extendedae.util.FCClientUtil; import com.glodblock.github.glodium.util.GlodUtil; +import com.gregtechceu.gtceu.api.gui.factory.MachineUIFactory; +import com.gregtechceu.gtceu.api.machine.MetaMachine; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.network.FriendlyByteBuf; @@ -133,6 +135,41 @@ public class CraftingMonitorOpenProviderC2SPacket { return; } catch (Exception ignored) { } + } else if (provider instanceof com.gregtechceu.gtceu.integration.ae2.machine.MEPatternBufferPartMachine machine) { + // 处理 MEPatternBufferPartMachine:打开其界面并高亮位置,尽量反射获取槽位页码 + try { + BlockPos pos = machine.getPos(); + Level level = machine.getLevel(); + if (pos == null || level == null) continue; + if (!level.isClientSide) { // 确保在服务器端执行 + MachineUIFactory.INSTANCE.openUI(MetaMachine.getMachine(level, pos), player); + } + + // 最后发送高亮包,保证界面已打开 + if (pattern.getOutputs() != null && pattern.getOutputs().length > 0 && pattern.getOutputs()[0] != null) { + AEKey key = pattern.getOutputs()[0].what(); + ModNetwork.CHANNEL.sendTo(new SetPatternHighlightS2CPacket(key, true), player.connection.connection, NetworkDirection.PLAY_TO_CLIENT); + } + + } catch (Exception ignored) { + } + } else if (provider instanceof org.gtlcore.gtlcore.common.machine.multiblock.part.ae.MEPatternBufferPartMachine machine) { + // 处理 MEPatternBufferPartMachine:打开其界面并高亮位置,尽量反射获取槽位页码 + try { + BlockPos pos = machine.getPos(); + Level level = machine.getLevel(); + if (pos == null || level == null) continue; + if (!level.isClientSide) { // 确保在服务器端执行 + MachineUIFactory.INSTANCE.openUI(MetaMachine.getMachine(level, pos), player); + } + + // 最后发送高亮包,保证界面已打开 + if (pattern.getOutputs() != null && pattern.getOutputs().length > 0 && pattern.getOutputs()[0] != null) { + AEKey key = pattern.getOutputs()[0].what(); + ModNetwork.CHANNEL.sendTo(new SetPatternHighlightS2CPacket(key, true), player.connection.connection, NetworkDirection.PLAY_TO_CLIENT); + } + } catch (Exception ignored) { + } } } } diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 42a1ca5..47b794c 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -28,7 +28,7 @@ side = "BOTH" [[dependencies.extendedae_plus]] modId = "expatternprovider" mandatory = true -versionRange = "[1.20-1.4.0-forge,)" +versionRange = "[1.20-1.1.12-forge,)" ordering = "AFTER" side = "BOTH" diff --git a/src/main/resources/extendedae_plus.mixins.json b/src/main/resources/extendedae_plus.mixins.json index 5314e85..07c1a58 100644 --- a/src/main/resources/extendedae_plus.mixins.json +++ b/src/main/resources/extendedae_plus.mixins.json @@ -23,6 +23,8 @@ "extendedae.client.HighlightButtonMixin", "extendedae.client.gui.GuiExPatternProviderMixin", "extendedae.client.gui.GuiExPatternTerminalMixin", + "gtceu.AEPatternViewSlotWidgetMixin", + "gtceu.SlotWidgetMixin", "hooks.ModelBakeryMixin", "jei.EncodePatternTransferHandlerMixin", "jei.EncodingHelperMixin", @@ -56,7 +58,8 @@ "extendedae.common.TileExPatternProviderMixin", "extendedae.container.ContainerExPatternProviderMixin", "extendedae.container.ContainerExPatternTerminalMixin", - "extendedae.container.ContainerWirelessExPatternTerminalMixin" + "extendedae.container.ContainerWirelessExPatternTerminalMixin", + "gtceu.ModularUIContainerCloseMixin" ], "injectors": { "defaultRequire": 1