Skip to content

自定义道具系统

概述

自定义道具系统是 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(抽象基类)

所有自定义道具必须继承此类,定义以下关键成员:

成员类型说明
idString唯一标识符,如 "test_item"
nameKeyString语言文件中的显示名称 key
loreKeyString语言文件中的描述 key
baseMaterialMaterial载体材质(物品图标)
cooldownSecondsint冷却时间(秒),0 = 无冷却
consumableboolean是否消耗品

必须实现的方法

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);

使用流程

  1. 玩家右键物品 → PlayerInteractEvent
  2. CustomItemListener 识别道具
  3. 检查冷却 → 检查 canUse()
  4. 触发 CustomItemUseEvent
  5. 调用 onUse() 执行效果
  6. 成功 → 设置冷却、处理消耗

添加新道具

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.ymllang/en_us.yml 中添加:

yaml
bedwars-item-my-name: "§6我的道具"
bedwars-item-my-lore: "§7右键使用"

Debug UI

Debug 工具中包含自定义道具列表 UI,路径:

Debug 主菜单 → 自定义道具 → 列出所有道具 → 点击给予
  • Java 版:Bukkit Inventory
  • Bedrock 版:SimpleFormBuilder