圣遗物数据底层存储格式与处理逻辑初步升级

This commit is contained in:
Kokomi 2022-11-24 04:26:07 +08:00
parent 9ecc6e5b31
commit c91741690e
26 changed files with 298 additions and 277 deletions

View File

@ -1,12 +1,14 @@
# 2.1.0 # 2.1.1
* 底层增加面板计算逻辑,供后续功能使用 * 部分底层结构升级
* 底层增加面板计算逻辑,供后续功能使用
* 圣遗物数据底层存储格式与处理逻辑初步升级
* 圣遗物主词条评分规则微调,可能会影响部分角色评分 * 圣遗物主词条评分规则微调,可能会影响部分角色评分
* 元素杯属性不符会触发主词缀评分惩罚 * 元素杯属性不符会触发主词缀评分惩罚
* 充能主词条不再触发主词缀评分惩罚 * 充能主词条不再触发主词缀评分惩罚
* 一些已知问题修正与优化 * 一些已知问题修正与样式优化
# 2.0.1~2.0.9 # 2.1.0
* 增加群内排名功能 * 增加群内排名功能
* 默认关闭,如需启用可通过`#喵喵设置排名开启`进行打开 * 默认关闭,如需启用可通过`#喵喵设置排名开启`进行打开

View File

@ -5,7 +5,7 @@
import lodash from 'lodash' import lodash from 'lodash'
import { Profile, Common } from '../../components/index.js' import { Profile, Common } from '../../components/index.js'
import { getTargetUid, profileHelp, autoGetProfile } from './ProfileCommon.js' import { getTargetUid, profileHelp, autoGetProfile } from './ProfileCommon.js'
import { Artifact, Character } from '../../models/index.js' import { Artifact, Character, ProfileArtis } from '../../models/index.js'
/* /*
* 角色圣遗物面板 * 角色圣遗物面板
@ -27,10 +27,12 @@ export async function profileArtis (e) {
} }
let charCfg = profile.artis.getCharCfg() let charCfg = profile.artis.getCharCfg()
let { artis, mark: totalMark, markClass: totalMarkClass, usefulMark } = profile.getArtisMark()
let { attrMap } = Artifact.getMeta() let { attrMap } = Artifact.getMeta()
let artisDetail = profile.getArtisMark()
let artisKeyTitle = ProfileArtis.getArtisKeyTitle()
// 渲染图像 // 渲染图像
return await Common.render('character/artis-mark', { return await Common.render('character/artis-mark', {
uid, uid,
@ -38,10 +40,9 @@ export async function profileArtis (e) {
splash: char.getImgs(profile.costume).splash, splash: char.getImgs(profile.costume).splash,
data: profile, data: profile,
costume: profile.costume ? '2' : '', costume: profile.costume ? '2' : '',
artis, artisDetail,
totalMark, artisKeyTitle,
totalMarkClass,
usefulMark,
attrMap, attrMap,
charCfg charCfg
}, { e, scale: 1.3 }) }, { e, scale: 1.3 })
@ -72,7 +73,7 @@ export async function profileArtisList (e) {
} }
let profileArtis = profile.getArtisMark() let profileArtis = profile.getArtisMark()
lodash.forEach(profileArtis.artis, (arti, idx) => { lodash.forEach(profileArtis.artis, (arti, idx) => {
arti.usefulMark = profileArtis.usefulMark arti.charWeight = profileArtis.charWeight
arti.avatar = name arti.avatar = name
arti.side = char.side arti.side = char.side
artis.push(arti) artis.push(arti)
@ -87,11 +88,13 @@ export async function profileArtisList (e) {
artis = lodash.sortBy(artis, '_mark') artis = lodash.sortBy(artis, '_mark')
artis = artis.reverse() artis = artis.reverse()
artis = artis.slice(0, 28) artis = artis.slice(0, 28)
let artisKeyTitle = ProfileArtis.getArtisKeyTitle()
// 渲染图像 // 渲染图像
return await Common.render('character/artis-list', { return await Common.render('character/artis-list', {
save_id: uid, save_id: uid,
uid, uid,
artis artis,
artisKeyTitle
}, { e, scale: 1.4 }) }, { e, scale: 1.4 })
} }

View File

@ -1,7 +1,7 @@
import lodash from 'lodash' import lodash from 'lodash'
import { autoRefresh } from './ProfileCommon.js' import { autoRefresh } from './ProfileCommon.js'
import { Common, Format, Profile } from '../../components/index.js' import { Common, Format, Profile } from '../../components/index.js'
import { MysApi, Avatar, ProfileRank } from '../../models/index.js' import { MysApi, Avatar, ProfileRank, ProfileArtis } from '../../models/index.js'
export async function renderProfile (e, char, mode = 'profile', params = {}) { export async function renderProfile (e, char, mode = 'profile', params = {}) {
let selfUser = await MysApi.initUser(e) let selfUser = await MysApi.initUser(e)
@ -55,7 +55,6 @@ export async function renderProfile (e, char, mode = 'profile', params = {}) {
dmg: p(Math.max(a.dmg * 1 || 0, a.phy * 1 || 0)) dmg: p(Math.max(a.dmg * 1 || 0, a.phy * 1 || 0))
} }
let { artis, mark: totalMark, markClass: totalMarkClass, usefulMark, classTitle } = profile.getArtisMark()
let enemyLv = await selfUser.getCfg('char.enemyLv', 91) let enemyLv = await selfUser.getCfg('char.enemyLv', 91)
let dmgMsg = [] let dmgMsg = []
@ -94,6 +93,10 @@ export async function renderProfile (e, char, mode = 'profile', params = {}) {
rank = await ProfileRank.create({ group: e.group_id, uid, qq: e.user_id }) rank = await ProfileRank.create({ group: e.group_id, uid, qq: e.user_id })
await rank.getRank(profile, true) await rank.getRank(profile, true)
} }
let artisDetail = profile.getArtisMark()
let artisKeyTitle = ProfileArtis.getArtisKeyTitle()
// 渲染图像 // 渲染图像
return await Common.render('character/profile-detail', { return await Common.render('character/profile-detail', {
save_id: uid, save_id: uid,
@ -105,14 +108,11 @@ export async function renderProfile (e, char, mode = 'profile', params = {}) {
dmgMsg, dmgMsg,
dmgRet: dmgCalc.dmgRet || false, dmgRet: dmgCalc.dmgRet || false,
dmgCfg: dmgCalc.dmgCfg || false, dmgCfg: dmgCalc.dmgCfg || false,
artis, artisDetail,
artisKeyTitle,
enemyLv, enemyLv,
imgs: char.getImgs(profile.costume), imgs: char.getImgs(profile.costume),
enemyName: dmgCalc.enemyName || '小宝', enemyName: dmgCalc.enemyName || '小宝',
totalMark: c(totalMark, 1),
totalMarkClass,
classTitle,
usefulMark,
talentMap: { a: '普攻', e: '战技', q: '爆发' }, talentMap: { a: '普攻', e: '战技', q: '爆发' },
bodyClass: `char-${char.name}`, bodyClass: `char-${char.name}`,
mode mode

View File

@ -5,7 +5,7 @@
import lodash from 'lodash' import lodash from 'lodash'
import { Cfg, Common, App, Data } from '../components/index.js' import { Cfg, Common, App, Data } from '../components/index.js'
import { Abyss, AvatarList, Character, MysApi } from '../models/index.js' import { Abyss, AvatarList, Character, MysApi } from '../models/index.js'
import HutaoApi from './stat/HutaoApi.js' import HutaoApi from './wiki/HutaoApi.js'
let app = App.init({ let app = App.init({
id: 'stat', id: 'stat',

View File

@ -110,11 +110,7 @@ async function renderWiki ({ e, char }) {
lodash.extend(data, char.getData('weaponType,elemName')) lodash.extend(data, char.getData('weaponType,elemName'))
// 命座持有 // 命座持有
let holding = await CharWiki.getHolding(char.id) let holding = await CharWiki.getHolding(char.id)
// let usage = await CharWiki.getUsage(char.id) let usage = await CharWiki.getUsage(char.id)
let usage = {
weapons: await CharWiki.getWeapons(char.id),
artis: await CharWiki.getArtis(char.id)
}
return await Common.render('wiki/character-wiki', { return await Common.render('wiki/character-wiki', {
data, data,
attr: char.getAttrList(), attr: char.getAttrList(),

View File

@ -1,10 +1,14 @@
import HutaoApi from '../stat/HutaoApi.js'; import HutaoApi from './HutaoApi.js'
import lodash from 'lodash'; import lodash from 'lodash'
import { Format } from '../../components/index.js'; import { Format } from '../../components/index.js'
import { ArtifactSet, Weapon } from '../../models/index.js'; import { ArtifactSet, Weapon } from '../../models/index.js'
let CharWiki = { let CharWiki = {
// 命座持有 /**
* 角色命座持有
* @param id
* @returns {Promise<{}>}
*/
async getHolding (id) { async getHolding (id) {
let consData = (await HutaoApi.getCons()).data || {} let consData = (await HutaoApi.getCons()).data || {}
consData = lodash.find(consData, (ds) => ds.avatar === id) consData = lodash.find(consData, (ds) => ds.avatar === id)
@ -23,58 +27,12 @@ let CharWiki = {
} }
return holding return holding
}, },
async getWeapons (id) {
let wu = (await HutaoApi.getWeaponUsage()).data || {}
let weapons = []
if (wu[id]) {
lodash.forEach(wu[id], (ds) => {
let weapon = Weapon.get(ds.name)
if (weapon) {
weapons.push({
...weapon.getData('name,abbr,img,star'),
value: ds.value
})
}
})
}
weapons = lodash.sortBy(weapons, 'value')
weapons = weapons.reverse()
lodash.forEach(weapons, (ds) => {
ds.value = Format.percent(ds.value, 1)
})
return weapons
},
async getArtis (id) {
let au = (await HutaoApi.getArtisUsage()).data || {}
let artis = []
if (au[id]) {
lodash.forEach(au[id], (ds) => {
let imgs = []
let abbrs = []
let ss = ds.sets.split(',')
lodash.forEach(ss, (t) => {
t = t.split(':')
let artiSet = ArtifactSet.get(t[0])
if (artiSet) {
imgs.push(artiSet.img)
abbrs.push(artiSet.abbr + (ss.length === 1 ? t[1] : ''))
}
})
artis.push({ /**
imgs, * 角色武器圣遗物使用
title: abbrs.join('+'), * @param id
value: ds.value * @returns {Promise<{}|{artis: *[], weapons: *[]}>}
}) */
})
}
artis = lodash.sortBy(artis, 'value')
artis = artis.reverse()
artis.forEach((ds) => {
ds.value = Format.percent(ds.value)
})
return artis
},
async getUsage (id) { async getUsage (id) {
let ud = (await HutaoApi.getUsage()).data || {} let ud = (await HutaoApi.getUsage()).data || {}
if (!ud[id]) { if (!ud[id]) {
@ -86,6 +44,12 @@ let CharWiki = {
artis: CharWiki.getArtisData(ud.artis) artis: CharWiki.getArtisData(ud.artis)
} }
}, },
/**
* 武器使用
* @param data
* @returns {*[]}
*/
getWeaponsData (data = []) { getWeaponsData (data = []) {
let weapons = [] let weapons = []
@ -104,6 +68,12 @@ let CharWiki = {
}) })
return weapons return weapons
}, },
/**
* 圣遗物使用
* @param data
* @returns {*[]}
*/
getArtisData (data = []) { getArtisData (data = []) {
let artis = [] let artis = []

View File

@ -57,14 +57,6 @@ let HutaoApi = {
return await HutaoApi.req('/Statistics/Avatar/AvatarCollocation') return await HutaoApi.req('/Statistics/Avatar/AvatarCollocation')
}, },
async getWeaponUsage () {
return await HutaoApi.req('/Statistics/AvatarWeaponUsage')
},
async getArtisUsage () {
return await HutaoApi.req('/Statistics/AvatarReliquaryUsage')
},
async uploadData (data = {}) { async uploadData (data = {}) {
let body = JSON.stringify(data) let body = JSON.stringify(data)
return await HutaoApi.req('/Record/UploadData', { return await HutaoApi.req('/Record/UploadData', {

View File

@ -1,4 +1,7 @@
import lodash from 'lodash' import lodash from 'lodash'
import { Character } from '../models/index.js'
let CharId = Character.CharId
let Format = { let Format = {
int: function (d) { int: function (d) {
@ -15,7 +18,25 @@ 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

@ -152,11 +152,14 @@ let MiaoData = {
let tid = talentId[ds.id] let tid = talentId[ds.id]
key = talentKey[tid] key = talentKey[tid]
elem = elem || talentElem[tid] elem = elem || talentElem[tid]
ret[key] = {
level: ds.level
}
} else { } else {
key = ['a', 'e', 'q'][idx++] key = ['a', 'e', 'q'][idx++]
} ret[key] = ret[key] || {
ret[key] = { level: ds.level
level: ds.level }
} }
}) })

View File

@ -11,6 +11,7 @@ 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'
import CharMeta from './character-lib/CharMeta.js' import CharMeta from './character-lib/CharMeta.js'
import CharCfg from './character-lib/CharCfg.js'
let { abbrMap, wifeMap, idSort, idMap } = CharId let { abbrMap, wifeMap, idSort, idMap } = CharId
@ -112,10 +113,12 @@ class Character extends Base {
return this.getImgs().side return this.getImgs().side
} }
// gacha图像
get gacha () { get gacha () {
return this.getImgs().gacha return this.getImgs().gacha
} }
// 获取character相关图像
get imgs () { get imgs () {
return this.getImgs() return this.getImgs()
} }
@ -125,6 +128,7 @@ class Character extends Base {
return this.getDetail() return this.getDetail()
} }
// 获取命座天赋等级
get talentCons () { get talentCons () {
if (this.isTraveler) { if (this.isTraveler) {
return this.elem === 'dendro' ? { e: 3, q: 5 } : { e: 5, q: 3 } return this.elem === 'dendro' ? { e: 3, q: 5 } : { e: 5, q: 3 }
@ -132,19 +136,17 @@ class Character extends Base {
return this.meta?.talentCons || {} return this.meta?.talentCons || {}
} }
// 获取attr列表
getAttrList () { getAttrList () {
let { meta } = this let { meta } = this
return CharMeta.getAttrList(meta.baseAttr, meta.growAttr, this.elemName) return CharMeta.getAttrList(meta.baseAttr, meta.growAttr, this.elemName)
} }
// 获取素材
getMaterials (type = 'all') { getMaterials (type = 'all') {
return CharMeta.getMaterials(this, type) return CharMeta.getMaterials(this, type)
} }
getLvStat () {
return CharMeta.getLvStat(this)
}
// 获取生日 // 获取生日
get birthday () { get birthday () {
let birth = this.birth let birth = this.birth
@ -167,15 +169,18 @@ class Character extends Base {
return CharTalent.getAvatarTalent(this.id, talent, cons, mode, this.talentCons) return CharTalent.getAvatarTalent(this.id, talent, cons, mode, this.talentCons)
} }
// 检查老婆类型
checkWifeType (type) { checkWifeType (type) {
return !!wifeMap[type][this.id] return !!wifeMap[type][this.id]
} }
// 检查时装
checkCostume (id) { checkCostume (id) {
let costume = this.meta?.costume || [] let costume = this.meta?.costume || []
return costume.includes(id * 1) return costume.includes(id * 1)
} }
// 判断是否为某种元素角色
isElem (elem = '') { isElem (elem = '') {
elem = elem.toLowerCase() elem = elem.toLowerCase()
return this.elem === elem || this.elemName === elem return this.elem === elem || this.elemName === elem
@ -310,22 +315,10 @@ class Character extends Base {
return arr.sort((a, b) => (idSort[a] || 300) - (idSort[b] || 300)) return arr.sort((a, b) => (idSort[a] || 300) - (idSort[b] || 300))
} }
// 获取伤害计算配置
async getCalcRule () { async getCalcRule () {
if (!this._calcRule && this._calcRule !== false) { if (!this._calcRule && this._calcRule !== false) {
let cfg = await Data.importModule(`resources/meta/character/${this.name}/calc.js`) this._calcRule = await CharCfg.getCalcRule(this)
if (lodash.isEmpty(cfg)) {
this._calcRule = false
} else {
this._calcRule = {
details: cfg.details || false, // 计算详情
buffs: cfg.buffs || [], // 角色buff
defParams: cfg.defParams || {}, // 默认参数,一般为空
defDmgIdx: cfg.defDmgIdx || -1, // 默认详情index
defDmgKey: cfg.defDmgKey || '',
mainAttr: cfg.mainAttr || 'atk,cpct,cdmg', // 伤害属性
enemyName: cfg.enemyName || '小宝' // 敌人名称
}
}
} }
return this._calcRule return this._calcRule
} }
@ -333,6 +326,12 @@ class Character extends Base {
static matchElem (str, def) { static matchElem (str, def) {
return CharId.matchElem(str, def) return CharId.matchElem(str, def)
} }
static matchElemName () {
}
} }
Character.CharId = CharId
export default Character export default Character

View File

@ -1,12 +1,12 @@
/* /**
* 面板圣遗物 * 面板圣遗物
* */ */
import lodash from 'lodash' import lodash from 'lodash'
import Base from './Base.js' import Base from './Base.js'
import { Artifact, ArtifactSet, Character } from './index.js' import { Artifact, ArtifactSet, Character } from './index.js'
import { Format, Data } from '../components/index.js' import { Format, Data } from '../components/index.js'
import ArtisMark from './profile-lib/ArtisMark.js' import ArtisMark from './profile-lib/ArtisMark.js'
import { attrMap, attrNameMap, attrValue } from '../resources/meta/artifact/artis-mark.js' import { attrMap, attrValue } from '../resources/meta/artifact/artis-mark.js'
import CharArtis from './profile-lib/CharArtis.js' import CharArtis from './profile-lib/CharArtis.js'
export default class ProfileArtis extends Base { export default class ProfileArtis extends Base {
@ -87,16 +87,7 @@ export default class ProfileArtis extends Base {
if (!main) { if (!main) {
return '' return ''
} }
let title = main.title return ArtisMark.getKeyByTitle(main.key, true) || ''
if (/元素伤害/.test(title)) {
return 'dmg'
}
if (attrNameMap[main.title]) {
return attrNameMap[main.title]
} else {
console.log(main.title)
}
return ''
} }
is (check, pos = '') { is (check, pos = '') {
@ -126,6 +117,7 @@ export default class ProfileArtis extends Base {
return check return check
} }
// 获取圣遗物数据
getArtisData () { getArtisData () {
let ret = {} let ret = {}
this.forEach((ds, idx) => { this.forEach((ds, idx) => {
@ -139,6 +131,16 @@ export default class ProfileArtis extends Base {
return ret return ret
} }
/**
* 获取圣遗物套装数据
* @returns {*|{imgs: *[], names: *[], sets: {}, abbrs: *[], sName: string, name: (string|*)}}
* sets: 套装名:2/4
* names: [套装名]
* imgs: [img]
* abbrs[别名]
* name: '组合名字' 若为4件套会使用套装完整名
* sName: '简写名字'若为4件套也会使用简写
*/
getSetData () { getSetData () {
if (this._setData) { if (this._setData) {
return this._setData return this._setData
@ -174,6 +176,10 @@ export default class ProfileArtis extends Base {
return this._setData return this._setData
} }
/**
* 获取角色配置
* @returns {{classTitle: *, weight: *, posMaxMark: {}, mark: {}, attrs: {}}}
*/
getCharCfg () { getCharCfg () {
let char = Character.get(this.charid) let char = Character.get(this.charid)
let { attrWeight, title } = CharArtis.getCharArtisCfg(char, this.profile, this) let { attrWeight, title } = CharArtis.getCharArtisCfg(char, this.profile, this)
@ -200,15 +206,13 @@ export default class ProfileArtis extends Base {
} }
attrs[key] = ret attrs[key] = ret
}) })
let maxMark = ArtisMark.getMaxMark(attrs) let posMaxMark = ArtisMark.getMaxMark(attrs)
// 返回内容待梳理简化 // 返回内容待梳理简化
return { return {
attrs, attrs,
classTitle: title, classTitle: title,
weight: attrWeight, weight: attrWeight,
// 待删除 posMaxMark
mark: lodash.mapValues(attrs, (ds) => ds.mark),
maxMark
} }
} }
@ -216,10 +220,6 @@ export default class ProfileArtis extends Base {
let charCfg = this.getCharCfg() let charCfg = this.getCharCfg()
let artis = {} let artis = {}
let setCount = {} let setCount = {}
let usefulMark = {}
lodash.forEach(charCfg.attrs, (ds) => {
usefulMark[ds.title] = ds.weight
})
let totalMark = 0 let totalMark = 0
this.forEach((arti, idx) => { this.forEach((arti, idx) => {
let mark = ArtisMark.getMark(charCfg, idx, arti.main, arti.attrs, this.elem) let mark = ArtisMark.getMark(charCfg, idx, arti.main, arti.attrs, this.elem)
@ -241,8 +241,8 @@ export default class ProfileArtis extends Base {
_mark: mark, _mark: mark,
mark: Format.comma(mark, 1), mark: Format.comma(mark, 1),
markClass: ArtisMark.getMarkClass(mark), markClass: ArtisMark.getMarkClass(mark),
main: ArtisMark.formatArti(arti.main, charCfg.mark, true, this.elem || ''), main: ArtisMark.formatArti(arti.main, charCfg.attrs, true, this.elem || ''),
attrs: ArtisMark.formatArti(arti.attrs, charCfg.mark) attrs: ArtisMark.formatArti(arti.attrs, charCfg.attrs)
} }
} }
}) })
@ -270,7 +270,7 @@ export default class ProfileArtis extends Base {
classTitle: charCfg.classTitle classTitle: charCfg.classTitle
} }
if (withDetail) { if (withDetail) {
ret.usefulMark = usefulMark ret.charWeight = charCfg.weight
} }
return ret return ret
} }
@ -290,4 +290,8 @@ export default class ProfileArtis extends Base {
eachArtisSet (fn) { eachArtisSet (fn) {
ProfileArtis._eachArtisSet(this.sets, fn) ProfileArtis._eachArtisSet(this.sets, fn)
} }
static getArtisKeyTitle () {
return ArtisMark.getKeyTitleMap()
}
} }

View File

@ -0,0 +1,25 @@
import { Data } from '../../components/index.js'
import lodash from 'lodash'
/**
* 角色相关配置
*/
let CharCfg = {
// 获取角色伤害计算相关配置
async getCalcRule (char) {
let cfg = await Data.importModule(`resources/meta/character/${char.name}/calc.js`)
if (lodash.isEmpty(cfg)) {
return false
}
return {
details: cfg.details || false, // 计算详情
buffs: cfg.buffs || [], // 角色buff
defParams: cfg.defParams || {}, // 默认参数,一般为空
defDmgIdx: cfg.defDmgIdx || -1, // 默认详情index
defDmgKey: cfg.defDmgKey || '',
mainAttr: cfg.mainAttr || 'atk,cpct,cdmg', // 伤害属性
enemyName: cfg.enemyName || '小宝' // 敌人名称
}
}
}
export default CharCfg

View File

@ -1,6 +1,6 @@
/* /**
* 角色别名及角色ID相关 * 角色别名及角色ID相关
* */ * */
import lodash from 'lodash' import lodash from 'lodash'
import { Data } from '../../components/index.js' import { Data } from '../../components/index.js'
import { charPosIdx, elemAlias } from './CharMeta.js' import { charPosIdx, elemAlias } from './CharMeta.js'
@ -143,6 +143,7 @@ const CharId = {
getElemName (elem = '') { getElemName (elem = '') {
return elemTitleMap[CharId.getElem(elem)] return elemTitleMap[CharId.getElem(elem)]
}, },
elemTitleMap,
// 名字匹配元素 // 名字匹配元素
matchElem (name = '', defElem = '') { matchElem (name = '', defElem = '') {

View File

@ -1,4 +1,4 @@
/* /**
* 角色照片及角色图像资源相关 * 角色照片及角色图像资源相关
* */ * */
import fs from 'fs' import fs from 'fs'

View File

@ -149,10 +149,6 @@ const CharMeta = {
return type === 'all' ? ret : ret[0] return type === 'all' ? ret : ret[0]
}, },
getLvStat (char) {
},
getDesc (desc) { getDesc (desc) {
desc = desc.replace(/。$/, '') desc = desc.replace(/。$/, '')
desc = desc.replace('</br>', '') desc = desc.replace('</br>', '')

View File

@ -1,4 +1,4 @@
/* /**
* 角色天赋相关处理 * 角色天赋相关处理
* */ * */
import lodash from 'lodash' import lodash from 'lodash'

View File

@ -1,16 +1,47 @@
import lodash from 'lodash' import lodash from 'lodash'
import { Format } from '../../components/index.js' import { Format } from '../../components/index.js'
import { Character } from '../index.js'
import { attrNameMap, mainAttr, subAttr, attrMap } from '../../resources/meta/artifact/artis-mark.js' import { attrNameMap, mainAttr, subAttr, attrMap } from '../../resources/meta/artifact/artis-mark.js'
let ArtisMark = { let ArtisMark = {
// 根据Key获取标题
getKeyByTitle (title, dmg = false) {
if (/元素伤害加成/.test(title)) {
let elem = Format.elem(title)
return dmg ? 'dmg' : elem
} else if (title === '物理伤害加成') {
return 'phy'
}
return attrNameMap[title]
},
// 根据标题获取Key
getTitleByKey (key) {
// 检查是否是伤害字段
let dmg = Format.elemName(key, '')
if (dmg) {
return `${dmg}伤加成`
}
return attrMap[key].title
},
getKeyTitleMap () {
let ret = {}
lodash.forEach(attrMap, (ds, key) => {
ret[key] = ds.title
})
lodash.forEach(Format.elemTitleMap(), (name, key) => {
ret[key] = `${name}伤加成`
})
return ret
},
formatAttr (ds) { formatAttr (ds) {
if (!ds) { if (!ds) {
return {} return {}
} }
if (lodash.isArray(ds) && ds[0] && ds[1]) { if (lodash.isArray(ds) && ds[0] && ds[1]) {
return { return {
title: ds[0], key: ArtisMark.getKeyByTitle(ds[0]),
value: ds[1] value: ds[1]
} }
} }
@ -18,7 +49,7 @@ let ArtisMark = {
return {} return {}
} }
return { return {
title: ds.title || ds.name || ds.key || ds.id || '', key: ds.key || ArtisMark.getKeyByTitle(ds.title || ds.name || ds.key || ds.id || ''),
value: ds.value || '' value: ds.value || ''
} }
}, },
@ -30,13 +61,14 @@ let ArtisMark = {
* @param isMain * @param isMain
* @returns {{title: *, value: string}|*[]} * @returns {{title: *, value: string}|*[]}
*/ */
formatArti (ds, markCfg = false, isMain = false, elem = '') { formatArti (ds, charAttrCfg = false, isMain = false, elem = '') {
if (ds[0] && ds[0].title) { // 若为attr数组
if (ds[0] && (ds[0].title || ds[0].key)) {
let ret = [] let ret = []
let totalUpNum = 0 let totalUpNum = 0
let ltArr = [] let ltArr = []
lodash.forEach(ds, (d) => { lodash.forEach(ds, (d) => {
let arti = ArtisMark.formatArti(d, markCfg) let arti = ArtisMark.formatArti(d, charAttrCfg)
totalUpNum += arti.upNum totalUpNum += arti.upNum
if (arti.hasLt) { if (arti.hasLt) {
ltArr.push(arti) ltArr.push(arti)
@ -56,51 +88,39 @@ let ArtisMark = {
} }
return ret return ret
} }
let key = ds.key
let title = ds.title || ds[0] let title = ds.title || ds[0]
let key = '' if (!key) {
key = ArtisMark.getKeyByTitle(title)
} else if (!title) {
title = ArtisMark.getTitleByKey(key)
}
let isDmg = Format.isElem(key)
let val = ds.value || ds[1] let val = ds.value || ds[1]
let value = val let value = val
let num = ds.value || ds[1] let num = ds.value || ds[1]
if (!title || title === 'undefined') { if (!key || key === 'undefined') {
return {} return {}
} }
if (/伤害加成/.test(title) && val < 1) {
val = Format.pct(val * 100)
num = num * 100
} else if (/伤害加成|大|暴|充能|治疗/.test(title)) {
val = Format.pct(val)
} else {
val = Format.comma(val, 1)
}
if (/元素伤害加成/.test(title)) { let arrCfg = attrMap[isDmg ? 'dmg' : key]
title = title.replace('元素伤害', '伤')
let mainElem = Character.matchElem(title)
if (elem && mainElem.elem !== elem) {
key = '_dmg'
} else {
key = 'dmg'
}
} else if (title === '物理伤害加成') {
title = '物伤加成'
key = 'phy'
}
key = key || attrNameMap[title] val = Format[arrCfg.format](val, 1)
let ret = { let ret = {
title, key,
value: val value: val
} }
if (!isMain) { if (!isMain) {
let incRet = ArtisMark.getIncNum(title, value) let incRet = ArtisMark.getIncNum(key, value)
ret.upNum = incRet.num ret.upNum = incRet.num
ret.hasGt = incRet.hasGt ret.hasGt = incRet.hasGt
ret.hasLt = incRet.hasLt ret.hasLt = incRet.hasLt
} }
if (markCfg) { if (charAttrCfg) {
let mark = markCfg[key] * num || 0 let mark = charAttrCfg[key]?.mark * num || 0
if (isMain) { if (isMain) {
mark = mark / 4 + 0.01 mark = mark / 4 + 0.01
ret.key = key ret.key = key
@ -111,8 +131,9 @@ let ArtisMark = {
return ret return ret
}, },
getIncNum (title, value) { // 获取升级次数
let cfg = attrNameMap[title] && attrMap[attrNameMap[title]] getIncNum (key, value) {
let cfg = attrMap[key]
if (!value || !cfg || !cfg.value || !cfg.valueMin) { if (!value || !cfg || !cfg.value || !cfg.valueMin) {
return { num: 0 } return { num: 0 }
} }
@ -130,6 +151,7 @@ let ArtisMark = {
} }
}, },
// 获取评分档位
getMarkClass (mark) { getMarkClass (mark) {
let pct = mark let pct = mark
let scoreMap = [['D', 10], ['C', 16.5], ['B', 23.1], ['A', 29.7], ['S', 36.3], ['SS', 42.9], ['SSS', 49.5], ['ACE', 56.1], ['ACE²', 66]] let scoreMap = [['D', 10], ['C', 16.5], ['B', 23.1], ['A', 29.7], ['S', 36.3], ['SS', 42.9], ['SSS', 49.5], ['ACE', 56.1], ['ACE²', 66]]
@ -140,49 +162,31 @@ let ArtisMark = {
} }
}, },
// 获取位置分数
getMark (charCfg, posIdx, mainAttr, subAttr, elem = '') { getMark (charCfg, posIdx, mainAttr, subAttr, elem = '') {
let ret = 0 let ret = 0
let { mark, maxMark, weight } = charCfg let { attrs, posMaxMark } = charCfg
let mAttr = ArtisMark.getAttr(mainAttr, elem) let key = mainAttr.key
let fixPct = 1 let fixPct = 1
posIdx = posIdx * 1
if (posIdx >= 3) { if (posIdx >= 3) {
if (mAttr !== 'recharge') { let mainKey = key
fixPct = Math.max(0, Math.min(1, (weight[mAttr] || 0) / (maxMark['m' + posIdx]))) if (key !== 'recharge') {
if (posIdx === 4 && Format.isElem(key) && key === elem) {
mainKey = 'dmg'
}
fixPct = Math.max(0, Math.min(1, (attrs[mainKey]?.weight || 0) / (posMaxMark['m' + posIdx])))
} }
ret += ArtisMark.getAttrMark(mark, mainAttr) / 4 ret += (attrs[mainKey]?.mark || 0) * (mainAttr.value || 0) / 4
} }
lodash.forEach(subAttr, (ds) => { lodash.forEach(subAttr, (ds) => {
ret += ArtisMark.getAttrMark(mark, ds) ret += (attrs[ds.key]?.mark || 0) * (ds.value || 0)
}) })
return ret * (1 + fixPct) / 2 / posMaxMark[posIdx] * 66
},
return ret * (1 + fixPct) / 2 / maxMark[posIdx] * 66 // 获取位置最高分
},
getAttr (ds, elem = '') {
let title = ds.title || ds[0] || ''
let attr = attrNameMap[title]
if (/元素伤害/.test(title)) {
attr = 'dmg'
if (elem && Character.matchElem(title).elem !== elem) {
attr = '_dmg'
}
} else if (/物理|物伤/.test(title)) {
attr = 'phy'
}
return attr
},
getAttrMark (attrMark, ds) {
if (!ds) {
return 0
}
let attr = ArtisMark.getAttr(ds)
if (!attr) {
return 0
}
let val = ds.value || ds[1]
return (attrMark[attr] || 0) * val
},
getMaxMark (attrs) { getMaxMark (attrs) {
let ret = {} let ret = {}
for (let idx = 1; idx <= 5; idx++) { for (let idx = 1; idx <= 5; idx++) {
@ -208,6 +212,8 @@ let ArtisMark = {
} }
return ret return ret
}, },
// 获取最高分的属性
getMaxAttr (attrs = {}, list2 = [], maxLen = 1, banAttr = '') { getMaxAttr (attrs = {}, list2 = [], maxLen = 1, banAttr = '') {
let tmp = [] let tmp = []
lodash.forEach(list2, (attr) => { lodash.forEach(list2, (attr) => {

View File

@ -3,8 +3,8 @@
* @type {{}} * @type {{}}
*/ */
import { Weapon, ProfileAttr, Character } from '../index.js' import { Weapon, ProfileAttr } from '../index.js'
import { attrNameMap } from '../../resources/meta/artifact/artis-mark.js' import { Format } from '../../components/index.js'
import { calc as artisBuffs } from '../../resources/meta/artifact/index.js' import { calc as artisBuffs } from '../../resources/meta/artifact/index.js'
import { calc as weaponBuffs } from '../../resources/meta/weapon/index.js' import { calc as weaponBuffs } from '../../resources/meta/weapon/index.js'
import lodash from 'lodash' import lodash from 'lodash'
@ -39,7 +39,7 @@ class AttrCalc {
this.setWeaponAttr() this.setWeaponAttr()
this.setArtisAttr() this.setArtisAttr()
if (process.argv.includes('web-debug')) { if (process.argv.includes('web-debug')) {
// console.log(this.attr, this.attr.getAttr()) // console.log(this.attr, this.attr.getAttr())
} }
return this.attr.getAttr() return this.attr.getAttr()
} }
@ -185,19 +185,11 @@ class AttrCalc {
* @returns {boolean} * @returns {boolean}
*/ */
calcArtisAttr (ds, char) { calcArtisAttr (ds, char) {
let title = ds.title let key = ds.key
let key = attrNameMap[title] if (Format.isElem(key) && char.elem === key) {
if (/元素伤害/.test(title)) {
key = 'dmg' key = 'dmg'
let elem = Character.matchElem(title)
if (!char.isElem(elem.elem)) {
key = 'dmg2'
}
} }
if (/物/.test(title)) {
key = 'phy'
}
if (!key) { if (!key) {
return false return false
} }

View File

@ -9,17 +9,16 @@ async function init () {
let charPath = process.cwd() + '/plugins/miao-plugin/resources/meta/character' let charPath = process.cwd() + '/plugins/miao-plugin/resources/meta/character'
let chars = fs.readdirSync(charPath) let chars = fs.readdirSync(charPath)
for (let char of chars) { for (let char of chars) {
if (fs.existsSync(`${charPath}/${char}/artis.js`)) {
charCfg[char] = await Data.importModule(`resources/meta/character/${char}/artis.js`)
}
// 允许自定义配置文件,会覆盖喵喵版评分规则 // 允许自定义配置文件,会覆盖喵喵版评分规则
if (fs.existsSync(`${charPath}/${char}/artis_user.js`)) { if (fs.existsSync(`${charPath}/${char}/artis_user.js`)) {
charCfg[char] = await Data.importModule(`resources/meta/character/${char}/artis_user.js`) charCfg[char] = await Data.importModule(`resources/meta/character/${char}/artis_user.js`)
} else if (fs.existsSync(`${charPath}/${char}/artis.js`)) {
charCfg[char] = await Data.importModule(`resources/meta/character/${char}/artis.js`)
} }
} }
} }
await init() await init()
const CharArtis = { const CharArtis = {
reduceWeight (weight, key, plus, max) { reduceWeight (weight, key, plus, max) {
let original = weight[key] || 0 let original = weight[key] || 0

View File

@ -12,7 +12,7 @@
{{each artis ds}} {{each artis ds}}
<div class="item arti"> <div class="item arti">
{{if ds && ds.name && ds.main && ds.main.title && ds.main.title!="undefined"}} {{if ds && ds.name && ds.main && ds.main.key && ds.main.key!="undefined"}}
<div class="avatar"> <div class="avatar">
<img src="{{_res_path}}{{ds.side}}" onerror="whenError(this)"/> <img src="{{_res_path}}{{ds.side}}" onerror="whenError(this)"/>
</div> </div>
@ -24,11 +24,12 @@
<span class="mark mark-{{ds.markClass}}"><span>{{ds.mark}}分</span> - {{ds.markClass}}</span> <span class="mark mark-{{ds.markClass}}"><span>{{ds.mark}}分</span> - {{ds.markClass}}</span>
</div> </div>
<ul class="detail attr"> <ul class="detail attr">
<li class="arti-main"><span class="title">{{ds.main.title}}</span><span class="val">+{{ds.main.value}}</span></li> <li class="arti-main"><span class="title">{{artisKeyTitle[ds.main?.key]}}</span><span class="val">+{{ds.main?.value}}</span>
</li>
{{each ds.attrs attr}} {{each ds.attrs attr}}
{{if attr && attr.title}} {{if attr && attr.key}}
<li class="{{ds.usefulMark[attr.title]*1 > 79.9 ?`great`:(ds.usefulMark[attr.title]*1>0 ? `useful`:`nouse`)}}"> <li class="{{ds.charWeight[attr.key]*1 > 79.9 ?`great`:(ds.charWeight[attr.key]*1>0 ? `useful`:`nouse`)}}">
<span class="title"> {{if attr.upNum}}<i class="up-num up-{{attr.upNum}}"></i>{{/if}}{{attr.title}}</span> <span class="title"> {{if attr.upNum}}<i class="up-num up-{{attr.upNum}}"></i>{{/if}}{{artisKeyTitle[attr.key]}}</span>
<span class="val">+{{attr.value}}</span></li> <span class="val">+{{attr.value}}</span></li>
{{/if}} {{/if}}
{{/each}} {{/each}}

View File

@ -11,6 +11,7 @@
{{block 'main'}} {{block 'main'}}
{{set ad = artisDetail}}
<div class="basic"> <div class="basic">
<div class="main-pic" <div class="main-pic"
style="background-image:url({{_res_path}}{{splash}})"></div> style="background-image:url({{_res_path}}{{splash}})"></div>
@ -22,8 +23,8 @@
<div class="item arti-stat"> <div class="item arti-stat">
<div class="arti-class-title">评分规则:{{charCfg.classTitle}}</div> <div class="arti-class-title">评分规则:{{charCfg.classTitle}}</div>
<div class="arti-stat-ret"> <div class="arti-stat-ret">
<div><strong class="mark-{{totalMarkClass}}">{{totalMarkClass}}</strong><span>圣遗物评级</span></div> <div><strong class="mark-{{artisDetail.markClass}}">{{ad.markClass}}</strong><span>圣遗物评级</span></div>
<div><strong>{{totalMark}}</strong><span>圣遗物总分</span></div> <div><strong>{{ad.mark}}</strong><span>圣遗物总分</span></div>
</div> </div>
</div> </div>
</div> </div>
@ -33,13 +34,13 @@
<div class="artis"> <div class="artis">
<% for(let idx = 1; idx<=5; idx++) { <% for(let idx = 1; idx<=5; idx++) {
let ds = artis[idx] let ds = ad?.artis[idx]
%> %>
{{if idx === 1 }} {{if idx === 1 }}
<div class="item no-bg"></div> <div class="item no-bg"></div>
{{/if}} {{/if}}
<div class="item arti {{idx}}"> <div class="item arti {{idx}}">
{{if ds && ds.name && ds.main && ds.main.title && ds.main.title!="undefined"}} {{if ds && ds.name && ds.main && ds.main.key && ds.main.key!="undefined"}}
<div class="arti-icon"> <div class="arti-icon">
<div class="img" style="background-image:url({{_res_path}}{{ds.img}})"></div> <div class="img" style="background-image:url({{_res_path}}{{ds.img}})"></div>
<span>+{{ds.level}}</span> <span>+{{ds.level}}</span>
@ -50,7 +51,7 @@
</div> </div>
<ul class="detail attr"> <ul class="detail attr">
<li class="arti-main"> <li class="arti-main">
<span class="title">{{ds.main.title}}</span> <span class="title">{{artisKeyTitle[ds.main.key]}}</span>
<span class="val">+{{ds.main.value}}</span> <span class="val">+{{ds.main.value}}</span>
{{if idx >1 }} {{if idx >1 }}
<span class="mark">{{ mark( ds.main.mark / 6 ) }}</span> <span class="mark">{{ mark( ds.main.mark / 6 ) }}</span>
@ -59,9 +60,9 @@
{{/if}} {{/if}}
</li> </li>
{{each ds.attrs attr}} {{each ds.attrs attr}}
{{if attr.title}} {{if attr.key}}
<li class="{{usefulMark[attr.title]*1 > 79.9 ?`great`:(usefulMark[attr.title]*1>0 ? `useful`:`nouse`)}}"><span <li class="{{ad.charWeight[attr.key]*1 > 79.9 ?`great`:(ad.charWeight[attr.key]*1>0 ? `useful`:`nouse`)}}"><span
class="title">{{attr.title}} </span><span class="title">{{artisKeyTitle[attr.key]}} </span><span
class="val">+{{attr.value}}</span> class="val">+{{attr.value}}</span>
<span class="mark">{{ ( 46.6 / 6 / 100 * attr._mark ).toFixed(1) }}</span> <span class="mark">{{ ( 46.6 / 6 / 100 * attr._mark ).toFixed(1) }}</span>
</li> </li>
@ -73,7 +74,7 @@
<li> <li>
<span class="title">总分对齐</span> <span class="title">总分对齐</span>
<span class="val"> <span class="val">
*{{( 66 / (46.6/6/100 * charCfg.maxMark[idx]) * 100).toFixed(1)}}% *{{( 66 / (46.6/6/100 * charCfg.posMaxMark[idx]) * 100).toFixed(1)}}%
</span> </span>
</li> </li>
{{if idx>2}} {{if idx>2}}
@ -83,8 +84,8 @@
{{if ds.main.title === '充能效率'}} {{if ds.main.title === '充能效率'}}
*100% *100%
{{else}} {{else}}
{{set mainWeight = charCfg?.weight[ds.main?.key] || 0}} {{set mainWeight = charCfg?.weight[ds.main?.key===data.elem?'dmg':ds.main?.key] || 0}}
*{{(50 + 50 * mainWeight / charCfg.maxMark["m"+idx] ).toFixed(0)}}% *{{(50 + 50 * mainWeight / charCfg.posMaxMark["m"+idx] ).toFixed(0)}}%
{{/if}} {{/if}}
</span> </span>
</li> </li>
@ -115,12 +116,14 @@
<div>副词条最高分</div> <div>副词条最高分</div>
<div>主词条最高分</div> <div>主词条最高分</div>
</div> </div>
{{each attrMap ds key}}{{if ds.type!== "plus" && charCfg.weight[key] > 0}} {{each attrMap ds key}}
{{if ds.type!== "plus" && charCfg.weight[key] > 0}}
<div class="tr"> <div class="tr">
<div class="th">{{ds.title}}</div> <div class="th">{{ds.title}}</div>
<div class="td">{{charCfg.weight[key]}}</div> <div class="td">{{charCfg.weight[key]}}</div>
<div class="td">{{ds.text}}</div> <div class="td">{{ds.text}}</div>
<div class="td">{{charCfg.mark[key] > 0 ? (46.6/6 / 100 * charCfg.mark[key]).toFixed(2) : "-"}}</div> <div class="td">{{charCfg.attrs[key]?.mark > 0 ? (46.6/6 / 100 * charCfg.attrs[key]?.mark).toFixed(2) : "-"}}
</div>
<div class="td"> <div class="td">
{{if ['元素伤害','物伤加成','治疗加成'].includes(ds.title)}} {{if ['元素伤害','物伤加成','治疗加成'].includes(ds.title)}}
&nbsp; &nbsp; - &nbsp; &nbsp; -
@ -156,7 +159,7 @@
</div> </div>
<div class="tr"> <div class="tr">
<div class="th">最高分(对齐前)</div> <div class="th">最高分(对齐前)</div>
{{each charCfg.maxMark m key}} {{each charCfg.posMaxMark m key}}
{{if key.length === 1}} {{if key.length === 1}}
<div>{{ mark( m / 6 )}}</div> <div>{{ mark( m / 6 )}}</div>
{{/if}} {{/if}}
@ -164,7 +167,7 @@
</div> </div>
<div class="tr"> <div class="tr">
<div class="th">总分对齐比例</div> <div class="th">总分对齐比例</div>
{{each charCfg.maxMark m key}} {{each charCfg.posMaxMark m key}}
{{if key.length === 1}} {{if key.length === 1}}
<div>{{( 66 / (46.6/6/100 * m) * 100).toFixed(1)}}%</div> <div>{{( 66 / (46.6/6/100 * m) * 100).toFixed(1)}}%</div>
{{/if}} {{/if}}
@ -174,9 +177,9 @@
<div class="th">最优主词缀权重</div> <div class="th">最优主词缀权重</div>
<div>-</div> <div>-</div>
<div>-</div> <div>-</div>
<div>{{charCfg.maxMark.m3}}</div> <div>{{charCfg.posMaxMark.m3}}</div>
<div>{{charCfg.maxMark.m4}}</div> <div>{{charCfg.posMaxMark.m4}}</div>
<div>{{charCfg.maxMark.m5}}</div> <div>{{charCfg.posMaxMark.m5}}</div>
</div> </div>
</div> </div>
<ul class="cont-msg"> <ul class="cont-msg">

View File

@ -64,6 +64,7 @@
</div> </div>
{{if mode === "profile" && dataSource !== "input2"}} {{if mode === "profile" && dataSource !== "input2"}}
{{set ad = artisDetail}}
<div class="artis"> <div class="artis">
<div> <div>
<div class="item weapon"> <div class="item weapon">
@ -78,14 +79,14 @@
<div class="item arti-stat"> <div class="item arti-stat">
<div class="arti-class-title">评分规则:{{classTitle}}</div> <div class="arti-class-title">评分规则:{{classTitle}}</div>
<div class="arti-stat-ret"> <div class="arti-stat-ret">
<div><strong class="mark-{{totalMarkClass}}">{{totalMarkClass}}</strong><span>圣遗物评级</span></div> <div><strong class="mark-{{ad.markClass}}">{{ad.markClass}}</strong><span>圣遗物评级</span></div>
<div><strong>{{totalMark}}</strong><span>圣遗物总分</span></div> <div><strong>{{ad.mark}}</strong><span>圣遗物总分</span></div>
</div> </div>
</div> </div>
</div> </div>
{{each artis ds idx}} {{each ad.artis ds idx}}
<div class="item arti"> <div class="item arti">
{{if ds && ds.name && ds.main && ds.main.title && ds.main.title!="undefined"}} {{if ds && ds.name && ds.main && ds.main.key && ds.main.key!="undefined"}}
<div class="arti-icon"> <div class="arti-icon">
<div class="img" style="background-image:url({{_res_path}}{{ds.img}})"></div> <div class="img" style="background-image:url({{_res_path}}{{ds.img}})"></div>
<span>+{{ds.level}}</span> <span>+{{ds.level}}</span>
@ -95,11 +96,12 @@
<span class="mark mark-{{ds.markClass}}"><span>{{ds.mark}}分</span> - {{ds.markClass}}</span> <span class="mark mark-{{ds.markClass}}"><span>{{ds.mark}}分</span> - {{ds.markClass}}</span>
</div> </div>
<ul class="detail attr"> <ul class="detail attr">
<li class="arti-main"><span class="title">{{ds.main.title}}</span><span class="val">+{{ds.main.value}}</span></li> <li class="arti-main"><span class="title">{{artisKeyTitle[ds.main?.key]}}</span><span class="val">+{{ds.main.value}}</span>
</li>
{{each ds.attrs attr}} {{each ds.attrs attr}}
{{if attr && attr.title}} {{if attr && attr.key}}
<li class="{{usefulMark[attr.title]*1 > 79.9 ?`great`:(usefulMark[attr.title]*1>0 ? `useful`:`nouse`)}}"> <li class="{{ad.charWeight[attr.key]*1 > 79.9 ?`great`:(ad.charWeight[attr.key]*1>0 ? `useful`:`nouse`)}}">
<span class="title"> {{if attr.upNum}}<i class="up-num up-{{attr.upNum}}"></i>{{/if}}{{attr.title}}</span> <span class="title"> {{if attr.upNum}}<i class="up-num up-{{attr.upNum}}"></i>{{/if}}{{artisKeyTitle[attr.key]}}</span>
<span class="val">+{{attr.value}}</span> <span class="val">+{{attr.value}}</span>
</li> </li>
{{/if}} {{/if}}

View File

@ -122,12 +122,6 @@ body {
.talent-cont strong { .talent-cont strong {
color: #d3bc8e; color: #d3bc8e;
} }
.weapon-list {
padding: 3px;
}
.weapon-list .item {
margin: 3px;
}
.char-holding { .char-holding {
display: flex; display: flex;
padding: 8px; padding: 8px;
@ -205,6 +199,13 @@ body {
transform: scale(0.9); transform: scale(0.9);
margin-top: -3px; margin-top: -3px;
} }
.weapon-list {
padding: 3px;
}
.weapon-list .item {
margin: 3px 3px 3px 4px;
width: 74px;
}
.artis-list .item-bg { .artis-list .item-bg {
background-size: contain; background-size: contain;
background-position: center; background-position: center;

View File

@ -88,7 +88,8 @@
<div class="cont"> <div class="cont">
<div class="cont-title border-less">常用武器</div> <div class="cont-title border-less">常用武器</div>
<div class="item-list weapon-list"> <div class="item-list weapon-list">
{{each weapons weapon}} {{each weapons weapon idx}}
{{if idx <7}}
<div class="item item-card"> <div class="item item-card">
<div class="item-icon star{{weapon.star}}"> <div class="item-icon star{{weapon.star}}">
<div class="item-bg" style="background-image:url({{_res_path}}{{weapon.img}})"></div> <div class="item-bg" style="background-image:url({{_res_path}}{{weapon.img}})"></div>
@ -96,6 +97,7 @@
<div class="item-value">{{weapon.value}}</div> <div class="item-value">{{weapon.value}}</div>
<div class="item-title">{{weapon.abbr}}</div> <div class="item-title">{{weapon.abbr}}</div>
</div> </div>
{{/if}}
{{/each}} {{/each}}
</div> </div>
</div> </div>
@ -105,7 +107,8 @@
<div class="cont"> <div class="cont">
<div class="cont-title border-less">常用圣遗物<span>持有率、武器、圣遗物统计来自胡桃API未经允许请勿使用此数据</span></div> <div class="cont-title border-less">常用圣遗物<span>持有率、武器、圣遗物统计来自胡桃API未经允许请勿使用此数据</span></div>
<div class="item-list weapon-list artis-list"> <div class="item-list weapon-list artis-list">
{{each artis arti}} {{each artis arti idx}}
{{if idx <7}}
<div class="item item-card"> <div class="item item-card">
<div class="item-icon star5 artis-count{{arti.imgs.length}}"> <div class="item-icon star5 artis-count{{arti.imgs.length}}">
{{each arti.imgs img idx}} {{each arti.imgs img idx}}
@ -116,6 +119,7 @@
<div class="item-value">{{arti.value}}</div> <div class="item-value">{{arti.value}}</div>
<div class="item-title">{{arti.title}}</div> <div class="item-title">{{arti.title}}</div>
</div> </div>
{{/if}}
{{/each}} {{/each}}
</div> </div>
</div> </div>

View File

@ -159,14 +159,6 @@ body {
} }
} }
.weapon-list {
padding: 3px;
.item {
margin: 3px;
}
}
.char-holding { .char-holding {
display: flex; display: flex;
padding: 8px; padding: 8px;
@ -259,6 +251,15 @@ body {
margin-top: -3px; margin-top: -3px;
} }
.weapon-list {
padding: 3px;
.item {
margin: 3px 3px 3px 4px;
width: 74px;
}
}
.artis-list { .artis-list {
.item-bg { .item-bg {
background-size: contain; background-size: contain;

View File

@ -47,7 +47,7 @@ app.get('/', function (req, res) {
app.get('/:page', function (req, res) { app.get('/:page', function (req, res) {
let [plugin, app, page] = req.params.page.split('_') let [plugin, app, page] = req.params.page.split('_')
if (page == 'favicon.ico') { if (plugin == 'favicon.ico') {
return res.send('') return res.send('')
} }
let data = JSON.parse(fs.readFileSync(_path + `/data/ViewData/${plugin}/${app}_${page}.json`, 'utf8')) let data = JSON.parse(fs.readFileSync(_path + `/data/ViewData/${plugin}/${app}_${page}.json`, 'utf8'))