物品的创建
如果你想制作一个自定义的物品,你需要经过若干步骤方能搞定。让我们从最基础的开始,然后制作一把附魔的钻石剑。
创建一个 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;
}
Creating the basic item is done. Now this is a normal diamond sword that we created, but what if we wanted something more interesting? What about enchanting and naming our sword? We can use Keys#APPLIED_ENCHANTMENTS to give our sword some enchantments. The following example will give our sword every enchantment in the game, to level 1000.
import java.util.List;
import java.util.stream.Collectors;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.meta.ItemEnchantment
import org.spongepowered.api.item.Enchantment;
public void withThousandEnchantmentLevel(ItemStack superMegaAwesomeSword){
List<Enchantment> enchantments = RegistryTypes
.ENCHANTMENT_TYPE
.get()
.stream()
.filter(type -> type.canBeAppliedToStack(superMegaAwesomeSword))
.map(type -> Enchantment.of(type, 1000))
.collect(Collectors.toList());
superMegaAwesomeSword.offer(Keys.APPLIED_ENCHANTMENTS);
}
现在我们想给这 OP 钻石剑起个看起来很厉害的名字。我们可以直接为 ItemStack
提供一个名字的键值,这样我们就能直接把这个 ItemStack
对象的名字改成 SUPER MEGA AWESOME Diamond Sword
(译注:大概就是“狂拽酷炫叼炸天的钻石剑”的意思):
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.NamedTextColor;
import org.spongepowered.api.data.Keys;
import org.spongepowered.api.item.ItemTypes;
superMegaAwesomeSword.offer(Keys.DISPLAY_NAME, TextComponent.ofChildren(
Component.text("SUPER ", NamedTextColor.BLUE),
Component.text("MEGA ", NamedTextColor.GOLD),
Component.text("AWESOME ", NamedTextColor.DARK_AQUA),
ItemTypes.DIAMOND_SWORD.get().asComponent().color(NamedTextColor.AQUA));
最后,如果想要让你的剑永不磨损,你可以用另外一个键:
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.server.ServerWorld;
import java.util.Optional;
public void spawnItem(ItemStack superMegaAwesomeSword, ServerLocation spawnLocation) {
ServerWorld world = spawnLocation.world();
Item item = world.createEntity(EntityTypes.ITEM, spawnLocation.getPosition());
item.offer(Keys.REPRESENTED_ITEM, superMegaAwesomeSword.createSnapshot());
try (StackFrame frame = Sponge.server().causeStackManager().pushCauseFrame()) {
frame.addContext(EventContextKeys.SPAWN_TYPE, SpawnTypes.PLACEMENT);
word.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();
}