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 均无按朝向变换坐标的分支。

相关条目