调整元素属性底层逻辑

This commit is contained in:
Kokomi 2022-11-24 23:27:03 +08:00
parent abfb93c111
commit 768a7b80c3
16 changed files with 118 additions and 142 deletions

View File

@ -1,9 +1,8 @@
import lodash from 'lodash' import lodash from 'lodash'
import { Character } from '../models/index.js' import Elem from './common-lib/elem.js'
let CharId = Character.CharId
let Format = { let Format = {
...Elem,
int: function (d) { int: function (d) {
return parseInt(d) return parseInt(d)
}, },
@ -18,25 +17,7 @@ let Format = {
}, },
percent: function (num, fix = 1) { percent: function (num, fix = 1) {
return Format.pct(num * 100, fix) return Format.pct(num * 100, fix)
},
elem: function (str, def = '') {
let ret = CharId.matchElem(str, def)
return ret ? ret.elem : def
},
elemName: function (elem, def = '') {
return CharId.getElemName(elem) || def
},
isElem (elem) {
return !!CharId.getElemName(elem)
},
elemTitleMap () {
return CharId.elemTitleMap
} }
} }
export default Format export default Format

View File

@ -0,0 +1,65 @@
import { Data } from '../index.js'
import lodash from 'lodash'
const elemAlias = {
anemo: '风,蒙德',
geo: '岩,璃月',
electro: '雷,电,雷电,稻妻',
dendro: '草,须弥',
pyro: '火,纳塔',
hydro: '水,枫丹',
cryo: '冰,至冬'
}
// 元素属性映射, 名称=>elem
let elemMap = {}
// 标准元素名
let elemTitleMap = {}
lodash.forEach(elemAlias, (txt, key) => {
elemMap[key] = key
elemTitleMap[key] = txt[0]
Data.eachStr(txt, (t) => (elemMap[t] = key))
})
const Elem = {
// 根据名称获取元素key
elem (elem = '', defElem = '') {
elem = elem.toLowerCase()
return elemMap[elem] || defElem
},
// 根据key获取元素名
elemName (elem = '', defName = '') {
return elemTitleMap[Elem.elem(elem)] || defName
},
// 从字符串中匹配元素
matchElem (name = '', defElem = '', withName = false) {
const elemReg = new RegExp(`^(${lodash.keys(elemMap).join('|')})`)
let elemRet = elemReg.exec(name)
let elem = (elemRet && elemRet[1]) ? Elem.elem(elemRet[1]) : defElem
if (elem) {
if (withName) {
return {
elem,
name: name.replace(elemReg, '')
}
}
return elem
}
return ''
},
eachElem (fn) {
lodash.forEach(elemTitleMap, (title, key) => {
fn(key, title)
})
},
isElem (elem = '') {
return !!elemMap[elem]
}
}
export default Elem

View File

@ -6,7 +6,7 @@
* */ * */
import lodash from 'lodash' import lodash from 'lodash'
import Base from './Base.js' import Base from './Base.js'
import { Data } from '../components/index.js' import { Data, Format } from '../components/index.js'
import CharImg from './character-lib/CharImg.js' import CharImg from './character-lib/CharImg.js'
import CharTalent from './character-lib/CharTalent.js' import CharTalent from './character-lib/CharTalent.js'
import CharId from './character-lib/CharId.js' import CharId from './character-lib/CharId.js'
@ -33,7 +33,7 @@ class Character extends Base {
if (!this.isCustom) { if (!this.isCustom) {
let meta = getMeta(name) let meta = getMeta(name)
this.meta = meta this.meta = meta
this.elem = CharId.getElem(elem || meta.elem) || 'anemo' this.elem = Format.elem(elem || meta.elem, 'anemo')
} else { } else {
this.meta = {} this.meta = {}
} }
@ -95,7 +95,7 @@ class Character extends Base {
// 获取元素名称 // 获取元素名称
get elemName () { get elemName () {
return CharId.getElemName(this.elem) return Format.elemName(this.elem)
} }
// 获取角色描述 // 获取角色描述
@ -322,14 +322,6 @@ class Character extends Base {
} }
return this._calcRule return this._calcRule
} }
static matchElem (str, def) {
return CharId.matchElem(str, def)
}
static matchElemName () {
}
} }
Character.CharId = CharId Character.CharId = CharId

View File

@ -19,8 +19,10 @@ export default class ProfileArtis extends Base {
setProfile (profile, artis) { setProfile (profile, artis) {
this.profile = profile this.profile = profile
if (artis) {
this.setArtisSet(artis) this.setArtisSet(artis)
} }
}
setArtisSet (ds) { setArtisSet (ds) {
for (let key in ds) { for (let key in ds) {
@ -75,6 +77,10 @@ export default class ProfileArtis extends Base {
return this.getSetData().names || [] return this.getSetData().names || []
} }
get hasArtis () {
return !lodash.isEmpty(this.artis)
}
mainAttr (idx = '') { mainAttr (idx = '') {
if (!idx) { if (!idx) {
let ret = {} let ret = {}

View File

@ -63,10 +63,8 @@ export default class ProfileData extends Base {
} }
setArtis (ds = false) { setArtis (ds = false) {
if (ds) {
this.artis.setProfile(this, ds) this.artis.setProfile(this, ds)
} }
}
setTalent (ds = {}, mode = 'level') { setTalent (ds = {}, mode = 'level') {
this.talent = this.char.getAvatarTalent(ds, this.cons, mode) this.talent = this.char.getAvatarTalent(ds, this.cons, mode)

View File

@ -2,7 +2,7 @@ import fs from 'fs'
import lodash from 'lodash' import lodash from 'lodash'
import Base from './Base.js' import Base from './Base.js'
import { Character } from './index.js' import { Character } from './index.js'
import { attrMap } from './profile-lib/DmgCalcMeta.js' import { attrMap } from '../resources/meta/artifact/index.js'
import DmgBuffs from './profile-lib/DmgBuffs.js' import DmgBuffs from './profile-lib/DmgBuffs.js'
import DmgAttr from './profile-lib/DmgAttr.js' import DmgAttr from './profile-lib/DmgAttr.js'
import DmgCalc from './profile-lib/DmgCalc.js' import DmgCalc from './profile-lib/DmgCalc.js'
@ -195,6 +195,7 @@ export default class ProfileDmg extends Base {
attr: [] attr: []
} }
// 计算角色属性增减
mainAttr = mainAttr.split(',') mainAttr = mainAttr.split(',')
let params = lodash.merge({}, defParams, detail.params || {}) let params = lodash.merge({}, defParams, detail.params || {})
let basicDmg = dmgDetail.basicRet let basicDmg = dmgDetail.basicRet
@ -232,7 +233,6 @@ export default class ProfileDmg extends Base {
if (mode === 'single') { if (mode === 'single') {
return ret[0] return ret[0]
} }
return { return {
ret, ret,
msg, msg,

View File

@ -30,7 +30,7 @@ export default class ProfileRank {
* @returns {Promise<{}|boolean>} * @returns {Promise<{}|boolean>}
*/ */
async getRank (profile, force = false) { async getRank (profile, force = false) {
if (!this.groupId || !this.allowRank || !profile.hasData) { if (!profile || !this.groupId || !this.allowRank || !profile.hasData) {
return false return false
} }
let ret = {} let ret = {}
@ -46,7 +46,7 @@ export default class ProfileRank {
} }
async getTypeRank (profile, type, force) { async getTypeRank (profile, type, force) {
if (!profile.hasData || !type) { if (!profile || !profile.hasData || !type) {
return false return false
} }
if (type === 'dmg' && !profile.hasDmg) { if (type === 'dmg' && !profile.hasDmg) {
@ -85,7 +85,13 @@ export default class ProfileRank {
} }
async getTypeValue (profile, type) { async getTypeValue (profile, type) {
if (!profile || !profile.hasData) {
return false
}
if (type === 'mark') { if (type === 'mark') {
if (!profile?.artis?.hasArtis) {
return false
}
let mark = profile.getArtisMark(false) let mark = profile.getArtisMark(false)
if (mark && mark._mark) { if (mark && mark._mark) {
return { return {

View File

@ -60,7 +60,7 @@ export default class ProfileReq extends Base {
return this.err(`请求过快,请${cdTime}秒后重试..`) return this.err(`请求过快,请${cdTime}秒后重试..`)
} }
await this.setCd(20) await this.setCd(20)
this.msg('开始获取数据,可能会需要一定时间~') this.msg(`开始获取uid:${this.uid}的数据,可能会需要一定时间~`)
await sleep(100) await sleep(100)
// 发起请求 // 发起请求
let data = {} let data = {}

View File

@ -2,8 +2,8 @@
* 角色别名及角色ID相关 * 角色别名及角色ID相关
* */ * */
import lodash from 'lodash' import lodash from 'lodash'
import { Data } from '../../components/index.js' import { Data, Format } from '../../components/index.js'
import { charPosIdx, elemAlias } from './CharMeta.js' import { charPosIdx } from './CharMeta.js'
// 别名表 // 别名表
let aliasMap = {} let aliasMap = {}
@ -15,10 +15,6 @@ let abbrMap = {}
let wifeMap = {} let wifeMap = {}
// id排序 // id排序
let idSort = {} let idSort = {}
// 元素属性映射
let elemMap = {}
// 元素名
let elemTitleMap = {}
let gsCfg let gsCfg
@ -70,12 +66,6 @@ lodash.forEach(charPosIdx, (chars, pos) => {
}) })
}) })
lodash.forEach(elemAlias, (txt, key) => {
elemMap[key] = key
elemTitleMap[key] = txt[0]
Data.eachStr(txt, (t) => (elemMap[t] = key))
})
const CharId = { const CharId = {
aliasMap, aliasMap,
idMap, idMap,
@ -92,7 +82,7 @@ const CharId = {
if (!lodash.isObject(ds)) { if (!lodash.isObject(ds)) {
ds = lodash.trim(ds || '').toLowerCase() ds = lodash.trim(ds || '').toLowerCase()
// 尝试使用元素起始匹配 // 尝试使用元素起始匹配
let em = CharId.matchElem(ds) let em = Format.matchElem(ds, '', true)
if (em && aliasMap[em.name] && CharId.isTraveler(aliasMap[em.name])) { if (em && aliasMap[em.name] && CharId.isTraveler(aliasMap[em.name])) {
return ret(aliasMap[em.name], em.elem) return ret(aliasMap[em.name], em.elem)
} }
@ -112,7 +102,7 @@ const CharId = {
} }
// 获取字段进行匹配 // 获取字段进行匹配
let { id = '', name = '' } = ds let { id = '', name = '' } = ds
let elem = CharId.getElem(ds.elem || ds.element) || '' let elem = Format.elem(ds.elem || ds.element)
// 直接匹配 // 直接匹配
if (aliasMap[id || name]) { if (aliasMap[id || name]) {
return ret(aliasMap[id || name], elem) return ret(aliasMap[id || name], elem)
@ -133,36 +123,6 @@ const CharId = {
return false return false
}, },
// 获取元素
getElem (elem = '') {
elem = elem.toLowerCase()
return elemMap[elem] || false
},
// 获取元素名
getElemName (elem = '') {
return elemTitleMap[CharId.getElem(elem)]
},
elemTitleMap,
// 名字匹配元素
matchElem (name = '', defElem = '') {
const elemReg = new RegExp(`^(${lodash.keys(elemMap).join('|')})`)
let elemRet = elemReg.exec(name)
if (elemRet && elemRet[1]) {
return {
elem: CharId.getElem(elemRet[1]),
name: name.replace(elemReg, '')
}
} else if (defElem) {
return {
elem: CharId.getElem(defElem),
name
}
}
return false
},
getTravelerId (id) { getTravelerId (id) {
return id * 1 === 10000005 ? 10000005 : 10000007 return id * 1 === 10000005 ? 10000005 : 10000007
} }

View File

@ -3,7 +3,7 @@
* */ * */
import lodash from 'lodash' import lodash from 'lodash'
import { Material } from '../index.js' import { Material } from '../index.js'
import { Format, Data } from '../../components/index.js' import { Format } from '../../components/index.js'
// 角色排序 // 角色排序
export const charPosIdx = { export const charPosIdx = {
@ -13,17 +13,6 @@ export const charPosIdx = {
4: '班尼特,心海,琴,芭芭拉,七七,迪奥娜,托马,空,荧,阿贝多,钟离' 4: '班尼特,心海,琴,芭芭拉,七七,迪奥娜,托马,空,荧,阿贝多,钟离'
} }
// 元素别名
export const elemAlias = {
anemo: '风,蒙德',
geo: '岩,璃月',
electro: '雷,电,雷电,稻妻',
dendro: '草,须弥',
pyro: '火,纳塔',
hydro: '水,枫丹',
cryo: '冰,至冬'
}
export const baseAttrName = { export const baseAttrName = {
hp: '基础生命', hp: '基础生命',
atk: '基础攻击', atk: '基础攻击',

View File

@ -6,7 +6,7 @@ let ArtisMark = {
// 根据Key获取标题 // 根据Key获取标题
getKeyByTitle (title, dmg = false) { getKeyByTitle (title, dmg = false) {
if (/元素伤害加成/.test(title)) { if (/元素伤害加成/.test(title)) {
let elem = Format.elem(title) let elem = Format.matchElem(title)
return dmg ? 'dmg' : elem return dmg ? 'dmg' : elem
} else if (title === '物理伤害加成') { } else if (title === '物理伤害加成') {
return 'phy' return 'phy'
@ -29,7 +29,7 @@ let ArtisMark = {
lodash.forEach(attrMap, (ds, key) => { lodash.forEach(attrMap, (ds, key) => {
ret[key] = ds.title ret[key] = ds.title
}) })
lodash.forEach(Format.elemTitleMap(), (name, key) => { Format.eachElem((key, name) => {
ret[key] = `${name}伤加成` ret[key] = `${name}伤加成`
}) })
return ret return ret

View File

@ -17,20 +17,13 @@ async function init () {
} }
} }
} }
await init() await init()
const CharArtis = { const CharArtis = {
reduceWeight (weight, key, plus, max) {
let original = weight[key] || 0
if (original < max) {
weight[key] = Math.max(original + plus, max)
return true
}
return false
},
getCharArtisCfg (char, profile, artis) { getCharArtisCfg (char, profile, artis) {
let { attr, weapon } = profile let { attr, weapon } = profile
let rule = function (title, attrWeight) { let rule = function (title, attrWeight) {
return { return {
title, title,

View File

@ -1,7 +1,7 @@
/* /*
* 伤害计算 - 属性计算 * 伤害计算 - 属性计算
* */ * */
import { attrMap, eleMap } from './DmgCalcMeta.js' import { attrMap } from '../../resources/meta/artifact/index.js'
import lodash from 'lodash' import lodash from 'lodash'
import DmgMastery from './DmgMastery.js' import DmgMastery from './DmgMastery.js'
import { Format } from '../../components/index.js' import { Format } from '../../components/index.js'
@ -64,7 +64,7 @@ let DmgAttr = {
ret.weapon = weapon // 武器 ret.weapon = weapon // 武器
ret.weaponType = char.weaponType // 武器类型 ret.weaponType = char.weaponType // 武器类型
ret.element = eleMap[char.elem.toLowerCase()] // 元素类型 ret.element = Format.elemName(char.elem) // 元素类型
ret.refine = ((weapon.affix || ret.refine || 1) * 1 - 1) || 0 // 武器精炼 ret.refine = ((weapon.affix || ret.refine || 1) * 1 - 1) || 0 // 武器精炼
ret.multi = 0 // 倍率独立乘区 ret.multi = 0 // 倍率独立乘区
ret.vaporize = 0 // 蒸发 ret.vaporize = 0 // 蒸发
@ -94,7 +94,7 @@ let DmgAttr = {
refine: attr.refine, refine: attr.refine,
weaponType: attr.weaponType, weaponType: attr.weaponType,
weapon: attr.weapon, weapon: attr.weapon,
element: eleMap[attr.element] || attr.element, element: Format.elemName(attr.element) || attr.element,
// 计算属性 // 计算属性
calc: DmgAttr.getAttrValue calc: DmgAttr.getAttrValue
} }
@ -107,11 +107,11 @@ let DmgAttr = {
if (incAttr && attrMap[incAttr]) { if (incAttr && attrMap[incAttr]) {
let aCfg = attrMap[incAttr] let aCfg = attrMap[incAttr]
attr[incAttr][aCfg.type] += aCfg.val attr[incAttr][aCfg.calc] += aCfg.value
} }
if (reduceAttr && attrMap[reduceAttr]) { if (reduceAttr && attrMap[reduceAttr]) {
let aCfg = attrMap[reduceAttr] let aCfg = attrMap[reduceAttr]
attr[reduceAttr][aCfg.type] -= aCfg.val attr[reduceAttr][aCfg.calc] -= aCfg.value
} }
lodash.forEach(buffs, (buff) => { lodash.forEach(buffs, (buff) => {

View File

@ -1,15 +1,5 @@
import lodash from 'lodash' import lodash from 'lodash'
export const eleMap = {
anemo: '风',
cryo: '冰',
electro: '雷',
geo: '岩',
hydro: '水',
pyro: '火',
dendro: '草'
}
// 元素反应类型及基数 // 元素反应类型及基数
export const erType = { export const erType = {
vaporize: { type: 'pct', num: ({ element }) => element === '水' ? 2 : 1.5, title: '蒸发' }, vaporize: { type: 'pct', num: ({ element }) => element === '水' ? 2 : 1.5, title: '蒸发' },
@ -32,16 +22,6 @@ lodash.forEach(erType, (er, key) => {
}) })
export const erTitle = erTmp export const erTitle = erTmp
export const attrMap = {
atk: { type: 'pct', val: 5.83, title: '大攻击', text: '5.8%' },
hp: { type: 'pct', val: 5.83, title: '大生命', text: '5.8%' },
def: { type: 'pct', val: 7.29, title: '大防御', text: '7.3%' },
recharge: { type: 'plus', val: 6.48, title: '元素充能', text: '6.5%' },
mastery: { type: 'plus', val: 23.31, title: '元素精通', text: '23.3' },
cpct: { type: 'plus', val: 3.89, title: '暴击率', text: '3.9%' },
cdmg: { type: 'plus', val: 7.77, title: '暴击伤害', text: '7.8%' }
}
// 各等级精通基础伤害 // 各等级精通基础伤害
export const eleBaseDmg = { export const eleBaseDmg = {
1: 4.291, 1: 4.291,

View File

@ -53,7 +53,7 @@ export const usefulAttr = {
: { hp: 0, atk: 75, def: 0, cpct: 100, cdmg: 100, mastery: 75, dmg: 100, phy: 0, recharge: 55, heal: 0 }, : { hp: 0, atk: 75, def: 0, cpct: 100, cdmg: 100, mastery: 75, dmg: 100, phy: 0, recharge: 55, heal: 0 },
赛诺: { hp: 0, atk: 75, def: 0, cpct: 100, cdmg: 100, mastery: 75, dmg: 100, phy: 0, recharge: 55, heal: 0 }, 赛诺: { hp: 0, atk: 75, def: 0, cpct: 100, cdmg: 100, mastery: 75, dmg: 100, phy: 0, recharge: 55, heal: 0 },
坎蒂丝: { hp: 75, atk: 75, def: 0, cpct: 100, cdmg: 100, mastery: 0, dmg: 100, phy: 0, recharge: 55, heal: 0 }, 坎蒂丝: { hp: 75, atk: 75, def: 0, cpct: 100, cdmg: 100, mastery: 0, dmg: 100, phy: 0, recharge: 55, heal: 0 },
妮露: { hp: 80, atk: 0, def: 0, cpct: 100, cdmg: 100, mastery: 75, dmg: 80, phy: 0, recharge: 30, heal: 0 }, 妮露: { hp: 100, atk: 0, def: 0, cpct: 100, cdmg: 100, mastery: 80, dmg: 100, phy: 0, recharge: 30, heal: 0 },
纳西妲: { hp: 0, atk: 55, def: 0, cpct: 100, cdmg: 100, mastery: 100, dmg: 100, phy: 0, recharge: 55, heal: 0 }, 纳西妲: { hp: 0, atk: 55, def: 0, cpct: 100, cdmg: 100, mastery: 100, dmg: 100, phy: 0, recharge: 55, heal: 0 },
多莉: { hp: 75, atk: 75, def: 0, cpct: 100, cdmg: 100, mastery: 0, dmg: 75, phy: 0, recharge: 55, heal: 100 }, 多莉: { hp: 75, atk: 75, def: 0, cpct: 100, cdmg: 100, mastery: 0, dmg: 75, phy: 0, recharge: 55, heal: 100 },
莱依拉: { hp: 100, atk: 75, def: 0, cpct: 100, cdmg: 100, mastery: 0, dmg: 100, phy: 0, recharge: 35 } 莱依拉: { hp: 100, atk: 75, def: 0, cpct: 100, cdmg: 100, mastery: 0, dmg: 100, phy: 0, recharge: 35 }

View File

@ -35,7 +35,9 @@ export const abbr = {
辰砂往生录: '辰砂', 辰砂往生录: '辰砂',
来歆余响: '余响', 来歆余响: '余响',
深林的记忆: '草套', 深林的记忆: '草套',
饰金之梦: '饰金' 饰金之梦: '饰金',
沙上楼阁史话: '沙套',
乐园遗落之花: '乐园'
} }
export const attrValue = { export const attrValue = {
@ -50,17 +52,21 @@ export const attrValue = {
phy: 7.288, phy: 7.288,
heal: 4.487 heal: 4.487
} }
/**
*
* @type {{phy: {format: string, text: string, title: string, type: string, value: number}, def: {valueMin: number, format: string, calc: string, text: string, title: string, type: string, value: number}, hp: {valueMin: number, format: string, calc: string, text: string, title: string, type: string, value: number}, atkPlus: {valueMin: number, format: string, title: string, type: string, value: number, base: string}, hpPlus: {valueMin: number, format: string, title: string, type: string, value: number, base: string}, mastery: {valueMin: number, format: string, calc: string, text: string, title: string, type: string, value: number}, cpct: {valueMin: number, format: string, calc: string, text: string, title: string, type: string, value: number}, defPlus: {valueMin: number, format: string, title: string, type: string, value: number, base: string}, cdmg: {valueMin: number, format: string, calc: string, text: string, title: string, type: string, value: number}, recharge: {valueMin: number, format: string, calc: string, text: string, title: string, type: string, value: number}, heal: {format: string, text: string, title: string, type: string, value: number}, atk: {valueMin: number, format: string, calc: string, text: string, title: string, type: string, value: number}, dmg: {format: string, text: string, title: string, type: string, value: number}}}
*/
export const attrMap = { export const attrMap = {
atk: { title: '大攻击', format: 'pct', type: 'normal', value: 5.83, text: '5.83%', valueMin: 4.08 }, atk: { title: '大攻击', format: 'pct', calc: 'pct', type: 'normal', value: 5.83, text: '5.83%', valueMin: 4.08 },
atkPlus: { title: '小攻击', format: 'comma', type: 'plus', base: 'atk', value: 19.45, valueMin: 13.62 }, atkPlus: { title: '小攻击', format: 'comma', type: 'plus', base: 'atk', value: 19.45, valueMin: 13.62 },
def: { title: '大防御', format: 'pct', type: 'normal', value: 7.29, text: '7.29%', valueMin: 5.1 }, def: { title: '大防御', format: 'pct', calc: 'pct', type: 'normal', value: 7.29, text: '7.29%', valueMin: 5.1 },
defPlus: { title: '小防御', format: 'comma', type: 'plus', base: 'def', value: 23.15, valueMin: 16.2 }, defPlus: { title: '小防御', format: 'comma', type: 'plus', base: 'def', value: 23.15, valueMin: 16.2 },
hp: { title: '大生命', format: 'pct', type: 'normal', value: 5.83, text: '5.83%', valueMin: 4.08 }, hp: { title: '大生命', format: 'pct', calc: 'pct', type: 'normal', value: 5.83, text: '5.83%', valueMin: 4.08 },
hpPlus: { title: '小生命', format: 'comma', type: 'plus', base: 'hp', value: 298.75, valueMin: 209.13 }, hpPlus: { title: '小生命', format: 'comma', type: 'plus', base: 'hp', value: 298.75, valueMin: 209.13 },
cpct: { title: '暴击率', format: 'pct', type: 'normal', value: 3.89, text: '3.89%', valueMin: 2.72 }, cpct: { title: '暴击率', format: 'pct', calc: 'plus', type: 'normal', value: 3.89, text: '3.89%', valueMin: 2.72 },
cdmg: { title: '暴击伤害', format: 'pct', type: 'normal', value: 7.77, text: '7.77%', valueMin: 5.44 }, cdmg: { title: '暴击伤害', format: 'pct', calc: 'plus', type: 'normal', value: 7.77, text: '7.77%', valueMin: 5.44 },
mastery: { title: '元素精通', format: 'comma', type: 'normal', value: 23.31, text: '23.31', valueMin: 16.32 }, mastery: { title: '元素精通', format: 'comma', calc: 'plus', type: 'normal', value: 23.31, text: '23.31', valueMin: 16.32 },
recharge: { title: '充能效率', format: 'pct', type: 'normal', value: 6.48, text: '6.48%', valueMin: 4.53 }, recharge: { title: '充能效率', format: 'pct', calc: 'plus', type: 'normal', value: 6.48, text: '6.48%', valueMin: 4.53 },
dmg: { title: '元素伤害', format: 'pct', type: 'normal', value: 5.825, text: '5.83%' }, dmg: { title: '元素伤害', format: 'pct', type: 'normal', value: 5.825, text: '5.83%' },
phy: { title: '物伤加成', format: 'pct', type: 'normal', value: 7.288, text: '7.29%' }, phy: { title: '物伤加成', format: 'pct', type: 'normal', value: 7.288, text: '7.29%' },
heal: { title: '治疗加成', format: 'pct', type: 'normal', value: 4.487, text: '4.49%' } heal: { title: '治疗加成', format: 'pct', type: 'normal', value: 4.487, text: '4.49%' }