优化伤害计算等

This commit is contained in:
UCPr 2025-05-31 18:51:04 +08:00
parent 7ace8908ff
commit 95a2ee64de
50 changed files with 173 additions and 221 deletions

View file

@ -175,7 +175,8 @@ export class Calculator {
readonly buffM: BuffManager
readonly avatar: ZZZAvatarInfo
readonly skills: skill[] = []
private usefulBuffs: buff[] = []
/** 对当前所计算的技能有用的buff、计算后的buff */
private readonly usefulBuffResults: Map<buff, buff> = new Map()
private cache: { [type: string]: damage } = Object.create(null)
private props: Exclude<damage['props'], undefined> = {}
/** 当前正在计算的技能 */
@ -325,8 +326,8 @@ export class Calculator {
critDMG: BasicArea * ! * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea,
expectDMG: BasicArea * CriticalArea * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea
}
const damage: damage = { skill, usefulBuffs: _.sortBy(this.usefulBuffs, ['type', 'value']).reverse(), props, areas, result }
this.usefulBuffs = []
const damage: damage = { skill, usefulBuffs: _.sortBy(Array.from(this.usefulBuffResults.values()), ['type', 'value']).reverse(), props, areas, result }
this.usefulBuffResults.clear()
if (skill.after) {
damage.add = (d) => {
if (typeof d === 'string') d = this.calc_skill(d)
@ -387,7 +388,13 @@ export class Calculator {
const base: { [type: string]: number } = {}
types.forEach(t => base[t] = t.includes('百分比') ? this.avatar.base_properties[prop.nameZHToNameEN(t.replace('百分比', '')) as keyof ZZZAvatarInfo['base_properties']] * subBaseValueData[t][0] : subBaseValueData[t][0])
logger.debug('词条变化值:', base)
const buffs = types.map(t => ({
const buffs: {
name: subStatKeys
shortName: string
type: buff['type']
value: number
valueBase: typeof subBaseValueData[subStatKeys][1]
}[] = types.map(t => ({
name: t,
shortName: prop.nameToShortName3(t),
type: t.replace('百分比', '') as buff['type'],
@ -432,14 +439,25 @@ export class Calculator {
const base: { [type: string]: number } = {}
types.forEach(t => base[t] = (t.includes('百分比') || ['异常掌控', '冲击力', '能量自动回复'].includes(t)) ? this.avatar.base_properties[prop.nameZHToNameEN(t.replace('百分比', '')) as keyof ZZZAvatarInfo['base_properties']] * mainBaseValueData[t][0] : mainBaseValueData[t][0])
logger.debug(logger.red('词条变化值:'), base)
const buffs = types.map(t => ({
name: t,
shortName: prop.nameToShortName3(t),
type: (t.includes('属性伤害加成') ? '增伤' : t.replace('百分比', '')) as buff['type'],
value: base[t],
element: t.includes('属性伤害加成') ? prop.nameZHToNameEN(t).replace('DMGBonus', '') : undefined,
valueBase: mainBaseValueData[t][1]
}))
const buffs: {
name: mainStatKeys
shortName: string
type: buff['type']
value: number
element?: element
valueBase: typeof mainBaseValueData[mainStatKeys][1]
}[] = types.map(t => {
const data: typeof buffs[number] = {
name: t,
shortName: prop.nameToShortName3(t),
type: (t.includes('属性伤害加成') ? '增伤' : t.replace('百分比', '')) as buff['type'],
value: base[t],
element: (t.includes('属性伤害加成') ? prop.nameZHToNameEN(t).replace('DMGBonus', '') : '') as element,
valueBase: mainBaseValueData[t][1]
}
if (!data.element) delete data.element
return data
})
buffs.push({
// @ts-expect-error
name: '空白对照',
@ -465,21 +483,25 @@ export class Calculator {
})
}
/* 计算已注册技能差异 */
/**
*
* - buff形式两两组合进行差异计算
* @param buffs buffs
* @returns `buffs.length * buffs.length`2
*/
calc_differences<B extends Partial<buff>>(
buffs: B[],
skill: skill['type']
): { add: B, del: B, damage: damage, difference: number }[][]
/* 计算技能差异 */
/**
*
* @param buffs buffs
* @returns `buffs.length * buffs.length`2
*/
calc_differences<B extends Partial<buff>>(
buffs: B[],
skill?: skill
): { add: B, del: B, damage: damage, difference: number }[][]
/**
* buff形式两两组合进行差异计算
* @param buffs buffs
* @returns `buffs.length维`
*/
calc_differences<B extends buff>(
buffs: B[],
skill?: skill['type'] | skill
@ -574,9 +596,9 @@ export class Calculator {
return Multiplier
}
/** 获取角色自身**出伤**异常的异常数据 */
/** 获取角色自身`出伤异常`的异常数据 */
get_AnomalyData(): typeof AnomalyData[number]
/** 获取角色自身**指定**异常的异常数据 */
/** 获取角色自身`指定异常`的异常数据 */
get_AnomalyData(anomaly: anomaly): typeof AnomalyData[number]
get_AnomalyData(anomaly?: anomaly) {
if (!anomaly) {
@ -598,12 +620,12 @@ export class Calculator {
get_AnomalyMultiplier(skill: skill, usefulBuffs: buff[], times = 0) {
const anomalyData = this.get_AnomalyData(skill?.type.slice(0, 2) as anomaly)
if (!anomalyData) return
let Multiplier = anomalyData.multiplier
if (times !== 1 && anomalyData.duration && anomalyData.interval) {
// 未指定触发次数时,自动计算最大触发次数
if (!times && anomalyData.duration && anomalyData.interval) {
const AnomalyDuration = this.get_AnomalyDuration(skill, usefulBuffs, anomalyData.duration)
times ||= Math.floor((AnomalyDuration * 10) / (anomalyData.interval * 10))
Multiplier = anomalyData.multiplier * times
times = Math.floor((AnomalyDuration * 10) / (anomalyData.interval * 10))
}
const Multiplier = anomalyData.multiplier * (times || 1)
logger.debug(`倍率:${Multiplier}`)
return Multiplier
}
@ -637,9 +659,9 @@ export class Calculator {
case 'object': {
if (!Array.isArray(value) || !buff) return 0
switch (buff.source) {
case 'Weapon': return value[this.avatar.weapon.star - 1] || 0
case 'Talent':
case 'Addition': return value[this.get_SkillLevel('T') - 1] || 0
case '音擎': return value[this.avatar.weapon.star - 1] || 0
case '核心被动':
case '额外能力': return value[this.get_SkillLevel('T') - 1] || 0
}
}
default: return 0
@ -648,7 +670,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 {
return this.props[type] ??= this.buffM._filter(usefulBuffs, {
@ -658,17 +680,13 @@ export class Calculator {
type
}, this).reduce((previousValue, buff) => {
const { value } = buff
let add = 0
if (isRatio && typeof value === 'number' && Math.abs(value) < 1) { // 绝对值小于1时认为是百分比
add = value * initial
} else {
add = this.calc_value(value, buff)
if (Math.abs(add) < 1 && isRatio && (typeof value === 'string' || Array.isArray(value)))
add *= initial
}
if (!this.usefulBuffs.find(b => b.name === buff.name && b.type === buff.type && add === buff.value))
this.usefulBuffs.push({ ...buff, value: add })
logger.debug(`\tBuff${buff.name}${buff.range || '全类型'}增加${add}${buff.element || ''}${type}`)
let add = this.calc_value(value, buff)
// 启用isRatio时若计算值绝对值小于1按照百分比提高处理
if (isRatio && Math.abs(add) < 1 && (typeof value === 'number' || typeof value === 'string' || Array.isArray(value)))
add *= initial
if (!this.usefulBuffResults.has(buff))
this.usefulBuffResults.set(buff, { ...buff, value: add })
logger.debug(`\tBuff${buff.name}${(buff.include ? (buff.range ? [buff.range, buff.include] : buff.include) : buff.range) || '全类型'}增加${add}${buff.element || ''}${type}`)
return previousValue + add
}, initial)
}