Merge remote-tracking branch 'origin/1.21.1'
# Conflicts: # build/generated/sources/modMetadata/META-INF/neoforge.mods.toml
This commit is contained in:
commit
162b15a748
|
|
@ -166,6 +166,7 @@ dependencies {
|
|||
runtimeOnly "curse.maven:ex-pattern-provider-892005:6863556"
|
||||
|
||||
//aea
|
||||
// compileOnly "curse.maven:advancedae-1084104:6932981"
|
||||
implementation "curse.maven:advancedae-1084104:6932981"
|
||||
|
||||
//geckolib
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package com.extendedae_plus.api.advancedBlocking;
|
||||
|
||||
import appeng.api.config.YesNo;
|
||||
|
||||
public interface IPatternProviderMenuAdvancedSync {
|
||||
boolean eap$getAdvancedBlockingSynced();
|
||||
YesNo eap$getAdvancedBlockingSynced();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,9 +25,6 @@ public final class ScaledProcessingPatternAdv extends ScaledProcessingPattern im
|
|||
this.dirMap = ((AdvProcessingPattern) original).getDirectionMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull AdvProcessingPattern getOriginal() {return (AdvProcessingPattern) this.original;}
|
||||
|
||||
@Override
|
||||
public void pushInputsToExternalInventory(KeyCounter[] inputHolder, PatternInputSink sink) {
|
||||
// 如果 sparseInputs 与 inputs 一一对应,则无需 reorder
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package com.extendedae_plus.api.smartDoubling;
|
||||
|
||||
import appeng.api.config.YesNo;
|
||||
|
||||
public interface IPatternProviderMenuDoublingSync {
|
||||
boolean eap$getSmartDoublingSynced();
|
||||
YesNo eap$getSmartDoublingSynced();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -28,27 +28,27 @@ public class GlobalProviderModesScreen extends AbstractContainerScreen<NetworkPa
|
|||
int x = this.leftPos + (this.imageWidth - totalW3) / 2;
|
||||
|
||||
// 行1:三个单项切换
|
||||
addRenderableWidget(Button.builder(Component.translatable("gui.extendedae_plus.global.toggle_blocking"), b ->
|
||||
this.addRenderableWidget(Button.builder(Component.translatable("gui.extendedae_plus.global.toggle_blocking"), b ->
|
||||
PacketDistributor.sendToServer(new GlobalToggleProviderModesC2SPacket(
|
||||
GlobalToggleProviderModesC2SPacket.Op.TOGGLE,
|
||||
GlobalToggleProviderModesC2SPacket.Op.NOOP,
|
||||
GlobalToggleProviderModesC2SPacket.Op.NOOP,
|
||||
GlobalToggleProviderModesC2SPacket.Operation.TOGGLE,
|
||||
GlobalToggleProviderModesC2SPacket.Operation.NOOP,
|
||||
GlobalToggleProviderModesC2SPacket.Operation.NOOP,
|
||||
this.menu.getBlockEntityPos()
|
||||
))).bounds(x, y, w, h).build());
|
||||
|
||||
addRenderableWidget(Button.builder(Component.translatable("gui.extendedae_plus.global.toggle_adv_blocking"), b ->
|
||||
this.addRenderableWidget(Button.builder(Component.translatable("gui.extendedae_plus.global.toggle_adv_blocking"), b ->
|
||||
PacketDistributor.sendToServer(new GlobalToggleProviderModesC2SPacket(
|
||||
GlobalToggleProviderModesC2SPacket.Op.NOOP,
|
||||
GlobalToggleProviderModesC2SPacket.Op.TOGGLE,
|
||||
GlobalToggleProviderModesC2SPacket.Op.NOOP,
|
||||
GlobalToggleProviderModesC2SPacket.Operation.NOOP,
|
||||
GlobalToggleProviderModesC2SPacket.Operation.TOGGLE,
|
||||
GlobalToggleProviderModesC2SPacket.Operation.NOOP,
|
||||
this.menu.getBlockEntityPos()
|
||||
))).bounds(x + w + s, y, w, h).build());
|
||||
|
||||
addRenderableWidget(Button.builder(Component.translatable("gui.extendedae_plus.global.toggle_smart_doubling"), b ->
|
||||
this.addRenderableWidget(Button.builder(Component.translatable("gui.extendedae_plus.global.toggle_smart_doubling"), b ->
|
||||
PacketDistributor.sendToServer(new GlobalToggleProviderModesC2SPacket(
|
||||
GlobalToggleProviderModesC2SPacket.Op.NOOP,
|
||||
GlobalToggleProviderModesC2SPacket.Op.NOOP,
|
||||
GlobalToggleProviderModesC2SPacket.Op.TOGGLE,
|
||||
GlobalToggleProviderModesC2SPacket.Operation.NOOP,
|
||||
GlobalToggleProviderModesC2SPacket.Operation.NOOP,
|
||||
GlobalToggleProviderModesC2SPacket.Operation.TOGGLE,
|
||||
this.menu.getBlockEntityPos()
|
||||
))).bounds(x + (w + s) * 2, y, w, h).build());
|
||||
|
||||
|
|
@ -57,23 +57,36 @@ public class GlobalProviderModesScreen extends AbstractContainerScreen<NetworkPa
|
|||
// 第二行:两列按钮,总宽并居中
|
||||
int totalW2 = w * 2 + s;
|
||||
int x2 = this.leftPos + (this.imageWidth - totalW2) / 2;
|
||||
addRenderableWidget(Button.builder(Component.translatable("gui.extendedae_plus.global.all_on"), b ->
|
||||
this.addRenderableWidget(Button.builder(Component.translatable("gui.extendedae_plus.global.all_on"), b ->
|
||||
PacketDistributor.sendToServer(new GlobalToggleProviderModesC2SPacket(
|
||||
GlobalToggleProviderModesC2SPacket.Op.SET_TRUE,
|
||||
GlobalToggleProviderModesC2SPacket.Op.SET_TRUE,
|
||||
GlobalToggleProviderModesC2SPacket.Op.SET_TRUE,
|
||||
GlobalToggleProviderModesC2SPacket.Operation.SET_TRUE,
|
||||
GlobalToggleProviderModesC2SPacket.Operation.SET_TRUE,
|
||||
GlobalToggleProviderModesC2SPacket.Operation.SET_TRUE,
|
||||
this.menu.getBlockEntityPos()
|
||||
))).bounds(x2, y2, w, h).build());
|
||||
|
||||
addRenderableWidget(Button.builder(Component.translatable("gui.extendedae_plus.global.all_off"), b ->
|
||||
this.addRenderableWidget(Button.builder(Component.translatable("gui.extendedae_plus.global.all_off"), b ->
|
||||
PacketDistributor.sendToServer(new GlobalToggleProviderModesC2SPacket(
|
||||
GlobalToggleProviderModesC2SPacket.Op.SET_FALSE,
|
||||
GlobalToggleProviderModesC2SPacket.Op.SET_FALSE,
|
||||
GlobalToggleProviderModesC2SPacket.Op.SET_FALSE,
|
||||
GlobalToggleProviderModesC2SPacket.Operation.SET_FALSE,
|
||||
GlobalToggleProviderModesC2SPacket.Operation.SET_FALSE,
|
||||
GlobalToggleProviderModesC2SPacket.Operation.SET_FALSE,
|
||||
this.menu.getBlockEntityPos()
|
||||
))).bounds(x2 + w + s, y2, w, h).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(net.minecraft.client.gui.GuiGraphics gfx, int mouseX, int mouseY, float partialTicks) {
|
||||
this.renderBackground(gfx, mouseX, mouseY, partialTicks);
|
||||
super.render(gfx, mouseX, mouseY, partialTicks);
|
||||
gfx.drawString(this.font, CUSTOM_TITLE, this.leftPos + 10, this.topPos + 8, 0xFFFFFF, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderLabels(net.minecraft.client.gui.GuiGraphics gfx, int mouseX, int mouseY) {
|
||||
// 不绘制默认的玩家物品栏标题(例如“物品栏”),避免与自定义面板重叠
|
||||
// 标题已在 render() 中手动绘制
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderBg(net.minecraft.client.gui.GuiGraphics gfx, float partialTicks, int mouseX, int mouseY) {
|
||||
// 半透明全屏遮罩,避免底层 HUD(准星/物品栏文字)透出
|
||||
|
|
@ -92,17 +105,4 @@ public class GlobalProviderModesScreen extends AbstractContainerScreen<NetworkPa
|
|||
gfx.fill(panelLeft, panelTop, panelLeft + 1, panelBottom, 0x80FFFFFF);
|
||||
gfx.fill(panelRight - 1, panelTop, panelRight, panelBottom, 0x80000000);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(net.minecraft.client.gui.GuiGraphics gfx, int mouseX, int mouseY, float partialTicks) {
|
||||
this.renderBackground(gfx, mouseX, mouseY, partialTicks);
|
||||
super.render(gfx, mouseX, mouseY, partialTicks);
|
||||
gfx.drawString(this.font, CUSTOM_TITLE, this.leftPos + 10, this.topPos + 8, 0xFFFFFF, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderLabels(net.minecraft.client.gui.GuiGraphics gfx, int mouseX, int mouseY) {
|
||||
// 不绘制默认的玩家物品栏标题(例如“物品栏”),避免与自定义面板重叠
|
||||
// 标题已在 render() 中手动绘制
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -10,12 +10,9 @@ 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);
|
||||
registrar.playToClient(AdvancedBlockingSyncS2CPacket.TYPE, AdvancedBlockingSyncS2CPacket.STREAM_CODEC, AdvancedBlockingSyncS2CPacket::handle);
|
||||
registrar.playToClient(ProvidersListS2CPacket.TYPE, ProvidersListS2CPacket.STREAM_CODEC, ProvidersListS2CPacket::handle);
|
||||
registrar.playToServer(RequestProvidersListC2SPacket.TYPE, RequestProvidersListC2SPacket.STREAM_CODEC, RequestProvidersListC2SPacket::handle);
|
||||
registrar.playToClient(SetProviderPageS2CPacket.TYPE, SetProviderPageS2CPacket.STREAM_CODEC, SetProviderPageS2CPacket::handle);
|
||||
|
|
|
|||
|
|
@ -25,14 +25,14 @@ public class AdvPatternProviderLogicContainsRedirectMixin {
|
|||
try {
|
||||
if (o instanceof ScaledProcessingPattern scaled) {
|
||||
IPatternDetails base = scaled.getOriginal();
|
||||
if (list.indexOf(base) != -1) {
|
||||
if (list.contains(base)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// 使用 indexOf 避免再次触发对 List.contains 的 redirect(防止递归)
|
||||
return list.indexOf(o) != -1;
|
||||
return list.contains(o);
|
||||
} catch (Throwable t) {
|
||||
return list.indexOf(o) != -1;
|
||||
return list.contains(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,138 +0,0 @@
|
|||
package com.extendedae_plus.mixin.advancedae.client.gui;
|
||||
|
||||
import appeng.api.config.Settings;
|
||||
import appeng.api.config.YesNo;
|
||||
import appeng.client.gui.AEBaseScreen;
|
||||
import appeng.client.gui.style.ScreenStyle;
|
||||
import appeng.client.gui.widgets.SettingToggleButton;
|
||||
import com.extendedae_plus.api.smartDoubling.IPatternProviderMenuDoublingSync;
|
||||
import com.extendedae_plus.api.advancedBlocking.IPatternProviderMenuAdvancedSync;
|
||||
import com.extendedae_plus.network.ToggleAdvancedBlockingC2SPacket;
|
||||
import com.extendedae_plus.network.ToggleSmartDoublingC2SPacket;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.pedroksl.advanced_ae.client.gui.AdvPatternProviderScreen;
|
||||
import net.pedroksl.advanced_ae.gui.advpatternprovider.AdvPatternProviderMenu;
|
||||
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;
|
||||
|
||||
import static com.extendedae_plus.util.ExtendedAELogger.LOGGER;
|
||||
|
||||
/**
|
||||
* 为高级ae样板供应器界面添加“高级阻挡模式”按钮。
|
||||
* - 位于左侧工具栏
|
||||
* - 点击仅发送 C2S 切换请求;状态由 AE2 @GuiSync 回传决定
|
||||
*/
|
||||
@Mixin(AdvPatternProviderScreen.class)
|
||||
public abstract class AdvPatternProviderScreenMixin extends AEBaseScreen<AdvPatternProviderMenu> {
|
||||
|
||||
@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 AdvPatternProviderScreenMixin(AdvPatternProviderMenu menu, Inventory playerInventory, Component title, ScreenStyle style) {
|
||||
super(menu, playerInventory, title, style);
|
||||
}
|
||||
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
private void eap$initAdvancedBlocking(AdvPatternProviderMenu 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) {
|
||||
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回传
|
||||
var conn = Minecraft.getInstance().getConnection();
|
||||
if (conn != null) conn.send(ToggleAdvancedBlockingC2SPacket.INSTANCE);
|
||||
}
|
||||
) {
|
||||
@Override
|
||||
public java.util.List<Component> getTooltipMessage() {
|
||||
boolean enabled = eap$AdvancedBlockingEnabled;
|
||||
var title = Component.literal("智能阻挡");
|
||||
var line = enabled
|
||||
? 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();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
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) -> {
|
||||
var conn = Minecraft.getInstance().getConnection();
|
||||
if (conn != null) conn.send(ToggleSmartDoublingC2SPacket.INSTANCE);
|
||||
}
|
||||
) {
|
||||
@Override
|
||||
public java.util.List<Component> getTooltipMessage() {
|
||||
boolean enabled = eap$SmartDoublingEnabled;
|
||||
var title = Component.literal("智能翻倍");
|
||||
var line = enabled
|
||||
? Component.literal("已启用:根据请求量对处理样板进行智能缩放")
|
||||
: 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();
|
||||
}
|
||||
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();
|
||||
}
|
||||
this.eap$SmartDoublingEnabled = desired2;
|
||||
this.eap$SmartDoublingToggle.set(desired2 ? YesNo.YES : YesNo.NO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package com.extendedae_plus.mixin.advancedae.client.gui;
|
||||
|
||||
import appeng.api.config.YesNo;
|
||||
import appeng.client.gui.AEBaseScreen;
|
||||
import appeng.client.gui.style.ScreenStyle;
|
||||
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 net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.pedroksl.advanced_ae.client.gui.AdvPatternProviderScreen;
|
||||
import net.pedroksl.advanced_ae.gui.advpatternprovider.AdvPatternProviderMenu;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 为高级ae样板供应器界面添加“高级阻挡模式”按钮。
|
||||
* - 位于左侧工具栏
|
||||
* - 点击仅发送 C2S 切换请求;状态由 AE2 @GuiSync 回传决定
|
||||
*/
|
||||
@Mixin(AdvPatternProviderScreen.class)
|
||||
public abstract class AdvPatternProviderSmartFeaturesMixin extends AEBaseScreen<AdvPatternProviderMenu> {
|
||||
@Unique private EAPServerSettingToggleButton<YesNo> eap$AdvancedBlockingToggle;
|
||||
@Unique private EAPServerSettingToggleButton<YesNo> eap$SmartDoublingToggle;
|
||||
|
||||
public AdvPatternProviderSmartFeaturesMixin(AdvPatternProviderMenu menu, Inventory playerInventory, Component title, ScreenStyle style) {
|
||||
super(menu, playerInventory, title, style);
|
||||
}
|
||||
|
||||
@Inject(method = "<init>", at = @At("RETURN"), remap = false)
|
||||
private void eap$initAdvancedBlocking(AdvPatternProviderMenu 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +1,12 @@
|
|||
package com.extendedae_plus.mixin.advancedae.client.gui;
|
||||
|
||||
import appeng.api.config.Settings;
|
||||
import appeng.api.config.YesNo;
|
||||
import appeng.client.gui.AEBaseScreen;
|
||||
import appeng.client.gui.style.ScreenStyle;
|
||||
import appeng.client.gui.widgets.SettingToggleButton;
|
||||
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.network.ToggleAdvancedBlockingC2SPacket;
|
||||
import com.extendedae_plus.network.ToggleSmartDoublingC2SPacket;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import com.extendedae_plus.client.gui.widgets.EAPServerSettingToggleButton;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.pedroksl.advanced_ae.client.gui.SmallAdvPatternProviderScreen;
|
||||
|
|
@ -20,8 +17,6 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import static com.extendedae_plus.util.ExtendedAELogger.LOGGER;
|
||||
|
||||
/**
|
||||
* 为高级ae样板供应器界面添加“高级阻挡模式”按钮。
|
||||
* - 位于左侧工具栏
|
||||
|
|
@ -29,110 +24,29 @@ import static com.extendedae_plus.util.ExtendedAELogger.LOGGER;
|
|||
*/
|
||||
@Mixin(SmallAdvPatternProviderScreen.class)
|
||||
public abstract class SmallAdvPatternProviderScreenMixin extends AEBaseScreen<SmallAdvPatternProviderMenu> {
|
||||
|
||||
@Unique
|
||||
private SettingToggleButton<YesNo> eap$AdvancedBlockingToggle;
|
||||
|
||||
@Unique
|
||||
private boolean eap$AdvancedBlockingEnabled = false;
|
||||
|
||||
@Unique
|
||||
private SettingToggleButton<YesNo> eap$SmartDoublingToggle;
|
||||
|
||||
@Unique
|
||||
private boolean eap$SmartDoublingEnabled = false;
|
||||
@Unique private EAPServerSettingToggleButton<YesNo> eap$AdvancedBlockingToggle;
|
||||
@Unique private EAPServerSettingToggleButton<YesNo> eap$SmartDoublingToggle;
|
||||
|
||||
public SmallAdvPatternProviderScreenMixin(SmallAdvPatternProviderMenu menu, Inventory playerInventory, Component title, ScreenStyle style) {
|
||||
super(menu, playerInventory, title, style);
|
||||
}
|
||||
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
@Inject(method = "<init>", at = @At("RETURN"), remap = false)
|
||||
private void eap$initAdvancedBlocking(SmallAdvPatternProviderMenu 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) {
|
||||
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回传
|
||||
var conn = Minecraft.getInstance().getConnection();
|
||||
if (conn != null) conn.send(ToggleAdvancedBlockingC2SPacket.INSTANCE);
|
||||
}
|
||||
) {
|
||||
@Override
|
||||
public java.util.List<Component> getTooltipMessage() {
|
||||
boolean enabled = SmallAdvPatternProviderScreenMixin.this.eap$AdvancedBlockingEnabled;
|
||||
var title = Component.literal("智能阻挡");
|
||||
var line = enabled
|
||||
? Component.literal("已启用:对于同一种配方将不再阻挡(需要开启原版的阻挡模式)")
|
||||
: Component.literal("已禁用:这么好的功能为什么不打开呢");
|
||||
return java.util.List.of(title, line);
|
||||
}
|
||||
};
|
||||
// 初始化后立刻对齐当前@GuiSync状态,避免首帧显示不一致
|
||||
this.eap$AdvancedBlockingToggle.set(this.eap$AdvancedBlockingEnabled ? YesNo.YES : YesNo.NO);
|
||||
|
||||
this.eap$AdvancedBlockingToggle = new EAPServerSettingToggleButton<>(EAPSettings.ADVANCED_BLOCKING, YesNo.YES);
|
||||
this.addToLeftToolbar(this.eap$AdvancedBlockingToggle);
|
||||
|
||||
// 智能翻倍按钮:与高级阻挡同款样式,点击仅发送C2S,状态由@GuiSync驱动
|
||||
try {
|
||||
if (menu instanceof IPatternProviderMenuDoublingSync sync2) {
|
||||
this.eap$SmartDoublingEnabled = sync2.eap$getSmartDoublingSynced();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
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) -> {
|
||||
var conn = Minecraft.getInstance().getConnection();
|
||||
if (conn != null) conn.send(ToggleSmartDoublingC2SPacket.INSTANCE);
|
||||
}
|
||||
) {
|
||||
@Override
|
||||
public java.util.List<Component> getTooltipMessage() {
|
||||
boolean enabled = SmallAdvPatternProviderScreenMixin.this.eap$SmartDoublingEnabled;
|
||||
var title = Component.literal("智能翻倍");
|
||||
var line = enabled
|
||||
? Component.literal("已启用:根据请求量对处理样板进行智能缩放")
|
||||
: Component.literal("已禁用:按原始样板数量进行发配");
|
||||
return java.util.List.of(title, line);
|
||||
}
|
||||
};
|
||||
|
||||
this.eap$SmartDoublingToggle.set(this.eap$SmartDoublingEnabled ? YesNo.YES : YesNo.NO);
|
||||
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.eap$AdvancedBlockingToggle != null) {
|
||||
boolean desired = this.eap$AdvancedBlockingEnabled;
|
||||
if (this.menu instanceof IPatternProviderMenuAdvancedSync sync) {
|
||||
desired = sync.eap$getAdvancedBlockingSynced();
|
||||
}
|
||||
this.eap$AdvancedBlockingEnabled = desired;
|
||||
this.eap$AdvancedBlockingToggle.set(desired ? YesNo.YES : YesNo.NO);
|
||||
if (this.menu instanceof IPatternProviderMenuDoublingSync sync) {
|
||||
this.eap$SmartDoublingToggle.set(sync.eap$getSmartDoublingSynced());
|
||||
}
|
||||
|
||||
if (this.eap$SmartDoublingToggle != null) {
|
||||
boolean desired2 = this.eap$SmartDoublingEnabled;
|
||||
if (this.menu instanceof IPatternProviderMenuDoublingSync sync2) {
|
||||
desired2 = sync2.eap$getSmartDoublingSynced();
|
||||
}
|
||||
this.eap$SmartDoublingEnabled = desired2;
|
||||
this.eap$SmartDoublingToggle.set(desired2 ? YesNo.YES : YesNo.NO);
|
||||
if (this.menu instanceof IPatternProviderMenuAdvancedSync sync) {
|
||||
this.eap$AdvancedBlockingToggle.set(sync.eap$getAdvancedBlockingSynced());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,23 @@
|
|||
package com.extendedae_plus.mixin.advancedae.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.PatternProviderTarget;
|
||||
import com.extendedae_plus.api.advancedBlocking.IAdvancedBlocking;
|
||||
import appeng.util.ConfigManager;
|
||||
import com.extendedae_plus.api.config.EAPSettings;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.pedroksl.advanced_ae.common.logic.AdvPatternProviderLogic;
|
||||
import net.pedroksl.advanced_ae.common.logic.AdvPatternProviderLogicHost;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
|
@ -18,51 +27,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 = AdvPatternProviderLogic.class, remap = false)
|
||||
public class AdvPatternProviderLogicAdvancedMixin implements IAdvancedBlocking {
|
||||
@Unique
|
||||
private static final String EAP_ADV_BLOCKING_KEY = "eap_advanced_blocking";
|
||||
public class AdvPatternProviderLogicAdvancedMixin {
|
||||
@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;Lnet/pedroksl/advanced_ae/common/logic/AdvPatternProviderLogicHost;I)V",
|
||||
at = @At("TAIL")
|
||||
)
|
||||
private void onInitTail(IManagedGridNode mainNode, AdvPatternProviderLogicHost 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 = ((AdvPatternProviderLogic)(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;
|
||||
|
|
@ -90,5 +93,26 @@ public class AdvPatternProviderLogicAdvancedMixin implements IAdvancedBlocking {
|
|||
return true; // 每个输入槽都至少匹配了一个候选输入
|
||||
}
|
||||
|
||||
@Shadow public void saveChanges() {}
|
||||
@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 = "readFromNBT", at = @At("TAIL"))
|
||||
private void eap$readSmartDoublingFromNbt(CompoundTag tag, HolderLookup.Provider registries, CallbackInfo ci) {
|
||||
// TODO
|
||||
// 适配旧版本中的数据,后续版本删除
|
||||
if (tag.contains("eap_advanced_blocking")) {
|
||||
this.configManager.putSetting(EAPSettings.ADVANCED_BLOCKING,
|
||||
tag.getBoolean("eap_advanced_blocking") ? YesNo.YES : YesNo.NO);
|
||||
tag.remove("eap_advanced_blocking");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,75 +1,73 @@
|
|||
package com.extendedae_plus.mixin.advancedae.helpers;
|
||||
|
||||
import appeng.api.config.Setting;
|
||||
import appeng.api.config.YesNo;
|
||||
import appeng.api.crafting.IPatternDetails;
|
||||
import com.extendedae_plus.api.smartDoubling.ISmartDoubling;
|
||||
import appeng.api.networking.IManagedGridNode;
|
||||
import appeng.api.util.IConfigManager;
|
||||
import appeng.util.ConfigManager;
|
||||
import com.extendedae_plus.api.config.EAPSettings;
|
||||
import com.extendedae_plus.api.smartDoubling.ISmartDoublingAwarePattern;
|
||||
import com.extendedae_plus.mixin.advancedae.accessor.AdvPatternProviderLogicPatternsAccessor;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.pedroksl.advanced_ae.common.logic.AdvPatternProviderLogic;
|
||||
import net.pedroksl.advanced_ae.common.logic.AdvPatternProviderLogicHost;
|
||||
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 = AdvPatternProviderLogic.class, remap = false)
|
||||
public class AdvPatternProviderLogicDoublingMixin implements ISmartDoubling {
|
||||
@Unique
|
||||
private static final String EAP_SMART_DOUBLING_KEY = "eap_smart_doubling";
|
||||
public class AdvPatternProviderLogicDoublingMixin {
|
||||
@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;Lnet/pedroksl/advanced_ae/common/logic/AdvPatternProviderLogicHost;I)V",
|
||||
at = @At("TAIL")
|
||||
)
|
||||
private void onInitTail(IManagedGridNode mainNode, AdvPatternProviderLogicHost 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 = ((AdvPatternProviderLogicPatternsAccessor) this).eap$patterns();
|
||||
for (IPatternDetails details : list) {
|
||||
if (details instanceof ISmartDoublingAwarePattern aware) {
|
||||
aware.eap$setAllowScaling(value);
|
||||
}
|
||||
}
|
||||
// 触发一次刷新,让网络及时拿到最新状态(也会触发 ICraftingProvider.requestUpdate(mainNode))
|
||||
((AdvPatternProviderLogic) (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, 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, HolderLookup.Provider registries, CallbackInfo ci) {
|
||||
if (tag.contains(EAP_SMART_DOUBLING_KEY)) {
|
||||
this.eap$smartDoubling = tag.getBoolean(EAP_SMART_DOUBLING_KEY);
|
||||
// TODO
|
||||
// 适配旧版本中的数据,后续版本删除
|
||||
if (tag.contains("eap_smart_doubling")) {
|
||||
this.configManager.putSetting(EAPSettings.SMART_DOUBLING,
|
||||
tag.getBoolean("eap_smart_doubling") ? YesNo.YES : YesNo.NO);
|
||||
tag.remove("eap_smart_doubling");
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "updatePatterns", at = @At("TAIL"))
|
||||
private void eap$applySmartDoublingToPatterns(CallbackInfo ci) {
|
||||
try {
|
||||
var list = ((AdvPatternProviderLogicPatternsAccessor) this).eap$patterns();
|
||||
boolean allow = this.eap$smartDoubling;
|
||||
for (IPatternDetails details : list) {
|
||||
if (details 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() {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
package com.extendedae_plus.mixin.advancedae.menu;
|
||||
|
||||
import appeng.menu.AEBaseMenu;
|
||||
import appeng.api.config.YesNo;
|
||||
import appeng.menu.guisync.GuiSync;
|
||||
import com.extendedae_plus.api.advancedBlocking.IAdvancedBlocking;
|
||||
import com.extendedae_plus.api.advancedBlocking.IPatternProviderMenuAdvancedSync;
|
||||
import com.extendedae_plus.api.config.EAPSettings;
|
||||
import net.pedroksl.advanced_ae.common.logic.AdvPatternProviderLogic;
|
||||
import net.pedroksl.advanced_ae.gui.advpatternprovider.AdvPatternProviderMenu;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
|
|
@ -14,29 +14,20 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(AdvPatternProviderMenu.class)
|
||||
@Mixin(value = AdvPatternProviderMenu.class, remap = false)
|
||||
public abstract class AdvPatternProviderMenuAdvancedMixin implements IPatternProviderMenuAdvancedSync {
|
||||
@Final
|
||||
@Shadow(remap = false)
|
||||
protected AdvPatternProviderLogic logic;
|
||||
|
||||
// 选择一个未占用的 GUI 同步 id(AE2 已用到 7),这里使用 21 以避冲突
|
||||
@Unique
|
||||
@GuiSync(22) private boolean eap$AdvancedBlocking = false;
|
||||
@Shadow @Final protected AdvPatternProviderLogic logic;
|
||||
@Unique @GuiSync(20) private YesNo eap$AdvancedBlocking;
|
||||
|
||||
@Inject(method = "broadcastChanges", at = @At("HEAD"))
|
||||
private void eap$syncAdvancedBlocking(CallbackInfo ci) {
|
||||
// 避免@Shadow父类方法,改用公共API:AEBaseMenu#isClientSide()
|
||||
if (!((AEBaseMenu) (Object) this).isClientSide()) {
|
||||
var l = this.logic;
|
||||
if (l instanceof IAdvancedBlocking holder) {
|
||||
this.eap$AdvancedBlocking = holder.eap$getAdvancedBlocking();
|
||||
}
|
||||
private void eap$syncSmartDoubling(CallbackInfo ci) {
|
||||
if (!((AdvPatternProviderMenu) (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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
package com.extendedae_plus.mixin.advancedae.menu;
|
||||
|
||||
import appeng.menu.AEBaseMenu;
|
||||
import appeng.api.config.YesNo;
|
||||
import appeng.menu.guisync.GuiSync;
|
||||
import com.extendedae_plus.api.config.EAPSettings;
|
||||
import com.extendedae_plus.api.smartDoubling.IPatternProviderMenuDoublingSync;
|
||||
import com.extendedae_plus.api.smartDoubling.ISmartDoubling;
|
||||
import net.pedroksl.advanced_ae.common.logic.AdvPatternProviderLogic;
|
||||
import net.pedroksl.advanced_ae.gui.advpatternprovider.AdvPatternProviderMenu;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
|
|
@ -14,27 +14,20 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(AdvPatternProviderMenu.class)
|
||||
@Mixin(value = AdvPatternProviderMenu.class, remap = false)
|
||||
public abstract class AdvPatternProviderMenuDoublingMixin implements IPatternProviderMenuDoublingSync {
|
||||
@Final
|
||||
@Shadow(remap = false)
|
||||
protected AdvPatternProviderLogic logic;
|
||||
|
||||
@Unique
|
||||
@GuiSync(23) private boolean eap$SmartDoubling = false;
|
||||
@Shadow @Final protected AdvPatternProviderLogic 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();
|
||||
}
|
||||
if (!((AdvPatternProviderMenu) (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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,14 +25,14 @@ public class PatternProviderLogicContainsRedirectMixin {
|
|||
try {
|
||||
if (o instanceof ScaledProcessingPattern scaled) {
|
||||
IPatternDetails base = scaled.getOriginal();
|
||||
if (list.indexOf(base) != -1) {
|
||||
if (list.contains(base)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// 使用 indexOf 避免再次触发对 List.contains 的 redirect(防止递归)
|
||||
return list.indexOf(o) != -1;
|
||||
return list.contains(o);
|
||||
} catch (Throwable t) {
|
||||
return list.indexOf(o) != -1;
|
||||
return list.contains(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,154 +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.translatable("gui.tooltips.extendedae_plus.advanced_blocking.title");
|
||||
var line = net.minecraft.network.chat.Component.translatable(
|
||||
enabled ? "gui.tooltips.extendedae_plus.advanced_blocking.enabled"
|
||||
: "gui.tooltips.extendedae_plus.advanced_blocking.disabled"
|
||||
);
|
||||
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.translatable("gui.tooltips.extendedae_plus.smart_doubling.title");
|
||||
var line = net.minecraft.network.chat.Component.translatable(
|
||||
enabled ? "gui.tooltips.extendedae_plus.smart_doubling.enabled"
|
||||
: "gui.tooltips.extendedae_plus.smart_doubling.disabled"
|
||||
);
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 同步 id(AE2 已用到 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父类方法,改用公共API:AEBaseMenu#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) {
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
package com.extendedae_plus.network;
|
||||
|
||||
import com.extendedae_plus.ExtendedAEPlus;
|
||||
import com.extendedae_plus.client.ClientAdvancedBlockingState;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.neoforged.neoforge.network.handling.IPayloadContext;
|
||||
|
||||
/**
|
||||
* S2C:同步某个 Provider 的高级阻挡状态到客户端(本地存储)。
|
||||
*/
|
||||
public class AdvancedBlockingSyncS2CPacket implements CustomPacketPayload {
|
||||
public static final Type<AdvancedBlockingSyncS2CPacket> TYPE = new Type<>(
|
||||
ResourceLocation.fromNamespaceAndPath(ExtendedAEPlus.MODID, "adv_blocking_sync"));
|
||||
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, AdvancedBlockingSyncS2CPacket> STREAM_CODEC = StreamCodec.of(
|
||||
(buf, pkt) -> {
|
||||
buf.writeUtf(pkt.dimensionId);
|
||||
buf.writeLong(pkt.blockPosLong);
|
||||
buf.writeBoolean(pkt.enabled);
|
||||
},
|
||||
buf -> new AdvancedBlockingSyncS2CPacket(buf.readUtf(), buf.readLong(), buf.readBoolean())
|
||||
);
|
||||
|
||||
private final String dimensionId;
|
||||
private final long blockPosLong;
|
||||
private final boolean enabled;
|
||||
|
||||
public AdvancedBlockingSyncS2CPacket(String dimensionId, long blockPosLong, boolean enabled) {
|
||||
this.dimensionId = dimensionId;
|
||||
this.blockPosLong = blockPosLong;
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type<? extends CustomPacketPayload> type() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
public static void handle(final AdvancedBlockingSyncS2CPacket msg, final IPayloadContext ctx) {
|
||||
ctx.enqueueWork(() -> {
|
||||
String key = ClientAdvancedBlockingState.key(msg.dimensionId, msg.blockPosLong);
|
||||
ClientAdvancedBlockingState.set(key, msg.enabled);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -9,8 +9,7 @@ import appeng.helpers.patternprovider.PatternProviderLogic;
|
|||
import appeng.helpers.patternprovider.PatternProviderLogicHost;
|
||||
import appeng.parts.crafting.PatternProviderPart;
|
||||
import com.extendedae_plus.ExtendedAEPlus;
|
||||
import com.extendedae_plus.api.advancedBlocking.IAdvancedBlocking;
|
||||
import com.extendedae_plus.api.smartDoubling.ISmartDoubling;
|
||||
import com.extendedae_plus.api.config.EAPSettings;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
|
@ -19,188 +18,244 @@ 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 org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* C2S:全网批量切换样板供应器的三种模式:
|
||||
* - 阻挡模式(AE2 内置 BLOCKING_MODE 设置)
|
||||
* - 高级阻挡模式(IAdvancedBlocking mixin)
|
||||
* - 智能翻倍模式(ISmartDoubling mixin)
|
||||
*
|
||||
* 负载为三个操作码(各1字节),分别对应:blocking、advancedBlocking、smartDoubling。
|
||||
* C2S 包:全局批量切换样板供应器的三种模式
|
||||
* - 普通阻挡模式(AE2 原生 BLOCKING_MODE)
|
||||
* - 高级阻挡模式
|
||||
* - 智能翻倍模式
|
||||
* <p>
|
||||
* 包体包含三个操作码(每个 1 byte)以及控制器方块位置,用于定位所属 ME 网络。
|
||||
*/
|
||||
public class GlobalToggleProviderModesC2SPacket implements CustomPacketPayload {
|
||||
|
||||
public static final Type<GlobalToggleProviderModesC2SPacket> TYPE = new Type<>(
|
||||
ResourceLocation.fromNamespaceAndPath(ExtendedAEPlus.MODID, "global_toggle_provider_modes"));
|
||||
|
||||
public static final StreamCodec<FriendlyByteBuf, GlobalToggleProviderModesC2SPacket> STREAM_CODEC = StreamCodec.of(
|
||||
(buf, pkt) -> {
|
||||
buf.writeByte(pkt.opBlocking.id);
|
||||
buf.writeByte(pkt.opAdvancedBlocking.id);
|
||||
buf.writeByte(pkt.opSmartDoubling.id);
|
||||
buf.writeBlockPos(pkt.controllerPos);
|
||||
(buf, packet) -> {
|
||||
buf.writeByte(packet.blockingModeOperation.id);
|
||||
buf.writeByte(packet.advancedBlockingOperation.id);
|
||||
buf.writeByte(packet.smartDoublingOperation.id);
|
||||
buf.writeBlockPos(packet.controllerBlockPos);
|
||||
},
|
||||
buf -> new GlobalToggleProviderModesC2SPacket(Op.byId(buf.readByte()), Op.byId(buf.readByte()), Op.byId(buf.readByte()), buf.readBlockPos())
|
||||
buf -> new GlobalToggleProviderModesC2SPacket(
|
||||
Operation.byId(buf.readByte()),
|
||||
Operation.byId(buf.readByte()),
|
||||
Operation.byId(buf.readByte()),
|
||||
buf.readBlockPos())
|
||||
);
|
||||
private final Op opBlocking;
|
||||
private final Op opAdvancedBlocking;
|
||||
private final Op opSmartDoubling;
|
||||
private final BlockPos controllerPos;
|
||||
public GlobalToggleProviderModesC2SPacket(Op opBlocking, Op opAdvancedBlocking, Op opSmartDoubling, BlockPos controllerPos) {
|
||||
this.opBlocking = opBlocking;
|
||||
this.opAdvancedBlocking = opAdvancedBlocking;
|
||||
this.opSmartDoubling = opSmartDoubling;
|
||||
this.controllerPos = controllerPos;
|
||||
|
||||
private final Operation blockingModeOperation;
|
||||
private final Operation advancedBlockingOperation;
|
||||
private final Operation smartDoublingOperation;
|
||||
|
||||
/**
|
||||
* 发起请求的玩家的控制器位置,用于获取对应的 IGrid
|
||||
*/
|
||||
private final BlockPos controllerBlockPos;
|
||||
|
||||
public GlobalToggleProviderModesC2SPacket(Operation blockingModeOperation,
|
||||
Operation advancedBlockingOperation,
|
||||
Operation smartDoublingOperation,
|
||||
BlockPos controllerBlockPos) {
|
||||
this.blockingModeOperation = blockingModeOperation;
|
||||
this.advancedBlockingOperation = advancedBlockingOperation;
|
||||
this.smartDoublingOperation = smartDoublingOperation;
|
||||
this.controllerBlockPos = controllerBlockPos;
|
||||
}
|
||||
|
||||
public static void handle(final GlobalToggleProviderModesC2SPacket msg, final IPayloadContext ctx) {
|
||||
ctx.enqueueWork(() -> {
|
||||
if (!(ctx.player() instanceof ServerPlayer player)) return;
|
||||
if (player == null) return;
|
||||
public static void handle(final GlobalToggleProviderModesC2SPacket message, final IPayloadContext context) {
|
||||
context.enqueueWork(() -> {
|
||||
if (!(context.player() instanceof ServerPlayer player)) return;
|
||||
|
||||
// 从控制方块实体的 AE2 节点确定 AE 网络上下文
|
||||
var level = player.serverLevel();
|
||||
var be = level.getBlockEntity(msg.controllerPos);
|
||||
if (!(be instanceof IInWorldGridNodeHost host)) return;
|
||||
var node = host.getGridNode(null);
|
||||
if (node == null) return;
|
||||
IGrid grid = node.getGrid();
|
||||
var blockEntity = level.getBlockEntity(message.controllerBlockPos);
|
||||
if (!(blockEntity instanceof IInWorldGridNodeHost gridNodeHost)) return;
|
||||
|
||||
var gridNode = gridNodeHost.getGridNode(null);
|
||||
if (gridNode == null) return;
|
||||
|
||||
IGrid grid = gridNode.getGrid();
|
||||
if (grid == null) return;
|
||||
|
||||
int affected = applyToAllProviders(grid, msg);
|
||||
// 向发起玩家反馈影响数量,便于判断按钮是否生效
|
||||
player.displayClientMessage(Component.literal("E+ 全局切换已应用到 " + affected + " 个样板供应器"), true);
|
||||
int affectedCount = applyToAllPatternProviders(grid, message);
|
||||
|
||||
// 给发起者一个短暂的行动条提示,方便知道本次操作实际影响了多少个供应器
|
||||
player.displayClientMessage(
|
||||
Component.literal("E+ 全局切换已应用到 " + affectedCount + " 个样板供应器"),
|
||||
true);
|
||||
});
|
||||
}
|
||||
|
||||
private static int applyToAllProviders(IGrid grid, GlobalToggleProviderModesC2SPacket msg) {
|
||||
int affected = 0;
|
||||
// 去重集合,避免同一逻辑重复计数
|
||||
Set<PatternProviderLogic> all = new HashSet<>();
|
||||
/**
|
||||
* 遍历当前 ME 网络中所有样板供应器(方块、零件、第三方实现),并应用切换操作
|
||||
*/
|
||||
private static int applyToAllPatternProviders(IGrid grid, GlobalToggleProviderModesC2SPacket message) {
|
||||
int affectedCount = 0;
|
||||
// 用 Set 去重,因为同一个 Logic 实例可能被多种方式收集到
|
||||
Set<PatternProviderLogic> uniqueLogics = new HashSet<>();
|
||||
|
||||
// 方块形式的样板供应器(全部/在线)
|
||||
try {
|
||||
Set<PatternProviderBlockEntity> blocksAll = grid.getMachines(PatternProviderBlockEntity.class);
|
||||
Set<PatternProviderBlockEntity> blocksActive = grid.getActiveMachines(PatternProviderBlockEntity.class);
|
||||
for (PatternProviderBlockEntity be : blocksAll) if (be != null && be.getLogic() != null) all.add(be.getLogic());
|
||||
for (PatternProviderBlockEntity be : blocksActive) if (be != null && be.getLogic() != null) all.add(be.getLogic());
|
||||
} catch (Throwable ignored) {}
|
||||
// 1. AE2 原生的方块实体形式(Pattern Provider BlockEntity)
|
||||
collectLogicsFromMachineSet(grid.getMachines(PatternProviderBlockEntity.class), uniqueLogics);
|
||||
collectLogicsFromMachineSet(grid.getActiveMachines(PatternProviderBlockEntity.class), uniqueLogics);
|
||||
|
||||
// Part 形式的样板供应器(全部/在线)
|
||||
try {
|
||||
Set<PatternProviderPart> partsAll = grid.getMachines(PatternProviderPart.class);
|
||||
Set<PatternProviderPart> partsActive = grid.getActiveMachines(PatternProviderPart.class);
|
||||
for (PatternProviderPart part : partsAll) if (part != null && part.getLogic() != null) all.add(part.getLogic());
|
||||
for (PatternProviderPart part : partsActive) if (part != null && part.getLogic() != null) all.add(part.getLogic());
|
||||
} catch (Throwable ignored) {}
|
||||
// 2. AE2 原生的电缆零件形式(Pattern Provider Part)
|
||||
collectLogicsFromMachineSet(grid.getMachines(PatternProviderPart.class), uniqueLogics);
|
||||
collectLogicsFromMachineSet(grid.getActiveMachines(PatternProviderPart.class), uniqueLogics);
|
||||
|
||||
// 兼容:任意实现了 PatternProviderLogicHost 的机器(例如 ExtendedAE 的 PartExPatternProvider)
|
||||
try {
|
||||
Set<PatternProviderLogicHost> hostsAll = grid.getMachines(PatternProviderLogicHost.class);
|
||||
Set<PatternProviderLogicHost> hostsActive = grid.getActiveMachines(PatternProviderLogicHost.class);
|
||||
for (PatternProviderLogicHost host : hostsAll) if (host != null && host.getLogic() != null) all.add(host.getLogic());
|
||||
for (PatternProviderLogicHost host : hostsActive) if (host != null && host.getLogic() != null) all.add(host.getLogic());
|
||||
} catch (Throwable ignored) {}
|
||||
// 3. 任何实现了 PatternProviderLogicHost 接口的机器(包括 ExtendedAE 自己的扩展)
|
||||
collectLogicsFromMachineSet(grid.getMachines(PatternProviderLogicHost.class), uniqueLogics);
|
||||
collectLogicsFromMachineSet(grid.getActiveMachines(PatternProviderLogicHost.class), uniqueLogics);
|
||||
|
||||
// 兼容:显式匹配第三方具体类(通过反射),避免 AE2 仅按精确类型匹配导致 interface 不返回的问题
|
||||
collectByClassName(grid, all, "com.glodblock.github.extendedae.common.parts.PartExPatternProvider");
|
||||
collectByClassName(grid, all, "com.glodblock.github.extendedae.common.tileentities.TileExPatternProvider");
|
||||
// 4. 兼容 ExtendedAE(glodblock)自己的 ExPatternProvider(因为 AE2 的 getMachines 只按精确类匹配接口会漏)
|
||||
collectByReflection(grid, uniqueLogics, "com.glodblock.github.extendedae.common.parts.PartExPatternProvider");
|
||||
collectByReflection(grid, uniqueLogics, "com.glodblock.github.extendedae.common.tileentities.TileExPatternProvider");
|
||||
|
||||
for (PatternProviderLogic logic : all) {
|
||||
if (applyToLogic(logic, msg)) affected++;
|
||||
// 真正执行切换
|
||||
for (PatternProviderLogic logic : uniqueLogics) {
|
||||
if (applyOperationToLogic(logic, message)) {
|
||||
affectedCount++;
|
||||
}
|
||||
}
|
||||
return affected;
|
||||
return affectedCount;
|
||||
}
|
||||
|
||||
private static void collectByClassName(IGrid grid, Set<PatternProviderLogic> out, String className) {
|
||||
try {
|
||||
Class<?> cls = Class.forName(className);
|
||||
// 收集全部与在线两类机器
|
||||
Set<?> all = grid.getMachines((Class) cls);
|
||||
Set<?> active = grid.getActiveMachines((Class) cls);
|
||||
for (Object o : all) addLogicIfPresent(out, o);
|
||||
for (Object o : active) addLogicIfPresent(out, o);
|
||||
} catch (Throwable ignored) {}
|
||||
/**
|
||||
* 工具方法:把一个 Set<? extends SomeMachine> 中的 Logic 加入去重集合
|
||||
*/
|
||||
private static void collectLogicsFromMachineSet(Set<?> machineSet, Set<PatternProviderLogic> target) {
|
||||
if (machineSet == null) return;
|
||||
for (Object obj : machineSet) {
|
||||
addLogicIfPresent(target, obj);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addLogicIfPresent(Set<PatternProviderLogic> out, Object o) {
|
||||
/**
|
||||
* 通过反射兼容第三方精确类(防止接口匹配漏掉)
|
||||
*/
|
||||
private static void collectByReflection(IGrid grid, Set<PatternProviderLogic> target, String className) {
|
||||
try {
|
||||
if (o instanceof PatternProviderLogicHost host) {
|
||||
var logic = host.getLogic();
|
||||
if (logic != null) out.add(logic);
|
||||
Class<?> clazz = Class.forName(className);
|
||||
collectLogicsFromMachineSet(grid.getMachines(clazz), target);
|
||||
collectLogicsFromMachineSet(grid.getActiveMachines(clazz), target);
|
||||
} catch (Throwable ignored) {
|
||||
// 如果类不存在(比如玩家没装 ExtendedAE)直接忽略
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从任意对象里尝试取出 PatternProviderLogic(兼容多种实现)
|
||||
*/
|
||||
private static void addLogicIfPresent(Set<PatternProviderLogic> target, Object obj) {
|
||||
if (obj == null) return;
|
||||
try {
|
||||
if (obj instanceof PatternProviderLogicHost host && host.getLogic() != null) {
|
||||
target.add(host.getLogic());
|
||||
return;
|
||||
}
|
||||
// 兜底:若对象有 getLogic 方法且返回 PatternProviderLogic
|
||||
var m = o.getClass().getMethod("getLogic");
|
||||
Object ret = m.invoke(o);
|
||||
if (ret instanceof PatternProviderLogic logic) out.add(logic);
|
||||
} catch (Throwable ignored) {}
|
||||
// 兜底反射调用 getLogic()
|
||||
var method = obj.getClass().getMethod("getLogic");
|
||||
Object result = method.invoke(obj);
|
||||
if (result instanceof PatternProviderLogic logic) {
|
||||
target.add(logic);
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean applyToLogic(PatternProviderLogic logic, GlobalToggleProviderModesC2SPacket msg) {
|
||||
/**
|
||||
* 对单个 PatternProviderLogic 应用本次包里携带的三种操作
|
||||
*/
|
||||
private static boolean applyOperationToLogic(PatternProviderLogic logic, GlobalToggleProviderModesC2SPacket message) {
|
||||
if (logic == null) return false;
|
||||
boolean changed = false;
|
||||
// 1) 阻挡模式(AE2 内置设置)
|
||||
if (msg.opBlocking != Op.NOOP) {
|
||||
boolean current = safeIsBlocking(logic);
|
||||
boolean target = computeTarget(current, msg.opBlocking);
|
||||
var cm = logic.getConfigManager();
|
||||
if (cm != null) {
|
||||
cm.putSetting(Settings.BLOCKING_MODE, target ? YesNo.YES : YesNo.NO);
|
||||
changed = changed || (current != target);
|
||||
var configManager = logic.getConfigManager();
|
||||
if (configManager == null) return false;
|
||||
|
||||
boolean anyChanged = false;
|
||||
|
||||
// 1. AE2 原生阻挡模式
|
||||
if (message.blockingModeOperation != Operation.NOOP) {
|
||||
boolean current = isBlockingModeEnabled(logic);
|
||||
boolean target = calculateTargetState(current, message.blockingModeOperation);
|
||||
configManager.putSetting(Settings.BLOCKING_MODE, target ? YesNo.YES : YesNo.NO);
|
||||
anyChanged |= (current != target);
|
||||
}
|
||||
|
||||
// 2. 高级阻挡模式
|
||||
if (message.advancedBlockingOperation != Operation.NOOP) {
|
||||
boolean current = configManager.getSetting(EAPSettings.ADVANCED_BLOCKING) == YesNo.YES;
|
||||
boolean target = calculateTargetState(current, message.advancedBlockingOperation);
|
||||
configManager.putSetting(EAPSettings.ADVANCED_BLOCKING, target ? YesNo.YES : YesNo.NO);
|
||||
anyChanged |= (current != target);
|
||||
}
|
||||
|
||||
// 3. 智能翻倍模式
|
||||
if (message.smartDoublingOperation != Operation.NOOP) {
|
||||
boolean current = configManager.getSetting(EAPSettings.SMART_DOUBLING) == YesNo.YES;
|
||||
boolean target = calculateTargetState(current, message.smartDoublingOperation);
|
||||
configManager.putSetting(EAPSettings.SMART_DOUBLING, target ? YesNo.YES : YesNo.NO);
|
||||
anyChanged |= (current != target);
|
||||
}
|
||||
|
||||
// 有改动时保存并让 AE2 同步到客户端
|
||||
if (anyChanged) {
|
||||
try {
|
||||
logic.saveChanges();
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
// 2) 高级阻挡(mixin 接口)
|
||||
if (msg.opAdvancedBlocking != Op.NOOP && logic instanceof IAdvancedBlocking adv) {
|
||||
boolean current = adv.eap$getAdvancedBlocking();
|
||||
boolean target = computeTarget(current, msg.opAdvancedBlocking);
|
||||
adv.eap$setAdvancedBlocking(target);
|
||||
changed = changed || (current != target);
|
||||
}
|
||||
// 3) 智能翻倍(mixin 接口)
|
||||
if (msg.opSmartDoubling != Op.NOOP && logic instanceof ISmartDoubling sd) {
|
||||
boolean current = sd.eap$getSmartDoubling();
|
||||
boolean target = computeTarget(current, msg.opSmartDoubling);
|
||||
sd.eap$setSmartDoubling(target);
|
||||
changed = changed || (current != target);
|
||||
}
|
||||
// 保存更改并让 AE2 同步
|
||||
if (changed) {
|
||||
try { logic.saveChanges(); } catch (Throwable ignored) {}
|
||||
}
|
||||
return changed;
|
||||
return anyChanged;
|
||||
}
|
||||
|
||||
private static boolean computeTarget(boolean current, Op op) {
|
||||
return switch (op) {
|
||||
/**
|
||||
* 根据当前状态和操作码计算目标状态
|
||||
*/
|
||||
private static boolean calculateTargetState(boolean currentValue, Operation operation) {
|
||||
return switch (operation) {
|
||||
case SET_TRUE -> true;
|
||||
case SET_FALSE -> false;
|
||||
case TOGGLE -> !current;
|
||||
default -> current;
|
||||
case TOGGLE -> !currentValue;
|
||||
case NOOP -> currentValue;
|
||||
};
|
||||
}
|
||||
|
||||
private static boolean safeIsBlocking(PatternProviderLogic logic) {
|
||||
try { return logic.isBlocking(); } catch (Throwable t) { return false; }
|
||||
/**
|
||||
* 安全获取 AE2 原生阻挡模式状态(防止旧版本抛异常)
|
||||
*/
|
||||
private static boolean isBlockingModeEnabled(PatternProviderLogic logic) {
|
||||
try {
|
||||
return logic.isBlocking();
|
||||
} catch (Throwable t) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type<? extends CustomPacketPayload> type() {
|
||||
public @NotNull Type<? extends CustomPacketPayload> type() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
public enum Op {
|
||||
NOOP((byte) 0),
|
||||
SET_TRUE((byte) 1),
|
||||
SET_FALSE((byte) 2),
|
||||
TOGGLE((byte) 3);
|
||||
/**
|
||||
* 操作类型枚举(对应客户端发来的 1 byte)
|
||||
*/
|
||||
public enum Operation {
|
||||
NOOP((byte) 0), // 不执行任何操作
|
||||
SET_TRUE((byte) 1), // 强制开启
|
||||
SET_FALSE((byte) 2), // 强制关闭
|
||||
TOGGLE((byte) 3); // 切换当前状态
|
||||
|
||||
public final byte id;
|
||||
|
||||
Op(byte id) {this.id = id;}
|
||||
Operation(byte id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
static Op byId(byte id) {
|
||||
static Operation byId(byte id) {
|
||||
return switch (id) {
|
||||
case 1 -> SET_TRUE;
|
||||
case 2 -> SET_FALSE;
|
||||
|
|
@ -209,4 +264,4 @@ public class GlobalToggleProviderModesC2SPacket implements CustomPacketPayload {
|
|||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -142,10 +142,10 @@
|
|||
"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.advanced_blocking.title": "Smart Blocking",
|
||||
"gui.tooltips.extendedae_plus.advanced_blocking.enabled": "Enabled: Will not block the same recipe type (requires vanilla blocking mode to be on)",
|
||||
"gui.tooltips.extendedae_plus.advanced_blocking.disabled": "Disabled: Why not turn on this great feature?",
|
||||
"gui.tooltips.extendedae_plus.smart_doubling.title": "Smart Doubling",
|
||||
"gui.tooltips.extendedae_plus.smart_doubling.enabled": "Enabled: Intelligently scales processing patterns based on request amount",
|
||||
"gui.tooltips.extendedae_plus.smart_doubling.disabled": "Disabled: Distributes according to original pattern count"
|
||||
"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"
|
||||
}
|
||||
|
|
@ -141,11 +141,10 @@
|
|||
"gui.tooltips.extendedae_plus.RedstoneControl": "红石控制",
|
||||
"gui.tooltips.extendedae_plus.RedstoneControlEnabled": "使用红石信号控制加速",
|
||||
"gui.tooltips.extendedae_plus.RedstoneControlDisabled": "忽略红石信号",
|
||||
|
||||
"gui.tooltips.extendedae_plus.advanced_blocking.title": "智能阻挡",
|
||||
"gui.tooltips.extendedae_plus.advanced_blocking.enabled": "已启用:对于同一种配方将不再阻挡(需要开启原版的阻挡模式)",
|
||||
"gui.tooltips.extendedae_plus.advanced_blocking.disabled": "已禁用:这么好的功能为什么不打开呢",
|
||||
"gui.tooltips.extendedae_plus.smart_doubling.title": "智能翻倍",
|
||||
"gui.tooltips.extendedae_plus.smart_doubling.enabled": "已启用:根据请求量对处理样板进行智能缩放",
|
||||
"gui.tooltips.extendedae_plus.smart_doubling.disabled": "已禁用:按原始样板数量进行发配"
|
||||
"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": "按原始样板数量进行发配"
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@
|
|||
"advancedae.helpers.AdvPatternProviderLogicAdvancedMixin",
|
||||
"advancedae.helpers.AdvPatternProviderLogicDoublingMixin",
|
||||
"advancedae.menu.AdvPatternProviderMenuAdvancedMixin",
|
||||
"advancedae.menu.AdvPatternProviderMenuDoublingMixin",
|
||||
"ae2.AEProcessingPatternMixin",
|
||||
"ae2.CraftingCalculationMixin",
|
||||
"ae2.CraftingCPUClusterMixin",
|
||||
|
|
@ -62,7 +63,7 @@
|
|||
"PickFromWirelessMixin",
|
||||
"accessor.AbstractContainerScreenAccessor",
|
||||
"accessor.ScreenAccessor",
|
||||
"advancedae.client.gui.AdvPatternProviderScreenMixin",
|
||||
"advancedae.client.gui.AdvPatternProviderSmartFeaturesMixin",
|
||||
"advancedae.client.gui.SmallAdvPatternProviderScreenMixin",
|
||||
"ae2.QuartzCuttingKnifeItemMixin",
|
||||
"ae2.accessor.AEBaseScreenAccessor",
|
||||
|
|
@ -75,8 +76,8 @@
|
|||
"ae2.client.gui.PatternEncodingTermScreenMixin",
|
||||
"ae2.client.gui.PatternEncodingTermUploadMixin",
|
||||
"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",
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user