2022-08-22 20:53:31 +00:00
|
|
|
|
/*
|
|
|
|
|
* 伤害计算 - 属性计算
|
|
|
|
|
* */
|
2023-10-06 23:44:15 +00:00
|
|
|
|
import { eleBaseDmg } from './DmgCalcMeta.js'
|
2022-08-22 20:53:31 +00:00
|
|
|
|
import lodash from 'lodash'
|
2022-08-24 01:07:06 +00:00
|
|
|
|
import DmgMastery from './DmgMastery.js'
|
2023-10-21 18:54:45 +00:00
|
|
|
|
import { Format, Meta } from '#miao'
|
2023-11-12 21:06:03 +00:00
|
|
|
|
import AttrItem from './AttrItem.js'
|
2022-08-22 20:53:31 +00:00
|
|
|
|
|
|
|
|
|
let DmgAttr = {
|
|
|
|
|
// 计算并返回指定属性值
|
2023-05-23 19:30:30 +00:00
|
|
|
|
getAttrValue (ds = {}) {
|
2022-08-22 20:53:31 +00:00
|
|
|
|
return (ds.base || 0) + (ds.plus || 0) + ((ds.base || 0) * (ds.pct || 0) / 100)
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 获取profile对应attr属性值
|
2023-11-12 21:06:03 +00:00
|
|
|
|
getAttr ({ originalAttr, attr, weapon, char, game = 'gs' }) {
|
2022-08-22 20:53:31 +00:00
|
|
|
|
let ret = {}
|
|
|
|
|
|
2023-11-12 21:06:03 +00:00
|
|
|
|
if (originalAttr) {
|
|
|
|
|
ret = lodash.merge({}, originalAttr)
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-22 20:53:31 +00:00
|
|
|
|
// 基础属性
|
|
|
|
|
lodash.forEach('atk,def,hp'.split(','), (key) => {
|
2023-11-12 21:06:03 +00:00
|
|
|
|
ret[key] = AttrItem.create(originalAttr?.[key] || {
|
2022-08-22 20:53:31 +00:00
|
|
|
|
base: attr[`${key}Base`] * 1 || 0,
|
|
|
|
|
plus: attr[key] * 1 - attr[`${key}Base`] * 1 || 0,
|
|
|
|
|
pct: 0
|
2023-11-12 21:06:03 +00:00
|
|
|
|
})
|
2022-08-22 20:53:31 +00:00
|
|
|
|
})
|
|
|
|
|
|
2024-02-17 14:25:42 +00:00
|
|
|
|
lodash.forEach((game === 'gs' ? 'mastery,recharge,cpct,cdmg,heal,dmg,phy' : 'speed,recharge,cpct,cdmg,heal,dmg,enemydmg,effPct,effDef,stance').split(','), (key) => {
|
2023-11-12 21:06:03 +00:00
|
|
|
|
ret[key] = AttrItem.create(originalAttr?.[key] || {
|
2022-08-22 20:53:31 +00:00
|
|
|
|
base: attr[key] * 1 || 0, // 基础值
|
|
|
|
|
plus: 0, // 加成值
|
|
|
|
|
pct: 0, // 百分比加成
|
|
|
|
|
inc: 0 // 提高:护盾增效&治疗增效
|
2023-11-12 21:06:03 +00:00
|
|
|
|
})
|
2022-08-22 20:53:31 +00:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// 技能属性记录
|
2024-09-06 12:49:43 +00:00
|
|
|
|
lodash.forEach((game === 'gs' ? 'a,a2,a3,e,q,nightsoul' : 'a,a2,a3,e,e2,q,q2,t,dot,break').split(','), (key) => {
|
2023-11-12 21:06:03 +00:00
|
|
|
|
ret[key] = ret[key] || {
|
2022-08-22 20:53:31 +00:00
|
|
|
|
pct: 0, // 倍率加成
|
|
|
|
|
multi: 0, // 独立倍率乘区加成,宵宫E等
|
|
|
|
|
|
|
|
|
|
plus: 0, // 伤害值提高
|
|
|
|
|
dmg: 0, // 伤害提高
|
2023-08-13 18:39:27 +00:00
|
|
|
|
enemydmg: 0, // 承受伤害提高
|
2022-08-22 20:53:31 +00:00
|
|
|
|
cpct: 0, // 暴击提高
|
|
|
|
|
cdmg: 0, // 爆伤提高
|
|
|
|
|
|
|
|
|
|
def: 0, // 防御降低
|
|
|
|
|
ignore: 0 // 无视防御
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
2023-11-12 21:06:03 +00:00
|
|
|
|
ret.enemy = ret.enemy || {
|
2022-08-22 20:53:31 +00:00
|
|
|
|
def: 0, // 降低防御
|
|
|
|
|
ignore: 0, // 无视防御
|
|
|
|
|
phy: 0 // 物理防御
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-12 21:06:03 +00:00
|
|
|
|
ret.shield = AttrItem.create(originalAttr?.shield || {
|
2022-08-22 20:53:31 +00:00
|
|
|
|
base: 100, // 基础
|
|
|
|
|
plus: 0, // 护盾强效
|
|
|
|
|
inc: 100 // 吸收倍率
|
2023-11-12 21:06:03 +00:00
|
|
|
|
})
|
2022-08-22 20:53:31 +00:00
|
|
|
|
|
2023-11-12 21:06:03 +00:00
|
|
|
|
if (!originalAttr) {
|
|
|
|
|
ret.weapon = weapon // 武器
|
|
|
|
|
ret.weaponTypeName = char.weaponTypeName // 武器类型
|
|
|
|
|
ret.element = Format.elemName(char.elem) // 元素类型
|
|
|
|
|
ret.refine = ((weapon.affix || ret.refine || 1) * 1 - 1) || 0 // 武器精炼
|
|
|
|
|
ret.multi = 0 // 倍率独立乘区
|
|
|
|
|
ret.kx = 0 // 敌人抗性降低
|
|
|
|
|
if (game === 'gs') {
|
|
|
|
|
ret.vaporize = 0 // 蒸发
|
|
|
|
|
ret.melt = 0 // 融化
|
|
|
|
|
ret.burning = 0 // 燃烧
|
2024-01-02 15:41:38 +00:00
|
|
|
|
ret.crystallize = 0 // 结晶
|
2023-11-12 21:06:03 +00:00
|
|
|
|
ret.superConduct = 0 // 超导
|
|
|
|
|
ret.swirl = 0 // 扩散
|
|
|
|
|
ret.electroCharged = 0 // 感电
|
|
|
|
|
ret.shatter = 0 // 碎冰
|
|
|
|
|
ret.overloaded = 0 // 超载
|
|
|
|
|
ret.bloom = 0 // 绽放
|
|
|
|
|
ret.burgeon = 0 // 烈绽放
|
|
|
|
|
ret.hyperBloom = 0 // 超绽放
|
|
|
|
|
ret.aggravate = 0 // 超激化
|
|
|
|
|
ret.spread = 0 // 蔓激化
|
|
|
|
|
ret.fykx = 0 // 敌人反应抗性降低
|
|
|
|
|
} else if (game === 'sr') {
|
2023-11-15 21:07:55 +00:00
|
|
|
|
ret.sp = char.sp * 1
|
2024-06-20 22:43:11 +00:00
|
|
|
|
// 超击破
|
|
|
|
|
ret.superBreak = {
|
|
|
|
|
ignore: 0 // 无视防御
|
|
|
|
|
}
|
2023-08-13 18:39:27 +00:00
|
|
|
|
}
|
2023-05-21 18:13:38 +00:00
|
|
|
|
}
|
2022-08-22 20:53:31 +00:00
|
|
|
|
return ret
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 获取数据集
|
|
|
|
|
getDs (attr, meta, params) {
|
|
|
|
|
return {
|
|
|
|
|
...meta,
|
|
|
|
|
attr,
|
|
|
|
|
params,
|
|
|
|
|
refine: attr.refine,
|
2022-11-26 08:12:32 +00:00
|
|
|
|
weaponTypeName: attr.weaponTypeName,
|
2023-11-12 21:06:03 +00:00
|
|
|
|
element: Format.elemName(attr.element) || attr.element, // 计算属性
|
2022-08-22 20:53:31 +00:00
|
|
|
|
calc: DmgAttr.getAttrValue
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 计算属性
|
2023-11-27 20:18:06 +00:00
|
|
|
|
calcAttr ({ originalAttr, buffs, meta, artis, params = {}, incAttr = '', reduceAttr = '', talent = '', game = 'gs' }) {
|
2023-11-13 01:59:48 +00:00
|
|
|
|
let attr = DmgAttr.getAttr({ originalAttr, game })
|
2022-08-22 20:53:31 +00:00
|
|
|
|
let msg = []
|
2023-10-21 18:54:45 +00:00
|
|
|
|
let { attrMap } = Meta.getMeta(game, 'arti')
|
2023-05-21 18:13:38 +00:00
|
|
|
|
|
2022-08-22 20:53:31 +00:00
|
|
|
|
if (incAttr && attrMap[incAttr]) {
|
|
|
|
|
let aCfg = attrMap[incAttr]
|
2022-11-24 15:27:03 +00:00
|
|
|
|
attr[incAttr][aCfg.calc] += aCfg.value
|
2022-08-22 20:53:31 +00:00
|
|
|
|
}
|
|
|
|
|
if (reduceAttr && attrMap[reduceAttr]) {
|
|
|
|
|
let aCfg = attrMap[reduceAttr]
|
2022-11-24 15:27:03 +00:00
|
|
|
|
attr[reduceAttr][aCfg.calc] -= aCfg.value
|
2022-08-22 20:53:31 +00:00
|
|
|
|
}
|
2024-07-04 13:22:55 +00:00
|
|
|
|
|
|
|
|
|
lodash.forEach(buffs, (buff) => {
|
|
|
|
|
meta.mastery = meta.mastery || buff.mastery // 先反应
|
|
|
|
|
})
|
2022-08-22 20:53:31 +00:00
|
|
|
|
lodash.forEach(buffs, (buff) => {
|
|
|
|
|
let ds = DmgAttr.getDs(attr, meta, params)
|
|
|
|
|
|
|
|
|
|
ds.currentTalent = talent
|
2023-11-27 20:18:06 +00:00
|
|
|
|
ds.artis = artis
|
2022-08-22 20:53:31 +00:00
|
|
|
|
|
2022-11-24 03:54:27 +00:00
|
|
|
|
if (buff.isStatic) {
|
|
|
|
|
return
|
|
|
|
|
}
|
2022-08-22 20:53:31 +00:00
|
|
|
|
// 如果存在rule,则进行计算
|
|
|
|
|
if (buff.check && !buff.check(ds)) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (buff.cons) {
|
|
|
|
|
if (ds.cons * 1 < buff.cons * 1) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-05-21 18:13:38 +00:00
|
|
|
|
if (!lodash.isUndefined(buff.maxCons)) {
|
|
|
|
|
if (ds.cons * 1 > buff.maxCons * 1) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-05-22 19:19:45 +00:00
|
|
|
|
if (buff.tree) {
|
|
|
|
|
if (!ds.trees[`10${buff.tree}`]) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-08-22 20:53:31 +00:00
|
|
|
|
|
|
|
|
|
let title = buff.title
|
|
|
|
|
|
|
|
|
|
if (buff.mastery) {
|
2023-10-06 23:44:15 +00:00
|
|
|
|
let mKey = {
|
2023-11-12 21:06:03 +00:00
|
|
|
|
vaporize: '蒸发', melt: '融化', swirl: '扩散'
|
2023-10-06 23:44:15 +00:00
|
|
|
|
}
|
|
|
|
|
let mKey2 = {
|
2023-11-12 21:06:03 +00:00
|
|
|
|
aggravate: '超激化', spread: '蔓激化'
|
2023-10-06 23:44:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-08-22 20:53:31 +00:00
|
|
|
|
let mastery = Math.max(0, attr.mastery.base + attr.mastery.plus)
|
|
|
|
|
buff.data = buff.data || {}
|
2023-10-06 23:44:15 +00:00
|
|
|
|
|
|
|
|
|
let key = buff.mastery
|
|
|
|
|
if (mKey[key]) {
|
2022-11-26 08:12:32 +00:00
|
|
|
|
buff.data['_' + key] = DmgMastery.getMultiple(key, mastery) * 100
|
2023-10-06 23:44:15 +00:00
|
|
|
|
} else if (mKey2[key]) {
|
|
|
|
|
let eleNum = DmgMastery.getBasePct(key, attr.element)
|
|
|
|
|
let eleBase = 1 + attr[key] / 100 + DmgMastery.getMultiple(key, mastery)
|
|
|
|
|
eleBase *= eleBaseDmg[ds.level]
|
|
|
|
|
buff.data['_' + key] = DmgMastery.getMultiple(key, mastery) * 100
|
|
|
|
|
buff.data['_' + key + 'num'] = eleNum * eleBase
|
|
|
|
|
}
|
2022-08-22 20:53:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lodash.forEach(buff.data, (val, key) => {
|
|
|
|
|
if (lodash.isFunction(val)) {
|
|
|
|
|
val = val(ds)
|
|
|
|
|
}
|
2024-03-02 07:06:11 +00:00
|
|
|
|
if (!val && val !== 0) {
|
2023-11-12 21:06:03 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
2022-08-22 20:53:31 +00:00
|
|
|
|
|
|
|
|
|
title = title.replace(`[${key}]`, Format.comma(val, 1))
|
2023-11-12 21:06:03 +00:00
|
|
|
|
|
2022-08-22 20:53:31 +00:00
|
|
|
|
// 技能提高
|
2024-05-09 15:32:56 +00:00
|
|
|
|
let tRet = /^(a|a2|a3|e|q|t|dot|break)(Def|Ignore|Dmg|Enemydmg|Plus|Pct|Cpct|Cdmg|Multi)$/.exec(key)
|
2022-08-22 20:53:31 +00:00
|
|
|
|
if (tRet) {
|
|
|
|
|
attr[tRet[1]][tRet[2].toLowerCase()] += val * 1 || 0
|
|
|
|
|
return
|
|
|
|
|
}
|
2024-05-13 12:05:34 +00:00
|
|
|
|
let aRet = /^(hp|def|atk|mastery|cpct|cdmg|heal|recharge|dmg|enemydmg|phy|shield|speed|stance)(Plus|Pct|Inc)?$/.exec(key)
|
2022-08-22 20:53:31 +00:00
|
|
|
|
if (aRet) {
|
|
|
|
|
attr[aRet[1]][aRet[2] ? aRet[2].toLowerCase() : 'plus'] += val * 1 || 0
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (key === 'enemyDef') {
|
|
|
|
|
attr.enemy.def += val * 1 || 0
|
|
|
|
|
return
|
|
|
|
|
}
|
2023-05-21 18:13:38 +00:00
|
|
|
|
if (key === 'ignore' || key === 'enemyIgnore') {
|
|
|
|
|
attr.enemy.ignore += val * 1 || 0
|
|
|
|
|
return
|
|
|
|
|
}
|
2022-08-22 20:53:31 +00:00
|
|
|
|
|
2024-03-28 12:46:14 +00:00
|
|
|
|
if (['vaporize', 'melt', 'crystallize', 'burning', 'superConduct', 'swirl', 'electroCharged', 'shatter', 'overloaded', 'bloom', 'burgeon', 'hyperBloom', 'aggravate', 'spread', 'kx', 'fykx', 'multi'].includes(key)) {
|
2022-08-22 20:53:31 +00:00
|
|
|
|
attr[key] += val * 1 || 0
|
2024-06-20 22:43:11 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let sRet = /^(superBreak)(Ignore)$/.exec(key)
|
|
|
|
|
if (sRet) {
|
|
|
|
|
attr[sRet[1]][sRet[2].toLowerCase()] += val * 1 || 0
|
2023-08-13 18:39:27 +00:00
|
|
|
|
}
|
2022-08-22 20:53:31 +00:00
|
|
|
|
})
|
|
|
|
|
msg.push(title)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
attr, msg
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
export default DmgAttr
|