更新加权词条评分与双爆 (#532)

* 增加加权词条评分和双爆评分

* 增加加权词条评分和双爆评分
This commit is contained in:
panganqi 2023-03-28 03:42:50 +08:00 committed by GitHub
parent ef88bb729e
commit edae19cfb5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 138 additions and 21 deletions

View File

@ -1,7 +1,7 @@
import lodash from 'lodash'
import { Character, ProfileRank, ProfileDmg, Player } from '../../models/index.js'
import ProfileDetail from './ProfileDetail.js'
import { Data, Common, Format } from '#miao'
import { Character, ProfileRank, ProfileDmg, Player } from '#miao.models'
import { Data, Common, Format } from '../../components/index.js'
import lodash from 'lodash'
export async function groupRank (e) {
const groupRank = Common.cfg('groupRank')
@ -9,7 +9,7 @@ export async function groupRank (e) {
let type = ''
if (/(排名|排行|列表)/.test(msg)) {
type = 'list'
} else if (/(最强|最高|最高分|最牛|第一)/.test(msg)) {
} else if (/(最强|最高|最多|最高分|最牛|第一)/.test(msg)) {
type = 'detail'
} else if (/极限/.test(msg)) {
type = 'super'
@ -19,7 +19,9 @@ export async function groupRank (e) {
return false
}
let mode = /(分|圣遗物|评分|ACE)/.test(msg) ? 'mark' : 'dmg'
let name = msg.replace(/(#|最强|最高分|第一|极限|最高|最牛|圣遗物|评分|群内|群|排名|排行|面板|面版|详情|榜)/g, '')
mode = /(词条)/.test(msg) ? 'valid':mode
mode = /(双爆)/.test(msg) ? 'crit':mode
let name = msg.replace(/(#|最强|最高分|第一|词条|双爆|极限|最高|最多词条|最多双爆|最高词条|最高双爆|最牛|圣遗物|评分|群内|群|排名|排行|面板|面版|详情|榜)/g, '')
let char = Character.get(name)
if (!char) {
// 名字不存在或不为列表模式则返回false
@ -182,7 +184,7 @@ async function renderCharRankList ({ e, uids, char, mode, groupId }) {
uid,
isMax: !char,
...avatar.getData('id,star,name,sName,level,fetter,cons,weapon,elem,talent,artisSet,imgs'),
artisMark: Data.getData(mark, 'mark,markClass')
artisMark: Data.getData(mark, 'mark,markClass,valid,crit')
}
let dmg = data?.dmg?.data
if (dmg && dmg.avg) {
@ -207,7 +209,17 @@ async function renderCharRankList ({ e, uids, char, mode, groupId }) {
}
}
}
tmp._mark = mark?._mark || 0
if (mode === 'crit'){
tmp._mark = mark?._crit*6.6044 || 0
}
else if (mode === 'valid'){
tmp._mark = mark?._valid || 0
}
else{
tmp._mark = mark?._mark || 0
}
tmp._formatmark = Format.comma(tmp._mark, 1)
tmp._dmg = dmg?.avg || 0
tmp._star = 5 - tmp.star
list.push(tmp)
@ -215,8 +227,16 @@ async function renderCharRankList ({ e, uids, char, mode, groupId }) {
}
let title
if (char) {
title = `#${char.name}${mode === 'mark' ? '圣遗物' : ''}排行`
list = lodash.sortBy(list, mode === 'mark' ? '_mark' : '_dmg').reverse()
if (mode === 'mark'){
title = `#${char.name}${'圣遗物评分'}排行`
}
if (mode === 'crit'){
title = `#${char.name}${'双爆副词条'}排行`
}
if (mode === 'valid'){
title = `#${char.name}${'加权有效词条'}排行`
}
list = lodash.sortBy(list, mode === 'dmg' ? '_dmg' : '_mark').reverse()
} else {
title = `#${mode === 'mark' ? '最高分' : '最强'}排行`
list = lodash.sortBy(list, ['uid', '_star', 'id'])

View File

@ -4,7 +4,7 @@
import lodash from 'lodash'
import AvatarArtis from './AvatarArtis.js'
import { Artifact, ArtifactSet, Character } from './index.js'
import { Format } from '#miao'
import { Format } from '../components/index.js'
import ArtisMark from './profile/ArtisMark.js'
import { attrMap } from '../resources/meta/artifact/index.js'
import CharArtis from './profile/CharArtis.js'
@ -67,9 +67,15 @@ export default class ProfileArtis extends AvatarArtis {
let artis = {}
let setCount = {}
let totalMark = 0
let totalCrit = 0
let totalVaild = 0
this.forEach((arti, idx) => {
let mark = ArtisMark.getMark(charCfg, idx, arti.main, arti.attrs, this.elem)
let crit = ArtisMark.getCritMark(charCfg, idx, arti.main, arti.attrs, this.elem)
let vaild = ArtisMark.getValidMark(charCfg, idx, arti.main, arti.attrs, this.elem)
totalMark += mark
totalCrit += crit
totalVaild += vaild
setCount[arti.set] = (setCount[arti.set] || 0) + 1
if (!withDetail) {
artis[idx] = {
@ -108,6 +114,10 @@ export default class ProfileArtis extends AvatarArtis {
let ret = {
mark: Format.comma(totalMark, 1),
_mark: totalMark,
crit: Format.comma(totalCrit, 1),
_crit: totalCrit,
valid: Format.comma(totalVaild, 1),
_valid: totalVaild,
markClass: ArtisMark.getMarkClass(totalMark / 5),
artis,
sets,

View File

@ -1,6 +1,6 @@
import lodash from 'lodash'
import moment from 'moment'
import { Cfg, Common, Data } from '#miao'
import { Cfg, Common, Data } from '../components/index.js'
export default class ProfileRank {
constructor (data) {
@ -35,7 +35,7 @@ export default class ProfileRank {
let keys = await redis.keys(`miao:rank:${groupId}:${type}:*`)
let ret = []
for (let key of keys) {
let keyRet = /^miao:rank:\d+:(?:mark|dmg):(\d{8})$/.exec(key)
let keyRet = /^miao:rank:\d+:(?:mark|dmg|crit|valid):(\d{8})$/.exec(key)
if (keyRet && keyRet[1]) {
let charId = keyRet[1]
let uid = await ProfileRank.getGroupMaxUid(groupId, charId, type)
@ -72,7 +72,7 @@ export default class ProfileRank {
static async resetRank (groupId, groupMemList, charId = '') {
let keys = await redis.keys(`miao:rank:${groupId}:*`)
for (let key of keys) {
let charRet = /^miao:rank:\d+:(?:mark|dmg):(\d{8})$/.exec(key)
let charRet = /^miao:rank:\d+:(?:mark|dmg|crit|valid):(\d{8})$/.exec(key)
if (charRet) {
if (charId === '' || charId * 1 === charRet[1] * 1) {
await redis.del(key)
@ -172,7 +172,7 @@ export default class ProfileRank {
return false
}
for (let key of keys) {
let charRet = /^miao:rank:\d+:(?:mark|dmg):(\d{8})$/.exec(key)
let charRet = /^miao:rank:\d+:(?:mark|dmg|crit|valid):(\d{8})$/.exec(key)
if (charRet) {
await redis.zRem(key, uid)
}
@ -244,7 +244,7 @@ export default class ProfileRank {
return false
}
let ret = {}
for (let typeKey of ['mark', 'dmg']) {
for (let typeKey of ['mark', 'dmg','crit','valid']) {
let typeRank = await this.getTypeRank(profile, typeKey, force)
ret[typeKey] = typeRank
if (!ret.rank || ret.rank >= typeRank.rank) {
@ -305,7 +305,31 @@ export default class ProfileRank {
let mark = profile.getArtisMark(false)
if (mark && mark._mark) {
return {
score: mark._mark * 1,
score: mark.mark * 1,
data: mark
}
}
}
if (type === 'crit') {
if (!profile?.artis?.hasArtis) {
return false
}
let mark = profile.getArtisMark(false)
if (mark && mark._crit) {
return {
score: mark._crit * 1,
data: mark
}
}
}
if (type === 'valid') {
if (!profile?.artis?.hasArtis) {
return false
}
let mark = profile.getArtisMark(false)
if (mark && mark._valid) {
return {
score: mark._valid * 1,
data: mark
}
}

View File

@ -1,6 +1,6 @@
import lodash from 'lodash'
import { Format } from '#miao'
import { attrNameMap, mainAttr, subAttr, attrMap } from '../../resources/meta/artifact/index.js'
import { Format } from '../../components/index.js'
import { attrNameMap, mainAttr, subAttr, attrMap ,basicNum,attrPct} from '../../resources/meta/artifact/index.js'
let ArtisMark = {
// 根据Key获取标题
@ -195,6 +195,60 @@ let ArtisMark = {
})
return ret * (1 + fixPct) / 2 / posMaxMark[posIdx] * 66
},
getCritMark (charCfg, posIdx, mainAttr, subAttr, elem = '') {
let ret = 0
let { attrs, posMaxMark } = charCfg
let key = mainAttr?.key
if (!key) {
return 0
}
let fixPct = 1
posIdx = posIdx * 1
if (posIdx >= 4) {
let mainKey = key
if (posIdx === 4 && Format.isElem(key) && key === elem) {
mainKey = 'dmg'
}
fixPct = Math.max(0, Math.min(1, (attrs[mainKey]?.weight || 0) / (posMaxMark['m' + posIdx])))
}
if(key === 'cpct'|| key === 'cdmg' ){
ret += 9.41
}
lodash.forEach(subAttr, (ds) => {
if (ds.key === 'cpct' || ds.key === 'cdmg' ){
let temp_s = (attrs[ds.key]?.mark || 0) * (ds.value || 0)/85
ret += temp_s
}
})
return ret
},
getValidMark (charCfg, posIdx, mainAttr, subAttr, elem = '') {
let ret = 0
let { attrs, posMaxMark } = charCfg
let key = mainAttr?.key
if (!key) {
return 0
}
let fixPct = 1
posIdx = posIdx * 1
if (posIdx >= 4) {
let mainKey = key
if (posIdx === 4 && Format.isElem(key) && key === elem) {
mainKey = 'dmg'
}
fixPct = Math.max(0, Math.min(1, (attrs[mainKey]?.weight || 0) / (posMaxMark['m' + posIdx])))
}
lodash.forEach(subAttr, (ds) => {
let temp_s = (attrs[ds.key]?.mark || 0) * (ds.value || 0)/85
ret += temp_s
})
return ret
},
// 获取位置最高分
getMaxMark (attrs) {

View File

@ -25,6 +25,14 @@
<i class="group-rank-icon mark-icon"></i><strong>圣遗物评分排名:</strong>
基于角色评分规则进行圣遗物评分。评分规则为线性规则,无法体现词条平衡等实际因素,评分仅供娱乐
</li>
<li>
<i class="group-rank-icon mark-icon"></i><strong>双爆排名:</strong>
以圣遗物的双爆(包括头)为排序的群内排名
</li>
<li>
<i class="group-rank-icon mark-icon"></i><strong>加权有效词条排名:</strong>
以圣遗物的加权有效词条(按照喵喵权重加权)为排序的群内排名
</li>
<li>
<strong>排名范围:</strong>
本群内 / 时间点:{{rankCfg.time}} 后 / 在群内主动通过 #面板 命令查看过的面板数据
@ -103,6 +111,7 @@
{{set mark = ds.artisMark || false }}
{{set marks = ds._formatmark || false }}
{{set aImgs = ds?.artisSet?.imgs || []}}
<div class="char-item char-artis class-{{mark?.markClass||'D'}}">
<div
@ -121,7 +130,7 @@
</div>
<div class="artis-mark">
<span class="cons artis-mark-class class-{{mark?.markClass||'D'}}">{{mark.markClass}}</span>
{{mark.mark}}
{{marks}}
</div>
</div>
</div>

View File

@ -77,8 +77,8 @@ export const attrMap = {
}
// const basicNum = 23.312 / 6
const basicNum = 3.885
const attrPct = {
export const basicNum = 3.885
export const attrPct = {
atk: 1.5,
atkPlus: 5,
def: 1.875,