物品的创建
如果你想制作一个自定义的物品,你需要经过若干步骤方能搞定。让我们从最基础的开始,然后制作一把附魔的钻石剑。
创建一个 ItemStack 对象需要 ItemStack 的构造器;这构造器可通过 ItemStack#builder() 方法获得。这个构造器能让我们设定这个物品的类型及耐久。接下来,我们要制作一个带有自定义的名字的无限耐久附魔钻石剑。如果你想要一把普通的钻石剑,没有任何其他奇奇怪怪的数据,只需如此:
import org.spongepowered.api.item.ItemTypes;
import org.spongepowered.api.item.inventory.ItemStack;
public ItemStack generateSword() {
ItemStack superMegaAwesomeSword = ItemStack.builder()
.itemType(ItemTypes.DIAMOND_SWORD).build();
return superMegaAwesomeSword;
}
现在一把崭新的钻石剑就出来了。但这是把普通的钻石剑。如果我们想要加点有趣的属性呢?比如,改个名字?或者加个附魔?附魔可以借助 EnchantmentData 完成。下面我们将为钻石剑加附魔。你需要确保你在 return superMegaAwesomeSword;
之前把这些附魔全部搞定。
import java.util.List;
import java.util.stream.Collectors;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.manipulator.mutable.item.EnchantmentData;
import org.spongepowered.api.data.meta.ItemEnchantment
import org.spongepowered.api.item.Enchantment;
EnchantmentData enchantmentData = superMegaAwesomeSword
.getOrCreate(EnchantmentData.class).get();
final List<EnchantmentType> enchantments = Sponge.getRegistry()
.getAllOf(EnchantmentType.class).stream().collect(Collectors.toList());
for (EnchantmentType enchantment : enchantments) {
enchantmentData.set(enchantmentData.enchantments()
.add(Enchantment.of(enchantment, 1000)));
}
superMegaAwesomeSword.offer(enchantmentData);
现在我们想给这 OP 钻石剑起个看起来很厉害的名字。我们可以直接为 ItemStack
提供一个名字的键值,这样我们就能直接把这个 ItemStack
对象的名字改成 SUPER MEGA AWESOME Diamond Sword
(译注:大概就是“狂拽酷炫叼炸天的钻石剑”的意思):
import org.spongepowered.api.data.key.Keys;
import org.spongepowered.api.text.Text;
import org.spongepowered.api.text.format.TextColors;
superMegaAwesomeSword.offer(Keys.DISPLAY_NAME, Text.of(
TextColors.BLUE, "SUPER ",
TextColors.GOLD, "MEGA ",
TextColors.DARK_AQUA, "AWESOME ",
TextColors.AQUA, "Diamond Sword"));
最后,如果想要让你的剑永不磨损,你可以用另外一个键:
superMegaAwesomeSword.offer(Keys.UNBREAKABLE, true);
完工!现在这把永不损坏的剑不仅有各种附魔,还有一个华丽的名字,拿去给服务器里的小伙伴们玩去吧。
生成物品
当然我们可以直接把这把剑扔进玩家的背包中,但如果我们想让这把剑以掉落物的形式出现呢?是时候让“实体生成”登场了。有鉴于在游戏中,ItemStack
表现出来的外观还是 Item,我们是可以用生成普通 Entity 的方式来搞定这个事情的。此时,EntityType 将会是 EntityTypes#ITEM,同时我们还需要指定 Entity
代表了我们的 ItemStack
实例。这个过程可以通过使用 Keys#REPRESENTED_ITEM 完成。下面是例子:
import org.spongepowered.api.entity.Entity;
import org.spongepowered.api.entity.EntityTypes;
import org.spongepowered.api.event.CauseStackManager.StackFrame;
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
import org.spongepowered.api.world.extent.Extent;
import java.util.Optional;
public void spawnItem(ItemStack superMegaAwesomeSword, Location<World> spawnLocation) {
Extent extent = spawnLocation.getExtent();
Entity item = extent.createEntity(EntityTypes.ITEM, spawnLocation.getPosition());
item.offer(Keys.REPRESENTED_ITEM, superMegaAwesomeSword.createSnapshot());
try (StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
frame.addContext(EventContextKeys.SPAWN_TYPE, SpawnTypes.PLACEMENT);
extent.spawnEntity(item);
}
}
用方块创建 ItemStack
正常情况下,若需要方块对应的 ItemStack
,可以用 ItemStack.Builder#itemType(ItemType) 方法来获得方块对应的物品,但如果我们需要根据 BlockState 来创建 ItemStack
实例呢?只需要使用 ItemStack.Builder#fromBlockState(BlockState) 即可。下面是例子:
import org.spongepowered.api.block.BlockState;
public ItemStack createStack(BlockState state) {
return ItemStack.builder().fromBlockState(state).build();
}