优化appflux升级槽兼容
This commit is contained in:
parent
7d621af169
commit
38b06eb484
|
|
@ -87,7 +87,7 @@ dependencies {
|
|||
modImplementation "appeng:appliedenergistics2-forge:${ae2_version}"
|
||||
modImplementation "org.appliedenergistics:guideme:${guideme_version}"
|
||||
modImplementation "curse.maven:applied-energistics-2-wireless-terminals-459929:${wireless_terminals_version}"
|
||||
modImplementation "curse.maven:applied-flux-965012:7072853"
|
||||
modCompileOnly "curse.maven:applied-flux-965012:7072853"
|
||||
modImplementation "curse.maven:mega-cells-622112:${mega_cells_version}"
|
||||
|
||||
//mae2
|
||||
|
|
|
|||
|
|
@ -3,14 +3,31 @@ package com.extendedae_plus.compat;
|
|||
import appeng.api.upgrades.IUpgradeInventory;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 升级卡槽兼容性管理类
|
||||
* 检测ExtendedAE-appflux模组是否存在,如果存在则使用其升级卡槽功能
|
||||
* 否则使用我们自己的实现
|
||||
* 统一管理:
|
||||
* 1. 是否由我们自己提供升级槽
|
||||
* 2. appflux存在时是否复用其升级槽
|
||||
* 3. appflux PatternProviderLogic 的反射访问入口
|
||||
*/
|
||||
public class UpgradeSlotCompat {
|
||||
public final class UpgradeSlotCompat {
|
||||
private static final String APPFLUX_MOD_ID = "appflux";
|
||||
|
||||
private static final int LOCAL_PATTERN_PROVIDER_UPGRADE_SLOTS = 2;
|
||||
private static final int APPFLUX_PATTERN_PROVIDER_UPGRADE_SLOTS = 2;
|
||||
private static final String[] APPFLUX_UPGRADES_FIELD_NAMES = { "af_upgrades", "af_$upgrades" };
|
||||
private static final String[] APPFLUX_UPGRADES_CHANGED_METHOD_NAMES = { "af_onUpgradesChanged", "af_$onUpgradesChanged" };
|
||||
|
||||
private static Field patternProviderAppfluxUpgradesField;
|
||||
private static boolean patternProviderAppfluxUpgradesFieldResolved;
|
||||
private static Method patternProviderAppfluxUpgradesChangedMethod;
|
||||
private static boolean patternProviderAppfluxUpgradesChangedMethodResolved;
|
||||
|
||||
private UpgradeSlotCompat() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测Applied Flux模组是否存在
|
||||
* @return true如果存在,false如果不存在
|
||||
|
|
@ -18,16 +35,36 @@ public class UpgradeSlotCompat {
|
|||
public static boolean isAppfluxPresent() {
|
||||
return ModList.get().isLoaded(APPFLUX_MOD_ID);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 是否由我们自己提供升级槽实现。
|
||||
*/
|
||||
public static boolean usesDedicatedUpgradeSlots() {
|
||||
return !isAppfluxPresent();
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否应当复用 appflux 注入到 PatternProviderLogic 上的升级槽。
|
||||
*/
|
||||
public static boolean usesAppfluxUpgradeSlots() {
|
||||
return isAppfluxPresent();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测是否应该启用我们的升级卡槽功能
|
||||
* @return true如果应该启用,false如果检测到appflux模组存在
|
||||
*/
|
||||
public static boolean shouldEnableUpgradeSlots() {
|
||||
boolean appfluxExists = isAppfluxPresent();
|
||||
return !appfluxExists;
|
||||
return usesDedicatedUpgradeSlots();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 是否需要持久化和管理我们本地创建的升级槽。
|
||||
*/
|
||||
public static boolean shouldManageLocalUpgradeInventory() {
|
||||
return usesDedicatedUpgradeSlots();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测是否应该启用频道卡功能
|
||||
* 频道卡是我们独有的功能,即使appflux存在也应该启用
|
||||
|
|
@ -36,19 +73,105 @@ public class UpgradeSlotCompat {
|
|||
public static boolean shouldEnableChannelCard() {
|
||||
return true; // 频道卡功能总是启用,因为appflux没有实现这个功能
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* appflux 存在时,我们仍然需要监听其升级槽变化来驱动额外的兼容逻辑。
|
||||
*/
|
||||
public static boolean shouldListenToAppfluxUpgrades() {
|
||||
return usesAppfluxUpgradeSlots();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测是否应该在Screen中添加升级面板
|
||||
* @return true如果应该添加,false如果检测到appflux模组存在
|
||||
*/
|
||||
public static boolean shouldAddUpgradePanelToScreen() {
|
||||
return shouldEnableUpgradeSlots();
|
||||
return usesDedicatedUpgradeSlots();
|
||||
}
|
||||
|
||||
/**
|
||||
* 兼容性升级菜单接口
|
||||
*/
|
||||
public interface IUpgradeableMenuCompat {
|
||||
IUpgradeInventory getCompatUpgrades();
|
||||
public static int getPatternProviderLocalUpgradeSlots() {
|
||||
return LOCAL_PATTERN_PROVIDER_UPGRADE_SLOTS;
|
||||
}
|
||||
|
||||
public static int getPatternProviderAppfluxUpgradeSlots() {
|
||||
return APPFLUX_PATTERN_PROVIDER_UPGRADE_SLOTS;
|
||||
}
|
||||
|
||||
public static IUpgradeInventory getPatternProviderAppfluxUpgrades(Object logicInstance) {
|
||||
Field field = resolvePatternProviderAppfluxUpgradesField(logicInstance.getClass());
|
||||
if (field == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
Object value = field.get(logicInstance);
|
||||
return value instanceof IUpgradeInventory inventory ? inventory : null;
|
||||
} catch (IllegalAccessException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean setPatternProviderAppfluxUpgrades(Object logicInstance, IUpgradeInventory inventory) {
|
||||
Field field = resolvePatternProviderAppfluxUpgradesField(logicInstance.getClass());
|
||||
if (field == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
field.set(logicInstance, inventory);
|
||||
return true;
|
||||
} catch (IllegalAccessException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean invokePatternProviderAppfluxUpgradesChanged(Object logicInstance) throws ReflectiveOperationException {
|
||||
Method method = resolvePatternProviderAppfluxUpgradesChangedMethod(logicInstance.getClass());
|
||||
if (method == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
method.invoke(logicInstance);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Field resolvePatternProviderAppfluxUpgradesField(Class<?> logicClass) {
|
||||
if (!patternProviderAppfluxUpgradesFieldResolved) {
|
||||
patternProviderAppfluxUpgradesField = findField(logicClass, APPFLUX_UPGRADES_FIELD_NAMES);
|
||||
patternProviderAppfluxUpgradesFieldResolved = true;
|
||||
}
|
||||
return patternProviderAppfluxUpgradesField;
|
||||
}
|
||||
|
||||
private static Method resolvePatternProviderAppfluxUpgradesChangedMethod(Class<?> logicClass) {
|
||||
if (!patternProviderAppfluxUpgradesChangedMethodResolved) {
|
||||
patternProviderAppfluxUpgradesChangedMethod = findMethod(logicClass, APPFLUX_UPGRADES_CHANGED_METHOD_NAMES);
|
||||
patternProviderAppfluxUpgradesChangedMethodResolved = true;
|
||||
}
|
||||
return patternProviderAppfluxUpgradesChangedMethod;
|
||||
}
|
||||
|
||||
private static Field findField(Class<?> owner, String[] candidates) {
|
||||
for (String candidate : candidates) {
|
||||
try {
|
||||
Field field = owner.getDeclaredField(candidate);
|
||||
field.setAccessible(true);
|
||||
return field;
|
||||
} catch (NoSuchFieldException ignored) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Method findMethod(Class<?> owner, String[] candidates) {
|
||||
for (String candidate : candidates) {
|
||||
try {
|
||||
Method method = owner.getDeclaredMethod(candidate);
|
||||
method.setAccessible(true);
|
||||
return method;
|
||||
} catch (NoSuchMethodException ignored) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,11 @@ public class MixinConditions implements IMixinConfigPlugin {
|
|||
return ModCheckUtils.isLoaded(ModCheckUtils.MODID_AAE);
|
||||
}
|
||||
|
||||
// === AppFlux 兼容 ===
|
||||
if (mixinClassName.startsWith("com.extendedae_plus.mixin.appflux")) {
|
||||
return ModCheckUtils.isLoaded(ModCheckUtils.MODID_APPFLUX);
|
||||
}
|
||||
|
||||
// === GuideME 版本兼容 ===
|
||||
if (mixinClassName.startsWith("com.extendedae_plus.mixin.guideme.")) {
|
||||
return ModCheckUtils.isLoadedAndLowerThan(ModCheckUtils.MODID_GUIDEME, "20.1.14");
|
||||
|
|
|
|||
|
|
@ -1,22 +1,48 @@
|
|||
package com.extendedae_plus.mixin.ae2.client.gui.patternProvider;
|
||||
|
||||
import appeng.api.upgrades.IUpgradeableObject;
|
||||
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.UpgradesPanel;
|
||||
import appeng.core.localization.GuiText;
|
||||
import appeng.menu.SlotSemantics;
|
||||
import appeng.menu.implementations.PatternProviderMenu;
|
||||
import com.extendedae_plus.compat.UpgradeSlotCompat;
|
||||
import com.extendedae_plus.mixin.ae2.accessor.PatternProviderMenuAccessor;
|
||||
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;
|
||||
|
||||
@Mixin(PatternProviderScreen.class)
|
||||
public abstract class PatternProviderScreenMixin<C extends PatternProviderMenu> extends AEBaseScreen<C> {
|
||||
public PatternProviderScreenMixin(C menu, Inventory playerInventory, Component title, ScreenStyle style) {
|
||||
super(menu, playerInventory, title, style);
|
||||
}
|
||||
|
||||
@Inject(method = "<init>", at = @At("TAIL"))
|
||||
private void eap$initCompatUpgrades(PatternProviderMenu menu, Inventory playerInventory, Component title, ScreenStyle style, CallbackInfo ci) {
|
||||
if (!UpgradeSlotCompat.shouldAddUpgradePanelToScreen()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.widgets.add("upgrades", new UpgradesPanel(
|
||||
menu.getSlots(SlotSemantics.UPGRADE),
|
||||
this::eap$getCompatibleUpgrades));
|
||||
} catch (Exception e) {
|
||||
com.extendedae_plus.util.Logger.EAP$LOGGER.error("PatternProviderScreen兼容性升级面板初始化失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示样板供应器的customName
|
||||
*/
|
||||
|
|
@ -27,4 +53,23 @@ public abstract class PatternProviderScreenMixin<C extends PatternProviderMenu>
|
|||
this.setTextContent(AEBaseScreen.TEXT_ID_DIALOG_TITLE, t);
|
||||
}
|
||||
}
|
||||
|
||||
@Unique
|
||||
private List<Component> eap$getCompatibleUpgrades() {
|
||||
var list = new ArrayList<Component>();
|
||||
list.add(GuiText.CompatibleUpgrades.text());
|
||||
|
||||
try {
|
||||
if (((PatternProviderMenuAccessor) this.menu).eap$logic() instanceof IUpgradeableObject upgradeableLogic) {
|
||||
var upgrades = upgradeableLogic.getUpgrades();
|
||||
if (upgrades != null) {
|
||||
list.addAll(Upgrades.getTooltipLinesForMachine(upgrades.getUpgradableItem()));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
com.extendedae_plus.util.Logger.EAP$LOGGER.error("获取兼容升级列表失败", e);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ 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;
|
||||
|
|
@ -21,9 +20,7 @@ import static com.extendedae_plus.util.Logger.EAP$LOGGER;
|
|||
* 优先级设置为500,低于appflux的默认优先级,避免冲突
|
||||
*/
|
||||
@Mixin(value = PatternProviderMenu.class, priority = 500, remap = false)
|
||||
public abstract class PatternProviderCompatMixin extends AEBaseMenu implements UpgradeSlotCompat.IUpgradeableMenuCompat {
|
||||
@Unique
|
||||
private IUpgradeInventory eap$compatUpgrades;
|
||||
public abstract class PatternProviderCompatMixin extends AEBaseMenu {
|
||||
|
||||
public PatternProviderCompatMixin(MenuType<?> menuType, int id, Inventory playerInventory, Object host) {
|
||||
super(menuType, id, playerInventory, host);
|
||||
|
|
@ -33,12 +30,10 @@ public abstract class PatternProviderCompatMixin extends AEBaseMenu implements U
|
|||
at = @At("TAIL"))
|
||||
private void eap$initCompatUpgrades(MenuType<?> menuType, int id, Inventory playerInventory, PatternProviderLogicHost host, CallbackInfo ci) {
|
||||
try {
|
||||
// 检测是否应该启用升级卡槽功能
|
||||
if (UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||
// 直接初始化升级功能
|
||||
if (host instanceof IUpgradeableObject upgradeableHost) {
|
||||
this.eap$compatUpgrades = upgradeableHost.getUpgrades();
|
||||
this.setupUpgrades(this.eap$compatUpgrades);
|
||||
if (UpgradeSlotCompat.shouldManageLocalUpgradeInventory()) {
|
||||
if (host.getLogic() instanceof IUpgradeableObject upgradeableLogic) {
|
||||
IUpgradeInventory upgrades = upgradeableLogic.getUpgrades();
|
||||
this.setupUpgrades(upgrades);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
|
@ -46,9 +41,4 @@ public abstract class PatternProviderCompatMixin extends AEBaseMenu implements U
|
|||
EAP$LOGGER.error("PatternProviderMenu兼容性升级初始化失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IUpgradeInventory getCompatUpgrades() {
|
||||
return this.eap$compatUpgrades;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,12 +33,11 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* PatternProviderLogic的兼容性Mixin
|
||||
* 优先级设置为1500,在appflux之后应用
|
||||
* 优先级设置为500,在appflux之前应用
|
||||
* 根据appflux是否存在来决定是否实现IUpgradeableObject接口
|
||||
*/
|
||||
@Mixin(value = PatternProviderLogic.class, priority = 500, remap = false)
|
||||
|
|
@ -77,9 +76,6 @@ public abstract class PatternProviderLogicCompatMixin implements IUpgradeableObj
|
|||
@Unique
|
||||
private boolean eap$compatVirtualCraftingEnabled = false;
|
||||
|
||||
@Unique
|
||||
private static Field eap$compatAppfluxUpgradesField;
|
||||
|
||||
@Shadow
|
||||
public abstract IGrid getGrid();
|
||||
|
||||
|
|
@ -159,13 +155,11 @@ public abstract class PatternProviderLogicCompatMixin implements IUpgradeableObj
|
|||
}
|
||||
}
|
||||
|
||||
// 监听appflux的升级变化 - 通过注入到appflux的af_$onUpgradesChanged方法
|
||||
@Inject(method = "af_$onUpgradesChanged", at = @At("TAIL"), remap = false, require = 0)
|
||||
private void eap$onAppfluxUpgradesChanged(CallbackInfo ci) {
|
||||
@Unique
|
||||
private void eap$compatOnExternalUpgradesChanged() {
|
||||
try {
|
||||
eap$compatSyncVirtualCraftingState();
|
||||
if (UpgradeSlotCompat.shouldEnableChannelCard()) {
|
||||
// 升级变更,重置并尝试初始化频道卡
|
||||
eap$compatLastChannel = -1;
|
||||
eap$compatHasInitialized = false;
|
||||
eap$compatInitializeChannelLink();
|
||||
|
|
@ -175,25 +169,34 @@ public abstract class PatternProviderLogicCompatMixin implements IUpgradeableObj
|
|||
}
|
||||
}
|
||||
|
||||
// 监听 appflux 1.21.1 当前源码中的升级变化回调
|
||||
@Inject(method = "af_onUpgradesChanged", at = @At("TAIL"), remap = false, require = 0)
|
||||
private void eap$onAppfluxUpgradesChanged(CallbackInfo ci) {
|
||||
eap$compatOnExternalUpgradesChanged();
|
||||
}
|
||||
|
||||
// 兼容旧命名,避免不同 appflux 版本导致注入失效
|
||||
@Inject(method = "af_$onUpgradesChanged", at = @At("TAIL"), remap = false, require = 0)
|
||||
private void eap$onLegacyAppfluxUpgradesChanged(CallbackInfo ci) {
|
||||
eap$compatOnExternalUpgradesChanged();
|
||||
}
|
||||
|
||||
@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 {
|
||||
|
||||
boolean upgradeSlots = UpgradeSlotCompat.shouldEnableUpgradeSlots();
|
||||
boolean upgradeSlots = UpgradeSlotCompat.shouldManageLocalUpgradeInventory();
|
||||
boolean channelCard = UpgradeSlotCompat.shouldEnableChannelCard();
|
||||
|
||||
|
||||
if (upgradeSlots) {
|
||||
// 只有在升级槽功能启用时才创建升级槽
|
||||
this.eap$compatUpgrades = UpgradeInventories.forMachine(
|
||||
host.getTerminalIcon().getItem(),
|
||||
2,
|
||||
this::eap$compatOnUpgradesChanged
|
||||
host.getTerminalIcon().getItem(),
|
||||
UpgradeSlotCompat.getPatternProviderLocalUpgradeSlots(),
|
||||
this::eap$compatOnUpgradesChanged
|
||||
);
|
||||
} else if (channelCard) {
|
||||
// 如果装了appflux,我们不创建自己的升级槽,而是监听appflux的升级槽
|
||||
} else {
|
||||
} else if (!channelCard) {
|
||||
this.eap$compatUpgrades = UpgradeInventories.empty();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.EAP$LOGGER.error("兼容性升级初始化失败", e);
|
||||
|
|
@ -203,7 +206,7 @@ public abstract class PatternProviderLogicCompatMixin implements IUpgradeableObj
|
|||
@Inject(method = "writeToNBT", at = @At("TAIL"))
|
||||
private void eap$compatSaveUpgrades(CompoundTag tag, CallbackInfo ci) {
|
||||
try {
|
||||
if (UpgradeSlotCompat.shouldEnableUpgradeSlots() || UpgradeSlotCompat.shouldEnableChannelCard()) {
|
||||
if (UpgradeSlotCompat.shouldManageLocalUpgradeInventory()) {
|
||||
this.eap$compatUpgrades.writeToNBT(tag, "compat_upgrades");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
|
@ -214,15 +217,16 @@ public abstract class PatternProviderLogicCompatMixin implements IUpgradeableObj
|
|||
@Inject(method = "readFromNBT", at = @At("TAIL"))
|
||||
private void eap$compatLoadUpgrades(CompoundTag tag, CallbackInfo ci) {
|
||||
try {
|
||||
if (UpgradeSlotCompat.shouldEnableUpgradeSlots() || UpgradeSlotCompat.shouldEnableChannelCard()) {
|
||||
if (UpgradeSlotCompat.shouldManageLocalUpgradeInventory()) {
|
||||
this.eap$compatUpgrades.readFromNBT(tag, "compat_upgrades");
|
||||
if (UpgradeSlotCompat.shouldEnableChannelCard()) {
|
||||
eap$compatLastChannel = -1;
|
||||
eap$compatHasInitialized = false;
|
||||
eap$compatInitializeChannelLink();
|
||||
}
|
||||
eap$compatSyncVirtualCraftingState();
|
||||
}
|
||||
|
||||
if (UpgradeSlotCompat.shouldEnableChannelCard()) {
|
||||
eap$compatLastChannel = -1;
|
||||
eap$compatHasInitialized = false;
|
||||
eap$compatInitializeChannelLink();
|
||||
}
|
||||
eap$compatSyncVirtualCraftingState();
|
||||
} catch (Exception e) {
|
||||
Logger.EAP$LOGGER.error("兼容性升级加载失败", e);
|
||||
}
|
||||
|
|
@ -231,7 +235,7 @@ public abstract class PatternProviderLogicCompatMixin implements IUpgradeableObj
|
|||
@Inject(method = "addDrops", at = @At("TAIL"))
|
||||
private void eap$compatDropUpgrades(List<ItemStack> drops, CallbackInfo ci) {
|
||||
try {
|
||||
if (UpgradeSlotCompat.shouldEnableUpgradeSlots() || UpgradeSlotCompat.shouldEnableChannelCard()) {
|
||||
if (UpgradeSlotCompat.shouldManageLocalUpgradeInventory()) {
|
||||
for (var stack : this.eap$compatUpgrades) {
|
||||
if (!stack.isEmpty()) {
|
||||
drops.add(stack);
|
||||
|
|
@ -246,8 +250,10 @@ public abstract class PatternProviderLogicCompatMixin implements IUpgradeableObj
|
|||
@Inject(method = "clearContent", at = @At("TAIL"))
|
||||
private void eap$compatClearUpgrades(CallbackInfo ci) {
|
||||
try {
|
||||
if (UpgradeSlotCompat.shouldEnableUpgradeSlots() || UpgradeSlotCompat.shouldEnableChannelCard()) {
|
||||
if (UpgradeSlotCompat.shouldManageLocalUpgradeInventory()) {
|
||||
this.eap$compatUpgrades.clear();
|
||||
}
|
||||
if (UpgradeSlotCompat.shouldEnableChannelCard()) {
|
||||
eap$compatVirtualCraftingEnabled = false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
|
@ -257,7 +263,7 @@ public abstract class PatternProviderLogicCompatMixin implements IUpgradeableObj
|
|||
|
||||
@Override
|
||||
public IUpgradeInventory getUpgrades() {
|
||||
if (UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||
if (UpgradeSlotCompat.shouldManageLocalUpgradeInventory()) {
|
||||
return this.eap$compatUpgrades != null ? this.eap$compatUpgrades : UpgradeInventories.empty();
|
||||
} else {
|
||||
return eap$compatGetEffectiveUpgradeInventory();
|
||||
|
|
@ -396,29 +402,17 @@ public abstract class PatternProviderLogicCompatMixin implements IUpgradeableObj
|
|||
|
||||
@Unique
|
||||
private IUpgradeInventory eap$compatGetEffectiveUpgradeInventory() {
|
||||
if (UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||
if (UpgradeSlotCompat.shouldManageLocalUpgradeInventory()) {
|
||||
return this.eap$compatUpgrades;
|
||||
}
|
||||
|
||||
if (!UpgradeSlotCompat.shouldEnableChannelCard()) {
|
||||
if (!UpgradeSlotCompat.shouldListenToAppfluxUpgrades()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (this.eap$compatUpgrades != null && this.eap$compatUpgrades != UpgradeInventories.empty()) {
|
||||
return this.eap$compatUpgrades;
|
||||
}
|
||||
|
||||
try {
|
||||
if (eap$compatAppfluxUpgradesField == null) {
|
||||
eap$compatAppfluxUpgradesField = PatternProviderLogic.class.getDeclaredField("af_$upgrades");
|
||||
eap$compatAppfluxUpgradesField.setAccessible(true);
|
||||
}
|
||||
Object value = eap$compatAppfluxUpgradesField.get(this);
|
||||
if (value instanceof IUpgradeInventory inventory) {
|
||||
return inventory;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.EAP$LOGGER.error("获取appflux升级槽失败", e);
|
||||
IUpgradeInventory inventory = UpgradeSlotCompat.getPatternProviderAppfluxUpgrades(this);
|
||||
if (inventory != null) {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
return UpgradeInventories.empty();
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
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() && !UpgradeSlotCompat.shouldEnableChannelCard()) {
|
||||
return UpgradeInventories.empty();
|
||||
}
|
||||
return ((IUpgradeableObject) this.getLogic()).getUpgrades();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
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.UpgradesPanel;
|
||||
import appeng.core.localization.GuiText;
|
||||
import appeng.menu.SlotSemantics;
|
||||
import appeng.menu.implementations.PatternProviderMenu;
|
||||
import com.extendedae_plus.compat.UpgradeSlotCompat;
|
||||
import com.extendedae_plus.util.Logger;
|
||||
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> {
|
||||
public PatternProviderScreenCompatMixin(C menu, Inventory playerInventory, Component title, ScreenStyle style) {
|
||||
super(menu, playerInventory, title, style);
|
||||
}
|
||||
|
||||
@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) {
|
||||
// 静默处理异常,确保不会因为升级功能导致崩溃
|
||||
Logger.EAP$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));
|
||||
} catch (Exception e) {
|
||||
Logger.EAP$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) {
|
||||
Logger.EAP$LOGGER.error("获取兼容升级列表失败", e);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
|
@ -13,12 +13,9 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 当appflux存在时,修改PatternProviderLogic的升级槽数量为2个
|
||||
* 优先级设置为2000,确保在appflux之后应用
|
||||
* 当 appflux 存在时,把它默认的 1 槽升级栏扩展为我们兼容层需要的 2 槽。
|
||||
* 优先级设置为 2000,确保在 appflux 自己初始化之后执行。
|
||||
*/
|
||||
@Mixin(value = PatternProviderLogic.class, priority = 2000, remap = false)
|
||||
public class AppfluxPatternProviderLogicMixin {
|
||||
|
|
@ -30,59 +27,42 @@ public class AppfluxPatternProviderLogicMixin {
|
|||
at = @At("TAIL"))
|
||||
private void eap$modifyAppfluxUpgradeSlots(IManagedGridNode mainNode, PatternProviderLogicHost host, int patternInventorySize, CallbackInfo ci) {
|
||||
try {
|
||||
if (host instanceof MirrorPatternProviderBlockEntity) {
|
||||
if (host instanceof MirrorPatternProviderBlockEntity || !UpgradeSlotCompat.shouldListenToAppfluxUpgrades()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 只有当appflux存在且不启用我们的升级槽时才修改数量
|
||||
if (!UpgradeSlotCompat.shouldEnableUpgradeSlots() && UpgradeSlotCompat.shouldEnableChannelCard()) {
|
||||
IUpgradeInventory currentUpgrades = UpgradeSlotCompat.getPatternProviderAppfluxUpgrades(this);
|
||||
if (currentUpgrades == null) {
|
||||
Logger.EAP$LOGGER.debug("未找到appflux升级槽字段,跳过升级槽兼容调整");
|
||||
return;
|
||||
}
|
||||
|
||||
// 使用反射找到appflux的升级槽字段并替换
|
||||
try {
|
||||
Field upgradesField = PatternProviderLogic.class.getDeclaredField("af_$upgrades");
|
||||
upgradesField.setAccessible(true);
|
||||
IUpgradeInventory currentUpgrades = (IUpgradeInventory) upgradesField.get(this);
|
||||
Method onUpgradesChanged = null;
|
||||
try {
|
||||
onUpgradesChanged = PatternProviderLogic.class.getDeclaredMethod("af_$onUpgradesChanged");
|
||||
onUpgradesChanged.setAccessible(true);
|
||||
} catch (NoSuchMethodException ignored) {
|
||||
}
|
||||
|
||||
if (currentUpgrades != null) {
|
||||
int targetSlots = UpgradeSlotCompat.getPatternProviderAppfluxUpgradeSlots();
|
||||
if (currentUpgrades.size() == targetSlots) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建新的2槽升级槽
|
||||
Method finalOnUpgradesChanged = onUpgradesChanged;
|
||||
IUpgradeInventory newUpgrades = UpgradeInventories.forMachine(
|
||||
host.getTerminalIcon().getItem(),
|
||||
2,
|
||||
() -> {
|
||||
try {
|
||||
if (finalOnUpgradesChanged != null) {
|
||||
finalOnUpgradesChanged.invoke(this);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.EAP$LOGGER.error("调用appflux升级变更方法失败", e);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 复制原有升级卡到新的升级槽
|
||||
for (int i = 0; i < Math.min(currentUpgrades.size(), newUpgrades.size()); i++) {
|
||||
if (!currentUpgrades.getStackInSlot(i).isEmpty()) {
|
||||
newUpgrades.insertItem(i, currentUpgrades.getStackInSlot(i).copy(), false);
|
||||
}
|
||||
IUpgradeInventory newUpgrades = UpgradeInventories.forMachine(
|
||||
host.getTerminalIcon().getItem(),
|
||||
targetSlots,
|
||||
() -> {
|
||||
try {
|
||||
UpgradeSlotCompat.invokePatternProviderAppfluxUpgradesChanged(this);
|
||||
} catch (Exception e) {
|
||||
Logger.EAP$LOGGER.error("调用appflux升级变更方法失败", e);
|
||||
}
|
||||
|
||||
// 替换升级槽
|
||||
upgradesField.set(this, newUpgrades);
|
||||
}
|
||||
} catch (NoSuchFieldException e) {
|
||||
Logger.EAP$LOGGER.debug("未找到appflux升级槽字段,跳过升级槽兼容调整");
|
||||
} catch (Exception e) {
|
||||
Logger.EAP$LOGGER.error("反射修改appflux升级槽失败", e);
|
||||
);
|
||||
|
||||
for (int i = 0; i < Math.min(currentUpgrades.size(), newUpgrades.size()); i++) {
|
||||
if (!currentUpgrades.getStackInSlot(i).isEmpty()) {
|
||||
newUpgrades.insertItem(i, currentUpgrades.getStackInSlot(i).copy(), false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!UpgradeSlotCompat.setPatternProviderAppfluxUpgrades(this, newUpgrades)) {
|
||||
Logger.EAP$LOGGER.debug("设置appflux升级槽失败,跳过升级槽兼容调整");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.EAP$LOGGER.error("AppfluxPatternProviderLogicMixin执行失败", e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
"ae2.client.gui.patternProvider.PatternProviderHighlightCleanupMixin",
|
||||
"ae2.client.gui.patternProvider.PatternProviderScreenMixin",
|
||||
"ae2.client.gui.patternProvider.PatternProviderSmartFeaturesMixin",
|
||||
"ae2.compat.PatternProviderScreenCompatMixin",
|
||||
"ae2.items.QuartzCuttingKnifeItemMixin",
|
||||
"ae2.menu.CraftConfirmMenuGoBackMixin",
|
||||
"extendedae.accessor.GuiExPatternTerminalAccessor",
|
||||
|
|
@ -66,7 +65,6 @@
|
|||
"ae2.autopattern.PatternProviderLogicContainsRedirectMixin",
|
||||
"ae2.compat.PatternProviderCompatMixin",
|
||||
"ae2.compat.PatternProviderLogicCompatMixin",
|
||||
"ae2.compat.PatternProviderLogicHostCompatMixin",
|
||||
"ae2.helpers.InterfaceLogicChannelCardMixin",
|
||||
"ae2.helpers.InterfaceLogicTickerMixin",
|
||||
"ae2.helpers.InterfaceLogicUpgradesMixin",
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user