基本信息
| 属性 |
值 |
| 全限定名 |
com.gtnewhorizons.neid.mixins.interfaces.ClientBlockTransformer |
| 注册方式 |
通过 ClientBlockTransformerRegistry.registerTransformer |
| 调用时机 |
客户端,服务端发出的 S21/S22/S23 包在写入/构造时 |
| 内部类 |
BlockIdCache(Block ↔ id 反查缓存) |
方法
boolean transformBlock(World world, int x, int y, int z, BlockMeta blockMeta);
- 作用:转换单个方块。
blockMeta 是池化可变对象,直接 mutate(不要 new BlockMeta(...) 替换)。
- 返回值:
true 表示做了改写(注册表据此决定是否把新 BlockMeta 写回包);false 表示 no-op。
- 使用场景:替代方块、隐藏方块(返回 air)、强制改 metadata(如发光状态)。
default void transformBulk(World world, IntToLongFunction coord, ShortBuffer blocks, ShortBuffer metas) {
BlockIdCache input = new BlockIdCache();
BlockIdCache output = new BlockIdCache();
int len = blocks.capacity();
BlockMeta pooled = new BlockMeta(Blocks.air, 0);
for (int i = 0; i < len; i++) {
pooled.setBlock(input.getBlock(blocks.get(i)));
pooled.setBlockMeta(metas.get(i));
long c = coord.applyAsLong(i);
boolean didSomething = transformBlock(world,
CoordinatePacker.unpackX(c), CoordinatePacker.unpackY(c), CoordinatePacker.unpackZ(c), pooled);
if (didSomething) {
blocks.put(i, (short) output.getId(pooled.getBlock()));
metas.put(i, (short) pooled.getBlockMeta());
}
}
}
- 默认实现:把单点
transformBlock 套上 buffer 循环 + 双向 BlockIdCache 缓存实现。
- 子类可覆写:如果 transformer 能一次性优化整个 buffer(如纯 ID 范围裁剪),直接覆写避免循环开销。
coord:index → packed long(CoordinatePacker.pack(x, y, z)),用于把 buffer index 还原为世界坐标。
blocks.get(i) / metas.get(i):注意 ShortBuffer.get(i) 是绝对位置读取(不会移动 cursor),子实现可放心重复调用。
内部类 BlockIdCache
| 字段 |
类型 |
用途 |
block |
Block |
上次查询的 Block |
blockId |
int |
上次查询的 Block ID(-1 表示未初始化) |
| 方法 |
用途 |
int getId(Block block) |
Block → ID(缓存上一次查询) |
Block getBlock(int id) |
ID → Block(缓存上一次查询,绕开 Block.blockRegistry 的二次查表) |
Block.getIdFromBlock / Block.getBlockById 全局哈希调用开销不小,BlockIdCache 让 transformer 在一个 buffer 循环内多次引用同一 Block 时跳过查表。
实现示例模式(伪代码)
public class MyTransformer implements ClientBlockTransformer {
@Override
public boolean transformBlock(World world, int x, int y, int z, BlockMeta bm) {
if (bm.getBlock() == Blocks.redstone_ore && bm.getBlockMeta() == 0) {
bm.setBlock(Blocks.air); // 隐藏未激活的红石矿
return true;
}
return false;
}
}
// 在 mod preInit 注册:ClientBlockTransformerRegistry.registerTransformer(new MyTransformer());
相关条目