Tile Entities
Tile entities - это блоки способные к дополнительным операциям, такие как автономный крафт (печки и варочные стойки) или обеспечивающие эффекты (маяк или нотный блок). Так же они могут хранить дополнительную информацию, как инвентарь или текст (сундуки, таблички или командные блоки)
Идентификация Tile Entities и их типа
Снова, все начинается с Location. Location#getTileEntity() - это функция возвращающая tile entity соответствующая блоку, или ``Optional.empty()`, если блок не является tile entity.
import org.spongepowered.api.world.Location; import org.spongepowered.api.world.World; public boolean isTileEntity(Location<World> blockLoc) { return blockLoc.getTileEntity().isPresent(); }
Тип клетки может быть получен функцией TileEntity#getType(), которая возвращает TileEntityType. Которые затем можно сравнивать по аналогии с BlockType. После выполнения этой проверки переменная 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(); } }
After performing this cast, the methods provided by the particular interface can be accessed (in this example the
Jukebox#ejectRecord() method). For detailed information about TileEntity
subtypes and their respective
methods refer to the org.spongepowered.api.block.tileentity package and its subpackages in the API.
Accessing and Modifying a Tile Entity’s Data
Similar to block states, the data stored in a tile entity is accessed using a DataManipulator. Since the
kind of a data is fully described by the DataManipulator
used, all data manipulation can be done with the
TileEntity
interface itself and does not require a cast.
The following example contains two methods to alter the data of a sign. The first method reads (if possible) the first line, the second attempts to set it and returns the boolean value indicating its success.
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; }
The main difference to working with a BlockState
is that a tile entity is a mutable DataHolder as
opposed to the immutable BlockState
.
Accessing Inventories
Quite a share of tile entities come with their own inventory, most notably chests and furnaces. That inventory cannot
be accessed directly from the TileEntity
interface. So a cast will be necessary. Since all tile entities containing
an inventory extend the TileEntityCarrier interface it suffices to cast to that interface as shown below.
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(); [...] } }
Смотрите документацию оборудования для того, чтобы использовать его.