新版智能倍增、智能阻挡按钮及相关文本等内容;

全面替换ae和eae供应器智能功能相关内容为内置按钮等
This commit is contained in:
C-H716 2025-11-25 13:17:16 +08:00
parent cda8900df7
commit f6b61b6940
17 changed files with 235 additions and 450 deletions

View File

@ -1,5 +1,7 @@
package com.extendedae_plus.api.advancedBlocking;
import appeng.api.config.YesNo;
public interface IPatternProviderMenuAdvancedSync {
boolean eap$getAdvancedBlockingSynced();
YesNo eap$getAdvancedBlockingSynced();
}

View File

@ -11,8 +11,9 @@ import java.util.Map;
public final class EAPSettings {
private static final Map<String, Setting<?>> SETTINGS = new HashMap<>();
public static final Setting<YesNo> ACCELERATE = register("accelerate", YesNo.NO, YesNo.YES);
public static final Setting<YesNo> REDSTONE_CONTROL = register("redstoneControl", YesNo.NO, YesNo.YES);
public static final Setting<YesNo> REDSTONE_CONTROL = register("redstone_control", YesNo.NO, YesNo.YES);
public static final Setting<YesNo> SMART_DOUBLING = register("smart_doubling", YesNo.NO, YesNo.YES);
public static final Setting<YesNo> ADVANCED_BLOCKING = register("advanced_blocking", YesNo.NO, YesNo.YES);
private EAPSettings() {
}

View File

@ -1,5 +1,7 @@
package com.extendedae_plus.api.smartDoubling;
import appeng.api.config.YesNo;
public interface IPatternProviderMenuDoublingSync {
boolean eap$getSmartDoublingSynced();
YesNo eap$getSmartDoublingSynced();
}

View File

@ -28,13 +28,13 @@ public class EAPSettingToggleButton<T extends Enum<T>> extends IconButton {
private final EnumSet<T> validValues;
private T currentValue;
public EAPSettingToggleButton(Setting<T> setting, T val,
IHandler<EAPSettingToggleButton<T>> onPress) {
EAPSettingToggleButton(Setting<T> setting, T val,
IHandler<EAPSettingToggleButton<T>> onPress) {
this(setting, val, t -> true, onPress);
}
public EAPSettingToggleButton(Setting<T> setting, T val, Predicate<T> isValidValue,
IHandler<EAPSettingToggleButton<T>> onPress) {
private EAPSettingToggleButton(Setting<T> setting, T val, Predicate<T> isValidValue,
IHandler<EAPSettingToggleButton<T>> onPress) {
super(EAPSettingToggleButton::onPress);
this.onPress = onPress;
@ -64,6 +64,21 @@ public class EAPSettingToggleButton<T extends Enum<T>> extends IconButton {
registerApp(Icon.REDSTONE_IGNORE, EAPSettings.REDSTONE_CONTROL, YesNo.NO,
EAPText.RedstoneControl,
EAPText.RedstoneControlDisabled);
registerApp(Icon.BLOCKING_MODE_YES, EAPSettings.SMART_DOUBLING, YesNo.YES,
EAPText.SmartDoubling,
EAPText.SmartDoublingEnabled);
registerApp(Icon.BLOCKING_MODE_NO, EAPSettings.SMART_DOUBLING, YesNo.NO,
EAPText.SmartDoubling,
EAPText.SmartDoublingDisabled);
registerApp(Icon.BLOCKING_MODE_YES, EAPSettings.ADVANCED_BLOCKING, YesNo.YES,
EAPText.AdvancedBlocking,
EAPText.AdvancedBlockingEnabled);
registerApp(Icon.BLOCKING_MODE_NO, EAPSettings.ADVANCED_BLOCKING, YesNo.NO,
EAPText.AdvancedBlocking,
EAPText.AdvancedBlockingDisabled);
}
}
@ -106,7 +121,7 @@ public class EAPSettingToggleButton<T extends Enum<T>> extends IconButton {
if (currentScreen instanceof AEBaseScreen) {
backwards = ((AEBaseScreen<?>) currentScreen).isHandlingRightClick();
}
onPress.handle(this, backwards);
this.onPress.handle(this, backwards);
}
@Nullable
@ -119,7 +134,7 @@ public class EAPSettingToggleButton<T extends Enum<T>> extends IconButton {
@Override
protected Icon getIcon() {
var app = getApperance();
var app = this.getApperance();
if (app != null && app.icon != null) {
return app.icon;
}
@ -128,7 +143,7 @@ public class EAPSettingToggleButton<T extends Enum<T>> extends IconButton {
@Override
protected Item getItemOverlay() {
var app = getApperance();
var app = this.getApperance();
if (app != null && app.item != null) {
return app.item;
}
@ -150,7 +165,7 @@ public class EAPSettingToggleButton<T extends Enum<T>> extends IconButton {
return buttonAppearance.tooltipLines;
}
public Setting<T> getSetting() {
Setting<T> getSetting() {
return this.buttonSetting;
}
@ -165,7 +180,7 @@ public class EAPSettingToggleButton<T extends Enum<T>> extends IconButton {
}
public T getNextValue(boolean backwards) {
return EnumCycler.rotateEnum(currentValue, backwards, validValues);
return EnumCycler.rotateEnum(this.currentValue, backwards, this.validValues);
}
@FunctionalInterface

View File

@ -10,7 +10,15 @@ public enum EAPText implements LocalizationEnum {
RedstoneControl("Redstone control", Type.TOOLTIP),
RedstoneControlEnabled("Control acceleration with redstone signal", Type.TOOLTIP),
RedstoneControlDisabled("Ignore redstone signals", Type.TOOLTIP);
RedstoneControlDisabled("Ignore redstone signals", Type.TOOLTIP),
AdvancedBlocking("Smart Blocking", Type.TOOLTIP),
AdvancedBlockingEnabled("Will not block the same recipe type (requires vanilla blocking mode enabled)", Type.TOOLTIP),
AdvancedBlockingDisabled("Use vanilla blocking logic", Type.TOOLTIP),
SmartDoubling("Smart Doubling", Type.TOOLTIP),
SmartDoublingEnabled("Intelligently double processing patterns based on request quantity", Type.TOOLTIP),
SmartDoublingDisabled("Distribute according to original pattern quantity", Type.TOOLTIP);
private final String englishText;
private final Type type;

View File

@ -9,8 +9,6 @@ public class ModNetwork {
// Mod 构造中通过 modEventBus.addListener(ModNetwork::registerPayloadHandlers) 注册
public static void registerPayloadHandlers(final RegisterPayloadHandlersEvent event) {
var registrar = event.registrar(ExtendedAEPlus.MODID);
registrar.playToServer(ToggleAdvancedBlockingC2SPacket.TYPE, ToggleAdvancedBlockingC2SPacket.STREAM_CODEC, ToggleAdvancedBlockingC2SPacket::handle);
registrar.playToServer(ToggleSmartDoublingC2SPacket.TYPE, ToggleSmartDoublingC2SPacket.STREAM_CODEC, ToggleSmartDoublingC2SPacket::handle);
registrar.playToServer(ScalePatternsC2SPacket.TYPE, ScalePatternsC2SPacket.STREAM_CODEC, ScalePatternsC2SPacket::handle);
registrar.playToServer(InterfaceAdjustConfigAmountC2SPacket.TYPE, InterfaceAdjustConfigAmountC2SPacket.STREAM_CODEC, InterfaceAdjustConfigAmountC2SPacket::handle);
registrar.playToClient(SetPatternHighlightS2CPacket.TYPE, SetPatternHighlightS2CPacket.STREAM_CODEC, SetPatternHighlightS2CPacket::handle);

View File

@ -1,152 +0,0 @@
package com.extendedae_plus.mixin.ae2.client.gui;
import appeng.api.config.Settings;
import appeng.api.config.YesNo;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.implementations.PatternProviderScreen;
import appeng.client.gui.style.ScreenStyle;
import appeng.client.gui.widgets.SettingToggleButton;
import appeng.menu.implementations.PatternProviderMenu;
import com.extendedae_plus.api.IExPatternButton;
import com.extendedae_plus.api.advancedBlocking.IPatternProviderMenuAdvancedSync;
import com.extendedae_plus.api.smartDoubling.IPatternProviderMenuDoublingSync;
import com.extendedae_plus.network.ToggleAdvancedBlockingC2SPacket;
import com.extendedae_plus.network.ToggleSmartDoublingC2SPacket;
import com.extendedae_plus.util.ExtendedAELogger;
import com.glodblock.github.extendedae.client.gui.GuiExPatternProvider;
import net.minecraft.client.Minecraft;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/**
* AE2 原版样板供应器界面添加高级阻挡模式按钮
* - 位于左侧工具栏
* - 点击仅发送 C2S 切换请求状态由 AE2 @GuiSync 回传决定
*/
@Mixin(value = PatternProviderScreen.class, remap = false)
public abstract class PatternProviderScreenMixin<C extends PatternProviderMenu> extends AEBaseScreen<C> {
@Unique
private SettingToggleButton<YesNo> eap$AdvancedBlockingToggle;
@Unique
private boolean eap$AdvancedBlockingEnabled = false;
@Unique
private SettingToggleButton<YesNo> eap$SmartDoublingToggle;
@Unique
private boolean eap$SmartDoublingEnabled = false;
public PatternProviderScreenMixin(C menu, Inventory playerInventory, Component title, ScreenStyle style) {
super(menu, playerInventory, title, style);
}
@Inject(method = "<init>", at = @At("RETURN"), remap = false)
private void eap$initAdvancedBlocking(C menu, Inventory playerInventory, Component title, ScreenStyle style, CallbackInfo ci) {
// 使用 @GuiSync 初始化
try {
if (menu instanceof IPatternProviderMenuAdvancedSync sync) {
this.eap$AdvancedBlockingEnabled = sync.eap$getAdvancedBlockingSynced();
}
} catch (Throwable t) {
ExtendedAELogger.LOGGER.error("Error initializing advanced sync", t);
}
// 使用 SettingToggleButton<YesNo> 的外观原版图标但自定义悬停描述为智能阻挡
this.eap$AdvancedBlockingToggle = new SettingToggleButton<>(
Settings.BLOCKING_MODE,
this.eap$AdvancedBlockingEnabled ? YesNo.YES : YesNo.NO,
(btn, backwards) -> {
// 不做本地切换点击仅发送自定义C2S显示由@GuiSync回传
// debug removed
var conn = Minecraft.getInstance().getConnection();
if (conn != null) conn.send(ToggleAdvancedBlockingC2SPacket.INSTANCE);
}
) {
@Override
public java.util.List<net.minecraft.network.chat.Component> getTooltipMessage() {
boolean enabled = PatternProviderScreenMixin.this.eap$AdvancedBlockingEnabled;
var title = net.minecraft.network.chat.Component.literal("智能阻挡");
var line = enabled
? net.minecraft.network.chat.Component.literal("已启用:对于同一种配方将不再阻挡(需要开启原版的阻挡模式)")
: net.minecraft.network.chat.Component.literal("已禁用:这么好的功能为什么不打开呢");
return java.util.List.of(title, line);
}
};
// 初始化后立刻对齐当前@GuiSync状态避免首帧显示不一致
// debug removed
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();
}
} catch (Throwable t) {
ExtendedAELogger.LOGGER.error("Error initializing smart doubling sync", t);
}
this.eap$SmartDoublingToggle = new SettingToggleButton<>(
Settings.BLOCKING_MODE,
this.eap$SmartDoublingEnabled ? YesNo.YES : YesNo.NO,
(btn, backwards) -> {
// debug removed
var conn = Minecraft.getInstance().getConnection();
if (conn != null) conn.send(ToggleSmartDoublingC2SPacket.INSTANCE);
}
) {
@Override
public java.util.List<net.minecraft.network.chat.Component> getTooltipMessage() {
boolean enabled = PatternProviderScreenMixin.this.eap$SmartDoublingEnabled;
var title = net.minecraft.network.chat.Component.literal("智能翻倍");
var line = enabled
? net.minecraft.network.chat.Component.literal("已启用:根据请求量对处理样板进行智能缩放")
: net.minecraft.network.chat.Component.literal("已禁用:按原始样板数量进行发配");
return java.util.List.of(title, line);
}
};
this.eap$SmartDoublingToggle.set(this.eap$SmartDoublingEnabled ? YesNo.YES : YesNo.NO);
this.addToLeftToolbar(this.eap$SmartDoublingToggle);
}
// 每帧刷新仅从菜单(@GuiSync)同步布尔值保持按钮状态一致
@Inject(method = "updateBeforeRender", at = @At("HEAD"), remap = false)
private void eap$updateAdvancedBlocking(CallbackInfo ci) {
if (this.eap$AdvancedBlockingToggle != null) {
boolean desired = this.eap$AdvancedBlockingEnabled;
if (this.menu instanceof IPatternProviderMenuAdvancedSync sync) {
desired = sync.eap$getAdvancedBlockingSynced();
}
// debug removed
this.eap$AdvancedBlockingEnabled = desired;
this.eap$AdvancedBlockingToggle.set(desired ? YesNo.YES : YesNo.NO);
}
if (this.eap$SmartDoublingToggle != null) {
boolean desired2 = this.eap$SmartDoublingEnabled;
if (this.menu instanceof IPatternProviderMenuDoublingSync sync2) {
desired2 = sync2.eap$getSmartDoublingSynced();
}
// debug removed
this.eap$SmartDoublingEnabled = desired2;
this.eap$SmartDoublingToggle.set(desired2 ? YesNo.YES : YesNo.NO);
}
if ((Object) this instanceof GuiExPatternProvider) {
try {
((IExPatternButton) this).eap$updateButtonsLayout();
} catch (Throwable t) {
// debug removed
}
}
}
}

View File

@ -0,0 +1,62 @@
package com.extendedae_plus.mixin.ae2.client.gui;
import appeng.api.config.YesNo;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.implementations.PatternProviderScreen;
import appeng.client.gui.style.ScreenStyle;
import appeng.menu.implementations.PatternProviderMenu;
import com.extendedae_plus.api.IExPatternButton;
import com.extendedae_plus.api.advancedBlocking.IPatternProviderMenuAdvancedSync;
import com.extendedae_plus.api.config.EAPSettings;
import com.extendedae_plus.api.smartDoubling.IPatternProviderMenuDoublingSync;
import com.extendedae_plus.client.gui.widgets.EAPServerSettingToggleButton;
import com.glodblock.github.extendedae.client.gui.GuiExPatternProvider;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/**
* AE2 原版样板供应器界面添加高级阻挡模式按钮
* - 位于左侧工具栏
* - 点击仅发送 C2S 切换请求状态由 AE2 @GuiSync 回传决定
*/
@Mixin(value = PatternProviderScreen.class, remap = false)
public abstract class PatternProviderSmartFeaturesMixin<C extends PatternProviderMenu> extends AEBaseScreen<C> {
@Unique private EAPServerSettingToggleButton<YesNo> eap$AdvancedBlockingToggle;
@Unique private EAPServerSettingToggleButton<YesNo> eap$SmartDoublingToggle;
public PatternProviderSmartFeaturesMixin(C menu, Inventory playerInventory, Component title, ScreenStyle style) {
super(menu, playerInventory, title, style);
}
@Inject(method = "<init>", at = @At("RETURN"), remap = false)
private void eap$initAdvancedBlocking(C menu, Inventory playerInventory, Component title, ScreenStyle style, CallbackInfo ci) {
this.eap$AdvancedBlockingToggle = new EAPServerSettingToggleButton<>(EAPSettings.ADVANCED_BLOCKING, YesNo.YES);
this.addToLeftToolbar(this.eap$AdvancedBlockingToggle);
this.eap$SmartDoublingToggle = new EAPServerSettingToggleButton<>(EAPSettings.SMART_DOUBLING, YesNo.YES);
this.addToLeftToolbar(this.eap$SmartDoublingToggle);
}
// 每帧刷新仅从菜单(@GuiSync)同步布尔值保持按钮状态一致
@Inject(method = "updateBeforeRender", at = @At("HEAD"), remap = false)
private void eap$updateAdvancedBlocking(CallbackInfo ci) {
if (this.menu instanceof IPatternProviderMenuDoublingSync sync) {
this.eap$SmartDoublingToggle.set(sync.eap$getSmartDoublingSynced());
}
if (this.menu instanceof IPatternProviderMenuAdvancedSync sync) {
this.eap$AdvancedBlockingToggle.set(sync.eap$getAdvancedBlockingSynced());
}
if ((Object) this instanceof GuiExPatternProvider) {
try {
((IExPatternButton) this).eap$updateButtonsLayout();
} catch (Throwable t) {
// debug removed
}
}
}
}

View File

@ -1,17 +1,22 @@
package com.extendedae_plus.mixin.ae2.helpers;
import appeng.api.config.Setting;
import appeng.api.config.Settings;
import appeng.api.config.YesNo;
import appeng.api.crafting.IPatternDetails;
import appeng.api.crafting.IPatternDetails.IInput;
import appeng.api.networking.IManagedGridNode;
import appeng.api.stacks.AEKey;
import appeng.api.stacks.GenericStack;
import appeng.api.stacks.KeyCounter;
import appeng.api.util.IConfigManager;
import appeng.helpers.patternprovider.PatternProviderLogic;
import appeng.helpers.patternprovider.PatternProviderLogicHost;
import appeng.helpers.patternprovider.PatternProviderTarget;
import com.extendedae_plus.api.advancedBlocking.IAdvancedBlocking;
import com.extendedae_plus.api.ids.EAPComponents;
import appeng.util.ConfigManager;
import com.extendedae_plus.api.config.EAPSettings;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.component.DataComponentMap;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.player.Player;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
@ -21,51 +26,45 @@ import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Collections;
import java.util.Set;
@Mixin(value = PatternProviderLogic.class, remap = false)
public class PatternProviderLogicAdvancedMixin implements IAdvancedBlocking {
@Unique
private static final String EAP_ADV_BLOCKING_KEY = "epp_advanced_blocking";
public class PatternProviderLogicAdvancedMixin {
@Shadow @Final private IConfigManager configManager;
@Unique
private boolean eap$advancedBlocking = false;
@Shadow public IConfigManager getConfigManager() {throw new AssertionError();}
@Override
public boolean eap$getAdvancedBlocking() {
return this.eap$advancedBlocking;
}
@Shadow public boolean isBlocking() {throw new AssertionError();}
@Override
public void eap$setAdvancedBlocking(boolean value) {
this.eap$advancedBlocking = value;
}
@Inject(method = "writeToNBT", at = @At("TAIL"))
private void eap$writeAdvancedToNbt(CompoundTag tag, HolderLookup.Provider registries, CallbackInfo ci) {
tag.putBoolean(EAP_ADV_BLOCKING_KEY, this.eap$advancedBlocking);
}
@Inject(method = "readFromNBT", at = @At("TAIL"))
private void eap$readAdvancedFromNbt(CompoundTag tag, HolderLookup.Provider registries, CallbackInfo ci) {
if (tag.contains(EAP_ADV_BLOCKING_KEY)) {
this.eap$advancedBlocking = tag.getBoolean(EAP_ADV_BLOCKING_KEY);
}
@Inject(
method = "<init>(Lappeng/api/networking/IManagedGridNode;Lappeng/helpers/patternprovider/PatternProviderLogicHost;I)V",
at = @At("TAIL")
)
private void onInitTail(IManagedGridNode mainNode, PatternProviderLogicHost host, int patternInventorySize, CallbackInfo ci) {
// 直接往构建后的 configManager 里加 setting
ConfigManager configManager = (ConfigManager) this.getConfigManager();
configManager.registerSetting(EAPSettings.ADVANCED_BLOCKING, YesNo.NO);
}
// pushPattern 重定向对 adapter.containsPatternInput(...) 的调用
@Redirect(method = "pushPattern", at = @At(value = "INVOKE", target = "Lappeng/helpers/patternprovider/PatternProviderTarget;containsPatternInput(Ljava/util/Set;)Z"))
@Redirect(
method = "pushPattern",
at = @At(
value = "INVOKE",
target = "Lappeng/helpers/patternprovider/PatternProviderTarget;containsPatternInput(Ljava/util/Set;)Z"
)
)
private boolean eap$redirectBlockingContains(PatternProviderTarget adapter,
java.util.Set<AEKey> patternInputs,
Set<AEKey> patternInputs,
IPatternDetails patternDetails,
appeng.api.stacks.KeyCounter[] inputHolder) {
KeyCounter[] inputHolder) {
// 原版是否打开阻挡
boolean vanillaBlocking = ((PatternProviderLogic) (Object) this).isBlocking();
if (!vanillaBlocking) {
if (!this.isBlocking()) {
return adapter.containsPatternInput(patternInputs);
}
// 仅当高级阻挡启用时启用匹配则不阻挡
if (this.eap$advancedBlocking) {
if (this.configManager.getSetting(EAPSettings.ADVANCED_BLOCKING) == YesNo.YES) {
if (this.eap$targetFullyMatchesPatternInputs(adapter, patternDetails)) {
// 返回 false 表示不包含阻挡关键物从而不触发 continue允许发配
return false;
@ -77,7 +76,7 @@ public class PatternProviderLogicAdvancedMixin implements IAdvancedBlocking {
@Unique
private boolean eap$targetFullyMatchesPatternInputs(PatternProviderTarget adapter, IPatternDetails patternDetails) {
for (IInput in : patternDetails.getInputs()) {
for (IPatternDetails.IInput in : patternDetails.getInputs()) {
boolean slotMatched = false;
for (GenericStack candidate : in.getPossibleInputs()) {
AEKey key = candidate.what().dropSecondary();
@ -93,18 +92,26 @@ public class PatternProviderLogicAdvancedMixin implements IAdvancedBlocking {
return true; // 每个输入槽都至少匹配了一个候选输入
}
@Shadow
public void saveChanges() {}
@Inject(method = "exportSettings", at = @At("TAIL"))
private void onExportSettings(DataComponentMap.Builder builder, CallbackInfo ci) {
builder.set(EAPComponents.ADVANCED_BLOCKING, this.eap$advancedBlocking);
@Inject(method = "configChanged", at = @At("HEAD"))
private void eap$onConfigChanged(IConfigManager manager, Setting<?> setting, CallbackInfo ci) {
// 开启智能阻挡联动开启原版阻挡
if (setting == EAPSettings.ADVANCED_BLOCKING && manager.getSetting(EAPSettings.ADVANCED_BLOCKING) == YesNo.YES) {
manager.putSetting(Settings.BLOCKING_MODE, YesNo.YES);
}
// 关闭原版阻挡联动关闭智能阻挡
if (setting == Settings.BLOCKING_MODE && manager.getSetting(Settings.BLOCKING_MODE) == YesNo.NO) {
manager.putSetting(EAPSettings.ADVANCED_BLOCKING, YesNo.NO);
}
}
@Inject(method = "importSettings", at = @At("TAIL"))
private void onImportSettings(DataComponentMap input, Player player, CallbackInfo ci) {
this.eap$advancedBlocking = Boolean.TRUE.equals(input.get(EAPComponents.ADVANCED_BLOCKING.get()));
// 持久化到 world
this.saveChanges();
@Inject(method = "readFromNBT", at = @At("TAIL"))
private void eap$readSmartDoublingFromNbt(CompoundTag tag, HolderLookup.Provider registries, CallbackInfo ci) {
// TODO
// 适配旧版本中的数据后续版本删除
if (tag.contains("epp_advanced_blocking")) {
this.configManager.putSetting(EAPSettings.ADVANCED_BLOCKING,
tag.getBoolean("epp_advanced_blocking") ? YesNo.YES : YesNo.NO);
tag.remove("epp_advanced_blocking");
}
}
}

View File

@ -1,90 +1,73 @@
package com.extendedae_plus.mixin.ae2.helpers;
import appeng.api.config.Setting;
import appeng.api.config.YesNo;
import appeng.api.crafting.IPatternDetails;
import appeng.crafting.pattern.AEProcessingPattern;
import appeng.api.networking.IManagedGridNode;
import appeng.api.util.IConfigManager;
import appeng.helpers.patternprovider.PatternProviderLogic;
import com.extendedae_plus.api.ids.EAPComponents;
import com.extendedae_plus.api.smartDoubling.ISmartDoubling;
import appeng.helpers.patternprovider.PatternProviderLogicHost;
import appeng.util.ConfigManager;
import com.extendedae_plus.api.config.EAPSettings;
import com.extendedae_plus.api.smartDoubling.ISmartDoublingAwarePattern;
import com.extendedae_plus.mixin.ae2.accessor.PatternProviderLogicPatternsAccessor;
import net.minecraft.core.component.DataComponentMap;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.player.Player;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.List;
@Mixin(value = PatternProviderLogic.class, remap = false)
public class PatternProviderLogicDoublingMixin implements ISmartDoubling {
@Unique
private static final String EAP_SMART_DOUBLING_KEY = "epp_smart_doubling";
public class PatternProviderLogicDoublingMixin {
@Shadow @Final private List<IPatternDetails> patterns;
@Shadow @Final private IConfigManager configManager;
@Unique
private boolean eap$smartDoubling = false;
@Shadow
public IConfigManager getConfigManager() {return null;}
@Override
public boolean eap$getSmartDoubling() {
return this.eap$smartDoubling;
@Shadow
public void updatePatterns() {}
@Inject(
method = "<init>(Lappeng/api/networking/IManagedGridNode;Lappeng/helpers/patternprovider/PatternProviderLogicHost;I)V",
at = @At("TAIL")
)
private void onInitTail(IManagedGridNode mainNode, PatternProviderLogicHost host, int patternInventorySize, CallbackInfo ci) {
// 直接往构建后的 configManager 里加 setting
ConfigManager configManager = (ConfigManager) this.getConfigManager();
configManager.registerSetting(EAPSettings.SMART_DOUBLING, YesNo.NO);
}
@Override
public void eap$setSmartDoubling(boolean value) {
this.eap$smartDoubling = value;
// 立即将开关状态应用到当前 Provider 的样板上避免等待下一次 updatePatterns
try {
var list = ((PatternProviderLogicPatternsAccessor) this).eap$patterns();
for (IPatternDetails details : list) {
if (details instanceof AEProcessingPattern proc && proc instanceof ISmartDoublingAwarePattern aware) {
aware.eap$setAllowScaling(value);
}
}
// 触发一次刷新让网络及时拿到最新状态也会触发 ICraftingProvider.requestUpdate(mainNode)
((PatternProviderLogic) (Object) this).updatePatterns();
} catch (Throwable ignored) {
@Inject(method = "configChanged", at = @At("HEAD"))
private void eap$onConfigChanged(IConfigManager manager, Setting<?> setting, CallbackInfo ci) {
if (setting == EAPSettings.SMART_DOUBLING) {
this.updatePatterns();
}
}
@Inject(method = "writeToNBT", at = @At("TAIL"))
private void eap$writeSmartDoublingToNbt(CompoundTag tag, net.minecraft.core.HolderLookup.Provider registries, CallbackInfo ci) {
tag.putBoolean(EAP_SMART_DOUBLING_KEY, this.eap$smartDoubling);
}
@Inject(method = "readFromNBT", at = @At("TAIL"))
private void eap$readSmartDoublingFromNbt(CompoundTag tag, net.minecraft.core.HolderLookup.Provider registries, CallbackInfo ci) {
if (tag.contains(EAP_SMART_DOUBLING_KEY)) {
this.eap$smartDoubling = tag.getBoolean(EAP_SMART_DOUBLING_KEY);
private void eap$readSmartDoublingFromNbt(CompoundTag tag, HolderLookup.Provider registries, CallbackInfo ci) {
// TODO
// 适配旧版本中的数据后续版本删除
if (tag.contains("epp_smart_doubling")) {
this.configManager.putSetting(EAPSettings.SMART_DOUBLING,
tag.getBoolean("epp_smart_doubling") ? YesNo.YES : YesNo.NO);
tag.remove("epp_smart_doubling");
}
}
@Inject(method = "updatePatterns", at = @At("TAIL"))
private void eap$applySmartDoublingToPatterns(CallbackInfo ci) {
try {
var list = ((PatternProviderLogicPatternsAccessor) this).eap$patterns();
boolean allow = this.eap$smartDoubling;
for (IPatternDetails details : list) {
if (details instanceof AEProcessingPattern proc && proc instanceof ISmartDoublingAwarePattern aware) {
aware.eap$setAllowScaling(allow);
}
IConfigManager configManager = this.getConfigManager();
boolean allowScaling = configManager.getSetting(EAPSettings.SMART_DOUBLING) == YesNo.YES;
for (IPatternDetails details : this.patterns) {
if (details instanceof ISmartDoublingAwarePattern aware) {
aware.eap$setAllowScaling(allowScaling);
}
} catch (Throwable ignored) {
}
}
@Shadow
public void saveChanges() {}
@Inject(method = "exportSettings", at = @At("TAIL"))
private void onExportSettings(DataComponentMap.Builder builder, CallbackInfo ci) {
builder.set(EAPComponents.SMART_DOUBLING, this.eap$smartDoubling);
}
@Inject(method = "importSettings", at = @At("TAIL"))
private void onImportSettings(DataComponentMap input, Player player, CallbackInfo ci) {
this.eap$smartDoubling = Boolean.TRUE.equals(input.get(EAPComponents.SMART_DOUBLING.get()));
// 持久化到 world
this.saveChanges();
}
}

View File

@ -1,51 +1,33 @@
package com.extendedae_plus.mixin.ae2.menu;
import appeng.api.config.YesNo;
import appeng.helpers.patternprovider.PatternProviderLogic;
import appeng.menu.AEBaseMenu;
import appeng.menu.guisync.GuiSync;
import appeng.menu.implementations.PatternProviderMenu;
import com.extendedae_plus.api.advancedBlocking.IAdvancedBlocking;
import com.extendedae_plus.api.advancedBlocking.IPatternProviderMenuAdvancedSync;
import com.extendedae_plus.api.config.EAPSettings;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(PatternProviderMenu.class)
public abstract class PatternProviderMenuAdvancedMixin implements IPatternProviderMenuAdvancedSync {
@Shadow
protected PatternProviderLogic logic;
// 选择一个未占用的 GUI 同步 idAE2 已用到 7这里使用 20 以避冲突
@Unique
@GuiSync(20) private boolean eap$AdvancedBlocking = false;
@Shadow @Final protected PatternProviderLogic logic;
@Unique @GuiSync(20) private YesNo eap$AdvancedBlocking;
@Inject(method = "broadcastChanges", at = @At("HEAD"))
private void eap$syncAdvancedBlocking(CallbackInfo ci) {
// 避免@Shadow父类方法改用公共APIAEBaseMenu#isClientSide()
if (!((AEBaseMenu) (Object) this).isClientSide()) {
var l = this.logic;
if (l instanceof IAdvancedBlocking holder) {
this.eap$AdvancedBlocking = holder.eap$getAdvancedBlocking();
// debug removed
}
private void eap$syncSmartDoubling(CallbackInfo ci) {
if (!((PatternProviderMenu) (Object) this).isClientSide()) {
this.eap$AdvancedBlocking = this.logic.getConfigManager().getSetting(EAPSettings.ADVANCED_BLOCKING);
}
}
@Override
public boolean eap$getAdvancedBlockingSynced() {
public YesNo eap$getAdvancedBlockingSynced() {
return this.eap$AdvancedBlocking;
}
// 调试 Screen 每帧读取这些 getter 时打印验证 Mixin 是否生效
@Inject(method = "getBlockingMode", at = @At("HEAD"), remap = false)
private void eap$debug_getBlockingMode(CallbackInfoReturnable<?> cir) {
}
@Inject(method = "getShowInAccessTerminal", at = @At("HEAD"), remap = false)
private void eap$debug_getShowInAccessTerminal(CallbackInfoReturnable<?> cir) {
}
}

View File

@ -1,11 +1,12 @@
package com.extendedae_plus.mixin.ae2.menu;
import appeng.api.config.YesNo;
import appeng.helpers.patternprovider.PatternProviderLogic;
import appeng.menu.AEBaseMenu;
import appeng.menu.guisync.GuiSync;
import appeng.menu.implementations.PatternProviderMenu;
import com.extendedae_plus.api.config.EAPSettings;
import com.extendedae_plus.api.smartDoubling.IPatternProviderMenuDoublingSync;
import com.extendedae_plus.api.smartDoubling.ISmartDoubling;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
@ -15,25 +16,18 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(PatternProviderMenu.class)
public abstract class PatternProviderMenuDoublingMixin implements IPatternProviderMenuDoublingSync {
@Shadow
protected PatternProviderLogic logic;
@Unique
@GuiSync(21) private boolean eap$SmartDoubling = false;
@Shadow @Final protected PatternProviderLogic logic;
@Unique @GuiSync(21) private YesNo eap$SmartDoubling;
@Inject(method = "broadcastChanges", at = @At("HEAD"))
private void eap$syncSmartDoubling(CallbackInfo ci) {
if (!((AEBaseMenu) (Object) this).isClientSide()) {
var l = this.logic;
if (l instanceof ISmartDoubling holder) {
this.eap$SmartDoubling = holder.eap$getSmartDoubling();
// debug removed
}
if (!((PatternProviderMenu) (Object) this).isClientSide()) {
this.eap$SmartDoubling = this.logic.getConfigManager().getSetting(EAPSettings.SMART_DOUBLING);
}
}
@Override
public boolean eap$getSmartDoublingSynced() {
public YesNo eap$getSmartDoublingSynced() {
return this.eap$SmartDoubling;
}
}
}

View File

@ -1,69 +0,0 @@
package com.extendedae_plus.network;
import appeng.api.config.Settings;
import appeng.api.config.YesNo;
import appeng.menu.implementations.PatternProviderMenu;
import com.extendedae_plus.ExtendedAEPlus;
import com.extendedae_plus.api.advancedBlocking.IAdvancedBlocking;
import com.extendedae_plus.mixin.advancedae.accessor.AdvPatternProviderMenuAdvancedAccessor;
import com.extendedae_plus.mixin.ae2.accessor.PatternProviderMenuAdvancedAccessor;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.neoforged.neoforge.network.handling.IPayloadContext;
import net.pedroksl.advanced_ae.gui.advpatternprovider.AdvPatternProviderMenu;
/**
* C2S切换高级阻挡模式
* 不含额外负载直接基于玩家当前打开的 PatternProviderMenu 进行切换
*/
public class ToggleAdvancedBlockingC2SPacket implements CustomPacketPayload {
public static final Type<ToggleAdvancedBlockingC2SPacket> TYPE = new Type<>(
ResourceLocation.fromNamespaceAndPath(ExtendedAEPlus.MODID, "toggle_adv_blocking"));
public static final ToggleAdvancedBlockingC2SPacket INSTANCE = new ToggleAdvancedBlockingC2SPacket();
public static final StreamCodec<FriendlyByteBuf, ToggleAdvancedBlockingC2SPacket> STREAM_CODEC =
StreamCodec.unit(INSTANCE);
private ToggleAdvancedBlockingC2SPacket() {}
public static void handle(final ToggleAdvancedBlockingC2SPacket msg, final IPayloadContext ctx) {
ctx.enqueueWork(() -> {
if (!(ctx.player() instanceof ServerPlayer player)) return;
var containerMenu = player.containerMenu;
if (containerMenu instanceof PatternProviderMenu menu) {
var accessor = (PatternProviderMenuAdvancedAccessor) menu;
var logic = accessor.eap$logic();
if (logic instanceof IAdvancedBlocking holder) {
boolean current = holder.eap$getAdvancedBlocking();
boolean next = !current;
holder.eap$setAdvancedBlocking(next);
// 自动开启原版阻挡
logic.getConfigManager().putSetting(Settings.BLOCKING_MODE, YesNo.YES);
// 保存并触发 AE2 的菜单 @GuiSync 广播到所有观看该菜单的玩家
logic.saveChanges();
}
}else if (containerMenu instanceof AdvPatternProviderMenu menu){
var accessor = (AdvPatternProviderMenuAdvancedAccessor) menu;
var logic = accessor.eap$logic();
if (logic instanceof IAdvancedBlocking holder) {
boolean current = holder.eap$getAdvancedBlocking();
boolean next = !current;
holder.eap$setAdvancedBlocking(next);
// 自动开启原版阻挡
logic.getConfigManager().putSetting(Settings.BLOCKING_MODE, YesNo.YES);
// 保存并触发 AE2 的菜单 @GuiSync 广播到所有观看该菜单的玩家
logic.saveChanges();
}
}
});
}
@Override
public Type<? extends CustomPacketPayload> type() {
return TYPE;
}
}

View File

@ -1,61 +0,0 @@
package com.extendedae_plus.network;
import appeng.menu.implementations.PatternProviderMenu;
import com.extendedae_plus.ExtendedAEPlus;
import com.extendedae_plus.api.smartDoubling.ISmartDoubling;
import com.extendedae_plus.mixin.advancedae.accessor.AdvPatternProviderMenuAdvancedAccessor;
import com.extendedae_plus.mixin.ae2.accessor.PatternProviderMenuAdvancedAccessor;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.neoforged.neoforge.network.handling.IPayloadContext;
import net.pedroksl.advanced_ae.gui.advpatternprovider.AdvPatternProviderMenu;
/**
* C2S切换智能翻倍启用状态
* 不含额外负载基于玩家当前打开的 PatternProviderMenu 进行切换
*/
public class ToggleSmartDoublingC2SPacket implements CustomPacketPayload {
public static final Type<ToggleSmartDoublingC2SPacket> TYPE = new Type<>(
ResourceLocation.fromNamespaceAndPath(ExtendedAEPlus.MODID, "toggle_smart_doubling"));
public static final ToggleSmartDoublingC2SPacket INSTANCE = new ToggleSmartDoublingC2SPacket();
public static final StreamCodec<FriendlyByteBuf, ToggleSmartDoublingC2SPacket> STREAM_CODEC =
StreamCodec.unit(INSTANCE);
private ToggleSmartDoublingC2SPacket() {}
public static void handle(final ToggleSmartDoublingC2SPacket msg, final IPayloadContext ctx) {
ctx.enqueueWork(() -> {
if (!(ctx.player() instanceof ServerPlayer player)) return;
var containerMenu = player.containerMenu;
if (containerMenu instanceof PatternProviderMenu menu) {
var accessor = (PatternProviderMenuAdvancedAccessor) menu;
var logic = accessor.eap$logic();
if (logic instanceof ISmartDoubling holder) {
boolean current = holder.eap$getSmartDoubling();
boolean next = !current;
holder.eap$setSmartDoubling(next);
logic.saveChanges();
}
}else if (containerMenu instanceof AdvPatternProviderMenu menu){
var accessor = (AdvPatternProviderMenuAdvancedAccessor) menu;
var logic = accessor.eap$logic();
if (logic instanceof ISmartDoubling holder) {
boolean current = holder.eap$getSmartDoubling();
boolean next = !current;
holder.eap$setSmartDoubling(next);
logic.saveChanges();
}
}
});
}
@Override
public Type<? extends CustomPacketPayload> type() {
return TYPE;
}
}

View File

@ -138,5 +138,11 @@
"gui.tooltips.extendedae_plus.AccelerateBlacklisted": "Do not accelerate target block entities",
"gui.tooltips.extendedae_plus.RedstoneControl": "Redstone Control",
"gui.tooltips.extendedae_plus.RedstoneControlEnabled": "Control acceleration with redstone signal",
"gui.tooltips.extendedae_plus.RedstoneControlDisabled": "Ignore redstone signals"
"gui.tooltips.extendedae_plus.RedstoneControlDisabled": "Ignore redstone signals",
"gui.tooltips.extendedae_plus.AdvancedBlocking": "Smart Blocking",
"gui.tooltips.extendedae_plus.AdvancedBlockingEnabled": "Will not block the same recipe type (requires vanilla blocking mode enabled)",
"gui.tooltips.extendedae_plus.AdvancedBlockingDisabled": "Use vanilla blocking logic",
"gui.tooltips.extendedae_plus.SmartDoubling": "Smart Doubling",
"gui.tooltips.extendedae_plus.SmartDoublingEnabled": "Intelligently double processing patterns based on request quantity",
"gui.tooltips.extendedae_plus.SmartDoublingDisabled": "Distribute according to original pattern quantity"
}

View File

@ -137,5 +137,11 @@
"gui.tooltips.extendedae_plus.RedstoneControl": "红石控制",
"gui.tooltips.extendedae_plus.RedstoneControlEnabled": "使用红石信号控制加速",
"gui.tooltips.extendedae_plus.RedstoneControlDisabled": "忽略红石信号"
"gui.tooltips.extendedae_plus.RedstoneControlDisabled": "忽略红石信号",
"gui.tooltips.extendedae_plus.AdvancedBlocking": "智能阻挡",
"gui.tooltips.extendedae_plus.AdvancedBlockingEnabled": "对于同一种配方将不再阻挡 (需要启用原版阻挡模式)",
"gui.tooltips.extendedae_plus.AdvancedBlockingDisabled": "使用原版阻挡逻辑",
"gui.tooltips.extendedae_plus.SmartDoubling": "智能翻倍",
"gui.tooltips.extendedae_plus.SmartDoublingEnabled": "根据请求量对处理样板进行智能翻倍",
"gui.tooltips.extendedae_plus.SmartDoublingDisabled": "按原始样板数量进行发配"
}

View File

@ -15,6 +15,7 @@
"advancedae.helpers.AdvPatternProviderLogicAdvancedMixin",
"advancedae.helpers.AdvPatternProviderLogicDoublingMixin",
"advancedae.menu.AdvPatternProviderMenuAdvancedMixin",
"advancedae.menu.AdvPatternProviderMenuDoublingMixin",
"ae2.AEProcessingPatternMixin",
"ae2.CraftingCalculationMixin",
"ae2.CraftingCPUClusterMixin",
@ -73,8 +74,8 @@
"ae2.client.gui.InterfaceScreenMixin",
"ae2.client.gui.PatternEncodingTermScreenMixin",
"ae2.client.gui.PatternProviderCloseMixin",
"ae2.client.gui.PatternProviderScreenMixin",
"ae2.client.gui.PatternProviderScreenUpgradesMixin",
"ae2.client.gui.PatternProviderSmartFeaturesMixin",
"ae2.client.gui.ScreenStyleMixin",
"ae2.client.gui.SlotGridLayoutMixin",
"ae2.menu.CraftConfirmMenuGoBackMixin",