Blöcke verändern

Den Typ eines Blocks ändern

Changing the Type of a Block is as simple as calling the Location#blockType(BlockType) method with the new BlockType. The following code turns the block at the given Location into a sponge:

import org.spongepowered.api.block.BlockTypes;
import org.spongepowered.api.world.server.ServerLocation;
import org.spongepowered.api.world.server.ServerWorld;

public void setToSponge(ServerLocation 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

Similar to the above example, the Location class provides a Location#setBlock(BlockState) method accepting a new BlockState. To make use of it, you first must acquire a BlockState you can modify. You can do so either by getting the block’s current state via the Location#block() method or by using a BlockType‚s default state. The latter is demonstrated below. The default state for a Sponge block is retrieved and then modified to directly create a wet sponge block:

import org.spongepowered.api.Sponge;
import org.spongepowered.api.block.BlockState;
import org.spongepowered.api.data.Keys;

public void setToWetSponge(ServerLocation blockLoc) {
    BlockState state = BlockTypes.SPONGE.get().getDefaultState();
    BlockState newState = state.with(Keys.IS_WET, true).get();
    blockLoc.setBlock(newState);
}

Since a BlockState is an DataHolder.Immutable, you may use the provided methods with() and without(), both of which will return a new altered BlockState or Optional.empty() if the given DataManipulator.Immutable is not applicable to the kind of block represented by the BlockState.

The with() method accepts an DataManipulator.Immutable and will try to create a new BlockState with the given data set, overwriting existing values. The following example will change any stairs block to face east.

public void faceEast(ServerLocation blockLoc) {
    BlockState state = blockLoc.block();
    Optional<BlockState> withEastState = state.with(Keys.DIRECTION, Direction.EAST);
    if (withEastState.isPresent()) {
        blockLoc.setBlock(dirtState);
    }
}

The without() method accepts a class reference and will create a new BlockState without the data represented by the given class. If the block state would not be valid without that data, a default value will be used. So if the Keys.DIRECTION from a block’s state is removed, it will fall back to Direction#NORTH, the default value. The following example will dry the block at a given Location, if possible.

public void dry(ServerLocation blockLoc) {
    BlockState wetState = blockLoc.block();
    Optional<BlockState> dryState = wetState.without(Keys.IS_WET);
    if (dryState.isPresent()) {
        blockLoc.setBlock(dryState.get());
    }
}

Since the Keys#IS_WET data manipulator represents boolean data, by removing it we set the wetness of the block (if it has any) to false. The dryState.isPresent() check will fail on block states that cannot be wet since Keys.IS_WET will be Optional.empty() in that case.

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;
import org.spongepowered.api.world.BlockChangeFlags;

public void copyBlock(ServerLocation from, ServerLocation to) {
    BlockSnapshot snapshot = from.createSnapshot();
    to.restoreSnapshot(snapshot, false, BlockChangeFlags.ALL);
}