package com.extendedae_plus.util; import appeng.api.stacks.AEKey; import appeng.api.stacks.GenericStack; import appeng.crafting.pattern.AEProcessingPattern; import com.extendedae_plus.api.SmartDoublingAwarePattern; import com.extendedae_plus.config.ModConfigs; import com.extendedae_plus.content.ScaledProcessingPattern; public final class PatternScaler { private PatternScaler() { } public static ScaledProcessingPattern scale(AEProcessingPattern base, AEKey target, long requestedAmount) { if (base == null) throw new IllegalArgumentException("base"); if (target == null) throw new IllegalArgumentException("target"); // 双保险:若样板标记为不允许缩放,直接放弃缩放(返回 null 表示调用方应保持原样板) if (base instanceof SmartDoublingAwarePattern aware && !aware.eap$allowScaling()) { return null; } GenericStack[] baseOutputs = base.getOutputs(); // 新逻辑:不再对样板进行单位化处理 // 找到目标输出在 outputs 中的索引(尝试匹配 target,否则取第一个非空输出) int targetOutIndex = -1; for (int i = 0; i < baseOutputs.length; i++) { var out = baseOutputs[i]; if (out != null && target != null && out.what() != null && out.what().equals(target)) { targetOutIndex = i; break; } } if (targetOutIndex == -1) { for (int i = 0; i < baseOutputs.length; i++) { if (baseOutputs[i] != null) { targetOutIndex = i; break; } } } if (targetOutIndex == -1 && baseOutputs.length > 0) targetOutIndex = 0; long perOperationTarget = 1L; if (targetOutIndex >= 0 && baseOutputs[targetOutIndex] != null) { long amt = baseOutputs[targetOutIndex].amount(); if (amt > 0) perOperationTarget = amt; } // 使用最小整数倍(ceil)策略:直接选择满足请求的最小倍数 long multiplier = 1L; if (requestedAmount > 0) { long needed = requestedAmount / perOperationTarget + ((requestedAmount % perOperationTarget) == 0 ? 0 : 1); multiplier = needed <= 1L ? 1L : needed; } // 小请求绕过:若请求量小且不会带来收益,则不启用缩放(返回 null) try { int minBenefit = ModConfigs.SMART_SCALING_MIN_BENEFIT_FACTOR.get(); if (minBenefit > 1 && requestedAmount > 0 && requestedAmount < perOperationTarget * (long) minBenefit) { return null; } } catch (Throwable ignore) { // 配置读取异常时保持默认行为(不绕过) } // 应用配置的最大倍数上限(0 表示不限制) try { int maxMul = ModConfigs.SMART_SCALING_MAX_MULTIPLIER.get(); if (maxMul > 0 && multiplier > maxMul) { multiplier = maxMul; } } catch (Throwable ignore) { // 配置读取异常时不施加上限 } // 仅使用 multiplier 构建轻量化 ScaledProcessingPattern(具体视图按需计算) return new ScaledProcessingPattern(base, base.getDefinition(), multiplier); } }