兼容applied flux
This commit is contained in:
parent
a8b9b8e749
commit
428f4520b2
|
|
@ -81,7 +81,7 @@ dependencies {
|
||||||
|
|
||||||
annotationProcessor "org.spongepowered:mixin:${mixin_version}:processor"
|
annotationProcessor "org.spongepowered:mixin:${mixin_version}:processor"
|
||||||
|
|
||||||
modImplementation "curse.maven:applied-flux-965012:6755986"
|
// modImplementation "curse.maven:applied-flux-965012:6755986"
|
||||||
modCompileOnly "curse.maven:mega-cells-622112:${mega_cells_version}"
|
modCompileOnly "curse.maven:mega-cells-622112:${mega_cells_version}"
|
||||||
modCompileOnly "curse.maven:jade-324717:${jade_version}"
|
modCompileOnly "curse.maven:jade-324717:${jade_version}"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import appeng.api.storage.StorageCells;
|
||||||
import appeng.menu.locator.MenuLocators;
|
import appeng.menu.locator.MenuLocators;
|
||||||
import com.extendedae_plus.ae.api.storage.InfinityBigIntegerCellHandler;
|
import com.extendedae_plus.ae.api.storage.InfinityBigIntegerCellHandler;
|
||||||
import com.extendedae_plus.client.ClientRegistrar;
|
import com.extendedae_plus.client.ClientRegistrar;
|
||||||
|
import com.extendedae_plus.compat.CompatibilityTest;
|
||||||
import com.extendedae_plus.config.ModConfig;
|
import com.extendedae_plus.config.ModConfig;
|
||||||
import com.extendedae_plus.init.*;
|
import com.extendedae_plus.init.*;
|
||||||
import com.extendedae_plus.menu.locator.CuriosItemLocator;
|
import com.extendedae_plus.menu.locator.CuriosItemLocator;
|
||||||
|
|
@ -62,6 +63,9 @@ public class ExtendedAEPlus {
|
||||||
private void commonSetup(final FMLCommonSetupEvent event) {
|
private void commonSetup(final FMLCommonSetupEvent event) {
|
||||||
StorageCells.addCellHandler(InfinityBigIntegerCellHandler.INSTANCE);
|
StorageCells.addCellHandler(InfinityBigIntegerCellHandler.INSTANCE);
|
||||||
|
|
||||||
|
// 运行兼容性测试
|
||||||
|
CompatibilityTest.testCompatibility();
|
||||||
|
|
||||||
// 注册本模组网络通道与数据包
|
// 注册本模组网络通道与数据包
|
||||||
event.enqueueWork(() -> {
|
event.enqueueWork(() -> {
|
||||||
// 注册升级卡
|
// 注册升级卡
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
package com.extendedae_plus.compat;
|
||||||
|
|
||||||
|
import com.extendedae_plus.util.ExtendedAELogger;
|
||||||
|
import net.minecraftforge.fml.ModList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 兼容性测试类
|
||||||
|
* 用于验证模组兼容性检测是否正常工作
|
||||||
|
*/
|
||||||
|
public class CompatibilityTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试模组兼容性检测
|
||||||
|
*/
|
||||||
|
public static void testCompatibility() {
|
||||||
|
ExtendedAELogger.LOGGER.info("=== ExtendedAE_Plus 兼容性测试开始 ===");
|
||||||
|
|
||||||
|
// 测试appflux模组检测
|
||||||
|
boolean appfluxExists = ModList.get().isLoaded("appflux");
|
||||||
|
ExtendedAELogger.LOGGER.info("ExtendedAE-appflux模组检测结果: {}", appfluxExists ? "存在" : "不存在");
|
||||||
|
|
||||||
|
// 测试升级卡槽功能启用状态
|
||||||
|
boolean shouldEnableUpgrades = UpgradeSlotCompat.shouldEnableUpgradeSlots();
|
||||||
|
ExtendedAELogger.LOGGER.info("升级卡槽功能启用状态: {}", shouldEnableUpgrades ? "启用" : "禁用");
|
||||||
|
|
||||||
|
// 测试Screen升级面板添加状态
|
||||||
|
boolean shouldAddPanel = UpgradeSlotCompat.shouldAddUpgradePanelToScreen();
|
||||||
|
ExtendedAELogger.LOGGER.info("Screen升级面板添加状态: {}", shouldAddPanel ? "启用" : "禁用");
|
||||||
|
|
||||||
|
// 输出兼容性策略
|
||||||
|
if (appfluxExists) {
|
||||||
|
ExtendedAELogger.LOGGER.info("兼容性策略: 检测到ExtendedAE-appflux模组,将使用其升级卡槽功能");
|
||||||
|
} else {
|
||||||
|
ExtendedAELogger.LOGGER.info("兼容性策略: 未检测到ExtendedAE-appflux模组,将使用我们自己的升级卡槽功能");
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtendedAELogger.LOGGER.info("=== ExtendedAE_Plus 兼容性测试完成 ===");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取兼容性状态报告
|
||||||
|
*/
|
||||||
|
public static String getCompatibilityReport() {
|
||||||
|
boolean appfluxExists = ModList.get().isLoaded("appflux");
|
||||||
|
boolean upgradesEnabled = UpgradeSlotCompat.shouldEnableUpgradeSlots();
|
||||||
|
|
||||||
|
StringBuilder report = new StringBuilder();
|
||||||
|
report.append("ExtendedAE_Plus 兼容性报告:\n");
|
||||||
|
report.append("- ExtendedAE-appflux模组: ").append(appfluxExists ? "已安装" : "未安装").append("\n");
|
||||||
|
report.append("- 升级卡槽功能: ").append(upgradesEnabled ? "启用中" : "已禁用").append("\n");
|
||||||
|
|
||||||
|
if (appfluxExists && !upgradesEnabled) {
|
||||||
|
report.append("- 兼容性状态: 正常 (使用appflux的升级功能)\n");
|
||||||
|
} else if (!appfluxExists && upgradesEnabled) {
|
||||||
|
report.append("- 兼容性状态: 正常 (使用我们的升级功能)\n");
|
||||||
|
} else {
|
||||||
|
report.append("- 兼容性状态: 异常 (配置不一致)\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return report.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
202
src/main/java/com/extendedae_plus/compat/UpgradeSlotCompat.java
Normal file
202
src/main/java/com/extendedae_plus/compat/UpgradeSlotCompat.java
Normal file
|
|
@ -0,0 +1,202 @@
|
||||||
|
package com.extendedae_plus.compat;
|
||||||
|
|
||||||
|
import appeng.api.upgrades.IUpgradeInventory;
|
||||||
|
import appeng.api.upgrades.IUpgradeableObject;
|
||||||
|
import appeng.api.upgrades.UpgradeInventories;
|
||||||
|
import appeng.client.gui.style.ScreenStyle;
|
||||||
|
import appeng.client.gui.widgets.ToolboxPanel;
|
||||||
|
import appeng.client.gui.widgets.UpgradesPanel;
|
||||||
|
import appeng.core.localization.GuiText;
|
||||||
|
import appeng.helpers.patternprovider.PatternProviderLogicHost;
|
||||||
|
import appeng.menu.AEBaseMenu;
|
||||||
|
import appeng.menu.SlotSemantics;
|
||||||
|
import appeng.menu.ToolboxMenu;
|
||||||
|
import com.extendedae_plus.util.ExtendedAELogger;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.world.inventory.Slot;
|
||||||
|
import net.minecraftforge.fml.ModList;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 升级卡槽兼容性管理类
|
||||||
|
* 检测ExtendedAE-appflux模组是否存在,如果存在则使用其升级卡槽功能
|
||||||
|
* 否则使用我们自己的实现
|
||||||
|
*/
|
||||||
|
public class UpgradeSlotCompat {
|
||||||
|
private static final String APPFLUX_MOD_ID = "appflux";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测是否应该启用我们的升级卡槽功能
|
||||||
|
* @return true如果应该启用,false如果检测到appflux模组存在
|
||||||
|
*/
|
||||||
|
public static boolean shouldEnableUpgradeSlots() {
|
||||||
|
boolean appfluxExists = ModList.get().isLoaded(APPFLUX_MOD_ID);
|
||||||
|
ExtendedAELogger.LOGGER.info("ExtendedAE-appflux模组检测: {}", appfluxExists ? "存在" : "不存在");
|
||||||
|
|
||||||
|
if (appfluxExists) {
|
||||||
|
ExtendedAELogger.LOGGER.info("检测到ExtendedAE-appflux模组,跳过我们的升级卡槽功能");
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
ExtendedAELogger.LOGGER.info("未检测到ExtendedAE-appflux模组,启用我们的升级卡槽功能");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测是否应该在Screen中添加升级面板
|
||||||
|
* @return true如果应该添加,false如果检测到appflux模组存在
|
||||||
|
*/
|
||||||
|
public static boolean shouldAddUpgradePanelToScreen() {
|
||||||
|
return shouldEnableUpgradeSlots();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化菜单升级功能(如果需要的话)
|
||||||
|
* @param menu 目标菜单
|
||||||
|
* @param host 样板供应器逻辑主机
|
||||||
|
* @return 是否成功初始化
|
||||||
|
*/
|
||||||
|
public static boolean initMenuUpgrades(AEBaseMenu menu, PatternProviderLogicHost host) {
|
||||||
|
if (!shouldEnableUpgradeSlots()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 创建工具箱菜单
|
||||||
|
ToolboxMenu toolbox = new ToolboxMenu(menu);
|
||||||
|
|
||||||
|
// 设置升级槽
|
||||||
|
if (host instanceof IUpgradeableObject upgradeableHost) {
|
||||||
|
// 使用反射调用protected的setupUpgrades方法
|
||||||
|
try {
|
||||||
|
var setupUpgradesMethod = AEBaseMenu.class.getDeclaredMethod("setupUpgrades", IUpgradeInventory.class);
|
||||||
|
setupUpgradesMethod.setAccessible(true);
|
||||||
|
setupUpgradesMethod.invoke(menu, upgradeableHost.getUpgrades());
|
||||||
|
} catch (Exception e) {
|
||||||
|
ExtendedAELogger.LOGGER.error("反射调用setupUpgrades失败", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用反射或接口设置工具箱
|
||||||
|
if (menu instanceof IUpgradeableMenuCompat compatMenu) {
|
||||||
|
compatMenu.setCompatToolbox(toolbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtendedAELogger.LOGGER.debug("成功为PatternProviderMenu初始化升级功能");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
ExtendedAELogger.LOGGER.error("初始化PatternProviderMenu升级功能时出错", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为Screen添加升级面板(如果需要的话)
|
||||||
|
* @param widgets 小部件映射
|
||||||
|
* @param menu 菜单实例
|
||||||
|
* @param style 屏幕样式
|
||||||
|
* @return 是否成功添加
|
||||||
|
*/
|
||||||
|
public static boolean addUpgradePanelToScreen(Object widgets, Object menu, ScreenStyle style) {
|
||||||
|
if (!shouldAddUpgradePanelToScreen()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (menu instanceof IUpgradeableMenuCompat compatMenu) {
|
||||||
|
try {
|
||||||
|
// 使用反射获取widgets的add方法 - 尝试不同的方法签名
|
||||||
|
var widgetsClass = widgets.getClass();
|
||||||
|
var addMethod = widgetsClass.getDeclaredMethod("add", String.class, Object.class);
|
||||||
|
addMethod.setAccessible(true);
|
||||||
|
|
||||||
|
// 获取升级槽位
|
||||||
|
var menuClass = menu.getClass();
|
||||||
|
var getSlotsMethod = menuClass.getMethod("getSlots", SlotSemantics.class);
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<Slot> upgradeSlots = (List<Slot>) getSlotsMethod.invoke(menu, SlotSemantics.UPGRADE);
|
||||||
|
|
||||||
|
// 添加升级面板
|
||||||
|
UpgradesPanel upgradesPanel = new UpgradesPanel(upgradeSlots, () -> getCompatibleUpgrades(compatMenu));
|
||||||
|
addMethod.invoke(widgets, "upgrades", upgradesPanel);
|
||||||
|
|
||||||
|
// 添加工具箱面板(如果存在)
|
||||||
|
ToolboxMenu toolbox = compatMenu.getCompatToolbox();
|
||||||
|
if (toolbox != null && toolbox.isPresent()) {
|
||||||
|
ToolboxPanel toolboxPanel = new ToolboxPanel(style, toolbox.getName());
|
||||||
|
addMethod.invoke(widgets, "toolbox", toolboxPanel);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtendedAELogger.LOGGER.debug("成功为PatternProviderScreen添加升级面板");
|
||||||
|
return true;
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
// 尝试其他可能的方法签名
|
||||||
|
try {
|
||||||
|
var widgetsClass = widgets.getClass();
|
||||||
|
var putMethod = widgetsClass.getDeclaredMethod("put", String.class, Object.class);
|
||||||
|
putMethod.setAccessible(true);
|
||||||
|
|
||||||
|
// 获取升级槽位
|
||||||
|
var menuClass = menu.getClass();
|
||||||
|
var getSlotsMethod = menuClass.getMethod("getSlots", SlotSemantics.class);
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<Slot> upgradeSlots = (List<Slot>) getSlotsMethod.invoke(menu, SlotSemantics.UPGRADE);
|
||||||
|
|
||||||
|
// 添加升级面板
|
||||||
|
UpgradesPanel upgradesPanel = new UpgradesPanel(upgradeSlots, () -> getCompatibleUpgrades(compatMenu));
|
||||||
|
putMethod.invoke(widgets, "upgrades", upgradesPanel);
|
||||||
|
|
||||||
|
// 添加工具箱面板(如果存在)
|
||||||
|
ToolboxMenu toolbox = compatMenu.getCompatToolbox();
|
||||||
|
if (toolbox != null && toolbox.isPresent()) {
|
||||||
|
ToolboxPanel toolboxPanel = new ToolboxPanel(style, toolbox.getName());
|
||||||
|
putMethod.invoke(widgets, "toolbox", toolboxPanel);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtendedAELogger.LOGGER.debug("成功为PatternProviderScreen添加升级面板(使用put方法)");
|
||||||
|
return true;
|
||||||
|
} catch (Exception e2) {
|
||||||
|
ExtendedAELogger.LOGGER.error("反射调用widgets方法失败", e2);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
ExtendedAELogger.LOGGER.error("为PatternProviderScreen添加升级面板时出错", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取兼容的升级列表
|
||||||
|
*/
|
||||||
|
private static List<Component> getCompatibleUpgrades(IUpgradeableMenuCompat menu) {
|
||||||
|
var list = new ArrayList<Component>();
|
||||||
|
list.add(GuiText.CompatibleUpgrades.text());
|
||||||
|
|
||||||
|
try {
|
||||||
|
IUpgradeInventory upgrades = menu.getCompatUpgrades();
|
||||||
|
if (upgrades != null) {
|
||||||
|
list.addAll(appeng.api.upgrades.Upgrades.getTooltipLinesForMachine(upgrades.getUpgradableItem()));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
ExtendedAELogger.LOGGER.error("获取兼容升级列表时出错", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 兼容性升级菜单接口
|
||||||
|
*/
|
||||||
|
public interface IUpgradeableMenuCompat {
|
||||||
|
ToolboxMenu getCompatToolbox();
|
||||||
|
void setCompatToolbox(ToolboxMenu toolbox);
|
||||||
|
IUpgradeInventory getCompatUpgrades();
|
||||||
|
}
|
||||||
|
}
|
||||||
79
src/main/java/com/extendedae_plus/mixin/MixinConditions.java
Normal file
79
src/main/java/com/extendedae_plus/mixin/MixinConditions.java
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
package com.extendedae_plus.mixin;
|
||||||
|
|
||||||
|
import net.minecraftforge.fml.ModList;
|
||||||
|
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
|
||||||
|
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mixin条件加载插件
|
||||||
|
* 用于根据模组存在情况动态加载不同的Mixin
|
||||||
|
*/
|
||||||
|
public class MixinConditions implements IMixinConfigPlugin {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad(String mixinPackage) {
|
||||||
|
// 初始化时调用
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRefMapperConfig() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
|
||||||
|
// 对于升级相关的Mixin,检查appflux是否存在
|
||||||
|
if (mixinClassName.contains("PatternProviderMenuUpgradesMixin") ||
|
||||||
|
mixinClassName.contains("PatternProviderScreenUpgradesMixin") ||
|
||||||
|
mixinClassName.contains("PatternProviderLogicUpgradesMixin") ||
|
||||||
|
mixinClassName.contains("PatternProviderLogicHostUpgradesMixin")) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 检查ModList是否已初始化
|
||||||
|
if (net.minecraftforge.fml.ModList.get() == null) {
|
||||||
|
System.out.println("[ExtendedAE_Plus] ModList未初始化,默认应用升级Mixin: " + mixinClassName);
|
||||||
|
return true; // 修改策略:未初始化时默认应用,运行时再检查
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean appfluxExists = net.minecraftforge.fml.ModList.get().isLoaded("appflux");
|
||||||
|
boolean shouldApply = !appfluxExists;
|
||||||
|
|
||||||
|
System.out.println("[ExtendedAE_Plus] 升级Mixin检查: " + mixinClassName +
|
||||||
|
", appflux存在: " + appfluxExists +
|
||||||
|
", 应用Mixin: " + shouldApply);
|
||||||
|
|
||||||
|
return shouldApply;
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("[ExtendedAE_Plus] ModList检查失败,默认应用升级Mixin: " + mixinClassName);
|
||||||
|
return true; // 修改策略:出错时默认应用,运行时再检查
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其他Mixin正常应用
|
||||||
|
System.out.println("[ExtendedAE_Plus] 加载Mixin: " + mixinClassName);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
|
||||||
|
// 接受目标类
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getMixins() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preApply(String targetClassName, org.objectweb.asm.tree.ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
|
||||||
|
// 应用前调用
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postApply(String targetClassName, org.objectweb.asm.tree.ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
|
||||||
|
// 应用后调用
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,6 +10,7 @@ import appeng.core.localization.GuiText;
|
||||||
import appeng.menu.SlotSemantics;
|
import appeng.menu.SlotSemantics;
|
||||||
import appeng.menu.implementations.PatternProviderMenu;
|
import appeng.menu.implementations.PatternProviderMenu;
|
||||||
import com.extendedae_plus.bridge.IUpgradableMenu;
|
import com.extendedae_plus.bridge.IUpgradableMenu;
|
||||||
|
import com.extendedae_plus.compat.UpgradeSlotCompat;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
|
@ -21,15 +22,20 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Mixin(value = PatternProviderScreen.class, remap = false)
|
@Mixin(value = PatternProviderScreen.class, priority = 2000, remap = false)
|
||||||
public abstract class PatternProviderScreenUpgradesMixin<C extends PatternProviderMenu> extends AEBaseScreen<C> {
|
public abstract class PatternProviderScreenUpgradesMixin<C extends PatternProviderMenu> extends AEBaseScreen<C> {
|
||||||
|
|
||||||
@Inject(method = "<init>", at = @At("TAIL"))
|
@Inject(method = "<init>", at = @At("TAIL"))
|
||||||
private void eap$initUpgrades(PatternProviderMenu menu, Inventory playerInventory, Component title, ScreenStyle style, CallbackInfo ci) {
|
private void eap$initUpgrades(PatternProviderMenu menu, Inventory playerInventory, Component title, ScreenStyle style, CallbackInfo ci) {
|
||||||
|
// 只有在应该启用升级卡槽时才添加升级面板
|
||||||
|
if (!UpgradeSlotCompat.shouldAddUpgradePanelToScreen()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.widgets.add("upgrades", new UpgradesPanel(
|
this.widgets.add("upgrades", new UpgradesPanel(
|
||||||
menu.getSlots(SlotSemantics.UPGRADE),
|
menu.getSlots(SlotSemantics.UPGRADE),
|
||||||
this::eap$getCompatibleUpgrades));
|
this::eap$getCompatibleUpgrades));
|
||||||
if (((IUpgradableMenu) menu).getToolbox().isPresent()) {
|
if (((IUpgradableMenu) menu).getToolbox() != null && ((IUpgradableMenu) menu).getToolbox().isPresent()) {
|
||||||
this.widgets.add("toolbox", new ToolboxPanel(style, ((IUpgradableMenu) menu).getToolbox().getName()));
|
this.widgets.add("toolbox", new ToolboxPanel(style, ((IUpgradableMenu) menu).getToolbox().getName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
package com.extendedae_plus.mixin.ae2.compat;
|
||||||
|
|
||||||
|
import appeng.api.upgrades.IUpgradeInventory;
|
||||||
|
import appeng.helpers.patternprovider.PatternProviderLogicHost;
|
||||||
|
import appeng.menu.AEBaseMenu;
|
||||||
|
import appeng.menu.ToolboxMenu;
|
||||||
|
import appeng.menu.implementations.PatternProviderMenu;
|
||||||
|
import com.extendedae_plus.compat.UpgradeSlotCompat;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.MenuType;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PatternProviderMenu的兼容性Mixin
|
||||||
|
* 优先级设置为500,低于appflux的默认优先级,避免冲突
|
||||||
|
*/
|
||||||
|
@Mixin(value = PatternProviderMenu.class, priority = 500, remap = false)
|
||||||
|
public abstract class PatternProviderCompatMixin extends AEBaseMenu implements UpgradeSlotCompat.IUpgradeableMenuCompat {
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private ToolboxMenu eap$compatToolbox;
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private IUpgradeInventory eap$compatUpgrades;
|
||||||
|
|
||||||
|
@Inject(method = "<init>(Lnet/minecraft/world/inventory/MenuType;ILnet/minecraft/world/entity/player/Inventory;Lappeng/helpers/patternprovider/PatternProviderLogicHost;)V",
|
||||||
|
at = @At("TAIL"))
|
||||||
|
private void eap$initCompatUpgrades(MenuType<?> menuType, int id, Inventory playerInventory, PatternProviderLogicHost host, CallbackInfo ci) {
|
||||||
|
try {
|
||||||
|
// 检测是否应该启用升级卡槽功能
|
||||||
|
if (UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
// 直接初始化升级功能
|
||||||
|
this.eap$compatToolbox = new ToolboxMenu(this);
|
||||||
|
|
||||||
|
if (host instanceof appeng.api.upgrades.IUpgradeableObject upgradeableHost) {
|
||||||
|
this.eap$compatUpgrades = upgradeableHost.getUpgrades();
|
||||||
|
this.setupUpgrades(this.eap$compatUpgrades);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 静默处理异常,确保不会因为升级功能导致崩溃
|
||||||
|
com.extendedae_plus.util.ExtendedAELogger.LOGGER.error("PatternProviderMenu兼容性升级初始化失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ToolboxMenu getCompatToolbox() {
|
||||||
|
return this.eap$compatToolbox;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCompatToolbox(ToolboxMenu toolbox) {
|
||||||
|
this.eap$compatToolbox = toolbox;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IUpgradeInventory getCompatUpgrades() {
|
||||||
|
return this.eap$compatUpgrades;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构造函数,Mixin要求
|
||||||
|
public PatternProviderCompatMixin(MenuType<?> menuType, int id, Inventory playerInventory, Object host) {
|
||||||
|
super(menuType, id, playerInventory, host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,337 @@
|
||||||
|
package com.extendedae_plus.mixin.ae2.compat;
|
||||||
|
|
||||||
|
import appeng.api.networking.IManagedGridNode;
|
||||||
|
import appeng.api.networking.security.IActionSource;
|
||||||
|
import appeng.api.upgrades.IUpgradeInventory;
|
||||||
|
import appeng.api.upgrades.IUpgradeableObject;
|
||||||
|
import appeng.api.upgrades.UpgradeInventories;
|
||||||
|
import appeng.helpers.patternprovider.PatternProviderLogic;
|
||||||
|
import appeng.helpers.patternprovider.PatternProviderLogicHost;
|
||||||
|
import com.extendedae_plus.ae.items.ChannelCardItem;
|
||||||
|
import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge;
|
||||||
|
import com.extendedae_plus.compat.UpgradeSlotCompat;
|
||||||
|
import com.extendedae_plus.init.ModItems;
|
||||||
|
import com.extendedae_plus.wireless.WirelessSlaveLink;
|
||||||
|
import com.extendedae_plus.wireless.endpoint.GenericNodeEndpointImpl;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PatternProviderLogic的兼容性Mixin
|
||||||
|
* 优先级设置为500,避免与appflux冲突
|
||||||
|
*/
|
||||||
|
@Mixin(value = PatternProviderLogic.class, priority = 500, remap = false)
|
||||||
|
public abstract class PatternProviderLogicCompatMixin implements IUpgradeableObject, InterfaceWirelessLinkBridge {
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private IUpgradeInventory eap$compatUpgrades = UpgradeInventories.empty();
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private WirelessSlaveLink eap$compatLink;
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private long eap$compatLastChannel = -1;
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private boolean eap$compatClientConnected = false;
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private boolean eap$compatHasInitialized = false;
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private int eap$compatDelayedInitTicks = 0;
|
||||||
|
|
||||||
|
@Final
|
||||||
|
@Shadow
|
||||||
|
private PatternProviderLogicHost host;
|
||||||
|
|
||||||
|
@Final
|
||||||
|
@Shadow
|
||||||
|
private IManagedGridNode mainNode;
|
||||||
|
|
||||||
|
@Final
|
||||||
|
@Shadow
|
||||||
|
private IActionSource actionSource;
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private void eap$compatOnUpgradesChanged() {
|
||||||
|
if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.host.saveChanges();
|
||||||
|
// 升级变更,重置并尝试初始化
|
||||||
|
eap$compatLastChannel = -1;
|
||||||
|
eap$compatHasInitialized = false;
|
||||||
|
eap$compatInitializeChannelLink();
|
||||||
|
} catch (Exception e) {
|
||||||
|
com.extendedae_plus.util.ExtendedAELogger.LOGGER.error("兼容性升级变更处理失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "<init>(Lappeng/api/networking/IManagedGridNode;Lappeng/helpers/patternprovider/PatternProviderLogicHost;I)V",
|
||||||
|
at = @At("TAIL"))
|
||||||
|
private void eap$compatInitUpgrades(IManagedGridNode mainNode, PatternProviderLogicHost host, int patternInventorySize, CallbackInfo ci) {
|
||||||
|
try {
|
||||||
|
if (UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
this.eap$compatUpgrades = UpgradeInventories.forMachine(
|
||||||
|
host.getTerminalIcon().getItem(),
|
||||||
|
1,
|
||||||
|
this::eap$compatOnUpgradesChanged
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
com.extendedae_plus.util.ExtendedAELogger.LOGGER.error("兼容性升级初始化失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "writeToNBT", at = @At("TAIL"))
|
||||||
|
private void eap$compatSaveUpgrades(CompoundTag tag, CallbackInfo ci) {
|
||||||
|
try {
|
||||||
|
if (UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
this.eap$compatUpgrades.writeToNBT(tag, "compat_upgrades");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
com.extendedae_plus.util.ExtendedAELogger.LOGGER.error("兼容性升级保存失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "readFromNBT", at = @At("TAIL"))
|
||||||
|
private void eap$compatLoadUpgrades(CompoundTag tag, CallbackInfo ci) {
|
||||||
|
try {
|
||||||
|
if (UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
this.eap$compatUpgrades.readFromNBT(tag, "compat_upgrades");
|
||||||
|
// 从 NBT 加载后,重置并尝试初始化
|
||||||
|
eap$compatLastChannel = -1;
|
||||||
|
eap$compatHasInitialized = false;
|
||||||
|
eap$compatInitializeChannelLink();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
com.extendedae_plus.util.ExtendedAELogger.LOGGER.error("兼容性升级加载失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "addDrops", at = @At("TAIL"))
|
||||||
|
private void eap$compatDropUpgrades(List<ItemStack> drops, CallbackInfo ci) {
|
||||||
|
try {
|
||||||
|
if (UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
for (var stack : this.eap$compatUpgrades) {
|
||||||
|
if (!stack.isEmpty()) {
|
||||||
|
drops.add(stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
com.extendedae_plus.util.ExtendedAELogger.LOGGER.error("兼容性升级掉落失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "clearContent", at = @At("TAIL"))
|
||||||
|
private void eap$compatClearUpgrades(CallbackInfo ci) {
|
||||||
|
try {
|
||||||
|
if (UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
this.eap$compatUpgrades.clear();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
com.extendedae_plus.util.ExtendedAELogger.LOGGER.error("兼容性升级清理失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IUpgradeInventory getUpgrades() {
|
||||||
|
if (UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
return this.eap$compatUpgrades;
|
||||||
|
}
|
||||||
|
return UpgradeInventories.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eap$updateWirelessLink() {
|
||||||
|
if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (eap$compatLink != null) {
|
||||||
|
eap$compatLink.updateStatus();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
com.extendedae_plus.util.ExtendedAELogger.LOGGER.error("兼容性无线链接更新失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
public void eap$compatInitializeChannelLink() {
|
||||||
|
if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 客户端早退
|
||||||
|
if (host.getBlockEntity() != null && host.getBlockEntity().getLevel() != null && host.getBlockEntity().getLevel().isClientSide) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 避免重复初始化
|
||||||
|
if (eap$compatHasInitialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 等待网格完成引导
|
||||||
|
if (!mainNode.hasGridBooted()) {
|
||||||
|
eap$compatDelayedInitTicks = Math.max(eap$compatDelayedInitTicks, 5);
|
||||||
|
try {
|
||||||
|
mainNode.ifPresent((grid, node) -> {
|
||||||
|
try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored) {}
|
||||||
|
});
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
long channel = 0L;
|
||||||
|
boolean found = false;
|
||||||
|
for (ItemStack stack : this.eap$compatUpgrades) {
|
||||||
|
if (!stack.isEmpty() && stack.getItem() == ModItems.CHANNEL_CARD.get()) {
|
||||||
|
channel = ChannelCardItem.getChannel(stack);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
// 无频道卡:断开并视为初始化完成
|
||||||
|
if (eap$compatLink != null) {
|
||||||
|
eap$compatLink.setFrequency(0L);
|
||||||
|
eap$compatLink.updateStatus();
|
||||||
|
}
|
||||||
|
eap$compatHasInitialized = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eap$compatLink == null) {
|
||||||
|
var endpoint = new GenericNodeEndpointImpl(() -> host.getBlockEntity(), () -> this.mainNode.getNode());
|
||||||
|
eap$compatLink = new WirelessSlaveLink(endpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
eap$compatLink.setFrequency(channel);
|
||||||
|
eap$compatLink.updateStatus();
|
||||||
|
|
||||||
|
if (eap$compatLink.isConnected()) {
|
||||||
|
eap$compatHasInitialized = true;
|
||||||
|
} else {
|
||||||
|
eap$compatHasInitialized = false;
|
||||||
|
eap$compatDelayedInitTicks = Math.max(eap$compatDelayedInitTicks, 5);
|
||||||
|
try {
|
||||||
|
mainNode.ifPresent((grid, node) -> {
|
||||||
|
try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored) {}
|
||||||
|
});
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
com.extendedae_plus.util.ExtendedAELogger.LOGGER.error("兼容性频道链接初始化失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eap$setClientWirelessState(boolean connected) {
|
||||||
|
if (UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
eap$compatClientConnected = connected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean eap$isWirelessConnected() {
|
||||||
|
if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (host.getBlockEntity() != null && host.getBlockEntity().getLevel() != null && host.getBlockEntity().getLevel().isClientSide) {
|
||||||
|
return eap$compatClientConnected;
|
||||||
|
} else {
|
||||||
|
return eap$compatLink != null && eap$compatLink.isConnected();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
com.extendedae_plus.util.ExtendedAELogger.LOGGER.error("检查兼容性无线连接状态失败", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean eap$hasTickInitialized() {
|
||||||
|
if (UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
return eap$compatHasInitialized;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eap$setTickInitialized(boolean initialized) {
|
||||||
|
if (UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
eap$compatHasInitialized = initialized;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eap$handleDelayedInit() {
|
||||||
|
if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 仅服务端
|
||||||
|
if (host.getBlockEntity() != null && host.getBlockEntity().getLevel() != null && host.getBlockEntity().getLevel().isClientSide) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!eap$compatHasInitialized) {
|
||||||
|
if (!mainNode.hasGridBooted()) {
|
||||||
|
if (eap$compatDelayedInitTicks > 0) {
|
||||||
|
eap$compatDelayedInitTicks--;
|
||||||
|
}
|
||||||
|
if (eap$compatDelayedInitTicks == 0) {
|
||||||
|
eap$compatDelayedInitTicks = 5;
|
||||||
|
try {
|
||||||
|
mainNode.ifPresent((grid, node) -> {
|
||||||
|
try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored) {}
|
||||||
|
});
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
eap$compatInitializeChannelLink();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
com.extendedae_plus.util.ExtendedAELogger.LOGGER.error("兼容性延迟初始化失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "onMainNodeStateChanged", at = @At("TAIL"))
|
||||||
|
private void eap$compatOnMainNodeStateChangedTail(CallbackInfo ci) {
|
||||||
|
if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
eap$compatLastChannel = -1;
|
||||||
|
eap$compatHasInitialized = false;
|
||||||
|
eap$compatDelayedInitTicks = 10;
|
||||||
|
try {
|
||||||
|
mainNode.ifPresent((grid, node) -> {
|
||||||
|
try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored) {}
|
||||||
|
});
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
|
} catch (Exception e) {
|
||||||
|
com.extendedae_plus.util.ExtendedAELogger.LOGGER.error("兼容性主节点状态变更处理失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.extendedae_plus.mixin.ae2.compat;
|
||||||
|
|
||||||
|
import appeng.api.upgrades.IUpgradeInventory;
|
||||||
|
import appeng.api.upgrades.IUpgradeableObject;
|
||||||
|
import appeng.api.upgrades.UpgradeInventories;
|
||||||
|
import appeng.helpers.patternprovider.PatternProviderLogic;
|
||||||
|
import appeng.helpers.patternprovider.PatternProviderLogicHost;
|
||||||
|
import com.extendedae_plus.compat.UpgradeSlotCompat;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PatternProviderLogicHost的兼容性Mixin
|
||||||
|
* 优先级设置为500,避免与appflux冲突
|
||||||
|
*/
|
||||||
|
@Mixin(value = PatternProviderLogicHost.class, priority = 500, remap = false)
|
||||||
|
public interface PatternProviderLogicHostCompatMixin extends IUpgradeableObject {
|
||||||
|
@Shadow PatternProviderLogic getLogic();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default IUpgradeInventory getUpgrades() {
|
||||||
|
if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
return UpgradeInventories.empty();
|
||||||
|
}
|
||||||
|
return ((IUpgradeableObject) this.getLogic()).getUpgrades();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
package com.extendedae_plus.mixin.ae2.compat;
|
||||||
|
|
||||||
|
import appeng.api.upgrades.Upgrades;
|
||||||
|
import appeng.client.gui.AEBaseScreen;
|
||||||
|
import appeng.client.gui.implementations.PatternProviderScreen;
|
||||||
|
import appeng.client.gui.style.ScreenStyle;
|
||||||
|
import appeng.client.gui.widgets.ToolboxPanel;
|
||||||
|
import appeng.client.gui.widgets.UpgradesPanel;
|
||||||
|
import appeng.core.localization.GuiText;
|
||||||
|
import appeng.menu.SlotSemantics;
|
||||||
|
import appeng.menu.implementations.PatternProviderMenu;
|
||||||
|
import com.extendedae_plus.compat.UpgradeSlotCompat;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PatternProviderScreen的兼容性Mixin
|
||||||
|
* 优先级设置为500,避免与appflux冲突
|
||||||
|
*/
|
||||||
|
@Mixin(value = PatternProviderScreen.class, priority = 500, remap = false)
|
||||||
|
public abstract class PatternProviderScreenCompatMixin<C extends PatternProviderMenu> extends AEBaseScreen<C> {
|
||||||
|
|
||||||
|
@Inject(method = "<init>", at = @At("TAIL"))
|
||||||
|
private void eap$initCompatUpgrades(PatternProviderMenu menu, Inventory playerInventory, Component title, ScreenStyle style, CallbackInfo ci) {
|
||||||
|
try {
|
||||||
|
// 检测是否应该添加升级面板
|
||||||
|
if (UpgradeSlotCompat.shouldAddUpgradePanelToScreen()) {
|
||||||
|
// 直接添加升级面板,不使用复杂的反射
|
||||||
|
this.eap$addUpgradePanelDirect(menu, style);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 静默处理异常,确保不会因为升级功能导致崩溃
|
||||||
|
com.extendedae_plus.util.ExtendedAELogger.LOGGER.error("PatternProviderScreen兼容性升级面板初始化失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private void eap$addUpgradePanelDirect(PatternProviderMenu menu, ScreenStyle style) {
|
||||||
|
try {
|
||||||
|
// 直接添加升级面板
|
||||||
|
this.widgets.add("upgrades", new UpgradesPanel(
|
||||||
|
menu.getSlots(SlotSemantics.UPGRADE),
|
||||||
|
this::eap$getCompatibleUpgrades));
|
||||||
|
|
||||||
|
// 添加工具箱面板(如果菜单实现了兼容接口)
|
||||||
|
if (menu instanceof UpgradeSlotCompat.IUpgradeableMenuCompat compatMenu) {
|
||||||
|
var toolbox = compatMenu.getCompatToolbox();
|
||||||
|
if (toolbox != null && toolbox.isPresent()) {
|
||||||
|
this.widgets.add("toolbox", new ToolboxPanel(style, toolbox.getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
com.extendedae_plus.util.ExtendedAELogger.LOGGER.error("直接添加升级面板失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private List<Component> eap$getCompatibleUpgrades() {
|
||||||
|
var list = new ArrayList<Component>();
|
||||||
|
list.add(GuiText.CompatibleUpgrades.text());
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (menu instanceof UpgradeSlotCompat.IUpgradeableMenuCompat compatMenu) {
|
||||||
|
var upgrades = compatMenu.getCompatUpgrades();
|
||||||
|
if (upgrades != null) {
|
||||||
|
list.addAll(Upgrades.getTooltipLinesForMachine(upgrades.getUpgradableItem()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
com.extendedae_plus.util.ExtendedAELogger.LOGGER.error("获取兼容升级列表失败", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构造函数,Mixin要求
|
||||||
|
public PatternProviderScreenCompatMixin(C menu, Inventory playerInventory, Component title, ScreenStyle style) {
|
||||||
|
super(menu, playerInventory, title, style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,12 +10,15 @@ import org.spongepowered.asm.mixin.Shadow;
|
||||||
/**
|
/**
|
||||||
* 让 PatternProviderLogicHost 作为 IUpgradeableObject 的代理,菜单可从 host 获取升级槽。
|
* 让 PatternProviderLogicHost 作为 IUpgradeableObject 的代理,菜单可从 host 获取升级槽。
|
||||||
*/
|
*/
|
||||||
@Mixin(value = PatternProviderLogicHost.class, remap = false)
|
@Mixin(value = PatternProviderLogicHost.class, priority = 2000, remap = false)
|
||||||
public interface PatternProviderLogicHostUpgradesMixin extends IUpgradeableObject {
|
public interface PatternProviderLogicHostUpgradesMixin extends IUpgradeableObject {
|
||||||
@Shadow PatternProviderLogic getLogic();
|
@Shadow PatternProviderLogic getLogic();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default IUpgradeInventory getUpgrades() {
|
default IUpgradeInventory getUpgrades() {
|
||||||
|
if (!com.extendedae_plus.compat.UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
return appeng.api.upgrades.UpgradeInventories.empty();
|
||||||
|
}
|
||||||
return ((IUpgradeableObject) this.getLogic()).getUpgrades();
|
return ((IUpgradeableObject) this.getLogic()).getUpgrades();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import appeng.api.upgrades.UpgradeInventories;
|
||||||
import appeng.helpers.patternprovider.PatternProviderLogic;
|
import appeng.helpers.patternprovider.PatternProviderLogic;
|
||||||
import appeng.helpers.patternprovider.PatternProviderLogicHost;
|
import appeng.helpers.patternprovider.PatternProviderLogicHost;
|
||||||
import com.extendedae_plus.ae.items.ChannelCardItem;
|
import com.extendedae_plus.ae.items.ChannelCardItem;
|
||||||
|
import com.extendedae_plus.compat.UpgradeSlotCompat;
|
||||||
import com.extendedae_plus.init.ModItems;
|
import com.extendedae_plus.init.ModItems;
|
||||||
import com.extendedae_plus.wireless.WirelessSlaveLink;
|
import com.extendedae_plus.wireless.WirelessSlaveLink;
|
||||||
import com.extendedae_plus.wireless.endpoint.GenericNodeEndpointImpl;
|
import com.extendedae_plus.wireless.endpoint.GenericNodeEndpointImpl;
|
||||||
|
|
@ -29,7 +30,7 @@ import java.util.List;
|
||||||
* 为 PatternProviderLogic 注入升级槽,实现 IUpgradeableObject。
|
* 为 PatternProviderLogic 注入升级槽,实现 IUpgradeableObject。
|
||||||
* 仅负责升级槽的持久化/掉落/清空与初始化,不改变原有逻辑。
|
* 仅负责升级槽的持久化/掉落/清空与初始化,不改变原有逻辑。
|
||||||
*/
|
*/
|
||||||
@Mixin(value = PatternProviderLogic.class, remap = false)
|
@Mixin(value = PatternProviderLogic.class, priority = 2000, remap = false)
|
||||||
public abstract class PatternProviderLogicUpgradesMixin implements IUpgradeableObject, InterfaceWirelessLinkBridge {
|
public abstract class PatternProviderLogicUpgradesMixin implements IUpgradeableObject, InterfaceWirelessLinkBridge {
|
||||||
@Unique
|
@Unique
|
||||||
private IUpgradeInventory eap$upgrades = UpgradeInventories.empty();
|
private IUpgradeInventory eap$upgrades = UpgradeInventories.empty();
|
||||||
|
|
@ -75,16 +76,27 @@ public abstract class PatternProviderLogicUpgradesMixin implements IUpgradeableO
|
||||||
@Inject(method = "<init>(Lappeng/api/networking/IManagedGridNode;Lappeng/helpers/patternprovider/PatternProviderLogicHost;I)V",
|
@Inject(method = "<init>(Lappeng/api/networking/IManagedGridNode;Lappeng/helpers/patternprovider/PatternProviderLogicHost;I)V",
|
||||||
at = @At("TAIL"))
|
at = @At("TAIL"))
|
||||||
private void eap$initUpgrades(IManagedGridNode mainNode, PatternProviderLogicHost host, int patternInventorySize, CallbackInfo ci) {
|
private void eap$initUpgrades(IManagedGridNode mainNode, PatternProviderLogicHost host, int patternInventorySize, CallbackInfo ci) {
|
||||||
|
// 只有在应该启用升级卡槽时才初始化
|
||||||
|
if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.eap$upgrades = UpgradeInventories.forMachine(host.getTerminalIcon().getItem(), 1, this::eap$onUpgradesChanged);
|
this.eap$upgrades = UpgradeInventories.forMachine(host.getTerminalIcon().getItem(), 1, this::eap$onUpgradesChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "writeToNBT", at = @At("TAIL"))
|
@Inject(method = "writeToNBT", at = @At("TAIL"))
|
||||||
private void eap$saveUpgrades(CompoundTag tag, CallbackInfo ci) {
|
private void eap$saveUpgrades(CompoundTag tag, CallbackInfo ci) {
|
||||||
|
if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.eap$upgrades.writeToNBT(tag, "upgrades");
|
this.eap$upgrades.writeToNBT(tag, "upgrades");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "readFromNBT", at = @At("TAIL"))
|
@Inject(method = "readFromNBT", at = @At("TAIL"))
|
||||||
private void eap$loadUpgrades(CompoundTag tag, CallbackInfo ci) {
|
private void eap$loadUpgrades(CompoundTag tag, CallbackInfo ci) {
|
||||||
|
if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.eap$upgrades.readFromNBT(tag, "upgrades");
|
this.eap$upgrades.readFromNBT(tag, "upgrades");
|
||||||
// 从 NBT 加载后,重置并尝试初始化(可能刚进入世界)
|
// 从 NBT 加载后,重置并尝试初始化(可能刚进入世界)
|
||||||
eap$lastChannel = -1;
|
eap$lastChannel = -1;
|
||||||
|
|
@ -94,6 +106,9 @@ public abstract class PatternProviderLogicUpgradesMixin implements IUpgradeableO
|
||||||
|
|
||||||
@Inject(method = "addDrops", at = @At("TAIL"))
|
@Inject(method = "addDrops", at = @At("TAIL"))
|
||||||
private void eap$dropUpgrades(List<ItemStack> drops, CallbackInfo ci) {
|
private void eap$dropUpgrades(List<ItemStack> drops, CallbackInfo ci) {
|
||||||
|
if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
for (var stack : this.eap$upgrades) {
|
for (var stack : this.eap$upgrades) {
|
||||||
if (!stack.isEmpty()) {
|
if (!stack.isEmpty()) {
|
||||||
drops.add(stack);
|
drops.add(stack);
|
||||||
|
|
@ -103,6 +118,9 @@ public abstract class PatternProviderLogicUpgradesMixin implements IUpgradeableO
|
||||||
|
|
||||||
@Inject(method = "clearContent", at = @At("TAIL"))
|
@Inject(method = "clearContent", at = @At("TAIL"))
|
||||||
private void eap$clearUpgrades(CallbackInfo ci) {
|
private void eap$clearUpgrades(CallbackInfo ci) {
|
||||||
|
if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.eap$upgrades.clear();
|
this.eap$upgrades.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -115,6 +133,9 @@ public abstract class PatternProviderLogicUpgradesMixin implements IUpgradeableO
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IUpgradeInventory getUpgrades() {
|
public IUpgradeInventory getUpgrades() {
|
||||||
|
if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
return UpgradeInventories.empty();
|
||||||
|
}
|
||||||
return this.eap$upgrades;
|
return this.eap$upgrades;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import appeng.menu.AEBaseMenu;
|
||||||
import appeng.menu.ToolboxMenu;
|
import appeng.menu.ToolboxMenu;
|
||||||
import appeng.menu.implementations.PatternProviderMenu;
|
import appeng.menu.implementations.PatternProviderMenu;
|
||||||
import com.extendedae_plus.bridge.IUpgradableMenu;
|
import com.extendedae_plus.bridge.IUpgradableMenu;
|
||||||
|
import com.extendedae_plus.compat.UpgradeSlotCompat;
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
import net.minecraft.world.inventory.MenuType;
|
import net.minecraft.world.inventory.MenuType;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
|
@ -18,7 +19,7 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
@Mixin(value = PatternProviderMenu.class, remap = false)
|
@Mixin(value = PatternProviderMenu.class, priority = 2000, remap = false)
|
||||||
public abstract class PatternProviderMenuUpgradesMixin extends AEBaseMenu implements IUpgradableMenu {
|
public abstract class PatternProviderMenuUpgradesMixin extends AEBaseMenu implements IUpgradableMenu {
|
||||||
@Final
|
@Final
|
||||||
@Shadow protected PatternProviderLogic logic;
|
@Shadow protected PatternProviderLogic logic;
|
||||||
|
|
@ -29,17 +30,28 @@ public abstract class PatternProviderMenuUpgradesMixin extends AEBaseMenu implem
|
||||||
@Inject(method = "<init>(Lnet/minecraft/world/inventory/MenuType;ILnet/minecraft/world/entity/player/Inventory;Lappeng/helpers/patternprovider/PatternProviderLogicHost;)V",
|
@Inject(method = "<init>(Lnet/minecraft/world/inventory/MenuType;ILnet/minecraft/world/entity/player/Inventory;Lappeng/helpers/patternprovider/PatternProviderLogicHost;)V",
|
||||||
at = @At("TAIL"))
|
at = @At("TAIL"))
|
||||||
private void eap$initUpgrades(MenuType<?> menuType, int id, Inventory playerInventory, PatternProviderLogicHost host, CallbackInfo ci) {
|
private void eap$initUpgrades(MenuType<?> menuType, int id, Inventory playerInventory, PatternProviderLogicHost host, CallbackInfo ci) {
|
||||||
|
// 只有在应该启用升级卡槽时才初始化
|
||||||
|
if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.eap$toolbox = new ToolboxMenu(this);
|
this.eap$toolbox = new ToolboxMenu(this);
|
||||||
this.setupUpgrades(((IUpgradeableObject) host).getUpgrades());
|
this.setupUpgrades(((IUpgradeableObject) host).getUpgrades());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ToolboxMenu getToolbox() {
|
public ToolboxMenu getToolbox() {
|
||||||
|
if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return this.eap$toolbox;
|
return this.eap$toolbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IUpgradeInventory getUpgrades() {
|
public IUpgradeInventory getUpgrades() {
|
||||||
|
if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
return appeng.api.upgrades.UpgradeInventories.empty();
|
||||||
|
}
|
||||||
return ((IUpgradeableObject) this.logic).getUpgrades();
|
return ((IUpgradeableObject) this.logic).getUpgrades();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
"ae2.client.gui.PatternEncodingTermScreenMixin",
|
"ae2.client.gui.PatternEncodingTermScreenMixin",
|
||||||
"ae2.client.gui.PatternProviderCloseMixin",
|
"ae2.client.gui.PatternProviderCloseMixin",
|
||||||
"ae2.client.gui.PatternProviderScreenMixin",
|
"ae2.client.gui.PatternProviderScreenMixin",
|
||||||
"ae2.client.gui.PatternProviderScreenUpgradesMixin",
|
"ae2.compat.PatternProviderScreenCompatMixin",
|
||||||
"ae2.client.gui.SlotGridLayoutMixin",
|
"ae2.client.gui.SlotGridLayoutMixin",
|
||||||
"ae2.menu.CraftConfirmMenuGoBackMixin",
|
"ae2.menu.CraftConfirmMenuGoBackMixin",
|
||||||
"extendedae.accessor.GuiExPatternTerminalAccessor",
|
"extendedae.accessor.GuiExPatternTerminalAccessor",
|
||||||
|
|
@ -63,9 +63,9 @@
|
||||||
"ae2.menu.PatternEncodingTermMenuMixin",
|
"ae2.menu.PatternEncodingTermMenuMixin",
|
||||||
"ae2.menu.PatternProviderMenuAdvancedMixin",
|
"ae2.menu.PatternProviderMenuAdvancedMixin",
|
||||||
"ae2.menu.PatternProviderMenuDoublingMixin",
|
"ae2.menu.PatternProviderMenuDoublingMixin",
|
||||||
"ae2.helpers.patternprovider.PatternProviderLogicUpgradesMixin",
|
"ae2.compat.PatternProviderLogicCompatMixin",
|
||||||
"ae2.helpers.patternprovider.PatternProviderLogicHostUpgradesMixin",
|
"ae2.compat.PatternProviderLogicHostCompatMixin",
|
||||||
"ae2.menu.PatternProviderMenuUpgradesMixin",
|
"ae2.compat.PatternProviderCompatMixin",
|
||||||
"ae2.helpers.patternprovider.PatternProviderLogicTickerMixin",
|
"ae2.helpers.patternprovider.PatternProviderLogicTickerMixin",
|
||||||
"ae2.parts.AEBasePartClientSyncMixin",
|
"ae2.parts.AEBasePartClientSyncMixin",
|
||||||
"ae2.parts.automation.IOBusPartChannelCardMixin",
|
"ae2.parts.automation.IOBusPartChannelCardMixin",
|
||||||
|
|
@ -84,5 +84,6 @@
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
},
|
},
|
||||||
|
"plugin": "com.extendedae_plus.mixin.MixinConditions",
|
||||||
"priority": 1000
|
"priority": 1000
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user