feat: 添加对高级ae的高级处理样板倍增支持

This commit is contained in:
C-H716 2025-10-07 18:04:16 +08:00
parent a6c6691f6f
commit 4c407e412b
4 changed files with 96 additions and 9 deletions

View File

@ -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; // 原始样板引用

View File

@ -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<AEKey, Direction> 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);
}
}
}
}

View File

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

View File

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