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); }