传送器侧面模式系统(Attachment Modes)
基本信息
| 属性 | 值 |
|---|---|
| 实现类 | codechicken.translocator.TileTranslocator.Attachment(内部类) |
| 归属方块 | Translocator:translocator(metadata 0 / 1 共用) |
| 侧面数量 | 6(Attachment[] attachments = new Attachment[6],下/上/北/南/西/东,side ^ 1 即对面) |
| 生效范围 | 物品传送器与液体传送器共用同一套模式,见下方变体对比 |
| 持久化 | 每个侧面一个 NBT 复合标签 atmt0 … atmt5 |
这是整个 mod 的核心机制:传送器本体只是一个"壳",真正干活的是它 6 个侧面上的 Attachment。
TileTranslocator 本身是抽象类,只负责侧面的增删、NBT/网络包同步、射线检测用的碰撞盒和红石供电判定;
具体"搬什么"由两个子类实现——物品走 物品传送器,液体走 液体传送器。
侧面的创建与销毁
创建:用 物品传送器方块物品右键贴在一个容器/罐体表面时,
ItemTranslocator.placeBlockAt 调用 createAttachment(side ^ 1),在朝向目标那一面新建一个侧面。
已存在侧面的那一面不能重复添加(if (ttrans.attachments[side ^ 1] != null) return false)。
合法性:BlockTranslocator.canExistOnSide 按 metadata 判定
—— metadata 0 要求 world.getTileEntity(...) instanceof IInventory;
metadata 1 要求 instanceof IFluidHandler。不满足则不能附着。
自动销毁:邻接方块变化时 onNeighborBlockChange 遍历 6 面,只要有一面不再满足上面的条件
就调用 harvestPart(i, true) 回收该侧。harvestPart 掉落该侧的物品后把 attachments[i] 置 null,
并检查是否所有侧面都没了——是则把整个方块变成空气。
拆除单个侧面:准星对准某个面左键,removedByPlayer 用射线命中结果里的 subHit % 6 决定拆哪一面,
只掉这一面及其附加物(升级件),方块本体保留;最后一面被拆掉时方块才消失。
quantityDropped 返回 0、掉落完全由 getDrops 逐面收集 —— 这就是为什么拆一个装满升级件的
六面传送器能拿回整套零件。
侧面状态字段
| 字段 | 含义 | 默认值 | 持久化键 |
|---|---|---|---|
side |
所属面(0~5) | 构造入参 | 不保存(由下标决定) |
a_eject |
抽出面(true=从这一面往外抽) | true |
不保存(由红石算出) |
b_eject |
上一 tick 的 a_eject,用于插值 |
true |
不保存 |
redstone |
是否受红石控制 | false |
redstone |
invert_redstone |
红石逻辑是否取反 | true |
invert_redstone |
fast |
高速模式(Glowstone 粉) | false |
fast |
a_insertpos / b_insertpos |
中间插针的伸出进度(1=伸出,0=缩回) | 1 |
不保存 |
a_insertpos |
同上(当前) | 1 |
— |
a_eject 的计算式(Attachment.update):
a_eject = (redstone && gettingPowered()) != invert_redstone;
即 红石关闭时永远抽出;红石打开后,是否抽出 = !gettingPowered() XOR invert_redstone,
默认 invert_redstone = true,所以给红石信号 = 停止抽出(可改成给信号才抽出)。
gettingPowered() 用 worldObj.isBlockIndirectlyGettingPowered,是间接供电判定,所以放在红石粉旁边即可。
交互方式
对某一个面右键时,BlockTranslocator.onBlockActivated 先做射线检测:
命中外圈底座(subHit < 6 且局部 x、z 都在 ±2/16 格内)则改判为中心插针(subHit += 6)。
所以一个面有 2 个可点击的子部位:外圈和中心按钮。
| 触发 | 条件 | 行为 |
|---|---|---|
| 右键·外圈·空手 | held == null 且 subPart == 0 |
打开该面的 GUI(物品传送器弹出过滤器界面;液体传送器不弹出任何界面) |
| 右键·中心按钮·空手 | held == null 且 subPart == 1 |
翻转 invert_redstone(切换红石取反逻辑) |
| 右键·空手·潜行 | held == null 且 isSneaking() |
调用 stripModifiers(),拆掉这一面所有升级件并原样掉回 |
| 右键·持红石粉 | Items.redstone 且该面未装过 |
装上红石模式,扣 1 个;并把 invert_redstone 翻转让当前状态保持不变 |
| 右键·持萤石粉 | Items.glowstone_dust 且该面未装过 |
装上高速模式,扣 1 个 |
| 其他持物 | 任意 | 落到 openGui / 子类逻辑 |
| 左键·任意面 | — | 拆掉这一面(见上) |
拆除掉的升级件(stripModifiers):红石粉(1 个)、Glowstone 粉(1 个);
物品传送器额外掉 钻石粒 或铁锭;
液体传送器额外掉 GregTech 泵盖。
stripModifiers 里有一行细节:拆掉红石粉时会检查 invert_redstone != a_eject,
如果不一致就把它翻回来,所以拆完后当前的红石表现不变。
渲染图标位
Attachment.getIconIndex() 把状态压成一个贴图列索引,渲染器用它取
translocator:textures/tex.png 上的状态图元(field / 64.0 取横坐标,metadata / 2 取纵坐标):
| 位 | 含义 |
|---|---|
1 / 2 |
装了红石粉,且当前未通电 / 通电(redstone ? (gettingPowered() ? 2 : 1) : 0) |
4 |
高速模式 |
8 |
物品变体独有:调节(regulate)模式 |
16 / 32 |
物品变体独有:已装铁锭信号器,当前未充能 / 充能 |
变体对比:基础 / 物品 / 液体三层
TileTranslocator 是抽象基类,两个子类的差异全部来自 createAttachment 造出的侧面类型。
| 属性 | 基础(TileTranslocator) |
物品(TileItemTranslocator) |
液体(TileLiquidTranslocator) |
|---|---|---|---|
| metadata | 0 与 1 共用壳 | 0 | 1 |
| 侧面类 | Attachment |
Attachment + ItemAttachment |
Attachment + LiquidAttachment |
| 目标方块要求 | 由 canExistOnSide 判定 |
IInventory |
IFluidHandler |
| 每 tick 抽出上限 | 抽象,未实现 | 1 个(fast 时整叠) |
100 mB(fast 时 1000 mB) |
| 过滤器 | 无 | 9 格,每格 1 / 64 / 65535 个(见物品页) | 完全没有,只按流体类型自动分配 |
| 额外升级件 | 红石粉、Glowstone 粉 | 钻石粒(调节)、铁锭(信号器) | GregTech 泵盖(自定义流量) |
| 每 tick 输出分配 | 未实现 | 随机拆分到所有注入面,先非红石面后红石面 | 随机拆分到所有注入面,先非红石面后红石面 |
| 客户端动画 | 插针伸缩 | 物品实体沿路径浮动 | 螺旋流体带 + 粒子连线 |
实现 IFluidHandler |
否 | 否 | 是(但自身 fill/drain 全部返回 0/null,只用于 WAILA 显示 6 个 0 容量罐体) |
| 输出优先级 | — | redstone == false 的注入面优先 |
redstone == false 的注入面优先 |
三层的关系是「继承 + 覆盖」,不是并列:TileLiquidTranslocator 的 updateEntity() 先调
super.updateEntity()(即 TileTranslocator 的侧面状态推进),再叠加自己的抽取逻辑;
TileItemTranslocator 同理。
相关条目
- 物品传送器 - 物品变体:过滤器、速率与信号器
- 液体传送器 - 液体变体:mB/t 速率与 GregTech 泵盖
- 合成网格 - 不使用本侧面系统的第二个方块
- GregTech 泵盖兼容层 - 只作用于液体变体侧面的速率改写
- 模组配置 -
Translocator.cfg的两个开关