拨号装置
Dial Home Device 是本 mod 唯一的交互方块。玩家把它放在星门控制器方块旁,用它为星门设定 7 位地址并发起拨号。GUI 由 ModularUI 库实现(GTNH 环境自带),面板尺寸 176×100。
基本信息
| 属性 | 值 |
|---|---|
| 注册名 | stargatenh:dialing_device |
| 方块类 | BlockDialingDevice(继承 BlockContainer) |
| TileEntity | TileDialingDevice,注册 ID TileDialingDeviceNH |
| 材质 | Material.iron |
| 硬度 / 爆炸抗性 | 本 mod 未设置,继承原版默认值(2.0 / 10.0) |
| 亮度 | 无 |
| 掉落 | 默认(damage 0) |
本 mod 只有这一个非星门方块,且每个材质组共用同一个实例(ModBlocks.dialingDeviceBlock 是静态单例,构造时只设一次名字)。
联动方式
TileDialingDevice.connectGate() 按固定顺序在同一 Y 层、恰好 4 格的四个方向上寻找星门控制器:
| 顺序 | 检测坐标 | 方向 |
|---|---|---|
| 1 | (x+4, y, z) |
东 |
| 2 | (x−4, y, z) |
西 |
| 3 | (x, y, z+4) |
南 |
| 4 | (x, y, z−4) |
北 |
- 命中第一个
TileStargateController即绑定。 - 四处都没有则绑定失败(
controller保持null),GUI 顶部显示Link Failed!,所有操作控件禁用。 controller是客户端逻辑字段,不写入 NBT——每次打开界面时由BlockDialingDevice.onBlockActivated()重新调用connectGate()绑定。因此移动或拆除控制器后重新打开界面即可刷新绑定。
[!IMPORTANT] 距离是硬编码的 4 格,且只接受与方块同 Y。装置必须与控制器处于同一水平面;高 1 格、低 1 格或隔 3 格/5 格都无法联动。
界面
面板 176×100,包含 7 个符号选择按钮(CycleButtonWidget,length(16))以及随机、锁定、拨号三个按钮。界面有两种互斥形态,由 hasAddress() 切换:
| 状态 | 顶部提示 | 符号按钮 | 可用按钮 |
|---|---|---|---|
| 未设定地址 | Set Address for this Stargate |
启用(编辑 dialingAddress) |
随机、锁定 |
| 已设定地址 | Stargate operational. |
启用(回显 dialingAddress,为 −1 时回落到控制器已注册的 registeredAddress) |
拨号 |
未设定地址时
- 符号按钮 — 每位在 0–15 之间循环切换,背景贴图为
gui/sigil_bg/gui/sigil_bg_active,前景为gui/sigil_<0..15>。 - 随机按钮(贴图
gui/random)— 生成一个随机且未被占用的地址:do { 7 × rng.nextInt(16) } while (registry.lookup(...) != null),拒绝采样直到不冲突。 - 实时状态提示 — 同步值
isUnique每帧查询注册表,显示Address is available(可用)或Address already in use(已占用)。 - 锁定按钮(贴图
gui/checkmark)— 仅当isUnique为真才可点击。点击后调用controller.setAddress(dialingAddress),把 7 位缓冲全部重置为 −1,并关闭面板。
已设定地址时
- 拨号按钮(贴图
gui/checkmark)— 调用controller.dialOut(dialingAddress),触发 7 个雪佛龙依次锁定,详见 拨号序列。 - 拨出不消耗任何资源,也没有次数限制(但目标星门只能被拨通一次)。
交互
| 触发 | 行为 |
|---|---|
| 右键 | connectGate() 重新绑定控制器,打开 ModularUI 面板 |
| 界面内点击符号 | 该位 0–15 循环切换 |
| 界面内点击随机 | 生成随机未占用地址 |
| 界面内点击锁定 | 永久设定该地址 |
| 界面内点击拨号 | 拨向该地址 |
[!NOTE]
hasAddressSyncer虽然在buildUI()中创建并注册到syncManager,其 setter 也无hasAddress守卫,但没有任何控件绑定它,因此客户端无法通过界面清除已设定的地址。地址的唯一写入路径是TileStargateController.setAddress()。
数值
| 数值名 | 值 |
|---|---|
| 与控制器的距离 | 4 格(固定) |
| 允许的相对方向 | ±X / ±Z 共 4 个,同 Y |
| 面板尺寸 | 176 × 100 |
| 每位符号选项数 | 16(0–15) |
| 符号按钮尺寸 / 间距 | 16×16 / childPadding 6 |
| 随机 / 锁定 / 拨号按钮 | 18×18 |
| 能量消耗 | 无(本 mod 无能量系统,拨号不耗电) |
限制
- 必须在控制器 4 格外的同一 Y 层,否则界面显示
Link Failed!。 - 地址只能设定一次(
setAddress()首行if (hasAddress) return;),界面不会提供修改或清除已设地址的入口。 dialingAddress缓冲不写入 NBT,区块卸载后玩家未锁定的输入会丢失。- 地址冲突时锁定按钮禁用(
isUnique为假),玩家需改地址或换用随机按钮。 - 随机按钮的拒绝采样没有重试上限,理论上存在极小概率长时间循环(16⁷ ≈ 2.68 亿空间,实践中不会发生)。
- 一个星门可以有多个拨号装置同时指向它,彼此的输入缓冲相互独立。