Signal Terminal
基本信息
| 属性 | 值 |
|---|---|
| 注册名 | TMechworks:signalTerminal |
| 方块类 | SignalTerminal(Block + ITileEntityProvider) |
| TileEntity | SignalTerminalLogic(TileEntity,实现 ISignalTransceiver) |
| 材质 | Material.circuits |
| 硬度 / 抗性 | 0.1 / 1(setHardness(0.1F) + setResistance(1)) |
| 步声 | soundTypeMetal |
| 碰撞箱 | getCollisionBoundingBoxFromPool 返回 null —— 本身不阻挡,实际碰撞来自 13 个 hitbox |
| 库存 / GUI | 无 |
| 通道 | 6 面 × 16 通道,共 96 条逻辑连接 |
| 通道贴图 | 16 种染料色玻璃 |
| 所属总线 | 必须是某个 Signal Bus 的成员 |
| 放置条件 | 6 面中至少一面贴实心方块(canPlaceBlockAt) |
| 掉落 | getDrops 恒返回空;breakBlock 改掉已注册的终端与线材 |
核心机制:6 面 × 16 通道的选择器
这是本方块的关键设计,也是 byte[16] 信号数组的由来。
SignalTerminalLogic.sideChannel是byte[6]—— 每个面绑定一个通道号 0–15(:27)。connectedSides是byte[6]—— 每个面当前的信号强度(:25)。- 总线用
byte[16]搬运 16 个通道的强度。终端从总线取signals[sideChannel[i]]赋给connectedSides[i](processSignalUpdate,:177-225)。
因此一个终端的 6 个面可以各自绑定到 16 条通道中的任意一条,实现「一路输入、六路分线,且每路监听不同信号」。
通道切换
SignalTerminal.onBlockActivated(blocks/SignalTerminal.java:441-476):
int side = sideBoxMapping[boxHit];
if (par5EntityPlayer.isSneaking()) ((SignalTerminalLogic) te).prevChannel(side);
else ((SignalTerminalLogic) te).nextChannel(side);
- 普通右键该面的通道块 →
nextChannel(side)(+1,16 回绕到 0) - 潜行右键 →
prevChannel(side)(−1,0 回绕到 15)
两个方法都在 worldObj.isRemote 时直接返回(仅服务端改状态),并置 doUpdate = true 触发重算。
13 个 hitbox
HITBOXES = 13,sideBoxMapping = {-1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5}。索引 0 是无效(boxHit == 0 时 return false),索引 1–12 按「每面 2 个」分配:parts[2i-1] = 面板(plate),parts[2i] = 通道(channel)。closestClicked(player, 3.0F, ...) 用射线在 13 个 AABB 中取最近命中。
getRenderType() 返回 SignalTerminalRender.renderID(TESR),isOpaqueCube() / renderAsNormalBlock() 均返回 false。
16 种通道色
channelTextureNames = white, orange, magenta, lightblue, yellow, lime, pink, gray, lightgray, cyan, purple, blue, brown, green, red, black —— 即 1.7.10 的 16 种染色玻璃,贴图路径 tmechworks:glass/stainedglass_<name>。玩家从贴图即可读出每面绑定的通道号。
数值
| 数值 | 值 |
|---|---|
| 材质 | Material.circuits |
| 硬度 / 抗性 | 0.1 / 1 |
| 步声 | soundTypeMetal |
| 面数 | 6 |
| 每面通道数 | 16(0–15) |
sideChannel |
byte[6],NBT 键 sideChannel(getByteArray) |
connectedSides |
byte[6],NBT 键 connectedSides(getByteArray) |
| 通道贴图数 | 16(16 染色玻璃) |
| hitbox 数 | 13(索引 0 无效,1–12 = 6 面 × 2) |
| hitbox 映射 | {-1, 0,0, 1,1, 2,2, 3,3, 4,4, 5,5} |
| 射线检测距离 | 3.0F |
| 面板 AABB | plate 0.25–0.75 宽,low 0.0–0.15 / high 0.85–1.0 |
| 通道 AABB | channel 0.375–0.625 |
| 中心块 AABB(无 TE 时) | 0.375–0.625 全轴 |
| 通道切换 | 普通右键 next(+1 mod 16)/ 潜行右键 prev(−1 mod 16) |
| 弱电 / 强电 | 6 面均输出 |
| 放置 NBT 键 | connectedSide(onBlockPlacedBy 读入后清空) |
| 掉落 | getDrops 恒空;breakBlock 掉 getDroppedTerminals() 个终端 + getDroppedWire() 个 Length Wire |
交互
| 触发 | 行为 |
|---|---|
| 放置 | 需至少一面贴实心方块;读物品 NBT 的 connectedSide 预设朝向 |
| 右键面板外的通道块 | 切换该面通道(+1) |
| 潜行 + 右键 | 切换该面通道(−1) |
| 右键索引 0 的 hitbox | return false(无效果) |
| Spool of Wire 右键 | 记录本方块坐标到 Spool 的 spoolWireData |
| 总线信号变化 | receiveSignalUpdate → processSignalUpdate 逐面更新 + notifyBlocksOfNeighborChange |
| 破坏 | notifyBreak() 注销总线归属;掉已注册终端与线材(motionY +0.2 高斯散射) |
配方
common/MechRecipes.java:119-128,1 条:
b
g
b
| 符号 | 材料 | 数量 |
|---|---|---|
b |
TMechworks:signalBus |
2 |
g |
minecraft:glass(OreDictionary.WILDCARD_VALUE) |
1 |
源码缺陷
getDrops恒返回空ArrayList(:492-494):正常破坏不掉落自身物品。breakBlock只掉「已注册的终端 + 线材」。这意味着未接入总线的终端被拆后物品直接消失,且该设计对「刚放就想拆回」的玩家极不友好。readFromNBT的数组长度无防御(:84-90):sideChannel/connectedSides用getByteArray读回,只对sideChannel检查了length != 6并重置;connectedSides未做同样检查,若 NBT 数据损坏或来自旧版本会得到非 6 长度数组,后续connectedSides[i]越界。processSignalUpdate的oSide作用域(:195-215):int oSide;声明在case 0:块内却跨 case 赋值,依赖「无花括号 case」的作用域规则,可读性差。onBlockActivated有重复的isRemote判断(:445与:447):外层已判if (!par1World.isRemote),内层又判一次,冗余。onBlockPlacedBy清空物品 NBT 的方式粗暴(:485):itemStack.stackTagCompound = null直接丢弃整个 NBT,若玩家在物品上还有其他自定义数据会一并丢失。canPlaceBlockAt/canBlockStay逻辑完全重复(:152-159与:195-202),6 个isSideSolid调用逐字相同,可提取为共用方法。breakBlock用new Random()(:501)而非world.rand/itemRand,每次破坏产生相同的散射序列(因为未 seed 变化来自时间戳),掉落物散射不可控。getChannelIcon(int channel)有边界检查但getChannelIcons()之外无索引保护:SignalBusLogic侧的localHighSignals[16]若sideChannel被外部写坏会越界。
相关条目
- Signal Bus - 本方块必须归属的网络
- Spool of Wire - 跨维度建立总线归属的工具
- Signal Bus 网络 - 网络的聚合与调度机制
- 命令行 -
/tmech_blockInfo可查看本方块 TE 的 NBT(含sideChannel)