补充伊芙琳驱动盘频分、修正伊芙琳伤害计算

This commit is contained in:
UCPr 2025-02-13 15:55:27 +08:00
parent fb5970a7d9
commit 52ef8512fa
5 changed files with 112 additions and 46 deletions

View file

@ -113,32 +113,47 @@ export class BuffManager {
buffs = buffs.filter(buff => { buffs = buffs.filter(buff => {
if (buff.status === false) if (buff.status === false)
return false; return false;
for (const key in param) { const judge = (() => {
if (key === 'redirect') // 未传入calc时不判断range、include、exclude
continue; if (typeof valueOcalc !== 'object' || Array.isArray(valueOcalc))
if (key === 'range') { return true;
// buff指定排除该技能
if (buff.exclude && buff.exclude.includes(valueOcalc.skill.type))
return false;
// 11 10 01
if (buff.range || buff.include) {
// 11 01 存在include且满足时则直接返回true
if (buff.include && buff.include.includes(valueOcalc.skill.type))
return true;
// 01 没有range则代表只有include直接返回false
if (!buff.range)
return false;
// 11 10 直接返回range的结果即可
const buffRange = buff.range; const buffRange = buff.range;
const skillRange = param.range?.filter(r => typeof r === 'string'); const skillRange = param.range?.filter(r => typeof r === 'string');
if (!buffRange || !skillRange) if (!skillRange?.length)
continue; // 对任意类型生效 return true; // 对任意类型生效
if (!skillRange.length)
continue;
// buff作用范围向后覆盖 // buff作用范围向后覆盖
// 存在重定向时range须全匹配redirect向后覆盖 // 存在重定向时range须全匹配redirect向后覆盖
else if (param.redirect) { else if (param.redirect) {
if (skillRange.some(ST => buffRange.some(BT => BT === ST))) if (skillRange.some(ST => buffRange.some(BT => BT === ST)))
continue; return true;
if (buffRange.some(BT => param.redirect.startsWith(BT))) if (buffRange.some(BT => param.redirect.startsWith(BT)))
continue; return true;
return false; return false;
} }
// 不存在重定向时range向后覆盖 // 不存在重定向时range向后覆盖
else if (!skillRange.some(ST => buffRange.some(BT => ST.startsWith(BT)))) return skillRange.some(ST => buffRange.some(BT => ST.startsWith(BT)));
return false;
else
continue;
} }
else if (key === 'element') { // 00
return true;
})();
if (!judge)
return false;
for (const key in param) {
if (key === 'redirect' || key === 'range')
continue;
if (key === 'element') {
if (!buff.element || !param.element) if (!buff.element || !param.element)
continue; // 对任意属性生效 continue; // 对任意属性生效
if (Array.isArray(buff.element)) { if (Array.isArray(buff.element)) {

View file

@ -75,8 +75,26 @@ export interface buff {
buffM: BuffManager buffM: BuffManager
calc: Calculator calc: Calculator
}) => number) | string | number[] }) => number) | string | number[]
/** Buff增益技能类型范围无则对全部生效参考技能类型命名标准 */ /**
* Buff增益技能类型****
* - **redirect****range**
* - **redirect****range****redirect**
*/
range?: string[] | anomaly[] range?: string[] | anomaly[]
/**
* Buff增益技能类型****
* - **range**
* - **range****include**buff对全部技能生效
* - **range****include**buff生效
* - **redirect****range****include****include****redirect**
*/
include?: string[]
/**
* Buff增益技能类型****
* - **include**
* - **range****include**
*/
exclude?: string[]
/** Buff增益属性类型无则对全部生效 */ /** Buff增益属性类型无则对全部生效 */
element?: element | element[] element?: element | element[]
/** /**
@ -152,13 +170,13 @@ export class BuffManager {
} }
_filter<T extends keyof buff>(buffs: buff[], type: T, value: buff[T]): buff[] _filter<T extends keyof buff>(buffs: buff[], type: T, value: buff[T]): buff[]
_filter(buffs: buff[], obj: { [key in Exclude<keyof buff, 'status' | 'check' | 'element'>]?: buff[key] } & { element: element, redirect?: skill['type'] }, calc?: Calculator): buff[] _filter(buffs: buff[], obj: { [key in Exclude<keyof buff, 'status' | 'check' | 'element' | 'include' | 'exclude'>]?: buff[key] } & { element: element, redirect?: skill['type'] }, calc?: Calculator): buff[]
_filter(buffs: buff[], fnc: (buff: buff, index: number) => boolean): buff[] _filter(buffs: buff[], fnc: (buff: buff, index: number) => boolean): buff[]
_filter<T extends keyof buff>( _filter<T extends keyof buff>(
buffs: buff[], buffs: buff[],
param: param:
| T | T
| ({ [key in Exclude<keyof buff, 'status' | 'check' | 'element'>]?: buff[key] } & { element: element, redirect?: skill['type'] }) | ({ [key in Exclude<keyof buff, 'status' | 'check' | 'element' | 'include' | 'exclude'>]?: buff[key] } & { element: element, redirect?: skill['type'] })
| ((buff: buff, index: number) => boolean), | ((buff: buff, index: number) => boolean),
valueOcalc?: buff[T] | Calculator valueOcalc?: buff[T] | Calculator
) { ) {
@ -169,24 +187,38 @@ export class BuffManager {
} else if (typeof param === 'object') { } else if (typeof param === 'object') {
buffs = buffs.filter(buff => { buffs = buffs.filter(buff => {
if (buff.status === false) return false if (buff.status === false) return false
for (const key in param) { const judge = (() => {
if (key === 'redirect') continue // 未传入calc时不判断range、include、exclude
if (key === 'range') { if (typeof valueOcalc !== 'object' || Array.isArray(valueOcalc)) return true
// buff指定排除该技能
if (buff.exclude && buff.exclude.includes(valueOcalc.skill.type)) return false
// 11 10 01
if (buff.range || buff.include) {
// 11 01 存在include且满足时则直接返回true
if (buff.include && buff.include.includes(valueOcalc.skill.type)) return true
// 01 没有range则代表只有include直接返回false
if (!buff.range) return false
// 11 10 直接返回range的结果即可
const buffRange = buff.range const buffRange = buff.range
const skillRange = param.range?.filter(r => typeof r === 'string') const skillRange = param.range?.filter(r => typeof r === 'string')
if (!buffRange || !skillRange) continue // 对任意类型生效 if (!skillRange?.length) return true // 对任意类型生效
if (!skillRange.length) continue
// buff作用范围向后覆盖 // buff作用范围向后覆盖
// 存在重定向时range须全匹配redirect向后覆盖 // 存在重定向时range须全匹配redirect向后覆盖
else if (param.redirect) { else if (param.redirect) {
if (skillRange.some(ST => buffRange.some(BT => BT === ST))) continue if (skillRange.some(ST => buffRange.some(BT => BT === ST))) return true
if (buffRange.some(BT => param.redirect!.startsWith(BT))) continue if (buffRange.some(BT => param.redirect!.startsWith(BT))) return true
return false return false
} }
// 不存在重定向时range向后覆盖 // 不存在重定向时range向后覆盖
else if (!skillRange.some(ST => buffRange.some(BT => ST.startsWith(BT)))) return false return skillRange.some(ST => buffRange.some(BT => ST.startsWith(BT)))
else continue }
} else if (key === 'element') { // 00
return true
})()
if (!judge) return false
for (const key in param) {
if (key === 'redirect' || key === 'range') continue
if (key === 'element') {
if (!buff.element || !param.element) continue // 对任意属性生效 if (!buff.element || !param.element) continue // 对任意属性生效
if (Array.isArray(buff.element)) { if (Array.isArray(buff.element)) {
if (buff.element.includes(param.element)) continue if (buff.element.includes(param.element)) continue
@ -243,7 +275,7 @@ export class BuffManager {
* - range须全匹配redirect向后覆盖 * - range须全匹配redirect向后覆盖
* - range向后覆盖 * - range向后覆盖
*/ */
filter(obj: { [key in Exclude<keyof buff, 'status' | 'check' | 'element'>]?: buff[key] } & { element: element, redirect?: skill['type'] }, calc?: Calculator): buff[] filter(obj: { [key in Exclude<keyof buff, 'status' | 'check' | 'element' | 'include' | 'exclude'>]?: buff[key] } & { element: element, redirect?: skill['type'] }, calc?: Calculator): buff[]
/** /**
* buff * buff
*/ */
@ -251,7 +283,7 @@ export class BuffManager {
filter<T extends keyof buff>( filter<T extends keyof buff>(
param: param:
| T | T
| ({ [key in Exclude<keyof buff, 'status' | 'check' | 'element'>]?: buff[key] } & { element: element, redirect?: skill['type'] }) | ({ [key in Exclude<keyof buff, 'status' | 'check' | 'element' | 'include' | 'exclude'>]?: buff[key] } & { element: element, redirect?: skill['type'] })
| ((buff: buff, index: number) => boolean), | ((buff: buff, index: number) => boolean),
valueOcalc?: buff[T] | Calculator valueOcalc?: buff[T] | Calculator
) { ) {

View file

@ -23,7 +23,7 @@
### 认识buff ### 认识buff
每个buff由各项[buff参数](./BuffManager.ts#L49)组成,重要参数: 每个buff由各项[buff参数](./BuffManager.ts#L48)组成,重要参数:
```js ```js
{ {
@ -48,7 +48,11 @@
* 角色自身的buff提高值可能随技能/天赋等级提高而提高此时可以于data.json的"buff"中添加对应的倍率信息同上支持百分比提高此时value即为键名其首字母必须为对应技能的基类参考技能类型命名标准 * 角色自身的buff提高值可能随技能/天赋等级提高而提高此时可以于data.json的"buff"中添加对应的倍率信息同上支持百分比提高此时value即为键名其首字母必须为对应技能的基类参考技能类型命名标准
*/ */
value: number | number[] | Function | string value: number | number[] | Function | string
/** Buff增益技能类型范围无则对全部生效参考技能类型命名标准 */ /**
* Buff增益技能类型生效范围参考技能类型命名标准
* - 当技能参数不存在redirect时range作用范围向后覆盖
* - 当技能参数存在redirect时range须全匹配redirect向后覆盖
*/
range?: string[] range?: string[]
/** Buff增益属性类型无则对全部属性生效 */ /** Buff增益属性类型无则对全部属性生效 */
element?: element | element[] element?: element | element[]
@ -59,15 +63,17 @@
- **name**Buff名称。可重复 - **name**Buff名称。可重复
- **source**Buff来源。用于管理buff、简化参数、判断生效条件等。查看[buff来源](./BuffManager.ts#L33) - **source**Buff来源。用于管理buff、简化参数、判断生效条件等。查看[buff来源](./BuffManager.ts#L32)
- **type**Buff增益的类型。查看[增益类型](./BuffManager.ts#L35) - **type**Buff增益的类型。查看[增益类型](./BuffManager.ts#L34)
- **value**Buff增益值。具体解释如上述 - **value**Buff增益值。具体解释如上述
- **range**Buff增益技能类型范围。该参数用于鉴别不同buff的[生效范围](#技能类型命名对buff作用的影响)(比如只对普攻生效),[填写方法](#技能类型命名标准)会在技能属性中详细说明 - **range**Buff增益技能类型范围。该参数用于鉴别不同buff的[生效范围](#技能类型命名对buff作用的影响)(比如只对普攻生效),[填写方法](#技能类型命名标准)会在技能属性中详细说明
- **element**Buff增益属性类型可为字符串或字符串数组。该参数用于鉴别不同buff的生效属性比如只对冰属性伤害生效。查看[属性类型](./BuffManager.ts#L6) - **element**Buff增益属性类型可为字符串或字符串数组。该参数用于鉴别不同buff的生效属性比如只对冰属性伤害生效。查看[属性类型](./BuffManager.ts#L5)
- buff存在更多的参数用于处理各种情况详见[buff参数](./BuffManager.ts#L48)
### 注册buff ### 注册buff
@ -269,7 +275,9 @@ buff作用范围将以技能类型命名为依据向后覆盖。以上述[艾莲
- 属性异常中**强击**和**碎冰**没有持续时间的概念,总倍率不受持续时间的影响也无法结算紊乱。因此对于作用于**异常持续时间**的buff其buff.range应填写异常对应的**状态异常****畏缩**和**霜寒**),灼烧等既是伤害异常也是状态异常则无需区分。 - 属性异常中**强击**和**碎冰**没有持续时间的概念,总倍率不受持续时间的影响也无法结算紊乱。因此对于作用于**异常持续时间**的buff其buff.range应填写异常对应的**状态异常****畏缩**和**霜寒**),灼烧等既是伤害异常也是状态异常则无需区分。
- 对于`“X"(造成的伤害)被视为“Y”(伤害)`此类特殊技能,需要指定技能**重定向参数**同时上述buff覆盖规则会发生变化具体请参考[源码内描述](./Calculator.ts#L22),此处不作过多说明 - 对于`“X"(造成的伤害)被视为“Y”(伤害)`此类特殊技能,需要指定技能**重定向参数**同时上述buff覆盖规则会发生变化具体请参考[源码内描述](./Calculator.ts#L22)
> 需要注意的是:即使出现`“X"(造成的伤害)被视为“Y”(伤害)`,对**Y**类型的增益**X**不一定能吃到,视具体情况变化
### 技能倍率 ### 技能倍率

View file

@ -25,21 +25,16 @@ export const buffs = [
name: '额外能力:潜袭支点', name: '额外能力:潜袭支点',
type: '增伤', type: '增伤',
value: 0.3, value: 0.3,
range: ['RL', 'RZ'] range: ['RL', 'RZ'],
exclude: ['Y6']
}, },
{ {
name: '额外能力:潜袭支点', name: '额外能力:潜袭支点',
type: '倍率', type: '倍率',
check: ({ calc }) => calc.get_CRITRate() >= 0.8, check: ({ calc }) => calc.get_CRITRate() >= 0.8,
value: ({ calc }) => calc.skill.name !== '连携技:月辉丝·绊' ? 0 : calc.get_SkillMultiplier('RL') * 0.25, value: ({ calc }) => calc.get_SkillMultiplier(calc.skill.type) * 0.25,
range: ['RL'] range: ['RL', 'RZ'],
}, exclude: ['Y6']
{
name: '额外能力:潜袭支点',
type: '倍率',
check: ({ calc }) => calc.get_CRITRate() >= 0.8,
value: ({ calc }) => calc.get_SkillMultiplier('RZ') * 0.25,
range: ['RZ']
} }
] ]

View file

@ -376,6 +376,22 @@
"31403": 0, "31403": 0,
"31903": 0.5 "31903": 0.5
}, },
"1321": {
"11102": 0,
"11103": 0,
"12102": 0.75,
"12103": 0.75,
"13103": 0,
"13102": 0,
"20103": 1,
"21103": 1,
"23103": 0.75,
"23203": 0.75,
"30502": 0,
"31203": 0,
"31403": 0,
"31603": 1
},
"2011": {}, "2011": {},
"2021": {} "2021": {}
} }