TileEntityLandingPad / TileEntityLandingPadSingle

事实基准:/Users/evlos/a/mirror/Galacticraft(master,minecraftVersion = 1.7.10)逐行读源码。

注册信息(两个类,注册名不同)

TileEntity 注册名 注册类 注册处 结构
Landing Pad TileEntityLandingPadSingle GalacticraftCore.java:714 单块(玩家放置的最小单位)
Landing Pad Full TileEntityLandingPad GalacticraftCore.java:715 3 × 3 × 1 多方块

两者分属不同注册名,不是同一实体的两个状态——Single 是玩家放的方块, Full 是 9 块凑齐后自动替换出来的整体。

槽位数量与布局

两者都没有物品槽位(不实现 IInventory)。 Landing Pad 是停靠 / 加油设施,燃料通过 IFuelableTiered 接口与停靠实体交互。

TileEntityLandingPad 实现接口(core/tile/TileEntityLandingPad.java:31-32):

public class TileEntityLandingPad extends TileEntityMulti
        implements IMultiBlock, IFuelableTiered, IFuelDock, ICargoEntity {

结构尺寸:3 × 3 × 1(单层,不堆高)

core/tile/TileEntityLandingPad.java:94-107 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(x, placedPosition.y, z);   // Y 原样,无 y 循环
        if (!vecToAdd.equals(placedPosition)) {
            makeFakeBlock(this.worldObj, vecToAdd, placedPosition, 2);
        }
    }
}
维度 范围 计数
X -1 ~ +1 3
Y 只有主块那一层(placedPosition.y 原样) 1
Z -1 ~ +1 3

共 3 × 3 = 9 格(主块 + 8 个假方块),只有 1 层高。

⚠ Landing Pad 是单层的 3×3,不是 3×3×3。 onCreate 里根本没有 y 循环——与 NASA 工作台的 3×3×4、空间站的 1×1×3 形成对比。

onDestroy(:110-135)同样只循环 x/z(:115-116),Y 取 thisBlock.y。 销毁时对每格调 this.worldObj.func_147480_a(x, y, z, false)(:127) 强制刷新,并按 rand.nextDouble() < 0.1D 的 10% 概率发方块破坏粒子(:118)。

自动合并:9 个 Single 凑成 Full

core/tile/TileEntityLandingPadSingle.java:14-45 updateEntity()(仅服务端,:15):

for (int x = this.xCoord - 1; x < this.xCoord + 2; x++) {   // 周围 3×3
    for (int z = this.zCoord - 1; z < this.zCoord + 2; z++) {
        tile = worldObj.getTileEntity(x, this.yCoord, z);
        if (tile instanceof TileEntityLandingPadSingle) attachedLaunchPads.add(tile);
    }
}

if (attachedLaunchPads.size() == 9) {                       // :28 必须是 9 个
    for (tile : attachedLaunchPads) {                       // :29-34 拆掉 9 个 single
        tile.invalidate();
        worldObj.setBlock(..., Blocks.air, 0, 3);
    }
    worldObj.setBlock(..., GCBlocks.landingPadFull, 0, 3);  // :36 在中心放 full
    ((TileEntityLandingPad) worldObj.getTileEntity(...)).onCreate(...);  // :41
}
步骤 行 行为
扫描 :18-26 在同一 Y 层的 3×3 范围内找 TileEntityLandingPadSingle
判定 :28 数量 必须 == 9 才触发
拆除 :29-34 9 个 Single 全部 invalidate() + 置为空气
替换 :36-38 中心放 GCBlocks.landingPadFull
建结构 :40-42 对新 TileEntityLandingPad 调 onCreate(...)

⚠ 判定是严格的 == 9——放不满 9 个不会合并成 Full。 且扫描只覆盖 xCoord-1 .. xCoord+1、同一 y, 所以必须是同一水平面上完整的一圈 3×3,竖直方向不参与。

⚠ :34 有一行被注释掉的旧实现(// ((GCCoreBlockLandingPadFull)...))—— 不要把它当成当前生效的代码。

与火箭(实体)的关系

core/tile/TileEntityLandingPad.java:34:

private IDockable dockedEntity;

停靠对象字段类型是 IDockable 接口,不是 TileEntity。

getRocketTier()(:155-158):

if (this.dockedEntity != null && this.dockedEntity instanceof EntityTieredRocket) {
    return ((EntityTieredRocket) this.dockedEntity).getRocketTier();
}

⚠ 这坐实了「1.7.10 的火箭是 Entity、不是多方块」: 停靠台读的是 EntityTieredRocket(micdoodle8.mods.galacticraft.api.prefab.entity.EntityTieredRocket) 这个实体的 tier。源码树里不存在 BlockRocket / TileEntityRocket。 详见 TileEntityMulti 与 5 个真实多方块。

:53 还会遍历 list 收集同层的 pad;:71 调 fuelable.isDockValid(this) 校验可否停靠; :130-132 / :147-148 分别转发 onPadDestroyed() 与 addFuel / removeFuel 给停靠实体。

可否旋转

不可旋转。 onCreate / onDestroy 的 x/z 循环完全对称,无按朝向变换坐标的分支。

GUI / Container

TileEntityLandingPad 本身没有 GUI(不开界面)。 燃料靠停靠实体交互,不通过方块界面。

网络封包

TileEntityMulti.mainBlockPosition 带 @NetworkedField(targetSide = Side.CLIENT) (core/tile/TileEntityMulti.java:17-18),由 GC 自己的字段同步机制自动下发。 无独立的封包 ID。

相关条目