微型控制器部件

[!INFO] 源码: ControlPanelPart.java、PBFacePart.java

控制面板的部件侧实现。ControlPanelPart extends PBFacePart(后者继承 CodeChicken 的 JCuboidFacePart),实现 Project Red 的 IConnectable 与 IBundledEmitter。

部件类型

项 值
类型名 pb_controlpanel(硬编码在 getType())
工厂 ControlPanelPart.Factory implements IPartFactory
占用槽位 1 << side(getSlotMask),单面
包围盒 newBounds(0, 0, 0, 1, 1/8.0, 1) — 面板厚 1/8 格
面板内 NBT 字段 material、mounting、connectionMask、gridSize、controlTypes、controlMetadata、controlStates、channelColors、labels

持久化状态

字段 类型 说明
mounting int 0 = flush,1 = surface
gridSize int 2/3/4,缺失默认 4
connectionMask int 位掩码,标记已连线的 4 个角方向;缺失默认 0x3
controlTypes byte[16] 控件类型 ordinal
controlStates byte[16] 当前状态(不入物品,单独存)
controlMetadata byte[16] 放置时 meta
channelColors byte[16] 通道色
labels List[32] 16×2 文本

非持久字段(重载后重算):base、signal[16]、releaseTime[16]。

ControlType 枚举

ControlPanelPart.ControlType:NONE(0) / BLANK(1) / LEVER(2) / BUTTON(3) / LAMP(4)。

信号收发

输出(getBundledSignal(side)):清空 signal[16],遍历活跃格子,LEVER/BUTTON 且状态 > 0 且通道 < 16 的,置 signal[channel] = 255。

输入(getInputs()):BundledUtils.getAllSignals(this, side, connectionMask) 取回 16 通道信号,只驱动 LAMP 格子 —— setControlState(i, sig[ch] != 0 ? 1 : 0)。

触发时机:onPartChanged 与 onNeighborChanged → updateInputs()(仅服务端,随后 markDirty + sendDescUpdate)。

连接

实现 IConnectable 的三个连接方法全部委托给 connectTo(part, r):

  • 拒绝连接另一个 ControlPanelPart(return false)
  • 接受其他任何部件,设置 connectionMask |= 1 << r 并 markDirty
  • canConnectCorner(int r) 恒为 true

connectionMask 决定 BundledUtils.getAllSignals 扫描哪几个角方向(for (int r = 0; r <= 3; r++) if ((connectionMask & (1 << r)) != 0))。

网络通道

ProjectBlueChannel(FML 通道名 gce.projectblue),Message 枚举:

消息 方向 载荷
EDIT_CONTROL_PANEL_TEXT S→C blockX/Y/Z、partIndex、cell
UPDATE_CONTROL_PANEL_TEXT C→S 同上 + line、text

部件定位用坐标 + partIndex(tile().jPartList().indexOf(part)),收到后 instanceof ControlPanelPart 校验再写入。

⚠️ 该通道用 Java 原生序列化传输枚举,BaseNBTChannel.ValidatingObjectInputStream 只放行「本消息枚举类」和 java.lang.Enum,其他类一律记 SuspiciousPackets 并抛异常。

另有一条通用数据通道 projectblue.data(BaseDataChannel,字符串路由),供 GUI 使用。

相关