瓦實體
Tile entity 是可以执行诸如自动合成一类的附加操作 (熔炉和炼药台),或者提供特殊效果 (例如信标和音符盒) 的方块。它们也保存诸如物品栏或者文字一类的附加数据 (例如箱子、告示牌或命令方块)。
确定 Tile Entity 和它们的类型
我们再一次从 Location 开始。这一名为 Location#getTileEntity() 的方法返回一个方块对应的 Tile Entity。如果对应的方块没有 Tile Entity,它将返回一个 Optional.empty()
。
import org.spongepowered.api.world.Location; import org.spongepowered.api.world.World; public boolean isTileEntity(Location<World> blockLoc) { return blockLoc.getTileEntity().isPresent(); }
一个 Tile Entity 的类型可以通过 TileEntity#getType() 方法返回的 TileEntityType 获取。它和 BlockType 十分相似。在检查完 Tile Entity 的类型之后我们就可以安全地转换将其为 TileEntity 的相应子类。
import org.spongepowered.api.block.tileentity.Jukebox; import org.spongepowered.api.block.tileentity.TileEntity; import org.spongepowered.api.block.tileentity.TileEntityTypes; public boolean isJukebox(TileEntity entity) { return entity.getType().equals(TileEntityTypes.JUKEBOX); } public void ejectDiscFromJukebox(TileEntity entity) { if (isJukebox(entity)) { Jukebox jukebox = (Jukebox) entity; jukebox.ejectRecord(); } }
在进行一个类型转换之后,各个子接口提供的方法就可以被访问了(在示例中是 Jukebox#ejectRecord() 方法)。关于 TileEntity
的子类及其各自的方法的更多信息可以去 API 中的 org.spongepowered.api.block.tileentity 包( Package
)和其子包( Subpackage
)中查看。
Tile Entity 数据的访问和修改
和方块状态类似,在 Tile Entity 中存储的数据都可以通过一个 DataManipulator 来访问。既然通过使用 DataManipulator
可以完整地描述数据的类型,所有的数据操作都可以仅使用 TileEntity
接口完成而不需要强制类型转换。
接下来的例子包含了两个修改告示牌的数据的方法。第一个方法 (在可能时) 读取第一行的内容,第二个尝试去设置它并且返回一个布尔值代表操作的成功与否。
import org.spongepowered.api.data.manipulator.mutable.tileentity.SignData; import org.spongepowered.api.text.Text; import java.util.Optional; public Optional<Text> getFirstLine(TileEntity entity) { Optional<SignData> data = entity.getOrCreate(SignData.class); if (data.isPresent()) { return Optional.of(data.get().lines().get(0)); } return Optional.empty(); } public boolean setFirstLine(TileEntity entity, Text line) { if (entity.supports(SignData.class)) { SignData sign = entity.getOrCreate(SignData.class).get(); sign.set(sign.lines().set(0, line)); entity.offer(sign); return true; } return false; }
和使用 BlockState
的主要区别,是 Tile Entity 是一个可变的 DataHolder ,而和不可变的 BlockState
不同。
访问物品栏
很大一部分的 Tile Entity 都带有它们自己的物品栏( Inventory ),最值得注意的是箱子和熔炉。物品栏不能直接通过 TileEntity
接口获得,所以有必要执行一个强制类型转换。既然所有包含一个物品栏的 Tile Entity 都继承自 TileEntityCarrier 接口,只需要强制类型转换到它就已经足够了,正如接下来的例子所示。
import org.spongepowered.api.block.tileentity.carrier.TileEntityCarrier; import org.spongepowered.api.item.inventory.Inventory; public void useInventory(TileEntity entity) { if (entity instanceof TileEntityCarrier) { TileEntityCarrier carrier = (TileEntityCarrier) entity; Inventory inventory = carrier.getInventory(); ... } }
请参阅操作物品栏(Inventory)的相关文档。