增加面板计算逻辑开关,启用后可使用面板计算数据

This commit is contained in:
Kokomi 2022-11-25 00:31:36 +08:00
parent 23c06511b6
commit 1a92456166
11 changed files with 103 additions and 64 deletions

View File

@ -1,7 +1,7 @@
# 2.1.1 # 2.1.1
* 部分底层结构升级 * 部分底层结构升级
* 底层增加面板计算逻辑,供后续功能使用 * 底层增加面板计算逻辑,默认不启用,具体应用待后续升级
* 圣遗物数据底层存储格式与处理逻辑初步升级 * 圣遗物数据底层存储格式与处理逻辑初步升级
* 圣遗物主词条评分规则微调,可能会影响部分角色评分 * 圣遗物主词条评分规则微调,可能会影响部分角色评分
* 元素杯属性不符会触发主词缀评分惩罚 * 元素杯属性不符会触发主词缀评分惩罚

View File

@ -100,7 +100,7 @@ export async function renderProfile (e, char, mode = 'profile', params = {}) {
return await Common.render('character/profile-detail', { return await Common.render('character/profile-detail', {
save_id: uid, save_id: uid,
uid, uid,
data: avatar.getData('name,abbr,cons,level,weapon,talent,dataSource,updateTime'), data: avatar.getData('name,abbr,cons,level,weapon,talent,dataSource,updateTime,_attrCalc'),
attr, attr,
elem: char.elem, elem: char.elem,
dmgData, dmgData,

View File

@ -47,14 +47,7 @@ export const cfgSchema = {
key: '戳一戳', key: '戳一戳',
def: true, def: true,
oldCfgKey: 'char.poke' oldCfgKey: 'char.poke'
}, }
commaGroup: {
title: '数字逗号分组',
key: '逗号',
def: 3,
type: 'num',
desc: '根据语言习惯设置数字分组,如千位组设为 3万位组设为 4。暂不支持欧洲样式'
},
} }
}, },
wiki: { wiki: {
@ -108,6 +101,19 @@ export const cfgSchema = {
def: false, def: false,
oldCfgKey: 'sys.help', oldCfgKey: 'sys.help',
desc: '开启后将使用喵喵版帮助作为Yunzai的默认帮助默认关闭' desc: '开启后将使用喵喵版帮助作为Yunzai的默认帮助默认关闭'
},
commaGroup: {
title: '数字逗号分组',
key: '逗号',
def: 3,
type: 'num',
desc: '根据语言习惯设置数字分组如千位组设为3万位组设为4'
},
attrCalc: {
title: '面板计算属性',
key: '计算',
def: false,
desc: '实验特性:#雷神面板 使用面板计算属性取代展柜属性'
} }
} }
} }

View File

@ -316,12 +316,19 @@ class Character extends Base {
} }
// 获取伤害计算配置 // 获取伤害计算配置
async getCalcRule () { getCalcRule () {
if (!this._calcRule && this._calcRule !== false) { if (!this._calcRule && this._calcRule !== false) {
this._calcRule = await CharCfg.getCalcRule(this) this._calcRule = CharCfg.getCalcRule(this)
} }
return this._calcRule return this._calcRule
} }
getArtisCfg () {
if (!this._artisRule && this._artisRule !== false) {
this._artisRule = CharCfg.getArtisCfg(this)
}
return this._artisRule
}
} }
Character.CharId = CharId Character.CharId = CharId

View File

@ -1,7 +1,5 @@
import lodash from 'lodash' import lodash from 'lodash'
import Base from './Base.js' import Base from './Base.js'
import DmgMastery from './profile-lib/DmgMastery.js'
import { Format } from '../components/index.js'
const baseAttr = 'atk,def,hp,mastery,recharge,cpct,cdmg,dmg,phy,heal,shield'.split(',') const baseAttr = 'atk,def,hp,mastery,recharge,cpct,cdmg,dmg,phy,heal,shield'.split(',')
let attrReg = new RegExp(`^(${baseAttr.join('|')})(Base|Plus|Pct|Inc)$`) let attrReg = new RegExp(`^(${baseAttr.join('|')})(Base|Plus|Pct|Inc)$`)
@ -9,10 +7,10 @@ let attrReg = new RegExp(`^(${baseAttr.join('|')})(Base|Plus|Pct|Inc)$`)
class ProfileAttr extends Base { class ProfileAttr extends Base {
constructor (data = null) { constructor (data = null) {
super() super()
this._init(data) this.init(data)
} }
_init (data) { init (data) {
// 基础属性 // 基础属性
this._attr = {} this._attr = {}
let attr = this._attr let attr = this._attr
@ -28,7 +26,7 @@ class ProfileAttr extends Base {
} }
} }
static init (data = null) { static create (data = null) {
return new ProfileAttr(data) return new ProfileAttr(data)
} }
@ -71,6 +69,7 @@ class ProfileAttr extends Base {
if (testRet && testRet[1] && testRet[2]) { if (testRet && testRet[1] && testRet[2]) {
let key = testRet[1] let key = testRet[1]
let key2 = testRet[2].toLowerCase() let key2 = testRet[2].toLowerCase()
attr[key][key2] = attr[key][key2] || 0
attr[key][key2] += val * 1 attr[key][key2] += val * 1
return true return true
} }
@ -105,6 +104,7 @@ class ProfileAttr extends Base {
ret[`${key}Base`] = this[`${key}Base`] ret[`${key}Base`] = this[`${key}Base`]
} }
}) })
ret._calc = true
return ret return ret
} }
} }

View File

@ -1,7 +1,7 @@
import lodash from 'lodash' import lodash from 'lodash'
import Base from './Base.js' import Base from './Base.js'
import moment from 'moment' import moment from 'moment'
import { Data } from '../components/index.js' import { Data, Cfg } from '../components/index.js'
import { Character, ProfileArtis, ProfileDmg } from './index.js' import { Character, ProfileArtis, ProfileDmg } from './index.js'
import AttrCalc from './profile-lib/AttrCalc.js' import AttrCalc from './profile-lib/AttrCalc.js'
@ -15,18 +15,27 @@ export default class ProfileData extends Base {
this.id = char.id this.id = char.id
this.char = char this.char = char
this.uid = uid || '' this.uid = uid || ''
this.setBasic(ds) this.setBasic(ds)
ds.attr && this.setAttr(ds.attr) ds.attr && this.setAttr(ds.attr)
ds.weapon && this.setWeapon(ds.weapon) ds.weapon && this.setWeapon(ds.weapon)
ds.talent && this.setTalent(ds.talent) ds.talent && this.setTalent(ds.talent)
this.artis = new ProfileArtis(this.id, this.elem) this.artis = new ProfileArtis(this.id, this.elem)
ds.artis && this.setArtis(ds.artis) ds.artis && this.setArtis(ds.artis)
if (process.argv.includes('web-debug')) { if (Cfg.get('attrCalc')) {
AttrCalc.getAttr(this) this._attr = AttrCalc.create(this)
this.attr = this._attr.calc()
this._attrCalc = true
} }
} }
static create (ds, uid) {
let profile = new ProfileData(ds, uid)
if (!profile) {
return false
}
return profile
}
setBasic (ds = {}) { setBasic (ds = {}) {
this.level = ds.lv || ds.level || 1 this.level = ds.lv || ds.level || 1
this.cons = ds.cons || 0 this.cons = ds.cons || 0

View File

@ -1,14 +1,50 @@
import { Data } from '../../components/index.js' import { Data } from '../../components/index.js'
import lodash from 'lodash' import lodash from 'lodash'
import fs from 'fs'
const charPath = process.cwd() + '/plugins/miao-plugin/resources/meta/character'
let cfgMap = {
char: {},
async init () {
let chars = fs.readdirSync(charPath)
for (let char of chars) {
cfgMap.char[char] = {}
let curr = cfgMap.char[char]
// 评分规则
if (cfgMap.exists(char, 'artis_user')) {
curr.artis = await cfgMap.getCfg(char, 'artis_user', 'default')
} else if (cfgMap.exists(char, 'artis')) {
curr.artis = await cfgMap.getCfg(char, 'artis', 'default')
}
// 伤害计算
if (cfgMap.exists(char, 'calc_user')) {
curr.calc = await cfgMap.getCfg(char, 'calc_user')
} else if (cfgMap.exists(char, 'calc')) {
curr.calc = await cfgMap.getCfg(char, 'calc')
}
}
},
exists (char, file) {
return fs.existsSync(`${charPath}/${char}/${file}.js`)
},
async getCfg (char, file, module = '') {
let cfg = await Data.importModule(`resources/meta/character/${char}/${file}.js`)
if (module) {
return cfg[module]
}
return cfg
}
}
await cfgMap.init()
/** /**
* 角色相关配置 * 角色相关配置
*/ */
let CharCfg = { let CharCfg = {
// 获取角色伤害计算相关配置 // 获取角色伤害计算相关配置
async getCalcRule (char) { getCalcRule (char) {
let cfg = await Data.importModule(`resources/meta/character/${char.name}/calc.js`) let cfg = cfgMap.char[char.name]?.calc
if (lodash.isEmpty(cfg)) { if (!cfg || lodash.isEmpty(cfg)) {
return false return false
} }
return { return {
@ -20,6 +56,9 @@ let CharCfg = {
mainAttr: cfg.mainAttr || 'atk,cpct,cdmg', // 伤害属性 mainAttr: cfg.mainAttr || 'atk,cpct,cdmg', // 伤害属性
enemyName: cfg.enemyName || '小宝' // 敌人名称 enemyName: cfg.enemyName || '小宝' // 敌人名称
} }
},
getArtisCfg (char) {
return cfgMap.char[char.name]?.artis || false
} }
} }
export default CharCfg export default CharCfg

View File

@ -18,28 +18,27 @@ class AttrCalc {
/** /**
* 静态调用入口 * 静态调用入口
* @param profile * @param profile
* @returns {boolean|void} * @returns {AttrCalc}
*/ */
static async getAttr (profile) { static create (profile) {
let attr = new AttrCalc(profile) return new AttrCalc(profile)
return await attr.calc()
} }
/** /**
* 实例调用入口 * 面板属性计算
* @param profile * @returns {{}}
*/ */
async calc (profile) { calc () {
this.attr = ProfileAttr.init({ this.attr = ProfileAttr.create({
recharge: 100, recharge: 100,
cpct: 5, cpct: 5,
cdmg: 50 cdmg: 50
}) })
await this.setCharAttr() this.setCharAttr()
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()
} }
@ -52,7 +51,7 @@ class AttrCalc {
* 计算角色属性 * 计算角色属性
* @param affix * @param affix
*/ */
async setCharAttr (affix = '') { setCharAttr (affix = '') {
let { char, level, promote } = this.profile let { char, level, promote } = this.profile
let metaAttr = char.detail?.attr || {} let metaAttr = char.detail?.attr || {}
let { keys = {}, details = {} } = metaAttr let { keys = {}, details = {} } = metaAttr
@ -87,7 +86,7 @@ class AttrCalc {
this.addAttr('defBase', getLvData(2)) this.addAttr('defBase', getLvData(2))
this.addAttr(keys[3], getLvData(3, true)) this.addAttr(keys[3], getLvData(3, true))
let charBuffs = await char.getCalcRule() let charBuffs = char.getCalcRule()
lodash.forEach(charBuffs.buffs, (buff) => { lodash.forEach(charBuffs.buffs, (buff) => {
if (!buff.isStatic) { if (!buff.isStatic) {
return true return true
@ -189,7 +188,6 @@ class AttrCalc {
if (Format.isElem(key) && char.elem === key) { if (Format.isElem(key) && char.elem === key) {
key = 'dmg' key = 'dmg'
} }
if (!key) { if (!key) {
return false return false
} }

View File

@ -1,24 +1,5 @@
import { usefulAttr } from '../../resources/meta/artifact/artis-mark.js' import { usefulAttr } from '../../resources/meta/artifact/artis-mark.js'
import { Data } from '../../components/index.js'
import lodash from 'lodash' import lodash from 'lodash'
import fs from 'fs'
let charCfg = {}
async function init () {
let charPath = process.cwd() + '/plugins/miao-plugin/resources/meta/character'
let chars = fs.readdirSync(charPath)
for (let char of chars) {
// 允许自定义配置文件,会覆盖喵喵版评分规则
if (fs.existsSync(`${charPath}/${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()
const CharArtis = { const CharArtis = {
@ -88,7 +69,7 @@ const CharArtis = {
} }
} }
let charRule = charCfg[char.name]?.default || function ({ def }) { let charRule = char.getArtisCfg() || function ({ def }) {
return def(usefulAttr[char.name] || { atk: 75, cpct: 100, cdmg: 100 }) return def(usefulAttr[char.name] || { atk: 75, cpct: 100, cdmg: 100 })
} }

View File

@ -42,7 +42,7 @@
</ul> </ul>
<div class="data-info"> <div class="data-info">
{{if data.dataSource}} {{if data.dataSource}}
<span>数据源:{{ {miao:"喵喵Api",enka:"Enka.Network",input:"手工录入"}[data.dataSource]||data.dataSource }}</span> <span>{{if data._attrCalc}}[ 面板属性计算:开启 ] ·{{/if}} 数据源:{{ {miao:"喵喵Api",enka:"Enka.Network",input:"手工录入"}[data.dataSource]||data.dataSource }}</span>
{{/if}} {{/if}}
{{if data.updateTime}} {{if data.updateTime}}
<span class="time">{{data.updateTime}}</span> <span class="time">{{data.updateTime}}</span>

View File

@ -5,9 +5,10 @@ import lodash from 'lodash'
let _path = process.cwd() let _path = process.cwd()
async function testCalcAttr (profile) { function testCalcAttr (profile) {
if (profile.hasData) { if (profile.hasData) {
let attr2 = await AttrCalc.getAttr(profile) let attrCalc = AttrCalc.create(profile)
let attr2 = attrCalc.calc()
let char = profile.char let char = profile.char
let ret = {} let ret = {}
lodash.forEach(profile.attr, (val, key) => { lodash.forEach(profile.attr, (val, key) => {
@ -90,9 +91,7 @@ async function test (ignore) {
if (ignore.includes(uid * 1)) { if (ignore.includes(uid * 1)) {
continue continue
} }
Profile.forEach(uid, (profile) => {
await Profile.forEach(uid, async (profile) => {
if (count > 0) { if (count > 0) {
return false return false
} }
@ -101,7 +100,7 @@ async function test (ignore) {
return true return true
} }
console.log(profile.id) console.log(profile.id)
let ret = await testCalcAttr(profile) let ret = testCalcAttr(profile)
if (ret === false) { if (ret === false) {
count++ count++
} }