mirror of
https://github.com/ZZZure/ZZZ-Plugin.git
synced 2025-12-16 13:17:32 +00:00
薇薇安伤害计算
This commit is contained in:
parent
297be2d481
commit
7ace8908ff
9 changed files with 240 additions and 53 deletions
|
|
@ -264,7 +264,7 @@ export class ZZZAvatarInfo {
|
||||||
this.level_rank = Math.floor(this.level / 10);
|
this.level_rank = Math.floor(this.level / 10);
|
||||||
const weight = scoreFnc[this.id] && scoreFnc[this.id](this);
|
const weight = scoreFnc[this.id] && scoreFnc[this.id](this);
|
||||||
this.weightRule = weight?.[0] || '默认';
|
this.weightRule = weight?.[0] || '默认';
|
||||||
this.scoreWeight = formatScoreWeight(weight?.[1]) || scoreWeight[this.id];
|
this.scoreWeight = Object.assign(formatScoreWeight(weight?.[1]) || {}, scoreWeight[this.id]);
|
||||||
for (const equip of this.equip) {
|
for (const equip of this.equip) {
|
||||||
equip.get_score(this.scoreWeight);
|
equip.get_score(this.scoreWeight);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -200,18 +200,23 @@ export class BuffManager {
|
||||||
find(type, value) {
|
find(type, value) {
|
||||||
return this.buffs.find(buff => buff[type] === value);
|
return this.buffs.find(buff => buff[type] === value);
|
||||||
}
|
}
|
||||||
operator(type, value, fnc) {
|
operator(key, value, fnc) {
|
||||||
this.forEach(buff => {
|
const isMatch = typeof key === 'object' ?
|
||||||
if (buff[type] === value) {
|
(targetBuff) => Object.entries(key).every(([k, v]) => targetBuff[k] === v) :
|
||||||
fnc(buff);
|
(targetBuff) => targetBuff[key] === value;
|
||||||
}
|
this.forEach(buff => isMatch(buff) && (fnc || value)(buff));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
close(type, value) {
|
close(key, value) {
|
||||||
this.operator(type, value, buff => buff.status = false);
|
if (typeof key === 'object')
|
||||||
|
this.operator(key, buff => buff.status = false);
|
||||||
|
else
|
||||||
|
this.operator(key, value, buff => buff.status = false);
|
||||||
}
|
}
|
||||||
open(type, value) {
|
open(key, value) {
|
||||||
this.operator(type, value, buff => buff.status = true);
|
if (typeof key === 'object')
|
||||||
|
this.operator(key, buff => buff.status = true);
|
||||||
|
else
|
||||||
|
this.operator(key, value, buff => buff.status = true);
|
||||||
}
|
}
|
||||||
default(param, value) {
|
default(param, value) {
|
||||||
if (typeof param === 'object') {
|
if (typeof param === 'object') {
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ export class BuffManager {
|
||||||
readonly buffs: buff[] = []
|
readonly buffs: buff[] = []
|
||||||
/** 套装计数 */
|
/** 套装计数 */
|
||||||
setCount: { [name: string]: number } = {}
|
setCount: { [name: string]: number } = {}
|
||||||
defaultBuff: { [key in keyof buff]?: buff[key] } = {}
|
defaultBuff: Partial<buff> = {}
|
||||||
|
|
||||||
constructor(avatar: ZZZAvatarInfo) {
|
constructor(avatar: ZZZAvatarInfo) {
|
||||||
this.avatar = avatar
|
this.avatar = avatar
|
||||||
|
|
@ -319,39 +319,46 @@ export class BuffManager {
|
||||||
return this.buffs.find(buff => buff[type] === value)
|
return this.buffs.find(buff => buff[type] === value)
|
||||||
}
|
}
|
||||||
|
|
||||||
operator<T extends keyof buff>(type: T, value: buff[T], fnc: (buff: buff) => void) {
|
operator(buff: Partial<buff>, fnc: (buff: buff) => void): void
|
||||||
this.forEach(buff => {
|
operator<T extends keyof buff>(key: T, value: buff[T], fnc: (buff: buff) => void): void
|
||||||
if (buff[type] === value) {
|
operator<T extends keyof buff>(key: T | Partial<buff>, value: buff[T] | ((buff: buff) => void), fnc?: (buff: buff) => void) {
|
||||||
fnc(buff)
|
const isMatch = typeof key === 'object' ?
|
||||||
}
|
(targetBuff: buff) => Object.entries(key).every(([k, v]) => targetBuff[k as keyof buff] === v) :
|
||||||
})
|
(targetBuff: buff) => targetBuff[key] === value
|
||||||
|
this.forEach(buff => isMatch(buff) && (fnc || value as (buff: buff) => void)(buff))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** 关闭符合条件的所有buff */
|
||||||
* 关闭符合条件的所有buff
|
close(buff: Partial<buff>): void
|
||||||
*/
|
close<T extends keyof buff>(key: T, value: buff[T]): void
|
||||||
close<T extends keyof buff>(type: T, value: buff[T]) {
|
close<T extends keyof buff>(key: T | Partial<buff>, value?: buff[T] | Partial<buff>) {
|
||||||
this.operator(type, value, buff => buff.status = false)
|
if (typeof key === 'object')
|
||||||
|
this.operator(key, buff => buff.status = false)
|
||||||
|
else
|
||||||
|
this.operator(key, value as buff[T], buff => buff.status = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** 开启符合条件的所有buff */
|
||||||
* 开启符合条件的所有buff
|
open(buff: Partial<buff>): void
|
||||||
*/
|
open<T extends keyof buff>(key: T, value: buff[T]): void
|
||||||
open<T extends keyof buff>(type: T, value: buff[T]) {
|
open<T extends keyof buff>(key: T, value?: buff[T]) {
|
||||||
this.operator(type, value, buff => buff.status = true)
|
if (typeof key === 'object')
|
||||||
|
this.operator(key, buff => buff.status = true)
|
||||||
|
else
|
||||||
|
this.operator(key, value as buff[T], buff => buff.status = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置后续新增buff参数的默认值
|
* 设置后续新增buff参数的默认值
|
||||||
* @param obj 直接覆盖默认值
|
* @param obj 直接覆盖默认值
|
||||||
*/
|
*/
|
||||||
default(obj: { [key in keyof buff]?: buff[key] }): void
|
default(obj: Partial<buff>): void
|
||||||
/**
|
/**
|
||||||
* 设置后续新增buff参数的默认值
|
* 设置后续新增buff参数的默认值
|
||||||
* @param value 为undefined时删除默认值
|
* @param value 为undefined时删除默认值
|
||||||
*/
|
*/
|
||||||
default<T extends keyof buff>(type: T, value?: buff[T]): void
|
default<T extends keyof buff>(key: T, value?: buff[T]): void
|
||||||
default<T extends keyof buff>(param: T | { [key in keyof buff]?: buff[key] }, value?: buff[T]): void {
|
default<T extends keyof buff>(param: T | Partial<buff>, value?: buff[T]): void {
|
||||||
if (typeof param === 'object') {
|
if (typeof param === 'object') {
|
||||||
this.defaultBuff = param
|
this.defaultBuff = param
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ export class Calculator {
|
||||||
const areas = {};
|
const areas = {};
|
||||||
if (skill.before)
|
if (skill.before)
|
||||||
skill.before({ avatar: this.avatar, calc: this, usefulBuffs, skill, props, areas });
|
skill.before({ avatar: this.avatar, calc: this, usefulBuffs, skill, props, areas });
|
||||||
const isAnomaly = typeof anomalyEnum[skill.type] === 'number';
|
const isAnomaly = typeof anomalyEnum[skill.type.slice(0, 2)] === 'number';
|
||||||
if (!areas.BasicArea) {
|
if (!areas.BasicArea) {
|
||||||
let Multiplier = props.倍率;
|
let Multiplier = props.倍率;
|
||||||
if (!Multiplier) {
|
if (!Multiplier) {
|
||||||
|
|
@ -120,7 +120,7 @@ export class Calculator {
|
||||||
Multiplier = skill.fixedMultiplier;
|
Multiplier = skill.fixedMultiplier;
|
||||||
}
|
}
|
||||||
else if (isAnomaly) {
|
else if (isAnomaly) {
|
||||||
Multiplier = (skill.type === '紊乱' ?
|
Multiplier = (skill.type.startsWith('紊乱') ?
|
||||||
this.get_DiscoverMultiplier(skill) :
|
this.get_DiscoverMultiplier(skill) :
|
||||||
this.get_AnomalyMultiplier(skill, usefulBuffs, skill.name.includes('每') ? 1 : 0)) || 0;
|
this.get_AnomalyMultiplier(skill, usefulBuffs, skill.name.includes('每') ? 1 : 0)) || 0;
|
||||||
}
|
}
|
||||||
|
|
@ -146,7 +146,7 @@ export class Calculator {
|
||||||
areas.AnomalyProficiencyArea ??= this.get_AnomalyProficiencyArea(skill, usefulBuffs);
|
areas.AnomalyProficiencyArea ??= this.get_AnomalyProficiencyArea(skill, usefulBuffs);
|
||||||
areas.AnomalyBoostArea ??= this.get_AnomalyBoostArea(skill, usefulBuffs);
|
areas.AnomalyBoostArea ??= this.get_AnomalyBoostArea(skill, usefulBuffs);
|
||||||
areas.LevelArea ??= this.get_LevelArea();
|
areas.LevelArea ??= this.get_LevelArea();
|
||||||
if (skill.type !== '紊乱') {
|
if (!skill.type.startsWith('紊乱')) {
|
||||||
props.异常暴击率 ??= this.get_AnomalyCRITRate(skill, usefulBuffs);
|
props.异常暴击率 ??= this.get_AnomalyCRITRate(skill, usefulBuffs);
|
||||||
props.异常暴击伤害 ??= this.get_AnomalyCRITDMG(skill, usefulBuffs);
|
props.异常暴击伤害 ??= this.get_AnomalyCRITDMG(skill, usefulBuffs);
|
||||||
areas.CriticalArea ??= 1 + props.异常暴击率 * (props.异常暴击伤害 - 1);
|
areas.CriticalArea ??= 1 + props.异常暴击率 * (props.异常暴击伤害 - 1);
|
||||||
|
|
@ -372,23 +372,28 @@ export class Calculator {
|
||||||
logger.debug(`技能倍率:${Multiplier}`);
|
logger.debug(`技能倍率:${Multiplier}`);
|
||||||
return Multiplier;
|
return Multiplier;
|
||||||
}
|
}
|
||||||
get_AnomalyData(type) {
|
get_AnomalyData(anomaly) {
|
||||||
|
if (!anomaly) {
|
||||||
|
return AnomalyData.find(({ element_type, sub_element_type, multiplier }) => multiplier &&
|
||||||
|
element_type === this.avatar.element_type &&
|
||||||
|
sub_element_type === this.avatar.sub_element_type);
|
||||||
|
}
|
||||||
let a = AnomalyData.filter(({ element_type }) => element_type === this.avatar.element_type);
|
let a = AnomalyData.filter(({ element_type }) => element_type === this.avatar.element_type);
|
||||||
if (type === '紊乱')
|
if (anomaly === '紊乱')
|
||||||
a = a.filter(({ discover }) => discover);
|
a = a.filter(({ discover }) => discover);
|
||||||
else
|
else
|
||||||
a = a.filter(({ name, multiplier }) => name === type && multiplier);
|
a = a.filter(({ name, multiplier }) => name === anomaly && multiplier);
|
||||||
if (a.length === 1)
|
if (a.length === 1)
|
||||||
return a[0];
|
return a[0];
|
||||||
a = a.filter(({ sub_element_type }) => sub_element_type === this.avatar.sub_element_type);
|
a = a.filter(({ sub_element_type }) => sub_element_type === this.avatar.sub_element_type);
|
||||||
return a[0];
|
return a[0];
|
||||||
}
|
}
|
||||||
get_AnomalyMultiplier(skill, usefulBuffs, times = 0) {
|
get_AnomalyMultiplier(skill, usefulBuffs, times = 0) {
|
||||||
const anomalyData = this.get_AnomalyData(skill.type);
|
const anomalyData = this.get_AnomalyData(skill?.type.slice(0, 2));
|
||||||
if (!anomalyData)
|
if (!anomalyData)
|
||||||
return;
|
return;
|
||||||
let Multiplier = anomalyData.multiplier;
|
let Multiplier = anomalyData.multiplier;
|
||||||
if (anomalyData.duration && anomalyData.interval) {
|
if (times !== 1 && anomalyData.duration && anomalyData.interval) {
|
||||||
const AnomalyDuration = this.get_AnomalyDuration(skill, usefulBuffs, anomalyData.duration);
|
const AnomalyDuration = this.get_AnomalyDuration(skill, usefulBuffs, anomalyData.duration);
|
||||||
times ||= Math.floor((AnomalyDuration * 10) / (anomalyData.interval * 10));
|
times ||= Math.floor((AnomalyDuration * 10) / (anomalyData.interval * 10));
|
||||||
Multiplier = anomalyData.multiplier * times;
|
Multiplier = anomalyData.multiplier * times;
|
||||||
|
|
@ -397,7 +402,7 @@ export class Calculator {
|
||||||
return Multiplier;
|
return Multiplier;
|
||||||
}
|
}
|
||||||
get_DiscoverMultiplier(skill) {
|
get_DiscoverMultiplier(skill) {
|
||||||
const anomalyData = this.get_AnomalyData(skill.type);
|
const anomalyData = this.get_AnomalyData(skill?.type.slice(0, 2));
|
||||||
if (!anomalyData)
|
if (!anomalyData)
|
||||||
return;
|
return;
|
||||||
const AnomalyDuration = this.get_AnomalyDuration({
|
const AnomalyDuration = this.get_AnomalyDuration({
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,7 @@ export interface damage {
|
||||||
x?: (n: number) => void
|
x?: (n: number) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** ID 2 EN */
|
||||||
const elementType2element = (elementType: number) => elementEnum[[0, 1, 2, 3, -1, 4][elementType - 200]] as element
|
const elementType2element = (elementType: number) => elementEnum[[0, 1, 2, 3, -1, 4][elementType - 200]] as element
|
||||||
|
|
||||||
const subBaseValueData = {
|
const subBaseValueData = {
|
||||||
|
|
@ -265,7 +266,7 @@ export class Calculator {
|
||||||
}, this)
|
}, this)
|
||||||
const areas = {} as damage['areas']
|
const areas = {} as damage['areas']
|
||||||
if (skill.before) skill.before({ avatar: this.avatar, calc: this, usefulBuffs, skill, props, areas })
|
if (skill.before) skill.before({ avatar: this.avatar, calc: this, usefulBuffs, skill, props, areas })
|
||||||
const isAnomaly = typeof anomalyEnum[skill.type as anomaly] === 'number'
|
const isAnomaly = typeof anomalyEnum[skill.type.slice(0, 2) as anomaly] === 'number'
|
||||||
if (!areas.BasicArea) {
|
if (!areas.BasicArea) {
|
||||||
let Multiplier = props.倍率
|
let Multiplier = props.倍率
|
||||||
if (!Multiplier) {
|
if (!Multiplier) {
|
||||||
|
|
@ -273,7 +274,7 @@ export class Calculator {
|
||||||
Multiplier = skill.fixedMultiplier
|
Multiplier = skill.fixedMultiplier
|
||||||
} else if (isAnomaly) {
|
} else if (isAnomaly) {
|
||||||
Multiplier = (
|
Multiplier = (
|
||||||
skill.type === '紊乱' ?
|
skill.type.startsWith('紊乱') ?
|
||||||
this.get_DiscoverMultiplier(skill) :
|
this.get_DiscoverMultiplier(skill) :
|
||||||
this.get_AnomalyMultiplier(skill, usefulBuffs, skill.name.includes('每') ? 1 : 0)
|
this.get_AnomalyMultiplier(skill, usefulBuffs, skill.name.includes('每') ? 1 : 0)
|
||||||
) || 0
|
) || 0
|
||||||
|
|
@ -295,7 +296,7 @@ export class Calculator {
|
||||||
areas.AnomalyProficiencyArea ??= this.get_AnomalyProficiencyArea(skill, usefulBuffs)
|
areas.AnomalyProficiencyArea ??= this.get_AnomalyProficiencyArea(skill, usefulBuffs)
|
||||||
areas.AnomalyBoostArea ??= this.get_AnomalyBoostArea(skill, usefulBuffs)
|
areas.AnomalyBoostArea ??= this.get_AnomalyBoostArea(skill, usefulBuffs)
|
||||||
areas.LevelArea ??= this.get_LevelArea()
|
areas.LevelArea ??= this.get_LevelArea()
|
||||||
if (skill.type !== '紊乱') { // 紊乱暂无异常暴击区
|
if (!skill.type.startsWith('紊乱')) { // 紊乱暂无异常暴击区
|
||||||
props.异常暴击率 ??= this.get_AnomalyCRITRate(skill, usefulBuffs)
|
props.异常暴击率 ??= this.get_AnomalyCRITRate(skill, usefulBuffs)
|
||||||
props.异常暴击伤害 ??= this.get_AnomalyCRITDMG(skill, usefulBuffs)
|
props.异常暴击伤害 ??= this.get_AnomalyCRITDMG(skill, usefulBuffs)
|
||||||
areas.CriticalArea ??= 1 + props.异常暴击率! * (props.异常暴击伤害! - 1)
|
areas.CriticalArea ??= 1 + props.异常暴击率! * (props.异常暴击伤害! - 1)
|
||||||
|
|
@ -573,10 +574,21 @@ export class Calculator {
|
||||||
return Multiplier
|
return Multiplier
|
||||||
}
|
}
|
||||||
|
|
||||||
get_AnomalyData(type: skill['type']) {
|
/** 获取角色自身**出伤**异常的异常数据 */
|
||||||
|
get_AnomalyData(): typeof AnomalyData[number]
|
||||||
|
/** 获取角色自身**指定**异常的异常数据 */
|
||||||
|
get_AnomalyData(anomaly: anomaly): typeof AnomalyData[number]
|
||||||
|
get_AnomalyData(anomaly?: anomaly) {
|
||||||
|
if (!anomaly) {
|
||||||
|
return AnomalyData.find(({ element_type, sub_element_type, multiplier }) =>
|
||||||
|
multiplier &&
|
||||||
|
element_type === this.avatar.element_type &&
|
||||||
|
sub_element_type === this.avatar.sub_element_type
|
||||||
|
)
|
||||||
|
}
|
||||||
let a = AnomalyData.filter(({ element_type }) => element_type === this.avatar.element_type)
|
let a = AnomalyData.filter(({ element_type }) => element_type === this.avatar.element_type)
|
||||||
if (type === '紊乱') a = a.filter(({ discover }) => discover)
|
if (anomaly === '紊乱') a = a.filter(({ discover }) => discover)
|
||||||
else a = a.filter(({ name, multiplier }) => name === type && multiplier)
|
else a = a.filter(({ name, multiplier }) => name === anomaly && multiplier)
|
||||||
if (a.length === 1) return a[0]
|
if (a.length === 1) return a[0]
|
||||||
a = a.filter(({ sub_element_type }) => sub_element_type === this.avatar.sub_element_type)
|
a = a.filter(({ sub_element_type }) => sub_element_type === this.avatar.sub_element_type)
|
||||||
return a[0]
|
return a[0]
|
||||||
|
|
@ -584,10 +596,10 @@ export class Calculator {
|
||||||
|
|
||||||
/** 获取属性异常倍率 */
|
/** 获取属性异常倍率 */
|
||||||
get_AnomalyMultiplier(skill: skill, usefulBuffs: buff[], times = 0) {
|
get_AnomalyMultiplier(skill: skill, usefulBuffs: buff[], times = 0) {
|
||||||
const anomalyData = this.get_AnomalyData(skill.type)
|
const anomalyData = this.get_AnomalyData(skill?.type.slice(0, 2) as anomaly)
|
||||||
if (!anomalyData) return
|
if (!anomalyData) return
|
||||||
let Multiplier = anomalyData.multiplier
|
let Multiplier = anomalyData.multiplier
|
||||||
if (anomalyData.duration && anomalyData.interval) {
|
if (times !== 1 && anomalyData.duration && anomalyData.interval) {
|
||||||
const AnomalyDuration = this.get_AnomalyDuration(skill, usefulBuffs, anomalyData.duration)
|
const AnomalyDuration = this.get_AnomalyDuration(skill, usefulBuffs, anomalyData.duration)
|
||||||
times ||= Math.floor((AnomalyDuration * 10) / (anomalyData.interval * 10))
|
times ||= Math.floor((AnomalyDuration * 10) / (anomalyData.interval * 10))
|
||||||
Multiplier = anomalyData.multiplier * times
|
Multiplier = anomalyData.multiplier * times
|
||||||
|
|
@ -598,7 +610,7 @@ export class Calculator {
|
||||||
|
|
||||||
/** 获取紊乱倍率 */
|
/** 获取紊乱倍率 */
|
||||||
get_DiscoverMultiplier(skill: skill) {
|
get_DiscoverMultiplier(skill: skill) {
|
||||||
const anomalyData = this.get_AnomalyData(skill.type)
|
const anomalyData = this.get_AnomalyData(skill?.type.slice(0, 2) as anomaly)
|
||||||
if (!anomalyData) return
|
if (!anomalyData) return
|
||||||
const AnomalyDuration = this.get_AnomalyDuration({
|
const AnomalyDuration = this.get_AnomalyDuration({
|
||||||
...skill,
|
...skill,
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
- 元组:[评分规则名, 权重数据]
|
- 元组:[评分规则名, 权重数据]
|
||||||
- 类型:**[string, { [词条名: string]: number }]**
|
- 类型:**[string, { [词条名: string]: number }]**
|
||||||
- 若返回其他类型,会自动选择默认评分规则
|
- 若返回其他类型,会自动选择默认评分规则
|
||||||
|
- 自定义权重会以默认权重为基础值,即**自定义权重中未指定的词条会取默认权重中的数据**
|
||||||
|
|
||||||
## 方法二:直接修改默认权重
|
## 方法二:直接修改默认权重
|
||||||
|
|
||||||
|
|
@ -207,8 +208,7 @@ Buff来源可分为三大类:武器、套装、角色(影画、核心被动
|
||||||
- 游戏中的buff生效情况错综复杂,但通过[自定义敌方属性](#自定义敌方属性)和对buff的精确管控,插件的计算结果将与游戏实机十分吻合
|
- 游戏中的buff生效情况错综复杂,但通过[自定义敌方属性](#自定义敌方属性)和对buff的精确管控,插件的计算结果将与游戏实机十分吻合
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img width="251" src="https://s2.loli.net/2025/01/14/o6mi3LKdgGtT2RP.jpg" title="悠真伤害统计">
|
<img width="800" src="https://s2.loli.net/2025/05/30/FIvQ5DCAZBcT9z1.png" title="薇薇安伤害计算">
|
||||||
<img width="251" src="https://s2.loli.net/2025/01/14/Ue5kLpha7N621Px.jpg" title="悠真游戏实机">
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
## 技能属性
|
## 技能属性
|
||||||
|
|
@ -276,6 +276,8 @@ Buff来源可分为三大类:武器、套装、角色(影画、核心被动
|
||||||
> - 感电
|
> - 感电
|
||||||
> - 侵蚀
|
> - 侵蚀
|
||||||
> - 紊乱
|
> - 紊乱
|
||||||
|
>
|
||||||
|
> 当需要对属性异常进行变体时(如薇薇安的异放),使命名以属性异常名开头即可(如 侵蚀·异放),注意buff作用范围需保持同步
|
||||||
|
|
||||||
> - 追加攻击
|
> - 追加攻击
|
||||||
> - 直接以“追加攻击”命名
|
> - 直接以“追加攻击”命名
|
||||||
|
|
@ -327,7 +329,7 @@ buff作用范围将以技能类型命名为依据向后覆盖。以上述[艾莲
|
||||||
|
|
||||||
- 属性异常中**强击**和**碎冰**没有持续时间的概念,总倍率不受持续时间的影响也无法结算紊乱。因此对于作用于**异常持续时间**的buff,其buff.range应填写异常对应的**状态异常**(**畏缩**和**霜寒**),灼烧等既是伤害异常也是状态异常则无需区分
|
- 属性异常中**强击**和**碎冰**没有持续时间的概念,总倍率不受持续时间的影响也无法结算紊乱。因此对于作用于**异常持续时间**的buff,其buff.range应填写异常对应的**状态异常**(**畏缩**和**霜寒**),灼烧等既是伤害异常也是状态异常则无需区分
|
||||||
|
|
||||||
- 对于`“X"(造成的伤害)被视为“Y”(伤害)`此类特殊技能,需要指定技能**重定向参数**,同时上述buff覆盖规则会发生变化,具体请参考[源码内描述](./Calculator.ts#L22)
|
- 对于`“X"(造成的伤害)被视为“Y”(伤害)`此类特殊技能,需要指定技能**重定向参数**,同时上述buff覆盖规则会发生变化,具体请参考[源码内描述](./Calculator.ts#L23)
|
||||||
|
|
||||||
> 需要注意的是:即使出现`“X"(造成的伤害)被视为“Y”(伤害)`,对**Y**类型的增益**X**不一定能吃到,视具体情况变化
|
> 需要注意的是:即使出现`“X"(造成的伤害)被视为“Y”(伤害)`,对**Y**类型的增益**X**不一定能吃到,视具体情况变化
|
||||||
|
|
||||||
|
|
@ -428,7 +430,7 @@ counter(145.7, 159, 16)
|
||||||
|
|
||||||
敌方基础属性可查看[此表](https://img.nga.178.com/attachments/mon_202407/16/axvkQq44x-2xpiZyT3cSwm-1hf.png)
|
敌方基础属性可查看[此表](https://img.nga.178.com/attachments/mon_202407/16/axvkQq44x-2xpiZyT3cSwm-1hf.png)
|
||||||
|
|
||||||
例如将敌人的1级基础防御力设置为36:
|
例如将敌人的1级基础防御力设置为36(如提尔锋):
|
||||||
|
|
||||||
```JS
|
```JS
|
||||||
export function calc(buffM, calc, avatar) {
|
export function calc(buffM, calc, avatar) {
|
||||||
|
|
|
||||||
106
model/damage/character/薇薇安/calc.js
Normal file
106
model/damage/character/薇薇安/calc.js
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
/** @type {import('../../BuffManager.ts').BuffManager['buffs']} */
|
||||||
|
export const buffs = [
|
||||||
|
{
|
||||||
|
name: '1影',
|
||||||
|
type: '异常增伤', // 异常易伤?
|
||||||
|
value: 0.16,
|
||||||
|
is: {
|
||||||
|
team: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '2影',
|
||||||
|
type: '无视抗性',
|
||||||
|
value: 0.15,
|
||||||
|
range: ['侵蚀·异放']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '4影',
|
||||||
|
type: '暴击率',
|
||||||
|
value: 1,
|
||||||
|
range: ['AX', 'AH']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '4影',
|
||||||
|
type: '攻击力',
|
||||||
|
value: 0.12
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '6影',
|
||||||
|
type: '增伤',
|
||||||
|
value: 0.4,
|
||||||
|
element: 'Ether',
|
||||||
|
isForever: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '额外能力:预言之泪',
|
||||||
|
type: '异常增伤',
|
||||||
|
value: 0.12,
|
||||||
|
// 侵蚀、侵蚀结算的紊乱生效
|
||||||
|
check: ({ calc }) => calc.skill.element === 'Ether',
|
||||||
|
range: ['侵蚀', '紊乱']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
/** @param {import('../../Calculator.ts').Calculator} vva */
|
||||||
|
const generateBefore = (vva) => {
|
||||||
|
/** @type {import('../../Calculator.ts').skill['before']} */
|
||||||
|
const before = ({ avatar, calc, areas }) => {
|
||||||
|
const AnomalyMultiplier = calc.get_AnomalyMultiplier(undefined, undefined, 1)
|
||||||
|
const ATK = calc.get_ATK(calc.skill)
|
||||||
|
const AnomalyProficiency = vva.get_AnomalyProficiency(calc.skill)
|
||||||
|
const skillMultiplier = vva.get_SkillMultiplier(`TY${avatar.element_type}`)
|
||||||
|
const n = AnomalyProficiency / 10 * skillMultiplier * (vva.avatar.rank >= 2 ? 1.3 : 1)
|
||||||
|
areas.BasicArea = ATK * AnomalyMultiplier * n
|
||||||
|
}
|
||||||
|
return before
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @type {import('../../Calculator.ts').Calculator['skills']} */
|
||||||
|
export const skills = [
|
||||||
|
{ name: '侵蚀每段', type: '侵蚀' },
|
||||||
|
{ name: '紊乱', type: '紊乱' },
|
||||||
|
{
|
||||||
|
name: '异放·结算薇薇安',
|
||||||
|
type: '侵蚀·异放',
|
||||||
|
isMain: true,
|
||||||
|
banCache: true,
|
||||||
|
before: (data) => generateBefore(data.calc)(data)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '6影特殊异放·5护羽',
|
||||||
|
type: '侵蚀·异放',
|
||||||
|
check: 6,
|
||||||
|
banCache: true,
|
||||||
|
dmg: (calc) => {
|
||||||
|
const dmg = calc.calc_skill({
|
||||||
|
...calc.skills.find(skill => skill.type === '侵蚀·异放'),
|
||||||
|
after: ({ damage }) => damage.x(5)
|
||||||
|
})
|
||||||
|
dmg.skill.name = '6影特殊异放·5护羽'
|
||||||
|
return dmg
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ name: '普攻:翎羽拂击四段', type: 'AP4' },
|
||||||
|
{ name: '普攻:淑女礼仪·舞步', type: 'AT' },
|
||||||
|
{ name: '普攻:裙裾浮游·悬落', type: 'AX' },
|
||||||
|
{ name: '普攻:落羽生花', type: 'AH' },
|
||||||
|
{
|
||||||
|
name: '薇薇安的预言',
|
||||||
|
type: 'TW',
|
||||||
|
fixedMultiplier: 0.55
|
||||||
|
},
|
||||||
|
{ name: '闪避反击:羽刃反振', type: 'CF' },
|
||||||
|
{ name: '强化特殊技:堇花悼亡', type: 'EQ' },
|
||||||
|
{ name: '连携技:星羽和声', type: 'RL' },
|
||||||
|
{ name: '终结技:飞鸟鸣颂', type: 'RZ' }
|
||||||
|
]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {import('../../BuffManager.ts').BuffManager} buffM
|
||||||
|
* @param {import('../../Calculator.ts').Calculator} calc
|
||||||
|
* @param {import('../../../avatar.js').ZZZAvatarInfo} avatar
|
||||||
|
*/
|
||||||
|
// export function calc(buffM, calc, avatar) {
|
||||||
|
|
||||||
|
// }
|
||||||
43
model/damage/character/薇薇安/data.json
Normal file
43
model/damage/character/薇薇安/data.json
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
{
|
||||||
|
"skill": {
|
||||||
|
"AP4": [
|
||||||
|
1.284,1.401,1.518,1.635,1.752,1.869,1.986,2.103,2.22,2.337,2.454,2.571,2.688,2.805,2.922,3.039
|
||||||
|
],
|
||||||
|
"AT": [
|
||||||
|
0.478,0.522,0.566,0.61,0.654,0.698,0.742,0.786,0.83,0.874,0.918,0.962,1.006,1.05,1.094,1.138
|
||||||
|
],
|
||||||
|
"AX": [
|
||||||
|
0.802,0.875,0.948,1.021,1.094,1.167,1.24,1.313,1.386,1.459,1.532,1.605,1.678,1.751,1.824,1.897
|
||||||
|
],
|
||||||
|
"AH": [
|
||||||
|
2.2,2.4,2.6,2.8,3,3.2,3.4,3.6,3.8,4,4.2,4.4,4.6,4.8,5,5.2
|
||||||
|
],
|
||||||
|
"CF": [
|
||||||
|
2.364,2.579,2.794,3.009,3.224,3.439,3.654,3.869,4.084,4.299,4.514,4.729,4.944,5.159,5.374,5.589
|
||||||
|
],
|
||||||
|
"EQ": [
|
||||||
|
5.926,6.465,7.004,7.543,8.082,8.621,9.16,9.699,10.238,10.777,11.316,11.855,12.394,12.933,13.472,14.011
|
||||||
|
],
|
||||||
|
"RL": [
|
||||||
|
6.589,7.188,7.787,8.386,8.985,9.584,10.183,10.782,11.381,11.98,12.579,13.178,13.777,14.376,14.975,15.574
|
||||||
|
],
|
||||||
|
"RZ": [
|
||||||
|
16.868,18.402,19.936,21.47,23.004,24.538,26.072,27.606,29.14,30.674,32.208,33.742,35.276,36.81,38.344,39.878
|
||||||
|
],
|
||||||
|
"TY200": [
|
||||||
|
0.0037,0.0044,0.0051,0.0058,0.0065,0.007,0.0075
|
||||||
|
],
|
||||||
|
"TY201": [
|
||||||
|
0.04,0.0466,0.0532,0.0598,0.0664,0.073,0.08
|
||||||
|
],
|
||||||
|
"TY202": [
|
||||||
|
0.0054,0.0063,0.0072,0.0081,0.009,0.0099,0.0108
|
||||||
|
],
|
||||||
|
"TY203": [
|
||||||
|
0.016,0.0186,0.0212,0.0238,0.0264,0.029,0.032
|
||||||
|
],
|
||||||
|
"TY205": [
|
||||||
|
0.0307,0.0359,0.0411,0.0463,0.0515,0.0565,0.0615
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
7
model/damage/weapon/飞鸟星梦.js
Normal file
7
model/damage/weapon/飞鸟星梦.js
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
/** @type {import('../BuffManager.ts').BuffManager['buffs']} */
|
||||||
|
export const buffs = [
|
||||||
|
{
|
||||||
|
type: '异常精通',
|
||||||
|
value: [20, 23, 26, 29, 32].map(v => v * 6)
|
||||||
|
}
|
||||||
|
]
|
||||||
Loading…
Add table
Add a link
Reference in a new issue