Skip to content

脚本系统

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 内置对象

脚本中可以直接使用以下对象:

对象类型说明
playerPlayer触发者(等同于 trigger
triggerPlayer触发者
dungeonDungeonInstance当前副本实例
actionActionWrapper动作调用入口

内置函数:

函数说明
getVar(name)获取变量值(不存在返回 0
setVar(name, value)设置变量
log(message)输出日志到控制台
parseTime(str)时间字符串转 tick 数

dungeon 对象方法

dungeon 是当前副本实例,可以在脚本中读取副本状态:

方法/属性返回类型说明
dungeon.runningTimeLong副本已运行时间(秒)
dungeon.statusString当前状态(PREPARING / ACTIVE / COMPLETED / FAILED / CANCELLED)
dungeon.isTimeoutBoolean是否已超时
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.idString地牢模板 ID
dungeon.template.nameString地牢显示名称
dungeon.template.timeLimitInt时间限制(秒)
dungeon.worldWorld副本世界对象(Bukkit World)
dungeon.startTimeLong开始时间戳(毫秒)
dungeon.partyParty?队伍对象(无队伍时为 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

基于 MIT 许可发布