Skip to content

词缀脚本(JS)

所属:开发者 · 同组:事件大全 · Provider 与桥接 相关:词缀系统 · 秘境与钥石

声明式词缀(数量 / 等级 / 环境 / 状态 / 战利品)配不出来的复杂效果,可以下沉到 JS 脚本词缀。引擎复用 QinhCoreLib 的 GraalJS(与 QS 同一套运行时)。本页讲引用格式、ctx 上下文、降级行为,并给完整示例。

🔑 架构红线:脚本是给词缀加「世界 / 玩家交互」效果(上药水、发物品、发钱、加属性),不是让 QR 自己算伤害。它跟词缀其他类别一样,受危险预算约束。


1. 在 affixes.yml 里挂脚本

词缀的 effect.type 设为 script,用 script 指向脚本里的函数:

yaml
affixes:
  blood_ritual:
    name: "§4血祭"
    lore: ["§7秘境激活时降下血之考验"]
    category: ENV
    danger: 25            # 危险值(受 realm.tiers.danger-budget 约束)
    reward: 20
    min-tier: 3
    effect:
      type: script                                   # ★ 用脚本作为效果
      script: "qinhruins:affix_example.js:onActivate" # 命名空间:文件:函数

引用格式

qinhruins:路径.js[:函数名]
说明
qinhruins:命名空间前缀(QR 启动时 RuinScriptBridge.register 向 QCL 注册到此命名空间)
路径.js相对 QR 脚本目录 plugins/QinhRuins/scripts/ 的文件路径
:函数名可选;指定调用文件里的某个函数。省略则调用约定的默认函数(示例文件里是 main

脚本文件放在 plugins/QinhRuins/scripts/,首次启动会自动释放示例 affix_example.js


2. 触发时机

脚本在 秘境激活的那一瞬间,对当时 在场的每位玩家各执行一次onActivate(ctx) 收到的 ctx.player() 是当前这名玩家)。这是 fire-and-forget:抛异常只记日志,不影响秘境激活本身。


3. 两个全局对象:ctxqcl

GraalJS 运行时给脚本绑定 两个 全局对象(由 CoreLib QinhScriptApi 提供):

  • ctx —— 只读上下文:拿玩家、读注入变量。
  • qcl —— 动作 API:发物品、上药水、加属性、发钱、打日志、切线程等。

注意

常见误区:动作方法挂在 qcl 上,不是 ctxctx 只有 player() / get() / set() / vars()。写成 ctx.itemGive(...) 会因方法不存在而报错。

ctx —— 上下文(读变量)

脚本可读变量只有三个(由秘境运行时注入):

调用含义
ctx.player()当前玩家(Bukkit Player,可能为 null,需判空)
ctx.get("tier")秘境层数(Int)
ctx.get("affix")当前词缀 id(String)
ctx.get("danger")当前词缀危险值(Int)

只有这三个键(tier / affix / danger)。不存在 skilllevelvar_* 等 —— 那些是 QinhSkills 脚本的键,QR 不注入。

qcl —— 动作 API

调用作用
qcl.itemGive(ref, amount)给当前玩家物品;ref 支持 minecraft:qinhitems:mythicmobs:qinhruins: 等前缀
qcl.addPotion(目标, 类型, tick, 等级)给目标上药水效果(类型为 Bukkit PotionEffectType 名,如 "SPEED"
qcl.heal(n)给当前玩家回血
qcl.damage(目标, n)对目标造成伤害
qcl.buff(目标, key, 值, 运算, tick, 来源)CoreLib 属性增益(运算如 FLAT / RELATIVE / MULTIPLY,来源用于分源叠加)
qcl.economyDeposit(n, provider, currency)发货币(另有 economyHas / economyWithdraw
qcl.runSyncLater(tick, function)延迟若干 tick 后在 主线程 执行回调(另有 runSync / runSyncAndWait
qcl.logInfo(msg)打信息日志(另有 logWarn / logError

注意

脚本可能在异步语境调用。任何动世界 / 实体的操作(传送、改方块、生成实体等)务必包进 qcl.runSyncLater(0, ...) 切回主线程,否则可能抛线程异常。上药水 / 发物品 / 发钱这些 qcl 动作方法已自行处理线程。


4. 完整示例

QR 首次启动会在 plugins/QinhRuins/scripts/ 释放一份示例 affix_example.js。下面是 可直接运行 的写法(读变量用 ctx,做动作用 qcl):

javascript
function onActivate(ctx) {
    var player = ctx.player();
    if (!player) return;

    var tier = ctx.get("tier") || 1;
    var amp = Math.min(tier, 5) - 1;          // 层数越高,增益越强

    // 给玩家上「迅捷」30 秒,等级随层数
    qcl.addPotion(player, "SPEED", 20 * 30, amp);

    // 高层额外奖励一个金苹果
    if (tier >= 5) {
        qcl.itemGive("minecraft:golden_apple", 1);
    }

    player.sendMessage("§4[血祭] §7秘境注入了 §cT" + tier + " §7之力……");
    qcl.logInfo("[QR词缀] " + player.getName() + " 触发脚本词缀 T" + tier);
}

// 默认函数:引用里不写 :函数名 时调用 main
function main(ctx) {
    onActivate(ctx);
}

提示

牢记前缀分工:读数据用 ctxplayer() / get()),做动作用 qclitemGive / addPotion / …)。写成 ctx.itemGive(...) 会因方法不存在而报错。

引用方式:

  • qinhruins:affix_example.js:onActivate —— 显式调 onActivate
  • qinhruins:affix_example.js —— 省略函数名,调 main

5. 降级(引擎不可用时)

QR 经 反射 桥接 QCL 的 QinhScriptBridge。GraalJS 运行时未就绪时,脚本词缀 静默跳过(打一条 warning,不影响秘境其他词缀生效):

[QR-JS] GraalJS 未就绪,跳过词缀脚本 ref=qinhruins:affix_example.js:onActivate
        (需 CoreLib 拉到 GraalJS 且 javascript.enabled=true)

GraalJS 需要 Paper / Purpur 运行时拉到 GraalJS 库且 javascript.enabled=true。如果你的脚本词缀没生效,先查这条日志。


6. 何时用脚本、何时用声明式词缀

需求
刷怪 ×N / 怪等级 +N / 禁疗 / 限时 / 缓慢虚弱 / 贪婪鎏金等声明式词缀(无引擎依赖,见 词缀系统
按层数发不同物品 / 发钱 / 加临时属性 / 复杂分支type: script JS 词缀

声明式优先 —— 零引擎依赖、永不降级。


下一步