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 DataManipulator
s 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 DataManipulator
s and properties that are applied to
the block, and any BlockTraits for a block. It stores all immutable values 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 DataManipulator
s 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 DataManipulator
s in place of BlockTrait
s where possible as they are
only to be meant as a fallback for modded compatibility.