diff --git a/build.gradle b/build.gradle index cbb9f40..bba57a0 100644 --- a/build.gradle +++ b/build.gradle @@ -139,12 +139,12 @@ dependencies { implementation "curse.maven:curios-309927:6529130" compileOnly "curse.maven:ex-pattern-provider-892005:6863556" - implementation "curse.maven:applied-flux-965012:5614830" + compileOnly "curse.maven:applied-flux-965012:5614830" compileOnly "dev.emi:emi-neoforge:1.1.10+1.21" compileOnly "curse.maven:mega-cells-622112:6005043" compileOnly "curse.maven:jade-324717:5427817" compileOnly "me.shedaniel:RoughlyEnoughItems-neoforge:16.0.729" - // compileOnly "mekanism:Mekanism:1.21.1-10.7.0.55" + compileOnly "mekanism:Mekanism:1.21.1-10.7.0.55" compileOnly "curse.maven:applied-mekanistics-574300:5978711" compileOnly "dev.latvian.mods:kubejs-neoforge:2101.7.1-build.188" compileOnly "dev.latvian.mods:rhino:2101.2.5-build.54" @@ -155,7 +155,7 @@ dependencies { compileOnly "curse.maven:ae2-jei-integration-1074338:5748513" // runtime test - runtimeOnly "curse.maven:applied-flux-965012:5614830" + //runtimeOnly "curse.maven:applied-flux-965012:5614830" runtimeOnly "de.mari_023:ae2wtlib:19.2.1" runtimeOnly "curse.maven:jade-324717:5427817" runtimeOnly "curse.maven:mega-cells-622112:6005043" diff --git a/src/main/java/com/extendedae_plus/compat/AppliedFluxCompat.java b/src/main/java/com/extendedae_plus/compat/AppliedFluxCompat.java new file mode 100644 index 0000000..651f5be --- /dev/null +++ b/src/main/java/com/extendedae_plus/compat/AppliedFluxCompat.java @@ -0,0 +1,41 @@ +package com.extendedae_plus.compat; + +import appeng.client.gui.implementations.PatternProviderScreen; +import appeng.client.gui.widgets.UpgradesPanel; +import com.extendedae_plus.util.ExtendedAELogger; + +/** + * AppliedFlux 兼容性处理工具类 + * 用于检测和处理与AppliedFlux模组的UI冲突 + */ +public final class AppliedFluxCompat { + + private AppliedFluxCompat() {} + + /** + * 检查PatternProviderScreen是否已经有AppliedFlux添加的升级面板 + * 简化版本:主要通过AppliedFlux模组加载状态来判断 + */ + public static boolean hasAppliedFluxUpgradePanel(PatternProviderScreen screen) { + // 如果AppliedFlux未加载,肯定没有其升级面板 + if (!UpgradeSlotCompat.shouldUseLowPriorityMode()) { + return false; + } + + // 如果AppliedFlux加载了,假设它会添加升级面板 + // 这是一个保守的假设,避免冲突 + ExtendedAELogger.LOGGER.debug("[AppliedFlux兼容] 检测到AppliedFlux已加载,假设存在升级面板"); + return true; + } + + /** + * 检查是否应该跳过添加我们的升级面板 + */ + public static boolean shouldSkipOurUpgradePanel(PatternProviderScreen screen) { + if (!UpgradeSlotCompat.shouldUseLowPriorityMode()) { + return false; + } + + return hasAppliedFluxUpgradePanel(screen); + } +} diff --git a/src/main/java/com/extendedae_plus/compat/UpgradeSlotCompat.java b/src/main/java/com/extendedae_plus/compat/UpgradeSlotCompat.java index 0c9f191..5b549ce 100644 --- a/src/main/java/com/extendedae_plus/compat/UpgradeSlotCompat.java +++ b/src/main/java/com/extendedae_plus/compat/UpgradeSlotCompat.java @@ -5,6 +5,7 @@ import net.neoforged.fml.ModList; public final class UpgradeSlotCompat { private static Boolean APPFLUX_LOADED; + private static Boolean APPFLUX_PATTERN_PROVIDER_MIXIN_ACTIVE; private UpgradeSlotCompat() {} @@ -20,6 +21,29 @@ public final class UpgradeSlotCompat { return APPFLUX_LOADED; } + /** + * 检测AppliedFlux的PatternProviderScreen mixin是否活跃 + * 这比简单检查模组是否加载更准确 + */ + private static boolean isAppfluxPatternProviderMixinActive() { + if (APPFLUX_PATTERN_PROVIDER_MIXIN_ACTIVE == null) { + try { + if (!isAppfluxLoaded()) { + APPFLUX_PATTERN_PROVIDER_MIXIN_ACTIVE = false; + } else { + // 尝试检测AppliedFlux的mixin类是否存在 + Class.forName("com.glodblock.github.appflux.mixins.MixinPatternProviderScreen"); + APPFLUX_PATTERN_PROVIDER_MIXIN_ACTIVE = true; + } + } catch (ClassNotFoundException e) { + APPFLUX_PATTERN_PROVIDER_MIXIN_ACTIVE = false; + } catch (Throwable t) { + APPFLUX_PATTERN_PROVIDER_MIXIN_ACTIVE = false; + } + } + return APPFLUX_PATTERN_PROVIDER_MIXIN_ACTIVE; + } + // 是否由我们提供升级槽(当未安装 appflux 时) public static boolean shouldEnableUpgradeSlots() { return !isAppfluxLoaded(); @@ -30,9 +54,19 @@ public final class UpgradeSlotCompat { return true; } - // 客户端界面是否需要显示升级面板(装/不装 appflux 均显示; - // appflux 提供的升级槽会以 SlotSemantics.UPGRADE 出现在菜单中,我们只负责渲染面板) + // 客户端界面是否需要显示升级面板 + // 如果AppliedFlux的mixin活跃,我们降低优先级让它处理 public static boolean shouldAddUpgradePanelToScreen() { - return true; + return true; // 总是尝试添加,但在代码中检测冲突 + } + + // 是否应该使用低优先级模式(当AppliedFlux存在时) + public static boolean shouldUseLowPriorityMode() { + return isAppfluxPatternProviderMixinActive(); + } + + // 获取推荐的mixin优先级 + public static int getRecommendedMixinPriority() { + return isAppfluxPatternProviderMixinActive() ? 1500 : 2000; } } diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternProviderScreenUpgradesMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternProviderScreenUpgradesMixin.java index d8b60fb..2150990 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternProviderScreenUpgradesMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternProviderScreenUpgradesMixin.java @@ -3,7 +3,11 @@ package com.extendedae_plus.mixin.ae2.client.gui; import appeng.api.upgrades.Upgrades; import appeng.client.gui.AEBaseScreen; import appeng.client.gui.implementations.PatternProviderScreen; +import appeng.client.gui.layout.SlotGridLayout; +import appeng.client.gui.style.Blitter; import appeng.client.gui.style.ScreenStyle; +import appeng.client.gui.style.SlotPosition; +import appeng.client.gui.style.WidgetStyle; import appeng.client.gui.widgets.ToolboxPanel; import appeng.client.gui.widgets.UpgradesPanel; import appeng.core.localization.GuiText; @@ -12,6 +16,8 @@ import appeng.menu.implementations.PatternProviderMenu; import appeng.helpers.patternprovider.PatternProviderLogicHost; import appeng.menu.AEBaseMenu; import com.extendedae_plus.compat.UpgradeSlotCompat; +import com.extendedae_plus.compat.AppliedFluxCompat; +import com.extendedae_plus.util.IStyleAccessor; import net.minecraft.network.chat.Component; import net.minecraft.world.entity.player.Inventory; import org.spongepowered.asm.mixin.Mixin; @@ -23,30 +29,70 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.ArrayList; import java.util.List; -@Mixin(value = PatternProviderScreen.class, priority = 2000, remap = false) +@Mixin(value = PatternProviderScreen.class, priority = 1500, remap = false) public abstract class PatternProviderScreenUpgradesMixin extends AEBaseScreen { - @Inject(method = "", at = @At("TAIL")) + @Inject(method = "", at = @At("TAIL"), remap = false) private void eap$initUpgrades(PatternProviderMenu menu, Inventory playerInventory, Component title, ScreenStyle style, CallbackInfo ci) { + com.extendedae_plus.util.ExtendedAELogger.LOGGER.debug("[样板供应器][界面] 开始初始化升级面板"); + com.extendedae_plus.util.ExtendedAELogger.LOGGER.debug("[样板供应器][界面] shouldAddUpgradePanelToScreen: {}", UpgradeSlotCompat.shouldAddUpgradePanelToScreen()); + com.extendedae_plus.util.ExtendedAELogger.LOGGER.debug("[样板供应器][界面] shouldUseLowPriorityMode: {}", UpgradeSlotCompat.shouldUseLowPriorityMode()); + if (!UpgradeSlotCompat.shouldAddUpgradePanelToScreen()) { + com.extendedae_plus.util.ExtendedAELogger.LOGGER.debug("[样板供应器][界面] 跳过添加升级面板:shouldAddUpgradePanelToScreen返回false"); return; } - try { - this.widgets.add("upgrades", new UpgradesPanel( - menu.getSlots(SlotSemantics.UPGRADE), - this::eap$getCompatibleUpgrades)); - } catch (IllegalStateException already) { - // 已存在同名面板(可能由 AE2 或其他模组添加),忽略 - com.extendedae_plus.util.ExtendedAELogger.LOGGER.debug("[样板供应器][界面] 升级面板已存在,跳过添加"); - } - if (menu instanceof AEBaseMenu base && base instanceof com.extendedae_plus.bridge.IUpgradableMenu upg && upg.getToolbox() != null && upg.getToolbox().isPresent()) { + + // 使用改进的AppliedFlux兼容性检测 + @SuppressWarnings("unchecked") + PatternProviderScreen screen = (PatternProviderScreen) (Object) this; + + boolean shouldSkip = AppliedFluxCompat.shouldSkipOurUpgradePanel(screen); + com.extendedae_plus.util.ExtendedAELogger.LOGGER.debug("[样板供应器][界面] AppliedFlux兼容性检测结果: shouldSkip={}", shouldSkip); + + if (shouldSkip) { + com.extendedae_plus.util.ExtendedAELogger.LOGGER.debug("[样板供应器][界面] 检测到AppliedFlux升级面板,跳过添加我们的面板"); + } else { + com.extendedae_plus.util.ExtendedAELogger.LOGGER.debug("[样板供应器][界面] 开始添加升级面板"); + + // 检查是否已经存在upgrades widget try { - this.widgets.add("toolbox", new ToolboxPanel(style, upg.getToolbox().getName())); - } catch (IllegalStateException already) { - com.extendedae_plus.util.ExtendedAELogger.LOGGER.debug("[样板供应器][界面] 工具箱面板已存在,跳过添加"); + // 尝试添加升级面板 + this.widgets.add("upgrades", new UpgradesPanel(menu.getSlots(SlotSemantics.UPGRADE), this::eap$getCompatibleUpgrades)); + com.extendedae_plus.util.ExtendedAELogger.LOGGER.debug("[样板供应器][界面] 成功添加升级面板"); + } catch (IllegalStateException e) { + com.extendedae_plus.util.ExtendedAELogger.LOGGER.warn("[样板供应器][界面] 升级面板已存在,跳过添加: {}", e.getMessage()); + return; // 如果升级面板已存在,不继续添加其他内容 } + + // 设置TOOLBOX样式(完全按照AppliedFlux的方式) + var sp = new SlotPosition(); + sp.setBottom(84); + sp.setRight(1); + sp.setGrid(SlotGridLayout.BREAK_AFTER_3COLS); + var ws = new WidgetStyle(); + ws.setRight(2); + ws.setBottom(90); + ws.setWidth(59); + ws.setHeight(66); + style.getSlots().put("TOOLBOX", sp); + ((IStyleAccessor) style).getImages().put("toolbox", Blitter.texture("guis/extra_panels.png", 128, 128).src(69, 62, 59, 66)); + ((IStyleAccessor) style).getWidgets().put("toolbox", ws); + + // 添加工具箱面板 + if (menu instanceof AEBaseMenu base && base instanceof com.extendedae_plus.bridge.IUpgradableMenu upg && upg.getToolbox() != null && upg.getToolbox().isPresent()) { + try { + this.widgets.add("toolbox", new ToolboxPanel(style, upg.getToolbox().getName())); + com.extendedae_plus.util.ExtendedAELogger.LOGGER.debug("[样板供应器][界面] 成功添加工具箱面板"); + } catch (IllegalStateException e) { + com.extendedae_plus.util.ExtendedAELogger.LOGGER.warn("[样板供应器][界面] 工具箱面板已存在,跳过添加: {}", e.getMessage()); + } + } + + com.extendedae_plus.util.ExtendedAELogger.LOGGER.debug("[样板供应器][界面] 按照AppliedFlux方式完成升级面板和工具箱初始化"); } } + @Unique private List eap$getCompatibleUpgrades() { diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/ScreenStyleMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/ScreenStyleMixin.java new file mode 100644 index 0000000..c9bb4c4 --- /dev/null +++ b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/ScreenStyleMixin.java @@ -0,0 +1,34 @@ +package com.extendedae_plus.mixin.ae2.client.gui; + +import appeng.client.gui.style.Blitter; +import appeng.client.gui.style.ScreenStyle; +import appeng.client.gui.style.WidgetStyle; +import com.extendedae_plus.util.IStyleAccessor; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.Map; + +@Mixin(ScreenStyle.class) +public abstract class ScreenStyleMixin implements IStyleAccessor { + + @Final + @Shadow(remap = false) + private Map images; + @Final + @Shadow(remap = false) + private Map widgets; + + @SuppressWarnings("AddedMixinMembersNamePattern") + @Override + public Map getImages() { + return this.images; + } + + @SuppressWarnings("AddedMixinMembersNamePattern") + @Override + public Map getWidgets() { + return this.widgets; + } +} diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/compat/PatternProviderLogicCompatMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/compat/PatternProviderLogicCompatMixin.java index d9a530b..fa9f960 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/compat/PatternProviderLogicCompatMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/compat/PatternProviderLogicCompatMixin.java @@ -184,18 +184,49 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr boolean found = false; IUpgradeInventory upgrades = null; - if (UpgradeSlotCompat.shouldEnableUpgradeSlots()) { - upgrades = this.eap$compatUpgrades; - ExtendedAELogger.LOGGER.debug("[样板供应器] 使用自带升级槽(未安装 appflux): {}", upgrades != null); - } else { - // appflux 应该注入其自身的 IUpgradeableObject 实现 + + // 优先尝试从AppliedFlux获取升级槽(如果安装了的话) + if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) { + // 安装了appflux:优先使用appflux的升级槽 try { if ((Object) this instanceof IUpgradeableObject uo) { upgrades = uo.getUpgrades(); ExtendedAELogger.LOGGER.debug("[样板供应器] 使用 appflux 提供的升级槽: {}", upgrades != null); } } catch (Throwable t) { - ExtendedAELogger.LOGGER.error("[样板供应器] 获取第三方升级槽失败", t); + ExtendedAELogger.LOGGER.error("[样板供应器] 获取 appflux 升级槽失败,回退到兼容槽", t); + // 如果获取AppliedFlux升级槽失败,回退到我们的兼容槽 + upgrades = this.eap$compatUpgrades; + } + } else { + // 未安装appflux:使用我们的兼容升级槽 + upgrades = this.eap$compatUpgrades; + ExtendedAELogger.LOGGER.debug("[样板供应器] 使用自带升级槽(未安装 appflux): {}", upgrades != null); + } + + // 双重保险:如果主要方式失败,尝试备用方式 + if (upgrades == null || eap$isUpgradeInventoryEmpty(upgrades)) { + ExtendedAELogger.LOGGER.debug("[样板供应器] 主升级槽为空,尝试备用方式"); + + if (UpgradeSlotCompat.shouldEnableUpgradeSlots()) { + // 如果我们的槽为空,尝试检查是否有AppliedFlux的槽 + try { + if ((Object) this instanceof IUpgradeableObject uo) { + IUpgradeInventory backupUpgrades = uo.getUpgrades(); + if (backupUpgrades != null && !eap$isUpgradeInventoryEmpty(backupUpgrades)) { + upgrades = backupUpgrades; + ExtendedAELogger.LOGGER.debug("[样板供应器] 使用备用 appflux 升级槽"); + } + } + } catch (Throwable t) { + ExtendedAELogger.LOGGER.debug("[样板供应器] 备用升级槽检查失败: {}", t.getMessage()); + } + } else { + // 如果AppliedFlux的槽为空,尝试我们的兼容槽 + if (this.eap$compatUpgrades != null && !eap$isUpgradeInventoryEmpty(this.eap$compatUpgrades)) { + upgrades = this.eap$compatUpgrades; + ExtendedAELogger.LOGGER.debug("[样板供应器] 使用备用兼容升级槽"); + } } } @@ -273,6 +304,19 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr } // CompatUpgradeProvider 实现:仅在未安装 appflux 时由我们提供升级槽 + @Unique + private boolean eap$isUpgradeInventoryEmpty(IUpgradeInventory inventory) { + if (inventory == null) { + return true; + } + for (ItemStack stack : inventory) { + if (!stack.isEmpty()) { + return false; + } + } + return true; + } + @Override public IUpgradeInventory eap$getCompatUpgrades() { return this.eap$compatUpgrades != null ? this.eap$compatUpgrades : UpgradeInventories.empty(); diff --git a/src/main/java/com/extendedae_plus/util/IStyleAccessor.java b/src/main/java/com/extendedae_plus/util/IStyleAccessor.java new file mode 100644 index 0000000..1b47c25 --- /dev/null +++ b/src/main/java/com/extendedae_plus/util/IStyleAccessor.java @@ -0,0 +1,14 @@ +package com.extendedae_plus.util; + +import appeng.client.gui.style.Blitter; +import appeng.client.gui.style.WidgetStyle; + +import java.util.Map; + +public interface IStyleAccessor { + + Map getImages(); + + Map getWidgets(); + +} diff --git a/src/main/resources/extendedae_plus.mixins.json b/src/main/resources/extendedae_plus.mixins.json index 9fc4e10..875b677 100644 --- a/src/main/resources/extendedae_plus.mixins.json +++ b/src/main/resources/extendedae_plus.mixins.json @@ -63,6 +63,8 @@ "ae2.client.gui.PatternEncodingTermScreenMixin", "ae2.client.gui.PatternProviderCloseMixin", "ae2.client.gui.PatternProviderScreenMixin", + "ae2.client.gui.PatternProviderScreenUpgradesMixin", + "ae2.client.gui.ScreenStyleMixin", "ae2.client.gui.SlotGridLayoutMixin", "ae2.menu.CraftConfirmMenuGoBackMixin", "extendedae.accessor.GuiExPatternTerminalAccessor",