Blöcke verändern
Den Typ eines Blocks ändern
Den Typ eines Blocks zu ändern ist so einfach wie das Aufrufen der Location#setBlockType(BlockType)-Methode zusammen mit dem neuen BlockType. Der folgende Code verwandelt den Block an der angegebenen Location (Position) in einen Schwamm:
import org.spongepowered.api.block.BlockTypes; import org.spongepowered.api.world.Location; import org.spongepowered.api.world.World; public void setToSponge(Location<World> blockLoc) { blockLoc.setBlockType(BlockTypes.SPONGE); }
So einfach ist das. Wenn du nur den Block entfernen möchtest (was du machen könntest, indem du ihn mit Luft ersetzt), dann solltest du einfach die Methode Location#removeBlock() benutzen, die Location
bereitstellt.
Einen Block-Status verändern
Ähnlich zum Beispiel oben, bietet die Location``Klasse eine Methode :javadoc:`Location#setBlock(BlockState)` die einen :javadoc:`BlockState` verwendet. Um diese Methode verwenden zu können, musst du zuerst einen ``BlockState
holen, den du verändern kannst. Dies kannst du, indem du den aktuellen Status des Blockes mit Location#getBlock() abfragst oder dir Standardzustand eines BlockType
n holst. Hier wird zuerst der Ursprungszustand es Schwammes abgefragt und dann verändert, um damit einen nassen Schwamm Block zu erstellen:
import org.spongepowered.api.Sponge; import org.spongepowered.api.block.BlockState; import org.spongepowered.api.data.manipulator.mutable.WetData; public void setToWetSponge(Location<World> blockLoc) { BlockState state = BlockTypes.SPONGE.getDefaultState(); WetData wetness = Sponge.getDataManager(). getManipulatorBuilder(WetData.class).get().create(); wetness.set(wetness.wet().set(true)); BlockState newState = state.with(wetness.asImmutable()).get(); blockLoc.setBlock(newState); }
Da ein BlockState
ein :javadoc:`ImmutableDataHolder`` ist, kannst du die bereitgestellten Methoden with()
und without()
verwenden, die beide einen neuen geänderten BlockState
zurückgeben oder Optional. empty()
, wenn der angegebene :javadoc:`ImmutableDataManipulator`` nicht auf die Art des Blocks anwendbar ist, der durch den BlockState
repräsentiert wird.
Die Methode with()
akzeptiert einen ImmutableDataManipulator
und wird versuchen einen neuen BlockState
zu erstellen, bei dem die Daten gesetzt wurden, bzw. alte Daten überschrieben wurden. Das folgende Beispiel verändert jegliche Art von Dreckblöcken zu Podsol.
import org.spongepowered.api.data.key.Keys; import org.spongepowered.api.data.manipulator.immutable.block.ImmutableDirtData; import org.spongepowered.api.data.manipulator.mutable.block.DirtData; import org.spongepowered.api.data.type.DirtTypes; public void dirtToPodzol(Location<World> blockLoc) { BlockState state = blockLoc.getBlock(); Optional<ImmutableDirtData> dirtDataOpt = state.get(ImmutableDirtData.class); if (dirtDataOpt.isPresent()) { DirtData dirtData = dirtDataOpt.get().asMutable(); dirtData.set(Keys.DIRT_TYPE, DirtTypes.PODZOL); BlockState dirtState = state.with(dirtData.asImmutable()).get(); blockLoc.setBlock(dirtState); } }
Bitte beachte, dass DirtData eine veränderbare Kopie der Daten im BlockState
enthält. Diese werden verändert, bevor sie wieder eine unveränderliche Variante umgewandelt werden und zum Erstellen des neuen BlockState
s verwendet werden. Dieser ersetzt dann den vorherigen Block.
Die Methode without()
akzeptiert eine Referenz auf die Klasse, dessen Daten aus dem neu zu erstellendem BlockState` entfernt werden sollen. Wenn der Block ohne diese Daten nicht gültig wäre, wird der Standardwert verwendet. Wenn du also die DirtData
eines Erd-Blocks entfernst, dann wird diese auf den DirtTypes#DIRT zurückfallen, da dies der Standardwert ist. Das nachfolgende Beispiel versucht den Block an der angegebenen Stelle zu trocknen, falls möglich.
import org.spongepowered.api.data.manipulator.immutable.block.ImmutableWetData; public void dry(Location<World> blockLoc) { BlockState wetState = blockLoc.getBlock(); Optional<BlockState> dryState = wetState.without(ImmutableWetData.class); if (dryState.isPresent()) { blockLoc.setBlock(dryState.get()); } }
Da der WetData DataManipulator Daten vom Typ Boolean repräsentiert, setzen wir durch das Entfernen die Nässe des Blocks (wenn er eine hat) auf false. Die Prüfung dryState.isPresent()
schlägt bei Blöcken, die nicht nass sein können, fehl, da dryState
in diesem Fall Optional.empty()
ist.
Kopieren von Blöcken
Wenn du alle Eigenschaften eines Blockzustandes kopieren möchtest, dann ist die BlockSnapshot Klasse dein bester Freund. Während es nicht alle Daten bereitstellt, speichert es doch den BlockType
, seinem BlockState
und falls nötig auch die dazugehörigen Daten des Tile Entities (beispielsweise den Inhalt einer Kiste). Praktischer Weise enthält die Location
Klasse die Location#createSnapshot() Methode, die zum Erstellen eines Schnappschusses zum aktuellen Zeitpunkt verwendet werden kann. Dies macht das Kopieren von Blöcken von einem Ort zu einem anderen sehr einfach:
import org.spongepowered.api.block.BlockSnapshot; public void copyBlock(Location<World> from, Location<World> to) { BlockSnapshot snapshot = from.createSnapshot(); to.setBlock(snapshot.getState()); }