mirror of
https://github.com/yoimiya-kokomi/miao-plugin.git
synced 2024-11-25 01:21:55 +00:00
调整部分伤害计算底层逻辑
This commit is contained in:
parent
e59b3ded99
commit
f8c03dffcc
@ -1,8 +1,8 @@
|
||||
import fs from 'fs'
|
||||
import lodash from 'lodash'
|
||||
import { Character, ProfileReq, ProfileData } from '../models/index.js'
|
||||
import Miao from './profile-data/miao.js'
|
||||
import Enka from './profile-data/enka.js'
|
||||
import { Character, ProfileReq, ProfileData } from '../models/index.js'
|
||||
|
||||
const _path = process.cwd()
|
||||
const userPath = `${_path}/data/UserData/`
|
||||
|
@ -92,7 +92,7 @@ export const characters = {
|
||||
gongji: ['普契涅拉', '公鸡', '鸽子'],
|
||||
duizhang: ['卡皮塔诺', '队长'],
|
||||
nilu: ['妮露'],
|
||||
nahida: ['纳西妲', '草神']
|
||||
nahida: ['纳西妲', '草神', '小吉祥', '小吉祥草王', '花神', '草萝莉']
|
||||
}
|
||||
|
||||
/*
|
||||
@ -103,14 +103,14 @@ export const wifeData = {
|
||||
// 老婆&女朋友:成女、少女
|
||||
girlfriend: `琴, 丽莎, 荧, 芭芭拉, 安柏, 香菱, 北斗, 凝光, 菲谢尔, 诺艾尔, 甘雨, 莫娜, 刻晴, 砂糖, 辛焱, 罗莎莉亚, 胡桃,
|
||||
烟绯, 优菈, 神里绫华, 宵宫, 雷电将军, 珊瑚宫心海, 九条裟罗, 八重神子, 埃洛伊, 申鹤, 云堇, 夜兰, 久岐忍, 柯莱, 多莉, 伐难,
|
||||
女士, 萍姥姥, 柯莱, 多莉, 仆人, 少女, 妮露, 纳西妲`,
|
||||
女士, 萍姥姥, 柯莱, 多莉, 仆人, 少女, 妮露`,
|
||||
|
||||
// 老公&男朋友:成男、少男
|
||||
boyfriend: `空, 凯亚, 迪卢克, 雷泽, 温迪, 行秋, 魈, 钟离, 班尼特, 达达利亚, 重云, 阿贝多, 枫原万叶, 托马, 五郎, 荒泷一斗,
|
||||
鹿野院平藏, 神里绫人, 提纳里, 散兵, 白术, 提纳里, 富人, 博士, 丑角, 公鸡, 队长`,
|
||||
|
||||
// 女儿:萝莉
|
||||
daughter: '可莉, 七七, 迪奥娜, 早柚, 派蒙, 瑶瑶',
|
||||
daughter: '可莉, 七七, 迪奥娜, 早柚, 派蒙, 瑶瑶, 纳西妲',
|
||||
|
||||
// 儿子:正太
|
||||
son: ''
|
||||
@ -126,7 +126,7 @@ export const abbr = {
|
||||
荒泷一斗: '一斗',
|
||||
八重神子: '八重',
|
||||
九条裟罗: '九条',
|
||||
罗莎莉亚: '罗莎',
|
||||
罗莎莉亚: '修女',
|
||||
鹿野院平藏: '平藏',
|
||||
|
||||
松籁响起之时: '松籁',
|
||||
|
@ -129,6 +129,30 @@ export default class ProfileArtis extends Base {
|
||||
return ret
|
||||
}
|
||||
|
||||
getSetData () {
|
||||
let setCount = {}
|
||||
this.forEach((arti, idx) => {
|
||||
setCount[arti.set] = (setCount[arti.set] || 0) + 1
|
||||
})
|
||||
let sets = {}
|
||||
let names = []
|
||||
for (let set in setCount) {
|
||||
if (setCount[set] >= 2) {
|
||||
sets[set] = setCount[set] >= 4 ? 4 : 2
|
||||
names.push(Artifact.getArtiBySet(set))
|
||||
}
|
||||
}
|
||||
return { sets, names }
|
||||
}
|
||||
|
||||
get sets () {
|
||||
return this.getSetData().sets
|
||||
}
|
||||
|
||||
get names () {
|
||||
return this.getSetData().names
|
||||
}
|
||||
|
||||
getCharCfg () {
|
||||
let char = Character.get(this.charid)
|
||||
let name = char.name
|
||||
|
@ -116,7 +116,10 @@ export default class ProfileData extends Base {
|
||||
// 计算当前profileData的伤害信息
|
||||
async calcDmg ({ enemyLv = 91, mode = 'profile', dmgIdx = 0 }) {
|
||||
if (!this.dmg) {
|
||||
this.dmg = new ProfileDmg(this)
|
||||
let ds = this.getData('id,level,attr,cons,artis:artis.sets')
|
||||
ds.talent = lodash.mapValues(this.talent, 'level')
|
||||
ds.weapon = Data.getData(this.weapon, 'name,affix')
|
||||
this.dmg = new ProfileDmg(ds)
|
||||
}
|
||||
return await this.dmg.calcData({ enemyLv, mode, dmgIdx })
|
||||
}
|
||||
|
@ -1,64 +1,117 @@
|
||||
import fs from 'fs'
|
||||
import lodash from 'lodash'
|
||||
import Base from './Base.js'
|
||||
import { Character } from './index.js'
|
||||
import lodash from 'lodash'
|
||||
import { attrMap } from './profile-lib/calc-meta.js'
|
||||
import Calc from './profile-lib/Calc.js'
|
||||
import DmgBuffs from './profile-lib/DmgBuffs.js'
|
||||
import DmgAttr from './profile-lib/DmgAttr.js'
|
||||
import DmgCalc from './profile-lib/DmgCalc.js'
|
||||
|
||||
export default class ProfileDmg extends Base {
|
||||
constructor (profile = false) {
|
||||
constructor (profile = {}) {
|
||||
super()
|
||||
this.profile = profile
|
||||
if (profile && profile.id) {
|
||||
let { id } = profile
|
||||
this.char = Character.get(id)
|
||||
}
|
||||
if (!this.char) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 获取天赋数据
|
||||
talent () {
|
||||
let char = this.char
|
||||
let profile = this.profile
|
||||
let ret = {}
|
||||
let talentData = profile.talent || {}
|
||||
lodash.forEach(['a', 'e', 'q'], (key) => {
|
||||
let level = lodash.isNumber(talentData[key]) ? talentData[key] : (talentData[key].level || 1)
|
||||
|
||||
let map = {}
|
||||
|
||||
lodash.forEach(char.talent[key].tables, (tr) => {
|
||||
let val = tr.values[level - 1]
|
||||
// eslint-disable-next-line no-control-regex
|
||||
val = val.replace(/[^\x00-\xff]/g, '').trim()
|
||||
let valArr = []
|
||||
let valArr2 = []
|
||||
lodash.forEach(val.split('/'), (v, idx) => {
|
||||
let valNum = 0
|
||||
lodash.forEach(v.split('+'), (v) => {
|
||||
v = v.split('*')
|
||||
let v1 = v[0].replace('%', '').trim()
|
||||
valNum += v1 * (v[1] || 1)
|
||||
valArr2.push(v1)
|
||||
})
|
||||
valArr.push(valNum)
|
||||
})
|
||||
|
||||
if (isNaN(valArr[0])) {
|
||||
map[tr.name] = false
|
||||
} else if (valArr.length === 1) {
|
||||
map[tr.name] = valArr[0]
|
||||
} else {
|
||||
map[tr.name] = valArr
|
||||
}
|
||||
map[tr.name + '2'] = valArr2
|
||||
})
|
||||
ret[key] = map
|
||||
})
|
||||
return ret
|
||||
}
|
||||
|
||||
// 获取buff列表
|
||||
getBuffs (buffs) {
|
||||
return DmgBuffs.getBuffs(this.profile, buffs)
|
||||
}
|
||||
|
||||
async getCalcRule () {
|
||||
const _path = process.cwd()
|
||||
const cfgPath = `${_path}/plugins/miao-plugin/resources/meta/character/${this.char?.name}/calc.js`
|
||||
let cfg = {}
|
||||
if (fs.existsSync(cfgPath)) {
|
||||
cfg = await import(`file://${cfgPath}`)
|
||||
return {
|
||||
details: cfg.details || false, // 计算详情
|
||||
buffs: cfg.buffs || [], // 角色buff
|
||||
defParams: cfg.defParams || {}, // 默认参数,一般为空
|
||||
defDmgIdx: cfg.defDmgIdx || -1, // 默认详情index
|
||||
mainAttr: cfg.mainAttr || 'atk,cpct,cdmg', // 伤害属性
|
||||
enemyName: cfg.enemyName || '小宝' // 敌人名称
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
async calcData ({ enemyLv = 91, mode = 'profile', dmgIdx = 0 }) {
|
||||
if (!this.char || !this.profile) {
|
||||
return false
|
||||
}
|
||||
let { profile, char } = this
|
||||
let charCalcData = await Calc.getCharCalcRule(this.char.name)
|
||||
let { profile } = this
|
||||
let charCalcData = await this.getCalcRule()
|
||||
|
||||
if (!charCalcData) {
|
||||
return false
|
||||
}
|
||||
let talent = Calc.talent(profile, char)
|
||||
let { buffs, details, defParams, mainAttr, defDmgIdx, enemyName } = charCalcData
|
||||
|
||||
let talent = this.talent()
|
||||
|
||||
let meta = {
|
||||
cons: profile.cons * 1,
|
||||
talent
|
||||
}
|
||||
|
||||
let { buffs, details, defParams, mainAttr, defDmgIdx, enemyName } = charCalcData
|
||||
let { id, weapon, attr } = profile
|
||||
|
||||
defParams = defParams || {}
|
||||
|
||||
let originalAttr = Calc.attr(profile)
|
||||
let originalAttr = DmgAttr.getAttr({ id, weapon, attr, char: this.char })
|
||||
|
||||
let weaponBuffs = await Calc.weapon(profile.weapon.name)
|
||||
let reliBuffs = await Calc.reliquaries(profile.artis?.artis || {})
|
||||
buffs = lodash.concat(buffs, weaponBuffs, reliBuffs)
|
||||
let mKey = {
|
||||
zf: '蒸发',
|
||||
rh: '融化',
|
||||
ks: '扩散'
|
||||
}
|
||||
lodash.forEach(buffs, (buff, idx) => {
|
||||
if (lodash.isString(buff) && mKey[buff]) {
|
||||
buff = {
|
||||
title: `元素精通:${mKey[buff]}伤害提高[${buff}]%`,
|
||||
mastery: buff
|
||||
}
|
||||
buffs[idx] = buff
|
||||
}
|
||||
buff.sort = lodash.isUndefined(buff.sort) ? 1 : buff.sort
|
||||
})
|
||||
buffs = this.getBuffs(buffs)
|
||||
|
||||
buffs = lodash.sortBy(buffs, ['sort'])
|
||||
|
||||
let { msg } = Calc.calcAttr({ originalAttr, buffs, meta, params: defParams || {} })
|
||||
let { msg } = DmgAttr.calcAttr({ originalAttr, buffs, meta, params: defParams || {} })
|
||||
|
||||
let ret = []
|
||||
let detailMap = []
|
||||
@ -67,21 +120,21 @@ export default class ProfileDmg extends Base {
|
||||
|
||||
lodash.forEach(details, (detail, detailSysIdx) => {
|
||||
if (lodash.isFunction(detail)) {
|
||||
let { attr } = Calc.calcAttr({ originalAttr, buffs, meta })
|
||||
let ds = lodash.merge({ talent }, Calc.getDs(attr, meta))
|
||||
let { attr } = DmgAttr.calcAttr({ originalAttr, buffs, meta })
|
||||
let ds = lodash.merge({ talent }, DmgAttr.getDs(attr, meta))
|
||||
detail = detail({ ...ds, attr, profile })
|
||||
}
|
||||
let params = lodash.merge({}, defParams, detail.params || {})
|
||||
let { attr } = Calc.calcAttr({ originalAttr, buffs, meta, params, talent: detail.talent || '' })
|
||||
if (detail.check && !detail.check(Calc.getDs(attr, meta, params))) {
|
||||
let { attr } = DmgAttr.calcAttr({ originalAttr, buffs, meta, params, talent: detail.talent || '' })
|
||||
if (detail.check && !detail.check(DmgAttr.getDs(attr, meta, params))) {
|
||||
return
|
||||
}
|
||||
if (detail.cons && meta.cons < detail.cons * 1) {
|
||||
return
|
||||
}
|
||||
let ds = lodash.merge({ talent }, Calc.getDs(attr, meta, params))
|
||||
let ds = lodash.merge({ talent }, DmgAttr.getDs(attr, meta, params))
|
||||
|
||||
let dmg = Calc.getDmgFn({ ds, attr, profile, enemyLv, showDetail: detail.showDetail })
|
||||
let dmg = DmgCalc.getDmgFn({ ds, attr, level: profile.level, enemyLv, showDetail: detail.showDetail })
|
||||
let basicDmgRet
|
||||
|
||||
if (detail.dmg) {
|
||||
@ -123,7 +176,7 @@ export default class ProfileDmg extends Base {
|
||||
rowData.push({ type: 'na' })
|
||||
return
|
||||
}
|
||||
let { attr } = Calc.calcAttr({
|
||||
let { attr } = DmgAttr.calcAttr({
|
||||
originalAttr,
|
||||
buffs,
|
||||
meta,
|
||||
@ -132,8 +185,8 @@ export default class ProfileDmg extends Base {
|
||||
reduceAttr,
|
||||
talent: detail.talent || ''
|
||||
})
|
||||
let ds = lodash.merge({ talent }, Calc.getDs(attr, meta, params))
|
||||
let dmg = Calc.getDmgFn({ ds, attr, profile, enemyLv })
|
||||
let ds = lodash.merge({ talent }, DmgAttr.getDs(attr, meta, params))
|
||||
let dmg = DmgCalc.getDmgFn({ ds, attr, level: profile.level, enemyLv })
|
||||
if (detail.dmg) {
|
||||
let dmgCalcRet = detail.dmg(ds, dmg)
|
||||
rowData.push({
|
||||
|
@ -63,8 +63,14 @@ export default class ProfileReq extends Base {
|
||||
this.msg('开始获取数据,可能会需要一定时间~')
|
||||
await sleep(100)
|
||||
// 发起请求
|
||||
let req = await fetch(reqParam.url, reqParam.params || {})
|
||||
let data = await req.json()
|
||||
let data = {}
|
||||
try {
|
||||
let req = await fetch(reqParam.url, reqParam.params || {})
|
||||
data = await req.json()
|
||||
} catch (e) {
|
||||
console.log('面板请求错误', e)
|
||||
data = {}
|
||||
}
|
||||
data = await Serv.response(data, this)
|
||||
// 设置CD
|
||||
cdTime = Serv.getCdTime(data)
|
||||
|
@ -1,3 +1,4 @@
|
||||
import Base from './Base.js'
|
||||
import Character from './Character.js'
|
||||
import Artifact from './Artifact.js'
|
||||
import Avatars from './Avatars.js'
|
||||
@ -8,4 +9,4 @@ import ProfileData from './ProfileData.js'
|
||||
import ProfileArtis from './ProfileArtis.js'
|
||||
import ProfileDmg from './ProfileDmg.js'
|
||||
|
||||
export { Abyss, Character, Artifact, Avatars, ProfileServ, ProfileReq, ProfileData, ProfileArtis, ProfileDmg }
|
||||
export { Base, Abyss, Character, Artifact, Avatars, ProfileServ, ProfileReq, ProfileData, ProfileArtis, ProfileDmg }
|
||||
|
@ -1,321 +1,9 @@
|
||||
import fs from 'fs'
|
||||
import lodash from 'lodash'
|
||||
import { Format } from '../../components/index.js'
|
||||
import { Character } from '../index.js'
|
||||
import { eleBaseDmg, eleMap, attrMap } from './calc-meta.js'
|
||||
import { eleBaseDmg, eleMap, } from './calc-meta.js'
|
||||
import Mastery from './Mastery.js'
|
||||
|
||||
let Calc = {
|
||||
|
||||
async getCharCalcRule (name) {
|
||||
const _path = process.cwd()
|
||||
const cfgPath = `${_path}/plugins/miao-plugin/resources/meta/character/${name}/calc.js`
|
||||
|
||||
let details
|
||||
let buffs = []
|
||||
let defParams = {}
|
||||
let defDmgIdx = -1
|
||||
let mainAttr = 'atk,cpct,cdmg'
|
||||
let enemyName = '小宝'
|
||||
if (fs.existsSync(cfgPath)) {
|
||||
let fileData = await import(`file://${cfgPath}`)
|
||||
details = fileData.details || false
|
||||
buffs = fileData.buffs || []
|
||||
defParams = fileData.defParams || {}
|
||||
if (fileData.defDmgIdx) {
|
||||
defDmgIdx = fileData.defDmgIdx
|
||||
}
|
||||
if (fileData.mainAttr) {
|
||||
mainAttr = fileData.mainAttr
|
||||
}
|
||||
if (fileData.enemyName) {
|
||||
enemyName = fileData.enemyName
|
||||
}
|
||||
}
|
||||
|
||||
if (details) {
|
||||
return { details, buffs, defParams, defDmgIdx, mainAttr, enemyName }
|
||||
}
|
||||
return false
|
||||
},
|
||||
|
||||
// 获取基础属性
|
||||
attr (profile) {
|
||||
let ret = {}
|
||||
let { attr } = profile
|
||||
|
||||
// 基础属性
|
||||
lodash.forEach('atk,def,hp'.split(','), (key) => {
|
||||
ret[key] = {
|
||||
base: attr[`${key}Base`] * 1 || 0,
|
||||
plus: attr[key] * 1 - attr[`${key}Base`] * 1 || 0,
|
||||
pct: 0
|
||||
}
|
||||
})
|
||||
|
||||
lodash.forEach('mastery,recharge,cpct,cdmg,heal,dmg,phy'.split(','), (key) => {
|
||||
ret[key] = {
|
||||
base: attr[key] * 1 || 0,
|
||||
plus: 0,
|
||||
pct: 0,
|
||||
inc: 0 // 护盾增效&治疗增效
|
||||
}
|
||||
})
|
||||
|
||||
// 技能属性记录
|
||||
lodash.forEach('a,a2,a3,e,q'.split(','), (key) => {
|
||||
ret[key] = {
|
||||
pct: 0, // 倍率加成
|
||||
multi: 0, // 独立倍率乘区加成
|
||||
|
||||
plus: 0, // 伤害值提高
|
||||
dmg: 0, // 伤害提高
|
||||
cpct: 0, // 暴击提高
|
||||
cdmg: 0, // 爆伤提高
|
||||
|
||||
def: 0, // 防御降低
|
||||
ignore: 0 // 无视防御
|
||||
}
|
||||
})
|
||||
|
||||
ret.enemy = {
|
||||
def: 0, // 降低防御
|
||||
ignore: 0, // 无视防御
|
||||
phy: 0 // 物理防御
|
||||
}
|
||||
|
||||
ret.shield = {
|
||||
base: 100, // 基础
|
||||
plus: 0, // 护盾强效
|
||||
inc: 100 // 吸收倍率
|
||||
}
|
||||
|
||||
let char = Character.get(profile)
|
||||
ret.weapon = profile.weapon
|
||||
ret.weaponType = char.weaponType
|
||||
ret.element = eleMap[char.elem.toLowerCase()]
|
||||
ret.refine = (profile.weapon.affix * 1 - 1) || 0
|
||||
|
||||
ret.multi = 0
|
||||
|
||||
ret.zf = 0
|
||||
ret.rh = 0
|
||||
ret.gd = 0
|
||||
ret.ks = 0
|
||||
|
||||
ret.kx = 0
|
||||
ret.fykx = 0
|
||||
|
||||
return ret
|
||||
},
|
||||
|
||||
// 获取天赋数据
|
||||
talent (profile, char) {
|
||||
let ret = {}
|
||||
|
||||
let talentData = profile.talent || {}
|
||||
|
||||
lodash.forEach(['a', 'e', 'q'], (key) => {
|
||||
let td = talentData[key] || {}
|
||||
let lv = (td.level || td.level_current || 1) * 1
|
||||
|
||||
let map = {}
|
||||
|
||||
lodash.forEach(char.talent[key].tables, (tr) => {
|
||||
let val = tr.values[lv - 1]
|
||||
val = val.replace(/[^\x00-\xff]/g, '').trim()
|
||||
let valArr = []
|
||||
let valArr2 = []
|
||||
lodash.forEach(val.split('/'), (v, idx) => {
|
||||
let valNum = 0
|
||||
lodash.forEach(v.split('+'), (v) => {
|
||||
v = v.split('*')
|
||||
let v1 = v[0].replace('%', '').trim()
|
||||
valNum += v1 * (v[1] || 1)
|
||||
valArr2.push(v1)
|
||||
})
|
||||
valArr.push(valNum)
|
||||
})
|
||||
|
||||
if (isNaN(valArr[0])) {
|
||||
map[tr.name] = false
|
||||
} else if (valArr.length === 1) {
|
||||
map[tr.name] = valArr[0]
|
||||
} else {
|
||||
map[tr.name] = valArr
|
||||
}
|
||||
map[tr.name + '2'] = valArr2
|
||||
})
|
||||
ret[key] = map
|
||||
})
|
||||
return ret
|
||||
},
|
||||
|
||||
getDs (attr, meta, params) {
|
||||
return {
|
||||
...meta,
|
||||
attr,
|
||||
params,
|
||||
refine: attr.refine,
|
||||
weaponType: attr.weaponType,
|
||||
weapon: attr.weapon,
|
||||
element: eleMap[attr.element] || attr.element,
|
||||
calc (ds) {
|
||||
return (ds.base || 0) + (ds.plus || 0) + ((ds.base || 0) * (ds.pct || 0) / 100)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
calcAttr ({ originalAttr, buffs, meta, params = {}, incAttr = '', reduceAttr = '', talent = '' }) {
|
||||
let attr = lodash.merge({}, originalAttr)
|
||||
let msg = []
|
||||
|
||||
if (incAttr && attrMap[incAttr]) {
|
||||
let aCfg = attrMap[incAttr]
|
||||
attr[incAttr][aCfg.type] += aCfg.val
|
||||
}
|
||||
if (reduceAttr && attrMap[reduceAttr]) {
|
||||
let aCfg = attrMap[reduceAttr]
|
||||
attr[reduceAttr][aCfg.type] -= aCfg.val
|
||||
}
|
||||
|
||||
lodash.forEach(buffs, (buff) => {
|
||||
let ds = Calc.getDs(attr, meta, params)
|
||||
|
||||
ds.currentTalent = talent
|
||||
|
||||
let mKey = {
|
||||
zf: '蒸发',
|
||||
rh: '融化',
|
||||
ks: '扩散'
|
||||
}
|
||||
if (lodash.isString(buff) && mKey[buff]) {
|
||||
buff = {
|
||||
zf: {
|
||||
title: `元素精通:${mKey[buff]}伤害提高[${buff}]%`,
|
||||
mastery: buff
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果存在rule,则进行计算
|
||||
if (buff.check && !buff.check(ds)) {
|
||||
return
|
||||
}
|
||||
if (buff.cons) {
|
||||
if (ds.cons * 1 < buff.cons * 1) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
let title = buff.title
|
||||
|
||||
if (buff.mastery) {
|
||||
let mastery = Math.max(0, attr.mastery.base + attr.mastery.plus)
|
||||
// let masteryNum = 2.78 * mastery / (mastery + 1400) * 100;
|
||||
buff.data = buff.data || {}
|
||||
lodash.forEach(buff.mastery.split(','), (key) => {
|
||||
buff.data[key] = Mastery.getMultiple(key, mastery)
|
||||
// buff.data[key] = masteryNum;
|
||||
})
|
||||
}
|
||||
|
||||
lodash.forEach(buff.data, (val, key) => {
|
||||
if (lodash.isFunction(val)) {
|
||||
val = val(ds)
|
||||
}
|
||||
|
||||
title = title.replace(`[${key}]`, Format.comma(val, 1))
|
||||
// 技能提高
|
||||
let tRet = /^(a|a2|a3|e|q)(Def|Ignore|Dmg|Plus|Pct|Cpct|Cdmg|Multi)$/.exec(key)
|
||||
if (tRet) {
|
||||
attr[tRet[1]][tRet[2].toLowerCase()] += val * 1 || 0
|
||||
return
|
||||
}
|
||||
let aRet = /^(hp|def|atk|mastery|cpct|cdmg|heal|recharge|dmg|phy|shield)(Plus|Pct|Inc)?$/.exec(key)
|
||||
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
|
||||
}
|
||||
|
||||
if (['zf', 'rh', 'kx', 'gd', 'ks', 'fykx'].includes(key)) {
|
||||
attr[key] += val * 1 || 0
|
||||
}
|
||||
})
|
||||
msg.push(title)
|
||||
})
|
||||
|
||||
return {
|
||||
attr, msg
|
||||
}
|
||||
},
|
||||
|
||||
async weapon (weaponName) {
|
||||
const _path = process.cwd()
|
||||
const cfgPath = `${_path}/plugins/miao-plugin/resources/meta/weapons/calc.js`
|
||||
|
||||
let weapons = {}
|
||||
if (fs.existsSync(cfgPath)) {
|
||||
let fileData = await import(`file://${cfgPath}`)
|
||||
weapons = fileData.weapons || {}
|
||||
}
|
||||
|
||||
let weaponCfg = weapons[weaponName] || []
|
||||
if (lodash.isPlainObject(weaponCfg)) {
|
||||
weaponCfg = [weaponCfg]
|
||||
}
|
||||
|
||||
lodash.forEach(weaponCfg, (ds) => {
|
||||
if (!/:/.test(ds.title)) {
|
||||
ds.title = `${weaponName}:${ds.title}`
|
||||
}
|
||||
if (ds.refine) {
|
||||
ds.data = ds.data || {}
|
||||
lodash.forEach(ds.refine, (r, key) => {
|
||||
ds.data[key] = ({ refine }) => r[refine] * (ds.buffCount || 1)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
return weaponCfg
|
||||
},
|
||||
|
||||
async reliquaries (sets) {
|
||||
const _path = process.cwd()
|
||||
const cfgPath = `${_path}/plugins/miao-plugin/resources/meta/reliquaries/calc.js`
|
||||
|
||||
let buffs = {}
|
||||
if (fs.existsSync(cfgPath)) {
|
||||
let fileData = await import(`file://${cfgPath}`)
|
||||
buffs = fileData.buffs || {}
|
||||
}
|
||||
|
||||
let setMap = {}
|
||||
|
||||
lodash.forEach(sets, (set) => {
|
||||
if (set && set.set) {
|
||||
let name = set.set
|
||||
setMap[name] = (setMap[name] || 0) + 1
|
||||
}
|
||||
})
|
||||
|
||||
let retBuffs = []
|
||||
|
||||
lodash.forEach(setMap, (count, setName) => {
|
||||
if (count >= 2 && buffs[setName + 2]) {
|
||||
retBuffs.push(buffs[setName + 2])
|
||||
}
|
||||
if (count >= 4 && buffs[setName + 4]) {
|
||||
retBuffs.push(buffs[setName + 4])
|
||||
}
|
||||
})
|
||||
return retBuffs
|
||||
},
|
||||
|
||||
getDmgFn ({ ds, attr, profile, enemyLv, showDetail = false }) {
|
||||
let { calc } = ds
|
||||
|
||||
@ -449,132 +137,6 @@ let Calc = {
|
||||
}
|
||||
|
||||
return dmgFn
|
||||
},
|
||||
|
||||
async calcData ({ profile, char, enemyLv = 91, mode = 'profile', dmgIdx = 0 }) {
|
||||
let charCalcData = await Calc.getCharCalcRule(char.name)
|
||||
|
||||
if (!charCalcData) {
|
||||
return false
|
||||
}
|
||||
let talent = Calc.talent(profile, char)
|
||||
|
||||
let meta = {
|
||||
cons: profile.cons * 1,
|
||||
talent
|
||||
}
|
||||
|
||||
let { buffs, details, defParams, mainAttr, defDmgIdx, enemyName } = charCalcData
|
||||
|
||||
defParams = defParams || {}
|
||||
|
||||
let originalAttr = Calc.attr(profile)
|
||||
|
||||
let weaponBuffs = await Calc.weapon(profile.weapon.name)
|
||||
let reliBuffs = await Calc.reliquaries(profile.artis)
|
||||
buffs = lodash.concat(buffs, weaponBuffs, reliBuffs)
|
||||
|
||||
lodash.forEach(buffs, (buff) => {
|
||||
buff.sort = lodash.isUndefined(buff.sort) ? 1 : buff.sort
|
||||
})
|
||||
|
||||
buffs = lodash.sortBy(buffs, ['sort'])
|
||||
|
||||
let { msg } = Calc.calcAttr({ originalAttr, buffs, meta, params: defParams || {} })
|
||||
|
||||
let ret = []
|
||||
let detailMap = []
|
||||
let dmgRet = []
|
||||
let dmgDetail = {}
|
||||
|
||||
lodash.forEach(details, (detail, detailSysIdx) => {
|
||||
if (lodash.isFunction(detail)) {
|
||||
let { attr } = Calc.calcAttr({ originalAttr, buffs, meta })
|
||||
let ds = lodash.merge({ talent }, Calc.getDs(attr, meta))
|
||||
detail = detail({ ...ds, attr, profile })
|
||||
}
|
||||
let params = lodash.merge({}, defParams, detail.params || {})
|
||||
let { attr } = Calc.calcAttr({ originalAttr, buffs, meta, params, talent: detail.talent || '' })
|
||||
if (detail.check && !detail.check(Calc.getDs(attr, meta, params))) {
|
||||
return
|
||||
}
|
||||
if (detail.cons && meta.cons < detail.cons * 1) {
|
||||
return
|
||||
}
|
||||
let ds = lodash.merge({ talent }, Calc.getDs(attr, meta, params))
|
||||
|
||||
let dmg = Calc.getDmgFn({ ds, attr, profile, enemyLv, showDetail: detail.showDetail })
|
||||
let basicDmgRet
|
||||
|
||||
if (detail.dmg) {
|
||||
basicDmgRet = detail.dmg(ds, dmg)
|
||||
detail.userIdx = detailMap.length
|
||||
detailMap.push(detail)
|
||||
ret.push({
|
||||
title: detail.title,
|
||||
...basicDmgRet
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
if (mode === 'dmg') {
|
||||
let detail
|
||||
if (dmgIdx && detailMap[dmgIdx - 1]) {
|
||||
detail = detailMap[dmgIdx - 1]
|
||||
} else if (!lodash.isUndefined(defDmgIdx) && details[defDmgIdx]) {
|
||||
detail = details[defDmgIdx]
|
||||
} else {
|
||||
detail = detailMap[0]
|
||||
}
|
||||
|
||||
dmgDetail = {
|
||||
title: detail.title,
|
||||
userIdx: detail.userIdx,
|
||||
basicRet: lodash.merge({}, ret[detail.userIdx]),
|
||||
attr: []
|
||||
}
|
||||
|
||||
mainAttr = mainAttr.split(',')
|
||||
let params = lodash.merge({}, defParams, detail.params || {})
|
||||
let basicDmg = dmgDetail.basicRet
|
||||
lodash.forEach(mainAttr, (reduceAttr) => {
|
||||
dmgDetail.attr.push(attrMap[reduceAttr])
|
||||
let rowData = []
|
||||
lodash.forEach(mainAttr, (incAttr) => {
|
||||
if (incAttr === reduceAttr) {
|
||||
rowData.push({ type: 'na' })
|
||||
return
|
||||
}
|
||||
let { attr } = Calc.calcAttr({
|
||||
originalAttr,
|
||||
buffs,
|
||||
meta,
|
||||
params,
|
||||
incAttr,
|
||||
reduceAttr,
|
||||
talent: detail.talent || ''
|
||||
})
|
||||
let ds = lodash.merge({ talent }, Calc.getDs(attr, meta, params))
|
||||
let dmg = Calc.getDmgFn({ ds, attr, profile, enemyLv })
|
||||
if (detail.dmg) {
|
||||
let dmgCalcRet = detail.dmg(ds, dmg)
|
||||
rowData.push({
|
||||
type: dmgCalcRet.avg === basicDmg.avg ? 'avg' : (dmgCalcRet.avg > basicDmg.avg ? 'gt' : 'lt'),
|
||||
...dmgCalcRet
|
||||
})
|
||||
}
|
||||
})
|
||||
dmgRet.push(rowData)
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
ret,
|
||||
msg,
|
||||
dmgRet,
|
||||
enemyName,
|
||||
dmgCfg: dmgDetail
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
184
models/profile-lib/DmgAttr.js
Normal file
184
models/profile-lib/DmgAttr.js
Normal file
@ -0,0 +1,184 @@
|
||||
/*
|
||||
* 伤害计算 - 属性计算
|
||||
* */
|
||||
import { attrMap, eleMap } from './calc-meta.js'
|
||||
import lodash from 'lodash'
|
||||
import Mastery from './Mastery.js'
|
||||
import { Format } from '../../components/index.js'
|
||||
|
||||
let DmgAttr = {
|
||||
// 计算并返回指定属性值
|
||||
getAttrValue (ds) {
|
||||
return (ds.base || 0) + (ds.plus || 0) + ((ds.base || 0) * (ds.pct || 0) / 100)
|
||||
},
|
||||
|
||||
// 获取profile对应attr属性值
|
||||
getAttr ({ id, attr, weapon, char }) {
|
||||
let ret = {}
|
||||
|
||||
// 基础属性
|
||||
lodash.forEach('atk,def,hp'.split(','), (key) => {
|
||||
ret[key] = {
|
||||
base: attr[`${key}Base`] * 1 || 0,
|
||||
plus: attr[key] * 1 - attr[`${key}Base`] * 1 || 0,
|
||||
pct: 0
|
||||
}
|
||||
})
|
||||
|
||||
lodash.forEach('mastery,recharge,cpct,cdmg,heal,dmg,phy'.split(','), (key) => {
|
||||
ret[key] = {
|
||||
base: attr[key] * 1 || 0, // 基础值
|
||||
plus: 0, // 加成值
|
||||
pct: 0, // 百分比加成
|
||||
inc: 0 // 提高:护盾增效&治疗增效
|
||||
}
|
||||
})
|
||||
|
||||
// 技能属性记录
|
||||
lodash.forEach('a,a2,a3,e,q'.split(','), (key) => {
|
||||
ret[key] = {
|
||||
pct: 0, // 倍率加成
|
||||
multi: 0, // 独立倍率乘区加成,宵宫E等
|
||||
|
||||
plus: 0, // 伤害值提高
|
||||
dmg: 0, // 伤害提高
|
||||
cpct: 0, // 暴击提高
|
||||
cdmg: 0, // 爆伤提高
|
||||
|
||||
def: 0, // 防御降低
|
||||
ignore: 0 // 无视防御
|
||||
}
|
||||
})
|
||||
|
||||
ret.enemy = {
|
||||
def: 0, // 降低防御
|
||||
ignore: 0, // 无视防御
|
||||
phy: 0 // 物理防御
|
||||
}
|
||||
|
||||
ret.shield = {
|
||||
base: 100, // 基础
|
||||
plus: 0, // 护盾强效
|
||||
inc: 100 // 吸收倍率
|
||||
}
|
||||
|
||||
ret.weapon = weapon // 武器
|
||||
ret.weaponType = char.weaponType // 武器类型
|
||||
ret.element = eleMap[char.elem.toLowerCase()] // 元素类型
|
||||
ret.refine = ((weapon.affix || ret.refine || 1) * 1 - 1) || 0 // 武器精炼
|
||||
ret.multi = 0 // 倍率独立乘区
|
||||
ret.zf = 0 // 蒸发
|
||||
ret.rh = 0 // 融化
|
||||
ret.gd = 0 // 感电
|
||||
ret.ks = 0 // 扩散
|
||||
ret.kx = 0 // 敌人抗性降低
|
||||
ret.fykx = 0 // 敌人反应抗性降低
|
||||
|
||||
return ret
|
||||
},
|
||||
|
||||
// 获取数据集
|
||||
getDs (attr, meta, params) {
|
||||
return {
|
||||
...meta,
|
||||
attr,
|
||||
params,
|
||||
refine: attr.refine,
|
||||
weaponType: attr.weaponType,
|
||||
weapon: attr.weapon,
|
||||
element: eleMap[attr.element] || attr.element,
|
||||
// 计算属性
|
||||
calc: DmgAttr.getAttrValue
|
||||
}
|
||||
},
|
||||
|
||||
// 计算属性
|
||||
calcAttr ({ originalAttr, buffs, meta, params = {}, incAttr = '', reduceAttr = '', talent = '' }) {
|
||||
let attr = lodash.merge({}, originalAttr)
|
||||
let msg = []
|
||||
|
||||
if (incAttr && attrMap[incAttr]) {
|
||||
let aCfg = attrMap[incAttr]
|
||||
attr[incAttr][aCfg.type] += aCfg.val
|
||||
}
|
||||
if (reduceAttr && attrMap[reduceAttr]) {
|
||||
let aCfg = attrMap[reduceAttr]
|
||||
attr[reduceAttr][aCfg.type] -= aCfg.val
|
||||
}
|
||||
|
||||
lodash.forEach(buffs, (buff) => {
|
||||
let ds = DmgAttr.getDs(attr, meta, params)
|
||||
|
||||
ds.currentTalent = talent
|
||||
|
||||
let mKey = {
|
||||
zf: '蒸发',
|
||||
rh: '融化',
|
||||
ks: '扩散'
|
||||
}
|
||||
if (lodash.isString(buff) && mKey[buff]) {
|
||||
buff = {
|
||||
zf: {
|
||||
title: `元素精通:${mKey[buff]}伤害提高[${buff}]%`,
|
||||
mastery: buff
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果存在rule,则进行计算
|
||||
if (buff.check && !buff.check(ds)) {
|
||||
return
|
||||
}
|
||||
if (buff.cons) {
|
||||
if (ds.cons * 1 < buff.cons * 1) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
let title = buff.title
|
||||
|
||||
if (buff.mastery) {
|
||||
let mastery = Math.max(0, attr.mastery.base + attr.mastery.plus)
|
||||
// let masteryNum = 2.78 * mastery / (mastery + 1400) * 100;
|
||||
buff.data = buff.data || {}
|
||||
lodash.forEach(buff.mastery.split(','), (key) => {
|
||||
buff.data[key] = Mastery.getMultiple(key, mastery)
|
||||
// buff.data[key] = masteryNum;
|
||||
})
|
||||
}
|
||||
|
||||
lodash.forEach(buff.data, (val, key) => {
|
||||
if (lodash.isFunction(val)) {
|
||||
val = val(ds)
|
||||
}
|
||||
|
||||
title = title.replace(`[${key}]`, Format.comma(val, 1))
|
||||
// 技能提高
|
||||
let tRet = /^(a|a2|a3|e|q)(Def|Ignore|Dmg|Plus|Pct|Cpct|Cdmg|Multi)$/.exec(key)
|
||||
if (tRet) {
|
||||
attr[tRet[1]][tRet[2].toLowerCase()] += val * 1 || 0
|
||||
return
|
||||
}
|
||||
let aRet = /^(hp|def|atk|mastery|cpct|cdmg|heal|recharge|dmg|phy|shield)(Plus|Pct|Inc)?$/.exec(key)
|
||||
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
|
||||
}
|
||||
|
||||
if (['zf', 'rh', 'kx', 'gd', 'ks', 'fykx'].includes(key)) {
|
||||
attr[key] += val * 1 || 0
|
||||
}
|
||||
})
|
||||
msg.push(title)
|
||||
})
|
||||
|
||||
return {
|
||||
attr, msg
|
||||
}
|
||||
}
|
||||
}
|
||||
export default DmgAttr
|
87
models/profile-lib/DmgBuffs.js
Normal file
87
models/profile-lib/DmgBuffs.js
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 伤害计算 - Buff计算
|
||||
* */
|
||||
import lodash from 'lodash'
|
||||
|
||||
let weaponBuffs = {}
|
||||
let artisBuffs = {}
|
||||
|
||||
let DmgBuffs = {
|
||||
// 圣遗物Buff
|
||||
getArtisBuffs (artis) {
|
||||
let buffs = artisBuffs
|
||||
let setMap = {}
|
||||
lodash.forEach(artis, (arti, name) => {
|
||||
if (lodash.isNumber(arti)) {
|
||||
setMap[name] = arti
|
||||
} else {
|
||||
if (arti && arti.set) {
|
||||
let name = arti.set
|
||||
setMap[name] = (setMap[name] || 0) + 1
|
||||
}
|
||||
}
|
||||
})
|
||||
let retBuffs = []
|
||||
lodash.forEach(setMap, (count, setName) => {
|
||||
if (count >= 2 && buffs[setName + 2]) {
|
||||
retBuffs.push(buffs[setName + 2])
|
||||
}
|
||||
if (count >= 4 && buffs[setName + 4]) {
|
||||
retBuffs.push(buffs[setName + 4])
|
||||
}
|
||||
})
|
||||
return retBuffs
|
||||
},
|
||||
|
||||
// 武器Buff
|
||||
getWeaponBuffs (weaponName) {
|
||||
let weaponCfg = weaponBuffs[weaponName] || []
|
||||
if (lodash.isPlainObject(weaponCfg)) {
|
||||
weaponCfg = [weaponCfg]
|
||||
}
|
||||
lodash.forEach(weaponCfg, (ds) => {
|
||||
if (!/:/.test(ds.title)) {
|
||||
ds.title = `${weaponName}:${ds.title}`
|
||||
}
|
||||
if (ds.refine) {
|
||||
ds.data = ds.data || {}
|
||||
lodash.forEach(ds.refine, (r, key) => {
|
||||
ds.data[key] = ({ refine }) => r[refine] * (ds.buffCount || 1)
|
||||
})
|
||||
}
|
||||
})
|
||||
return weaponCfg
|
||||
},
|
||||
|
||||
getBuffs (profile, buffs = []) {
|
||||
let weaponBuffs = DmgBuffs.getWeaponBuffs(profile.weapon?.name || '')
|
||||
let artisBuffs = DmgBuffs.getArtisBuffs(profile.artis || {})
|
||||
buffs = lodash.concat(buffs, weaponBuffs, artisBuffs)
|
||||
let mKey = {
|
||||
zf: '蒸发',
|
||||
rh: '融化',
|
||||
ks: '扩散'
|
||||
}
|
||||
lodash.forEach(buffs, (buff, idx) => {
|
||||
if (lodash.isString(buff) && mKey[buff]) {
|
||||
buff = {
|
||||
title: `元素精通:${mKey[buff]}伤害提高[${buff}]%`,
|
||||
mastery: buff
|
||||
}
|
||||
buffs[idx] = buff
|
||||
}
|
||||
buff.sort = lodash.isUndefined(buff.sort) ? 1 : buff.sort
|
||||
})
|
||||
buffs = lodash.sortBy(buffs, ['sort'])
|
||||
return buffs
|
||||
}
|
||||
}
|
||||
|
||||
async function init () {
|
||||
const _path = `file://${process.cwd()}/plugins/miao-plugin/resources/meta`
|
||||
weaponBuffs = (await import(`${_path}/weapons/calc.js`)).weapons || {}
|
||||
artisBuffs = (await import(`${_path}/reliquaries/calc.js`)).buffs || {}
|
||||
}
|
||||
|
||||
await init()
|
||||
export default DmgBuffs
|
162
models/profile-lib/DmgCalc.js
Normal file
162
models/profile-lib/DmgCalc.js
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* 伤害计算 - 计算伤害
|
||||
* */
|
||||
import { eleBaseDmg } from './calc-meta.js'
|
||||
import Mastery from './Mastery.js'
|
||||
|
||||
let DmgCalc = {
|
||||
calcRet (fnArgs = {}, data = {}) {
|
||||
let {
|
||||
pctNum, // 技能倍率
|
||||
talent, // 天赋类型
|
||||
ele, // 元素反应
|
||||
basicNum, // 基础数值
|
||||
mode // 模式
|
||||
} = fnArgs
|
||||
let {
|
||||
ds, // 数据集
|
||||
attr, // 属性
|
||||
level, // 面板数据
|
||||
enemyLv, // 敌人等级
|
||||
showDetail = false // 是否展示详情
|
||||
} = data
|
||||
let calc = ds.calc
|
||||
|
||||
let { atk, dmg, phy, cdmg, cpct } = attr
|
||||
// 攻击区
|
||||
let atkNum = calc(atk)
|
||||
|
||||
// 倍率独立乘区
|
||||
let multiNum = attr.multi / 100
|
||||
|
||||
// 增伤区
|
||||
let dmgNum = (1 + dmg.base / 100 + dmg.plus / 100)
|
||||
|
||||
if (ele === 'phy') {
|
||||
dmgNum = (1 + phy.base / 100 + phy.plus / 100)
|
||||
}
|
||||
|
||||
let cpctNum = cpct.base / 100 + cpct.plus / 100
|
||||
|
||||
// 爆伤区
|
||||
let cdmgNum = cdmg.base / 100 + cdmg.plus / 100
|
||||
|
||||
let enemyDef = attr.enemy.def / 100
|
||||
let enemyIgnore = attr.enemy.ignore / 100
|
||||
|
||||
let plusNum = 0
|
||||
|
||||
if (talent && attr[talent]) {
|
||||
pctNum = pctNum / 100
|
||||
|
||||
let ds = attr[talent]
|
||||
|
||||
pctNum += ds.pct / 100
|
||||
dmgNum += ds.dmg / 100
|
||||
cpctNum += ds.cpct / 100
|
||||
cdmgNum += ds.cdmg / 100
|
||||
enemyDef += ds.def / 100
|
||||
enemyIgnore += ds.ignore / 100
|
||||
multiNum += ds.multi / 100
|
||||
plusNum += ds.plus
|
||||
}
|
||||
|
||||
// 防御区
|
||||
let defNum = (level + 100) / ((level + 100) + (enemyLv + 100) * (1 - enemyDef) * (1 - enemyIgnore))
|
||||
|
||||
// 抗性区
|
||||
let kx = attr.kx
|
||||
if (talent === 'fy') {
|
||||
kx = attr.fykx
|
||||
}
|
||||
kx = 10 - (kx || 0)
|
||||
let kNum = 0.9
|
||||
if (kx >= 0) {
|
||||
kNum = (100 - kx) / 100
|
||||
} else {
|
||||
kNum = 1 - kx / 200
|
||||
}
|
||||
|
||||
// 反应区
|
||||
let eleNum = 1
|
||||
let eleBase = 0
|
||||
|
||||
if (ele === 'ks' || ele === 'gd') {
|
||||
eleBase = eleBaseDmg[level] || 0
|
||||
}
|
||||
|
||||
if (ele === 'phy') {
|
||||
// do nothing
|
||||
} else if (ele) {
|
||||
eleNum = Mastery.getBasePct(ele, attr.element)
|
||||
|
||||
if (attr[ele]) {
|
||||
eleNum = eleNum * (1 + attr[ele] / 100)
|
||||
}
|
||||
}
|
||||
|
||||
cpctNum = Math.max(0, Math.min(1, cpctNum))
|
||||
if (cpctNum === 0) {
|
||||
cdmgNum = 0
|
||||
}
|
||||
|
||||
let ret = {}
|
||||
if (mode === 'basic') {
|
||||
ret = {
|
||||
dmg: basicNum * dmgNum * (1 + cdmgNum) * defNum * kNum * eleNum,
|
||||
avg: basicNum * dmgNum * (1 + cpctNum * cdmgNum) * defNum * kNum * eleNum
|
||||
}
|
||||
} else if (eleBase) {
|
||||
ret = {
|
||||
avg: eleBase * kNum * eleNum
|
||||
}
|
||||
} else {
|
||||
// 计算最终伤害
|
||||
ret = {
|
||||
dmg: (atkNum * pctNum * (1 + multiNum) + plusNum) * dmgNum * (1 + cdmgNum) * defNum * kNum * eleNum,
|
||||
avg: (atkNum * pctNum * (1 + multiNum) + plusNum) * dmgNum * (1 + cpctNum * cdmgNum) * defNum * kNum * eleNum
|
||||
}
|
||||
}
|
||||
if (showDetail) {
|
||||
console.log(attr, { atkNum, pctNum, multiNum, plusNum, dmgNum, cpctNum, cdmgNum, defNum, eleNum, kNum }, ret)
|
||||
}
|
||||
|
||||
return ret
|
||||
},
|
||||
getDmgFn (data) {
|
||||
let { showDetail, attr } = data
|
||||
let { calc } = attr
|
||||
|
||||
let dmgFn = function (pctNum = 0, talent = false, ele = false, basicNum = 0, mode = 'talent') {
|
||||
return DmgCalc.calcRet({ pctNum, talent, ele, basicNum, mode }, data)
|
||||
}
|
||||
|
||||
dmgFn.basic = function (basicNum = 0, talent = false, ele = false) {
|
||||
return dmgFn(0, talent, ele, basicNum, 'basic')
|
||||
}
|
||||
|
||||
// 计算治疗
|
||||
dmgFn.heal = function (num) {
|
||||
if (showDetail) {
|
||||
console.log(num, calc(attr.heal), attr.heal.inc)
|
||||
}
|
||||
return {
|
||||
avg: num * (1 + calc(attr.heal) / 100 + attr.heal.inc / 100)
|
||||
}
|
||||
}
|
||||
|
||||
// 计算护盾
|
||||
dmgFn.shield = function (num) {
|
||||
return {
|
||||
avg: num * (calc(attr.shield) / 100) * (attr.shield.inc / 100)
|
||||
}
|
||||
}
|
||||
// 扩散方法
|
||||
dmgFn.ks = function () {
|
||||
return dmgFn(0, 'fy', 'ks')
|
||||
}
|
||||
|
||||
return dmgFn
|
||||
}
|
||||
}
|
||||
export default DmgCalc
|
@ -1,10 +1,10 @@
|
||||
import Calc from '../models/profile-lib/Calc.js'
|
||||
import { Character } from '../models/index.js'
|
||||
import Miao from '../components/profile-data/miao.js'
|
||||
import { Data } from '../components/index.js'
|
||||
import { ProfileDmg } from '../models/index.js'
|
||||
|
||||
export async function calcDmg (inputData, enemyLv = 86) {
|
||||
let profile = Miao.getAvatarDetail(inputData)
|
||||
console.log(profile)
|
||||
let char = Character.get(profile)
|
||||
return await Calc.calcData({ profile, char, enemyLv })
|
||||
let dmg = new ProfileDmg(inputData)
|
||||
let ret = await dmg.calcData({ enemyLv })
|
||||
ret = Data.getData(ret, 'ret,msg,enemyName')
|
||||
ret.enemyLevel = enemyLv
|
||||
return ret
|
||||
}
|
Loading…
Reference in New Issue
Block a user