Tile Entities
Tile-Entities sind Blöcke, die fähig sind weitere Operationen wie automatisches Craften (Öfen und Braustände) auszuführen oder Effekte (Leuchtfeuer oder Notenblock) zu generieren. Sie enthalten außerdem weitere Daten wie ein Inventar oder Text (Truhen, Schilder oder Command-Blöcke).
Tile-Entities und ihren Typ erkennen
Wieder beginnt alles mit einer Location. Die Funktion Location#getTileEntity() gibt entweder das zum Block gehörende Tile-Entity oder Optional.empty()
zurück, falls der Block kein Tile-Entity ist.
import org.spongepowered.api.world.Location; import org.spongepowered.api.world.World; public boolean isTileEntity(Location<World> blockLoc) { return blockLoc.getTileEntity().isPresent(); }
Der Typ eines Tile-Entitys kann durch die Funktion TileEntity#getType() herausgefunden werden, die ein TileEntityType-Objekt zurückgibt. Dieses kann dann, ähnlich wie ein BlockType, verglichen werden. Nachdem dieser Test durchgeführt wurde, kann die TileEntity-Variable sicher zum Typ einer Unterklasse konvertiert werden.
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(); } }
Nachdem diese Typumwandlung stattgefunden hat, kann auf die Methoden des entsprechenden Interfaces zugegriffen werden (in diesem Beispiel die Methode Jukebox#ejectRecord()). Detaillierte Informationen über die TileEntity
-Unterklassen und ihre entsprechenden Methoden befinden sich im org.spongepowered.api.block.tileentity-Package und seinen untergeordneten Packages in der API-Dokumentation.
Zugreifen und Ändern der Daten eines Tile-Entitys
Ähnlich den Block-States wird mittels eines DataManipulator auf die Daten eines Tile-Entitys zugegriffen. Da die Art der Daten vollständig durch den benutzten DataManipulator
beschrieben sind, können alle Änderungen mit dem TileEntity
-Interface selbst durchgeführt werden und eine Typumwandlung ist nicht nötig.
Das folgende Beispiel zeigt zwei Methoden, um die Daten eines Schildes zu ändern. Die erste Methode liest (wenn möglich) die erste Zeile. Die Zweite versucht sie zu ändern und gibt einen booleschen Wert zurück, welcher angibt, ob die Operation erfolgreich war.
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; }
Der hauptsächliche Unterschied bei dem Arbeiten mit einem BlockState
und einem Tile-Entity ist, dass Letztere im Gegensatz zum unveränderlichen BlockState
ein veränderbarer DataHolder ist.
Auf Inventare zugreifen
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(); [...] } }
Wende dich an die Inventar Dokumentation bezüglich der Manipulation des Inventars.