feat: 添加对advancedae供应器的智能翻倍支持

This commit is contained in:
C-H716 2025-08-31 02:56:58 +08:00
parent d50b18812b
commit 9fa9a41a4f
6 changed files with 60 additions and 17 deletions

View File

@ -106,6 +106,9 @@ dependencies {
//mae2
// modRuntimeOnly "curse.maven:modern-ae2-additions-1028068:6342203"
modCompileOnly "curse.maven:modern-ae2-additions-1028068:6342203"
//advancedae
modCompileOnly "curse.maven:advancedae-1084104:5957960"
}
allprojects {

View File

@ -9,7 +9,7 @@ import org.spongepowered.asm.mixin.injection.Redirect;
import java.util.List;
/**
/**适配
* Redirect PatternProviderLogic.pushPattern 中对 List.contains 的调用
* 在遇到缩放样板时回退匹配到原始样板实例
*/

View File

@ -0,0 +1,40 @@
package com.extendedae_plus.mixin.ae2.autopattern.adaptation;
import appeng.api.crafting.IPatternDetails;
import com.extendedae_plus.content.ScaledProcessingPattern;
import net.pedroksl.advanced_ae.common.logic.AdvPatternProviderLogic;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.util.List;
/**适配
* Redirect PatternProviderLogic.pushPattern 中对 List.contains 的调用
* 在遇到缩放样板时回退匹配到原始样板实例
*/
@Pseudo
@Mixin(value = AdvPatternProviderLogic.class, remap = false)
public class AdvPatternProviderLogicContainsRedirectMixin {
@Redirect(method = "pushPattern",
at = @At(
value = "INVOKE",
target = "Ljava/util/List;contains(Ljava/lang/Object;)Z")
)
private boolean eap$patternsContains(List<?> list, Object o) {
try {
if (o instanceof ScaledProcessingPattern scaled) {
IPatternDetails base = scaled.getOriginal();
if (base != null && list.indexOf(base) != -1) {
return true;
}
}
// 使用 indexOf 避免再次触发对 List.contains redirect防止递归
return list.indexOf(o) != -1;
} catch (Throwable t) {
return list.indexOf(o) != -1;
}
}
}

View File

@ -9,6 +9,7 @@ import appeng.client.gui.style.ScreenStyle;
import appeng.client.gui.widgets.AETextField;
import appeng.client.gui.widgets.IconButton;
import appeng.menu.AEBaseMenu;
import com.extendedae_plus.mixin.extendedae.accessor.GuiExPatternTerminalAccessor;
import com.extendedae_plus.network.ModNetwork;
import com.extendedae_plus.network.OpenProviderUiC2SPacket;
import com.glodblock.github.extendedae.client.gui.GuiExPatternTerminal;
@ -39,9 +40,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.*;
@Pseudo
@Mixin(value = GuiExPatternTerminal.class)
@ -218,12 +217,11 @@ public abstract class GuiExPatternTerminalMixin extends AEBaseScreen<AEBaseMenu>
private void eap$tryOpenProviderUI(int rowIndex) {
try {
// 使用 Accessor 获取 rows避免取到父类导致失败
com.extendedae_plus.mixin.extendedae.accessor.GuiExPatternTerminalAccessor acc =
(com.extendedae_plus.mixin.extendedae.accessor.GuiExPatternTerminalAccessor) (Object) this;
java.util.ArrayList<?> rows = acc.getRows();
GuiExPatternTerminalAccessor acc = (GuiExPatternTerminalAccessor) this;
ArrayList<?> rows = acc.getRows();
// 找到该分组对应的第一个 PatternContainerRecord
Class<?> cls = com.glodblock.github.extendedae.client.gui.GuiExPatternTerminal.class;
Class<?> cls = GuiExPatternTerminal.class;
var byGroupField = cls.getDeclaredField("byGroup");
byGroupField.setAccessible(true);
Object byGroup = byGroupField.get(this); // HashMultimap<PatternContainerGroup, PatternContainerRecord>
@ -234,7 +232,7 @@ public abstract class GuiExPatternTerminalMixin extends AEBaseScreen<AEBaseMenu>
Object group = groupField.get(headerRow);
// 调用 byGroup.get(group)再取第一个元素
java.util.Collection<?> containers = (java.util.Collection<?>) byGroup.getClass().getMethod("get", Object.class).invoke(byGroup, group);
Collection<?> containers = (Collection<?>) byGroup.getClass().getMethod("get", Object.class).invoke(byGroup, group);
if (containers == null || containers.isEmpty()) {
return;
}
@ -245,7 +243,7 @@ public abstract class GuiExPatternTerminalMixin extends AEBaseScreen<AEBaseMenu>
var infoMapField = cls.getDeclaredField("infoMap");
infoMapField.setAccessible(true);
@SuppressWarnings("unchecked")
java.util.HashMap<Long, Object> infoMap = (java.util.HashMap<Long, Object>) infoMapField.get(this);
HashMap<Long, Object> infoMap = (HashMap<Long, Object>) infoMapField.get(this);
Object info = infoMap.get(serverId);
if (info == null) {
// 无位置信息提示
@ -299,7 +297,7 @@ public abstract class GuiExPatternTerminalMixin extends AEBaseScreen<AEBaseMenu>
// 通过反射调用refreshList方法 - 先尝试当前类失败后尝试父类
try {
java.lang.reflect.Method refreshMethod = null;
Method refreshMethod = null;
try {
// 先尝试在当前类中查找
refreshMethod = this.getClass().getDeclaredMethod("refreshList");
@ -514,13 +512,12 @@ public abstract class GuiExPatternTerminalMixin extends AEBaseScreen<AEBaseMenu>
// 动态放置/创建每个组标题后的打开UI按钮
try {
// 使用 Accessor 获取必要的字段避免反射失败
com.extendedae_plus.mixin.extendedae.accessor.GuiExPatternTerminalAccessor acc =
(com.extendedae_plus.mixin.extendedae.accessor.GuiExPatternTerminalAccessor) (Object) this;
GuiExPatternTerminalAccessor acc = (GuiExPatternTerminalAccessor) this;
java.util.ArrayList<?> rows = acc.getRows();
int currentScroll = acc.getScrollbar().getCurrentScroll();
// 直接引用目标类以获取其静态常量
Class<?> cls = com.glodblock.github.extendedae.client.gui.GuiExPatternTerminal.class;
Class<?> cls = GuiExPatternTerminal.class;
int GUI_PADDING_X = getIntConst(cls, "GUI_PADDING_X", 22);
int GUI_PADDING_Y = getIntConst(cls, "GUI_PADDING_Y", 6);
int GUI_HEADER_HEIGHT = getIntConst(cls, "GUI_HEADER_HEIGHT", 51);

View File

@ -8,12 +8,12 @@ import appeng.helpers.patternprovider.PatternProviderLogic;
import appeng.helpers.patternprovider.PatternProviderLogicHost;
import appeng.me.service.CraftingService;
import appeng.menu.AEBaseMenu;
import appeng.menu.me.crafting.CraftingCPUMenu;
import appeng.menu.locator.MenuLocators;
import appeng.menu.me.crafting.CraftingCPUMenu;
import appeng.parts.AEBasePart;
import com.extendedae_plus.mixin.ae2.accessor.PatternProviderLogicAccessor;
import com.mojang.logging.LogUtils;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.network.NetworkEvent;
@ -94,7 +94,7 @@ public class CraftingMonitorOpenProviderC2SPacket {
// 直接打开供应器自身的 UI调用 Host 默认方法
try {
// 部件与方块实体分别选择定位器
if (host instanceof appeng.parts.AEBasePart part) {
if (host instanceof AEBasePart part) {
host.openMenu(player, MenuLocators.forPart(part));
} else {
host.openMenu(player, MenuLocators.forBlockEntity(pbe));
@ -112,4 +112,6 @@ public class CraftingMonitorOpenProviderC2SPacket {
});
context.setPacketHandled(true);
}
}

View File

@ -41,6 +41,7 @@
"ae2.autopattern.CraftingTreeNodeMixin",
"ae2.autopattern.CraftingTreeProcessMixin",
"ae2.autopattern.PatternProviderLogicContainsRedirectMixin",
"ae2.autopattern.adaptation.AdvPatternProviderLogicContainsRedirectMixin",
"ae2.helpers.PatternProviderLogicAdvancedMixin",
"ae2.helpers.PatternProviderLogicDoublingMixin",
"ae2.menu.ContainerPatternEncodingTermMenuMixin",