修改實體

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

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

實體類型

Before we can jump behind the wheel with our Entity, we should check what type of Entity it is, as we may receive an Entity we didn’t create and thus, do not know its type. Doing this is a simple equality check. Here is an example of checking if our Entity is a creeper:

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 org.spongepowered.api.data.manipulator.mutable.DisplayNameData;
import org.spongepowered.api.text.Text;
import org.spongepowered.api.text.format.TextColors;

public void setDisplayName(Entity creeper) {
    DisplayNameData displayData = creeper.get(DisplayNameData.class).get();
    creeper.offer(displayData.displayName().set(Text.of(TextColors.DARK_AQUA,
                                                          "Inscrutable")));
}

另外,有更簡短的方式來完成這件事,只要在我們的 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, Text.of(TextColors.DARK_AQUA, "Inscrutable"));
}

這使我們的程式碼更簡潔,也更容易執行。參閱 data documentation 以了解使用 DataManipulatorKeys 的優勢。