mirror of
https://github.com/ZZZure/ZZZ-Plugin.git
synced 2025-12-16 13:17:32 +00:00
新增露西伤害计算等
This commit is contained in:
parent
208cb0ae05
commit
cecc33b24d
7 changed files with 265 additions and 133 deletions
|
|
@ -9,7 +9,7 @@ export class Calculator {
|
||||||
avatar;
|
avatar;
|
||||||
skills = [];
|
skills = [];
|
||||||
cache = {};
|
cache = {};
|
||||||
damageCache = {};
|
props = {};
|
||||||
defaultSkill = {};
|
defaultSkill = {};
|
||||||
enemy;
|
enemy;
|
||||||
constructor(buffM) {
|
constructor(buffM) {
|
||||||
|
|
@ -54,8 +54,8 @@ export class Calculator {
|
||||||
return;
|
return;
|
||||||
return this.calc_skill(MySkill);
|
return this.calc_skill(MySkill);
|
||||||
}
|
}
|
||||||
if (!skill.banCache && this.damageCache[skill.type])
|
if (!skill.banCache && this.cache[skill.type])
|
||||||
return this.damageCache[skill.type];
|
return this.cache[skill.type];
|
||||||
if (skill.check && !skill.check({ avatar: this.avatar, buffM: this.buffM, calc: this }))
|
if (skill.check && !skill.check({ avatar: this.avatar, buffM: this.buffM, calc: this }))
|
||||||
return;
|
return;
|
||||||
logger.debug(`${logger.green(skill.type)}${skill.name}伤害计算:`);
|
logger.debug(`${logger.green(skill.type)}${skill.name}伤害计算:`);
|
||||||
|
|
@ -64,71 +64,74 @@ export class Calculator {
|
||||||
logger.debug('自定义计算最终伤害:', dmg.result);
|
logger.debug('自定义计算最终伤害:', dmg.result);
|
||||||
return dmg;
|
return dmg;
|
||||||
}
|
}
|
||||||
this.cache = {};
|
const props = this.props = skill.props || {};
|
||||||
/** 缩小筛选范围 */
|
/** 缩小筛选范围 */
|
||||||
const usefulBuffs = this.buffM.filter({
|
const usefulBuffs = this.buffM.filter({
|
||||||
element: skill.element,
|
element: skill.element,
|
||||||
range: skill.redirect ? [skill.type, skill.redirect] : [skill.type]
|
range: skill.redirect ? [skill.type, skill.redirect] : [skill.type]
|
||||||
}, this);
|
}, this);
|
||||||
const detail = {};
|
const areas = {};
|
||||||
if (skill.before)
|
if (skill.before)
|
||||||
skill.before({ avatar: this.avatar, calc: this, detail, skill, usefulBuffs, });
|
skill.before({ avatar: this.avatar, calc: this, usefulBuffs, skill, props, areas });
|
||||||
const isAnomaly = typeof anomalyEnum[skill.type] === 'number';
|
const isAnomaly = typeof anomalyEnum[skill.type] === 'number';
|
||||||
if (!detail.BasicArea) {
|
if (!areas.BasicArea) {
|
||||||
if (!detail.Multiplier) {
|
let Multiplier = props.倍率;
|
||||||
|
if (!Multiplier) {
|
||||||
if (skill.fixedMultiplier) {
|
if (skill.fixedMultiplier) {
|
||||||
detail.Multiplier = skill.fixedMultiplier;
|
Multiplier = skill.fixedMultiplier;
|
||||||
}
|
}
|
||||||
else if (isAnomaly) {
|
else if (isAnomaly) {
|
||||||
detail.Multiplier = (skill.type === '紊乱' ?
|
Multiplier = (skill.type === '紊乱' ?
|
||||||
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;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (skill.skillMultiplier)
|
if (skill.skillMultiplier)
|
||||||
detail.Multiplier = skill.skillMultiplier[this.get_SkillLevel(skill.type[0]) - 1];
|
Multiplier = skill.skillMultiplier[this.get_SkillLevel(skill.type[0]) - 1];
|
||||||
else
|
else
|
||||||
detail.Multiplier = this.get_Multiplier(skill.type);
|
Multiplier = this.get_SkillMultiplier(skill.type);
|
||||||
}
|
}
|
||||||
const ExtraMultiplier = this.get_ExtraMultiplier(skill, usefulBuffs);
|
const ExtraMultiplier = this.get_ExtraMultiplier(skill, usefulBuffs);
|
||||||
detail.Multiplier += ExtraMultiplier;
|
Multiplier += ExtraMultiplier;
|
||||||
if (!detail.Multiplier)
|
if (!Multiplier)
|
||||||
return logger.warn('技能倍率缺失:', skill);
|
return logger.warn('技能倍率缺失:', skill);
|
||||||
if (ExtraMultiplier)
|
if (ExtraMultiplier)
|
||||||
logger.debug(`最终倍率:${detail.Multiplier}`);
|
logger.debug(`最终倍率:${Multiplier}`);
|
||||||
}
|
}
|
||||||
detail.ATK ??= this.get_ATK(skill, usefulBuffs);
|
props.倍率 = Multiplier;
|
||||||
|
this.get_ATK(skill, usefulBuffs);
|
||||||
|
areas.BasicArea = props.攻击力 * props.倍率;
|
||||||
}
|
}
|
||||||
detail.BasicArea ??= detail.ATK * detail.Multiplier;
|
logger.debug(`基础伤害区:${areas.BasicArea}`);
|
||||||
logger.debug(`基础伤害区:${detail.BasicArea}`);
|
|
||||||
if (isAnomaly) {
|
if (isAnomaly) {
|
||||||
detail.AnomalyProficiencyArea ??= this.get_AnomalyProficiencyArea(skill, usefulBuffs);
|
areas.AnomalyProficiencyArea ??= this.get_AnomalyProficiencyArea(skill, usefulBuffs);
|
||||||
detail.AnomalyBoostArea ??= this.get_AnomalyBoostArea(skill, usefulBuffs);
|
areas.AnomalyBoostArea ??= this.get_AnomalyBoostArea(skill, usefulBuffs);
|
||||||
detail.LevelArea ??= this.get_LevelArea();
|
areas.LevelArea ??= this.get_LevelArea();
|
||||||
detail.AnomalyCRITRate ??= this.get_AnomalyCRITRate(skill, usefulBuffs);
|
this.get_AnomalyCRITRate(skill, usefulBuffs);
|
||||||
detail.AnomalyCRITDMG ??= this.get_AnomalyCRITDMG(skill, usefulBuffs);
|
this.get_AnomalyCRITDMG(skill, usefulBuffs);
|
||||||
detail.CriticalArea ??= 1 + detail.AnomalyCRITRate * (detail.AnomalyCRITDMG - 1);
|
areas.CriticalArea ??= 1 + props.异常暴击率 * (props.异常暴击伤害 - 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
detail.CRITRate ??= this.get_CRITRate(skill, usefulBuffs);
|
this.get_CRITRate(skill, usefulBuffs);
|
||||||
detail.CRITDMG ??= this.get_CRITDMG(skill, usefulBuffs);
|
this.get_CRITDMG(skill, usefulBuffs);
|
||||||
detail.CriticalArea ??= 1 + detail.CRITRate * (detail.CRITDMG - 1);
|
areas.CriticalArea ??= 1 + props.暴击率 * (props.暴击伤害 - 1);
|
||||||
}
|
}
|
||||||
logger.debug(`暴击期望:${detail.CriticalArea}`);
|
logger.debug(`暴击期望:${areas.CriticalArea}`);
|
||||||
detail.BoostArea ??= this.get_BoostArea(skill, usefulBuffs);
|
areas.BoostArea ??= this.get_BoostArea(skill, usefulBuffs);
|
||||||
detail.VulnerabilityArea ??= this.get_VulnerabilityArea(skill, usefulBuffs);
|
areas.VulnerabilityArea ??= this.get_VulnerabilityArea(skill, usefulBuffs);
|
||||||
detail.ResistanceArea ??= this.get_ResistanceArea(skill, usefulBuffs);
|
areas.ResistanceArea ??= this.get_ResistanceArea(skill, usefulBuffs);
|
||||||
detail.DefenceArea ??= this.get_DefenceArea(skill, usefulBuffs);
|
areas.DefenceArea ??= this.get_DefenceArea(skill, usefulBuffs);
|
||||||
const { BasicArea, CRITDMG, CriticalArea, BoostArea, VulnerabilityArea, ResistanceArea, DefenceArea, AnomalyProficiencyArea, LevelArea, AnomalyBoostArea, AnomalyCRITRate, AnomalyCRITDMG } = detail;
|
const { BasicArea, CriticalArea, BoostArea, VulnerabilityArea, ResistanceArea, DefenceArea, AnomalyProficiencyArea, LevelArea, AnomalyBoostArea } = areas;
|
||||||
|
const { 暴击伤害, 异常暴击伤害 } = props;
|
||||||
const result = isAnomaly ?
|
const result = isAnomaly ?
|
||||||
{
|
{
|
||||||
critDMG: AnomalyCRITRate ? BasicArea * AnomalyCRITDMG * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea * AnomalyProficiencyArea * LevelArea * AnomalyBoostArea : 0,
|
critDMG: (CriticalArea !== 1) ? BasicArea * 异常暴击伤害 * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea * AnomalyProficiencyArea * LevelArea * AnomalyBoostArea : 0,
|
||||||
expectDMG: BasicArea * CriticalArea * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea * AnomalyProficiencyArea * LevelArea * AnomalyBoostArea
|
expectDMG: BasicArea * CriticalArea * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea * AnomalyProficiencyArea * LevelArea * AnomalyBoostArea
|
||||||
} : {
|
} : {
|
||||||
critDMG: BasicArea * CRITDMG * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea,
|
critDMG: BasicArea * 暴击伤害 * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea,
|
||||||
expectDMG: BasicArea * CriticalArea * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea
|
expectDMG: BasicArea * CriticalArea * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea
|
||||||
};
|
};
|
||||||
const damage = { skill, detail, result };
|
const damage = { skill, props, areas, result };
|
||||||
if (skill.after) {
|
if (skill.after) {
|
||||||
damage.add = (d) => {
|
damage.add = (d) => {
|
||||||
if (typeof d === 'string')
|
if (typeof d === 'string')
|
||||||
|
|
@ -145,11 +148,12 @@ export class Calculator {
|
||||||
logger.debug('伤害系数:' + n);
|
logger.debug('伤害系数:' + n);
|
||||||
damage.fnc(v => v * n);
|
damage.fnc(v => v * n);
|
||||||
};
|
};
|
||||||
skill.after({ avatar: this.avatar, damage, calc: this, usefulBuffs });
|
skill.after({ avatar: this.avatar, calc: this, usefulBuffs, skill, damage });
|
||||||
}
|
}
|
||||||
logger.debug('最终伤害:', result);
|
logger.debug('最终伤害:', result);
|
||||||
if (!skill.banCache)
|
if (!skill.banCache)
|
||||||
this.damageCache[skill.type] = damage;
|
this.cache[skill.type] = damage;
|
||||||
|
// console.log(damage)
|
||||||
return damage;
|
return damage;
|
||||||
}
|
}
|
||||||
calc() {
|
calc() {
|
||||||
|
|
@ -188,10 +192,10 @@ export class Calculator {
|
||||||
* 获取技能倍率
|
* 获取技能倍率
|
||||||
* @param type 参见技能命名标准
|
* @param type 参见技能命名标准
|
||||||
*/
|
*/
|
||||||
get_Multiplier(type) {
|
get_SkillMultiplier(type) {
|
||||||
const skillLevel = this.get_SkillLevel(type[0]);
|
const SkillLevel = this.get_SkillLevel(type[0]);
|
||||||
logger.debug(`${type[0]}等级:${skillLevel}`);
|
logger.debug(`${type[0]}等级:${SkillLevel}`);
|
||||||
const Multiplier = charData[this.avatar.id].skill[type]?.[skillLevel - 1];
|
const Multiplier = charData[this.avatar.id].skill[type]?.[SkillLevel - 1];
|
||||||
logger.debug(`技能倍率:${Multiplier}`);
|
logger.debug(`技能倍率:${Multiplier}`);
|
||||||
return Multiplier;
|
return Multiplier;
|
||||||
}
|
}
|
||||||
|
|
@ -258,7 +262,7 @@ export class Calculator {
|
||||||
* @param isRatio 是否支持buff.value为数值类型且<1时按初始数值百分比提高处理
|
* @param isRatio 是否支持buff.value为数值类型且<1时按初始数值百分比提高处理
|
||||||
*/
|
*/
|
||||||
get(type, initial, skill, usefulBuffs = this.buffM.buffs, isRatio = false) {
|
get(type, initial, skill, usefulBuffs = this.buffM.buffs, isRatio = false) {
|
||||||
return this.cache[type] ??= this.buffM._filter(usefulBuffs, {
|
return this.props[type] ??= this.buffM._filter(usefulBuffs, {
|
||||||
element: skill?.element,
|
element: skill?.element,
|
||||||
range: skill?.redirect ? [skill.type, skill.redirect] : [skill?.type],
|
range: skill?.redirect ? [skill.type, skill.redirect] : [skill?.type],
|
||||||
type
|
type
|
||||||
|
|
@ -322,18 +326,24 @@ export class Calculator {
|
||||||
logger.debug(`抗性区:${ResistanceArea}`);
|
logger.debug(`抗性区:${ResistanceArea}`);
|
||||||
return ResistanceArea;
|
return ResistanceArea;
|
||||||
}
|
}
|
||||||
|
/** 无视防御 */
|
||||||
|
get_IgnoreDEF(skill, usefulBuffs) {
|
||||||
|
const IgnoreDEF = this.get('无视防御', 0, skill, usefulBuffs);
|
||||||
|
IgnoreDEF && logger.debug(`无视防御:${IgnoreDEF}`);
|
||||||
|
return IgnoreDEF;
|
||||||
|
}
|
||||||
/** 穿透值 */
|
/** 穿透值 */
|
||||||
get_Pen(skill, usefulBuffs) {
|
get_Pen(skill, usefulBuffs) {
|
||||||
let Pen = this.get('穿透值', this.initial_properties.Pen, skill, usefulBuffs);
|
let Pen = this.get('穿透值', this.initial_properties.Pen, skill, usefulBuffs);
|
||||||
Pen = Math.max(0, Math.min(Pen, 1000));
|
Pen = Math.max(0, Math.min(Pen, 1000));
|
||||||
logger.debug(`穿透值:${Pen}`);
|
Pen && logger.debug(`穿透值:${Pen}`);
|
||||||
return Pen;
|
return Pen;
|
||||||
}
|
}
|
||||||
/** 穿透率 */
|
/** 穿透率 */
|
||||||
get_PenRatio(skill, usefulBuffs) {
|
get_PenRatio(skill, usefulBuffs) {
|
||||||
let PenRatio = this.get('穿透率', this.initial_properties.PenRatio, skill, usefulBuffs);
|
let PenRatio = this.get('穿透率', this.initial_properties.PenRatio, skill, usefulBuffs);
|
||||||
PenRatio = Math.max(0, Math.min(PenRatio, 2));
|
PenRatio = Math.max(0, Math.min(PenRatio, 2));
|
||||||
logger.debug(`穿透率:${PenRatio}`);
|
PenRatio && logger.debug(`穿透率:${PenRatio}`);
|
||||||
return PenRatio;
|
return PenRatio;
|
||||||
}
|
}
|
||||||
/** 防御区 */
|
/** 防御区 */
|
||||||
|
|
@ -343,11 +353,11 @@ export class Calculator {
|
||||||
const base = get_base(this.avatar.level);
|
const base = get_base(this.avatar.level);
|
||||||
/** 基础防御 */
|
/** 基础防御 */
|
||||||
const DEF = this.enemy.basicDEF / 50 * get_base(this.enemy.level);
|
const DEF = this.enemy.basicDEF / 50 * get_base(this.enemy.level);
|
||||||
const ignore_defence = this.get('无视防御', 0, skill, usefulBuffs);
|
const IgnoreDEF = this.get_IgnoreDEF(skill, usefulBuffs);
|
||||||
const Pen = this.get_Pen(skill, usefulBuffs);
|
const Pen = this.get_Pen(skill, usefulBuffs);
|
||||||
const PenRatio = this.get_PenRatio(skill, usefulBuffs);
|
const PenRatio = this.get_PenRatio(skill, usefulBuffs);
|
||||||
/** 防御 */
|
/** 防御 */
|
||||||
const defence = DEF * (1 - ignore_defence);
|
const defence = DEF * (1 - IgnoreDEF);
|
||||||
/** 有效防御 */
|
/** 有效防御 */
|
||||||
const effective_defence = Math.max(0, defence * (1 - PenRatio) - Pen);
|
const effective_defence = Math.max(0, defence * (1 - PenRatio) - Pen);
|
||||||
const DefenceArea = base / (effective_defence + base);
|
const DefenceArea = base / (effective_defence + base);
|
||||||
|
|
@ -377,21 +387,21 @@ export class Calculator {
|
||||||
/** 异常增伤区 */
|
/** 异常增伤区 */
|
||||||
get_AnomalyBoostArea(skill, usefulBuffs) {
|
get_AnomalyBoostArea(skill, usefulBuffs) {
|
||||||
const AnomalyBoostArea = this.get('异常增伤', 1, skill, usefulBuffs);
|
const AnomalyBoostArea = this.get('异常增伤', 1, skill, usefulBuffs);
|
||||||
logger.debug(`异常增伤区:${AnomalyBoostArea}`);
|
AnomalyBoostArea && logger.debug(`异常增伤区:${AnomalyBoostArea}`);
|
||||||
return AnomalyBoostArea;
|
return AnomalyBoostArea;
|
||||||
}
|
}
|
||||||
/** 异常暴击率 */
|
/** 异常暴击率 */
|
||||||
get_AnomalyCRITRate(skill, usefulBuffs) {
|
get_AnomalyCRITRate(skill, usefulBuffs) {
|
||||||
let AnomalyCRITRate = this.get('异常暴击率', 0, skill, usefulBuffs);
|
let AnomalyCRITRate = this.get('异常暴击率', 0, skill, usefulBuffs);
|
||||||
AnomalyCRITRate = Math.max(0, Math.min(AnomalyCRITRate, 1));
|
AnomalyCRITRate = Math.max(0, Math.min(AnomalyCRITRate, 1));
|
||||||
logger.debug(`异常暴击率:${AnomalyCRITRate}`);
|
AnomalyCRITRate && logger.debug(`异常暴击率:${AnomalyCRITRate}`);
|
||||||
return AnomalyCRITRate;
|
return AnomalyCRITRate;
|
||||||
}
|
}
|
||||||
/** 异常暴击伤害 */
|
/** 异常暴击伤害 */
|
||||||
get_AnomalyCRITDMG(skill, usefulBuffs) {
|
get_AnomalyCRITDMG(skill, usefulBuffs) {
|
||||||
let AnomalyCRITDMG = this.get('异常暴击伤害', 1, skill, usefulBuffs);
|
let AnomalyCRITDMG = this.get('异常暴击伤害', 1, skill, usefulBuffs);
|
||||||
AnomalyCRITDMG = Math.max(0, Math.min(AnomalyCRITDMG, 5));
|
AnomalyCRITDMG = Math.max(0, Math.min(AnomalyCRITDMG, 5));
|
||||||
logger.debug(`异常暴击伤害:${AnomalyCRITDMG}`);
|
AnomalyCRITDMG && logger.debug(`异常暴击伤害:${AnomalyCRITDMG}`);
|
||||||
return AnomalyCRITDMG;
|
return AnomalyCRITDMG;
|
||||||
}
|
}
|
||||||
/** 异常持续时间 */
|
/** 异常持续时间 */
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import type { BuffManager, anomaly, buff, element } from './BuffManager.ts'
|
import type { BuffManager, anomaly, buff, buffType, element } from './BuffManager.ts'
|
||||||
import type { ZZZAvatarInfo } from '../avatar.js'
|
import type { ZZZAvatarInfo } from '../avatar.js'
|
||||||
import { getMapData } from '../../utils/file.js'
|
import { getMapData } from '../../utils/file.js'
|
||||||
import { elementEnum, anomalyEnum } from './BuffManager.js'
|
import { elementEnum, anomalyEnum } from './BuffManager.js'
|
||||||
|
|
@ -15,10 +15,10 @@ export interface skill {
|
||||||
element: element
|
element: element
|
||||||
/** 技能倍率数组,于character/角色名/data.json中自动获取,该json中不存在相应数据时可填写该值,以填写值为准 */
|
/** 技能倍率数组,于character/角色名/data.json中自动获取,该json中不存在相应数据时可填写该值,以填写值为准 */
|
||||||
skillMultiplier?: number[]
|
skillMultiplier?: number[]
|
||||||
/** 指定固定技能倍率 */
|
/** 指定常数倍率(可吃倍率增益) */
|
||||||
fixedMultiplier?: number
|
fixedMultiplier?: number
|
||||||
/** 角色面板伤害统计中是否隐藏显示 */
|
/** 指定局内固定属性 */
|
||||||
isHide?: boolean
|
props?: { [key in buffType]?: number }
|
||||||
/**
|
/**
|
||||||
* 重定向技能伤害类型
|
* 重定向技能伤害类型
|
||||||
*
|
*
|
||||||
|
|
@ -26,6 +26,8 @@ export interface skill {
|
||||||
* 参考技能类型命名标准
|
* 参考技能类型命名标准
|
||||||
*/
|
*/
|
||||||
redirect?: string
|
redirect?: string
|
||||||
|
/** 角色面板伤害统计中是否隐藏显示 */
|
||||||
|
isHide?: boolean
|
||||||
/** 禁用伤害计算cache */
|
/** 禁用伤害计算cache */
|
||||||
banCache?: boolean
|
banCache?: boolean
|
||||||
/** 是否计算该技能 */
|
/** 是否计算该技能 */
|
||||||
|
|
@ -36,19 +38,23 @@ export interface skill {
|
||||||
}) => boolean)
|
}) => boolean)
|
||||||
/** 自定义计算逻辑 */
|
/** 自定义计算逻辑 */
|
||||||
dmg?: (calc: Calculator) => damage
|
dmg?: (calc: Calculator) => damage
|
||||||
/** 额外处理 */
|
/** 伤害计算前调用,可自由定义各属性等 */
|
||||||
before?: ({ avatar, calc, usefulBuffs, detail, skill }: {
|
before?: ({ avatar, calc, usefulBuffs, skill, props, areas }: {
|
||||||
avatar: ZZZAvatarInfo
|
avatar: ZZZAvatarInfo
|
||||||
calc: Calculator
|
calc: Calculator
|
||||||
detail: damage['detail']
|
|
||||||
usefulBuffs: buff[]
|
usefulBuffs: buff[]
|
||||||
/** 技能自身 */
|
/** 技能自身 */
|
||||||
skill: skill
|
skill: skill
|
||||||
|
props: damage['props']
|
||||||
|
areas: damage['areas']
|
||||||
}) => void
|
}) => void
|
||||||
after?: ({ avatar, calc, usefulBuffs, damage }: {
|
/** 伤害计算后调用,可对结果进行修改等 */
|
||||||
|
after?: ({ avatar, calc, usefulBuffs, skill, damage }: {
|
||||||
avatar: ZZZAvatarInfo
|
avatar: ZZZAvatarInfo
|
||||||
calc: Calculator
|
calc: Calculator
|
||||||
usefulBuffs: buff[]
|
usefulBuffs: buff[]
|
||||||
|
/** 技能自身 */
|
||||||
|
skill: skill
|
||||||
damage: damage
|
damage: damage
|
||||||
}) => void
|
}) => void
|
||||||
}
|
}
|
||||||
|
|
@ -56,18 +62,12 @@ export interface skill {
|
||||||
export interface damage {
|
export interface damage {
|
||||||
/** 技能类型 */
|
/** 技能类型 */
|
||||||
skill: skill
|
skill: skill
|
||||||
/** 各乘区详细数据 */
|
/** 技能属性 */
|
||||||
detail: {
|
props?: skill['props']
|
||||||
/** 伤害倍率 */
|
/** 各乘区数据 */
|
||||||
Multiplier: number
|
areas: {
|
||||||
/** 攻击力 */
|
|
||||||
ATK: number
|
|
||||||
/** 基础伤害区 */
|
/** 基础伤害区 */
|
||||||
BasicArea: number
|
BasicArea: number
|
||||||
/** 暴击率 */
|
|
||||||
CRITRate: number
|
|
||||||
/** 暴伤伤害 */
|
|
||||||
CRITDMG: number
|
|
||||||
/** 暴击区期望 */
|
/** 暴击区期望 */
|
||||||
CriticalArea: number
|
CriticalArea: number
|
||||||
/** 增伤区 */
|
/** 增伤区 */
|
||||||
|
|
@ -78,10 +78,6 @@ export interface damage {
|
||||||
ResistanceArea: number
|
ResistanceArea: number
|
||||||
/** 防御区 */
|
/** 防御区 */
|
||||||
DefenceArea: number
|
DefenceArea: number
|
||||||
/** 异常暴击率 */
|
|
||||||
AnomalyCRITRate: number
|
|
||||||
/** 异常暴击伤害 */
|
|
||||||
AnomalyCRITDMG: number
|
|
||||||
/** 异常精通区 */
|
/** 异常精通区 */
|
||||||
AnomalyProficiencyArea: number
|
AnomalyProficiencyArea: number
|
||||||
/** 异常增伤区 */
|
/** 异常增伤区 */
|
||||||
|
|
@ -122,7 +118,7 @@ interface enemy {
|
||||||
level: number
|
level: number
|
||||||
/** 1级基础防御力 */
|
/** 1级基础防御力 */
|
||||||
basicDEF: number
|
basicDEF: number
|
||||||
/** 抗性 */
|
/** 抗性区常量 */
|
||||||
resistance: number
|
resistance: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,8 +126,8 @@ export class Calculator {
|
||||||
readonly buffM: BuffManager
|
readonly buffM: BuffManager
|
||||||
readonly avatar: ZZZAvatarInfo
|
readonly avatar: ZZZAvatarInfo
|
||||||
readonly skills: skill[] = []
|
readonly skills: skill[] = []
|
||||||
private cache: { [key in buff['type']]?: number } = {}
|
private cache: { [type: string]: damage } = {}
|
||||||
private damageCache: { [type: string]: damage } = {}
|
private props: damage['props'] = {}
|
||||||
defaultSkill: { [key in keyof skill]?: skill[key] } = {}
|
defaultSkill: { [key in keyof skill]?: skill[key] } = {}
|
||||||
enemy: enemy
|
enemy: enemy
|
||||||
|
|
||||||
|
|
@ -194,7 +190,7 @@ export class Calculator {
|
||||||
if (!MySkill) return
|
if (!MySkill) return
|
||||||
return this.calc_skill(MySkill)
|
return this.calc_skill(MySkill)
|
||||||
}
|
}
|
||||||
if (!skill.banCache && this.damageCache[skill.type]) return this.damageCache[skill.type]
|
if (!skill.banCache && this.cache[skill.type]) return this.cache[skill.type]
|
||||||
if (skill.check && !skill.check({ avatar: this.avatar, buffM: this.buffM, calc: this })) return
|
if (skill.check && !skill.check({ avatar: this.avatar, buffM: this.buffM, calc: this })) return
|
||||||
logger.debug(`${logger.green(skill.type)}${skill.name}伤害计算:`)
|
logger.debug(`${logger.green(skill.type)}${skill.name}伤害计算:`)
|
||||||
if (skill.dmg) {
|
if (skill.dmg) {
|
||||||
|
|
@ -202,68 +198,71 @@ export class Calculator {
|
||||||
logger.debug('自定义计算最终伤害:', dmg.result)
|
logger.debug('自定义计算最终伤害:', dmg.result)
|
||||||
return dmg
|
return dmg
|
||||||
}
|
}
|
||||||
this.cache = {}
|
const props = this.props = skill.props || {}
|
||||||
/** 缩小筛选范围 */
|
/** 缩小筛选范围 */
|
||||||
const usefulBuffs = this.buffM.filter({
|
const usefulBuffs = this.buffM.filter({
|
||||||
element: skill.element,
|
element: skill.element,
|
||||||
range: skill.redirect ? [skill.type, skill.redirect] : [skill.type]
|
range: skill.redirect ? [skill.type, skill.redirect] : [skill.type]
|
||||||
}, this)
|
}, this)
|
||||||
const detail = {} as damage['detail']
|
const areas = {} as damage['areas']
|
||||||
if (skill.before) skill.before({ avatar: this.avatar, calc: this, detail, skill, usefulBuffs, })
|
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 as anomaly] === 'number'
|
||||||
if (!detail.BasicArea) {
|
if (!areas.BasicArea) {
|
||||||
if (!detail.Multiplier) {
|
let Multiplier = props.倍率
|
||||||
|
if (!Multiplier) {
|
||||||
if (skill.fixedMultiplier) {
|
if (skill.fixedMultiplier) {
|
||||||
detail.Multiplier = skill.fixedMultiplier
|
Multiplier = skill.fixedMultiplier
|
||||||
} else if (isAnomaly) {
|
} else if (isAnomaly) {
|
||||||
detail.Multiplier = (
|
Multiplier = (
|
||||||
skill.type === '紊乱' ?
|
skill.type === '紊乱' ?
|
||||||
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
|
||||||
} else {
|
} else {
|
||||||
if (skill.skillMultiplier) detail.Multiplier = skill.skillMultiplier[this.get_SkillLevel(skill.type[0]) - 1]
|
if (skill.skillMultiplier) Multiplier = skill.skillMultiplier[this.get_SkillLevel(skill.type[0]) - 1]
|
||||||
else detail.Multiplier = this.get_Multiplier(skill.type)
|
else Multiplier = this.get_SkillMultiplier(skill.type)
|
||||||
}
|
}
|
||||||
const ExtraMultiplier = this.get_ExtraMultiplier(skill, usefulBuffs)
|
const ExtraMultiplier = this.get_ExtraMultiplier(skill, usefulBuffs)
|
||||||
detail.Multiplier += ExtraMultiplier
|
Multiplier += ExtraMultiplier
|
||||||
if (!detail.Multiplier) return logger.warn('技能倍率缺失:', skill)
|
if (!Multiplier) return logger.warn('技能倍率缺失:', skill)
|
||||||
if (ExtraMultiplier) logger.debug(`最终倍率:${detail.Multiplier}`)
|
if (ExtraMultiplier) logger.debug(`最终倍率:${Multiplier}`)
|
||||||
}
|
}
|
||||||
detail.ATK ??= this.get_ATK(skill, usefulBuffs)
|
props.倍率 = Multiplier
|
||||||
|
this.get_ATK(skill, usefulBuffs)
|
||||||
|
areas.BasicArea = props.攻击力! * props.倍率
|
||||||
}
|
}
|
||||||
detail.BasicArea ??= detail.ATK * detail.Multiplier
|
logger.debug(`基础伤害区:${areas.BasicArea}`)
|
||||||
logger.debug(`基础伤害区:${detail.BasicArea}`)
|
|
||||||
if (isAnomaly) {
|
if (isAnomaly) {
|
||||||
detail.AnomalyProficiencyArea ??= this.get_AnomalyProficiencyArea(skill, usefulBuffs)
|
areas.AnomalyProficiencyArea ??= this.get_AnomalyProficiencyArea(skill, usefulBuffs)
|
||||||
detail.AnomalyBoostArea ??= this.get_AnomalyBoostArea(skill, usefulBuffs)
|
areas.AnomalyBoostArea ??= this.get_AnomalyBoostArea(skill, usefulBuffs)
|
||||||
detail.LevelArea ??= this.get_LevelArea()
|
areas.LevelArea ??= this.get_LevelArea()
|
||||||
detail.AnomalyCRITRate ??= this.get_AnomalyCRITRate(skill, usefulBuffs)
|
this.get_AnomalyCRITRate(skill, usefulBuffs)
|
||||||
detail.AnomalyCRITDMG ??= this.get_AnomalyCRITDMG(skill, usefulBuffs)
|
this.get_AnomalyCRITDMG(skill, usefulBuffs)
|
||||||
detail.CriticalArea ??= 1 + detail.AnomalyCRITRate * (detail.AnomalyCRITDMG - 1)
|
areas.CriticalArea ??= 1 + props.异常暴击率! * (props.异常暴击伤害! - 1)
|
||||||
} else {
|
} else {
|
||||||
detail.CRITRate ??= this.get_CRITRate(skill, usefulBuffs)
|
this.get_CRITRate(skill, usefulBuffs)
|
||||||
detail.CRITDMG ??= this.get_CRITDMG(skill, usefulBuffs)
|
this.get_CRITDMG(skill, usefulBuffs)
|
||||||
detail.CriticalArea ??= 1 + detail.CRITRate * (detail.CRITDMG - 1)
|
areas.CriticalArea ??= 1 + props.暴击率! * (props.暴击伤害! - 1)
|
||||||
}
|
}
|
||||||
logger.debug(`暴击期望:${detail.CriticalArea}`)
|
logger.debug(`暴击期望:${areas.CriticalArea}`)
|
||||||
detail.BoostArea ??= this.get_BoostArea(skill, usefulBuffs)
|
areas.BoostArea ??= this.get_BoostArea(skill, usefulBuffs)
|
||||||
detail.VulnerabilityArea ??= this.get_VulnerabilityArea(skill, usefulBuffs)
|
areas.VulnerabilityArea ??= this.get_VulnerabilityArea(skill, usefulBuffs)
|
||||||
detail.ResistanceArea ??= this.get_ResistanceArea(skill, usefulBuffs)
|
areas.ResistanceArea ??= this.get_ResistanceArea(skill, usefulBuffs)
|
||||||
detail.DefenceArea ??= this.get_DefenceArea(skill, usefulBuffs)
|
areas.DefenceArea ??= this.get_DefenceArea(skill, usefulBuffs)
|
||||||
const {
|
const {
|
||||||
BasicArea, CRITDMG, CriticalArea, BoostArea, VulnerabilityArea, ResistanceArea, DefenceArea,
|
BasicArea, CriticalArea, BoostArea, VulnerabilityArea, ResistanceArea, DefenceArea,
|
||||||
AnomalyProficiencyArea, LevelArea, AnomalyBoostArea, AnomalyCRITRate, AnomalyCRITDMG
|
AnomalyProficiencyArea, LevelArea, AnomalyBoostArea
|
||||||
} = detail
|
} = areas
|
||||||
|
const { 暴击伤害, 异常暴击伤害 } = props
|
||||||
const result: damage['result'] = isAnomaly ?
|
const result: damage['result'] = isAnomaly ?
|
||||||
{
|
{
|
||||||
critDMG: AnomalyCRITRate ? BasicArea * AnomalyCRITDMG * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea * AnomalyProficiencyArea * LevelArea * AnomalyBoostArea : 0,
|
critDMG: (CriticalArea !== 1) ? BasicArea * 异常暴击伤害! * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea * AnomalyProficiencyArea * LevelArea * AnomalyBoostArea : 0,
|
||||||
expectDMG: BasicArea * CriticalArea * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea * AnomalyProficiencyArea * LevelArea * AnomalyBoostArea
|
expectDMG: BasicArea * CriticalArea * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea * AnomalyProficiencyArea * LevelArea * AnomalyBoostArea
|
||||||
} : {
|
} : {
|
||||||
critDMG: BasicArea * CRITDMG * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea,
|
critDMG: BasicArea * 暴击伤害! * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea,
|
||||||
expectDMG: BasicArea * CriticalArea * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea
|
expectDMG: BasicArea * CriticalArea * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea
|
||||||
}
|
}
|
||||||
const damage: damage = { skill, detail, result }
|
const damage: damage = { skill, props, areas, result }
|
||||||
if (skill.after) {
|
if (skill.after) {
|
||||||
damage.add = (d) => {
|
damage.add = (d) => {
|
||||||
if (typeof d === 'string') d = this.calc_skill(d)
|
if (typeof d === 'string') d = this.calc_skill(d)
|
||||||
|
|
@ -279,10 +278,11 @@ export class Calculator {
|
||||||
logger.debug('伤害系数:' + n)
|
logger.debug('伤害系数:' + n)
|
||||||
damage.fnc!(v => v * n)
|
damage.fnc!(v => v * n)
|
||||||
}
|
}
|
||||||
skill.after({ avatar: this.avatar, damage, calc: this, usefulBuffs })
|
skill.after({ avatar: this.avatar, calc: this, usefulBuffs, skill, damage })
|
||||||
}
|
}
|
||||||
logger.debug('最终伤害:', result)
|
logger.debug('最终伤害:', result)
|
||||||
if (!skill.banCache) this.damageCache[skill.type] = damage
|
if (!skill.banCache) this.cache[skill.type] = damage
|
||||||
|
// console.log(damage)
|
||||||
return damage
|
return damage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -330,10 +330,10 @@ export class Calculator {
|
||||||
* 获取技能倍率
|
* 获取技能倍率
|
||||||
* @param type 参见技能命名标准
|
* @param type 参见技能命名标准
|
||||||
*/
|
*/
|
||||||
get_Multiplier(type: string) {
|
get_SkillMultiplier(type: string) {
|
||||||
const skillLevel = this.get_SkillLevel(type[0])
|
const SkillLevel = this.get_SkillLevel(type[0])
|
||||||
logger.debug(`${type[0]}等级:${skillLevel}`)
|
logger.debug(`${type[0]}等级:${SkillLevel}`)
|
||||||
const Multiplier = charData[this.avatar.id].skill[type]?.[skillLevel - 1]
|
const Multiplier = charData[this.avatar.id].skill[type]?.[SkillLevel - 1]
|
||||||
logger.debug(`技能倍率:${Multiplier}`)
|
logger.debug(`技能倍率:${Multiplier}`)
|
||||||
return Multiplier
|
return Multiplier
|
||||||
}
|
}
|
||||||
|
|
@ -399,7 +399,7 @@ export class Calculator {
|
||||||
* @param isRatio 是否支持buff.value为数值类型且<1时按初始数值百分比提高处理
|
* @param isRatio 是否支持buff.value为数值类型且<1时按初始数值百分比提高处理
|
||||||
*/
|
*/
|
||||||
get(type: buff['type'], initial: number, skill: skill, usefulBuffs: buff[] = this.buffM.buffs, isRatio = false): number {
|
get(type: buff['type'], initial: number, skill: skill, usefulBuffs: buff[] = this.buffM.buffs, isRatio = false): number {
|
||||||
return this.cache[type] ??= this.buffM._filter(usefulBuffs, {
|
return this.props![type] ??= this.buffM._filter(usefulBuffs, {
|
||||||
element: skill?.element,
|
element: skill?.element,
|
||||||
range: skill?.redirect ? [skill.type, skill.redirect] : [skill?.type],
|
range: skill?.redirect ? [skill.type, skill.redirect] : [skill?.type],
|
||||||
type
|
type
|
||||||
|
|
@ -470,11 +470,18 @@ export class Calculator {
|
||||||
return ResistanceArea
|
return ResistanceArea
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 无视防御 */
|
||||||
|
get_IgnoreDEF(skill: skill, usefulBuffs: buff[]) {
|
||||||
|
const IgnoreDEF = this.get('无视防御', 0, skill, usefulBuffs)
|
||||||
|
IgnoreDEF && logger.debug(`无视防御:${IgnoreDEF}`)
|
||||||
|
return IgnoreDEF
|
||||||
|
}
|
||||||
|
|
||||||
/** 穿透值 */
|
/** 穿透值 */
|
||||||
get_Pen(skill: skill, usefulBuffs: buff[]) {
|
get_Pen(skill: skill, usefulBuffs: buff[]) {
|
||||||
let Pen = this.get('穿透值', this.initial_properties.Pen, skill, usefulBuffs)
|
let Pen = this.get('穿透值', this.initial_properties.Pen, skill, usefulBuffs)
|
||||||
Pen = Math.max(0, Math.min(Pen, 1000))
|
Pen = Math.max(0, Math.min(Pen, 1000))
|
||||||
logger.debug(`穿透值:${Pen}`)
|
Pen && logger.debug(`穿透值:${Pen}`)
|
||||||
return Pen
|
return Pen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -482,7 +489,7 @@ export class Calculator {
|
||||||
get_PenRatio(skill: skill, usefulBuffs: buff[]) {
|
get_PenRatio(skill: skill, usefulBuffs: buff[]) {
|
||||||
let PenRatio = this.get('穿透率', this.initial_properties.PenRatio, skill, usefulBuffs)
|
let PenRatio = this.get('穿透率', this.initial_properties.PenRatio, skill, usefulBuffs)
|
||||||
PenRatio = Math.max(0, Math.min(PenRatio, 2))
|
PenRatio = Math.max(0, Math.min(PenRatio, 2))
|
||||||
logger.debug(`穿透率:${PenRatio}`)
|
PenRatio && logger.debug(`穿透率:${PenRatio}`)
|
||||||
return PenRatio
|
return PenRatio
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -493,11 +500,11 @@ export class Calculator {
|
||||||
const base = get_base(this.avatar.level)
|
const base = get_base(this.avatar.level)
|
||||||
/** 基础防御 */
|
/** 基础防御 */
|
||||||
const DEF = this.enemy.basicDEF / 50 * get_base(this.enemy.level)
|
const DEF = this.enemy.basicDEF / 50 * get_base(this.enemy.level)
|
||||||
const ignore_defence = this.get('无视防御', 0, skill, usefulBuffs)
|
const IgnoreDEF = this.get_IgnoreDEF(skill, usefulBuffs)
|
||||||
const Pen = this.get_Pen(skill, usefulBuffs)
|
const Pen = this.get_Pen(skill, usefulBuffs)
|
||||||
const PenRatio = this.get_PenRatio(skill, usefulBuffs)
|
const PenRatio = this.get_PenRatio(skill, usefulBuffs)
|
||||||
/** 防御 */
|
/** 防御 */
|
||||||
const defence = DEF * (1 - ignore_defence)
|
const defence = DEF * (1 - IgnoreDEF)
|
||||||
/** 有效防御 */
|
/** 有效防御 */
|
||||||
const effective_defence = Math.max(0, defence * (1 - PenRatio) - Pen)
|
const effective_defence = Math.max(0, defence * (1 - PenRatio) - Pen)
|
||||||
const DefenceArea = base / (effective_defence + base)
|
const DefenceArea = base / (effective_defence + base)
|
||||||
|
|
@ -531,7 +538,7 @@ export class Calculator {
|
||||||
/** 异常增伤区 */
|
/** 异常增伤区 */
|
||||||
get_AnomalyBoostArea(skill: skill, usefulBuffs: buff[]) {
|
get_AnomalyBoostArea(skill: skill, usefulBuffs: buff[]) {
|
||||||
const AnomalyBoostArea = this.get('异常增伤', 1, skill, usefulBuffs)
|
const AnomalyBoostArea = this.get('异常增伤', 1, skill, usefulBuffs)
|
||||||
logger.debug(`异常增伤区:${AnomalyBoostArea}`)
|
AnomalyBoostArea && logger.debug(`异常增伤区:${AnomalyBoostArea}`)
|
||||||
return AnomalyBoostArea
|
return AnomalyBoostArea
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -539,7 +546,7 @@ export class Calculator {
|
||||||
get_AnomalyCRITRate(skill: skill, usefulBuffs: buff[]) {
|
get_AnomalyCRITRate(skill: skill, usefulBuffs: buff[]) {
|
||||||
let AnomalyCRITRate = this.get('异常暴击率', 0, skill, usefulBuffs)
|
let AnomalyCRITRate = this.get('异常暴击率', 0, skill, usefulBuffs)
|
||||||
AnomalyCRITRate = Math.max(0, Math.min(AnomalyCRITRate, 1))
|
AnomalyCRITRate = Math.max(0, Math.min(AnomalyCRITRate, 1))
|
||||||
logger.debug(`异常暴击率:${AnomalyCRITRate}`)
|
AnomalyCRITRate && logger.debug(`异常暴击率:${AnomalyCRITRate}`)
|
||||||
return AnomalyCRITRate
|
return AnomalyCRITRate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -547,7 +554,7 @@ export class Calculator {
|
||||||
get_AnomalyCRITDMG(skill: skill, usefulBuffs: buff[]) {
|
get_AnomalyCRITDMG(skill: skill, usefulBuffs: buff[]) {
|
||||||
let AnomalyCRITDMG = this.get('异常暴击伤害', 1, skill, usefulBuffs)
|
let AnomalyCRITDMG = this.get('异常暴击伤害', 1, skill, usefulBuffs)
|
||||||
AnomalyCRITDMG = Math.max(0, Math.min(AnomalyCRITDMG, 5))
|
AnomalyCRITDMG = Math.max(0, Math.min(AnomalyCRITDMG, 5))
|
||||||
logger.debug(`异常暴击伤害:${AnomalyCRITDMG}`)
|
AnomalyCRITDMG && logger.debug(`异常暴击伤害:${AnomalyCRITDMG}`)
|
||||||
return AnomalyCRITDMG
|
return AnomalyCRITDMG
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,7 @@ export function set_buff(equip, buffM) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const suit_name = String(equip_detail.equip_suit.name);
|
const suit_name = equip_detail.equip_suit.name;
|
||||||
setCount[suit_name] = (setCount[suit_name] || 0) + 1;
|
setCount[suit_name] = (setCount[suit_name] || 0) + 1;
|
||||||
}
|
}
|
||||||
buffM.setCount = setCount;
|
buffM.setCount = setCount;
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ export function set_buff(equip: ZZZAvatarInfo['equip'], buffM: BuffManager) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const suit_name = String(equip_detail.equip_suit.name)
|
const suit_name = equip_detail.equip_suit.name
|
||||||
setCount[suit_name] = (setCount[suit_name] || 0) + 1
|
setCount[suit_name] = (setCount[suit_name] || 0) + 1
|
||||||
}
|
}
|
||||||
buffM.setCount = setCount
|
buffM.setCount = setCount
|
||||||
|
|
|
||||||
|
|
@ -77,14 +77,14 @@ export const skills = [
|
||||||
name: '强化E极性紊乱',
|
name: '强化E极性紊乱',
|
||||||
type: '紊乱',
|
type: '紊乱',
|
||||||
banCache: true,
|
banCache: true,
|
||||||
before: ({ calc, detail }) => {
|
before: ({ calc, areas }) => {
|
||||||
const skill = { type: '紊乱' }
|
const skill = { type: '紊乱' }
|
||||||
const DiscoverMultiplier = calc.get_DiscoverMultiplier(skill)
|
const DiscoverMultiplier = calc.get_DiscoverMultiplier(skill)
|
||||||
const n = calc.get('倍率', 0.15, { type: '强化E极性紊乱' })
|
const n = calc.get('倍率', 0.15, { type: '强化E极性紊乱' })
|
||||||
const ATK = calc.get_ATK(skill)
|
const ATK = calc.get_ATK(skill)
|
||||||
const AnomalyProficiency = calc.get_AnomalyProficiency(skill)
|
const AnomalyProficiency = calc.get_AnomalyProficiency(skill)
|
||||||
const skillMultiplier = calc.get_Multiplier('E极性紊乱')
|
const skillMultiplier = calc.get_SkillMultiplier('E极性紊乱')
|
||||||
detail.BasicArea = DiscoverMultiplier * ATK * n + AnomalyProficiency * skillMultiplier
|
areas.BasicArea = DiscoverMultiplier * ATK * n + AnomalyProficiency * skillMultiplier
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ name: '连携技:星月相随', type: 'RL' },
|
{ name: '连携技:星月相随', type: 'RL' },
|
||||||
|
|
@ -93,14 +93,14 @@ export const skills = [
|
||||||
name: '终结技极性紊乱',
|
name: '终结技极性紊乱',
|
||||||
type: '紊乱',
|
type: '紊乱',
|
||||||
banCache: true,
|
banCache: true,
|
||||||
before: ({ calc, detail }) => {
|
before: ({ calc, areas }) => {
|
||||||
const skill = { type: '紊乱' }
|
const skill = { type: '紊乱' }
|
||||||
const DiscoverMultiplier = calc.get_DiscoverMultiplier(skill)
|
const DiscoverMultiplier = calc.get_DiscoverMultiplier(skill)
|
||||||
const n = calc.get('倍率', 0.15, { type: '终结技极性紊乱' })
|
const n = calc.get('倍率', 0.15, { type: '终结技极性紊乱' })
|
||||||
const ATK = calc.get_ATK(skill)
|
const ATK = calc.get_ATK(skill)
|
||||||
const AnomalyProficiency = calc.get_AnomalyProficiency(skill)
|
const AnomalyProficiency = calc.get_AnomalyProficiency(skill)
|
||||||
const skillMultiplier = calc.get_Multiplier('R极性紊乱')
|
const skillMultiplier = calc.get_SkillMultiplier('R极性紊乱')
|
||||||
detail.BasicArea = DiscoverMultiplier * ATK * n + AnomalyProficiency * skillMultiplier
|
areas.BasicArea = DiscoverMultiplier * ATK * n + AnomalyProficiency * skillMultiplier
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
76
model/damage/character/露西/calc.js
Normal file
76
model/damage/character/露西/calc.js
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
/** @type {import('../../BuffManager.ts').BuffManager['buffs']} */
|
||||||
|
export const buffs = [
|
||||||
|
{
|
||||||
|
name: '4影',
|
||||||
|
type: '暴击伤害',
|
||||||
|
value: 0.1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '技能:加油!',
|
||||||
|
type: '攻击力',
|
||||||
|
value: ({ calc }) => {
|
||||||
|
const ratio = calc.calc_value('E1')
|
||||||
|
const fixed = calc.calc_value('E2')
|
||||||
|
return Math.min(600, calc.initial_properties.ATK * ratio + fixed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
/** @type {import('../../Calculator.ts').skill['before']} */
|
||||||
|
const before = ({ calc, usefulBuffs, props }) => {
|
||||||
|
const jiayou = usefulBuffs.find(buff => buff.name === '技能:加油!')
|
||||||
|
const delta = calc.calc_value(jiayou?.value)
|
||||||
|
const ratio = calc.calc_value('T')
|
||||||
|
props.攻击力 = calc.get_ATK() + delta * (ratio - 1)
|
||||||
|
usefulBuffs.splice(0, usefulBuffs.length)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @type {import('../../Calculator.ts').Calculator['skills']} */
|
||||||
|
export const skills = [
|
||||||
|
{ name: '灼烧', type: '灼烧' },
|
||||||
|
{ name: '普攻:淑女的球棍四段', type: 'AP4' },
|
||||||
|
{
|
||||||
|
name: '亲卫队小猪:抄家伙!(弹弓)',
|
||||||
|
type: 'AZCD',
|
||||||
|
element: 'Physical',
|
||||||
|
props: {
|
||||||
|
穿透值: 0,
|
||||||
|
穿透率: 0
|
||||||
|
},
|
||||||
|
before
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '亲卫队小猪:回旋挥击!',
|
||||||
|
type: 'AZH',
|
||||||
|
element: 'Physical',
|
||||||
|
props: {
|
||||||
|
穿透值: 0,
|
||||||
|
穿透率: 0
|
||||||
|
},
|
||||||
|
before
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '6影小猪空中落地爆炸',
|
||||||
|
type: 'Y',
|
||||||
|
check: ({ avatar }) => avatar.rank >= 6,
|
||||||
|
fixedMultiplier: 3,
|
||||||
|
props: {
|
||||||
|
穿透值: 0,
|
||||||
|
穿透率: 0
|
||||||
|
},
|
||||||
|
before
|
||||||
|
},
|
||||||
|
{ name: '闪避反击:獠牙折转!', type: 'CF' },
|
||||||
|
{ name: '强化特殊技:全垒打短按', type: 'EQP' },
|
||||||
|
{ name: '强化特殊技:全垒打长按', type: 'EQX' },
|
||||||
|
{
|
||||||
|
name: '连携技:大满贯!',
|
||||||
|
type: 'RL',
|
||||||
|
after: ({ damage }) => damage.x(3)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '终结技:再见全垒打!',
|
||||||
|
type: 'RZ',
|
||||||
|
after: ({ damage }) => damage.x(3)
|
||||||
|
}
|
||||||
|
]
|
||||||
39
model/damage/character/露西/data.json
Normal file
39
model/damage/character/露西/data.json
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
{
|
||||||
|
"skill": {
|
||||||
|
"AP4": [
|
||||||
|
2.726,2.974,3.222,3.47,3.718,3.966,4.214,4.462,4.71,4.958,5.206,5.454,5.702,5.95,6.198,6.446
|
||||||
|
],
|
||||||
|
"AZCD": [
|
||||||
|
1.75,1.91,2.07,2.23,2.39,2.55,2.71,2.87,3.03,3.19,3.35,3.51,3.67,3.83,3.99,4.15
|
||||||
|
],
|
||||||
|
"AZH": [
|
||||||
|
2.5,2.728,2.956,3.184,3.412,3.64,3.868,4.096,4.324,4.552,4.78,5.008,5.236,5.464,5.692,5.92
|
||||||
|
],
|
||||||
|
"CF": [
|
||||||
|
3.08,3.36,3.64,3.92,4.2,4.48,4.76,5.04,5.32,5.6,5.88,6.16,6.44,6.72,7,7.28
|
||||||
|
],
|
||||||
|
"EQP": [
|
||||||
|
5.084,5.547,6.01,6.473,6.936,7.399,7.862,8.325,8.788,9.251,9.714,10.177,10.64,11.103,11.566,12.029
|
||||||
|
],
|
||||||
|
"EQX": [
|
||||||
|
5.364,5.852,6.34,6.828,7.316,7.804,8.292,8.78,9.268,9.756,10.244,10.732,11.22,11.708,12.196,12.684
|
||||||
|
],
|
||||||
|
"RL": [
|
||||||
|
1.641,1.79,1.94,2.089,2.238,2.388,2.537,2.686,2.836,2.985,3.134,3.284,3.433,3.582,3.732,3.881
|
||||||
|
],
|
||||||
|
"RZ": [
|
||||||
|
5.728,6.249,6.77,7.291,7.812,8.333,8.854,9.375,9.896,10.417,10.938,11.459,11.98,12.501,13.022,13.543
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"buff": {
|
||||||
|
"T": [
|
||||||
|
1.4,1.5,1.6,1.7,1.8,1.9,2
|
||||||
|
],
|
||||||
|
"E1": [
|
||||||
|
0.138,0.146,0.154,0.162,0.17,0.178,0.186,0.194,0.202,0.21,0.218,0.226,0.234,0.242,0.25,0.258
|
||||||
|
],
|
||||||
|
"E2": [
|
||||||
|
44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue