修改方块
更改方块类型
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); }
它就是这么简单。如果你只是想要“删除”一个方法(也就是把它替换成空气),你可以只使用 Location#removeBlock() 这一由 Location
提供的方法。
更改方块状态
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.
复制方块
如果你想要复制一个方块的所有数据, BlockSnapshot 可能会是最好的选择。尽管它并不公开所有的数据,但是它存储了一个 BlockType
,它的 BlockState
,和所有额外的 Tile Entity 数据(如果有必要),比如一个箱子的物品栏( Inventory )。 Location
类提供了一个 Location#createSnapshot() 方法以即时创建一个方块的快照( BlockSnapshot
)。这使得把方块从一处复制到另一处变得十分简单:
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); }