添加扳手调整无线收发器频率

This commit is contained in:
GaLicn 2025-10-05 13:46:23 +08:00
parent 7060d78e5d
commit 3fffc27b03
6 changed files with 233 additions and 6 deletions

View File

@ -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();
}
}
}

View File

@ -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));
}
}

View File

@ -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++; }

View File

@ -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<NetworkEvent.Context> 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);
}
}

View File

@ -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"

View File

@ -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": "存储总线"