ZZZ-Plugin/model/damage/README.md
2025-09-09 00:49:19 +08:00

546 lines
No EOL
24 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 评分权重自定义
## 方法一:预设方法(推荐)
### 基础步骤
1. 复制模板文件:[ZZZ-plugin/model/damage/character/模板/score.js](./character/模板/score.js)
2. 进入角色数据文件夹:[ZZZ-plugin/model/damage/character/角色名](./character/)
3. 粘贴文件,并将粘贴的模板文件重命名为**score_user.js**
4. 打开**score_user.js**,根据需要调整权重数值
5. 保存并重启
示例图(“冰属性伤害加成”可简写为“属性伤害加成”):
<p align="center">
<img width=800 src="https://s2.loli.net/2025/06/01/aTyPoZ4gi89MqRC.jpg" title="词条权重自定义基础步骤">
</p>
### 进阶操作
> 将崽底层日志模式切换为**debug**模式,可在控制台查看评分计算详细过程;且会自动监听现有评分计算文件实时热更新。可按需开启
在函数体中,可根据玩家角色数据**动态选用**不同的权重方案。示例(原爱丽丝直伤流规则):
```js
/** @type {import('../../avatar.ts')['scoreFnc'][string]} */
export default function (avatar) {
const { CRITRate, CRITDMG, AnomalyProficiency } = avatar.initial_properties
// (暴击率 * 2 + 爆伤 >= 200%) 且 (异常精通 < 300) 时转为直伤流规则
if (CRITRate * 2 + CRITDMG >= 2 && AnomalyProficiency < 300) {
return ['直伤流', {
"生命值百分比": 0,
"攻击力百分比": 0.75,
"防御力百分比": 0,
"冲击力": 0,
"暴击率": 1,
"暴击伤害": 1,
"穿透率": 1,
"穿透值": 0.25,
"能量自动回复": 0,
"异常精通": 0.5,
"异常掌控": 0,
"属性伤害加成": 1
}]
}
}
```
- 函数参数:[ZZZAvatarInfo](../avatar.js#L173)(角色数据)
- 函数返回值:
- 元组:[评分规则名, 权重数据]
- 类型:**[string, { [词条名: string]: number }]**
- 若返回其他类型,会自动选择默认评分规则
- 自定义权重会以默认权重为基础值,即**自定义权重中未指定的词条会取默认权重中的数据**
## 方法二:直接修改默认权重
> 注意:直接修改插件所属文件,将会导致后续该文件更新冲突。若你不清楚如何解决冲突,请使用[方法一](#方法一预设方法推荐)
默认权重使用**权重模板**规则编写,详见[预定义权重规则](./Score.ts#L208):选择第一个符合条件的规则,若皆不符合则选择第一个有效规则
打开插件默认词条权重文件直接修改相应数据保存即可,重启生效
文件路径:[ZZZ-plugin/resources/map/EquipScore.json](../../resources/map/EquipScore.json)
## 鸣谢
感谢**银狐**对评分计算规则的指导建议
[点此查看](./Score.ts)评分计算规则源码如果有任何对评分计算的想法建议欢迎与我联系ucpr251@gmail.com
# 伤害计算自定义
> 注意:如需自定义伤害计算,请先确保你拥有对伤害计算的基础知识,可参考[此帖][伤害计算]了解伤害计算的组成部分与计算方法
如需省流请直接查看[总结](#总结)
后文将带你入门插件伤害计算逻辑,只要你需要自定义伤害计算,都建议你完整阅读:
> 底层已对伤害计算进行了规范化、模块化,只需要填参数就可以实现常见的伤害计算逻辑,即使不懂代码也可以参考模板独立完成。若存在问题、建议,可于插件群内询问或与我沟通
伤害计算需要明确这几部分:**初始属性**、**局内Buff**、**技能属性**、**敌方属性**,后文将分别说明
## 初始属性
初始属性,即**局外**时代理人的面板属性(参见[上帖][伤害计算]完整描述)
在伤害计算逻辑中,此部分数据可直接获取,不作过多说明
## 局内Buff
局内Buff即仅在局内生效的所有增益一个buff只能对单一属性进行增益但可以同时作用于多个技能。合理管控buff是做好伤害计算**最重要**的一步
### 认识buff
每个buff由各项[buff参数](./BuffManager.ts#L42)组成,重要参数:
```js
{
/** Buff名称 */
name: string
/** Buff来源 */
source: buffSource
/** Buff增益的类型 */
type: buffType
/**
* Buff增益数值可为数值、字符串、数组、函数
* @number
* - 一般情况下此值即为提高值
* - 当buff增益类型为攻击力/冲击力/异常精通/异常掌控/防御力/生命值时,若此值<1则将此值理解为初始属性的百分比提高
* @string
* 角色自身的buff提高值可能随技能/天赋等级提高而提高此时可以于data.json的"buff"中添加倍率数组同上支持百分比提高此时value即为键名其首字母必须为对应技能的基类参考技能类型命名标准
* @array
* 根据buff.source自动选择对应等级/星级的值同上支持百分比提高支持的source
* - 音擎:音擎星级(进阶)
* - 核心被动、额外能力:核心技等级
* @function
* 函数返回值即为提高值
*/
value: number | string | number[] | Function
/**
* Buff增益技能类型生效范围参考技能类型命名标准
* - 当技能参数不存在redirect时range作用范围向后覆盖生效
* - 当技能参数存在redirect时range与type全匹配时生效redirect向后覆盖生效
* - 若需全匹配的精细操作可使用include与exclude参数
*/
range?: string[]
/**
* Buff增益技能类型生效技能
* - 不同于range仅全匹配type时该值生效不会向后覆盖生效
* - 无range且无include则该buff对exclude以外的全部技能生效
* - range与include符合其一则认为buff生效
* - 当技能参数存在redirect时range与include的区别在于include不会尝试匹配redirect
*/
include?: string[]
/**
* Buff增益技能类型排除技能
* - 与include相同仅全匹配type时该值生效不会向后覆盖生效
* - 优先级高于range与include
*/
exclude?: string[]
/** Buff增益属性类型无则对全部属性生效 */
element?: element | element[]
}
```
额外说明:
- **name**Buff名称。可重复
- **source**Buff来源。用于管理buff、简化参数、判断生效条件等。查看[buff来源](./BuffManager.ts#L24)
- **type**Buff增益的类型。查看[增益类型](./BuffManager.ts#L26)
- **value**Buff增益值。具体解释如上述
- **range**Buff增益技能类型范围模糊匹配技能type。该参数用于鉴别不同buff的[生效范围](#技能类型命名对buff作用的影响)[填写方法](#技能类型命名标准)会在技能属性中详细说明
- **include**Buff增益技能类型生效技能全匹配技能type。总的来说对于作用于某一类的buff比如对所有普攻/强E生效应使用range而明确指定了生效技能的buff应使用include
- **exclude**Buff增益技能类型排除技能全匹配技能type。显式指定使该buff不作用于某些技能
- **element**Buff增益属性类型可为字符串或字符串数组。该参数用于鉴别不同buff的生效属性比如只对冰属性伤害生效。查看[属性类型](./BuffManager.ts#L5)
完整参数详见[buff参数](./BuffManager.ts#L42)
### 注册buff
伤害计算模块提供了注册、管理各buff的接口[BuffManager](./BuffManager.ts)所有buff都需要通过此类的实例**buffM**进行注册、管理
Buff来源可分为三大类武器、套装、角色影画、核心被动、额外能力、技能buff的注册也分为此三步骤、三部分。具体计算文件分别位于[武器](./weapon/) [套装](./set/) [角色](./character/)
- 自定义方法:复制对应的计算文件,重命名为**原名_user.js**calc_user.js修改相应逻辑重启即可
- buff注册方法武器、套装、角色每部分buff的注册我都为你提供了两种方式
- 一:[直接导出](./character/模板/calc.js#L66)在计算文件中导出buffs数组数组中保存各buff即可
- 二:[函数导出](./character/模板/calc.js#L1):调用[BuffManager](./BuffManager.ts)实例**buffM**的**new**方法传入你需要注册的buff即可
- 当上述两方式同时存在时,会**先**注册**直接导出**的buffs**然后**调用**导出的函数**
- 一般情况下,都更推荐**直接导出**的方法。如果你需要更灵活的导出方式,可以选择使用函数导出
- buff注册原则应尽可能地将能够吃到的buff都注册上**不考虑失衡易伤和任何需失衡触发的buff**
后文将说明武器、套装、角色三部分各自的buff注册细则
### 武器Buff
[武器buff计算文件模板](./weapon/模板.js)
[武器buff两种导出方式实例](./weapon/霰落星殿.js)
注意事项:
- 武器的**基础属性**和**高级属性**皆已计入[**初始属性**](#初始属性),无需处理
- 武器的**音擎效果**需要单独注册
- 武器buff的**value**值一般为数组类型,具体参考[认识buff](#认识buff)部分
- 武器与角色的职业检查会自动进行
### 套装Buff
[套装buff计算文件模板](./set/模板.js)
[套装buff两种导出方式实例](./set/折枝剑歌.js)
注意事项:
- 主词条的提升会自动注册,无需处理
- 二件套效果只有**属性伤害提升**和**局外面板以外的效果**(如驱动盘如影相随[追加攻击]和[冲刺攻击]造成的伤害提升)需要注册,其他已包含于初始属性无需注册
- 四件套效果需要单独注册
### 角色Buff
[角色buff计算文件模板](./character/模板/calc.js)
[角色buff两种导出方式实例](./character/星见雅/calc.js)
角色buff分为**影画、核心被动、额外能力、技能**四个来源
- **影画·Rank**
参数**name**建议按照模板填写,此时命座检查会自动进行
- **核心被动·Talent**
核心被动buff参数中的**buff增益值**可能随核心技等级提升而提升,此时**value**的可选两种类型1. 直接填写倍率`数组`,参考[仪玄伤害计算](./character/仪玄/calc.js#L33)2. 填写`字符串`并于data.json中添加倍率数组参考[安东伤害计算](./character/安东/calc.js#L17)
- **额外能力·Addition**
额外能力的阵营效果直接视为生效,正常注册即可
- **技能·Skill**
部分角色释放技能后会给自身附加增益,正常注册即可
### 管理buff
- [BuffManager](./BuffManager.ts)提供了部分管理buff的函数可自行查看使用
- 较为推荐的管理buff方式为在使用**直接导出**注册相应的buff的基础上通过**导出函数**来管理buff在函数中调整各buff
- **在线调试**:将云崽底层的日志类型(根目录/config/config/bot.yaml中的log_level)修改为**debug**并重启后插件会自动监听现有各计算文件实时更新并会在控制台输出伤害计算的详细过程初始属性、buff情况、技能数据、buff生效情况、各乘区数据可据此调试在未开启在线调试的情况下每次修改都需要重启才能生效。开启在线调试后对当前已有计算文件的修改会直接生效但新增计算文件仍需重启才能生效
- 游戏中的buff生效情况错综复杂但通过[自定义敌方属性](#自定义敌方属性)和对buff的精确管控插件的计算结果将与游戏实机十分吻合
<p align="center">
<img width="800" src="https://s2.loli.net/2025/05/30/FIvQ5DCAZBcT9z1.png" title="薇薇安伤害计算">
</p>
## 技能属性
技能属性,即在代理人技能详情界面对该技能的描述:技能名、伤害倍率、伤害类型等
### 认识技能
技能为泛指,任何可以造成伤害的输出手段,此处都可称为技能,包括属性异常、紊乱等
每个技能由各项[技能参数](./Calculator.ts#L9)组成,必需参数:
```js
{
/** 技能名,唯一 */
name: string
/** 技能类型,唯一,参考技能类型命名标准 */
type: string
/** 属性类型,不指定时,默认取角色属性 */
element: element
}
```
### 技能类型
由于不同Buff作用的技能类型不同为了统一判断某Buff是否对某技能生效规定**技能类型命名标准**
#### 技能类型命名标准
> - A 攻击
> - AP 普通攻击
> - AX 重击/蓄力攻击
> - AQ 强化普攻
> - C 闪避
> - CP 普通闪避
> - CF 闪避反击
> - CC 冲刺攻击
> - CX 蓄力闪避
> - L 支援技
> - LK 快速支援
> - LZ 招架支援
> - LT 突击支援
> - E 特殊技
> - EP 普通特殊技
> - EQ 强化特殊技
> - R
> - RZ 终结技
> - RL 连携技
> - T 核心技
> - 核心技中的技能各不相同,自行定义即可
> - Y 影画如柏妮思6影额外伤害
> - Y后接数字表示该技能为第n个影画的效果
> - 影画中的技能各不相同,自行定义即可
> - 属性异常
> - 强击 畏缩
> - 灼烧
> - 碎冰 霜寒
> - 感电
> - 侵蚀
> - 紊乱
>
> 当需要对属性异常进行变体时(如薇薇安的异放),使命名以属性异常名开头即可(如 侵蚀·异放注意buff作用范围需保持同步
> - 追加攻击
> - 直接以“追加攻击”命名
> - 追加攻击不被认为是一种新的输出手段(技能),它更类似于原直伤输出的一个额外标签,使该伤害能同时吃到**对其原所属技能类型生效**的增益和**仅对追加攻击生效**的增益,故一般不将其单独作为技能类型而是在技能属性的重定向参数中添加**追加攻击**参数,请参考[技能重定向说明注意事项](#技能类型命名对Buff作用的影响)
> - 贯穿伤害
> - 命名等同于直伤规则,无需作特殊处理,底层会自动识别是否为贯穿伤害
#### 技能类型命名解释说明
1. 首字母为技能所属**基类**,不可更改、不可单独作为技能类型,后跟字母表示技能分支
2. **树状命名**,后一位字母代表基于其前一位字母的分支,取技能名发音(倒着读)
3. 后跟数字可表示**段数**如AP1表示第一段普攻为避免混淆数字仅表示同一技能不同段数不用于区分不同技能
4. 当不需要进一步细分分支时必须遵守此标准命名否则可能导致Buff计算错误
5. 当需进一步细分多种分支时,应基于此标准已有的命名拓展命名,并确保前后一致
#### 技能类型命名示例
艾莲的冲刺攻击有三种不同的类型,为了区分,需要对其进行拓展
冲刺攻击类型命名标准为**CC**,故:
- “冲刺攻击:寒潮”可表示为**CCP**(普通冲刺攻击);
- “冲刺攻击:骇浪”可表示为**CCQ**(强化冲刺攻击);
- “冲刺攻击:冰渊潜袭”可表示为**CCX**(巡游冲刺攻击),其又分为普通和蓄力两种,又可分别表示为:
- 普通巡游冲刺攻击:**CCXP**
- 蓄力巡游冲刺攻击:**CCXX**
[点此查看](./character/艾莲/calc.js#L40)艾莲实际伤害计算文件
当然,若冲刺攻击不存在变体,则直接使用**CC**命名即可
#### 技能类型命名对Buff作用的影响
技能类型命名将直接决定某buff是否作用于某技能这也是规定标准命名的原因
buff作用范围将以技能类型命名为依据向后覆盖。以上述[艾莲冲刺攻击命名示例](#技能类型命名示例)为例在某buff的作用范围数组即buff的**range**参数)中:
- 如果包括**C**则代表对所有基于C闪避的分支都生效包括CP、CF、CC、CX等
- 如果包括**CC**则代表对所有基于CC冲刺攻击的分支都生效
- 如果只包括**CCQ**(强化冲刺攻击),则代表只对“冲刺攻击:骇浪”生效
- 如果只包括**CCX**(巡游冲刺攻击),则代表对“冲刺攻击:冰渊潜袭”生效(无论普通或蓄力)
- 如果只包括**CCXX**(蓄力巡游冲刺攻击),则代表只对“冲刺攻击:冰渊潜袭”的蓄力巡游冲刺攻击生效
[点此查看](./character/艾莲/calc.js#L24)艾莲实际伤害计算文件
注意事项:
- 属性异常中**强击**和**碎冰**没有持续时间的概念,总倍率不受持续时间的影响也无法结算紊乱。因此对于作用于**异常持续时间**的buff其buff.range应填写异常对应的**状态异常****畏缩**和**霜寒**),灼烧等既是伤害异常也是状态异常则无需区分
- 对于`“X"(造成的伤害)被视为“Y”(伤害)`此类特殊技能,需要指定技能**重定向参数**同时上述buff覆盖规则会发生变化具体请参考[源码内描述](./Calculator.ts#L46)
> 需要注意的是:即使出现`“X"(造成的伤害)被视为“Y”(伤害)`,对**Y**类型的增益**X**不一定能吃到,视具体情况变化
> 对于被视为**追加攻击**伤害的技能,其重定向参数一般为包含其**原技能类型**和**追加攻击**的数组,因为它可以吃到分别对两者生效的不同增益(以游戏内具体情况为准),参考[**零号·安比**伤害计算文件](./character/零号·安比/calc.js#L50)
### 技能倍率
[点此查看模板技能倍率](./character/模板/data.json)
不同等级的技能倍率不同,新增某技能的伤害计算时需要你手动添加对应的倍率信息
技能倍率保存在character/角色名/**data.json**中json数据的skill中的各个**键**即为技能类型**type****值**即为每个等级对应的倍率数组长度16
需要自定义data.json时同样复制一份重命名为**data_user.json**即可
角色每个技能各等级对应的倍率建议在[米游社官网图鉴](https://baike.mihoyo.com/zzz/wiki/channel/map/2/43)中查询。不建议使用第三方图鉴工具如B站的绝区零wiki其技能倍率可能存在错误
技能倍率大部分情况下为**等差数列**,少数情况下增量**存在变化**,请注意甄别。对于等差数列的技能倍率,下面是一个简易的生成函数,可复制粘贴直接使用:
<details>
<summary>点击展开</summary>
```js
import { exec } from 'child_process'
const copyToClipboard = (text) => {
exec('clip').stdin.end(text)
}
function counter(first, second, num = 16) {
if (first > 100 && second > 100) {
first = Math.round(first * 100)
second = Math.round(second * 100)
} else {
first = Math.round(first * 10000)
second = Math.round(second * 10000)
}
const step = second - first
const arr = [first / 10000]
let txt = first / 10000 + ''
for (let i = 1; i < num; i++) {
const next = (first + step * i) / 10000
txt += ',' + +next.toFixed(4)
arr.push(next)
}
if (process.platform === 'win32') {
copyToClipboard(txt)
}
console.log(txt)
return arr
}
// 可按照实际数值填写当倍率大于100%时可忽略百分号填写
// 参数依次为1级倍率 2级倍率 生成长度
counter(145.7, 159, 16)
```
</details>
### 注册技能
伤害计算模块提供了注册各技能的接口[Calculator](./Calculator.ts),所有技能都需要通过此类的实例**calc**进行注册
技能的注册较为简单:
1. 参考[模板](./character/模板/calc.js#L115)填入各技能相应参数一般只需要填name、type参数
2. 于[data.json](./character/模板/data.json)中为每个技能填写倍率(异常伤害无需填写)
注意事项:
- 若某技能所造成伤害的属性与角色属性不符,应指定该技能的属性**element**
- 技能的参数有较多可选的拓展,用于处理更复杂的情况,如有需要请自行查看[Calculator源码](./Calculator.ts)和已有角色的计算案例(较为复杂的计算案例可参考[柏妮思的伤害计算](./character/柏妮思/calc.js)
- 后续会根据需要,新增/调整拓展参数,对于已有的拓展会尽量保持兼容
- 目前只可注册角色的技能,部分武器有独立的造成额外伤害的机制,暂不考虑
## 敌方属性
影响伤害计算的敌方属性有:防御力、抗性、弱点
### 敌方属性的影响
- **防御力**:影响防御乘区。影响直伤和异常伤害计算
- **抗性、弱点**:影响抗性乘区。影响直伤和异常伤害计算
### 自定义敌方属性
可以用 **等级、1级基础防御力、抗性** 三个参数来衡量**防御力、抗性、弱点**
- **等级、1级基础防御力**:根据这两个参数可计算出敌方防御力。插件默认敌方等级=角色等级1级基础防御力=50
- **抗性**:敌方存在对应的弱点时,此值为 **-0.2**;敌方存在对应的抗性时,此值为 **0.2**;既不抗也不弱,此值为 **0**。插件默认抗性=-0.2
通过在角色伤害计算文件中导出**calc**函数调用函数参数中calc的[defEnemy](./Calculator.ts)方法,你可以对此三个参数进行自定义
敌方基础属性可查看[此表](https://docs.qq.com/sheet/DUHBodnJVQ1pKcFl4?tab=llkjkv)(最新)或[此图](https://img.nga.178.com/attachments/mon_202407/16/axvkQq44x-2xpiZyT3cSwm-1hf.png)
例如将敌人的1级基础防御力设置为36如提尔锋
```JS
export function calc(buffM, calc, avatar) {
calc.defEnemy('basicDEF', 36)
}
```
## 总结
角色伤害计算文件为[character/角色名/calc.js](./character/),如需自定义,将**calc.js**复制一份并重命名为**calc_user.js**后自行修改其中逻辑即可。**data.json**为技能倍率、天赋加成数据,如需自定义,同理将**data.json**复制一份并重命名为**data_user.json**后自行修改即可。[套装计算](./set/)和[武器计算](./weapon/)同理
请在对[伤害计算]有一定了解的基础上再进行伤害计算的修改
**新增**角色伤害计算的一般步骤为:
1. 复制一份[模板](./character/模板/)文件夹,重命名为对应角色名
2. 修改其中**calc.js**,选择你喜欢的[导出方式](#注册buff),一般推荐**直接导出**
3. 了解对应角色技能的变体,参考[技能类型命名标准](#技能类型命名标准)为每个需要注册的技能命名(即使有的技能变体你不需要计算,也推荐你按照标准命名进行拓展命名,便于后续拓展)
4. [注册对应的技能](#注册技能)只有先明确每个技能参数的type如何命名你才能知道如何填buff参数的range
5. [注册对应的buff](#注册buff)
6. 填写[技能倍率](#技能倍率)、[天赋倍率](#角色buff)
**修改**现有角色伤害计算的一般步骤为:
1. 复制一份该角色对应的calc.js文件重命名为calc_user.js
2. 根据需要修改其中的逻辑,可以通过组合使用[导出方式](#注册buff)进行管理
3. 如需新增技能倍率复制一份该角色对应的data.json文件重命名为data_user.json
4. 根据需要填写[技能倍率](#技能倍率)、[天赋倍率](#角色buff)
建议开启[在线调试](#管理buff)
## ToDo
- [x] 伤害计算模块化重构
- [x] 伤害计算自定义支持
- [x] 伤害计算说明文档
- [x] 全角色伤害计算
- [x] 驱动盘评分计算
- [x] 驱动盘词条差异计算
- [ ] 伤害计算buff指令热注入
- [ ] 伤害计算敌人自定义
- [ ] %XX面板换XXX指令
- [ ] 角色伤害、防卫战层数耗时、危局星数得分、爬塔排名
- [ ] 组队伤害计算
- [ ] 失衡值累积计算
- [ ] ~~异常积蓄值计算~~
- [ ] ~~治疗量计算~~
## 鸣谢
感谢[紫罗兰打烊啦](https://www.miyoushe.com/zzz/accountCenter/postList?id=279259320)对伤害计算细则的评测探讨指正
感谢[666bj](https://www.miyoushe.com/zzz/accountCenter/postList?id=291537017)对绝区零数据机制研究做出的贡献
---
[伤害计算]:https://www.miyoushe.com/zzz/article/66274506