物品与配置
介绍 Rebar 物品与配置系统的基础知识。
最后更新时间
概览
这节讲怎么给物品加自定义行为。我们用法棍喷火器来演示——右键点击实体时点燃它。
法棍喷火器
创建一个"普通"物品
像上一节一样,先做一个"普通"物品。
public final class ExampleAddonKeys {
public static final NamespacedKey baguetteFlamethrowerKey = new NamespacedKey(this, "baguette_flamethrower");
}public final class ExampleAddonItems {
// ...
public static final ItemStack baguetteFlamethrower = ItemStackBuilder.rebar(Material.BREAD, baguetteFlamethrowerKey)
.build();
// ...
public static void initialize() {
// ...
RebarItem.register(RebarItem.class, baguette);
PylonPages.FOOD.addItem(baguetteKey);
}
}item:
baguette:
name: Baguette Flamethrower
lore: |-
<arrow> Use the power of baguettes to vanquish your enemies
<arrow> <insn>Right click</insn> an entity to ignite it创建自定义物品类
接下来加点火逻辑。
需要新建一个 BaguetteFlamethrower 类。所有 Rebar 物品类都必须继承 RebarItem。
新建 BaguetteFlamethrower.java:
public class BaguetteFlamethrower extends RebarItem {
public BaguetteFlamethrower(@NotNull ItemStack stack) {
super(stack);
}
}想让玩家拿法棍喷火器右键实体时触发代码。为此需要实现一个 Rebar 物品接口。
Rebar 物品接口就是让你的物品能做更多事的接口——比如在物品被使用时执行代码。
这里要实现 RebarItemEntityInteractor 接口,它有一个方法:onUsedToRightClickEntity。
物品接口完整列表在这里。
public class BaguetteFlamethrower extends RebarItem implements RebarItemEntityInteractor {
public BaguetteFlamethrower(@NotNull ItemStack stack) {
super(stack);
}
@Override
public void onUsedToRightClickEntity(@NotNull PlayerInteractEntityEvent event, @NotNull EventPriority priority) {
event.getRightClicked().setFireTicks(40);
}
}使用自定义物品类
让法棍喷火器用这个自定义类,代替默认的 RebarItem:
把 RebarItem.register(...) 那行改成这样:
RebarItem.register(BaguetteFlamethrower.class, baguetteFlamethrower);跑一下服务器试试。用法棍喷火器右键一个实体,应该能让它着火 40 tick!
让物品可配置
物品可以绑定配置文件。看看服务器的 Pylon 设置目录(run/plugins/Rebar/settings/pylon),很多 Pylon 物品和方块都有自己的配置文件。
比如 bandage.yml:
consume-seconds: 1.25
heal-amount: 4.0创建配置文件
假如想加个配置文件,让你自己设置法棍喷火器的点燃时长。
新建 resources/settings/baguette_flamethrower.yml:
burn-time-ticks: 40最佳实践
配置选项是数量的话,名称里带上单位。如果只叫 burn-time,用户可能不知道单位是 tick,会误以为是秒或其他单位。
Rebar 在配置文件首次使用时,会自动把所有设置复制到 run/plugins/Rebar/settings/<你的附属组件名称> 目录下,方便服主配置。
读取配置文件
读取配置里的 burn-time-ticks 值,用 getSettings().getOrThrow(...) 就行。getSettings() 返回和物品键同名的配置——本例中是 flamethrower_baguette:
public class BaguetteFlamethrower extends RebarItem implements RebarItemEntityInteractor {
private final int burnTimeTicks = getSettings().getOrThrow("burn-time-ticks", ConfigAdapter.INT);
public BaguetteFlamethrower(@NotNull ItemStack stack) {
super(stack);
}
@Override
public void onUsedToRightClickEntity(@NotNull PlayerInteractEntityEvent event, @NotNull EventPriority priority) {
event.getRightClicked().setFireTicks(40);
}
}Rebar 怎么知道用哪个配置文件?
配置文件是按键分配的,不是按物品。访问 settings 时,Rebar 会取物品的键去找对应的设置文件!其实就是 Settings.get(key) 的简写。如果你用 Settings.get(NamespacedKey(MyAddon.getInstance(), "buffoon")),读的就是 buffoon.yml。
Settings 也有 get 方法,找不到键就返回 null。用 getOrThrow 的话,找不到键会直接抛异常,告诉你缺了哪个键、在哪。
调用 get 或 getOrThrow 时要传一个 ConfigAdapter,这个类定义了怎么从配置文件读值。
配置适配器列表在这里。
用配置值来点火
现在可以用这个值来点火了!
public class BaguetteFlamethrower extends RebarItem implements RebarItemEntityInteractor {
private final int burnTimeTicks = getSettings().getOrThrow("burn-time-ticks", ConfigAdapter.INT);
public BaguetteFlamethrower(@NotNull ItemStack stack) {
super(stack);
}
@Override
public void onUsedToRightClickEntity(@NotNull PlayerInteractEntityEvent event, @NotNull EventPriority priority) {
event.getRightClicked().setFireTicks(burnTimeTicks);
}
}改配置值的话燃烧时间也会跟着变。
测配置的时候注意:每次跑测试服务器任务都会清空 plugins 文件夹,里面的配置改动会被覆盖。所以要么改默认值,要么手动启服务器(不要用测试任务),这样 plugins 文件夹不会被清。
完整代码
public final class ExampleAddonKeys {
public static final NamespacedKey baguetteFlamethrowerKey = new NamespacedKey(this, "baguette_flamethrower");
}public class BaguetteFlamethrower extends RebarItem implements RebarItemEntityInteractor {
private final int burnTimeTicks = getSettings().getOrThrow("burn-time-ticks", ConfigAdapter.INT);
public BaguetteFlamethrower(@NotNull ItemStack stack) {
super(stack);
}
@Override
public void onUsedToRightClickEntity(@NotNull PlayerInteractEntityEvent event, @NotNull EventPriority priority) {
event.getRightClicked().setFireTicks(burnTimeTicks);
}
}public final class ExampleAddonItems {
// ...
public static final ItemStack baguetteFlamethrower = ItemStackBuilder.rebar(Material.BREAD, baguetteFlamethrowerKey)
.build();
// ...
public static void initialize() {
// ...
RebarItem.register(RebarItem.class, baguette);
PylonPages.FOOD.addItem(baguetteKey);
}
}item:
baguette:
name: Baguette Flamethrower
lore: |-
<arrow> Use the power of baguettes to vanquish your enemies
<arrow> <insn>Right click</insn> an entity to ignite itburn-time-ticks: 40