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。