Accéder aux Blocs
Informations basiques
Les blocs sont dans la majeure partie du temps identifiables et accessibles par leur Location (position). Cette position nous indique des coordonnées et un Extent (zone). Dans la plupart des cas un World (monde) sera utilisé comme zone.
import org.spongepowered.api.Sponge;
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
public Location<World> getBlockAt(String worldName, int posX, int posY, int posZ) {
World world = Sponge.getServer().getWorld(worldName).get();
Location<World> blockLoc = new Location<World>(world, posX, posY, posZ);
return blockLoc;
}
Avertissement
Notez que l’exemple ci-dessous ne vérifie pas si le monde existe. La méthode getWorld(worldName).get()
va échouer si aucun monde portant ce nom n’est chargé.
Avec cet objet Location
vous pouvez obtenir des informations plus complètes à propos du bloc. Le code suivant vérifie si un bloc référencé est une bannière en regardant le type de bloc.
import org.spongepowered.api.block.BlockType;
import org.spongepowered.api.block.BlockTypes;
public boolean isBanner(Location<World> blockLoc) {
BlockType type = blockLoc.getBlock().getType();
return type.equals(BlockTypes.STANDING_BANNER)
|| type.equals(BlockTypes.WALL_BANNER);
}
Astuce
La fonction ==
pourrait être utilisée à la place de equals()
comme il n’y a qu’une seule instance de BlockType pour chaque bloc, mais il est recommandé d’utiliser equals()
.
Manipulateurs de Données de Blocs
Les données d’un bloc sont contenues dans le DataManipulator, comme pour les autres parties de l’API. Ceci contient des informations liées au bloc, comme son orientation, son type (pierre / granite), et ainsi de suite. Vérifier les valeurs de ces manipulateurs est facile, vous devez juste vérifier la direction du bloc DirectionalData.
import org.spongepowered.api.data.key.Keys;
import org.spongepowered.api.data.manipulator.mutable.block.DirectionalData;
public boolean isFacingNorth(Location<World> blockLoc) {
Optional<DirectionalData> optionalData = blockLoc.get(DirectionalData.class);
if (!optionalData.isPresent()) {
return false;
}
DirectionalData data = optionalData.get();
if (data.get(Keys.DIRECTION).get().equals(Direction.NORTH)) {
return true;
}
return false;
}
Tout d’abord, nous devons savoir de quelle sous-interface de DataManipulator
nous avons besoin. Celles qui s’appliquent aux blocs se trouvent dans les packages org.spongepowered.api.data.manipulator.mutable et org.spongepowered.api.data.manipulator.mutable.block. Ensuite, nous pouvons juste passer cette classe à la méthode get(DataManipulator)
de Location
qui va retourner un Optional
. Nous devons ensuite vérifier si notre DataManipulator
existe actuellement pour notre bloc en vérifiant ifPresent()
. Si il existe, nous pouvons alors l’utiliser.
Plus d’infos sur les DataManipulator
s peuvent être trouvées dans la documentation des données.
Astuce
Si un bloc ne s’arrêtera jamais de supporter un DataManipulator
particulier, comme le DirectionalData
avec les escaliers, il n’y a alors pas besoin de vérifier le isPresent()
. Supprimez juste l’optional autour du DataManipulator
et récupérer les données non-optionnelles en ajoutant .get()
à la fin de l’instruction. Notez que cela entraînera une NullPointerException
si un bloc s’arrête de supporter un DataManipulator
particulier.
États des Blocs
Un BlockState contient un BlockType, n’importe quels DataManipulator
s et des propriétés qui sont appliquées au bloc, et n’importe quels BlockTraits pour un bloc. Il stocke toutes les valeurs immuables pour un bloc particulier. Une utilisation de ceci est de récupérer un ImmutableDataManipulator, comme montré ci-dessous :
import org.spongepowered.api.block.BlockState;
import org.spongepowered.api.data.manipulator.immutable.ImmutableWetData;
public boolean isWet(Location blockLoc) {
BlockState sponge = blockLoc.getBlock();
if (!sponge.getType().equals(BlockTypes.SPONGE)) {
return false;
}
Optional<ImmutableWetData> wetness = sponge.get(ImmutableWetData.class);
return wetness.isPresent();
}
Plus d’informations sur les DataManipulator
s mutables et immuables peuvent être trouvées dans la documentation des données.
Propriétés de Blocs
Les blocs peuvent contenir certaines propriétés. Une propriété est une valeur prédéterminée qui définit la logique de jeu de ce bloc particulier. Par exemple, les blocs peuvent contenir des valeurs de résistance aux explosions prédéterminées qui peuvent être utilisées pour déterminer avec quoi vous travailler, sans vérifier le type de bloc que ça pourrait être un par un. Par exemple, si nous voulions récupérer la résistance aux explosions d’un bloc et vérifier si elle est plus grande ou égale à un, ça serait fait comme ceci :
import org.spongepowered.api.data.Property;
import org.spongepowered.api.data.property.DoubleProperty;
import org.spongepowered.api.data.property.block.BlastResistanceProperty;
public boolean blastResistanceGreaterThanOne(Location<World> blockLoc) {
Optional<BlastResistanceProperty> optional =
blockLoc.getProperty(BlastResistanceProperty.class);
if(optional.isPresent()) {
BlastResistanceProperty resistance = optional.get();
DoubleProperty one = new DoubleProperty(1, Property.Operator.GEQUAL);
return one.matches(resistance);
}
return false;
}
Ceci récupére la résistance aux explosions de notre bloc et la compare à un nouveau DoubleProperty, puisque BlastResistanceProperty hérite de DoubleProperty
. La méthode va donc retourner si la résistance aux explosions de notre bloc est plus grande que un, la valeur du matches()
. Si nous voulions voir s’il y en a moins que deux, nous remplacerions l’opérateur de propriétés dans le constructeur de DoubleProperty
avec Property.Operator.LESS
.
Si nous étions en train de comparer deux propriétés déjà existantes, ça prendrait l”Operator
de notre première valeur, celle pour laquelle nous créons une propriété double. Si l”Operator
est DELEGATE
, qui est l’opérateur « aucun », alors il prendra l”Operator
de la seconde valeur, celle du matches()
. La comparaison retournera false si les deux sont DELEGATE
. Un exemple de comparaison de deux PoweredPropertys, et d’une BooleanProperty peut être trouvé ci-dessous :
import org.spongepowered.api.data.property.BooleanProperty;
import org.spongepowered.api.data.property.block.PoweredProperty;
public boolean areBlocksPowered(Location<World> blockLoc, Location<World> blockLoc2) {
Optional<PoweredProperty> optional = blockLoc.getProperty(PoweredProperty.class);
Optional<PoweredProperty> optional2 = blockLoc2.getProperty(PoweredProperty.class);
if(optional.isPresent() && optional2.isPresent()) {
PoweredProperty property1 = optional2.get();
PoweredProperty property2 = optional2.get();
BooleanProperty booleanProperty = new BooleanProperty(true, Property.Operator.EQUAL);
if(booleanProperty.matches(property1)) {
return property1.matches(property2);
}
}
return false;
}
Le second if
vérifie si une des propriétés est vraie. Si c’est vrai et que les deux sont égales, alors les deux valeurs doivent être vraies. Par conséquent, éliminant le besoin de vérifier la seconde valeur. Maintenant nous savons que les deux blocs sont alimentés.
Une liste des propriétés de blocs possibles peut être trouvée dans le package org.spongepowered.api.data.property.block.
Caractéristiques de Blocs
Une caractéristique de bloc est une certaine valeur sur l’état actuel d’un bloc. Un bloc peut ou peut ne pas contenir des caractéristiques selon le type de bloc. Par exemple, un lit possède un BooleanTrait appelé BED_OCCUPIED
. Comme un booléen peut seulement avoir deux valeurs, vrai et faux, la caractéristique BED_OCCUPIED
peut seulement être vraie ou fausse. Vérifier cette valeur est simple, appelez juste la méthode BlockState#getTraitValue(BlockTrait). Un exemple avec un lit est illustré ci-dessous :
import org.spongepowered.api.block.trait.BooleanTraits;
public boolean isBedOccupied(Location<World> blockLoc) {
if(blockLoc.getBlock().getType().equals(BlockTypes.BED)) {
return blockLoc.getBlock().getTraitValue(BooleanTraits.BED_OCCUPIED).get();
}
return false;
}
Avertissement
Si possible, il est recommandé d’utiliser les DataManipulator
s à la place des BlockTrait
s lorsque c’est possible car ils sont seulement conçus comme un secours pour la compatibilité avec les mods.