feat: 添加单样板供应器翻倍限制逻辑
This commit is contained in:
parent
5a940235c8
commit
92cf9803c6
|
|
@ -27,8 +27,6 @@ public class ScaledProcessingPattern implements IPatternDetails {
|
|||
private transient volatile GenericStack[] outputsCache;
|
||||
private transient volatile GenericStack[] sparseInputsCache;
|
||||
private transient volatile GenericStack[] sparseOutputsCache;
|
||||
// per-provider scaling limit (0 = no limit). Can be updated from UI via provider settings.
|
||||
private int perProviderScalingLimit = 0;
|
||||
|
||||
public ScaledProcessingPattern(AEProcessingPattern original, AEItemKey definition, long multiplier) {
|
||||
this.original = Objects.requireNonNull(original);
|
||||
|
|
@ -36,14 +34,6 @@ public class ScaledProcessingPattern implements IPatternDetails {
|
|||
this.multiplier = multiplier <= 0 ? 1L : multiplier;
|
||||
}
|
||||
|
||||
public int getPerProviderScalingLimit() {
|
||||
return this.perProviderScalingLimit;
|
||||
}
|
||||
|
||||
public void setPerProviderScalingLimit(int limit) {
|
||||
this.perProviderScalingLimit = Math.max(0, limit);
|
||||
}
|
||||
|
||||
/* -------------------- API 实现 -------------------- */
|
||||
|
||||
public AEProcessingPattern getOriginal() {
|
||||
|
|
|
|||
|
|
@ -2,4 +2,6 @@ package com.extendedae_plus.api.smartDoubling;
|
|||
|
||||
public interface IPatternProviderMenuDoublingSync {
|
||||
boolean eap$getSmartDoublingSynced();
|
||||
|
||||
int eap$getScalingLimit();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ package com.extendedae_plus.api.smartDoubling;
|
|||
public interface ISmartDoublingAwarePattern {
|
||||
boolean eap$allowScaling();
|
||||
void eap$setAllowScaling(boolean allow);
|
||||
/** per-provider scaling limit: 0 means no limit */
|
||||
|
||||
// 翻倍限制:0 表示无限制
|
||||
int eap$getScalingLimit();
|
||||
void eap$setScalingLimit(int limit);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,5 +2,10 @@ package com.extendedae_plus.api.smartDoubling;
|
|||
|
||||
public interface ISmartDoublingHolder {
|
||||
boolean eap$getSmartDoubling();
|
||||
|
||||
void eap$setSmartDoubling(boolean value);
|
||||
|
||||
int eap$getProviderSmartDoublingLimit();
|
||||
|
||||
void eap$setProviderSmartDoublingLimit(int limit);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,6 +90,12 @@ public class ModNetwork {
|
|||
.consumerNetworkThread(ToggleSmartDoublingC2SPacket::handle)
|
||||
.add();
|
||||
|
||||
CHANNEL.messageBuilder(com.extendedae_plus.network.provider.SetPerProviderScalingLimitC2SPacket.class, nextId(), NetworkDirection.PLAY_TO_SERVER)
|
||||
.encoder(com.extendedae_plus.network.provider.SetPerProviderScalingLimitC2SPacket::encode)
|
||||
.decoder(com.extendedae_plus.network.provider.SetPerProviderScalingLimitC2SPacket::decode)
|
||||
.consumerNetworkThread(com.extendedae_plus.network.provider.SetPerProviderScalingLimitC2SPacket::handle)
|
||||
.add();
|
||||
|
||||
CHANNEL.messageBuilder(GlobalToggleProviderModesC2SPacket.class, nextId(), NetworkDirection.PLAY_TO_SERVER)
|
||||
.encoder(GlobalToggleProviderModesC2SPacket::encode)
|
||||
.decoder(GlobalToggleProviderModesC2SPacket::decode)
|
||||
|
|
|
|||
|
|
@ -11,9 +11,12 @@ import com.extendedae_plus.api.IExPatternButtonsAccessor;
|
|||
import com.extendedae_plus.api.IPatternProviderMenuAdvancedSync;
|
||||
import com.extendedae_plus.api.smartDoubling.IPatternProviderMenuDoublingSync;
|
||||
import com.extendedae_plus.init.ModNetwork;
|
||||
import com.extendedae_plus.network.provider.SetPerProviderScalingLimitC2SPacket;
|
||||
import com.extendedae_plus.network.provider.ToggleAdvancedBlockingC2SPacket;
|
||||
import com.extendedae_plus.network.provider.ToggleSmartDoublingC2SPacket;
|
||||
import com.glodblock.github.extendedae.client.gui.GuiExPatternProvider;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.EditBox;
|
||||
import net.minecraft.client.gui.components.Tooltip;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
|
|
@ -33,20 +36,14 @@ import static com.extendedae_plus.util.Logger.EAP$LOGGER;
|
|||
@Mixin(PatternProviderScreen.class)
|
||||
public abstract class PatternProviderScreenMixin<C extends PatternProviderMenu> extends AEBaseScreen<C> {
|
||||
|
||||
@Unique
|
||||
private SettingToggleButton<YesNo> eap$AdvancedBlockingToggle;
|
||||
@Unique private SettingToggleButton<YesNo> eap$AdvancedBlockingToggle;
|
||||
@Unique private SettingToggleButton<YesNo> eap$SmartDoublingToggle;
|
||||
@Unique private EditBox eap$PerProviderLimitInput;
|
||||
|
||||
@Unique
|
||||
private boolean eap$AdvancedBlockingEnabled = false;
|
||||
|
||||
@Unique
|
||||
private SettingToggleButton<YesNo> eap$SmartDoublingToggle;
|
||||
|
||||
@Unique
|
||||
private boolean eap$SmartDoublingEnabled = false;
|
||||
|
||||
@Unique
|
||||
private net.minecraft.client.gui.components.EditBox eap$PerProviderLimitInput;
|
||||
@Unique private boolean eap$AdvancedBlockingEnabled = false;
|
||||
@Unique private boolean eap$SmartDoublingEnabled = false;
|
||||
@Unique private int eap$PerProviderScalingLimit = 0;
|
||||
@Unique private boolean eap$PerProviderLimitWasFocused = false;
|
||||
|
||||
public PatternProviderScreenMixin(C menu, Inventory playerInventory, Component title, ScreenStyle style) {
|
||||
super(menu, playerInventory, title, style);
|
||||
|
|
@ -73,24 +70,24 @@ public abstract class PatternProviderScreenMixin<C extends PatternProviderMenu>
|
|||
}
|
||||
) {
|
||||
@Override
|
||||
public java.util.List<net.minecraft.network.chat.Component> getTooltipMessage() {
|
||||
public java.util.List<Component> getTooltipMessage() {
|
||||
boolean enabled = eap$AdvancedBlockingEnabled;
|
||||
var title = net.minecraft.network.chat.Component.literal("智能阻挡");
|
||||
var title = Component.literal("智能阻挡");
|
||||
var line = enabled
|
||||
? net.minecraft.network.chat.Component.literal("已启用:对于同一种配方将不再阻挡(需要开启原版的阻挡模式)")
|
||||
: net.minecraft.network.chat.Component.literal("已禁用:这么好的功能为什么不打开呢");
|
||||
? Component.literal("已启用:对于同一种配方将不再阻挡(需要开启原版的阻挡模式)")
|
||||
: Component.literal("已禁用:这么好的功能为什么不打开呢");
|
||||
return java.util.List.of(title, line);
|
||||
}
|
||||
};
|
||||
// 初始化后立刻对齐当前@GuiSync状态,避免首帧显示不一致
|
||||
this.eap$AdvancedBlockingToggle.set(this.eap$AdvancedBlockingEnabled ? YesNo.YES : YesNo.NO);
|
||||
|
||||
this.addToLeftToolbar(this.eap$AdvancedBlockingToggle);
|
||||
|
||||
// 智能翻倍按钮:与高级阻挡同款样式,点击仅发送C2S,状态由@GuiSync驱动
|
||||
try {
|
||||
if (menu instanceof IPatternProviderMenuDoublingSync sync2) {
|
||||
this.eap$SmartDoublingEnabled = sync2.eap$getSmartDoublingSynced();
|
||||
this.eap$PerProviderScalingLimit = sync2.eap$getScalingLimit();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
EAP$LOGGER.error("Error initializing smart doubling sync", t);
|
||||
|
|
@ -104,12 +101,12 @@ public abstract class PatternProviderScreenMixin<C extends PatternProviderMenu>
|
|||
}
|
||||
) {
|
||||
@Override
|
||||
public java.util.List<net.minecraft.network.chat.Component> getTooltipMessage() {
|
||||
public java.util.List<Component> getTooltipMessage() {
|
||||
boolean enabled = eap$SmartDoublingEnabled;
|
||||
var title = net.minecraft.network.chat.Component.literal("智能翻倍");
|
||||
var title = Component.literal("智能翻倍");
|
||||
var line = enabled
|
||||
? net.minecraft.network.chat.Component.literal("已启用:根据请求量对处理样板进行智能缩放")
|
||||
: net.minecraft.network.chat.Component.literal("已禁用:按原始样板数量进行发配");
|
||||
? Component.literal("已启用:根据请求量对处理样板进行智能缩放")
|
||||
: Component.literal("已禁用:按原始样板数量进行发配");
|
||||
return java.util.List.of(title, line);
|
||||
}
|
||||
};
|
||||
|
|
@ -121,29 +118,33 @@ public abstract class PatternProviderScreenMixin<C extends PatternProviderMenu>
|
|||
try {
|
||||
// 使用与左侧工具栏一致的布局托管,避免绝对坐标问题
|
||||
// 使用更短的输入框并去除前导 0(显示更紧凑)
|
||||
this.eap$PerProviderLimitInput = new net.minecraft.client.gui.components.EditBox(this.font, 0, 0, 28, 12, net.minecraft.network.chat.Component.literal("Limit"));
|
||||
this.eap$PerProviderLimitInput.setValue("0");
|
||||
this.eap$PerProviderLimitInput = new EditBox(this.font, 0, 0, 28, 12, Component.literal("Limit"));
|
||||
this.eap$PerProviderLimitInput.setValue(String.valueOf(this.eap$PerProviderScalingLimit));
|
||||
this.eap$PerProviderLimitInput.setMaxLength(6);
|
||||
// 调试用:值变更时打印到控制台,同时去掉前导 0(如用户输入 012 -> 12),但保留单个 0
|
||||
// 值变更响应
|
||||
this.eap$PerProviderLimitInput.setResponder((s) -> {
|
||||
try {
|
||||
if (s != null && s.length() > 0) {
|
||||
// 去掉前导0但保留单个0
|
||||
if (s != null && !s.isEmpty()) {
|
||||
String trimmed = s.replaceFirst("^0+(?=.)", "");
|
||||
if (!trimmed.equals(s)) {
|
||||
this.eap$PerProviderLimitInput.setValue(trimmed);
|
||||
System.out.println("[EAP] PerProviderLimit changed (trimmed): " + trimmed);
|
||||
return;
|
||||
s = trimmed;
|
||||
}
|
||||
}
|
||||
System.out.println("[EAP] PerProviderLimit changed: " + s);
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
// 实时发送:尝试解析并发送到服务端(若值变化)
|
||||
int val = Integer.parseInt(s == null || s.isBlank() ? "0" : s);
|
||||
|
||||
if (val != this.eap$PerProviderScalingLimit) {
|
||||
this.eap$PerProviderScalingLimit = val;
|
||||
ModNetwork.CHANNEL.sendToServer(new SetPerProviderScalingLimitC2SPacket(val));
|
||||
}
|
||||
} catch (Throwable ignored) {}
|
||||
});
|
||||
// 初次加入渲染列表(后续在 updateBeforeRender 每帧更新 tooltip/位置)
|
||||
this.addRenderableWidget(this.eap$PerProviderLimitInput);
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
// 若菜单/逻辑已在之前同步了上限,则在控件创建后填充显示
|
||||
this.eap$PerProviderLimitInput.setValue(String.valueOf(this.eap$PerProviderScalingLimit));
|
||||
} catch (Throwable ignored) {}
|
||||
}
|
||||
|
||||
// 每帧刷新:仅从菜单(@GuiSync)同步布尔值,保持按钮状态一致
|
||||
|
|
@ -167,6 +168,20 @@ public abstract class PatternProviderScreenMixin<C extends PatternProviderMenu>
|
|||
this.eap$SmartDoublingToggle.set(desired2 ? YesNo.YES : YesNo.NO);
|
||||
}
|
||||
|
||||
if (this.eap$PerProviderLimitInput != null) {
|
||||
int remoteLimit = this.eap$PerProviderScalingLimit;
|
||||
if (this.menu instanceof IPatternProviderMenuDoublingSync sync3) {
|
||||
remoteLimit = sync3.eap$getScalingLimit();
|
||||
}
|
||||
// 若输入框没有焦点且远端值变化则更新控件;否则保留用户编辑的值
|
||||
boolean focused = this.eap$PerProviderLimitInput.isFocused();
|
||||
if (!focused && remoteLimit != this.eap$PerProviderScalingLimit) {
|
||||
this.eap$PerProviderScalingLimit = remoteLimit;
|
||||
this.eap$PerProviderLimitInput.setValue(String.valueOf(remoteLimit));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ((Object) this instanceof GuiExPatternProvider) {
|
||||
try {
|
||||
((IExPatternButtonsAccessor) this).eap$updateButtonsLayout();
|
||||
|
|
@ -184,45 +199,44 @@ public abstract class PatternProviderScreenMixin<C extends PatternProviderMenu>
|
|||
}
|
||||
|
||||
// 当输入框未获得焦点且内容为空时填充 0
|
||||
try {
|
||||
if (!this.eap$PerProviderLimitInput.isFocused() && this.eap$PerProviderLimitInput.getValue().trim().isEmpty()) {
|
||||
this.eap$PerProviderLimitInput.setValue("0");
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
if (!this.eap$PerProviderLimitInput.isFocused() && this.eap$PerProviderLimitInput.getValue().trim().isEmpty()) {
|
||||
this.eap$PerProviderLimitInput.setValue("0");
|
||||
}
|
||||
|
||||
// 优先参考已有的左侧按钮定位
|
||||
net.minecraft.client.gui.components.Button ref = eap$SmartDoublingToggle;
|
||||
|
||||
Button ref = eap$SmartDoublingToggle;
|
||||
if (ref != null) {
|
||||
int ex = ref.getX() - this.eap$PerProviderLimitInput.getWidth() - 5;
|
||||
int ey = ref.getY() + 2; // 向下移动 2 像素
|
||||
this.eap$PerProviderLimitInput.setX(ex);
|
||||
this.eap$PerProviderLimitInput.setY(ey);
|
||||
} else {
|
||||
// 回退到相对于 gui 的位置
|
||||
this.eap$PerProviderLimitInput.setX(this.leftPos - this.eap$PerProviderLimitInput.getWidth() - 4);
|
||||
this.eap$PerProviderLimitInput.setY(this.topPos + 7);
|
||||
}
|
||||
|
||||
// 动态更新 tooltip,简短且包含当前值
|
||||
try {
|
||||
String cur = this.eap$PerProviderLimitInput.getValue();
|
||||
if (cur == null || cur.isBlank()) cur = "0";
|
||||
var tip = net.minecraft.network.chat.Component.literal("智能翻倍上限: " + cur);
|
||||
this.eap$PerProviderLimitInput.setTooltip(Tooltip.create(tip));
|
||||
} catch (Throwable ignored) {}
|
||||
String cur = this.eap$PerProviderLimitInput.getValue();
|
||||
if (cur.isBlank()) cur = "0";
|
||||
var tip = Component.literal("智能翻倍上限: " + cur);
|
||||
this.eap$PerProviderLimitInput.setTooltip(Tooltip.create(tip));
|
||||
|
||||
// 当输入框失去焦点且之前处于聚焦时,提交当前值并更新本地同步字段
|
||||
boolean focusedNow = this.eap$PerProviderLimitInput.isFocused();
|
||||
if (this.eap$PerProviderLimitWasFocused && !focusedNow) {
|
||||
int val = Integer.parseInt(cur);
|
||||
// 更新本地展示值并发包到服务端
|
||||
this.eap$PerProviderScalingLimit = val;
|
||||
EAP$LOGGER.info("更新");
|
||||
ModNetwork.CHANNEL.sendToServer(new SetPerProviderScalingLimitC2SPacket(val));
|
||||
}
|
||||
this.eap$PerProviderLimitWasFocused = focusedNow;
|
||||
|
||||
} else {
|
||||
// 隐藏输入框
|
||||
try {
|
||||
if (this.renderables.contains(this.eap$PerProviderLimitInput)) {
|
||||
this.removeWidget(this.eap$PerProviderLimitInput);
|
||||
}
|
||||
} catch (Throwable ignored) {}
|
||||
if (this.renderables.contains(this.eap$PerProviderLimitInput)) {
|
||||
this.removeWidget(this.eap$PerProviderLimitInput);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
} catch (Throwable ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,18 +17,11 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||
|
||||
@Mixin(value = PatternProviderLogic.class, remap = false)
|
||||
public class PatternProviderLogicDoublingMixin implements ISmartDoublingHolder {
|
||||
@Unique
|
||||
private static final String EAP_SMART_DOUBLING_KEY = "eap_smart_doubling";
|
||||
@Unique private static final String EAP_SMART_DOUBLING_KEY = "eap_smart_doubling";
|
||||
@Unique private static final String EAP_PROVIDER_SCALING_LIMIT = "eap_provider_scaling_limit";
|
||||
|
||||
@Unique
|
||||
private boolean eap$smartDoubling = false;
|
||||
@Unique
|
||||
private static final Object EAP_SCALING_LOCK = new Object();
|
||||
@Unique
|
||||
private static final java.util.concurrent.ScheduledExecutorService EAP_EXECUTOR =
|
||||
java.util.concurrent.Executors.newSingleThreadScheduledExecutor(r -> new Thread(r, "eap-scaling-save"));
|
||||
@Unique
|
||||
private java.util.concurrent.ScheduledFuture<?> eap$pendingScalingSave = null;
|
||||
@Unique private boolean eap$smartDoubling = false;
|
||||
@Unique private int eap$providerScalingLimit = 0; // 供应器级别的上限,0 表示不限制
|
||||
|
||||
@Override
|
||||
public boolean eap$getSmartDoubling() {
|
||||
|
|
@ -48,36 +41,37 @@ public class PatternProviderLogicDoublingMixin implements ISmartDoublingHolder {
|
|||
}
|
||||
// 触发一次刷新,让网络及时拿到最新状态(也会触发 ICraftingProvider.requestUpdate(mainNode))
|
||||
((PatternProviderLogic) (Object) this).updatePatterns();
|
||||
} catch (Throwable ignored) {
|
||||
} catch (Throwable ignored) {}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int eap$getProviderSmartDoublingLimit() {
|
||||
return this.eap$providerScalingLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eap$setProviderSmartDoublingLimit(int limit) {
|
||||
// 更新供应器级别上限并去抖保存
|
||||
var list = ((PatternProviderLogicAccessor) this).eap$patterns();
|
||||
this.eap$providerScalingLimit = Math.max(0, limit);
|
||||
// 现在把防抖移到客户端屏幕端来处理,服务器端直接立即应用并保存
|
||||
for (IPatternDetails d : list) {
|
||||
if (d instanceof AEProcessingPattern proc && proc instanceof ISmartDoublingAwarePattern a) {
|
||||
try { a.eap$setScalingLimit(this.eap$providerScalingLimit); } catch (Throwable ignored) {}
|
||||
}
|
||||
}
|
||||
try {
|
||||
((PatternProviderLogic) (Object) this).updatePatterns();
|
||||
} catch (Throwable ignored) {}
|
||||
|
||||
}
|
||||
|
||||
@Inject(method = "writeToNBT", at = @At("TAIL"))
|
||||
private void eap$writeSmartDoublingToNbt(CompoundTag tag, CallbackInfo ci) {
|
||||
tag.putBoolean(EAP_SMART_DOUBLING_KEY, this.eap$smartDoubling);
|
||||
// persist any pattern-level scaling limits
|
||||
try {
|
||||
var list = ((PatternProviderLogicAccessor) this).eap$patterns();
|
||||
int[] limits = new int[list.size()];
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
var details = list.get(i);
|
||||
if (details instanceof com.extendedae_plus.ae.api.crafting.ScaledProcessingPattern sp) {
|
||||
limits[i] = sp.getPerProviderScalingLimit();
|
||||
} else if (details instanceof appeng.crafting.pattern.AEProcessingPattern base && base instanceof ISmartDoublingAwarePattern aware) {
|
||||
limits[i] = aware.eap$getScalingLimit();
|
||||
} else {
|
||||
limits[i] = 0;
|
||||
}
|
||||
}
|
||||
var listTag = new net.minecraft.nbt.ListTag();
|
||||
for (int v : limits) {
|
||||
var c = new CompoundTag();
|
||||
c.putInt("limit", v);
|
||||
listTag.add(c);
|
||||
}
|
||||
tag.put("eap_scaling_limits", listTag);
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
// 保存供应器级别上限
|
||||
tag.putInt(EAP_PROVIDER_SCALING_LIMIT, this.eap$providerScalingLimit);
|
||||
|
||||
}
|
||||
|
||||
@Inject(method = "readFromNBT", at = @At("TAIL"))
|
||||
|
|
@ -85,23 +79,9 @@ public class PatternProviderLogicDoublingMixin implements ISmartDoublingHolder {
|
|||
if (tag.contains(EAP_SMART_DOUBLING_KEY)) {
|
||||
this.eap$smartDoubling = tag.getBoolean(EAP_SMART_DOUBLING_KEY);
|
||||
}
|
||||
try {
|
||||
if (tag.contains("eap_scaling_limits")) {
|
||||
var list = ((PatternProviderLogicAccessor) this).eap$patterns();
|
||||
var limitsTag = tag.getList("eap_scaling_limits", net.minecraft.nbt.Tag.TAG_COMPOUND);
|
||||
int n = Math.min(list.size(), limitsTag.size());
|
||||
for (int i = 0; i < n; i++) {
|
||||
var c = limitsTag.getCompound(i);
|
||||
int lim = c.getInt("limit");
|
||||
var details = list.get(i);
|
||||
if (details instanceof com.extendedae_plus.ae.api.crafting.ScaledProcessingPattern sp) {
|
||||
sp.setPerProviderScalingLimit(lim);
|
||||
} else if (details instanceof appeng.crafting.pattern.AEProcessingPattern base && base instanceof ISmartDoublingAwarePattern aware) {
|
||||
aware.eap$setScalingLimit(lim);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable ignored) {}
|
||||
if (tag.contains(EAP_PROVIDER_SCALING_LIMIT)) {
|
||||
this.eap$providerScalingLimit = tag.getInt(EAP_PROVIDER_SCALING_LIMIT);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "updatePatterns", at = @At("TAIL"))
|
||||
|
|
@ -109,47 +89,24 @@ public class PatternProviderLogicDoublingMixin implements ISmartDoublingHolder {
|
|||
try {
|
||||
var list = ((PatternProviderLogicAccessor) this).eap$patterns();
|
||||
boolean allow = this.eap$smartDoubling;
|
||||
int limit = this.eap$providerScalingLimit;
|
||||
for (IPatternDetails details : list) {
|
||||
if (details instanceof AEProcessingPattern proc && proc instanceof ISmartDoublingAwarePattern aware) {
|
||||
aware.eap$setAllowScaling(allow);
|
||||
aware.eap$setScalingLimit(limit);
|
||||
}
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
// called by UI when user changes per-provider limit; apply with debounce and save
|
||||
@Unique
|
||||
public void eap$onPerProviderLimitChanged(int patternIndex, int newLimit) {
|
||||
try {
|
||||
var list = ((PatternProviderLogicAccessor) this).eap$patterns();
|
||||
if (patternIndex < 0 || patternIndex >= list.size()) return;
|
||||
var details = list.get(patternIndex);
|
||||
if (details instanceof com.extendedae_plus.ae.api.crafting.ScaledProcessingPattern sp) {
|
||||
sp.setPerProviderScalingLimit(newLimit);
|
||||
} else if (details instanceof appeng.crafting.pattern.AEProcessingPattern base && base instanceof ISmartDoublingAwarePattern aware) {
|
||||
aware.eap$setScalingLimit(newLimit);
|
||||
}
|
||||
|
||||
synchronized (EAP_SCALING_LOCK) {
|
||||
if (eap$pendingScalingSave != null) {
|
||||
eap$pendingScalingSave.cancel(false);
|
||||
}
|
||||
eap$pendingScalingSave = EAP_EXECUTOR.schedule(() -> {
|
||||
try {
|
||||
this.saveChanges();
|
||||
} catch (Throwable ignored) {}
|
||||
}, 1000, java.util.concurrent.TimeUnit.MILLISECONDS);
|
||||
}
|
||||
} catch (Throwable ignored) {}
|
||||
}
|
||||
|
||||
@Shadow
|
||||
public void saveChanges() {}
|
||||
|
||||
@Inject(method = "exportSettings(Lnet/minecraft/nbt/CompoundTag;)V", at = @At("TAIL"))
|
||||
private void onExportSettings(CompoundTag output, CallbackInfo ci) {
|
||||
output.putBoolean(EAP_SMART_DOUBLING_KEY, this.eap$smartDoubling);
|
||||
output.putInt(EAP_PROVIDER_SCALING_LIMIT, this.eap$providerScalingLimit);
|
||||
}
|
||||
|
||||
@Inject(method = "importSettings(Lnet/minecraft/nbt/CompoundTag;Lnet/minecraft/world/entity/player/Player;)V", at = @At("TAIL"))
|
||||
|
|
@ -159,5 +116,9 @@ public class PatternProviderLogicDoublingMixin implements ISmartDoublingHolder {
|
|||
// 持久化到 world
|
||||
this.saveChanges();
|
||||
}
|
||||
if (input.contains(EAP_PROVIDER_SCALING_LIMIT)) {
|
||||
this.eap$providerScalingLimit = input.getInt(EAP_PROVIDER_SCALING_LIMIT);
|
||||
this.saveChanges();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,17 +32,13 @@ public abstract class PatternProviderMenuDoublingMixin implements IPatternProvid
|
|||
@GuiSync(22)
|
||||
public int eap$PerProviderScalingLimit = 0; // 0 = no limit
|
||||
|
||||
public void eap$setPerProviderScalingLimit(int v) {
|
||||
this.eap$PerProviderScalingLimit = Math.max(0, v);
|
||||
// send to server via an existing packet channel or custom packet (not implemented here)
|
||||
}
|
||||
|
||||
@Inject(method = "broadcastChanges", at = @At("HEAD"))
|
||||
private void eap$syncSmartDoubling(CallbackInfo ci) {
|
||||
if (!((AEBaseMenu) (Object) this).isClientSide()) {
|
||||
var l = this.logic;
|
||||
if (l instanceof ISmartDoublingHolder holder) {
|
||||
this.eap$SmartDoubling = holder.eap$getSmartDoubling();
|
||||
this.eap$PerProviderScalingLimit = holder.eap$getProviderSmartDoublingLimit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -53,6 +49,7 @@ public abstract class PatternProviderMenuDoublingMixin implements IPatternProvid
|
|||
var l = this.logic;
|
||||
if (l instanceof ISmartDoublingHolder holder) {
|
||||
this.eap$SmartDoubling = holder.eap$getSmartDoubling();
|
||||
this.eap$PerProviderScalingLimit = holder.eap$getProviderSmartDoublingLimit();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
EAP$LOGGER.error("Error initializing smart doubling sync", t);
|
||||
|
|
@ -65,14 +62,21 @@ public abstract class PatternProviderMenuDoublingMixin implements IPatternProvid
|
|||
var l = this.logic;
|
||||
if (l instanceof ISmartDoublingHolder holder) {
|
||||
this.eap$SmartDoubling = holder.eap$getSmartDoubling();
|
||||
this.eap$PerProviderScalingLimit = holder.eap$getProviderSmartDoublingLimit();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
EAP$LOGGER.error("Error initializing smart doubling sync", t);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean eap$getSmartDoublingSynced() {
|
||||
return this.eap$SmartDoubling;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int eap$getScalingLimit() {
|
||||
return this.eap$PerProviderScalingLimit;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
package com.extendedae_plus.network.provider;
|
||||
|
||||
import appeng.menu.implementations.PatternProviderMenu;
|
||||
import com.extendedae_plus.api.smartDoubling.ISmartDoublingHolder;
|
||||
import com.extendedae_plus.mixin.advancedae.accessor.AdvPatternProviderMenuAdvancedAccessor;
|
||||
import com.extendedae_plus.mixin.ae2.accessor.PatternProviderMenuAccessor;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
import net.pedroksl.advanced_ae.gui.advpatternprovider.AdvPatternProviderMenu;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* C2S: set per-provider scaling limit for the currently opened provider and pattern index
|
||||
*/
|
||||
public class SetPerProviderScalingLimitC2SPacket {
|
||||
private final int limit;
|
||||
|
||||
public SetPerProviderScalingLimitC2SPacket(int limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
public static void encode(SetPerProviderScalingLimitC2SPacket msg, FriendlyByteBuf buf) {
|
||||
buf.writeInt(msg.limit);
|
||||
}
|
||||
|
||||
public static SetPerProviderScalingLimitC2SPacket decode(FriendlyByteBuf buf) {
|
||||
return new SetPerProviderScalingLimitC2SPacket(buf.readInt());
|
||||
}
|
||||
|
||||
public static void handle(SetPerProviderScalingLimitC2SPacket msg, Supplier<NetworkEvent.Context> ctxSupplier) {
|
||||
var ctx = ctxSupplier.get();
|
||||
ctx.enqueueWork(() -> {
|
||||
try {
|
||||
ServerPlayer player = ctx.getSender();
|
||||
if (player == null) return;
|
||||
var containerMenu = player.containerMenu;
|
||||
if (containerMenu instanceof PatternProviderMenu menu) {
|
||||
var accessor = (PatternProviderMenuAccessor) menu;
|
||||
var logic = accessor.eap$logic();
|
||||
if (logic instanceof ISmartDoublingHolder handler) {
|
||||
handler.eap$setProviderSmartDoublingLimit(msg.limit);
|
||||
}
|
||||
} else if (containerMenu instanceof AdvPatternProviderMenu advMenu) {
|
||||
var accessor = (AdvPatternProviderMenuAdvancedAccessor) advMenu;
|
||||
var logic = accessor.eap$logic();
|
||||
if (logic instanceof ISmartDoublingHolder handler) {
|
||||
handler.eap$setProviderSmartDoublingLimit(msg.limit);
|
||||
}
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
});
|
||||
ctx.setPacketHandled(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -66,6 +66,7 @@ public final class PatternScaler {
|
|||
if (patternLimit > 0 && multiplier > patternLimit) {
|
||||
multiplier = patternLimit;
|
||||
} else {
|
||||
// 应用配置的最大倍数上限(0 表示不限制)
|
||||
int maxMul = ModConfig.INSTANCE.smartScalingMaxMultiplier;
|
||||
if (maxMul > 0 && multiplier > maxMul) {
|
||||
multiplier = maxMul;
|
||||
|
|
@ -83,15 +84,7 @@ public final class PatternScaler {
|
|||
} catch (Throwable ignore) {
|
||||
// 配置读取异常时保持默认行为(不绕过)
|
||||
}
|
||||
// 应用配置的最大倍数上限(0 表示不限制)
|
||||
try {
|
||||
int maxMul = ModConfig.INSTANCE.smartScalingMaxMultiplier;
|
||||
if (maxMul > 0 && multiplier > maxMul) {
|
||||
multiplier = maxMul;
|
||||
}
|
||||
} catch (Throwable ignore) {
|
||||
// 配置读取异常时不施加上限
|
||||
}
|
||||
|
||||
if (ModList.get().isLoaded("advanced_ae")) {
|
||||
// 如果加载了 Advanced AE 且 base 实现了 AdvPatternDetails,返回兼容版
|
||||
try {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user