如何在Minecraft Bukkit插件中为武器添加射击冷却机制?
解决Minecraft Bukkit插件武器射击冷却问题
核心思路
通过玩家元数据标记特定武器的冷却状态,结合Bukkit Scheduler在冷却时间结束后移除标记,实现每把武器独立的射速限制。
修改步骤及代码实现
1. 完善事件监听类(OnPlayerInteract.java)
在右键事件中先检查冷却状态,只有未冷却时才允许射击,射击后启动计时器移除冷却标记:
package me.imhartash.imhartashguns.Events; import me.imhartash.imhartashguns.Handler.Gun; import me.imhartash.imhartashguns.ImHartashGuns; import org.bukkit.Bukkit; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.metadata.FixedMetadataValue; public class OnPlayerInteract implements Listener { private final ImHartashGuns plugin; // 构造函数传入插件实例,用于Scheduler和元数据管理 public OnPlayerInteract(ImHartashGuns plugin) { this.plugin = plugin; } @EventHandler public void onPlayerInteract(PlayerInteractEvent event) { // 只处理右键空气/方块动作 if (event.getAction() != Action.RIGHT_CLICK_AIR && event.getAction() != Action.RIGHT_CLICK_BLOCK) { return; } Gun gun = Gun.GetGunByItem(event.getItem()); if (gun == null) { return; } String cooldownKey = "gun_cooldown_" + gun.getName(); // 检查玩家是否处于当前武器的冷却中 if (event.getPlayer().hasMetadata(cooldownKey)) { long remainingTicks = event.getPlayer().getMetadata(cooldownKey).get(0).asLong(); double remainingSeconds = remainingTicks / 20.0; event.getPlayer().sendMessage("[" + gun.getName() + "] 冷却中,剩余 " + String.format("%.1f", remainingSeconds) + " 秒"); event.setCancelled(true); // 取消事件,避免触发其他右键行为 return; } // 执行射击逻辑 gun.shot(event.getItem(), event.getPlayer()); // 设置冷却标记,值为冷却时长(ticks) event.getPlayer().setMetadata(cooldownKey, new FixedMetadataValue(plugin, gun.getCD())); // 启动Scheduler,冷却结束后移除标记 Bukkit.getScheduler().runTaskLater(plugin, () -> { if (event.getPlayer().isOnline() && event.getPlayer().hasMetadata(cooldownKey)) { event.getPlayer().removeMetadata(cooldownKey, plugin); } }, gun.getCD()); } }
2. 注册事件时传入插件实例
在主类ImHartashGuns的onEnable方法中,注册事件时必须传入插件实例,否则Scheduler会失效:
@Override public void onEnable() { // 注册事件监听 getServer().getPluginManager().registerEvents(new OnPlayerInteract(this), this); // 其他初始化逻辑... }
3. 添加AWP武器定义(Gun.java)
在枚举中加入AWP的配置,设置合理的冷却时长(20 ticks = 1秒,CS原版AWP射速约1.5秒,对应30 ticks):
public enum Gun { AKM("AKM", 30, Material.GOLD_INGOT, 10, 20), GLOCK18("Glock-18", 18, Material.IRON_INGOT, 2, 200), AWP("AWP", 10, Material.DIAMOND_INGOT, 100, 30); // 新增AWP配置 // 原有枚举字段、构造函数、方法保持不变... }
关键细节说明
- 冷却与玩家绑定:使用玩家元数据而非物品数据,确保玩家切换武器时,不同武器的冷却独立计算。
- Scheduler必须传插件实例:Bukkit的Scheduler需要插件上下文才能正常运行,这是之前冷却失效的常见原因。
- 取消事件:冷却中调用
event.setCancelled(true),避免玩家在冷却时触发其他右键动作(比如用武器材质方块放置)。
内容的提问来源于stack exchange,提问作者ImHartash
相关产品推荐
相关产品推荐

