修改實體

警告

这些文档是为 SpongeAPI 7 编写的,可能已经过时。 如果你觉得你可以帮助更新它们,请提交一个 PR!

確實,生成常規的實體已經很足夠了,不過有沒有更有趣的東西呢?這時候就需要 DataManipulator 大顯身手了。一個 Entity 同時也是一個 DataHolder,也就是說,我們的 Entity 可以儲存資料。關於 DataHolder 的更多資訊可以在 data documentation 找到。

適用於 EntityDataManipulatorFoodDataHealthData 等。適用的 DataManipulator 清單可在 org.spongepowered.api.data.manipulator.mutableorg.spongepowered.api.data.manipulator.mutable.entity 找到。請注意,並非所有 DataManipulator 都適用於所有實體。

實體類型

在我们进一步操纵实体之前,我们首先应检查这个 Entity 是什么类型的,因为一些实体并不是我们自己生成的,所以我们可能并不清楚它的具体类型。一个很简单的检查就可以完成这一点,下面是一个检查一个 Entity 是否是一个爬行者的示例:

import org.spongepowered.api.entity.Entity;
import org.spongepowered.api.entity.EntityTypes;

public boolean isCreeper(Entity entity) {
    return entity.getType().equals(EntityTypes.CREEPER);
}

實體資料操作者(Entity Data Manipulators)

現在我們確定我們的 Entity 是一隻苦力怕了,那我們就可以對其使用針對苦力怕的 DataManipulator。例如 ExplosionRadiusData 是一個苦力怕可以擁有的 DataManipulator,並非所有 Entity 都可以。把一個 Entity 的爆炸範圍改為 50 的範例如下:

import org.spongepowered.api.data.manipulator.mutable.entity.ExplosiveRadiusData;

public void explosionRadius50(Entity creeper) {
    ExplosionRadiusData radiusData = creeper.get(ExplosionRadiusData.class).get();
    creeper.offer(radiusData.explosionRadius().setTo(50));
}

這將取得我們的 EntityExplosiveRadiusData 來讓我們使用。然後我們使用該資料將苦力怕的爆炸範圍設定為 50,接著我們必須將該資料提供回去給苦力怕,因為我們從我們的 Entity 取得的資料只是一個資料的副本。

也許我們想要給我們的 Entity 一個自定義名稱!這可以透過使用 DisplayNameData 來完成。以下是這個動作的一個範例:

import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.spongepowered.api.data.manipulator.mutable.DisplayNameData;

public void setDisplayName(Entity creeper) {
    DisplayNameData displayData = creeper.get(DisplayNameData.class).get();
    creeper.offer(displayData.displayName()
        .set(Component.text("Inscrutable", NamedTextColor.DARK_AQUA)));
}

另外,有更簡短的方式來完成這件事,只要在我們的 Entity 使用 Keys 而非 DataManipulator。就像這樣:

import org.spongepowered.api.data.key.Keys;

public void explosionRadius50(Entity creeper) {
    creeper.offer(Keys.EXPLOSION_RADIUS, Optional.of(50));
    creeper.offer(Keys.DISPLAY_NAME, Component.text("Inscrutable", NamedTextColor.DARK_AQUA));
}

This would neaten our code and is easier to perform. See the data documentation on the specific benefits of using either DataManipulators or just Keys.