Merge branch 'develop/iava' into develop/gtceu_support
# Conflicts: # src/main/resources/extendedae_plus.mixins.json
This commit is contained in:
commit
04869a616e
|
|
@ -18,6 +18,7 @@ public class ModConfigScreen extends Screen {
|
|||
private CycleButton<Boolean> crossDimToggle;
|
||||
private CycleButton<Boolean> providerRoundRobinToggle;
|
||||
private EditBox smartScalingMaxMulBox;
|
||||
private EditBox smartScalingMinBenefitBox;
|
||||
private CycleButton<Boolean> showEncoderToggle;
|
||||
private CycleButton<Boolean> patternTerminalShowSlotsToggle;
|
||||
|
||||
|
|
@ -66,6 +67,13 @@ public class ModConfigScreen extends Screen {
|
|||
this.addRenderableWidget(smartScalingMaxMulBox);
|
||||
row++;
|
||||
|
||||
// smartScalingMinBenefitFactor: Int 1-1024
|
||||
smartScalingMinBenefitBox = new EditBox(this.font, rightX, y + row * rowHeight, boxWidth, 20, Component.translatable("config.extendedae_plus.smartScalingMinBenefitFactor"));
|
||||
smartScalingMinBenefitBox.setValue(String.valueOf(ModConfigs.SMART_SCALING_MIN_BENEFIT_FACTOR.get()));
|
||||
smartScalingMinBenefitBox.setFilter(s -> s.matches("\\d*") && parseIntOrDefault(s, 1) >= 1 && parseIntOrDefault(s, 1024) <= 1024);
|
||||
this.addRenderableWidget(smartScalingMinBenefitBox);
|
||||
row++;
|
||||
|
||||
// show encoder pattern player toggle
|
||||
showEncoderToggle = this.addRenderableWidget(createToggle(rightX, y + row * rowHeight, boxWidth, 20, ModConfigs.SHOW_ENCOD_PATTERN_PLAYER.get()));
|
||||
row++;
|
||||
|
|
@ -95,6 +103,7 @@ public class ModConfigScreen extends Screen {
|
|||
boolean crossDim = crossDimToggle.getValue();
|
||||
boolean providerRoundRobin = providerRoundRobinToggle.getValue();
|
||||
int smartMaxMul = clamp(parseIntOrDefault(smartScalingMaxMulBox.getValue(), ModConfigs.SMART_SCALING_MAX_MULTIPLIER.get()), 0, 1048576);
|
||||
int smartMinBenefit = clamp(parseIntOrDefault(smartScalingMinBenefitBox.getValue(), ModConfigs.SMART_SCALING_MIN_BENEFIT_FACTOR.get()), 1, 1024);
|
||||
boolean showEncoder = showEncoderToggle.getValue();
|
||||
boolean patternShowSlots = patternTerminalShowSlotsToggle.getValue();
|
||||
|
||||
|
|
@ -104,6 +113,7 @@ public class ModConfigScreen extends Screen {
|
|||
ModConfigs.WIRELESS_CROSS_DIM_ENABLE.set(crossDim);
|
||||
ModConfigs.PROVIDER_ROUND_ROBIN_ENABLE.set(providerRoundRobin);
|
||||
ModConfigs.SMART_SCALING_MAX_MULTIPLIER.set(smartMaxMul);
|
||||
ModConfigs.SMART_SCALING_MIN_BENEFIT_FACTOR.set(smartMinBenefit);
|
||||
ModConfigs.SHOW_ENCOD_PATTERN_PLAYER.set(showEncoder);
|
||||
ModConfigs.PATTERN_TERMINAL_SHOW_SLOTS_DEFAULT.set(patternShowSlots);
|
||||
|
||||
|
|
@ -144,8 +154,9 @@ public class ModConfigScreen extends Screen {
|
|||
g.drawString(this.font, Component.translatable("config.extendedae_plus.wirelessCrossDimEnable"), leftX, y + 2 * rowHeight + 6, labelColor, false);
|
||||
g.drawString(this.font, Component.translatable("config.extendedae_plus.providerRoundRobinEnable"), leftX, y + 3 * rowHeight + 6, labelColor, false);
|
||||
g.drawString(this.font, Component.translatable("config.extendedae_plus.smartScalingMaxMultiplier_with_range"), leftX, y + 4 * rowHeight + 6, labelColor, false);
|
||||
g.drawString(this.font, Component.translatable("config.extendedae_plus.showEncoderPatternPlayer"), leftX, y + 5 * rowHeight + 6, labelColor, false);
|
||||
g.drawString(this.font, Component.translatable("config.extendedae_plus.patternTerminalShowSlotsDefault"), leftX, y + 6 * rowHeight + 6, labelColor, false);
|
||||
g.drawString(this.font, Component.translatable("config.extendedae_plus.smartScalingMinBenefitFactor"), leftX, y + 5 * rowHeight + 6, labelColor, false);
|
||||
g.drawString(this.font, Component.translatable("config.extendedae_plus.showEncoderPatternPlayer"), leftX, y + 6 * rowHeight + 6, labelColor, false);
|
||||
g.drawString(this.font, Component.translatable("config.extendedae_plus.patternTerminalShowSlotsDefault"), leftX, y + 7 * rowHeight + 6, labelColor, false);
|
||||
}
|
||||
|
||||
private static int parseIntOrDefault(String s, int def) {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ public final class ModConfigs {
|
|||
public static final ForgeConfigSpec.BooleanValue PROVIDER_ROUND_ROBIN_ENABLE;
|
||||
public static final ForgeConfigSpec.BooleanValue PATTERN_TERMINAL_SHOW_SLOTS_DEFAULT;
|
||||
public static final ForgeConfigSpec.IntValue SMART_SCALING_MAX_MULTIPLIER;
|
||||
public static final ForgeConfigSpec.IntValue SMART_SCALING_MIN_BENEFIT_FACTOR;
|
||||
|
||||
static {
|
||||
ForgeConfigSpec.Builder builder = new ForgeConfigSpec.Builder();
|
||||
|
|
@ -61,6 +62,13 @@ public final class ModConfigs {
|
|||
"此倍数是针对单次样板产出的放大倍数上限,用于限制一次推送中按倍增缩放的规模")
|
||||
.defineInRange("smartScalingMaxMultiplier", 0, 0, 1048576);
|
||||
|
||||
// 智能倍增最小收益因子:若 requestedAmount < perOperationTarget * 此因子,则不启用缩放(默认 4)
|
||||
SMART_SCALING_MIN_BENEFIT_FACTOR = builder
|
||||
.comment(
|
||||
"智能倍增最小收益因子(默认 4)",
|
||||
"当目标请求量小于 perOperationTarget * 此因子 时,智能倍增将不被启用以避免无意义包装")
|
||||
.defineInRange("smartScalingMinBenefitFactor", 4, 1, 1024);
|
||||
|
||||
// 模式访问终端(ExtendedAE 图样终端)默认是否显示槽位渲染(SlotsRow)。
|
||||
// true: 默认显示(可通过界面按钮临时隐藏);false: 默认隐藏(可通过按钮显示)
|
||||
PATTERN_TERMINAL_SHOW_SLOTS_DEFAULT = builder
|
||||
|
|
|
|||
|
|
@ -17,27 +17,21 @@ import java.util.Objects;
|
|||
*/
|
||||
public final class ScaledProcessingPattern implements IPatternDetails {
|
||||
|
||||
private final AEProcessingPattern original; // 原始样板引用
|
||||
private final AEItemKey definition; // 样板物品
|
||||
private final GenericStack[] sparseInputs; // 缩放后的稀疏输入
|
||||
private final GenericStack[] sparseOutputs; // 缩放后的稀疏输出
|
||||
private final IInput[] inputs; // 缩放后的压缩输入
|
||||
private final GenericStack[] condensedOutputs; // 缩放后的压缩输出
|
||||
// 最小化实例字段:只保留原始样板引用、定义和倍数
|
||||
private final AEProcessingPattern original; // 原始样板引用
|
||||
private final AEItemKey definition; // 样板物品(直接委托自 original)
|
||||
private final long multiplier; // 乘数(外部可视为视图参数)
|
||||
|
||||
public ScaledProcessingPattern(
|
||||
AEProcessingPattern original,
|
||||
AEItemKey definition,
|
||||
GenericStack[] sparseInputs,
|
||||
GenericStack[] sparseOutputs,
|
||||
IInput[] inputs,
|
||||
GenericStack[] condensedOutputs
|
||||
) {
|
||||
// 延迟计算缓存(轻量化实例时避免在构造器中分配大数组)
|
||||
private transient volatile IInput[] inputsCache;
|
||||
private transient volatile GenericStack[] outputsCache;
|
||||
private transient volatile GenericStack[] sparseInputsCache;
|
||||
private transient volatile GenericStack[] sparseOutputsCache;
|
||||
|
||||
public ScaledProcessingPattern(AEProcessingPattern original, AEItemKey definition, long multiplier) {
|
||||
this.original = Objects.requireNonNull(original);
|
||||
this.definition = Objects.requireNonNull(definition);
|
||||
this.sparseInputs = Objects.requireNonNull(sparseInputs);
|
||||
this.sparseOutputs = Objects.requireNonNull(sparseOutputs);
|
||||
this.inputs = Objects.requireNonNull(inputs);
|
||||
this.condensedOutputs = Objects.requireNonNull(condensedOutputs);
|
||||
this.multiplier = multiplier <= 0 ? 1L : multiplier;
|
||||
}
|
||||
|
||||
/* -------------------- API 实现 -------------------- */
|
||||
|
|
@ -53,25 +47,91 @@ public final class ScaledProcessingPattern implements IPatternDetails {
|
|||
|
||||
@Override
|
||||
public IInput[] getInputs() {
|
||||
return inputs;
|
||||
IInput[] cached = this.inputsCache;
|
||||
if (cached == null) {
|
||||
synchronized (this) {
|
||||
cached = this.inputsCache;
|
||||
if (cached == null) {
|
||||
var base = original.getInputs();
|
||||
IInput[] arr = new IInput[base.length];
|
||||
for (int i = 0; i < base.length; i++) {
|
||||
var in = base[i];
|
||||
// 不复制 template 数组,直接复用原始的 possible inputs;仅放大 multiplier
|
||||
arr[i] = new Input(in.getPossibleInputs(), in.getMultiplier() * this.multiplier);
|
||||
}
|
||||
this.inputsCache = arr;
|
||||
cached = arr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cached;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GenericStack[] getOutputs() {
|
||||
return condensedOutputs;
|
||||
GenericStack[] cached = this.outputsCache;
|
||||
if (cached == null) {
|
||||
synchronized (this) {
|
||||
cached = this.outputsCache;
|
||||
if (cached == null) {
|
||||
var baseOutputs = original.getOutputs();
|
||||
GenericStack[] arr = new GenericStack[baseOutputs.length];
|
||||
for (int i = 0; i < baseOutputs.length; i++) {
|
||||
var o = baseOutputs[i];
|
||||
if (o != null) arr[i] = new GenericStack(o.what(), o.amount() * this.multiplier);
|
||||
}
|
||||
this.outputsCache = arr;
|
||||
cached = arr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cached;
|
||||
}
|
||||
|
||||
public GenericStack[] getSparseInputs() {
|
||||
return sparseInputs;
|
||||
GenericStack[] cached = this.sparseInputsCache;
|
||||
if (cached == null) {
|
||||
synchronized (this) {
|
||||
cached = this.sparseInputsCache;
|
||||
if (cached == null) {
|
||||
var base = original.getSparseInputs();
|
||||
GenericStack[] arr = new GenericStack[base.length];
|
||||
for (int i = 0; i < base.length; i++) {
|
||||
var v = base[i];
|
||||
if (v != null) arr[i] = new GenericStack(v.what(), v.amount() * this.multiplier);
|
||||
}
|
||||
this.sparseInputsCache = arr;
|
||||
cached = arr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cached;
|
||||
}
|
||||
|
||||
public GenericStack[] getSparseOutputs() {
|
||||
return sparseOutputs;
|
||||
GenericStack[] cached = this.sparseOutputsCache;
|
||||
if (cached == null) {
|
||||
synchronized (this) {
|
||||
cached = this.sparseOutputsCache;
|
||||
if (cached == null) {
|
||||
var base = original.getSparseOutputs();
|
||||
GenericStack[] arr = new GenericStack[base.length];
|
||||
for (int i = 0; i < base.length; i++) {
|
||||
var v = base[i];
|
||||
if (v != null) arr[i] = new GenericStack(v.what(), v.amount() * this.multiplier);
|
||||
}
|
||||
this.sparseOutputsCache = arr;
|
||||
cached = arr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cached;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GenericStack getPrimaryOutput() {
|
||||
if (condensedOutputs.length > 0) return condensedOutputs[0];
|
||||
var outs = getOutputs();
|
||||
if (outs.length > 0 && outs[0] != null) return outs[0];
|
||||
return original.getPrimaryOutput();
|
||||
}
|
||||
|
||||
|
|
@ -82,26 +142,29 @@ public final class ScaledProcessingPattern implements IPatternDetails {
|
|||
|
||||
@Override
|
||||
public void pushInputsToExternalInventory(KeyCounter[] inputHolder, PatternInputSink inputSink) {
|
||||
// 保持和 AEProcessingPattern 一致,用 sparseInputs 驱动
|
||||
if (sparseInputs.length == inputs.length) {
|
||||
// 使用 lazy 计算的 sparseInputs 与 inputs 来驱动;当两者长度一致时直接委托
|
||||
GenericStack[] sInputs = getSparseInputs();
|
||||
IInput[] ins = getInputs();
|
||||
if (sInputs.length == ins.length) {
|
||||
IPatternDetails.super.pushInputsToExternalInventory(inputHolder, inputSink);
|
||||
} else {
|
||||
KeyCounter allInputs = new KeyCounter();
|
||||
for (KeyCounter counter : inputHolder) {
|
||||
allInputs.addAll(counter);
|
||||
}
|
||||
for (GenericStack sparseInput : sparseInputs) {
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -117,18 +180,22 @@ public final class ScaledProcessingPattern implements IPatternDetails {
|
|||
this.multiplier = multiplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GenericStack[] getPossibleInputs() {
|
||||
return this.template;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMultiplier() {
|
||||
return this.multiplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(AEKey input, Level level) {
|
||||
return input.matches(this.template[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable AEKey getRemainingKey(AEKey template) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,11 +113,12 @@ public abstract class ContainerPatternEncodingTermMenuMixin implements IActionHo
|
|||
}
|
||||
}
|
||||
|
||||
// 服务器端:在构造样板返回前插入编码玩家的名称
|
||||
@Inject(method = "encodePattern", at = @At("TAIL"), remap = false, cancellable = true)
|
||||
private void eap$writeEncodePlayerToPattern(CallbackInfoReturnable<ItemStack> cir) {
|
||||
@Inject(method = "encodePattern", at = @At("RETURN"), remap = false, cancellable = true)
|
||||
private void onEncodePatternReturn(CallbackInfoReturnable<ItemStack> cir) {
|
||||
ItemStack itemStack = cir.getReturnValue();
|
||||
itemStack.getOrCreateTag().putString("encodePlayer", this.epp$player.getGameProfile().getName());
|
||||
cir.setReturnValue(itemStack);
|
||||
if (itemStack != null && !itemStack.isEmpty()) {
|
||||
itemStack.getOrCreateTag().putString("encodePlayer", this.epp$player.getGameProfile().getName());
|
||||
cir.setReturnValue(itemStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,11 @@
|
|||
package com.extendedae_plus.util;
|
||||
|
||||
import appeng.api.crafting.IPatternDetails.IInput;
|
||||
import appeng.api.stacks.AEKey;
|
||||
import appeng.api.stacks.GenericStack;
|
||||
import appeng.crafting.pattern.AEProcessingPattern;
|
||||
import com.extendedae_plus.content.ScaledProcessingPattern;
|
||||
import com.extendedae_plus.api.SmartDoublingAwarePattern;
|
||||
import com.extendedae_plus.config.ModConfigs;
|
||||
|
||||
|
||||
import static com.extendedae_plus.util.ExtendedAELogger.LOGGER;
|
||||
import com.extendedae_plus.content.ScaledProcessingPattern;
|
||||
|
||||
public final class PatternScaler {
|
||||
private PatternScaler() {
|
||||
|
|
@ -24,9 +20,6 @@ public final class PatternScaler {
|
|||
return null;
|
||||
}
|
||||
|
||||
GenericStack[] baseSparseInputs = base.getSparseInputs();
|
||||
GenericStack[] baseSparseOutputs = base.getSparseOutputs();
|
||||
IInput[] baseInputs = base.getInputs();
|
||||
GenericStack[] baseOutputs = base.getOutputs();
|
||||
|
||||
// 新逻辑:不再对样板进行单位化处理
|
||||
|
|
@ -61,6 +54,15 @@ public final class PatternScaler {
|
|||
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();
|
||||
|
|
@ -71,48 +73,7 @@ public final class PatternScaler {
|
|||
// 配置读取异常时不施加上限
|
||||
}
|
||||
|
||||
// 构建压缩输入(将每个输入的 multiplier 翻倍,保留每个模板的原始数量)
|
||||
IInput[] scaledInputs = new IInput[baseInputs.length];
|
||||
for (int i = 0; i < baseInputs.length; i++) {
|
||||
var in = baseInputs[i];
|
||||
var template = in.getPossibleInputs();
|
||||
GenericStack[] scaledTemplates = new GenericStack[template.length];
|
||||
for (int j = 0; j < template.length; j++) {
|
||||
scaledTemplates[j] = new GenericStack(template[j].what(), template[j].amount());
|
||||
}
|
||||
scaledInputs[i] = new ScaledProcessingPattern.Input(scaledTemplates, in.getMultiplier() * multiplier);
|
||||
}
|
||||
|
||||
/* 4. 构建压缩输出 */
|
||||
GenericStack[] scaledCondensedOutputs = new GenericStack[baseOutputs.length];
|
||||
for (int i = 0; i < baseOutputs.length; i++) {
|
||||
GenericStack out = baseOutputs[i];
|
||||
if (out != null) {
|
||||
scaledCondensedOutputs[i] = new GenericStack(out.what(), out.amount() * multiplier);
|
||||
}
|
||||
}
|
||||
|
||||
// 构建并打印稀疏表示(直接按 multiplier 放大)
|
||||
GenericStack[] scaledSparseInputs = new GenericStack[baseSparseInputs.length];
|
||||
for (int i = 0; i < baseSparseInputs.length; i++) {
|
||||
var in = baseSparseInputs[i];
|
||||
if (in != null) {
|
||||
scaledSparseInputs[i] = new GenericStack(in.what(), in.amount() * multiplier);
|
||||
}
|
||||
}
|
||||
GenericStack[] scaledSparseOutputs = new GenericStack[baseSparseOutputs.length];
|
||||
for (int i = 0; i < baseSparseOutputs.length; i++) {
|
||||
var out = baseSparseOutputs[i];
|
||||
if (out != null) {
|
||||
scaledSparseOutputs[i] = new GenericStack(out.what(), out.amount() * multiplier);
|
||||
}
|
||||
}
|
||||
|
||||
return new ScaledProcessingPattern(base,
|
||||
base.getDefinition(),
|
||||
scaledSparseInputs,
|
||||
scaledSparseOutputs,
|
||||
scaledInputs,
|
||||
scaledCondensedOutputs);
|
||||
// 仅使用 multiplier 构建轻量化 ScaledProcessingPattern(具体视图按需计算)
|
||||
return new ScaledProcessingPattern(base, base.getDefinition(), multiplier);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,4 +37,5 @@
|
|||
"config.extendedae_plus.state_off": "Off",
|
||||
"config.extendedae_plus.smartScalingMaxMultiplier": "Smart Scaling Max Multiplier",
|
||||
"config.extendedae_plus.smartScalingMaxMultiplier_with_range": "Smart Scaling Max Multiplier (0 = Unlimited)"
|
||||
,"config.extendedae_plus.smartScalingMinBenefitFactor": "Smart Scaling Min Benefit Factor (default 4)"
|
||||
}
|
||||
|
|
@ -58,5 +58,6 @@
|
|||
"gui.extendedae_plus.global.all_on": "全部开启",
|
||||
"gui.extendedae_plus.global.all_off": "全部关闭",
|
||||
"config.extendedae_plus.smartScalingMaxMultiplier": "智能倍增最大倍数",
|
||||
"config.extendedae_plus.smartScalingMaxMultiplier_with_range": "智能倍增最大倍数 (0为不限制)"
|
||||
"config.extendedae_plus.smartScalingMaxMultiplier_with_range": "智能倍增最大倍数 (0为不限制)",
|
||||
"config.extendedae_plus.smartScalingMinBenefitFactor": "智能倍增最小收益因子 (默认 4)"
|
||||
}
|
||||
|
|
@ -35,6 +35,7 @@
|
|||
"mixins": [
|
||||
"ae2.AEProcessingPatternMixin",
|
||||
"ae2.CraftingCPUClusterMixin",
|
||||
"ae2.EncodedPatternItemMixin",
|
||||
"ae2.accessor.MEStorageMenuAccessor",
|
||||
"ae2.accessor.PatternEncodingTermMenuAccessor",
|
||||
"ae2.accessor.PatternProviderLogicAccessor",
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user