From 4c407e412be2b0c8029917ea0bd468b75a762680 Mon Sep 17 00:00:00 2001 From: C-H716 <1536152356@qq.com> Date: Tue, 7 Oct 2025 18:04:16 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=AF=B9=E9=AB=98?= =?UTF-8?q?=E7=BA=A7ae=E7=9A=84=E9=AB=98=E7=BA=A7=E5=A4=84=E7=90=86?= =?UTF-8?q?=E6=A0=B7=E6=9D=BF=E5=80=8D=E5=A2=9E=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/crafting/ScaledProcessingPattern.java | 2 +- .../crafting/ScaledProcessingPatternAdv.java | 69 +++++++++++++++++++ .../autopattern/CraftingTreeProcessMixin.java | 18 +++-- .../util/smartDoubling/PatternScaler.java | 16 ++++- 4 files changed, 96 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/extendedae_plus/ae/api/crafting/ScaledProcessingPatternAdv.java diff --git a/src/main/java/com/extendedae_plus/ae/api/crafting/ScaledProcessingPattern.java b/src/main/java/com/extendedae_plus/ae/api/crafting/ScaledProcessingPattern.java index ab8c924..c402127 100644 --- a/src/main/java/com/extendedae_plus/ae/api/crafting/ScaledProcessingPattern.java +++ b/src/main/java/com/extendedae_plus/ae/api/crafting/ScaledProcessingPattern.java @@ -15,7 +15,7 @@ import java.util.Objects; * 缩放后的处理样板,结构完全模拟 AEProcessingPattern。 * 保持 sparse/condensed/inputs 的一致性,同时保存原始样板。 */ -public final class ScaledProcessingPattern implements IPatternDetails { +public class ScaledProcessingPattern implements IPatternDetails { // 最小化实例字段:只保留原始样板引用、定义和倍数 private final AEProcessingPattern original; // 原始样板引用 diff --git a/src/main/java/com/extendedae_plus/ae/api/crafting/ScaledProcessingPatternAdv.java b/src/main/java/com/extendedae_plus/ae/api/crafting/ScaledProcessingPatternAdv.java new file mode 100644 index 0000000..f36a716 --- /dev/null +++ b/src/main/java/com/extendedae_plus/ae/api/crafting/ScaledProcessingPatternAdv.java @@ -0,0 +1,69 @@ +package com.extendedae_plus.ae.api.crafting; + +import appeng.api.stacks.AEItemKey; +import appeng.api.stacks.AEKey; +import appeng.api.stacks.GenericStack; +import appeng.api.stacks.KeyCounter; +import appeng.crafting.pattern.AEProcessingPattern; +import net.minecraft.core.Direction; +import net.pedroksl.advanced_ae.common.patterns.AdvPatternDetails; + +import java.util.HashMap; + +/** + * Advanced AE 扩展版,额外实现 AdvPatternDetails 接口。 + * 仅在 Advanced AE 加载时使用。 + */ +public final class ScaledProcessingPatternAdv extends ScaledProcessingPattern implements AdvPatternDetails { + + private final AdvPatternDetails adv; + + public ScaledProcessingPatternAdv(AEProcessingPattern original, AEItemKey definition, long multiplier) { + super(original, definition, multiplier); + this.adv = (AdvPatternDetails) original; + } + + @Override + public boolean directionalInputsSet() { + return adv.directionalInputsSet(); + } + + @Override + public HashMap getDirectionMap() { + return adv.getDirectionMap(); + } + + @Override + public Direction getDirectionSideForInputKey(AEKey key) { + return adv.getDirectionSideForInputKey(key); + } + + @Override + public void pushInputsToExternalInventory(KeyCounter[] inputHolder, PatternInputSink inputSink) { + // 使用 lazy 计算的 sparseInputs 与 inputs 来驱动;当两者长度一致时直接委托 + GenericStack[] sInputs = getSparseInputs(); + IInput[] ins = getInputs(); + if (sInputs.length == ins.length) { + super.pushInputsToExternalInventory(inputHolder, inputSink); + return; + } + + KeyCounter allInputs = new KeyCounter(); + for (KeyCounter counter : inputHolder) { + allInputs.addAll(counter); + } + for (GenericStack sparseInput : sInputs) { + if (sparseInput != null) { + AEKey key = sparseInput.what(); + long amount = sparseInput.amount(); + long available = allInputs.get(key); + if (available < amount) { + throw new RuntimeException("Expected at least %d of %s when pushing scaled pattern, but only %d available" + .formatted(amount, key, available)); + } + inputSink.pushInput(key, amount); + allInputs.remove(key, amount); + } + } + } +} diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/CraftingTreeProcessMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/CraftingTreeProcessMixin.java index 25a1ff1..605caae 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/CraftingTreeProcessMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/CraftingTreeProcessMixin.java @@ -36,20 +36,24 @@ public abstract class CraftingTreeProcessMixin { argsOnly = true, remap = false ) - private static IPatternDetails eap$replaceDetailsAtHead(IPatternDetails original, ICraftingService cc, CraftingCalculation job, IPatternDetails details, CraftingTreeNode craftingTreeNode) { + private static IPatternDetails eap$replaceDetailsAtHead(IPatternDetails original, + ICraftingService cc, + CraftingCalculation job, + IPatternDetails details, + CraftingTreeNode craftingTreeNode) { try { // 若传入的 details 已经是缩放样板,且原始样板不允许缩放,则直接解包为原始样板 if (details instanceof ScaledProcessingPattern sp) { - var proc0 = sp.getOriginal(); - if (proc0 instanceof ISmartDoublingAwarePattern aware0 && !aware0.eap$allowScaling()) { - return proc0; + var originalPattern = sp.getOriginal(); + if (originalPattern instanceof ISmartDoublingAwarePattern scalingAwarePattern && !scalingAwarePattern.eap$allowScaling()) { + return originalPattern; } } - if (!(details instanceof AEProcessingPattern proc)) return original; + if (!(details instanceof AEProcessingPattern processingPattern)) return original; // 若样板标记为不允许缩放,则直接跳过 - if (proc instanceof ISmartDoublingAwarePattern aware && !aware.eap$allowScaling()) { + if (processingPattern instanceof ISmartDoublingAwarePattern aware && !aware.eap$allowScaling()) { return original; } @@ -89,7 +93,7 @@ public abstract class CraftingTreeProcessMixin { } // 使用每-provider 的分配量来缩放样板 - var scaled = PatternScaler.scale(proc, parentTarget, perProvider); + var scaled = PatternScaler.scale(processingPattern, parentTarget, perProvider); return scaled != null ? scaled : original; } catch (Exception e) { EAP$LOGGER.warn("构建倍增样板出错", e); diff --git a/src/main/java/com/extendedae_plus/util/smartDoubling/PatternScaler.java b/src/main/java/com/extendedae_plus/util/smartDoubling/PatternScaler.java index 3a2eccf..eef400e 100644 --- a/src/main/java/com/extendedae_plus/util/smartDoubling/PatternScaler.java +++ b/src/main/java/com/extendedae_plus/util/smartDoubling/PatternScaler.java @@ -4,8 +4,10 @@ import appeng.api.stacks.AEKey; import appeng.api.stacks.GenericStack; import appeng.crafting.pattern.AEProcessingPattern; import com.extendedae_plus.ae.api.crafting.ScaledProcessingPattern; +import com.extendedae_plus.ae.api.crafting.ScaledProcessingPatternAdv; import com.extendedae_plus.api.smartDoubling.ISmartDoublingAwarePattern; import com.extendedae_plus.config.ModConfig; +import net.minecraftforge.fml.ModList; public final class PatternScaler { private PatternScaler() { @@ -72,7 +74,19 @@ public final class PatternScaler { } catch (Throwable ignore) { // 配置读取异常时不施加上限 } - + if (ModList.get().isLoaded("advanced_ae")) { + // 如果加载了 Advanced AE 且 base 实现了 AdvPatternDetails,返回兼容版 + try { + // 软依赖,不直接 import advIface + Class advIface = Class.forName("net.pedroksl.advanced_ae.common.patterns.AdvPatternDetails"); + if (advIface.isInstance(base)) { + // 直接 new ScaledProcessingPatternAdv,父类字段会正常初始化 + return new ScaledProcessingPatternAdv(base, base.getDefinition(), multiplier); + } + } catch (Throwable ignore) { + // 如果 Advanced AE 不存在或反射失败,就忽略,继续走普通逻辑 + } + } // 仅使用 multiplier 构建轻量化 ScaledProcessingPattern(具体视图按需计算) return new ScaledProcessingPattern(base, base.getDefinition(), multiplier); }