Blöcke verändern
Einen Block-Typ ändern
Das Ändern des Blocktypes ist so einfach, wie der Aufruf von Location#setBlockType(BlockType, Cause) mit dem neuen BlockType. Ähnlich wie bei den meisten Veränderungen von Blöcken, müssen wie den Grund (Cause
) für die Änderung des Blockes angeben. In den meisten Fällen reicht es hier, die Haupt-Plugin Klasse anzugeben. Der folgende Code verwandelt den Block an der angegebenen Stelle (Location) in einen Schwamm:
import org.spongepowered.api.block.BlockTypes; import org.spongepowered.api.event.cause.Cause; import org.spongepowered.api.world.Location; import org.spongepowered.api.world.World; public void setToSponge(Location<World> blockLoc, Object myPluginInstance) { blockLoc.setBlockType(BlockTypes.SPONGE, Cause.source(myPluginInstance).build()); }
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(Cause) benutzen, die Location
bereitstellt.
Einen Block-Status verändern
Ähnlich zum Beispiel oben, bietet die Location``Klasse eine Methode :javadoc:`Location#setBlock(BlockState, Cause)` 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, Object myPluginInstance) { 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, Cause.source(myPluginInstance).build()); }
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, Object myPluginInstance) { 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, Cause.source(myPluginInstance).build()); } }
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, Object myPluginInstance) { BlockState wetState = blockLoc.getBlock(); Optional<BlockState> dryState = wetState.without(ImmutableWetData.class); if (dryState.isPresent()) { blockLoc.setBlock(dryState.get(), Cause.source(myPluginInstance).build()); } }
Da der WetData Daten Manipulator Boolean Daten repräsentiert, wird durch dessen entfernen dessen die Feuchtigkeit des Blocks (falls vorhanden) auf falsch gesetzt. Die Überprüfung des dryState.isPresent()` wird bei Blöcken, die nicht nass sein können, fehlschlagen, da der dryState
in dem Fall Optional.empty()
sein wird.
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, Object myPluginInstance) { BlockSnapshot snapshot = from.createSnapshot(); to.setBlock(snapshot.getState(), Cause.source(myPluginInstance).build()); }