diff --git a/src/main/java/com/extendedae_plus/client/ui/FrequencyInputScreen.java b/src/main/java/com/extendedae_plus/client/ui/FrequencyInputScreen.java new file mode 100644 index 0000000..595664f --- /dev/null +++ b/src/main/java/com/extendedae_plus/client/ui/FrequencyInputScreen.java @@ -0,0 +1,122 @@ +package com.extendedae_plus.client.ui; + +import com.extendedae_plus.init.ModNetwork; +import com.extendedae_plus.network.SetWirelessFrequencyC2SPacket; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; + +/** + * 频率输入界面 + * 用于通过输入框设置无线收发器的频率 + */ +public class FrequencyInputScreen extends Screen { + private final BlockPos pos; + private final long currentFrequency; + private EditBox frequencyInput; + + public FrequencyInputScreen(BlockPos pos, long currentFrequency) { + super(Component.translatable("extendedae_plus.screen.frequency_input.title")); + this.pos = pos; + this.currentFrequency = currentFrequency; + } + + @Override + protected void init() { + int centerX = this.width / 2; + int centerY = this.height / 2; + + // 频率输入框 + this.frequencyInput = new EditBox(this.font, centerX - 100, centerY - 10, 200, 20, + Component.translatable("extendedae_plus.screen.frequency_input.field")); + this.frequencyInput.setValue(String.valueOf(currentFrequency)); + this.frequencyInput.setMaxLength(19); // long最大值是19位 + this.frequencyInput.setFilter(text -> { + // 只允许输入数字 + if (text.isEmpty()) return true; + try { + Long.parseLong(text); + return true; + } catch (NumberFormatException e) { + return false; + } + }); + this.addRenderableWidget(this.frequencyInput); + this.setInitialFocus(this.frequencyInput); + + // 确认按钮 + Button confirmButton = Button.builder(Component.translatable("extendedae_plus.screen.frequency_input.confirm"), + button -> onConfirm()) + .bounds(centerX - 105, centerY + 20, 100, 20) + .build(); + this.addRenderableWidget(confirmButton); + + // 取消按钮 + Button cancelButton = Button.builder(Component.translatable("gui.cancel"), + button -> onClose()) + .bounds(centerX + 5, centerY + 20, 100, 20) + .build(); + this.addRenderableWidget(cancelButton); + } + + private void onConfirm() { + try { + String text = this.frequencyInput.getValue(); + if (text.isEmpty()) { + // 空值视为0 + text = "0"; + } + long frequency = Long.parseLong(text); + if (frequency < 0) { + frequency = 0; + } + + // 发送数据包到服务端 + ModNetwork.CHANNEL.sendToServer(new SetWirelessFrequencyC2SPacket(pos, frequency)); + this.onClose(); + } catch (NumberFormatException e) { + // 输入无效,不做处理 + } + } + + @Override + public void render(net.minecraft.client.gui.GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTicks) { + this.renderBackground(guiGraphics); + super.render(guiGraphics, mouseX, mouseY, partialTicks); + + // 绘制标题 + guiGraphics.drawCenteredString(this.font, this.title, this.width / 2, this.height / 2 - 40, 0xFFFFFF); + } + + @Override + public boolean isPauseScreen() { + return false; + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + // 按回车键确认 + if (keyCode == 257 || keyCode == 335) { // ENTER or NUMPAD_ENTER + onConfirm(); + return true; + } + // 按ESC键取消 + if (keyCode == 256) { // ESC + onClose(); + return true; + } + return super.keyPressed(keyCode, scanCode, modifiers); + } + + @Override + public void tick() { + super.tick(); + if (this.frequencyInput != null) { + this.frequencyInput.tick(); + } + } +} + diff --git a/src/main/java/com/extendedae_plus/hooks/WrenchHook.java b/src/main/java/com/extendedae_plus/hooks/WrenchHook.java index f098b45..5890cb1 100644 --- a/src/main/java/com/extendedae_plus/hooks/WrenchHook.java +++ b/src/main/java/com/extendedae_plus/hooks/WrenchHook.java @@ -2,9 +2,11 @@ package com.extendedae_plus.hooks; import appeng.util.InteractionUtil; import com.extendedae_plus.ExtendedAEPlus; +import com.extendedae_plus.client.ui.FrequencyInputScreen; import com.extendedae_plus.content.wireless.WirelessTransceiverBlockEntity; import appeng.block.crafting.CraftingUnitBlock; import appeng.blockentity.crafting.CraftingBlockEntity; +import net.minecraft.client.Minecraft; import net.minecraft.network.chat.Component; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; @@ -14,6 +16,8 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.eventbus.api.Event; import net.minecraftforge.eventbus.api.SubscribeEvent; @@ -86,19 +90,24 @@ public final class WrenchHook { } } } else if (!InteractionUtil.isInAlternateUseMode(player) && InteractionUtil.canWrenchRotate(stack)) { - // 未潜行 + 扳手:切换锁定状态 + // 未潜行 + 扳手:打开频率输入界面 BlockEntity be = level.getBlockEntity(hit.getBlockPos()); if (be instanceof WirelessTransceiverBlockEntity te) { - boolean newLocked = !te.isLocked(); - te.setLocked(newLocked); - // 提示玩家 - player.displayClientMessage(Component.literal(newLocked ? "已锁定收发器" : "已解锁收发器"), true); + if (level.isClientSide) { + // 客户端打开GUI + openFrequencyInputScreen(hit.getBlockPos(), te.getFrequency()); + } // 轻微反馈音效 - level.playSound(player, hit.getBlockPos(), SoundEvents.LEVER_CLICK, SoundSource.BLOCKS, 0.5F, newLocked ? 0.6F : 0.9F); + level.playSound(player, hit.getBlockPos(), SoundEvents.UI_BUTTON_CLICK.get(), SoundSource.BLOCKS, 0.5F, 1.0F); event.setCanceled(true); event.setCancellationResult(InteractionResult.sidedSuccess(level.isClientSide)); } } } + + @OnlyIn(Dist.CLIENT) + private static void openFrequencyInputScreen(net.minecraft.core.BlockPos pos, long currentFrequency) { + Minecraft.getInstance().setScreen(new FrequencyInputScreen(pos, currentFrequency)); + } } diff --git a/src/main/java/com/extendedae_plus/init/ModNetwork.java b/src/main/java/com/extendedae_plus/init/ModNetwork.java index 2ffe168..85a039e 100644 --- a/src/main/java/com/extendedae_plus/init/ModNetwork.java +++ b/src/main/java/com/extendedae_plus/init/ModNetwork.java @@ -131,6 +131,12 @@ public class ModNetwork { .decoder(ChannelCardBindPacket::decode) .consumerNetworkThread(ChannelCardBindPacket::handle) .add(); + + CHANNEL.messageBuilder(SetWirelessFrequencyC2SPacket.class, nextId(), NetworkDirection.PLAY_TO_SERVER) + .encoder(SetWirelessFrequencyC2SPacket::encode) + .decoder(SetWirelessFrequencyC2SPacket::decode) + .consumerNetworkThread(SetWirelessFrequencyC2SPacket::handle) + .add(); } private static int nextId() { return id++; } diff --git a/src/main/java/com/extendedae_plus/network/SetWirelessFrequencyC2SPacket.java b/src/main/java/com/extendedae_plus/network/SetWirelessFrequencyC2SPacket.java new file mode 100644 index 0000000..f3d398f --- /dev/null +++ b/src/main/java/com/extendedae_plus/network/SetWirelessFrequencyC2SPacket.java @@ -0,0 +1,80 @@ +package com.extendedae_plus.network; + +import com.extendedae_plus.content.wireless.WirelessTransceiverBlockEntity; +import net.minecraft.core.BlockPos; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerPlayer; +import net.minecraftforge.network.NetworkEvent; + +import java.util.function.Supplier; + +/** + * 设置无线收发器频率的网络数据包 + * 客户端发送到服务端,用于通过输入框设置频率 + */ +public class SetWirelessFrequencyC2SPacket { + + private final BlockPos pos; + private final long frequency; + + public SetWirelessFrequencyC2SPacket(BlockPos pos, long frequency) { + this.pos = pos; + this.frequency = frequency; + } + + public static void encode(SetWirelessFrequencyC2SPacket packet, FriendlyByteBuf buf) { + buf.writeBlockPos(packet.pos); + buf.writeLong(packet.frequency); + } + + public static SetWirelessFrequencyC2SPacket decode(FriendlyByteBuf buf) { + BlockPos pos = buf.readBlockPos(); + long frequency = buf.readLong(); + return new SetWirelessFrequencyC2SPacket(pos, frequency); + } + + public static void handle(SetWirelessFrequencyC2SPacket packet, Supplier ctx) { + ctx.get().enqueueWork(() -> { + ServerPlayer player = ctx.get().getSender(); + if (player == null) { + return; + } + + // 检查方块实体是否存在 + var level = player.serverLevel(); + if (!level.hasChunkAt(packet.pos)) { + return; + } + + var blockEntity = level.getBlockEntity(packet.pos); + if (!(blockEntity instanceof WirelessTransceiverBlockEntity te)) { + return; + } + + // 检查是否锁定 + if (te.isLocked()) { + player.displayClientMessage( + Component.literal("收发器已锁定,无法修改频道"), + true + ); + return; + } + + // 设置频率 + long newFreq = packet.frequency; + if (newFreq < 0) { + newFreq = 0; + } + te.setFrequency(newFreq); + + // 发送反馈消息 + player.displayClientMessage( + Component.literal("频道已设置为:" + te.getFrequency()), + true + ); + }); + ctx.get().setPacketHandled(true); + } +} + 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 3c8e58a..44be39c 100644 --- a/src/main/resources/assets/extendedae_plus/lang/en_us.json +++ b/src/main/resources/assets/extendedae_plus/lang/en_us.json @@ -114,6 +114,11 @@ "extendedae_plus.tooltip.owner.unset": "Owner: Unset", "extendedae_plus.tooltip.owner.public": "Owner: Public", + "extendedae_plus.screen.frequency_input.title": "Set Frequency", + "extendedae_plus.screen.frequency_input.current": "Current Frequency: %s", + "extendedae_plus.screen.frequency_input.field": "Frequency", + "extendedae_plus.screen.frequency_input.confirm": "Confirm", + "group.pattern_provider.name": "Pattern Provider", "group.entity_ticker.name": "Entity Accelerator", "group.storage.name": "StorageBus" 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 405cb16..f143c87 100644 --- a/src/main/resources/assets/extendedae_plus/lang/zh_cn.json +++ b/src/main/resources/assets/extendedae_plus/lang/zh_cn.json @@ -115,6 +115,11 @@ "extendedae_plus.tooltip.owner.unset": "所有者: 未设置", "extendedae_plus.tooltip.owner.public": "所有者: 公共", + "extendedae_plus.screen.frequency_input.title": "设置频率", + "extendedae_plus.screen.frequency_input.current": "当前频率:%s", + "extendedae_plus.screen.frequency_input.field": "频率", + "extendedae_plus.screen.frequency_input.confirm": "确认", + "group.pattern_provider.name": "样板供应器", "group.entity_ticker.name": "实体加速器", "group.storage.name": "存储总线"