主题
HNAttribute 的属性系统可以用一句话概括:
先把装备、Buff、外部来源统一成属性修饰符,再按 source 分组管理,最后进入战斗、显示、原版同步等后续流程。
这页会帮你建立对整个属性系统的全局理解,让你清楚地知道属性是如何从装备上读取、如何计算、如何生效的。
一、属性系统的核心流程
整个属性系统的工作流程是:
- 读取层: 从 Lore、PDC、NBT 等来源识别属性
- 来源管理: 按
source分组管理所有修饰符 - 属性计算: 合并所有来源,计算最终属性值
- 应用层: 进入战斗、显示、原版同步等系统
二、什么是属性修饰符
属性修饰符是 HNAttribute 里最基础的概念。你可以把它理解成"一条属性变化记录"。
一个修饰符包含四个核心信息:
- 属性 ID: 要修改哪个属性,例如
attack_damage(攻击力)、max_health(最大生命值) - 操作类型: 用什么方式修改,是直接加(
ADD)、基础乘法(MULTIPLY_BASE)还是总值乘法(MULTIPLY_TOTAL) - 数值: 具体的增减量,比如 +120 或 +50%
- 来源: 这个修饰符从哪里来,比如主手武器、某个 Buff、或者任务奖励
举个例子,当你装备一件武器,上面写着"攻击力: 120",系统会把它转换成:
- 属性 ID:
attack_damage - 操作:
ADD(加法) - 数值:
120 - 来源:
equipment:mainhand(主手装备)
这样系统就知道:"主手武器给玩家增加了 120 点攻击力"。
三、什么是 source (来源)
source 是整个属性系统里最重要的概念之一。你可以把它理解成"属性的身份证"。
为什么需要来源?因为系统需要知道每个属性值是从哪里来的,这样才能:
- 在你换装备时,精确删除旧装备的属性
- 在 Buff 结束时,准确移除 Buff 带来的属性
- 让你用命令查看"这个属性到底是哪些东西加起来的"
所有修饰符都会按 source 分组管理,常见的来源包括:
装备来源
equipment:mainhandequipment:offhandequipment:helmetequipment:chestplateequipment:leggingsequipment:boots
Buff 来源
buff:力量提升buff:钢铁护体
自定义来源
custom:quest-rewardcustom:artifact-bonus
属性映射来源
mapping:strengthmapping:vitality
source 的价值
通过 source 系统,你可以:
- 追踪属性来源: 用
/hnattr source命令查看所有正在生效的来源 - 精确管理属性: 换装备时只删除旧装备的属性,不影响 Buff 和其他来源
- 快速排查问题: 用
/hnattr trace <属性ID>查看某个属性是由哪些来源组成的
举个例子:
- 你装备了一把武器,获得 100 攻击力 → 来源是
equipment:mainhand - 你又吃了一个力量 Buff,获得 50 攻击力 → 来源是
buff:力量提升 - 你换了另一把武器,获得 150 攻击力 → 系统会删除旧的
equipment:mainhand来源,添加新的 - 这时你的总攻击力是 150(新武器) + 50(Buff) = 200,而不是 100 + 50 + 150 = 300
四、属性的三种操作类型
ADD (加法)
最常用的操作类型,直接增加数值。
示例:
装备攻击力: 100 (ADD)
→ 最终攻击力 = 100MULTIPLY_BASE (基础乘法)
对基础值进行百分比加成。多个 MULTIPLY_BASE 之间是加法叠加。
示例:
装备: 100 (ADD)
Buff1: 50% (MULTIPLY_BASE)
Buff2: 30% (MULTIPLY_BASE)
计算: 100 × (1 + 0.5 + 0.3) = 180MULTIPLY_TOTAL (总值乘法)
对最终值进行百分比加成,在所有计算的最后阶段应用。
示例:
装备: 100 (ADD)
Buff1: 50% (MULTIPLY_BASE)
Buff2: 20% (MULTIPLY_TOTAL)
计算:
1. 基础值: 100
2. 应用 MULTIPLY_BASE: 100 × 1.5 = 150
3. 应用 MULTIPLY_TOTAL: 150 × 1.2 = 180计算顺序
1
收集所有 ADD→得到基础值
2
应用所有 MULTIPLY_BASE(百分比相加)→得到中间值
3
应用所有 MULTIPLY_TOTAL(逐个相乘)→得到最终值
更详细的说明请参考: Buff 系统与修饰符
五、属性映射与派生
属性映射允许你定义"主属性"到"战斗属性"的转换。
例如:
strength(力量) →attack_damage(攻击力)vitality(体质) →max_health(最大生命值)vitality(体质) →health_regen(生命恢复)
这样玩家只需要关注"力量"、"体质"等主属性,系统会自动计算出战斗属性。
一层映射:最常见的用法
最常见的是一层映射,也就是:
text
主属性 → 最终属性比如:
text
力量 → 攻击力
体质 → 最大生命值为什么要用映射?
假设你想让玩家通过"力量"属性来提升攻击力,如果不用映射,你需要:
- 在每件装备上都写"攻击力: XXX"
- 玩家升级时手动调整所有装备的攻击力
但如果用映射,你只需要:
- 在装备上写"力量: 10"
- 配置"每 1 点力量 = 2 点攻击力"
- 系统会自动计算:10 力量 = 20 攻击力
这样配置更简单,调整数值也更方便。适合简单服,配置直观,调试也最省心。
链式派生:把成长拆成多层
如果你看到 Wiki 里提到"链式派生",不要被这个名字吓到。
它本质上只是:
text
A → B → C也就是多个普通映射串起来。
例如:
text
智力 → 法术强度 → 魔法伤害
智力 → 神圣亲和 → 治疗强度
智力 → 召唤精通 → 宠物伤害为什么要这样做?
假设你在做一个法师职业系统:
- 法师的智力会影响魔法伤害、治疗强度、宠物伤害
- 但你希望法师可以选择专精方向:
- 元素专精:智力更多地转化为魔法伤害
- 神圣专精:智力更多地转化为治疗强度
- 召唤专精:智力更多地转化为宠物伤害
如果直接用一层映射,你只能让智力同时影响所有三个属性,无法做专精差异。
但如果用链式派生:
- 上层(角色成长): 智力 → 法术强度、神圣亲和、召唤精通
- 中层(职业专精): 不同专精对中间层属性有不同加成
- 下层(最终效果): 法术强度 → 魔法伤害,神圣亲和 → 治疗强度,召唤精通 → 宠物伤害
这样做的好处是:
- 你可以让多个最终属性共用同一个中间层
- 你可以单独调整中间层,而不用把所有最终公式重写一遍
- 更容易做职业差异化成长,而不是所有职业都直接吃同一套最终属性
你可以把它理解成:
映射是在"把一个属性换算成另一个属性";链式派生是在"把一条成长路径拆成几段,各段各管各的"。
什么时候用?
- 如果你只是想快速做一套属性,先用一层映射就够了
- 如果你要做职业分化、专精成长、复杂平衡,再考虑链式派生
更完整的配置示例和实战说明,可以继续看:如何注册属性。
六、伤害通道声明
属性可以通过 channel 和 channel-role 字段声明自己属于哪个伤害通道。这是 v1.6.0 管线系统的核心机制。
yml
attack_damage:
display: "&c攻击力"
names: ["攻击力", "物理伤害"]
default: 1.0
channel: physical
channel-role: damage
defense:
display: "&9防御力"
names: ["防御力", "防御"]
default: 0.0
channel: physical
channel-role: resistchannel
声明这个属性属于哪个伤害通道。例如 physical、fire、ice、thunder。
channel-role
声明这个属性在通道中的角色:
| channel-role | 含义 | 示例 |
|---|---|---|
damage | 伤害来源值 | attack_damage, fire_damage |
resist | 抗性值 | defense, fire_resistance |
penetration_flat | 固定穿透 | physical_penetration_flat |
penetration_rate | 百分比穿透 | physical_penetration_rate |
工作原理
当战斗管线执行 collect_channels Stage 时,系统会自动扫描攻击者身上所有 channel-role=damage 且值 > 0 的属性,收集出本次攻击涉及的伤害通道。
一次攻击可以产出多个伤害通道。例如一把"火焰剑"同时有 attack_damage(physical 通道)和 fire_damage(fire 通道),攻击时会同时产出物理伤害和火焰伤害。
更多细节参考:伤害类型与战斗管线
七、属性的读取方式
HNAttribute 支持多种属性读取方式:
Lore 读取
最常见的方式,从物品的 Lore 中读取属性。
text
攻击力: 120
攻击速度: 15%
最大生命值: 60PDC 读取
从 PersistentDataContainer 中读取结构化数据。
NBT 读取
从原始 NBT 标签中读取属性。
条件系统
支持在属性行后面带条件:
text
攻击力: 100/Lv.10,权限: vip八、属性的自动刷新
当玩家进行以下操作时,属性会自动刷新:
- 切换主手/副手
- 点击/拖拽背包
- 关闭背包
- 丢弃/捡起物品
- 加入服务器
刷新时,插件会:
- 移除旧的槽位来源
- 读取新的物品结果
- 按对应 source 写回系统
九、最重要的调试命令
查看物品属性
text
/hnattr inspect查看手持物品被读取到的属性。
查看最终属性
text
/hnattr lookup查看自己当前的最终属性值。
查看所有来源
text
/hnattr source查看所有正在生效的属性来源。
追踪单个属性
text
/hnattr trace <属性ID>查看某个属性由哪些修饰符组成。
十、这一页最该记住的重点
- 属性系统的核心是"修饰符 + source 管理"
- 所有属性来源(装备、Buff、外部注入)都会转换成修饰符
source是整个系统的核心标识,用于精确管理和删除- 属性映射允许主属性自动派生战斗属性
- 属性通过
channel+channel-role声明伤害通道归属 - 调试属性问题的起手式是
/hnattr inspect和/hnattr trace
