Skip to content

上一页:config.yml 详解 · 下一页:命令与权限

🗡️ 属性系统(原生属性 + 手把手自定义教程)

QCL 自带一套原生属性后端(native):不装任何属性插件(AttributePlus / MythicLib 等)也能用上攻击力、暴击、防御、闪避、元素伤害等全套属性与伤害结算。全生态(QI 物品 / QS 技能 / QC 职业 / QSt 强化 / QF 锻造)统一从 QCL 这一处读属性,分源叠加:物品、职业、宝石、套装各算一「源」,同名属性自动相加。

本页讲清三件事:属性是怎么组织的有哪些内置属性怎么从零写一个自己的属性(.yml + JS 脚本)


一、先记住:三个文件各管一摊(最容易搞混的点)

文件管什么改完
attributes.yml(插件根目录)功能:新增属性、大类、伤害类型、JS 钩子、上下限、战力权重/qcl reload
lang/zh_cn/attributes.yml显示:每个属性的显示名 display_name / 图标 prefix / 单位 suffix/qcl reload/qi refresh
lang/attributes.yml(根目录)基准层:图标 prefix / 单位 suffix 在这里写一次,对所有属性通用同上
elements.yml元素系统:每个元素自动生成「X伤害 / X增伤 / X抗性」三个属性/qcl reload

⚠️ 想改属性在物品上显示的名字 / 加资源包图标 → 去 lang/ 那一层,不是 attributes.ymlattributes.yml 只管「这个属性存在、它怎么参与战斗」;长什么样在 lang/

显示配置放哪

  • 显示名 display_name:在 lang/zh_cn/attributes.yml
  • 图标 prefix / 单位 suffix:在根 lang/attributes.yml 设一次即可,对所有属性通用。

加载时根 lang/attributes.yml 为基准,lang/zh_cn/attributes.yml 逐字段覆盖它(显示名以后者为准,图标/单位沿用基准)。


二、内置属性总表

内置属性已写死在代码里,无需在 attributes.yml 声明就能直接用(物品 / 职业 / 怪物上写它的英文 key 即可)。/qcl attr list 可在游戏内查看全部。

📌 概率类属性一律是 0~1 小数0.2 = 20%),不是整数百分比!显示层 suffix% 时,数值会自动 ×100(存 0.2 → 显示 20%),你存的时候别自己换算。

大类属性 key显示名说明
基础attack_damage攻击力映射原版近战攻击
基础attack_speed攻击速度映射原版攻速
物理physical_damage物理增伤(%)放大物理伤害
物理physical_crit_rate物理暴击率(%)max 1.0
物理physical_crit_damage物理爆伤(%)暴击倍率
物理armor_penetration护甲穿透
物理projectile_damage投掷物增伤(%)弓弩/投掷
法术magic_attack / magic_damage法术伤害 / 法术增伤(%)
法术magic_crit_rate / magic_crit_damage法术暴击率(%) / 法术爆伤(%)
法术magic_penetration法术穿透
技能skill_attack / skill_damage技能伤害 / 技能增伤(%)
技能skill_crit_rate / skill_crit_damage技能暴击率(%) / 技能爆伤(%)
真实true_attack / true_damage真实伤害 / 真伤增伤(%)穿透防御
环境pvp_damage / pve_damagePVP/PVE 伤害(%)对玩家/对怪
环境pvp_defense / pve_defensePVP/PVE 防御(%)
减伤defense防御自带 defense.js:100 防御≈减伤 50%
减伤damage_reduction伤害减免(%)max 0.9,自带脚本
减伤dodge闪避率(%)max 1.0,自带 dodge.js 几率免伤
减伤block_rate格挡率(%)自带 block.js
减伤parry招架率(%)自带 parry.js
减伤crit_resist暴击抗性(%)max 1.0
减伤armor / armor_toughness护甲值 / 护甲韧性映射原版
减伤knockback_resistance击退抗性(%)映射原版
资源health生命映射原版 max_health
资源health_regen生命恢复
资源max_mana / mana_regen最大法力 / 法力恢复供 QS/QC 法力池
资源max_stamina / stamina_regen最大耐力 / 耐力恢复
通用movement_speed / max_absorption / luck移动速度 / 最大吸收 / 幸运映射原版
杂项lifesteal生命偷取(%)自带 lifesteal.js
杂项spell_vampirism / reflection法术吸血(%) / 伤害反弹(%)
杂项cooldown_reduction / exp_bonus / loot_bonus / money_bonus冷却缩减/经验/掉落/金币加成(%)
杂项attack_knockback攻击击退映射原版

元素属性(火/水/雷/风/土/金/木/光…)由 elements.yml 驱动,每个元素自动生成 <元素>伤害 / <元素>增伤 / <元素>抗性,详见第六节

查询命令

命令作用
/qcl attr list列出全部已注册属性(按大类分组)
/qcl attr show [玩家]查看玩家当前属性合计(分源后的总值)
/qcl attr debug开关「命中伤害溯源」,每次打/被打都打印属性结算过程
/qcl attr book打开属性面板书本
/qcl mobattr <key> <值>给你看向的怪物设置属性(测试自定义属性的最快方式

/qcl attr book 属性面板书


三、手把手教程:写一个自己的属性

下面三个场景由易到难。全程不用改源码、不用重启,写完 /qcl reload 即生效。

场景 A:纯映射原版属性(最简单,零脚本)

想要一个「迅捷」属性,本质就是原版移动速度。只需在 attributes.yml 加:

yaml
attributes:
  swiftness:
    display: 迅捷
    vanilla: movement_speed   # 映射到原版移速,QCL 自动走原版 AttributeModifier

/qcl reload → 完事。现在任何物品/职业写 swiftness 就能加移速。能映射的原版键:max_health movement_speed armor armor_toughness attack_speed attack_damage knockback_resistance luck max_absorption 等。

场景 B:带 JS 效果的属性(完整范例 · 荆棘反伤)

目标:「荆棘」——受到伤害时把一部分反弹给攻击者。需要 3 个文件 配合。

步骤 1️⃣ 写 JS 脚本

新建 plugins/QinhCoreLib/scripts/attributes/thorns.js

javascript
// 触发钩子:on_damage_taken —— 玩家受到伤害时
// 可用变量:
//   ctx.get("damage")          当前伤害值
//   ctx.get("value")           玩家荆棘总值(0~1,0.2 = 反弹 20%)
//   ctx.get("attacker")        攻击者实体(可能为 null,如摔落/火焰)
//   qcl.damage(entity, amount) 对实体造成伤害
function onDamageTaken() {
    var damage   = ctx.get("damage");
    var thorns   = ctx.get("value");
    var attacker = ctx.get("attacker");
    if (thorns > 0 && damage > 0 && attacker) {
        qcl.damage(attacker, damage * thorns);  // 把伤害的 thorns 比例反弹回去
    }
    return damage;   // 不改自己受到的伤害,原样返回
}

💡 脚本必须 return 一个数值(处理后的伤害)。on_damage_dealt / on_damage_taken 的返回值会成为新的伤害;不想改伤害就 return ctx.get("damage")

步骤 2️⃣ 在 attributes.yml 注册它

yaml
attributes:
  thorns:
    display: 荆棘           # 显示名(也可只在 lang/ 配,见步骤 3)
    category: 减伤          # /qcl attr list 的分组
    order: 100             # 钩子执行顺序,越小越先;反伤/吸血建议靠后
    hooks:
      on_damage_taken: qinhcorelib:attributes/thorns.js:onDamageTaken

引用格式固定为 qinhcorelib:attributes/<文件名>.js:<函数名>

步骤 3️⃣ 配显示(可选,但建议)

lang/zh_cn/attributes.yml 加:

yaml
thorns:
  display_name: "荆棘"
  prefix: ""        # 资源包 16px 贴图字符,想要图标就填这里
  suffix: "%"       # 带 % → 数值自动 ×100:存 0.2 显示 20%

步骤 4️⃣ 重载

/qcl reload

步骤 5️⃣ 把属性给到玩家测试

属性本身只是「定义」,要生效得有来源带上它。三种常见来源:

  • QI 物品:物品 providers.ap.value 的 JSON 里写英文 key,例如 {"thorns":0.2}(20% 反弹)。
  • QC 职业classes.ymlstats: 块写 thorns: { base: 0.1, per-level: 0.005 }
  • 快速测试(怪物):看向一只怪 → /qcl mobattr thorns 0.5 → 让它打你,看是否反伤。

验证:/qcl attr show 看自己身上的 thorns 合计;/qcl attr debug 打开后每次受击会打印结算过程。

自定义属性「荆棘」生效

场景 C:覆盖内置属性(改名 / 加图标,英文 key 不变)

想把「物理暴击率」在物品上显示成「暴击」并挂个资源包图标——不用动 key,只在 attributes.yml 写你要改的字段,其余(大类/伤害类型/战力)自动继承内置:

yaml
attributes:
  physical_crit_rate:
    display: 暴击
    prefix: ""        # 你资源包里的 16px 贴图字符

英文 key 永远是 physical_crit_rate(物品/职业照常用它),只是显示变了。这点和 MMOItems 一致。


四、attributes.yml 字段全表

字段作用默认
display显示名(也可在 lang/ 配,更推荐)= key
prefix显示名前缀(一般放资源包 16px 贴图字符 \uXXXX
category所属大类(用于 /qcl attr list 与属性 GUI 分组,可自定义新大类)杂项
vanilla映射的原版属性键(配了就走原版 AttributeModifier)
type伤害类型 physical / magic / skill / true(大类增伤属性用)
mitigation是否「减伤类」(true 时会被真实伤害穿透,如防御/伤害减免)false
combat-power战斗力权重(玩家战力 = Σ 属性值 × 权重)1.0
min / max数值上下限钳制(平衡工具,如概率类 max: 1.0无限制
message触发时给玩家的战斗提示(支持 {damage} {value} 占位)
order钩子执行顺序,越小越先(暴击=10,反伤/吸血建议 100)
hooksJS 钩子:事件名 → 脚本引用

钩子事件表

事件名触发时机脚本返回值
on_damage_dealt玩家造成伤害时新的伤害值
on_damage_taken玩家受到伤害时新的伤害值
on_kill击杀实体时
on_tick每 20 tick(需 QI 在装备扫描末尾调 refreshEquipHooks
on_equip装备带该属性的物品时
on_unequip卸下时

脚本里可用的接口

ctx = 当前上下文,qcl = 工具 API:

调用作用
ctx.get("damage")当前伤害值(已含暴击等前序钩子结果)
ctx.get("value")当前属性的玩家总值(已分源聚合)
ctx.get("attacker") / ctx.get("victim")攻击者 / 受害者实体(可能为 null)
ctx.get("<任意属性key>")读玩家任意其它属性的值
ctx.set(key, value)写上下文值
qcl.heal(amount)治疗自己(自动钳到最大生命)
qcl.damage(entity, amount)对实体造成伤害
qcl.addPotion(entity, "SLOWNESS", ticks, amplifier)施加药水效果
qcl.placeholder(text) / qcl.logInfo(msg) / qcl.itemGive(ref, amount)解析 PAPI / 打日志 / 发物品

内置范例脚本就在 scripts/attributes/thorns.js(反伤)、lifesteal.js(吸血)、defense.js(减伤曲线)、dodge.js(闪避)、block.jsparry.jsdamage_reduction.jscritical_rate.js。直接照抄改即可。


五、属性后端可切换

config.ymlattribute.backend

含义
native(默认)QCL 自带原生属性后端,无需任何属性插件
attributeplus改用 AttributePlus 接管属性(需装 AP,由 QinhItems 注册)
auto有可用第三方属性后端则优先用它,否则回退 native

全生态统一从这里读后端,无需各插件各配。改完 /qcl reload


六、元素系统

elements.yml:每个元素自动生成 3 个属性(/qcl attr list 可见、物品/职业可声明):

  • <元素>伤害:flat,加在你攻击上的该元素伤害
  • <元素>增伤:%,放大该元素伤害
  • <元素>抗性:%,减免受到的该元素伤害(0~1)

结算公式元素伤害 = Σ( <元素>伤害 × (1+<元素>增伤) × (1-目标<元素>抗性) × 相克倍率 )。元素伤害穿透物理防御/减伤,但被对应元素抗性减免,且吃闪避/格挡/招架。

相生相克(五行)restrains 列出「我克谁」。克之 ×restraint-bonus(默认 1.5),被克 ×(2-bonus),无关 ×1。目标的「本命元素」= 它抗性最高的那个元素。

yaml
restraint-bonus: 1.5
elements:
  fire:
    name: 
    color: "&c"
    restrains: [metal]   # 火克金
  # ……可自由增删元素 / 改相克

七、常见坑

  • 概率写成了整数:暴击率/闪避要写 0~1 小数(0.3 = 30%),写 30 会被 max: 1.0 钳成 100%。
  • 改显示名改错文件:显示名/图标在 lang/<语言>/attributes.yml,不是根 attributes.yml
  • suffix 双重换算suffix% 已自动 ×100,别再自己乘。
  • 脚本不返回值on_damage_* 脚本必须 return 一个数;漏了会让伤害变 undefined
  • 改了没生效attributes.yml/脚本改完要 /qcl reload;物品显示要再 /qi refresh 重渲。
  • 元素抗性方向:抗性是「减免受到的」,本命元素由抗性最高项决定——给怪堆高某元素抗性会让它「本命」变成那个元素。