diff --git a/src/main/java/com/extendedae_plus/ae/menu/EntitySpeedTickerMenu.java b/src/main/java/com/extendedae_plus/ae/menu/EntitySpeedTickerMenu.java index 086a261..1ec0691 100644 --- a/src/main/java/com/extendedae_plus/ae/menu/EntitySpeedTickerMenu.java +++ b/src/main/java/com/extendedae_plus/ae/menu/EntitySpeedTickerMenu.java @@ -1,11 +1,13 @@ package com.extendedae_plus.ae.menu; +import appeng.api.config.YesNo; +import appeng.api.util.IConfigManager; import appeng.core.definitions.AEItems; import appeng.menu.guisync.GuiSync; import appeng.menu.implementations.UpgradeableMenu; -import appeng.menu.slot.OptionalFakeSlot; import com.extendedae_plus.ae.parts.EntitySpeedTickerPart; import com.extendedae_plus.ae.screen.EntitySpeedTickerScreen; +import com.extendedae_plus.api.config.EAPSettings; import com.extendedae_plus.config.ModConfigs; import com.extendedae_plus.init.ModItems; import com.extendedae_plus.init.ModMenuTypes; @@ -21,14 +23,21 @@ import net.minecraft.world.level.block.entity.BlockEntity; * 实体加速器菜单,负责管理客户端与服务端的数据同步,处理加速卡、能量卡和目标方块的状态。 */ public class EntitySpeedTickerMenu extends UpgradeableMenu { - @GuiSync(716) public boolean accelerateEnabled = true; // 是否启用加速 - @GuiSync(717) public int entitySpeedCardCount; // 已安装的实体加速卡数量 - @GuiSync(718) public int energyCardCount; // 已安装的能量卡数量 - @GuiSync(719) public int effectiveSpeed = 1; // 当前生效的加速倍率 - @GuiSync(720) public double multiplier = 1.0; // 目标方块的配置倍率 - @GuiSync(721) public boolean targetBlacklisted = false; // 目标方块是否在黑名单中 - @GuiSync(722) public boolean networkEnergySufficient = true; // 网络能量是否充足 + @GuiSync(716) public YesNo accelerate; // 是否启用加速 + @GuiSync(717) public YesNo redstoneControl; // 是否启用红石控制 + private int entitySpeedCardCount; // 已安装的实体加速卡数量 + @GuiSync(719) public int energyCardCount; // 已安装的能量卡数量 + @GuiSync(720) public int effectiveSpeed = 1; // 当前生效的加速倍率 + @GuiSync(721) public double multiplier = 1.0; // 目标方块的配置倍率 + @GuiSync(722) public boolean targetBlacklisted = false; // 目标方块是否在黑名单中 + @GuiSync(723) public YesNo networkEnergySufficient; // 网络能量是否充足 + protected final EntitySpeedTickerPart logic; + + @Override + protected void loadSettingsFromHost(IConfigManager cm) { + // 不需要模糊模式 + } /** * 构造函数,初始化菜单并绑定部件。 * @param id 菜单ID @@ -37,39 +46,7 @@ public class EntitySpeedTickerMenu extends UpgradeableMenu partItem) { @@ -80,51 +85,40 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka .setFlags(GridFlags.REQUIRE_CHANNEL) .setIdlePowerUsage(1) .addService(IGridTickable.class, this); + configManager = IConfigManager.builder(this::configChanged) + .registerSetting(EAPSettings.ACCELERATE, YesNo.NO) + .registerSetting(EAPSettings.REDSTONE_CONTROL, YesNo.YES) + .build(); } - public boolean getAccelerateEnabled() { - return this.accelerateEnabled; + private void configChanged(IConfigManager manager, Setting setting) { + this.saveChanges(); + } + + public void saveChanges() { + getHost().markForSave(); + } + + public boolean isAccelerate() { + return this.configManager.getSetting(EAPSettings.ACCELERATE) == YesNo.YES; + } + + public boolean isRedstoneControl() { + return this.configManager.getSetting(EAPSettings.REDSTONE_CONTROL) == YesNo.YES; } public boolean isNetworkEnergySufficient() { - return this.networkEnergySufficient; - } - - /** - * 设置加速开关状态并通知菜单。 - * @param enabled 是否启用加速 - */ - public void setAccelerateEnabled(boolean enabled) { - this.accelerateEnabled = enabled; - if (menu != null) { - menu.setAccelerateEnabled(enabled); - } + return this.networkEnergySufficient == YesNo.YES; } /** * 更新网络能量充足状态并通知菜单。 + * * @param sufficient 是否能量充足 */ - private void updateNetworkEnergySufficient(boolean sufficient) { - this.networkEnergySufficient = sufficient; - if (menu != null) { - menu.setNetworkEnergySufficient(sufficient); - } - } - - /** - * 获取当前状态的渲染模型。 - * @return 当前状态的模型 - */ - @Override - public IPartModel getStaticModels() { - if (this.isActive() && this.isPowered()) { - return MODELS_HAS_CHANNEL; - } else if (this.isPowered()) { - return MODELS_ON; - } else { - return MODELS_OFF; - } + private void setNetworkEnergySufficient(boolean sufficient) { + this.networkEnergySufficient = sufficient ? YesNo.YES : YesNo.NO; + saveChanges(); } /** @@ -142,6 +136,22 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka return true; } + /** + * 获取当前状态的渲染模型。 + * + * @return 当前状态的模型 + */ + @Override + public IPartModel getStaticModels() { + if (this.isActive() && this.isPowered()) { + return MODELS_HAS_CHANNEL; + } else if (this.isPowered()) { + return MODELS_ON; + } else { + return MODELS_OFF; + } + } + /** * 定义部件的碰撞箱(用于物理碰撞和渲染) * @@ -165,17 +175,6 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka return new TickingRequest(1, 1, false); } - /** - * 当升级卡数量发生变化时调用,通知菜单更新 - */ - @Override - public void upgradesChanged() { - if (this.menu != null) { - // 使用 AE2 风格:当升级发生变化时让菜单广播变化(槽/数据会被同步),客户端会基于槽内容重新计算并刷新界面 - this.menu.broadcastChanges(); - } - } - /** * 网络定时回调,每次 tick 时调用 * @@ -186,7 +185,13 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka @Override public TickRateModulation tickingRequest(IGridNode iGridNode, int ticksSinceLastCall) { // 如果部件的加速开关被关闭,则不进行加速(提前返回) - if (!this.getAccelerateEnabled()) { + if (!isAccelerate()) { + return TickRateModulation.IDLE; + } + + // 检查红石控制 + if (isRedstoneControl() && !getRedstoneState()) { + // 如果启用了红石控制且没有红石信号,则不执行加速 return TickRateModulation.IDLE; } @@ -201,8 +206,9 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka /** * 对目标方块实体执行加速 tick 操作。 + * * @param blockEntity 目标方块实体 - * @param 方块实体类型 + * @param 方块实体类型 */ private void ticker(@NotNull T blockEntity) { if (!isValidForTicking()) { @@ -234,6 +240,7 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka /** * 检查网络节点是否有效。 + * * @return 是否可以执行 tick */ private boolean isValidForTicking() { @@ -242,6 +249,7 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka /** * 获取目标方块实体的 ticker。 + * * @param blockEntity 目标方块实体 * @return ticker 或 null */ @@ -252,6 +260,7 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka /** * 计算加速倍率。 + * * @return 生效的加速倍率 */ private int calculateSpeed() { @@ -262,7 +271,8 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka /** * 计算所需能量。 - * @param speed 加速倍率 + * + * @param speed 加速倍率 * @param blockId 目标方块ID * @return 所需能量 */ @@ -274,6 +284,7 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka /** * 提取网络能量并更新状态,优先从 AE2 网络提取 AE 能量,不足时从磁盘提取 FE 能量。 + * * @param requiredPower 所需能量(AE 单位) * @return 是否成功提取足够能量 */ @@ -296,10 +307,10 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka if (simulated >= requiredPower) { double extracted = energyService.extractAEPower(requiredPower, Actionable.MODULATE, PowerMultiplier.CONFIG); boolean sufficient = extracted >= requiredPower; - updateNetworkEnergySufficient(sufficient); + setNetworkEnergySufficient(sufficient); return sufficient; } - updateNetworkEnergySufficient(false); + setNetworkEnergySufficient(false); // 如果 appflux 存在且优先 AE 能量,尝试提取 FE 能量作为备用 if (appFluxLoaded && !preferDiskEnergy) { @@ -321,21 +332,22 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka long feRequired = (long) requiredPower << 1; // 1 AE = 2 FE long feExtracted = (long) extractMethod.invoke(null, energyService, storage, feRequired, source); if (feExtracted >= feRequired) { - updateNetworkEnergySufficient(true); + setNetworkEnergySufficient(true); return true; } } catch (Exception e) { // 如果反射失败,视为 FE 不可用 } - updateNetworkEnergySufficient(false); + setNetworkEnergySufficient(false); return false; } /** * 执行加速 tick 操作。 + * * @param blockEntity 目标方块实体 - * @param ticker 方块实体 ticker - * @param speed 加速倍率 + * @param ticker 方块实体 ticker + * @param speed 加速倍率 */ private void performTicks(T blockEntity, BlockEntityTicker ticker, @@ -395,4 +407,36 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka protected int getUpgradeSlots() { return 8; } + + /** + * 当升级卡数量发生变化时调用,通知菜单更新 + */ + @Override + public void upgradesChanged() { + if (this.menu != null) { + // 使用 AE2 风格:当升级发生变化时让菜单广播变化(槽/数据会被同步),客户端会基于槽内容重新计算并刷新界面 + this.menu.broadcastChanges(); + } + } + + public IConfigManager getConfigManager() { + return this.configManager; + } + + // 获取红石信号状态 + private boolean getRedstoneState() { + // 每次调用都更新红石状态,确保及时性 + updateRedstoneState(); + return redstoneState == YesNo.YES; + } + + // 更新红石信号状态 + private void updateRedstoneState() { + var be = this.getHost().getBlockEntity(); + if (be != null && be.getLevel() != null) { + redstoneState = be.getLevel().hasNeighborSignal(be.getBlockPos()) + ? YesNo.YES + : YesNo.NO; + } + } } \ No newline at end of file diff --git a/src/main/java/com/extendedae_plus/ae/screen/EntitySpeedTickerScreen.java b/src/main/java/com/extendedae_plus/ae/screen/EntitySpeedTickerScreen.java index b9a4352..834b616 100644 --- a/src/main/java/com/extendedae_plus/ae/screen/EntitySpeedTickerScreen.java +++ b/src/main/java/com/extendedae_plus/ae/screen/EntitySpeedTickerScreen.java @@ -1,90 +1,71 @@ package com.extendedae_plus.ae.screen; -import appeng.api.config.Settings; + import appeng.api.config.YesNo; -import appeng.client.gui.Icon; import appeng.client.gui.implementations.UpgradeableScreen; import appeng.client.gui.style.ScreenStyle; import appeng.client.gui.widgets.CommonButtons; -import appeng.client.gui.widgets.SettingToggleButton; import appeng.util.Platform; import com.extendedae_plus.ae.menu.EntitySpeedTickerMenu; -import com.extendedae_plus.network.ToggleEntityTickerC2SPacket; +import com.extendedae_plus.api.config.EAPSettings; +import com.extendedae_plus.client.gui.widgets.EAPServerSettingToggleButton; +import com.extendedae_plus.client.gui.widgets.EAPSettingToggleButton; import com.extendedae_plus.util.entitySpeed.PowerUtils; -import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; import net.minecraft.network.chat.Component; import net.minecraft.world.entity.player.Inventory; import java.util.HashMap; -import java.util.List; import java.util.Map; -public class EntitySpeedTickerScreen extends UpgradeableScreen { - private boolean eap$entitySpeedTickerEnabled = false; // 本地缓存的加速开关状态 - private final SettingToggleButton eap$entitySpeedTickerToggle; // 加速开关按钮 +public class EntitySpeedTickerScreen extends UpgradeableScreen { + private final EAPSettingToggleButton accelerateButton; // 加速开关按钮 + private final EAPSettingToggleButton redstoneControlButton; // 加速开关按钮 /** * 构造函数,初始化界面和控件。 - * @param menu 实体加速器菜单 + * + * @param menu 实体加速器菜单 * @param playerInventory 玩家背包 - * @param title 界面标题 - * @param style 界面样式 + * @param title 界面标题 + * @param style 界面样式 */ - public EntitySpeedTickerScreen(EntitySpeedTickerMenu menu, Inventory playerInventory, Component title, ScreenStyle style) { - super((C) menu, playerInventory, title, style); + public EntitySpeedTickerScreen(EntitySpeedTickerMenu menu, + Inventory playerInventory, + Component title, + ScreenStyle style) { + super(menu, playerInventory, title, style); this.addToLeftToolbar(CommonButtons.togglePowerUnit()); // 添加功率单位切换按钮 - this.eap$entitySpeedTickerEnabled = menu.getAccelerateEnabled(); - // 初始化加速开关按钮 - eap$entitySpeedTickerToggle = new SettingToggleButton<>( - Settings.BLOCKING_MODE, - this.eap$entitySpeedTickerEnabled ? YesNo.YES : YesNo.NO, - (btn, backwards) -> { - // 不做本地切换,点击仅发送自定义C2S,显示由@GuiSync回传 - var conn = Minecraft.getInstance().getConnection(); - if (conn != null) conn.send(ToggleEntityTickerC2SPacket.INSTANCE); - } - ) { - @Override - public List getTooltipMessage() { - if (menu.targetBlacklisted) { - return List.of( - Component.literal("实体加速"), - Component.literal("已禁用(目标在黑名单)") - ); - } - boolean enabled = eap$entitySpeedTickerEnabled; - return List.of( - Component.literal("实体加速"), - enabled ? Component.literal("已启用: 将加速目标方块实体的tick") : - Component.literal("已关闭: 不会对目标方块实体进行加速") - ); - } + this.accelerateButton = new EAPServerSettingToggleButton<>(EAPSettings.ACCELERATE, YesNo.NO); + this.addToLeftToolbar(this.accelerateButton); - @Override - protected Icon getIcon() { - if (menu.targetBlacklisted) return Icon.INVALID; - return this.getCurrentValue() == YesNo.YES ? Icon.VALID : Icon.INVALID; - } - }; - eap$entitySpeedTickerToggle.set(this.eap$entitySpeedTickerEnabled ? YesNo.YES : YesNo.NO); - this.addToLeftToolbar(eap$entitySpeedTickerToggle); + this.redstoneControlButton = new EAPServerSettingToggleButton<>(EAPSettings.REDSTONE_CONTROL, YesNo.NO); + this.addToLeftToolbar(this.redstoneControlButton); } @Override protected void updateBeforeRender() { super.updateBeforeRender(); - if (eap$entitySpeedTickerToggle != null && menu != null) { - eap$entitySpeedTickerEnabled = menu.getAccelerateEnabled(); - // 如果目标在黑名单,禁用按钮并显示关闭状态 - eap$entitySpeedTickerToggle.set(menu.targetBlacklisted ? YesNo.NO : (eap$entitySpeedTickerEnabled ? YesNo.YES : YesNo.NO)); - eap$entitySpeedTickerToggle.active = !menu.targetBlacklisted; + // 如果目标在黑名单,禁用按钮并显示关闭状态 + if (this.menu.targetBlacklisted) { + this.accelerateButton.active = false; + this.accelerateButton.set(YesNo.UNDECIDED); + } else { + this.accelerateButton.set(this.menu.getAccelerate()); } - textData(); + + this.redstoneControlButton.set(this.menu.getRedstoneControl()); + this.textData(); + } + + @Override + public void drawBG(GuiGraphics guiGraphics, int offsetX, int offsetY, int mouseX, int mouseY, float partialTicks) { + super.drawBG(guiGraphics, offsetX, offsetY, mouseX, mouseY, partialTicks); } public void refreshGui() { - textData(); + this.textData(); } /** @@ -92,7 +73,7 @@ public class EntitySpeedTickerScreen extends Up */ private void textData() { Map textContents = new HashMap<>(); - if (getMenu().targetBlacklisted) { + if (this.getMenu().targetBlacklisted) { // 黑名单禁用时的默认显示 textContents.put("enable", Component.translatable("screen.extendedae_plus.entity_speed_ticker.enable")); textContents.put("speed", Component.translatable("screen.extendedae_plus.entity_speed_ticker.speed", 0)); @@ -101,13 +82,13 @@ public class EntitySpeedTickerScreen extends Up textContents.put("multiplier", Component.translatable("screen.extendedae_plus.entity_speed_ticker.multiplier", String.format("%.2fx", 0.0))); } else { // 正常状态下显示实际数据 - int energyCardCount = getMenu().energyCardCount; - double multiplier = getMenu().multiplier; - int effectiveSpeed = getMenu().effectiveSpeed; + int energyCardCount = this.getMenu().energyCardCount; + double multiplier = this.getMenu().multiplier; + int effectiveSpeed = this.getMenu().effectiveSpeed; double finalPower = PowerUtils.computeFinalPowerForProduct(effectiveSpeed, energyCardCount); double remainingRatio = PowerUtils.getRemainingRatio(energyCardCount); - textContents.put("enable", getMenu().networkEnergySufficient ? null : + textContents.put("enable", this.getMenu().networkEnergySufficient == YesNo.YES ? null : Component.translatable("screen.extendedae_plus.entity_speed_ticker.warning_network_energy_insufficient")); textContents.put("speed", Component.translatable("screen.extendedae_plus.entity_speed_ticker.speed", effectiveSpeed)); textContents.put("energy", Component.translatable("screen.extendedae_plus.entity_speed_ticker.energy", Platform.formatPower(finalPower, false))); diff --git a/src/main/java/com/extendedae_plus/api/config/EAPSettings.java b/src/main/java/com/extendedae_plus/api/config/EAPSettings.java new file mode 100644 index 0000000..bac75e2 --- /dev/null +++ b/src/main/java/com/extendedae_plus/api/config/EAPSettings.java @@ -0,0 +1,42 @@ +package com.extendedae_plus.api.config; + +import appeng.api.config.Setting; +import appeng.api.config.YesNo; +import com.google.common.base.Preconditions; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; + +public final class EAPSettings { + private static final Map> SETTINGS = new HashMap<>(); + public static final Setting ACCELERATE = register("accelerate", YesNo.NO, YesNo.YES); + public static final Setting REDSTONE_CONTROL = register("redstoneControl", YesNo.NO, YesNo.YES); + + + private EAPSettings() { + } + + private synchronized static > Setting register(String name, Class enumClass) { + Preconditions.checkState(!SETTINGS.containsKey(name)); + var setting = new Setting<>(name, enumClass); + SETTINGS.put(name, setting); + return setting; + } + + @SafeVarargs + private synchronized static > Setting register(String name, T firstOption, T... moreOptions) { + Preconditions.checkState(!SETTINGS.containsKey(name)); + var setting = new Setting(name, firstOption.getDeclaringClass(), EnumSet.of(firstOption, moreOptions)); + SETTINGS.put(name, setting); + return setting; + } + + public static Setting getOrThrow(String name) { + var setting = SETTINGS.get(name); + if (setting == null) { + throw new IllegalArgumentException("Unknown setting '" + name + "'"); + } + return setting; + } +} diff --git a/src/main/java/com/extendedae_plus/client/ClientProxy.java b/src/main/java/com/extendedae_plus/client/ClientProxy.java index 9c373ee..39761f9 100644 --- a/src/main/java/com/extendedae_plus/client/ClientProxy.java +++ b/src/main/java/com/extendedae_plus/client/ClientProxy.java @@ -4,7 +4,6 @@ import appeng.client.render.crafting.CraftingCubeModel; import appeng.init.client.InitScreens; import com.extendedae_plus.ExtendedAEPlus; import com.extendedae_plus.ae.definitions.upgrades.EntitySpeedCardItem; -import com.extendedae_plus.ae.menu.EntitySpeedTickerMenu; import com.extendedae_plus.ae.screen.EntitySpeedTickerScreen; import com.extendedae_plus.client.render.crafting.EPlusCraftingCubeModelProvider; import com.extendedae_plus.content.crafting.EPlusCraftingUnitType; @@ -77,6 +76,6 @@ public final class ClientProxy { /** * 注册由 AE2 InitScreens 所需的屏幕资源映射(用于内置 JSON 屏幕注册) */ - InitScreens.register(event, ModMenuTypes.ENTITY_TICKER_MENU.get(), EntitySpeedTickerScreen::new, "/screens/entity_speed_ticker.json"); + InitScreens.register(event, ModMenuTypes.ENTITY_TICKER_MENU.get(), EntitySpeedTickerScreen::new, "/screens/entity_speed_ticker.json"); } } diff --git a/src/main/java/com/extendedae_plus/client/gui/widgets/EAPServerSettingToggleButton.java b/src/main/java/com/extendedae_plus/client/gui/widgets/EAPServerSettingToggleButton.java new file mode 100644 index 0000000..8eba770 --- /dev/null +++ b/src/main/java/com/extendedae_plus/client/gui/widgets/EAPServerSettingToggleButton.java @@ -0,0 +1,18 @@ +package com.extendedae_plus.client.gui.widgets; + +import appeng.api.config.Setting; +import appeng.core.network.ServerboundPacket; +import com.extendedae_plus.network.packet.EAPConfigButtonPacket; +import net.neoforged.neoforge.network.PacketDistributor; + +public class EAPServerSettingToggleButton> extends EAPSettingToggleButton { + + public EAPServerSettingToggleButton(Setting setting, T val) { + super(setting, val, EAPServerSettingToggleButton::sendToServer); + } + + private static > void sendToServer(EAPSettingToggleButton button, boolean backwards) { + ServerboundPacket message = new EAPConfigButtonPacket(button.getSetting(), backwards); + PacketDistributor.sendToServer(message); + } +} \ No newline at end of file diff --git a/src/main/java/com/extendedae_plus/client/gui/widgets/EAPSettingToggleButton.java b/src/main/java/com/extendedae_plus/client/gui/widgets/EAPSettingToggleButton.java new file mode 100644 index 0000000..4860fee --- /dev/null +++ b/src/main/java/com/extendedae_plus/client/gui/widgets/EAPSettingToggleButton.java @@ -0,0 +1,197 @@ +package com.extendedae_plus.client.gui.widgets; + +import appeng.api.config.Setting; +import appeng.api.config.YesNo; +import appeng.client.gui.AEBaseScreen; +import appeng.client.gui.Icon; +import appeng.client.gui.widgets.IconButton; +import appeng.core.localization.ButtonToolTips; +import appeng.core.localization.LocalizationEnum; +import appeng.util.EnumCycler; +import com.extendedae_plus.api.config.EAPSettings; +import com.extendedae_plus.common.definitions.EAPText; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.ItemLike; +import org.jetbrains.annotations.Nullable; + +import java.util.*; +import java.util.function.Predicate; + +public class EAPSettingToggleButton> extends IconButton { + private static Map, ButtonAppearance> appearances; + private final Setting buttonSetting; + private final IHandler> onPress; + private final EnumSet validValues; + private T currentValue; + + public EAPSettingToggleButton(Setting setting, T val, + IHandler> onPress) { + this(setting, val, t -> true, onPress); + } + + public EAPSettingToggleButton(Setting setting, T val, Predicate isValidValue, + IHandler> onPress) { + super(EAPSettingToggleButton::onPress); + this.onPress = onPress; + + EnumSet validValues = EnumSet.allOf(val.getDeclaringClass()); + validValues.removeIf(isValidValue.negate()); + validValues.removeIf(s -> !setting.getValues().contains(s)); + this.validValues = validValues; + + this.buttonSetting = setting; + this.currentValue = val; + + if (appearances == null) { + appearances = new HashMap<>(); + registerApp(Icon.VALID, EAPSettings.ACCELERATE, YesNo.YES, + EAPText.Accelerate, + EAPText.AccelerateEnabled); + registerApp(Icon.INVALID, EAPSettings.ACCELERATE, YesNo.NO, + EAPText.Accelerate, + EAPText.AccelerateDisabled); + registerApp(Icon.INVALID, EAPSettings.ACCELERATE, YesNo.UNDECIDED, + EAPText.Accelerate, + EAPText.AccelerateBlacklisted); + + registerApp(Icon.REDSTONE_LOW, EAPSettings.REDSTONE_CONTROL, YesNo.YES, + EAPText.RedstoneControl, + EAPText.RedstoneControlEnabled); + registerApp(Icon.REDSTONE_IGNORE, EAPSettings.REDSTONE_CONTROL, YesNo.NO, + EAPText.RedstoneControl, + EAPText.RedstoneControlDisabled); + } + } + + private static void onPress(Button btn) { + if (btn instanceof EAPSettingToggleButton) { + ((EAPSettingToggleButton) btn).triggerPress(); + } + } + + private static > void registerApp(Icon icon, Setting setting, T val, + LocalizationEnum title, Component... tooltipLines) { + var lines = new ArrayList(); + lines.add(title.text()); + Collections.addAll(lines, tooltipLines); + + appearances.put( + new EnumPair<>(setting, val), + new ButtonAppearance(icon, null, lines)); + } + + private static > void registerApp(ItemLike item, Setting setting, T val, + LocalizationEnum title, Component... tooltipLines) { + var lines = new ArrayList(); + lines.add(title.text()); + Collections.addAll(lines, tooltipLines); + + appearances.put( + new EnumPair<>(setting, val), + new ButtonAppearance(null, item.asItem(), lines)); + } + + private static > void registerApp(Icon icon, Setting setting, T val, + LocalizationEnum title, LocalizationEnum hint) { + registerApp(icon, setting, val, title, hint.text()); + } + + private void triggerPress() { + boolean backwards = false; + Screen currentScreen = Minecraft.getInstance().screen; + if (currentScreen instanceof AEBaseScreen) { + backwards = ((AEBaseScreen) currentScreen).isHandlingRightClick(); + } + onPress.handle(this, backwards); + } + + @Nullable + private ButtonAppearance getApperance() { + if (this.buttonSetting != null && this.currentValue != null) { + return appearances.get(new EnumPair<>(this.buttonSetting, this.currentValue)); + } + return null; + } + + @Override + protected Icon getIcon() { + var app = getApperance(); + if (app != null && app.icon != null) { + return app.icon; + } + return Icon.TOOLBAR_BUTTON_BACKGROUND; + } + + @Override + protected Item getItemOverlay() { + var app = getApperance(); + if (app != null && app.item != null) { + return app.item; + } + return null; + } + + @Override + public List getTooltipMessage() { + + if (this.buttonSetting == null || this.currentValue == null) { + return Collections.emptyList(); + } + + var buttonAppearance = appearances.get(new EnumPair<>(this.buttonSetting, this.currentValue)); + if (buttonAppearance == null) { + return Collections.singletonList(ButtonToolTips.NoSuchMessage.text()); + } + + return buttonAppearance.tooltipLines; + } + + public Setting getSetting() { + return this.buttonSetting; + } + + public T getCurrentValue() { + return this.currentValue; + } + + public void set(T e) { + if (this.currentValue != e) { + this.currentValue = e; + } + } + + public T getNextValue(boolean backwards) { + return EnumCycler.rotateEnum(currentValue, backwards, validValues); + } + + @FunctionalInterface + public interface IHandler> { + void handle(T button, boolean backwards); + } + + private record EnumPair>(Setting setting, T value) { + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (this.getClass() != obj.getClass()) { + return false; + } + final EnumPair other = (EnumPair) obj; + return other.setting == this.setting && other.value == this.value; + } + + @Override + public int hashCode() { + return this.setting.hashCode() ^ this.value.hashCode(); + } + } + + private record ButtonAppearance(@Nullable Icon icon, @Nullable Item item, List tooltipLines) { + } +} diff --git a/src/main/java/com/extendedae_plus/common/definitions/EAPText.java b/src/main/java/com/extendedae_plus/common/definitions/EAPText.java new file mode 100644 index 0000000..c8efc7e --- /dev/null +++ b/src/main/java/com/extendedae_plus/common/definitions/EAPText.java @@ -0,0 +1,41 @@ +package com.extendedae_plus.common.definitions; + +import appeng.core.localization.LocalizationEnum; + +public enum EAPText implements LocalizationEnum { + Accelerate("Entity Acceleration", Type.TOOLTIP), + AccelerateEnabled("Accelerate target block entity ticks", Type.TOOLTIP), + AccelerateDisabled("Do not accelerate target block entities", Type.TOOLTIP), + AccelerateBlacklisted("Target is blacklisted", Type.TOOLTIP), + + RedstoneControl("Redstone control", Type.TOOLTIP), + RedstoneControlEnabled("Control acceleration with redstone signal", Type.TOOLTIP), + RedstoneControlDisabled("Ignore redstone signals", Type.TOOLTIP); + + private final String englishText; + private final Type type; + + EAPText(String englishText, Type type) { + this.englishText = englishText; + this.type = type; + } + + public String getEnglishText() { + return this.englishText; + } + + public String getTranslationKey() { + return String.format("%s.%s.%s", this.type.root, "extendedae_plus", this.name()); + } + + private enum Type { + GUI("gui"), + TOOLTIP("gui.tooltips"); + + private final String root; + + Type(String root) { + this.root = root; + } + } +} diff --git a/src/main/java/com/extendedae_plus/compat/AppliedFluxCompat.java b/src/main/java/com/extendedae_plus/compat/AppliedFluxCompat.java index a5d4aa9..e765efe 100644 --- a/src/main/java/com/extendedae_plus/compat/AppliedFluxCompat.java +++ b/src/main/java/com/extendedae_plus/compat/AppliedFluxCompat.java @@ -1,8 +1,6 @@ package com.extendedae_plus.compat; import appeng.client.gui.implementations.PatternProviderScreen; -import appeng.client.gui.widgets.UpgradesPanel; -import com.extendedae_plus.util.ExtendedAELogger; /** * AppliedFlux 兼容性处理工具类 diff --git a/src/main/java/com/extendedae_plus/init/ModNetwork.java b/src/main/java/com/extendedae_plus/init/ModNetwork.java index 7c8c63b..b95be4d 100644 --- a/src/main/java/com/extendedae_plus/init/ModNetwork.java +++ b/src/main/java/com/extendedae_plus/init/ModNetwork.java @@ -2,13 +2,13 @@ package com.extendedae_plus.init; import com.extendedae_plus.ExtendedAEPlus; import com.extendedae_plus.network.*; +import com.extendedae_plus.network.packet.EAPConfigButtonPacket; import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent; public class ModNetwork { // 在 Mod 构造中通过 modEventBus.addListener(ModNetwork::registerPayloadHandlers) 注册 public static void registerPayloadHandlers(final RegisterPayloadHandlersEvent event) { var registrar = event.registrar(ExtendedAEPlus.MODID); - registrar.playToServer(ToggleEntityTickerC2SPacket.TYPE, ToggleEntityTickerC2SPacket.STREAM_CODEC, ToggleEntityTickerC2SPacket::handle); 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); @@ -42,5 +42,7 @@ public class ModNetwork { registrar.playToServer(com.extendedae_plus.network.SetWirelessFrequencyC2SPacket.TYPE, com.extendedae_plus.network.SetWirelessFrequencyC2SPacket.STREAM_CODEC, com.extendedae_plus.network.SetWirelessFrequencyC2SPacket::handle); + + registrar.playToServer(EAPConfigButtonPacket.TYPE, EAPConfigButtonPacket.STREAM_CODEC, EAPConfigButtonPacket::handleOnServer); } } diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternProviderScreenUpgradesMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternProviderScreenUpgradesMixin.java index c46560f..53fe44e 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternProviderScreenUpgradesMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternProviderScreenUpgradesMixin.java @@ -11,12 +11,12 @@ import appeng.client.gui.style.WidgetStyle; import appeng.client.gui.widgets.ToolboxPanel; import appeng.client.gui.widgets.UpgradesPanel; import appeng.core.localization.GuiText; -import appeng.menu.SlotSemantics; -import appeng.menu.implementations.PatternProviderMenu; import appeng.helpers.patternprovider.PatternProviderLogicHost; import appeng.menu.AEBaseMenu; -import com.extendedae_plus.compat.UpgradeSlotCompat; +import appeng.menu.SlotSemantics; +import appeng.menu.implementations.PatternProviderMenu; import com.extendedae_plus.compat.AppliedFluxCompat; +import com.extendedae_plus.compat.UpgradeSlotCompat; import com.extendedae_plus.util.IStyleAccessor; import net.minecraft.network.chat.Component; import net.minecraft.world.entity.player.Inventory; diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/compat/PatternProviderLogicCompatMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/compat/PatternProviderLogicCompatMixin.java index 9368cd8..8c11af4 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/compat/PatternProviderLogicCompatMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/compat/PatternProviderLogicCompatMixin.java @@ -1,7 +1,7 @@ package com.extendedae_plus.mixin.ae2.compat; -import appeng.api.networking.IManagedGridNode; import appeng.api.networking.IGridConnection; +import appeng.api.networking.IManagedGridNode; import appeng.api.networking.security.IActionSource; import appeng.api.upgrades.IUpgradeInventory; import appeng.api.upgrades.IUpgradeableObject; @@ -9,13 +9,13 @@ import appeng.api.upgrades.UpgradeInventories; import appeng.helpers.patternprovider.PatternProviderLogic; import appeng.helpers.patternprovider.PatternProviderLogicHost; import com.extendedae_plus.ae.items.ChannelCardItem; -import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge; import com.extendedae_plus.bridge.CompatUpgradeProvider; +import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge; import com.extendedae_plus.compat.UpgradeSlotCompat; import com.extendedae_plus.init.ModItems; +import com.extendedae_plus.util.ExtendedAELogger; import com.extendedae_plus.wireless.WirelessSlaveLink; import com.extendedae_plus.wireless.endpoint.GenericNodeEndpointImpl; -import com.extendedae_plus.util.ExtendedAELogger; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Final; diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicChannelCardMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicChannelCardMixin.java index 3eee600..8dd1c3d 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicChannelCardMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicChannelCardMixin.java @@ -8,8 +8,6 @@ import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge; import com.extendedae_plus.init.ModItems; import com.extendedae_plus.wireless.WirelessSlaveLink; import com.extendedae_plus.wireless.endpoint.InterfaceNodeEndpointImpl; -import com.extendedae_plus.util.ExtendedAELogger; -import net.minecraft.server.level.ServerLevel; import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicUpgradesMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicUpgradesMixin.java index ddfa398..68055c7 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicUpgradesMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicUpgradesMixin.java @@ -7,14 +7,10 @@ import appeng.helpers.InterfaceLogic; import appeng.helpers.InterfaceLogicHost; import com.extendedae_plus.bridge.CompatUpgradeProvider; import com.extendedae_plus.compat.UpgradeSlotCompat; -import net.neoforged.fml.ModList; import com.extendedae_plus.util.ExtendedAELogger; import net.minecraft.world.item.Item; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Mutable; -import org.spongepowered.asm.mixin.Unique; +import net.neoforged.fml.ModList; +import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/PatternProviderLogicUpgradesMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/PatternProviderLogicUpgradesMixin.java index cdff2af..e1d73da 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/PatternProviderLogicUpgradesMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/PatternProviderLogicUpgradesMixin.java @@ -2,7 +2,6 @@ package com.extendedae_plus.mixin.ae2.helpers; import appeng.api.networking.IManagedGridNode; import appeng.api.upgrades.IUpgradeInventory; -import appeng.api.upgrades.IUpgradeableObject; import appeng.api.upgrades.UpgradeInventories; import appeng.helpers.patternprovider.PatternProviderLogic; import appeng.helpers.patternprovider.PatternProviderLogicHost; @@ -19,8 +18,8 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.lang.reflect.Method; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.util.List; /** diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/menu/AEBaseMenuUpgradesDedupMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/menu/AEBaseMenuUpgradesDedupMixin.java index 93bc1c9..bfed658 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/menu/AEBaseMenuUpgradesDedupMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/menu/AEBaseMenuUpgradesDedupMixin.java @@ -1,10 +1,9 @@ package com.extendedae_plus.mixin.ae2.menu; +import appeng.api.upgrades.IUpgradeInventory; import appeng.menu.AEBaseMenu; import appeng.menu.SlotSemantics; import appeng.menu.implementations.PatternProviderMenu; -import appeng.api.upgrades.IUpgradeInventory; -import com.extendedae_plus.util.ExtendedAELogger; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/menu/InterfaceMenuUpgradesMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/menu/InterfaceMenuUpgradesMixin.java index fc6e80a..092c47a 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/menu/InterfaceMenuUpgradesMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/menu/InterfaceMenuUpgradesMixin.java @@ -5,9 +5,6 @@ import appeng.menu.AEBaseMenu; import appeng.menu.ToolboxMenu; import appeng.menu.implementations.InterfaceMenu; import com.extendedae_plus.bridge.IUpgradableMenu; -import com.extendedae_plus.compat.UpgradeSlotCompat; -import com.extendedae_plus.bridge.CompatUpgradeProvider; -import com.extendedae_plus.util.ExtendedAELogger; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.MenuType; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuAdvancedMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuAdvancedMixin.java index ac8b3b7..c6a0e32 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuAdvancedMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuAdvancedMixin.java @@ -1,15 +1,11 @@ package com.extendedae_plus.mixin.ae2.menu; import appeng.helpers.patternprovider.PatternProviderLogic; -import appeng.helpers.patternprovider.PatternProviderLogicHost; import appeng.menu.AEBaseMenu; import appeng.menu.guisync.GuiSync; import appeng.menu.implementations.PatternProviderMenu; import com.extendedae_plus.api.AdvancedBlockingHolder; import com.extendedae_plus.api.PatternProviderMenuAdvancedSync; -import com.extendedae_plus.util.ExtendedAELogger; -import net.minecraft.world.entity.player.Inventory; -import net.minecraft.world.inventory.MenuType; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuDoublingMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuDoublingMixin.java index adcffba..ee1b172 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuDoublingMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuDoublingMixin.java @@ -6,8 +6,6 @@ import appeng.menu.guisync.GuiSync; import appeng.menu.implementations.PatternProviderMenu; import com.extendedae_plus.api.PatternProviderMenuDoublingSync; import com.extendedae_plus.api.SmartDoublingHolder; -import com.extendedae_plus.util.ExtendedAELogger; -import net.minecraft.world.entity.player.Inventory; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuUpgradesMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuUpgradesMixin.java index 9fc4db7..92f4a92 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuUpgradesMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuUpgradesMixin.java @@ -5,11 +5,9 @@ import appeng.helpers.patternprovider.PatternProviderLogicHost; import appeng.menu.AEBaseMenu; import appeng.menu.ToolboxMenu; import appeng.menu.implementations.PatternProviderMenu; +import com.extendedae_plus.bridge.CompatUpgradeProvider; import com.extendedae_plus.bridge.IUpgradableMenu; import com.extendedae_plus.compat.UpgradeSlotCompat; -import com.extendedae_plus.bridge.CompatUpgradeProvider; -import appeng.api.upgrades.IUpgradeInventory; -import appeng.api.upgrades.IUpgradeableObject; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.MenuType; import org.spongepowered.asm.mixin.Final; @@ -19,7 +17,6 @@ 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 com.extendedae_plus.util.ExtendedAELogger; @Mixin(value = PatternProviderMenu.class, priority = 2000, remap = false) public abstract class PatternProviderMenuUpgradesMixin extends AEBaseMenu implements IUpgradableMenu { diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/parts/automation/IOBusPartChannelCardMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/parts/automation/IOBusPartChannelCardMixin.java index 97e1945..c0f4306 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/parts/automation/IOBusPartChannelCardMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/parts/automation/IOBusPartChannelCardMixin.java @@ -3,16 +3,14 @@ package com.extendedae_plus.mixin.ae2.parts.automation; import appeng.api.networking.security.IActionHost; import appeng.api.upgrades.IUpgradeInventory; import appeng.api.upgrades.IUpgradeableObject; -import appeng.helpers.InterfaceLogicHost; import appeng.parts.automation.IOBusPart; -import net.minecraft.nbt.CompoundTag; -import com.extendedae_plus.util.ExtendedAELogger; import com.extendedae_plus.ae.items.ChannelCardItem; import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge; import com.extendedae_plus.init.ModItems; +import com.extendedae_plus.util.ExtendedAELogger; import com.extendedae_plus.wireless.WirelessSlaveLink; import com.extendedae_plus.wireless.endpoint.GenericNodeEndpointImpl; -import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.nbt.CompoundTag; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/parts/storagebus/StorageBusPartChannelCardMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/parts/storagebus/StorageBusPartChannelCardMixin.java index 69609a6..9c1a5ad 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/parts/storagebus/StorageBusPartChannelCardMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/parts/storagebus/StorageBusPartChannelCardMixin.java @@ -5,14 +5,13 @@ import appeng.api.networking.security.IActionHost; import appeng.api.upgrades.IUpgradeInventory; import appeng.api.upgrades.IUpgradeableObject; import appeng.parts.storagebus.StorageBusPart; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.FriendlyByteBuf; -import com.extendedae_plus.util.ExtendedAELogger; import com.extendedae_plus.ae.items.ChannelCardItem; import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge; import com.extendedae_plus.init.ModItems; +import com.extendedae_plus.util.ExtendedAELogger; import com.extendedae_plus.wireless.WirelessSlaveLink; import com.extendedae_plus.wireless.endpoint.GenericNodeEndpointImpl; +import net.minecraft.nbt.CompoundTag; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; diff --git a/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternProviderMixin.java b/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternProviderMixin.java index 40e3708..3de1647 100644 --- a/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternProviderMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternProviderMixin.java @@ -7,14 +7,13 @@ import appeng.menu.SlotSemantics; import appeng.menu.slot.AppEngSlot; import com.extendedae_plus.NewIcon; import com.extendedae_plus.api.ExPatternButtonsAccessor; -import com.extendedae_plus.api.ExPatternPageAccessor; import com.extendedae_plus.config.ModConfigs; +import com.extendedae_plus.network.ScalePatternsC2SPacket; import com.glodblock.github.extendedae.client.button.ActionEPPButton; import com.glodblock.github.extendedae.client.gui.GuiExPatternProvider; import com.glodblock.github.extendedae.container.ContainerExPatternProvider; -import net.minecraft.network.chat.Component; import net.minecraft.client.Minecraft; -import com.extendedae_plus.network.ScalePatternsC2SPacket; +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; diff --git a/src/main/java/com/extendedae_plus/network/ToggleEntityTickerC2SPacket.java b/src/main/java/com/extendedae_plus/network/ToggleEntityTickerC2SPacket.java deleted file mode 100644 index 0407f95..0000000 --- a/src/main/java/com/extendedae_plus/network/ToggleEntityTickerC2SPacket.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.extendedae_plus.network; - -import com.extendedae_plus.ExtendedAEPlus; -import com.extendedae_plus.ae.menu.EntitySpeedTickerMenu; -import com.extendedae_plus.ae.parts.EntitySpeedTickerPart; -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; - -/** - * C2S: Toggle the accelerateEnabled flag on the EntitySpeedTickerPart bound to the open menu. - */ -public class ToggleEntityTickerC2SPacket implements CustomPacketPayload { - public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>( - ResourceLocation.fromNamespaceAndPath(ExtendedAEPlus.MODID, "toggle_entity_ticker")); - - public static final ToggleEntityTickerC2SPacket INSTANCE = new ToggleEntityTickerC2SPacket(); - - public static final StreamCodec STREAM_CODEC = - StreamCodec.unit(INSTANCE); - - private ToggleEntityTickerC2SPacket() {} - - @Override - public CustomPacketPayload.Type type() { - return TYPE; - } - - public static void handle(final ToggleEntityTickerC2SPacket msg, final IPayloadContext ctx) { - ctx.enqueueWork(() -> { - if (!(ctx.player() instanceof ServerPlayer player)) return; - - if (!(player.containerMenu instanceof EntitySpeedTickerMenu menu)) return; - - EntitySpeedTickerPart part = menu.getHost(); - if (part == null) return; - - // 切换部件上的状态,并把新状态同步到菜单字段,随后广播以通知客户端 - boolean current = part.getAccelerateEnabled(); - boolean next = !current; - part.setAccelerateEnabled(next); - // 确保菜单上的字段也被更新,这样 @GuiSync 会把状态发回客户端 - menu.setAccelerateEnabled(next); - menu.broadcastChanges(); - }); - } -} \ No newline at end of file diff --git a/src/main/java/com/extendedae_plus/network/packet/EAPConfigButtonPacket.java b/src/main/java/com/extendedae_plus/network/packet/EAPConfigButtonPacket.java new file mode 100644 index 0000000..0aaec0b --- /dev/null +++ b/src/main/java/com/extendedae_plus/network/packet/EAPConfigButtonPacket.java @@ -0,0 +1,60 @@ +package com.extendedae_plus.network.packet; + +import appeng.api.config.Setting; +import appeng.api.util.IConfigManager; +import appeng.api.util.IConfigurableObject; +import appeng.core.network.CustomAppEngPayload; +import appeng.core.network.ServerboundPacket; +import appeng.menu.AEBaseMenu; +import appeng.util.EnumCycler; +import com.extendedae_plus.api.config.EAPSettings; +import com.extendedae_plus.util.ExtendedAELogger; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.server.level.ServerPlayer; +import org.jetbrains.annotations.NotNull; + +public record EAPConfigButtonPacket(Setting option, boolean rotationDirection) implements ServerboundPacket { + + public static final StreamCodec STREAM_CODEC = StreamCodec.ofMember( + EAPConfigButtonPacket::write, + EAPConfigButtonPacket::decode); + + public static final Type TYPE = CustomAppEngPayload.createType("eap_config_button"); + + @Override + public @NotNull Type type() { + return TYPE; + } + + public static EAPConfigButtonPacket decode(RegistryFriendlyByteBuf stream) { + var option = EAPSettings.getOrThrow(stream.readUtf()); + var rotationDirection = stream.readBoolean(); + return new EAPConfigButtonPacket(option, rotationDirection); + } + + public void write(RegistryFriendlyByteBuf data) { + data.writeUtf(option.getName()); + data.writeBoolean(rotationDirection); + } + + @Override + public void handleOnServer(ServerPlayer player) { + if (player.containerMenu instanceof AEBaseMenu baseMenu) { + if (baseMenu.getTarget() instanceof IConfigurableObject configurableObject) { + var cm = configurableObject.getConfigManager(); + if (cm.hasSetting(option)) { + cycleSetting(cm, option); + } else { + ExtendedAELogger.LOGGER.info("Ignoring unsupported setting {} sent by client on {}", option, baseMenu.getTarget()); + } + } + } + } + + private > void cycleSetting(IConfigManager cm, Setting setting) { + var currentValue = cm.getSetting(setting); + var nextValue = EnumCycler.rotateEnum(currentValue, rotationDirection, setting.getValues()); + cm.putSetting(setting, nextValue); + } +} diff --git a/src/main/java/com/extendedae_plus/util/PatternScaler.java b/src/main/java/com/extendedae_plus/util/PatternScaler.java index 537d52c..1c23c6f 100644 --- a/src/main/java/com/extendedae_plus/util/PatternScaler.java +++ b/src/main/java/com/extendedae_plus/util/PatternScaler.java @@ -4,15 +4,13 @@ import appeng.api.crafting.IPatternDetails.IInput; import appeng.api.stacks.AEKey; import appeng.api.stacks.GenericStack; import appeng.crafting.pattern.AEProcessingPattern; -import com.extendedae_plus.content.ScaledProcessingPattern; import com.extendedae_plus.api.SmartDoublingAwarePattern; import com.extendedae_plus.config.ModConfigs; +import com.extendedae_plus.content.ScaledProcessingPattern; import java.util.ArrayList; import java.util.List; -import static com.extendedae_plus.util.ExtendedAELogger.LOGGER; - public final class PatternScaler { private PatternScaler() { } diff --git a/src/main/java/com/extendedae_plus/wireless/WirelessSlaveLink.java b/src/main/java/com/extendedae_plus/wireless/WirelessSlaveLink.java index 9a6c177..da22fd9 100644 --- a/src/main/java/com/extendedae_plus/wireless/WirelessSlaveLink.java +++ b/src/main/java/com/extendedae_plus/wireless/WirelessSlaveLink.java @@ -5,7 +5,6 @@ import appeng.api.networking.IGridConnection; import appeng.api.networking.IGridNode; import appeng.me.service.helpers.ConnectionWrapper; import com.extendedae_plus.config.ModConfigs; -import com.extendedae_plus.util.ExtendedAELogger; import net.minecraft.server.level.ServerLevel; import org.jetbrains.annotations.Nullable; diff --git a/src/main/resources/assets/extendedae_plus/lang/en_us.json b/src/main/resources/assets/extendedae_plus/lang/en_us.json index 650007b..bd4cde5 100644 --- a/src/main/resources/assets/extendedae_plus/lang/en_us.json +++ b/src/main/resources/assets/extendedae_plus/lang/en_us.json @@ -129,5 +129,13 @@ "group.pattern_provider.name": "Pattern Provider", "group.storage.name": "Storage Bus", - "group.entity_ticker.name": "Entity Ticker" + "group.entity_ticker.name": "Entity Ticker", + + "gui.tooltips.extendedae_plus.Accelerate": "Entity Acceleration", + "gui.tooltips.extendedae_plus.AccelerateEnabled": "Target is blacklisted", + "gui.tooltips.extendedae_plus.AccelerateDisabled": "Accelerate target block entity ticks", + "gui.tooltips.extendedae_plus.AccelerateBlacklisted": "Do not accelerate target block entities", + "gui.tooltips.extendedae_plus.RedstoneControl": "Redstone Control", + "gui.tooltips.extendedae_plus.RedstoneControlEnabled": "Control acceleration with redstone signal", + "gui.tooltips.extendedae_plus.RedstoneControlDisabled": "Ignore redstone signals" } \ No newline at end of file diff --git a/src/main/resources/assets/extendedae_plus/lang/zh_cn.json b/src/main/resources/assets/extendedae_plus/lang/zh_cn.json index 568ac44..1ad663e 100644 --- a/src/main/resources/assets/extendedae_plus/lang/zh_cn.json +++ b/src/main/resources/assets/extendedae_plus/lang/zh_cn.json @@ -119,15 +119,24 @@ "extendedae_plus.tooltip.frequency": "频率: %d", "extendedae_plus.tooltip.master_mode": "模式: %s", "extendedae_plus.tooltip.locked": "状态: %s", - + "gui.extendedae_plus.frequency_input.title": "设置频率", "gui.extendedae_plus.frequency_input.field": "频率", "gui.extendedae_plus.frequency_input.confirm": "确认", "gui.extendedae_plus.frequency_input.cancel": "取消", "extendedae_plus.wireless.locked": "已锁定收发器", "extendedae_plus.wireless.unlocked": "已解锁收发器", - + "group.pattern_provider.name": "样板供应器", "group.storage.name": "存储总线", - "group.entity_ticker.name": "实体加速器" + "group.entity_ticker.name": "实体加速器", + + "gui.tooltips.extendedae_plus.Accelerate": "实体加速", + "gui.tooltips.extendedae_plus.AccelerateEnabled": "加速目标方块实体的tick", + "gui.tooltips.extendedae_plus.AccelerateDisabled": "不加速目标方块实体", + "gui.tooltips.extendedae_plus.AccelerateBlacklisted": "目标在黑名单中", + + "gui.tooltips.extendedae_plus.RedstoneControl": "红石控制", + "gui.tooltips.extendedae_plus.RedstoneControlEnabled": "使用红石信号控制加速", + "gui.tooltips.extendedae_plus.RedstoneControlDisabled": "忽略红石信号" } \ No newline at end of file