[Java Spigot/Minecraft] 如何实现限制刷怪笼的刷怪数量?
实现Spigot刷怪笼刷怪数量限制方案
核心问题解决思路
1. 追踪怪物对应的刷怪笼
Spigot的CreatureSpawnEvent中,可通过getSpawnReason()判断怪物是否由刷怪笼生成(匹配SpawnReason.SPAWNER)。确认后调用getSpawner()获取刷怪笼的Spawner对象(即方块的BlockState),再通过spawner.getBlock().getLocation()拿到刷怪笼的唯一位置标识,以此建立怪物与刷怪笼的关联。
2. 存储刷怪上限与计数
推荐使用**PersistentDataContainer(PDC)**存储数据,这是Spigot 1.16+原生支持的方块绑定存储方式,服务器重启后数据不会丢失:
- 用两个
NamespacedKey分别存储已刷怪计数(如spawn_count)和刷怪上限(如spawn_limit) - 全局默认上限可在插件
config.yml中配置,刷怪笼首次触发时自动将默认值写入PDC
完整代码实现示例
1. 插件主类初始化配置与事件注册
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.NamespacedKey; public class SpawnerLimitPlugin extends JavaPlugin { public static NamespacedKey SPAWN_COUNT_KEY; public static NamespacedKey SPAWN_LIMIT_KEY; private int defaultLimit; @Override public void onEnable() { // 加载默认配置 saveDefaultConfig(); defaultLimit = getConfig().getInt("default-limit", 500); // 初始化PDC标识键 SPAWN_COUNT_KEY = new NamespacedKey(this, "spawn_count"); SPAWN_LIMIT_KEY = new NamespacedKey(this, "spawn_limit"); // 注册事件监听器 getServer().getPluginManager().registerEvents(new SpawnerLimitListener(this), this); } }
2. CreatureSpawnEvent事件处理逻辑
import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.block.Spawner; import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataType; import org.bukkit.Material; public class SpawnerLimitListener implements Listener { private final SpawnerLimitPlugin plugin; public SpawnerLimitListener(SpawnerLimitPlugin plugin) { this.plugin = plugin; } @EventHandler public void onCreatureSpawn(CreatureSpawnEvent event) { // 仅处理刷怪笼生成的怪物 if (event.getSpawnReason() != CreatureSpawnEvent.SpawnReason.SPAWNER) { return; } Spawner spawner = event.getSpawner(); if (spawner == null) { return; } PersistentDataContainer pdc = spawner.getPersistentDataContainer(); // 初始化上限(若未设置) if (!pdc.has(plugin.SPAWN_LIMIT_KEY, PersistentDataType.INTEGER)) { pdc.set(plugin.SPAWN_LIMIT_KEY, PersistentDataType.INTEGER, plugin.defaultLimit); spawner.update(); // 将数据保存到方块 } // 获取当前计数与上限 int currentCount = pdc.getOrDefault(plugin.SPAWN_COUNT_KEY, PersistentDataType.INTEGER, 0); int limit = pdc.get(plugin.SPAWN_LIMIT_KEY, PersistentDataType.INTEGER); // 计数达上限时执行逻辑 if (currentCount >= limit) { // 选项1:停止刷怪(取消本次生成并禁用刷怪笼) event.setCancelled(true); spawner.setSpawnRange(0); spawner.update(); // 选项2:直接销毁刷怪笼 // spawner.getBlock().setType(Material.AIR); return; } // 更新计数并保存 pdc.set(plugin.SPAWN_COUNT_KEY, PersistentDataType.INTEGER, currentCount + 1); spawner.update(); } }
3. config.yml配置示例
# 刷怪笼默认刷怪上限 default-limit: 500
额外优化建议
- 可添加指令(如
/setspawnlimit <位置> <数值>),实现单个刷怪笼的自定义上限设置 - 监听
BlockBreakEvent,若需统计全局刷怪笼数据,可在刷怪笼被破坏时清理内存中的临时计数(使用PDC则无需此操作) - 给达到上限的刷怪笼添加粒子效果,提示玩家该刷怪笼已停止工作
内容的提问来源于stack exchange,提问作者j4nluca_
相关产品推荐
相关产品推荐

