主题
脚本系统
QueDP 使用 GraalJS 引擎执行 JavaScript 脚本,支持 ES6+ 语法和 async/await。
脚本编写位置
脚本写在地牢配置文件的对应字段中:
| 文件 | 用途 |
|---|---|
scripts.yml | 生命周期脚本(on_start / on_end) |
monsters.yml | 怪物组的开始/完成脚本 |
obstacles.yml | 障碍物的创建/删除/触发脚本 |
interacts.yml | 交互点的触发脚本 |
tasks.yml | 定时/循环/事件任务脚本 |
函数库
在地牢文件夹中放置 .js 文件,会被自动加载为函数库,所有脚本中都可以直接调用:
dungeons/my_dungeon/
├── functions.js
├── scripts.yml
└── ...javascript
// functions.js
function announceWave(waveNum) {
action.title('@all', '&c第 ' + waveNum + ' 波', '&7消灭所有怪物!')
action.sound('@all', 'ENTITY_ENDER_DRAGON_GROWL')
}yaml
# scripts.yml
脚本:
- "announceWave(1)"TIP
函数库中的 function 声明会自动转换为 async function,内部可以使用 await。
JS 内置对象
脚本中可以直接使用以下对象:
| 对象 | 类型 | 说明 |
|---|---|---|
player | Player | 触发者(等同于 trigger) |
trigger | Player | 触发者 |
dungeon | DungeonInstance | 当前副本实例 |
action | ActionWrapper | 动作调用入口 |
内置函数:
| 函数 | 说明 |
|---|---|
getVar(name) | 获取变量值(不存在返回 0) |
setVar(name, value) | 设置变量 |
log(message) | 输出日志到控制台 |
parseTime(str) | 时间字符串转 tick 数 |
dungeon 对象方法
dungeon 是当前副本实例,可以在脚本中读取副本状态:
| 方法/属性 | 返回类型 | 说明 |
|---|---|---|
dungeon.runningTime | Long | 副本已运行时间(秒) |
dungeon.status | String | 当前状态(PREPARING / ACTIVE / COMPLETED / FAILED / CANCELLED) |
dungeon.isTimeout | Boolean | 是否已超时 |
dungeon.getOnlinePlayerCount() | Int | 当前在线玩家数 |
dungeon.getAlivePlayerCount() | Int | 存活玩家数(在线且未死亡) |
dungeon.getDeadPlayerCount() | Int | 当前死亡玩家数 |
dungeon.getPlayers() | Set | 所有在线玩家对象集合 |
dungeon.hasPlayer(player) | Boolean | 指定玩家是否在副本中 |
dungeon.isPlayerCurrentlyDead(player) | Boolean | 指定玩家是否处于死亡状态 |
dungeon.getKills(player) | Int | 指定玩家的击杀数 |
dungeon.getDeaths(player) | Int | 指定玩家的死亡数 |
dungeon.getTotalMobKills() | Int | 副本总怪物击杀数 |
dungeon.getMobKillCount(mobType) | Int | 指定怪物类型的击杀数(MythicMobs ID) |
dungeon.getSpawnedMobs() | List | 当前存活的怪物实体列表 |
dungeon.isSpawnedMob(entity) | Boolean | 实体是否是副本生成的怪物 |
dungeon.template.id | String | 地牢模板 ID |
dungeon.template.name | String | 地牢显示名称 |
dungeon.template.timeLimit | Int | 时间限制(秒) |
dungeon.world | World | 副本世界对象(Bukkit World) |
dungeon.startTime | Long | 开始时间戳(毫秒) |
dungeon.party | Party? | 队伍对象(无队伍时为 null) |
示例:
javascript
// 根据存活人数调整难度
if (dungeon.getAlivePlayerCount() <= 1) {
action.message('@all', '&c最后一人!怪物减弱!')
}
// 检查特定怪物击杀数
if (dungeon.getMobKillCount('Elite_Guard') >= 3) {
action.spawn_group('boss')
}
// 获取运行时间做判断
let time = dungeon.runningTime
if (time > 600) {
action.message('@all', '&e已经过去 10 分钟了...')
}选择器
Action 的第一个参数可以是选择器,指定目标玩家:
| 选择器 | 中文别名 | 说明 |
|---|---|---|
@all / @a | @所有玩家 | 副本中所有玩家 |
@trigger / @p | @触发者 | 触发脚本的玩家 |
@party | @队伍 | 队伍成员 |
@others | @其他玩家 | 除触发者外的所有玩家 |
@party_others | @队友 | 队伍内除触发者外的玩家 |
@nearest | @最近 | 距离触发者最近的其他玩家 |
@random / @r | @随机 | 随机一个玩家 |
字符串占位符
Action 参数中的 {变量名} 会被自动替换为对应值。
注意区分
JS 对象 player(上面的内置对象)和占位符 {player.name} 是两套东西:
- JS 对象
player始终是触发者,用于脚本逻辑(if (player.getHealth() < 10)) - 占位符
{player.name}跟随选择器目标,用于 action 参数的文本替换
玩家占位符(跟随选择器目标)
| 占位符 | 中文 | 说明 |
|---|---|---|
{player.name} | {玩家.名字} | 当前目标玩家的名字 |
{player.level} | {玩家.等级} | 当前目标玩家的等级 |
{player.health} | {玩家.血量} | 当前目标玩家的血量 |
{player.kills} | {玩家.击杀数} | 当前目标玩家的击杀数 |
{player.deaths} | {玩家.死亡数} | 当前目标玩家的死亡数 |
触发者占位符(始终是触发者)
| 占位符 | 中文 | 说明 |
|---|---|---|
{trigger.name} | {触发者.名字} | 触发脚本的玩家名字 |
地牢占位符
| 占位符 | 中文 | 说明 |
|---|---|---|
{dungeon.time} | {地牢.时间} | 运行时间(秒) |
{dungeon.players} | {地牢.玩家数} | 当前玩家数 |
{total_kills} | {总击杀} | 总怪物击杀数 |
特殊占位符
| 占位符 | 说明 |
|---|---|
{random:1-100} | 1 到 100 的随机整数 |
{random:苹果,香蕉,橙子} | 从列表中随机选一个 |
{自定义变量名} | 通过 setVar 设置的变量 |
{player.level * 2} | 含运算符的表达式会自动求值 |
player 与 trigger 的区别
javascript
// 每个玩家看到自己的名字
action.message('@all', '你好,{player.name}!')
// 所有人看到触发者的名字
action.message('@all', '{trigger.name} 触发了机关!')
// 有选择器:控制台对每个玩家各执行一次
action.command('@all', 'give {player.name} diamond 1')
// 无选择器:{player.name} 回退到触发者,执行一次
action.command('give {player.name} diamond 1')async/await
action.wait() 和 action.wait_clear() 是异步操作,会自动 await:
javascript
action.message('@all', '3秒后开始')
action.wait('3s')
action.message('@all', '战斗开始!')
action.spawn_group('wave_1')
action.wait_clear('wave_1')
action.message('@all', '第一波已清除')动作分类
- 消息类 — message / title / actionbar
- 玩家类 — teleport / give_item / heal / gamemode 等
- 特效类 — sound / particle / lightning / firework / bossbar
- 地牢类 — complete / fail / spawn_group / grant_reward 等
- 世界类 — world_time / weather / setblock / explosion / gamerule
- 战斗类 — potion / damage / absorption / velocity 等
- 流程控制 — wait / wait_clear
- 工具类 — set_var / command / player_command / freeze
- NPC 类 — spawn_npc / npc_talk / npc_walk / npc_follow / npc_equip / npc_shop / npc_choice / npc_quest / track_task / complete_task
