BedWars 产矿机系统
概述
产矿机(Resource Generator)是 BedWars 的核心经济系统,负责在游戏过程中持续产出矿物资源。所有产矿机数据均通过 YAML 配置文件驱动,不包含任何硬编码数值,支持按游戏模式加载不同配置。
三种产矿机类型:
| 类型 | 标识 | 产出矿物 | 产出方式 |
|---|---|---|---|
| 队伍产矿机 | team_generator | 铁、金(3 级+绿宝石) | 玩家在范围内直接进背包,否则掉落 |
| 钻石产矿机 | diamond_generator | 钻石 | 掉落物 |
| 绿宝石产矿机 | emerald_generator | 绿宝石 | 掉落物 |
配置文件
目录结构
plugins/BedWars/
└── generators/
├── default.yml # 默认配置(所有模式未单独指定时使用)
├── fast.yml # 示例:快节奏模式配置
└── ... # 按需添加配置文件在插件启动时通过 saveResource("generators/default.yml", false) 自动释放。
配置文件格式
以 default.yml 为例:
# 模式映射:模式ID → 配置文件名(不含 .yml 后缀)
# 未映射的模式使用 default
mode-mapping:
4t: "default"
# fast: "fast" # 示例:快节奏模式使用 fast.yml
# 产矿机等级数据
generators:
team_generator:
display-name: "队伍产矿机"
levels:
1:
outputs:
iron:
material: IRON_INGOT
interval: 2 # 产出间隔(秒)
amount: 3 # 每次产出数量
saturation: 128 # 该位置铁锭掉落物最大数量
direct-inventory: true # 玩家在范围内时直接进背包
gold:
material: GOLD_INGOT
interval: 5
amount: 1
saturation: 32
direct-inventory: true
2:
outputs:
iron:
material: IRON_INGOT
interval: 2
amount: 5
saturation: 128
direct-inventory: true
gold:
material: GOLD_INGOT
interval: 5
amount: 2
saturation: 32
direct-inventory: true
# ...更多等级
diamond_generator:
display-name: "钻石产矿机"
levels:
1:
outputs:
diamond:
material: DIAMOND
interval: 30
amount: 1
saturation: 8
direct-inventory: false
# ...
emerald_generator:
display-name: "绿宝石产矿机"
levels:
# ...
# 通用设置
settings:
pickup-range: 1.5 # 铁/金直接进背包时的玩家检测范围(方块数)产出字段说明
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
material | String | 是 | Bukkit Material 枚举名,如 IRON_INGOT、DIAMOND |
interval | int | 是 | 产出间隔,单位为秒 |
amount | int | 是 | 每次产出的物品数量 |
saturation | int | 是 | 饱和值,该位置该类型掉落物的最大数量,达到后暂停产出 |
direct-inventory | boolean | 是 | 玩家在 pickup-range 范围内时是否直接放入背包 |
模式配置映射
通过 mode-mapping 段,不同游戏模式可以使用不同的产矿机配置:
mode-mapping:
4t: "default" # 4 队模式使用 default.yml
fast: "fast" # fast 模式使用 fast.yml重要:mode-mapping 可以定义在任意配置文件中(不一定是 default.yml)。系统启动时会扫描 generators/ 目录下所有 .yml 文件,收集所有映射。例如:
default.yml中定义4t: "default"fast.yml中定义fast: "fast"
两个映射都会被系统发现和加载。
加载逻辑:
- 启动时扫描所有
generators/*.yml,收集所有mode-mapping段 GeneratorConfig.loadForMode(modeId)查找已收集的映射- 找到映射 → 加载对应文件;未找到 → 使用
default - 配置文件不存在 → 自动降级到
default - 已加载的配置会被缓存,不会重复解析
核心类
类关系图
GameMode.setupGenerators()
→ new GeneratorManager(plugin, gameManager)
→ generatorManager.loadGenerators()
→ config.loadForMode(modeId) // 加载配置
→ loadTeamGenerators(mapConfig, world) // 从地图配置读取位置
→ loadGeneratorsByType(...) // 加载钻石/绿宝石产矿机
→ generatorManager.startAll() // 启动所有产矿机
→ ResourceGenerator.start() // 每个产矿机启动 BukkitRunnableGeneratorConfig
cn.enderrealm.bedwars.game.generator.GeneratorConfig产矿机配置管理器,从 YAML 文件动态加载产矿机等级数据。
| 字段/方法 | 说明 |
|---|---|
loadForMode(modeId) | 根据模式 ID 加载对应配置文件,先查 mode-mapping,无映射用 default |
getTier(type, level) | 获取指定类型和等级的 GeneratorTier,等级不存在时降级到等级 1 |
getMaxLevel(type) | 获取指定类型的最高等级 |
getAllTiers(type) | 获取指定类型的所有等级配置 |
getPickupRange() | 获取玩家吸取范围(方块数),来自 settings.pickup-range |
getActiveConfigName() | 当前使用的配置文件名 |
getModeMapping() | 获取模式映射表(只读) |
类型常量:
| 常量 | 值 | 说明 |
|---|---|---|
TYPE_TEAM | "team_generator" | 队伍产矿机 |
TYPE_DIAMOND | "diamond_generator" | 钻石产矿机 |
TYPE_EMERALD | "emerald_generator" | 绿宝石产矿机 |
GeneratorTier
cn.enderrealm.bedwars.game.generator.GeneratorTier单个产矿机等级的数据类。
| 字段 | 类型 | 说明 |
|---|---|---|
level | int | 等级编号 |
outputs | List<MaterialOutput> | 该等级的所有矿物产出列表 |
saturation | int | 等级层级的饱和值(已弃用,现在从每个产出中读取) |
MaterialOutput(内部类)
| 字段 | 类型 | 说明 |
|---|---|---|
material | Material | 矿物类型 |
intervalSeconds | int | 产出间隔(秒) |
intervalTicks | int | 产出间隔(tick),= intervalSeconds * 20 |
amount | int | 每次产出数量 |
directInventory | boolean | 是否直接进背包 |
saturation | int | 饱和值,该位置该类型掉落物最大数量 |
ResourceGenerator
cn.enderrealm.bedwars.game.generator.ResourceGenerator单个产矿机实例,管理定时产出任务。
| 方法 | 说明 |
|---|---|
start() | 启动产矿机,为每种矿物创建独立的 BukkitRunnable 定时任务 |
stop() | 停止产矿机,取消所有定时任务 |
upgrade(newLevel) | 升级到指定等级,停止旧任务并用新配置重启 |
isRunning() | 是否正在运行 |
产出逻辑流程:
每次定时任务触发
→ 检查世界是否加载
→ 检查饱和值(该位置该类型掉落物数 < saturation?)
→ direct-inventory == true 且玩家在 pickup-range 内?
→ 是:直接放入玩家背包,背包满则掉落
→ 否:以掉落物形式产出GeneratorManager
cn.enderrealm.bedwars.game.generator.GeneratorManager管理一场游戏中所有产矿机实例。
| 方法 | 说明 |
|---|---|
loadGenerators() | 从地图 config.yml 加载产矿机位置并创建实例 |
startAll() | 启动所有产矿机 |
stopAll() | 停止所有产矿机(游戏结束时调用) |
getGeneratorsByType(type) | 按类型获取产矿机列表 |
getAllGenerators() | 获取所有产矿机(只读) |
upgradeAllByType(type, level) | 升级指定类型的所有产矿机 |
getConfig() | 获取当前使用的 GeneratorConfig |
地图配置(产矿机位置)
产矿机的位置在地图的 config.yml 中定义,通过编辑 UI 的「队伍产矿机」按钮设置。
位置格式
generators:
# 队伍产矿机(新配置格式)
team_generator:
0:
x: 1.5
y: 64.0
z: -2.5
1:
x: 15.0
y: 64.0
z: 30.5
# 钻石产矿机
diamond:
0:
x: 50.0
y: 70.0
z: 50.0
1:
x: -50.0
y: 70.0
z: -50.0
# 绿宝石产矿机
emerald:
0:
x: 0.0
y: 75.0
z: 0.0旧配置兼容
如果地图 config 中没有 team_generator 段但有 iron 段,系统会将 iron 的位置作为队伍产矿机的位置,忽略 gold 的位置。这确保了旧地图配置的向后兼容。
# 旧格式(仍然可用,自动迁移)
generators:
iron:
0: { x: 1.5, y: 64.0, z: -2.5 }
gold:
0: { x: 1.5, y: 64.0, z: -2.5 } # 会被忽略加载优先级:
- 有
generators.team_generator→ 使用team_generator的位置 - 无
team_generator但有generators.iron→ 使用iron的位置 - 都没有 → 不创建队伍产矿机
编辑 UI
队伍产矿机按钮
编辑 UI 中 slot 37 为队伍产矿机按钮(熔炉图标),替代了原来的铁/金资源点两个按钮:
| 槽位 | 物品 | 功能 |
|---|---|---|
| 37 | 熔炉 | 设置队伍产矿机位置(可设置多个) |
| 38 | 空 | 已合并到队伍产矿机 |
| 39 | 钻石 | 设置钻石产矿机位置 |
| 40 | 绿宝石 | 设置绿宝石产矿机位置 |
点击队伍产矿机按钮后,会在玩家当前位置添加一个产矿机位置,并在该位置显示一个发光的熔炉掉落物作为标记。
语言 Key
| Key | 中文 | English |
|---|---|---|
edit-ui-team-gen | §8设置队伍产矿机 | §8Set Team Generator |
edit-display-team-gen | §8队伍产矿机 | §8Team Generator |
edit-team-gen-set | §a队伍产矿机位置已设置! | §aTeam generator set successfully! |
edit-ui-locations-set | §a已设置 {0} 个位置 | §a{0} location(s) set |
edit-ui-locations-not-set | §c点击当前位置设置为资源点 | §cClick to set current location as generator |
游戏流程中的产矿机
生命周期
游戏开始
→ GameMode.setupGenerators(gameManager)
→ new GeneratorManager(plugin, gameManager)
→ config.loadForMode(modeId) // 根据模式加载配置
→ loadGenerators() // 从地图配置读取位置
→ startAll() // 启动所有产矿机
→ gm.setGeneratorManager(generatorManager)
游戏进行中
→ 产矿机按配置间隔持续产出
→ 可通过 upgradeAllByType() 升级
游戏结束
→ GameManager.cleanup()
→ generatorManager.stopAll() // 停止所有产矿机产矿机启动时机
产矿机在游戏正式开始时启动,而非等待大厅阶段。这通过 GameMode.setupGenerators() 在游戏初始化任务链中被调用来保证。
饱和值机制
饱和值限制产矿机位置附近同一类型掉落物的最大数量,防止矿物堆积:
- 每次产出前,统计产矿机位置 0.5×1.0×0.5 格范围内同类型掉落物的总数量
- 如果总数 >= 饱和值,则跳过本次产出
- 铁锭饱和值通常为 128,金锭为 32,钻石/绿宝石为 8
- 饱和值配置在每个产出条目中,按矿物类型独立计算
直接进背包机制
direct-inventory: true 的产出(铁锭、金锭)在玩家靠近时有特殊处理:
- 产出触发时,检测产矿机位置
pickup-range范围内的非旁观模式玩家 - 有玩家在范围内 → 物品直接放入玩家背包
- 背包满了 → 剩余物品以掉落物形式产出
- 没有玩家在范围内 → 以掉落物形式产出(与
direct-inventory: false行为一致) - 多个玩家同时在场 → 所有玩家都收到物品
pickup-range 默认值为 1.5 格,在配置文件的 settings.pickup-range 中设置。
默认等级数据
队伍产矿机
| 等级 | 铁锭间隔 | 铁锭数量 | 金锭间隔 | 金锭数量 | 绿宝石间隔 | 绿宝石数量 |
|---|---|---|---|---|---|---|
| 1 | 2s | 3 | 5s | 1 | - | - |
| 2 | 2s | 5 | 5s | 2 | - | - |
| 3 | 2s | 5 | 5s | 2 | 20s | 1 |
| 4 | 2s | 10 | 5s | 4 | 20s | 1 |
钻石产矿机
| 等级 | 间隔 | 数量 |
|---|---|---|
| 1 | 30s | 1 |
| 2 | 23s | 1 |
| 3 | 15s | 1 |
绿宝石产矿机
| 等级 | 间隔 | 数量 |
|---|---|---|
| 1 | 55s | 1 |
| 2 | 40s | 1 |
| 3 | 30s | 1 |
升级系统(预留)
当前 upgrade() 方法已实现基础功能:停止旧定时任务,加载新等级配置,重新启动定时任务。
升级接口:
// 升级指定类型的所有产矿机
generatorManager.upgradeAllByType(GeneratorConfig.TYPE_TEAM, 2);
// 升级单个产矿机
generator.upgrade(3);升级触发方式(商店购买、游戏事件等)尚未实现,仅预留方法签名。
扩展指南
添加新模式专属配置
- 在
generators/目录下创建新配置文件(如fast.yml) - 在新配置文件中添加
mode-mapping段(也可以在default.yml中添加):
# fast.yml
mode-mapping:
fast: "fast" # 定义 fast 模式使用本配置文件
generators:
team_generator:
# ... 更快的产出参数- 系统启动时会自动扫描所有配置文件,收集所有
mode-mapping定义 - 在
fast.yml中定义不同的产出参数(更短的间隔、更多的数量等)
添加新产矿机类型
- 在配置文件的
generators段添加新类型定义 - 在
GeneratorConfig中添加类型常量 - 在
GeneratorManager.loadGenerators()中添加加载逻辑 - 在编辑 UI 中添加对应的设置按钮
修改产出参数
直接编辑 generators/default.yml(或对应模式的配置文件),重启服务器或重载插件即可生效。无需修改代码。