TileEntityMulti 与 5 个真实多方块结构(NASA 工作台 / 空间站 / 低温仓 / 燃料装填台 / 登陆台)
事实基准:
/Users/evlos/a/mirror/Galacticraft(master,minecraftVersion = 1.7.10)逐行读源码。 本篇的尺寸全部从onCreate/onDestroy的循环边界读出,不是猜测。
先说一个必须纠正的前提:1.7.10 Galacticraft 没有火箭多方块
⚠ 「Galacticraft 的 Rocket 是一个巨大的多方块结构,尺寸极易编造」——在 1.7.10 源码中不成立。
穷举
find全树的结果:BlockRocket.java不存在,TileEntityRocket.java不存在,GCBlocks中也没有任何 rocket 方块。 1.7.10 的火箭是 Entity(EntityTier1Rocket/EntityTier2Rocket/EntityTier3Rocket/EntityCargoRocket/EntityAutoRocket,继承micdoodle8.mods.galacticraft.api.prefab.entity.EntityTieredRocket), 由ItemTier1Rocket等物品放置。EntityTier1Rocket的体积是setSize(1.2F, 3.5F)(core/entities/EntityTier1Rocket.java:30、:38), 即宽 1.2、高 3.5 格的单体实体——不是多方块。所谓「火箭蓝图」是 schematics(
SchematicRocketT1/SchematicTier2Rocket/SchematicTier3Rocket/SchematicCargoRocket),属于 NEI 配方展示与存档放置用的 方块摆放清单,不是运行时结构,不构成 TileEntity 多方块。
本 mod 真正存在的多方块只有 5 个,见下。
框架:TileEntityMulti 与 IMultiBlock
core/tile/TileEntityMulti.java:14:
public class TileEntityMulti extends TileEntityAdvanced {
@NetworkedField(targetSide = Side.CLIENT)
public BlockVec3 mainBlockPosition;
| 成员 | 行 | 作用 |
|---|---|---|
mainBlockPosition |
:18 |
指向主方块的坐标,带 @NetworkedField(targetSide = Side.CLIENT) 自动同步 |
setMainBlock(BlockVec3) |
:20-26 |
设定主方块,服务端调 markBlockForUpdate |
onBlockRemoval() |
:28-37 |
子块被拆时回调主块的 onDestroy |
onBlockActivated(...) |
:39-50 |
子块右键时转发到主块的 onActivated |
getMainBlockTile() |
:52-59 |
取主块 TileEntity |
结构由 BlockMulti(= GCBlocks.fakeBlock)生成假方块填充。
被排除的格子用 TileEntityMulti 占位,注册名 "Dummy Block"(GalacticraftCore.java:717)。
⚠ 顺带一提:
TileEntityMulti本身也注册为一个 TileEntity, 但它的注册名是Dummy Block——不是「多方块基类」的意思。
5 个真实多方块(集合运算:全树 extends TileEntityMulti + implements IMultiBlock)
| # | 主块 TileEntity | 注册名 | 源码 | 结构尺寸 | 可否旋转 |
|---|---|---|---|---|---|
| 1 | TileEntityNasaWorkbench |
NASA Workbench |
core/tile/TileEntityNasaWorkbench.java:17 |
3 × 3 × 4(去 4 角 + 顶底面心) | 不可(结构对称于 x/z) |
| 2 | TileEntitySpaceStationBase |
Space Station |
core/tile/TileEntitySpaceStationBase.java:11 |
1 × 1 × 3(纯竖柱) | 不可 |
| 3 | TileEntityCryogenicChamber |
Cryogenic Chamber |
planets/mars/tile/TileEntityCryogenicChamber.java:29 |
1 × 1 × 3(纯竖柱) | 不可 |
| 4 | TileEntityBuggyFueler |
Buggy Fueler |
core/tile/TileEntityBuggyFueler.java:24 |
3 × 3 × 1(单层平板) | 不可 |
| 5 | TileEntityLandingPad |
Landing Pad Full |
core/tile/TileEntityLandingPad.java:31 |
见下(分 Single / 完整两种) |
不可 |
⚠ TileEntityLandingPad extends TileEntityMulti(:31)但没有在同一行写 implements IMultiBlock,
它另有 getRocketTier() 等逻辑(:155-158)——见本篇末。
逐个读出的真实几何
1. NASA Workbench — 3 × 3 × 4,去掉 4 个竖棱 + 上下中心
core/tile/TileEntityNasaWorkbench.java onCreate(:32-61):
for (int y = 1; y < 3; y++) { // :37 y = 1, 2
for (int x = -1; x < 2; x++) { // :42 x = -1, 0, 1
for (int z = -1; z < 2; z++) { // :43 z = -1, 0, 1
if (!vecToAdd.equals(placedPosition) && (Math.abs(x) != 1 || Math.abs(z) != 1)) {
makeFakeBlock(..., 3);
}
}
}
}
// :56-60 额外在 y = +3 的正中放一块
vecToAdd = new BlockVec3(x, y + 3, z); // x、z 不变,即中心
makeFakeBlock(..., 3);
| 维度 | 范围 | 计数 |
|---|---|---|
| Y | 0(主块)~ 3 | 4 层 |
| X | -1 ~ +1 | 3 |
| Z | -1 ~ +1 | 3 |
排除规则 Math.abs(x) != 1 || Math.abs(z) != 1(:49)
→ 排除 (|x|=1 且 |z|=1),即4 个竖棱角柱(4 个角)不被填充。
onDestroy(:64-…)的循环是 x: -1..1、y: 0..3、z: -1..1(:67-69),
同样带 Math.abs(x) != 1 || Math.abs(z) != 1 过滤(:71),
并对 y == 0 || y == 3 的中心格发客户端破坏粒子(:72-79)。
结论:外形是一个 3×3 底面(4 角空缺成十字)+ 中间 2 层 + 顶部中心 1 块的「工作台架」, 共 3×3 + 5 + 1 = 最多 15 个格子(不含 4 个空角)。
⚠ 没有任何旋转逻辑——onCreate 的 x/z 循环是对称的,
onDestroy 同样对称,结构不能转向。
GUI:GuiIdsCore.NASA_WORKBENCH_ROCKET(:23),开的是火箭总装界面——
这也是 1.7.10 里「火箭」与多方块唯一的接触点:NASA 工作台是多方块,但火箭本身不是。
2. Space Station Base — 1 × 1 × 3 竖柱
core/tile/TileEntitySpaceStationBase.java:44-46:
for (int y = 1; y < 3; y++) { // y = 1, 2
vecToAdd = new BlockVec3(x, placedPosition.y + y, z); // x、z 原样
makeFakeBlock(...);
}
onDestroy(:55-56)同样是 for (int y = 0; y < 3; y++)。
X/Z 完全不动,只有 Y 方向 0~2 共 3 层 → 1 × 1 × 3 的纯竖柱。不可旋转。
3. Cryogenic Chamber — 1 × 1 × 3 竖柱
planets/mars/tile/TileEntityCryogenicChamber.java:130-134(onCreate)与 :143-147(onDestroy)
都是 for (int y = 0; y < 3; y++) 且 X/Z 取 placedPosition 原值。
同样是 1 × 1 × 3 纯竖柱。不可旋转。
4. Buggy Fueler — 3 × 3 × 1 单层平板
core/tile/TileEntityBuggyFueler.java:82-84(onCreate):
for (int x = -1; x < 2; x++) { // x = -1, 0, 1
for (int z = -1; z < 2; z++) { // z = -1, 0, 1
vecToAdd = new BlockVec3(placedPosition.x + x, placedPosition.y, placedPosition.z + z);
Y 只有一层(直接用 placedPosition.y,无 y 循环),X/Z 各 3 → 3 × 3 × 1 平板,共 9 格。
onDestroy(:99-100)同样只循环 x/z。
⚠ TileEntityBuggyFueler 内另有 x: -2..2、z: -2..2 的循环(:160-161),
但那是载具停靠检测范围(5×5),不是结构尺寸——
把它当成多方块尺寸即为量纲写反。
⚠ 注册时有两个变体:Buggy Fueler(TileEntityBuggyFueler)与
Buggy Fueler Single(TileEntityBuggyFuelerSingle,GalacticraftCore.java:721-722),
后者是单块版,不是这个 3×3 多方块。
5. Landing Pad — 分「单块」与「完整」两种注册
| 类 | 注册名 | 注册处 |
|---|---|---|
TileEntityLandingPadSingle |
Landing Pad |
GalacticraftCore.java:714 |
TileEntityLandingPad |
Landing Pad Full |
GalacticraftCore.java:715 |
core/tile/TileEntityLandingPad.java:31:extends TileEntityMulti。
⚠ TileEntityLandingPad 的类声明行没有 implements IMultiBlock,
且 onCreate / onDestroy 里的假方块生成在源码中未出现 x/y/z 三重循环
(与前 4 个不同)——它的填充由 TileEntityLandingPadSingle 侧的逻辑或方块自身完成。
本条目不断言其具体格数;详见 TileEntityLandingPad。
getRocketTier()(:155-158):
if (this.dockedEntity != null && this.dockedEntity instanceof EntityTieredRocket) {
return ((EntityTieredRocket) this.dockedEntity).getRocketTier();
}
即登陆台通过停靠的 EntityTieredRocket 实体判断火箭等级——
再次印证火箭是实体而非多方块结构。
汇总表
| 结构 | X | Y | Z | 排除规则 | 最多格数 | 旋转 |
|---|---|---|---|---|---|---|
| NASA Workbench | -1…1 | 0…3 | -1…1 | 去 4 竖棱角 + 主块自身 | ≤ 15 | 不可 |
| Space Station Base | 不动 | 0…2 | 不动 | 无 | 3 | 不可 |
| Cryogenic Chamber | 不动 | 0…2 | 不动 | 无 | 3 | 不可 |
| Buggy Fueler | -1…1 | 单层 | -1…1 | 无 | 9 | 不可 |
| Landing Pad | 见专篇 | 见专篇 | 见专篇 | — | 不写死 | 不可 |
⚠ 这 5 个结构没有一个支持旋转。 源码中
onCreate/onDestroy均无按朝向变换坐标的分支。