Skip to content

JavaScript 脚本

EmakiLevel 通过 CoreLib 的脚本系统注册脚本模块,模块 ID 为 level。脚本中通过 emaki.module("level") 获取模块门面,用于查询等级类型与玩家等级、注册经验调整规则和升级钩子。

本页只介绍 EmakiLevel 专属的脚本方法、注册字段、上下文和示例。通用脚本机制请阅读 CoreLib JavaScript 脚本系统

调用任何业务方法前,先用 available() 守卫。EmakiLevel 是 CoreLib 的 softdepend。

获取模块

js
function main(ctx) {
  const level = emaki.module("level");
  if (!level.available()) {
    return { skipped: true, message: "EmakiLevel 不可用" };
  }
  // ...
  return true;
}

基础探针方法

方法返回说明
available()boolean模块是否可用。

EmakiLevel 模块门面只提供 available() 探针。

查询方法

方法返回说明
typeIds()list返回所有等级类型 id,已排序。
type(typeId)map返回单个类型详情;不存在时返回空 Map。
level(playerUuid, typeId)int玩家某类型当前等级;UUID 非法时返回 0。
exp(playerUuid, typeId)double当前经验;UUID 非法时返回 0。
totalExp(playerUuid, typeId)double累计总经验;UUID 非法时返回 0。
requiredExp(playerUuid, typeId, targetLevel)double升到目标等级所需经验;UUID 非法时返回 0。

playerUuid 必须是合法的 UUID 字符串,内部用 UUID.fromString 解析,失败即返回 0。

type(typeId) 返回的 Map 字段:iddisplayNamedescriptionprimaryenabledstartLevelmaxLevelautoUpgrademanualUpgradeattributes

经验规则

经验规则在玩家获得经验时执行,可以读取上下文并调整最终经验或取消本次获取。

方法返回说明
registerExpRule(definition)boolean注册一条经验规则。
registerExpRule(id, definition)boolean重载:把 id 合并进 definition 后注册。
unregisterExpRule(id)void按 id 注销规则。
registeredExpRules()list返回已注册经验规则 id 列表。

规则 definition 字段

字段类型必填默认说明
idstring规则唯一 id,会被规范化;为空注册失败。
priorityint0优先级,数值小者先执行;相同按 id 排序。
typeIdsstring / list空(全部类型)限定生效的等级类型,也可用 types
reasonsstring / list空(全部来源)限定生效的经验来源 reason。
functionstringmodifyExp规则回调函数名,也可用 execute
timeoutMillislong引擎默认超时单次脚本超时。

规则回调的 ctx 字段

字段类型说明
ruleIdstring当前规则 id。
playerUuidstring玩家 UUID。
typeIdstring等级类型 id。
reasonstring经验来源。
originalAmountdouble原始经验值。
currentAmountdouble当前累积修改后的经验值。
multiplierdouble当前倍率。
multipliedAmountdouble应用倍率后的经验值。
dailyLimitdouble当日经验上限。
gainedTodaydouble当日已获得经验。

规则回调的返回字段

返回字段类型说明
cancelbooleantrue 则本次经验置 0。
actualAmountamountnumber显式设定结果经验(取非负值,优先于 multiplier)。
multipliernumber否则用 当前值 × multiplier(取非负值)。
messagestring写入轨迹的消息。

返回非对象或执行失败时保持原值并记录轨迹。

升级钩子

升级钩子在玩家升级后触发,用于发奖励、播报等副作用。

方法返回说明
onLevelUp(definition)boolean注册一个升级钩子。
onLevelUp(id, definition)boolean重载:把 id 合并进 definition 后注册。
unregisterLevelUpHook(id)void按 id 注销升级钩子。
registeredLevelUpHooks()list返回已注册升级钩子 id 列表。

钩子 definition 字段

字段类型必填默认说明
idstring钩子唯一 id;为空注册失败。
typeIdsstring / list空(全部类型)限定触发的等级类型,也可用 type
functionstringonLevelUp回调函数名,也可用 execute
timeoutMillislong引擎默认超时单次脚本超时。

升级钩子无 priority 字段,多个钩子按 id 字典序依次触发。

钩子回调的 event 字段

字段类型说明
hookIdstring钩子 id。
playerUuidstring玩家 UUID。
playerNamestring玩家名。
typeIdstring等级类型 id。
oldLevelint升级前等级。
newLevelint升级后等级。
oldExpdouble升级前经验。
newExpdouble升级后经验。
causestring升级原因。
requiredExpdouble所需经验。

查询示例

EmakiLevel 自带触发型示例脚本 scripts/examples/level_status.js

js
function main(ctx) {
  const level = emaki.module("level");
  const typeIds = level.typeIds();
  const typeId = typeIds.size() > 0 ? typeIds.get(0) : "main";
  let currentLevel = 0;
  let currentExp = 0;
  if (emaki.player.exists() && typeId) {
    currentLevel = level.level(emaki.player.uuid(), typeId);
    currentExp = level.exp(emaki.player.uuid(), typeId);
    emaki.player.sendMessage("[EmakiJS] 等级模块状态: type=" + typeId + " level=" + currentLevel + " exp=" + currentExp);
  }
  return {
    success: true,
    output: {
      level_available: level.available(),
      type_count: typeIds.size(),
      sample_type: String(typeId || ""),
      current_level: currentLevel,
      current_exp: currentExp
    }
  };
}

注册示例

EmakiLevel 自带扩展型示例脚本 scripts/examples/level_exp_rule.js

js
function register() {
  const level = emaki.module("level");

  level.registerExpRule({
    id: "js_weekend_bonus",
    priority: 10,
    function: "modifyExp"
  });

  level.onLevelUp({
    id: "js_levelup_message",
    function: "onLevelUp"
  });
}

function modifyExp(ctx) {
  const day = new Date().getDay();
  if (day === 0 || day === 6) {
    return {
      multiplier: 2.0,
      message: "weekend bonus"
    };
  }
  return {};
}

function onLevelUp(event) {
  emaki.logger.info("Level up hook: " + event.playerName + " " + event.typeId + " " + event.oldLevel + " -> " + event.newLevel);
  return true;
}

启用扩展脚本

把脚本放到 CoreLib 的全局扩展目录后重载:

text
plugins/EmakiCoreLib/scripts/extensions/global/level_exp_rule.js
text
/corelib script reload

示例文件默认释放到 plugins/EmakiCoreLib/scripts/examples/,不会自动启用。

脚本调试

开启名为 script 的调试子模块后,EmakiLevel 的 JS 规则每次执行都会把逐条规则的执行轨迹(trace)输出到服务端控制台,便于服务器管理员调试脚本规则。

开启命令:

text
/elv debug module script

trace 输出字段:规则 idbefore(执行前值)、after(执行后值)、message。该输出位于服务端控制台,面向服务器管理员调试,不会发送给玩家。

注意事项

  • 所有注册方法都要求 CoreLib 脚本系统已启用,否则注册返回 false 或静默跳过。
  • CoreLib 缺失时模块自动降级,规则和钩子不生效但不会报错。
  • 经验规则按优先级升序执行(数值小者先)。