自定义道具系统
概述
自定义道具系统是 bedwars 模块的游戏道具框架,基于原版物品为载体,通过 PersistentDataContainer 标识道具 ID,支持冷却、消耗、事件监听等特性。
包结构
cn.enderrealm.bedwars.game.items/
├── CustomItem.java # 道具抽象基类
├── CustomItemRegistry.java # 注册表
├── CustomItemManager.java # 生命周期管理器
├── CustomItemListener.java # 统一事件监听器
├── CustomItemUseEvent.java # 自定义 Bukkit Event
├── gui/
│ └── CustomItemDebugGUI.java # Debug UI
└── impl/
├── debug/
│ └── TestItem.java # 测试道具
└── combat/
└── DefenseTowerItem.java # 紧凑型防御塔核心类
CustomItem(抽象基类)
所有自定义道具必须继承此类,定义以下关键成员:
| 成员 | 类型 | 说明 |
|---|---|---|
id | String | 唯一标识符,如 "test_item" |
nameKey | String | 语言文件中的显示名称 key |
loreKey | String | 语言文件中的描述 key |
baseMaterial | Material | 载体材质(物品图标) |
cooldownSeconds | int | 冷却时间(秒),0 = 无冷却 |
consumable | boolean | 是否消耗品 |
必须实现的方法
java
// 使用道具的逻辑,返回 true 表示使用成功
public abstract boolean onUse(BedWars plugin, Player player, GameManager gm);可选覆写的方法
java
// 检查是否可以使用,默认:游戏运行中时可用
public boolean canUse(BedWars plugin, Player player, GameManager gm);
// 创建 ItemStack,默认:带 PDC 标记和 i18n 文本
public ItemStack createItemStack(BedWars plugin, Player player);CustomItemRegistry(注册表)
管理所有已注册的道具实例,使用 LinkedHashMap 保持注册顺序。
java
CustomItemRegistry registry = new CustomItemRegistry();
registry.register(new MyItem());
CustomItem item = registry.getItem("my_item");
Collection<CustomItem> all = registry.getAllItems();CustomItemManager(生命周期管理器)
负责道具的识别、给予、冷却管理。
java
CustomItemManager manager = new CustomItemManager(plugin);
// 识别 ItemStack 是否为自定义道具
CustomItem item = manager.fromItemStack(itemStack);
// 给予玩家道具
manager.giveItem(player, item);
// 冷却管理
boolean onCooldown = manager.isOnCooldown(player, item);
int remaining = manager.getRemainingCooldown(player, item);
manager.setCooldown(player, item);
manager.clearCooldowns(player);CustomItemUseEvent(自定义事件)
道具使用时触发的 Bukkit Event,可被其他插件监听和取消。
java
@EventHandler
public void onItemUse(CustomItemUseEvent event) {
Player player = event.getPlayer();
CustomItem item = event.getItem();
// 可选:取消使用
event.setCancelled(true);
}道具识别机制
使用 PersistentDataContainer 存储道具 ID:
java
// 标记(在 createItemStack 中)
NamespacedKey key = new NamespacedKey(plugin, "custom-item");
meta.getPersistentDataContainer().set(key, PersistentDataType.STRING, "my_item");
// 识别(在 fromItemStack 中)
String itemId = meta.getPersistentDataContainer().get(key, PersistentDataType.STRING);使用流程
- 玩家右键物品 →
PlayerInteractEvent CustomItemListener识别道具- 检查冷却 → 检查
canUse() - 触发
CustomItemUseEvent - 调用
onUse()执行效果 - 成功 → 设置冷却、处理消耗
添加新道具
1. 创建道具类
java
package cn.enderrealm.bedwars.game.items.impl.xxx;
public class MyItem extends CustomItem {
public MyItem() {
super("my_item", "bedwars-item-my-name", "bedwars-item-my-lore", Material.DIAMOND);
this.cooldownSeconds = 5;
this.consumable = false;
}
@Override
public boolean onUse(BedWars plugin, Player player, GameManager gm) {
// 道具效果
player.sendMessage("使用了道具!");
return true;
}
}2. 注册道具
在 CustomItemManager.registerBuiltinItems() 中添加:
java
private void registerBuiltinItems() {
registry.register(new TestItem());
registry.register(new DefenseTowerItem(plugin));
registry.register(new MyItem()); // 新增
}3. 添加语言 key
在 lang/zh_cn.yml 和 lang/en_us.yml 中添加:
yaml
bedwars-item-my-name: "§6我的道具"
bedwars-item-my-lore: "§7右键使用"Debug UI
Debug 工具中包含自定义道具列表 UI,路径:
Debug 主菜单 → 自定义道具 → 列出所有道具 → 点击给予- Java 版:Bukkit Inventory
- Bedrock 版:SimpleFormBuilder