BlockAccessCompat
基本信息
| 属性 | 值 |
|---|---|
| 完整类名 | com.gtnewhorizons.postea.api.BlockAccessCompat |
| 包路径 | api |
| 类型 | 工具 API(abstract class, 不允许实例化) |
| 调用时机 | 在 TileEntityReplacementManager.tileEntityTransformer 回调内部 |
| 后端实现 | 通过 Compat.getSubChunkAccess 兼容 Vanilla / EndlessIDs / NEID |
功能
在 TileEntity 转换器执行时,安全地读取 TE 所在坐标的方块 ID 与 meta。由于此时世界尚未完全加载,Forge 的 world.getBlock 会抛异常;本 API 通过直接读取 ExtendedBlockStorage 内部数组绕过这一限制,且能识别已被 Forge 当作 Air 处理的缺失 ID。
核心价值:无需为"已删除/缺失"的方块注册 dummy Block 即可识别其原始 ID——这正是 Postea 相比自己写迁移脚本的最大优势。
方法
| 方法 | 返回 | 说明 |
|---|---|---|
getBlockIDAtTE(NBTTagCompound tag, Chunk chunk) |
int |
TE 坐标位置的方块数值 ID(缺失时返回 0 = Air) |
getBlockMetaAtTE(NBTTagCompound tag, Chunk chunk) |
int |
TE 坐标位置的 meta 值 |
getBlockIDAndMetaAtTE(NBTTagCompound tag, Chunk chunk) |
int[2] |
同时返回 ID 与 meta(数组索引 0=ID, 1=meta) |
参数说明:
tag:TileEntity 的 NBT(必须包含x/y/z字段)。chunk:TileEntity 所在的Chunk。
异常处理:当 y >> 4 超出区块的 ExtendedBlockStorage[] 范围时,返回 0 / {0, 0} 而非崩溃。
跨 mod 兼容性
通过 Compat.getSubChunkAccess(ExtendedBlockStorage) 自动选择以下三种后端:
| 后端 | 触发条件 | 实现 |
|---|---|---|
| Vanilla | 默认 | 直接读写 ExtendedBlockStorage 内部数组 |
| EndlessIDs | endlessids 已安装 |
通过 SubChunkBlockHook 访问扩展 ID 空间 |
| NEID | neid 已安装 |
通过 IExtendedBlockStorageMixin 访问 NEID 扩展存储 |
识别通过反射检测 Class.forName,无副作用;运行时按需选择。
使用模式
在 TileEntity 转换器中读取原方块 ID
TileEntityReplacementManager.tileEntityTransformer("Furnace", (tag, world, chunk) -> {
int[] idMeta = BlockAccessCompat.getBlockIDAndMetaAtTE(tag, chunk);
int blockId = idMeta[0];
int meta = idMeta[1];
// blockId 是当前/曾经的方块数值 ID;可与 registerIDResolver 缓存的值比对
if (blockId == MyMod.litFurnaceId) {
// 点燃的熔炉 → 替换为带 fire charge 的箱子
return new BlockInfo(Blocks.chest, meta, oldTag -> addFireCharge(oldTag));
}
return new BlockInfo(Blocks.chest, meta, null); // 抹除 TileEntity
});
与 ID Resolver 配合识别已删除方块
BlockReplacementManager.registerIDResolver("deletedmod:rubberWood", id -> MyMod.rubberId = id);
TileEntityReplacementManager.tileEntityTransformer("deletedmod:rubberLeaves", (tag, world, chunk) -> {
if (BlockAccessCompat.getBlockIDAtTE(tag, chunk) == MyMod.rubberId) {
return new BlockInfo(Blocks.leaves, 0); // 把 TileEntity 抹掉,保留树叶方块
}
return null;
});
即使
deletedmod已被卸载、世界中该 ID 不存在,Postea 仍能从区块 NBT 中拿到该 ID 的数值;这是普通world.getBlock做不到的。
第三方 mod 集成
- EndlessIDs:自动启用,识别 32k+ ID 空间的方块。
- NotEnoughIDs (NEID):自动启用,识别 NEID 扩展存储。
- 与 gtnhlib 无直接依赖。