TileEntityReplacementManager
基本信息
| 属性 | 值 |
|---|---|
| 完整类名 | com.gtnewhorizons.postea.api.TileEntityReplacementManager |
| 包路径 | api |
| 类型 | 公共 API 注册表(abstract class, 不允许实例化) |
| 调用时机 | FMLPostInitializationEvent 或更晚(推荐 FMLLoadCompleteEvent 之后) |
| 关联事件 | ChunkEvent.Load |
功能
Postea 的核心 API 之一。允许其他 mod 在世界区块加载阶段拦截任意 TileEntity NBT 数据,对其执行以下三种操作之一:
- TileEntity → 普通方块:删除 TileEntity,将所在坐标替换为一个 Block,并保留原 metadata。
- 纯 NBT 转换:保留 TileEntity 类型,仅修改内部 NBT 字段(修改物品栏、能量值、自定义数据等)。
- TileEntity 整体替换:换成另一种 TileEntity 类型,并将旧 NBT 字段映射到新 NBT。
TileEntity 转换器总是在 Block 转换器之前执行。当返回
null时表示当前 handler 不识别该 TileEntity,Postea 会继续调用后续 handler。
方法
tileEntityTransformer(String, TriFunction<NBTTagCompound, World, Chunk, BlockInfo>)
注册一个 TileEntity 转换回调。
tileEntityId:要拦截的 TileEntity 类 ID(字符串,如"Chest"、"GT_TileEntity_Ores")。transformerFunction:接收 TileEntity 的 NBT、世界、区块,返回BlockInfo表示转换结果;返回null则跳过。
回调触发条件:世界加载时,对应 TileEntity 类型被反序列化之前。
createTETagAtSamePosition(String newId, NBTTagCompound tag)
生成一个仅保留坐标信息(x/y/z)的 TileEntity NBT 模板。可用于"整体替换 TileEntity 类型"的场景中复用旧坐标,避免手动读取 tag.getInteger("x") 等字段。
| 参数 | 说明 |
|---|---|
newId |
新 TileEntity 的类型 ID |
tag |
旧 TileEntity 的 NBT(不会被修改) |
返回值:仅包含 id 与坐标字段的新 NBTCompound。
行为规则
| 规则 | 说明 |
|---|---|
| 多个 handler 顺序 | 按注册顺序依次执行,任一返回非 null BlockInfo 即终止 |
| 返回 null | 表示本 handler 不处理,Postea 继续调用后续 handler |
| 区块加载期间世界未就绪 | world.getBlock 在转换时会抛异常——必须使用 BlockAccessCompat 替代 |
| 执行位置 | TileEntity transformers → Block transformers → Simple transformations |
| 执行时机 | 每个区块加载时(去重后);dev 环境下每次进出区块都会重新执行,便于调试 |
数据结构 BlockInfo(utility/BlockInfo)
转换回调的返回值类型。
| 字段 | 类型 | 说明 |
|---|---|---|
block |
Block |
替换后的方块 |
metadata |
int |
替换方块的 metadata |
tileTransformer |
Function<NBTTagCompound, NBTTagCompound> |
NBT 转换回调;null 表示删除 TileEntity |
提供两个构造函数:
| 构造签名 | 行为 |
|---|---|
BlockInfo(Block, int) |
删除 TileEntity,替换为普通方块 |
BlockInfo(Block, int, Function<NBTTagCompound, NBTTagCompound>) |
替换方块并转换 NBT |
使用模式
模式 1:TileEntity → 普通方块
将 GregTech 旧版矿石 TileEntity 全部抹除,按维度染成不同颜色的羊毛:
TileEntityReplacementManager.tileEntityTransformer("GT_TileEntity_Ores", (tag, world, chunk) -> {
if (world.provider.dimensionId == -1) return new BlockInfo(Blocks.wool, 1); // 下界
if (world.provider.dimensionId == 1) return new BlockInfo(Blocks.wool, 2); // 末地
return new BlockInfo(Blocks.wool, 3); // 主世界
});
模式 2:纯 NBT 转换(保留 TileEntity)
修改箱子内的物品 ID(13 槽位 → 钻石,其余 → 石头),不改变箱子本身:
TileEntityReplacementManager.tileEntityTransformer("Chest", (tag, world, chunk) -> {
NBTTagList slots = tag.getTagList("Items", 10);
for (int i = 0; i < slots.tagCount(); i++) {
NBTTagCompound slot = slots.getCompoundTagAt(i);
if (IDExtenderCompat.getItemStackID(slot) != reedsId) continue;
if (slot.getByte("Slot") == 13) {
IDExtenderCompat.setItemStackID(slot, diamondId);
} else {
IDExtenderCompat.setItemStackID(slot, stoneId);
}
}
return null; // 不替换方块
});
模式 3:TileEntity 整体替换(带 NBT 映射)
将 Furnace 替换为 Chest,搬运原物品栏;若原方块是点燃的熔炉则追加一个 fire charge:
TileEntityReplacementManager.tileEntityTransformer("Furnace", (tag, world, chunk) -> {
int[] idMeta = BlockAccessCompat.getBlockIDAndMetaAtTE(tag, chunk);
int blockId = idMeta[0], meta = idMeta[1];
return new BlockInfo(Blocks.chest, meta, oldTag -> transformFurnaceNBT(oldTag, blockId));
});
第三方 mod 集成
- 依赖:
required-after:gtnhlib@[0.6.21,)。 - 跨 mod 调用:所有其他 API(
BlockReplacementManager、ItemStackReplacementManager、BlockAccessCompat、IDExtenderCompat)都通过本类定义的转换流程协同工作。