铭文输入界面
SignPostLabelGui —— 客户端弹出式输入框,用于给未刻写的 路牌 写名字。界面上只有一个文本框和「完成 / 取消」两个按钮(复用 Atlas 的 I18n 键 gui.done / gui.cancel,标题键为 gui.signposts.marker.label,英文原文 “Inscription”,德文 “Inschrift”)。
打开条件
由 路牌 的 onBlockActivated 触发,全部在客户端:
if (currentItemStack != null && currentItemStack.getItem() instanceof SignPostMarkerItem) {
if (signPost.getMarkerId() == 0) {
SignPostsMod.proxy.openSignPostLabelGui(x, y, z, player.posX, Math.floor(player.posY - 1), player.posZ);
}
return false;
}
| 条件 | 要求 |
|---|---|
| 手持物 | 必须是 魔法路牌标记 |
| 路牌状态 | markerId == 0(尚未刻写);已刻写的路牌右键无反应 |
| 侧 | 无限制,任意面都可触发 |
| 重开保护 | ClientProxy.openSignPostLabelGui 内 if (mc.currentScreen == null),已有界面时不覆盖 |
跳转目标坐标的取法
传入界面的 3 个 double 跳转坐标不是路牌位置,而是玩家当时的位置:
| 参数 | 值 |
|---|---|
jumpX |
player.posX(浮点) |
jumpY |
Math.floor(player.posY - 1)(向下取整后作为 double 传入) |
jumpZ |
player.posZ(浮点) |
而路牌自身的方块坐标 x, y, z 由 Block 参数单独携带,用于在服务端定位要写入哪个 TileEntity。两者在 CreateJumpTargetMessage 中是两组独立的 6 个数字。
界面元素
| 元素 | 值 |
|---|---|
| 文本框宽度 | 200 px |
| 文本框高度 | 20 px |
| 水平位置 | (width - 200) / 2(水平居中) |
| 垂直位置 | height / 2 - 81 |
| 标题 | height / 2 - 97,文案 gui.signposts.marker.label |
| 最大字符数 | 15(textField.setMaxStringLength(15),与原版告示牌一致) |
| 按钮宽度 | BUTTON_WIDTH = 100 |
| 按钮间距 | BUTTON_SPACING = 4 |
| 按钮纵向位置 | height / 2 + 40 |
| 「完成」按钮 | width / 2 - 100 - 2,文案 gui.done |
| 「取消」按钮 | width / 2 + 2,文案 gui.cancel |
| 初始焦点 | textField.setFocused(true),输入框打开即获焦 |
| 初始文本 | setText("")(不预填已有的路牌名字) |
| 是否暂停游戏 | doesGuiPauseGame() 返回 false(多人游戏也不暂停) |
提交与取消
protected void actionPerformed(GuiButton button) {
if (button == btnDone) {
CreateJumpTargetMessage msg = new CreateJumpTargetMessage(signX, signY, signZ, jumpX, jumpY, jumpZ, textField.getText());
SignPostsNetworkHelper.sendCreateJumpTargetMessage(msg);
close();
} else if (button == btnCancel) {
close();
}
}
| 按钮 | 行为 |
|---|---|
| 完成 | 发送 判别号 0 的消息 并 close();不校验文本是否为空(可以提交空铭文) |
| 取消 | 直接 close(),不发任何消息,不扣耐久 |
界面继承 Atlas 的 GuiComponent,keyTyped 转发给 textField.textboxKeyTyped,mouseClicked 转发给 textField.mouseClicked——因此文本框可正常输入中文/非 ASCII(UTF8 编码上限 15 字符按 Java String.length() 计,不按码点)。
⚠️ 15 字符限制只在客户端界面生效。
CreateJumpTargetMessage用的ByteBufUtils.writeUTF8String无长度校验,而服务端addJumpTarget也不检查label长度。
界面实例复用
ClientProxy.init 只 new 一次(labelGui = new SignPostLabelGui()),openSignPostLabelGui 通过 labelGui.setJumpTargetValues(...) 覆盖字段后复用同一实例;atlasGui 同理。