Wejście do Block-ów
Informacje podstawowe
Bloki są najczęściej zidentyfikowane i dostępne przez ich Location. Ta lokacja odnosi się do określonych współrzędnych wewnątrz Extent. W większości przypadków World będzie służył jako Extent.
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;
}
Ostrzeżenie
Należy zauważyć, że powyższy przykład nie może sprawdzić czy istnieje w danym world. getWorld(worldName).get() nie powiedzie się, jeżeli nie jest to nazwa worldu który jest załadowany.
Z tym obiektem Location możesz otrzymać dalsze informacje na temat bloku. Poniższy kod sprawdza, czy wywoływany blok jest rodzaju transparent.
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);
}
Wskazówka
Funkcja == mogłaby być użyta w miejscu equals() ponieważ jest tylko jedna instancja BlockType dla każdego bloku, jednak generalnie zaleca się używać equals()
Manipulatory Danych w Block-ach
The data of a block is held as a DataManipulator, similar to other parts of the API. This is the container that holds information on components of our block such as the orientation of a block, specific types (stone vs. granite), and so on. Checking the values of these manipulators is easy, you just need to check the block’s direction 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;
}
First, we need to know which DataManipulator sub-interface we need. Those that are applicable to blocks are found
in the org.spongepowered.api.data.manipulator.mutable and
org.spongepowered.api.data.manipulator.mutable.block packages. Then, we can just pass that class to the
get(DataManipulator) method of Location which will return an Optional. We then have to check if our
DataManipulator actually exists for our block by checking ifPresent(). If it exists, then we can use it.
More on DataManipulators can be found in the data documentation.
Wskazówka
Jeśli Block nie będzie wspierał specyfikacji DataManipulator, takich jak DirectionalData to nie trzeba używać isPresent(). Po prostu usuń opcjonalne DataManipulator i pobierz obowiązkowe dane by użyć .get() na końcu instrukcji. Zauważ, że spowoduje to NullPointerException, jeśli kiedykolwiek Block przestanie pobierać szczególne dane DataManipulator.
Statusy Block-ów
A BlockState contains a BlockType, any DataManipulators and properties that are applied to
the block, and any BlockTraits for a block. It stores all immutable value’s for a particular block. One
use of this is getting an ImmutableDataManipulator, as shown below:
import org.spongepowered.api.block.BlockState;
import org.spongepowered.api.data.manipulator.immutable.ImmutableWetData;
public void 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();
}
More information on mutable and immutable DataManipulators can be found in the data documentation.
Właściwości Block-u
Block-i mogą zawierać pewne właściwości. Właściwością jest wstępnie ustawiona wartość, którą definiuje logika gry. Na przykład, Block-i mogą zawierać wartości spadanio-odporne, które mogą być używane do określenia czy pracujesz z, czy bez faktycznego sprawdzenia typu Block-u, czy może być jeden na drugim. Na przykład jeśli chcemy uzyskać odporność na wybuch i sprawdzić czy to jest większe lub / niż równe jeden, wyglądałoby to tak:
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 = DoubleProperty.greaterThanOrEqual(1);
return one.matches(resistance);
}
return false;
}
This will get the blast resistance of our block and compare it to a new DoubleProperty, as
BlastResistanceProperty inherits from DoubleProperty. The method will then return if the blast
resistance of our block is greater than one, the value in placed matches(). If we wanted to see if it was less than
two, we would replace it with lessThan().
If we were comparing two pre-existing properties, it will take the Operator of our first value, the one we are
creating a double property for. If the Operator is DELEGATE, which is the none operator, then it will take the
Operator of the second value, the one in matches(). Comparison will return false if both are DELEGATE.
An example of comparing two PoweredPropertys, a BooleanProperty, can be seen below:
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 = BooleanProperty.of(property1);
BooleanProperty booleanProperty2 = BooleanProperty.of(true);
if(booleanProperty2.matches(property1)) {
return booleanProperty.matches(property2);
}
}
return false;
}
Drugi if sprawdza czy kontrolnie czy jedna z wartości jest prawdą. Jeżeli jest prawdą, i obydwa są równe obie wartości muszą być prawdziwe. W związku z tym eliminując konieczność sprawdzania drugiej wartości, teraz wiemy, że obydwa Block-i są zasilane.
A list of possible block properties can be found in the org.spongepowered.api.data.property.block package.
Cechy Block-ów
A block trait is a certain value on the current state of a block. A block may or may not contain block traits depending
on the type of block. For example, a bed has a BooleanTrait called
BED_OCCUPIED. As a boolean can only have two values, true and false, the BED_OCCUPIED trait can only be true or
false. Checking this value is simple, just call the BlockState#getTraitValue(BlockTrait) method. An example
of this with a bed is shown below:
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;
}
Ostrzeżenie
If possible, it is recommended to use DataManipulators in place of BlockTraits where possible as they are
only to be meant as a fallback for modded compatibility.