Modifier les Blocs
Changer le type d’un bloc
Changer le type d’un bloc est aussi simple que d’appeler la méthode Location#setBlockType(BlockType) avec un nouveau BlockType. Le code qui suit transforme le bloc à la Location donnée en une éponge:
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); }
C’est aussi simple que cela. Si vous voulez juste “supprimer” un bloc (qui ce fait en le remplaçant par de l’air), vous devez juste utiliser la méthode Location#removeBlock() qui est fournit par une Location
(emplacement).
Modifier les États des Blocs
Comme dans l’exemple ci-dessus, la classe Location
fournit une méthode Location#setBlock(BlockState) utilisant un nouveau BlockState. Pour pouvoir l’utiliser, vous devez en premier lieu avoir un BlockState
que vous pouvez modifier. Vous pouvez faire la même chose en obtenant l’état actuel du bloc avec la méthode Location#getBlock() que fournit la classe Location
ou en utilisant l’état d’un bloc par défaut. Ce dernier est démontré ci-dessous: L’état par défaut d’un bloc d’éponge est récupéré et ensuite modifié pour créer directement un bloc d’éponge mouillée:
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); }
Puisqu’un BlockState
est un ImmutableDataHolder, vous pouvez utiliser les méthodes fournies with()
et without()
qui vont toutes les deux renvoyer un nouveau BlockState
modifié ou Optional.empty()
si le ImmutableDataManipulator donné n’est pas applicable au type de bloc représenté par le BlockState
.
La méthode with()
accepte un ImmutableDataManipulator
et va essayer de créer un nouveau BlockState
avec l’ensemble de données fourni, en écrasant les valeurs existantes. L’exemple suivant va changer n’importe quel bloc de terre en podzol.
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); } }
Notez que DirtData est une copie mutable des données contenues dans le BlockState
. Elles sont changées et ensuite utilisées pour créer un nouveau BlockState
qui va remplacer le bloc originel.
La méthode without()
accepte une classe référence et va créer un nouveau BlockState
sans les données représentées par la classe donnée. Si le nouveau BlockState
n’est pas valide sans ces données, une valeur par défaut sera utilisée. Donc si la donnée DirtData
d’un bloc de terre est supprimée, elle sera automatiquement remplacée par la valeur DirtTypes#DIRT, la valeur par défaut. L’exemple suivant va sécher le bloc à la Location
donnée, si possible.
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()); } }
Puisque le manipulateur de données WetData représente des données booléennes, en le supprimant nous définissons l’humidité du bloc (si il en possède) à false. La vérification dryState.isPresent()``échouera lorsqu'elle sera faîtes sur des blocs ne pouvant pas être humides et ``dryState
sera Optional.absent()
dans ce cas.
Copier les Blocs
Si vous souhaitez copier toutes les données d’un bloc, la classe BlockSnapshot sera votre meilleure amie. Même si elle ne prend pas en compte toutes les données, elle sauvegarde un BlockType
, son BlockState
et, si nécessaire, toutes les données supplémentaires des Tile Entities (Pour les inventaires de coffres par exemple). Comme les choses sont bien faites, la classe Location
fournit la méthode Location#createSnapshot() pour créer une copie du bloc à ce point dans le temps. Cela rend la copie d’un bloc d’un emplacement à un autre très simple :
import org.spongepowered.api.block.BlockSnapshot; public void copyBlock(Location<World> from, Location<World> to) { BlockSnapshot snapshot = from.createSnapshot(); to.setBlock(snapshot.getState()); }