From 876b39e561ff8ced1c3ccdfc05d9015cb4a7338f Mon Sep 17 00:00:00 2001 From: yoimiya-kokomi <592981798@qq.com> Date: Fri, 10 Jun 2022 04:53:38 +0800 Subject: [PATCH] =?UTF-8?q?`#=E8=A7=92=E8=89=B2=E9=9D=A2=E6=9D=BF`?= =?UTF-8?q?=E3=80=81`#=E5=9C=A3=E9=81=97=E7=89=A9=E5=88=97=E8=A1=A8`=20?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E6=96=B0=E7=9A=84=E5=9C=A3=E9=81=97=E7=89=A9?= =?UTF-8?q?=E8=AF=84=E5=88=86=E9=80=BB=E8=BE=91=E8=AE=A1=E7=AE=97=E8=AF=84?= =?UTF-8?q?=E5=88=86=20=20*=20=E6=96=B0=E7=9A=84=E5=9C=A3=E9=81=97?= =?UTF-8?q?=E7=89=A9=E8=AF=84=E5=88=86=E8=A7=84=E9=92=88=E5=AF=B9=E8=A7=92?= =?UTF-8?q?=E8=89=B2=E8=BF=9B=E8=A1=8C=E4=BA=86=E7=BB=86=E5=8C=96=EF=BC=8C?= =?UTF-8?q?=E5=90=8C=E6=97=B6=E5=B0=86=E5=BE=97=E5=88=86=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E4=BA=86=E6=8B=89=E9=BD=90=20=20*=20=E6=A0=B9=E6=8D=AE?= =?UTF-8?q?=E8=A7=92=E8=89=B2=E4=BD=BF=E7=94=A8=E4=B8=8D=E5=90=8C=E8=AF=8D?= =?UTF-8?q?=E6=9D=A1=E6=9D=83=E9=87=8D=E8=AE=A1=E7=AE=97=E3=80=82=E6=84=9F?= =?UTF-8?q?=E8=B0=A2@=E7=B3=96=E7=82=92=E6=A0=97=E5=AD=90=20@=E7=A7=8B?= =?UTF-8?q?=E5=A3=B0=20@49631073=20=E7=AD=89=E7=9A=84=E6=9D=83=E9=87=8D?= =?UTF-8?q?=E6=A2=B3=E7=90=86=20=20*=20=E4=BC=9A=E5=9C=A8=E5=90=8E?= =?UTF-8?q?=E7=BB=AD=E6=8F=90=E4=BE=9B=E5=8D=95=E7=8B=AC=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=EF=BC=8C=E4=BE=9B=E6=9F=A5=E7=9C=8B=E8=A7=92=E8=89=B2=E5=9C=A3?= =?UTF-8?q?=E9=81=97=E7=89=A9=E5=8F=8A=E8=AE=A1=E7=AE=97=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E4=B8=8E=E8=AE=A1=E7=AE=97=E9=80=BB=E8=BE=91=20=20*=20?= =?UTF-8?q?=E5=9B=A0=E4=B8=BA=E8=AE=A1=E5=88=86=E9=80=BB=E8=BE=91=E5=8F=98?= =?UTF-8?q?=E6=9B=B4=EF=BC=8C=E6=89=80=E4=BB=A5=E3=80=90=E5=88=86=E6=95=B0?= =?UTF-8?q?=E5=80=BC=E5=8F=8A=E6=A1=A3=E4=BD=8D=E3=80=91=E7=9B=B8=E8=BE=83?= =?UTF-8?q?=E4=BA=8E=E5=8D=87=E7=BA=A7=E4=B9=8B=E5=89=8D=E5=8F=AF=E8=83=BD?= =?UTF-8?q?=E6=9C=89=E6=89=80=E5=8F=98=E5=8C=96=E3=80=82=E5=A6=82=E6=9C=89?= =?UTF-8?q?=E4=B8=8D=E5=90=88=E7=90=86=E8=AE=A1=E7=AE=97=E8=AF=B7=E5=8F=8D?= =?UTF-8?q?=E9=A6=88=E7=BB=99=20@=E5=96=B5=E5=96=B5=20=20*=20=E5=A6=82?= =?UTF-8?q?=E9=9C=80=E4=B8=B4=E6=97=B6=E5=85=B3=E9=97=AD=E6=96=B0=E7=89=88?= =?UTF-8?q?=E8=AF=84=E5=88=86=EF=BC=8C=E5=8F=AF=E7=BC=96=E8=BE=91=E5=96=B5?= =?UTF-8?q?=E5=96=B5=20lib/app/character.js,=20const=20isNewScore=20=3D=20?= =?UTF-8?q?false;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 16 +- apps/character.js | 48 +++--- components/Profile.js | 2 +- components/models/Reliquaries2.js | 157 ++++++++++++++++++ resources/character/detail.css | 3 + resources/character/detail.html | 2 +- resources/character/detail.less | 3 + .../meta/reliquaries/reliquaries-mark-new.js | 101 +++++++++++ 8 files changed, 306 insertions(+), 26 deletions(-) create mode 100644 components/models/Reliquaries2.js create mode 100644 resources/meta/reliquaries/reliquaries-mark-new.js diff --git a/CHANGELOG.md b/CHANGELOG.md index f8b04c2a..f23f6ea3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,19 @@ -# 1.7.2 +# 1.7.3 -* 为`#面板更新`命令增加uid合法性校验 -* `#角色持有率`、`#深渊出场率` 页面细节样式调整 +* `#角色面板`、`#圣遗物列表` 使用新的圣遗物评分逻辑计算评分 + * 新的圣遗物评分规针对角色进行了细化,同时将得分进行了拉齐 + * 根据角色使用不同词条权重计算。感谢@糖炒栗子 @秋声 @49631073 等的权重梳理 + * 会在后续提供单独命令,供查看角色圣遗物及计算逻辑与计算逻辑 + * 因为计分逻辑变更,所以【分数值及档位】相较于升级之前可能有所变化。如有不合理计算请反馈给 @喵喵 + * 如需临时关闭新版评分,可编辑喵喵 lib/app/character.js, const isNewScore = false; -# 1.7.1 +# 1.7.1~1.7.2 -* `#更新面板` 功能fix +* `#更新面板` 功能升级及问题修正 * 修正武器类型、元素伤害字段导致的伤害计算问题 * 夜兰 请在游戏内不出场状况下获取面板属性 + * 为`#面板更新`命令增加uid合法性校验 +* `#角色持有率`、`#深渊出场率` 页面细节样式调整 # 1.7.0 diff --git a/apps/character.js b/apps/character.js index 55238ddd..e1aea5d6 100644 --- a/apps/character.js +++ b/apps/character.js @@ -5,8 +5,8 @@ import { Cfg } from "../components/index.js"; import Profile from "../components/Profile.js"; import Format from "../components/Format.js" import Reliquaries from "../components/models/Reliquaries.js"; +import Reliquaries2 from "../components/models/Reliquaries2.js"; import Calc from "../components/Calc.js"; -import fs from "fs"; import Common from "../components/Common.js"; @@ -15,6 +15,8 @@ let nameID = ""; let genshin = {}; await init(); +const isNewScore = true; + const relationMap = { wife: { keyword: "老婆,媳妇,妻子,娘子".split(","), @@ -495,7 +497,7 @@ async function autoRefresh(e) { e.reply("请确认角色已在【游戏内】橱窗展示并开放了查看详情。设置完毕后请5分钟后使用 #面板更新 重新获取") return false; } else { - e.reply(`本次获取成功角色: ${ret.join(", ")} `) + // e.reply(`本次获取成功角色: ${ret.join(", ")} `) return true; } } @@ -505,7 +507,6 @@ async function autoRefresh(e) { export async function getProfile(e, mode = "refresh") { let uid = await getTargetUid(e); - console.log('uid', uid) if (!uid) { return true; } @@ -742,28 +743,35 @@ export async function renderProfile(e, char, render, mode = "profile", params = dmgBonus: p(Math.max(a.dmgBonus * 1 || 0, a.phyBonus * 1 || 0)) }; - /* - let avatar = await getAvatar(e, char, MysApi); - let talent = await getTalent(e, avatar); -*/ - let reliquaries = [], totalMark = 0, totalMaxMark = 0; - let { titles: usefulTitles, mark: usefulMark } = Reliquaries.getUseful(char.name); + let newScore = Reliquaries2.getArtisMark(char.name, profile.artis); - lodash.forEach(profile.artis, (arti) => { + lodash.forEach(profile.artis, (arti, idx) => { + idx = idx.replace("arti", ""); let ds = arti; - let mark = Reliquaries.getMark(char.name, arti.attrs); + let mark = isNewScore ? newScore[idx] : Reliquaries.getMark(char.name, arti.attrs); let maxMark = Reliquaries.getMaxMark(char.name, arti.main[0] || ""); totalMark += mark; totalMaxMark += maxMark; ds.mark = c(mark, 1); - ds.markType = Reliquaries.getMarkScore(mark, maxMark); + ds.markType = isNewScore ? Reliquaries2.getMarkScore(mark) : Reliquaries.getMarkScore(mark, maxMark); ds.main = Profile.formatArti(arti.main); ds.attrs = Profile.formatArti(arti.attrs); reliquaries.push(ds); }); + let markScore, usefulMark; + if (isNewScore) { + let charCfg = Reliquaries2.getCharCfg(char.name); + usefulMark = charCfg.titleWeight; + markScore = Reliquaries2.getMarkScore(totalMark / 5); + } else { + let usefulData = Reliquaries.getUseful(char.name); + usefulMark = usefulData.mark; + markScore = Reliquaries.getMarkScore(totalMark, totalMaxMark); + } + let enemyLv = await selfUser.getCfg(`char.enemyLv`, 91); let dmgMsg = [], dmgData = []; @@ -816,9 +824,7 @@ export async function renderProfile(e, char, render, mode = "profile", params = enemyLv, enemyName: dmgCalc.enemyName || "小宝", totalMark: c(totalMark, 1), - totalMaxMark, - markScore: Reliquaries.getMarkScore(totalMark, totalMaxMark), - usefulTitles, + markScore, usefulMark, talentMap: { a: "普攻", e: "战技", q: "爆发" }, bodyClass: `char-${char.name}`, @@ -876,21 +882,25 @@ export async function getArtis(e, { render }) { lodash.forEach(profiles || [], (ds) => { let name = ds.name; - if (!name) { + if (!name || name === "空" || name === "荧") { return; } let { mark: usefulMark } = Reliquaries.getUseful(name); + /* 处理圣遗物 */ if (ds.artis) { - lodash.forEach(ds.artis, (arti) => { + let newScore = Reliquaries2.getArtisMark(name, ds.artis); + + lodash.forEach(ds.artis, (arti, idx) => { if (!arti.name) { return; } - let mark = Reliquaries.getMark(name, arti.attrs); + idx = idx.replace("arti", ""); + let mark = isNewScore ? newScore[idx] : Reliquaries.getMark(name, arti.attrs); let maxMark = Reliquaries.getMaxMark(name, arti.main[0] || ""); arti.mark = Format.comma(mark, 1); arti._mark = mark; - arti.markType = Reliquaries.getMarkScore(mark, maxMark); + arti.markType = isNewScore ? Reliquaries2.getMarkScore(mark) : Reliquaries.getMarkScore(mark, maxMark); arti.main = Profile.formatArti(arti.main); arti.attrs = Profile.formatArti(arti.attrs); arti.usefulMark = usefulMark; diff --git a/components/Profile.js b/components/Profile.js index 45e3696c..c1fa1a70 100644 --- a/components/Profile.js +++ b/components/Profile.js @@ -42,7 +42,7 @@ let Profile = { e.reply("请求过快,请稍后重试.."); return false; } else if (inCd === 'pending') { - e.reply("#ref距上次请求刷新成功间隔小于5分钟,请稍后重试.."); + e.reply("距上次请求刷新成功间隔小于5分钟,请稍后重试.."); return false; } await redis.set(`miao:role-all:${uid}`, 'loading', { EX: 20 }); diff --git a/components/models/Reliquaries2.js b/components/models/Reliquaries2.js new file mode 100644 index 00000000..1c87cd4b --- /dev/null +++ b/components/models/Reliquaries2.js @@ -0,0 +1,157 @@ +import { + attrValue, + attrNameMap, + attrMap, + mainAttr, + subAttr, + usefulAttr +} from "../../resources/meta/reliquaries/reliquaries-mark-new.js"; +import { Character } from "../models.js"; +import lodash from "lodash"; + +let charCfg = {}; +let Reliquaries = { + getCharCfg(name) { + if (charCfg[name]) { + return charCfg[name] + } + let attrWeight = usefulAttr[name] || { atk: 75, cp: 100, cd: 100 }; + let attrMark = {}; + + let char = Character.get(name); + let baseAttr = char.lvStat.detail['90']; + lodash.forEach(attrWeight, (weight, attr) => { + attrMark[attr] = weight / attrValue[attr]; + }); + + // let baseAttr = [400, 500, 300]; + if (attrMark.hp) { + attrMark.hpPlus = attrMark.hp / baseAttr[0] * 100; + } + if (attrMark.atk) { + attrMark.atkPlus = attrMark.atk / (baseAttr[1] + 400) * 100; + } + if (attrMark.def) { + attrMark.defPlus = attrMark.def / baseAttr[2] * 100; + } + let maxMark = Reliquaries.getMaxMark(attrWeight); + let titleMark = {}, titleWeight = {}; + lodash.forEach(attrMark, (mark, attr) => { + titleMark[attrMap[attr]] = mark; + titleWeight[attrMap[attr]] = attrWeight[attr] || 0; + if (/大/.test(attrMap[attr])) { + let newAttr = attrMap[attr]; + let newArr = newAttr.replace("大", "小"); + titleWeight[newArr] = attrWeight[attr] || 0; + } + }) + charCfg[name] = { + weight: attrWeight, + mark: attrMark, + titleMap: titleMark, + titleWeight, + maxMark + }; + return charCfg[name]; + }, + getMaxAttr(charAttr = {}, list2 = [], maxLen = 1, banAttr = "") { + let tmp = []; + lodash.forEach(list2, (attr) => { + if (attr === banAttr) return; + if (!charAttr[attr]) return; + tmp.push({ attr, mark: charAttr[attr] }); + }); + tmp = lodash.sortBy(tmp, "mark"); + tmp = tmp.reverse(); + let ret = []; + lodash.forEach(tmp, (ds) => ret.push(ds.attr)); + return ret.slice(0, maxLen); + }, + getMaxMark(attrWeight) { + let ret = {}; + for (let idx = 1; idx <= 5; idx++) { + let totalMark = 0, mMark = 0; + let mAttr = ""; + if (idx === 1) { + mAttr = "hpPlus"; + } else if (idx === 2) { + mAttr = "atkPlus"; + } else if (idx >= 3) { + mAttr = Reliquaries.getMaxAttr(attrWeight, mainAttr[idx])[0]; + mMark = attrWeight[mAttr]; + totalMark += attrWeight[mAttr] * 2; + } + + let sAttr = Reliquaries.getMaxAttr(attrWeight, subAttr, 4, mAttr); + lodash.forEach(sAttr, (attr, aIdx) => { + totalMark += attrWeight[attr] * (aIdx === 0 ? 6 : 1) + }); + ret[idx] = totalMark; + ret['m' + idx] = mMark; + } + return ret; + }, + getAttr(ds) { + let title = ds[0] + let attr = attrNameMap[title]; + if (/元素伤害/.test(title)) { + attr = "dmg"; + } else if (/物理|物伤/.test(title)) { + attr = "phy" + } + return attr; + }, + getAttrMark(attrMark, ds) { + if (!ds || !ds[1]) { + return 0; + } + let attr = Reliquaries.getAttr(ds); + let val = ds[1]; + return (attrMark[attr] || 0) * val; + }, + getMark(charCfg, posIdx, mainAttr, subAttr) { + let ret = 0; + let { mark, maxMark, weight } = charCfg; + let mAttr = Reliquaries.getAttr(mainAttr); + + let fixPct = 1; + if (posIdx >= 3) { + fixPct = Math.max(0, Math.min(1, (weight[mAttr] || 0) / (maxMark['m' + posIdx]))); + ret += Reliquaries.getAttrMark(mark, mainAttr) / 4 + } + + lodash.forEach(subAttr, (ds) => { + ret += Reliquaries.getAttrMark(mark, ds) + }); + + return ret * (1 + fixPct) / 2 / maxMark[posIdx] * 66; + }, + + getArtisMark(charName = "", artis = {}) { + let total = 0; + let charCfg = Reliquaries.getCharCfg(charName); + let ret = {} + lodash.forEach(artis, (ds, idx) => { + idx = idx.replace("arti", ""); + ret[idx] = Reliquaries.getMark(charCfg, idx, ds.main, ds.attrs) + }); + return ret; + }, + getMarkScore(mark) { + let pct = mark; + let scoreMap = [["D", 10], ["C", 16.5], ["B", 23.1], ["A", 29.7], ["S", 36.3], ["SS", 42.9], ["SSS", 50], ["ACE", 56.1], ["ACE²", 66]]; + for (let idx = 0; idx < scoreMap.length; idx++) { + if (pct < scoreMap[idx][1]) { + return scoreMap[idx][0]; + } + } + }, + getSet(name) { + for (let idx in meta) { + if (meta[idx].name === name) { + return meta[idx]; + } + } + } +} +export default Reliquaries; diff --git a/resources/character/detail.css b/resources/character/detail.css index 6c7ed27c..21562e3d 100644 --- a/resources/character/detail.css +++ b/resources/character/detail.css @@ -488,6 +488,9 @@ body { line-height: 26px; height: 26px; } +.artis ul.detail li.great span.title { + color: #ffe699; +} .artis ul.detail li.nouse span { color: #888; } diff --git a/resources/character/detail.html b/resources/character/detail.html index 5c4389a9..9270e5aa 100644 --- a/resources/character/detail.html +++ b/resources/character/detail.html @@ -84,7 +84,7 @@
  • {{ds.main[0]}}+{{ds.main[1]}}
  • {{each ds.attrs attr}} {{if attr[0]}} -
  • {{attr[0]}}{{attr[0]}} +{{attr[1]}}
  • {{/if}} {{/each}} diff --git a/resources/character/detail.less b/resources/character/detail.less index f2bab51a..edb88385 100644 --- a/resources/character/detail.less +++ b/resources/character/detail.less @@ -601,6 +601,9 @@ body { height: 26px; } +.artis ul.detail li.great span.title { + color: #ffe699; +} .artis ul.detail li.nouse span { color: #888; diff --git a/resources/meta/reliquaries/reliquaries-mark-new.js b/resources/meta/reliquaries/reliquaries-mark-new.js new file mode 100644 index 00000000..688527cb --- /dev/null +++ b/resources/meta/reliquaries/reliquaries-mark-new.js @@ -0,0 +1,101 @@ +export const attrValue = { + cp: 3.89, + cd: 7.77, + mastery: 23.31, + atk: 5.83, + hp: 5.83, + def: 7.29, + recharge: 6.48, + dmg: 5.825, + phy: 7.288, + heal: 4.487 +}; +export const attrMap = { + atk: "大攻击", + atkPlus: "小攻击", + def: "大防御", + defPlus: "小防御", + hp: "大生命", + hpPlus: "小生命", + cp: "暴击率", + cd: "暴击伤害", + mastery: "元素精通", + recharge: "充能效率", + dmg: "元素伤害", + phy: "物伤加成", + heal: "治疗加成", +}; +let anMap = {}; +for (let attr in attrMap) { + anMap[attrMap[attr]] = attr; +} + +export const attrNameMap = anMap; +/* 当前位置主词条不可能出现词缀*/ +export const banAttr = { + 1: "hpPlus,dmg,phy,heal".split(","), + 2: "atkPlus,dmg,phy,heal".split(","), + 3: "dmg,phy,heal".split(","), + 4: "heal".split(","), + 5: "dmg,phy".split(",") +}; + +export const mainAttr = { + 3: "atk,def,hp,mastery,recharge".split(","), + 4: "atk,def,hp,mastery,dmg,phy".split(","), + 5: "atk,def,hp,mastery,recharge,heal,cp,cd".split(",") +}; + +export const subAttr = "atk,def,hp,mastery,recharge,cp,cd".split(",") + +export const usefulAttr = { + '神里绫人': { hp: 40, atk: 75, def: 0, cp: 100, cd: 100, mastery: 25, dmg: 100, phy: 0, recharge: 20, heal: 0 }, + '八重神子': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 50, dmg: 100, phy: 0, recharge: 50, heal: 0 }, + '申鹤': { hp: 0, atk: 100, def: 0, cp: 75, cd: 75, mastery: 0, dmg: 100, phy: 0, recharge: 70, heal: 0 }, + '云堇': { hp: 0, atk: 25, def: 100, cp: 50, cd: 50, mastery: 0, dmg: 25, phy: 0, recharge: 90, heal: 0 }, + '荒泷一斗': { hp: 0, atk: 50, def: 90, cp: 100, cd: 100, mastery: 0, dmg: 100, phy: 0, recharge: 30, heal: 0 }, + '五郎': { hp: 0, atk: 50, def: 100, cp: 50, cd: 50, mastery: 0, dmg: 25, phy: 0, recharge: 90, heal: 0 }, + '班尼特': { hp: 90, atk: 30, def: 0, cp: 50, cd: 50, mastery: 0, dmg: 70, phy: 0, recharge: 80, heal: 100 }, + '枫原万叶': { hp: 0, atk: 60, def: 0, cp: 100, cd: 100, mastery: 100, dmg: 100, phy: 0, recharge: 55, heal: 0 }, + '雷电将军': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 20, dmg: 75, phy: 0, recharge: 90, heal: 0 }, + '行秋': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 20, dmg: 100, phy: 0, recharge: 65, heal: 0 }, + '钟离': { hp: 80, atk: 70, def: 0, cp: 100, cd: 100, mastery: 0, dmg: 100, phy: 50, recharge: 55, heal: 0 }, + '神里绫华': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 30, dmg: 100, phy: 0, recharge: 20, heal: 0 }, + '香菱': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 75, dmg: 100, phy: 0, recharge: 75, heal: 0 }, + '胡桃': { hp: 80, atk: 30, def: 0, cp: 100, cd: 100, mastery: 75, dmg: 100, phy: 0, recharge: 35, heal: 0 }, + '甘雨': { hp: 0, atk: 90, def: 0, cp: 100, cd: 100, mastery: 50, dmg: 100, phy: 0, recharge: 40, heal: 0 }, + '温迪': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 60, dmg: 100, phy: 0, recharge: 80, heal: 0 }, + '珊瑚宫心海': { hp: 100, atk: 50, def: 0, cp: 0, cd: 0, mastery: 0, dmg: 100, phy: 0, recharge: 65, heal: 100 }, + '莫娜': { hp: 0, atk: 50, def: 0, cp: 100, cd: 100, mastery: 75, dmg: 100, phy: 0, recharge: 80, heal: 0 }, + '阿贝多': { hp: 0, atk: 30, def: 80, cp: 100, cd: 100, mastery: 0, dmg: 100, phy: 0, recharge: 35, heal: 0 }, + '迪奥娜': { hp: 85, atk: 50, def: 0, cp: 75, cd: 75, mastery: 0, dmg: 65, phy: 0, recharge: 55, heal: 100 }, + '优菈': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 0, dmg: 40, phy: 100, recharge: 45, heal: 0 }, + '达达利亚': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 50, dmg: 100, phy: 0, recharge: 45, heal: 0 }, + '魈': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 0, dmg: 100, phy: 0, recharge: 20, heal: 0 }, + '宵宫': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 75, dmg: 100, phy: 0, recharge: 0, heal: 0 }, + '九条裟罗': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 0, dmg: 100, phy: 0, recharge: 55, heal: 0 }, + '琴': { hp: 0, atk: 90, def: 0, cp: 100, cd: 100, mastery: 0, dmg: 100, phy: 100, recharge: 55, heal: 100 }, + '菲谢尔': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 30, dmg: 100, phy: 60, recharge: 30, heal: 0 }, + '罗莎莉亚': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 0, dmg: 70, phy: 80, recharge: 40, heal: 0 }, + '可莉': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 20, dmg: 100, phy: 0, recharge: 40, heal: 0 }, + '凝光': { hp: 0, atk: 80, def: 0, cp: 100, cd: 100, mastery: 0, dmg: 100, phy: 0, recharge: 40, heal: 0 }, + '北斗': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 30, dmg: 100, phy: 0, recharge: 50, heal: 0 }, + '刻晴': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 15, dmg: 100, phy: 100, recharge: 30, heal: 0 }, + '托马': { hp: 75, atk: 50, def: 0, cp: 50, cd: 50, mastery: 0, dmg: 75, phy: 0, recharge: 55, heal: 40 }, + '迪卢克': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 50, dmg: 100, phy: 0, recharge: 40, heal: 0 }, + '芭芭拉': { hp: 80, atk: 50, def: 0, cp: 50, cd: 50, mastery: 15, dmg: 80, phy: 0, recharge: 55, heal: 100 }, + '诺艾尔': { hp: 0, atk: 75, def: 100, cp: 100, cd: 100, mastery: 0, dmg: 100, phy: 0, recharge: 70, heal: 0 }, + '旅行者': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 0, dmg: 100, phy: 0, recharge: 55, heal: 0 }, + '重云': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 0, dmg: 100, phy: 0, recharge: 70, heal: 0 }, + '七七': { hp: 0, atk: 100, def: 0, cp: 75, cd: 75, mastery: 0, dmg: 60, phy: 70, recharge: 25, heal: 100 }, + '凯亚': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 0, dmg: 100, phy: 100, recharge: 40, heal: 10 }, + '烟绯': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 40, dmg: 100, phy: 0, recharge: 40, heal: 0 }, + '早柚': { hp: 0, atk: 60, def: 0, cp: 70, cd: 70, mastery: 100, dmg: 80, phy: 0, recharge: 70, heal: 100 }, + '安柏': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 75, dmg: 100, phy: 100, recharge: 35, heal: 0 }, + '丽莎': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 40, dmg: 100, phy: 0, recharge: 45, heal: 0 }, + '埃洛伊': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 0, dmg: 100, phy: 0, recharge: 30, heal: 0 }, + '辛焱': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 0, dmg: 50, phy: 100, recharge: 30, heal: 0 }, + '砂糖': { hp: 0, atk: 60, def: 0, cp: 70, cd: 70, mastery: 100, dmg: 40, phy: 0, recharge: 70, heal: 0 }, + '雷泽': { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 0, dmg: 50, phy: 100, recharge: 35, heal: 0 }, + '夜兰': { hp: 80, atk: 0, def: 0, cp: 100, cd: 100, mastery: 25, dmg: 100, phy: 0, recharge: 75, heal: 0 }, +};