mirror of
https://github.com/yoimiya-kokomi/miao-plugin.git
synced 2024-11-21 22:48:13 +00:00
调整mys天赋更新逻辑
This commit is contained in:
parent
2993021be9
commit
4eae5af34e
29
CHANGELOG.md
29
CHANGELOG.md
@ -1,31 +1,32 @@
|
||||
# 2.4.8
|
||||
# 2.5.1 dev
|
||||
|
||||
* 星铁面板支持面板变换功能
|
||||
* 面板变换支持更换圣遗物套装,例如`#甘雨换乐团`、`#镜流换快枪手封印站`
|
||||
* 微调面板页面的部分样式
|
||||
* 重构Models的结构,尚未完全完成,功能可能不稳定
|
||||
* 原神的面板数据迁移至 **/data/PlayerData/gs**
|
||||
|
||||
# 2.4.1 ~ 2.4.7
|
||||
# 2.5.0
|
||||
|
||||
* 初步支持星铁面板数据获取与展示
|
||||
* 可使用`#星铁更新面板`来获取面板信息,通过`#希儿面板`来进行查看
|
||||
* 星铁面板展示圣遗物评分,评分功能尚未完全完成,分值与样式不为最终版本
|
||||
* 部分角色的伤害计算,以及圣遗物评分功能仍在补全中
|
||||
* 星铁面板展示圣遗物评分,评分功能尚未完全完成
|
||||
* 星铁面板天赋展示更新,支持展示行迹信息
|
||||
* 初步增加星铁的排名功能 **@Simplxss**
|
||||
* 增加`#星铁日历`功能 **@Aluxes**
|
||||
* 星铁面板支持面板变换功能
|
||||
* 请配合使用Miao-Yunzai 3.1.0可达到最佳效果
|
||||
* Miao-Yunzai可使用`*`来代填`#星铁`前缀,能区分游戏使用不同UID
|
||||
* 其他Yunzai版本出现原神与星铁UID混淆情况为正常情况,请手动切换UID或命令后附加UID查询
|
||||
* 角色数据及资源更新
|
||||
* 增加原神4.0~4.2的角色信息,可通过`#水神天赋`、`#水神图鉴`查看
|
||||
* 更新星铁1.2~1.3的角色数据与资源
|
||||
* 伤害计算更新
|
||||
* 增加林尼、卡夫卡、银狼的伤害计算**@Aluxes**
|
||||
* 增加原神4.0相关的武器计算 **@SmallK111407**
|
||||
* 增加菲米尼、符玄、玲可、三月七、娜塔莎、罗刹、黑塔的伤害计算 **@Aluxes**
|
||||
* 初步增加星铁的排名功能 **@Simplxss**
|
||||
* 面板功能升级
|
||||
* 面板变换支持更换圣遗物套装,例如`#甘雨换乐团`、`#镜流换快枪手封印站`
|
||||
* 增加`#重载面板`功能,用于手工修改面板数据后主动读取
|
||||
* 微调面板页面的部分样式
|
||||
* 角色数据及资源更新
|
||||
* 增加原神4.0~4.2的角色信息,可通过`#水神天赋`、`#水神图鉴`查看
|
||||
* 更新星铁1.2~1.3的角色数据与资源
|
||||
* 增加`#喵喵api`命令,用于查看喵ApiToken的有效期
|
||||
* 增加`#星铁日历`功能 **@Aluxes**
|
||||
* 增加`#重载面板`功能,用于手工修改面板数据后主动读取
|
||||
* 停用旧面板格式数据,非AttrIDs格式的数据不会展示,部分角色面板数据不展示是正常情况,重新更新面板数据即可
|
||||
* 一些已知问题修复
|
||||
|
||||
# 2.4.0
|
||||
|
@ -53,7 +53,7 @@ let Avatar = {
|
||||
data = avatar.getDetail()
|
||||
data.imgs = char.imgs
|
||||
data.source = avatar._source
|
||||
data.artis = avatar.getArtisDetail()
|
||||
data.artis = avatar.getArtisDetail(true)
|
||||
data.updateTime = moment(new Date(avatar._time)).format('MM-DD HH:mm')
|
||||
if (data.hasTalent) {
|
||||
data.talent = avatar.talent
|
||||
|
@ -9,6 +9,9 @@ const ProfileStat = {
|
||||
async avatarList (e) {
|
||||
return ProfileStat.render(e, true)
|
||||
},
|
||||
|
||||
// 渲染
|
||||
// isAvatarList true:练度统计 false角色列表
|
||||
async render (e, isAvatarList = false) {
|
||||
// 缓存时间,单位小时
|
||||
let msg = e.msg.replace('#', '').trim()
|
||||
|
276
models/Avatar.js
276
models/Avatar.js
@ -1,19 +1,259 @@
|
||||
import lodash from 'lodash'
|
||||
|
||||
import { Data } from '#miao'
|
||||
import { ProfileDmg } from './index.js'
|
||||
import AvatarBase from './avatar/AvatarBase.js'
|
||||
import { Data, Format } from '#miao'
|
||||
import { Character, ProfileDmg, Weapon } from './index.js'
|
||||
import Base from './Base.js'
|
||||
import Attr from './attr/Attr.js'
|
||||
import Artis from './artis/Artis.js'
|
||||
import ProfileAvatar from './avatar/ProfileAvatar.js'
|
||||
import ArtisMark from './artis/ArtisMark.js'
|
||||
import moment from 'moment'
|
||||
|
||||
export default class Avatar extends AvatarBase {
|
||||
const charKey = 'name,abbr,sName,star,imgs,face,side,gacha,weaponTypeName'.split(',')
|
||||
|
||||
export default class Avatar extends Base {
|
||||
constructor (ds = {}, game = 'gs') {
|
||||
super(ds, game)
|
||||
super()
|
||||
let char = Character.get({ id: ds.id, elem: ds.elem })
|
||||
if (!char) {
|
||||
return
|
||||
}
|
||||
this.id = char.id
|
||||
this.char = char
|
||||
this.game = char.game || game
|
||||
this._mysArtis = new Artis(this.game)
|
||||
this._artis = new Artis(this.game, true)
|
||||
}
|
||||
|
||||
|
||||
get hasTalent () {
|
||||
return this.talent && !lodash.isEmpty(this.talent) && !!this._talent
|
||||
}
|
||||
|
||||
get name () {
|
||||
return this.char?.name || ''
|
||||
}
|
||||
|
||||
get costume () {
|
||||
let costume = this._costume
|
||||
if (lodash.isArray(costume)) {
|
||||
costume = costume[0]
|
||||
}
|
||||
return costume
|
||||
}
|
||||
|
||||
get originalTalent () {
|
||||
return lodash.mapValues(this.talent, (ds) => ds.original)
|
||||
}
|
||||
|
||||
// 已经到达当前等级的最大天赋
|
||||
get isMaxTalent () {
|
||||
let maxLv = [1, 2, 4, 6, 8, 10]?.[this.promote - 1] || 10
|
||||
let minTalent = lodash.min(lodash.map(this.talent, (ds) => ds.original))
|
||||
if (this.name === '卡维') {
|
||||
console.log(
|
||||
'kaka', maxLv, minTalent, this.promote
|
||||
)
|
||||
}
|
||||
return minTalent >= maxLv
|
||||
}
|
||||
|
||||
get mysArtis () {
|
||||
return this._mysArtis
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取圣遗物套装属性
|
||||
* @returns {boolean|*|{imgs: *[], names: *[], sets: {}, abbrs: *[], sName: string, name: (string|*)}|{}}
|
||||
*/
|
||||
get artisSet () {
|
||||
return this.mysArtis.getSetData()
|
||||
}
|
||||
|
||||
get dataSource () {
|
||||
return {
|
||||
enka: 'Enka.Network',
|
||||
miao: '喵喵Api',
|
||||
mgg: 'MiniGG-Api',
|
||||
hutao: 'Hutao-Enka',
|
||||
mys: '米游社',
|
||||
homo: 'Mihomo'
|
||||
}[this._source] || this._source
|
||||
}
|
||||
|
||||
get updateTime () {
|
||||
let time = this._time
|
||||
if (!time) {
|
||||
return ''
|
||||
}
|
||||
if (lodash.isString(time)) {
|
||||
return moment(time).format('MM-DD HH:mm')
|
||||
}
|
||||
if (lodash.isNumber(time)) {
|
||||
return moment(new Date(time)).format('MM-DD HH:mm')
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
_get (key) {
|
||||
if (charKey.includes(key)) {
|
||||
return this.char[key]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置角色基础数据
|
||||
* @param ds
|
||||
* @param source
|
||||
*/
|
||||
setBasic (ds = {}, source = '') {
|
||||
const now = this._now || (new Date()) * 1
|
||||
this.level = ds.lv || ds.level || this.level || 1
|
||||
this.cons = ds.cons || this.cons || 0
|
||||
this.fetter = ds.fetter || this.fetter || 0
|
||||
this._costume = ds.costume || this._costume || 0
|
||||
this.elem = ds.elem || this.elem || this.char.elem || ''
|
||||
this.promote = Math.max((ds.promote ? ds.promote : this.promote) * 1 || 0, Attr.calcPromote(this.level))
|
||||
this.trees = this.trees || []
|
||||
this._source = ds._source || this._source || '' // 数据源
|
||||
this._time = ds._time || this._time || now // 面板最后更新时间
|
||||
this._update = ds._update || this._update || ds._time || now //最后更新时间,包括mys
|
||||
this._talent = ds._talent || this._talent || ds._time || now // 最后天赋更新时间,包括mys
|
||||
|
||||
if (ds.trees) {
|
||||
this.setTrees(ds.trees)
|
||||
}
|
||||
|
||||
// 存在数据源时更新时间
|
||||
if (source) {
|
||||
this._update = now
|
||||
if (source !== 'mys') {
|
||||
this._source = source
|
||||
this._time = now
|
||||
} else {
|
||||
this._source = this._source || source
|
||||
this._time = this._source !== 'mys' ? (this._time || now) : now
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 星铁的行迹数据
|
||||
setTrees (ds) {
|
||||
this.trees = []
|
||||
let prefix = ''
|
||||
let map = {}
|
||||
lodash.forEach(this.char?.detail?.tree || {}, (ds, key) => {
|
||||
let ret = /(\d{4})(\d{3})/.exec(key)
|
||||
if (ret && ret[1] && ret[2]) {
|
||||
prefix = prefix || ret[1]
|
||||
map[ret[2]] = key
|
||||
}
|
||||
})
|
||||
if (prefix) {
|
||||
for (let i = 0; i <= 3; i++) {
|
||||
map[`10${i}`] = `${prefix}10${i}`
|
||||
}
|
||||
}
|
||||
lodash.forEach(ds, (id) => {
|
||||
let ret = /\d{4}(\d{3})/.exec(id)
|
||||
this.trees.push(map[ret?.[1] || id] || id)
|
||||
})
|
||||
}
|
||||
|
||||
// 设置武器
|
||||
setWeapon (ds = {}) {
|
||||
let w = Weapon.get(ds.name || ds.id, this.game)
|
||||
if (!w) {
|
||||
return false
|
||||
}
|
||||
this.weapon = {
|
||||
id: ds.id || w.id,
|
||||
name: ds.name || w.name,
|
||||
level: ds.level || ds.lv || 1,
|
||||
promote: lodash.isUndefined(ds.promote) ? Attr.calcPromote(ds.level || ds.lv || 1) : (ds.promote || 0),
|
||||
affix: ds.affix,
|
||||
...w.getData('star,abbr,type,img')
|
||||
}
|
||||
if (this.weapon.level < 20) {
|
||||
this.weapon.promote = 0
|
||||
}
|
||||
}
|
||||
|
||||
// 获取武器详情信息
|
||||
getWeaponDetail () {
|
||||
let ret = {
|
||||
...this.weapon
|
||||
}
|
||||
if (!ret.id) {
|
||||
return {}
|
||||
}
|
||||
let wData = Weapon.get(ret.id, this.game)
|
||||
ret.splash = wData.imgs.gacha
|
||||
let wAttr = wData.calcAttr(ret.level, ret.promote)
|
||||
let attrs = {}
|
||||
if (this.isSr) {
|
||||
lodash.forEach(wAttr, (val, key) => {
|
||||
attrs[key] = Format.comma(val, 1)
|
||||
})
|
||||
} else if (this.isGs) {
|
||||
attrs.atkBase = Format.comma(wAttr.atkBase, 1)
|
||||
if (wAttr?.attr?.key) {
|
||||
let keyType = {
|
||||
mastery: 'comma'
|
||||
}
|
||||
attrs[wAttr.attr.key] = Format[keyType[wAttr.attr.key] || 'pct'](wAttr.attr.value, 1)
|
||||
}
|
||||
}
|
||||
ret.attrs = attrs
|
||||
ret.desc = wData.getAffixDesc(ret.affix)
|
||||
return ret
|
||||
}
|
||||
|
||||
// 设置天赋
|
||||
setTalent (ds = false, mode = 'original', updateTime = '') {
|
||||
const now = this._now || (new Date()) * 1
|
||||
if (ds) {
|
||||
let ret = this.char.getAvatarTalent(ds, this.cons, mode)
|
||||
if (ret) {
|
||||
this.talent = ret || this.talent
|
||||
// 设置天赋更新时间
|
||||
this._talent = ds._talent || this._talent || ds._time || now
|
||||
}
|
||||
}
|
||||
if (updateTime) {
|
||||
this._talent = now
|
||||
}
|
||||
}
|
||||
|
||||
getProfile () {
|
||||
if (!this.isProfile) {
|
||||
return false
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
// 判断当前profileData是否具备有效圣遗物信息
|
||||
hasArtis () {
|
||||
return this.isProfile && this.artis.length > 0
|
||||
}
|
||||
|
||||
// 获取数据详情
|
||||
getDetail (keys = '') {
|
||||
let imgs = this.char.getImgs(this.costume)
|
||||
if (this.isGs) {
|
||||
return {
|
||||
...(this.getData(keys || 'id,name,level,star,cons,fetter,elem,abbr,weapon,talent,artisSet') || {}),
|
||||
...Data.getData(imgs, 'face,qFace,side,gacha')
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
...(this.getData(keys || 'id,name,level,star,cons,elem,abbr,weapon,talent,artisSet,trees') || {}),
|
||||
...Data.getData(imgs, 'face,qFace,gacha,preview')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get isAvatar () {
|
||||
return true
|
||||
}
|
||||
@ -25,7 +265,7 @@ export default class Avatar extends AvatarBase {
|
||||
|
||||
// profile.hasData 别名
|
||||
get hasData () {
|
||||
return !!(this.level > 1 || this?.weapon?.name || this?.talent?.a)
|
||||
return !!(this.level > 1 || this?.weapon?.name)
|
||||
}
|
||||
|
||||
get imgs () {
|
||||
@ -52,8 +292,19 @@ export default class Avatar extends AvatarBase {
|
||||
return profile
|
||||
}
|
||||
|
||||
setAvatarBase (ds, source = '') {
|
||||
this._now = new Date() * 1
|
||||
this.setBasic(ds, source)
|
||||
ds.weapon && this.setWeapon(ds.weapon)
|
||||
ds.talent && this.setTalent(ds.talent, 'original', source)
|
||||
let artis = ds.mysArtis || ds.artis
|
||||
// 只要具备圣遗物信息,就更新mysArtis
|
||||
this._mysArtis.setArtisData(artis)
|
||||
delete this._now
|
||||
}
|
||||
|
||||
setAvatar (ds, source = '') {
|
||||
super.setAvatar(ds, source)
|
||||
this.setAvatarBase(ds, source)
|
||||
if (ds.artis && source !== 'mys') {
|
||||
this._artis.setArtisData(ds.artis)
|
||||
}
|
||||
@ -101,8 +352,11 @@ export default class Avatar extends AvatarBase {
|
||||
'name,id,elem,level,promote,cons,talent:originalTalent,trees'
|
||||
let ret = {
|
||||
...this.getData(keys),
|
||||
weapon: Data.getData(this.weapon, this.isGs ? 'name,level,promote,affix' : 'id,level,promote,affix'),
|
||||
artis: this.artis.toJSON()
|
||||
weapon: Data.getData(this.weapon, this.isGs ? 'name,level,promote,affix' : 'id,level,promote,affix')
|
||||
}
|
||||
let artis = this.artis.toJSON()
|
||||
if (!lodash.isEmpty(artis)) {
|
||||
ret.artis = artis
|
||||
}
|
||||
if (!this.mysArtis.isSameArtis(this.artis)) {
|
||||
ret.mysArtis = this.mysArtis.toJSON()
|
||||
@ -112,4 +366,8 @@ export default class Avatar extends AvatarBase {
|
||||
...this.getData('_source,_time,_update,_talent')
|
||||
}
|
||||
}
|
||||
|
||||
getArtisDetail (mysArtis = false) {
|
||||
return (mysArtis ? this.mysArtis : this.artis).getDetail()
|
||||
}
|
||||
}
|
||||
|
@ -178,6 +178,10 @@ export default class Player extends Base {
|
||||
// 设置角色数据
|
||||
setAvatar (ds, source = '') {
|
||||
let avatar = this.getAvatar(ds.id, true)
|
||||
if (!avatar.setAvatar) {
|
||||
console.log(this._avatars)
|
||||
console.log(avatar, ds)
|
||||
}
|
||||
avatar.setAvatar(ds, source)
|
||||
}
|
||||
|
||||
@ -206,6 +210,7 @@ export default class Player extends Base {
|
||||
id = avatars['10000005'] ? 10000005 : 10000007
|
||||
}
|
||||
}
|
||||
|
||||
if (!avatars[id]) {
|
||||
if (create) {
|
||||
avatars[id] = Avatar.create({ id }, this.game)
|
||||
@ -213,17 +218,15 @@ export default class Player extends Base {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
let avatar = avatars[id]
|
||||
if (!avatar.isAvatar) {
|
||||
let data = avatars[id]
|
||||
avatar = avatars[id] = Avatar.create(avatars[id], this.game)
|
||||
avatar.setAvatar(data)
|
||||
}
|
||||
if (avatar.hasData) {
|
||||
return avatar
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 循环Avatar
|
||||
async forEachAvatar (fn) {
|
||||
@ -321,6 +324,17 @@ export default class Player extends Base {
|
||||
return await MysAvatar.refreshTalent(this, ids, force)
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新角色数据
|
||||
*
|
||||
* @param cfg
|
||||
* @param cfg.detail mys-detail数据更新级别,角色列表与详情
|
||||
* @param cfg.talent mys-talent数据更新级别,角色天赋数据
|
||||
* @param cfg.index mys-index数据更新级别,游戏统计数据
|
||||
* @param cfg.profile 刷新面板数据
|
||||
* @param cfg.ids 刷新的角色列表
|
||||
*/
|
||||
|
||||
async refresh (cfg) {
|
||||
this.save(false)
|
||||
try {
|
||||
@ -331,7 +345,7 @@ export default class Player extends Base {
|
||||
await this.refreshMysDetail(cfg.detail)
|
||||
}
|
||||
if (cfg.talent || cfg.talent === 0) {
|
||||
await this.refreshTalent(cfg.ids, cfg.talent)
|
||||
await this.refreshTalent(cfg.ids || '', cfg.talent)
|
||||
}
|
||||
if (cfg.profile || cfg.profile === 0) {
|
||||
await this.refreshProfile(cfg.profile)
|
||||
@ -343,6 +357,18 @@ export default class Player extends Base {
|
||||
this.save(true)
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新并获取角色数据
|
||||
*
|
||||
* @param cfg
|
||||
* @param cfg.detail mys-detail数据更新级别,角色列表与详情
|
||||
* @param cfg.talent mys-talent数据更新级别,角色天赋数据
|
||||
* @param cfg.index mys-index数据更新级别,游戏统计数据
|
||||
* @param cfg.retType 返回类型,默认id为key对象,设置为array时返回数组
|
||||
* @param cfg.rank 返回为数组时,数据是否排序,排序规则:等级、星级、天赋、命座、武器、好感的顺序排序
|
||||
* @returns {Promise<any[]|{}>}
|
||||
*/
|
||||
|
||||
async refreshAndGetAvatarData (cfg) {
|
||||
await this.refresh(cfg)
|
||||
|
||||
@ -360,8 +386,9 @@ export default class Player extends Base {
|
||||
avatarRet[ds.id] = ds
|
||||
|
||||
let profile = avatar.getProfile()
|
||||
if (profile) {
|
||||
let mark = profile.getArtisMark(false)
|
||||
if (avatar.isProfile) {
|
||||
ds.artisSet = avatar.artis.getSetData()
|
||||
let mark = avatar.getArtisMark(false)
|
||||
ds.artisMark = Data.getData(mark, 'mark,markClass,names')
|
||||
if (rank) {
|
||||
rank.getRank(profile)
|
||||
|
@ -2,33 +2,137 @@
|
||||
* 面板圣遗物
|
||||
*/
|
||||
import lodash from 'lodash'
|
||||
import { Artifact, ArtifactSet, Character } from '#miao.models'
|
||||
import { Artifact, ArtifactSet } from '#miao.models'
|
||||
import { Data, Format } from '#miao'
|
||||
import ArtisMark from './ArtisMark.js'
|
||||
import { attrMap as attrMapGS } from '../../resources/meta/artifact/index.js'
|
||||
import { attrMap as attrMapSR } from '../../resources/meta-sr/artifact/index.js'
|
||||
import ArtisMarkCfg from './ArtisMarkCfg.js'
|
||||
import ArtisBase from './ArtisBase.js'
|
||||
import Base from '../Base.js'
|
||||
import ArtisAttr from './ArtisAttr.js'
|
||||
import ArtisSet from './ArtisSet.js'
|
||||
import ArtisMark from './ArtisMark.js'
|
||||
|
||||
export default class Artis extends ArtisBase {
|
||||
export default class Artis extends Base {
|
||||
constructor (game = 'gs', isProfile = false) {
|
||||
super(game)
|
||||
super()
|
||||
this.game = game
|
||||
this.artis = {}
|
||||
this.isProfile = !!isProfile
|
||||
}
|
||||
|
||||
|
||||
// 获取圣遗物套装数据
|
||||
getSetData () {
|
||||
return ArtisSet.getSetData(this)
|
||||
}
|
||||
|
||||
get sets () {
|
||||
return this.getSetData().sets || {}
|
||||
}
|
||||
|
||||
get names () {
|
||||
return this.getSetData().names || []
|
||||
}
|
||||
|
||||
// 有圣遗物数据
|
||||
get hasArtis () {
|
||||
return !lodash.isEmpty(this.artis)
|
||||
}
|
||||
|
||||
_get (key) {
|
||||
let artis = this.artis
|
||||
switch (key) {
|
||||
case 'length':
|
||||
return lodash.keys(artis).length
|
||||
}
|
||||
if (artis[key]) {
|
||||
return artis[key]
|
||||
}
|
||||
}
|
||||
|
||||
forEach (fn) {
|
||||
lodash.forEach(this.artis, (ds, idx) => {
|
||||
if (ds.name) {
|
||||
return fn(ds, idx)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
eachIdx (fn) {
|
||||
for (let idx = 1; idx <= (this.isGs ? 5 : 6); idx++) {
|
||||
this.artis[idx] = this.artis[idx] || {}
|
||||
let ret = fn(this.artis[idx], idx)
|
||||
if (ret === false) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setArtisData (ds = {}) {
|
||||
this.eachIdx((arti, idx) => {
|
||||
this.setArtis(idx, ds[idx] || ds[`arti${idx}`] || {})
|
||||
})
|
||||
}
|
||||
|
||||
getDetail () {
|
||||
let ret = {}
|
||||
for (let idx = 1; idx <= 5; idx++) {
|
||||
let ds = this.artis[idx]
|
||||
if (ds && (ds.name || ds.id)) {
|
||||
let artis = Artifact.get(ds)
|
||||
if (!artis) {
|
||||
continue
|
||||
}
|
||||
let tmp = {
|
||||
...artis?.getData('img,name,set'),
|
||||
level: ds.level || 1
|
||||
}
|
||||
if (ds.main && ds.attrs) {
|
||||
tmp.main = ds.main || null
|
||||
tmp.attrs = []
|
||||
for (let attrIdx in ds.attrs || []) {
|
||||
if (ds.attrs[attrIdx]) {
|
||||
tmp.attrs.push(ArtisMark.formatAttr(ds.attrs[attrIdx]))
|
||||
}
|
||||
}
|
||||
}
|
||||
ret[idx] = tmp
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
eachArtisSet (fn) {
|
||||
ArtifactSet.eachSet(this.sets, fn, this.game)
|
||||
}
|
||||
|
||||
// 有圣遗物词条
|
||||
get hasAttr () {
|
||||
return ArtisAttr.hasAttr(this)
|
||||
}
|
||||
|
||||
getMarkDetail (profile, withDetail = true) {
|
||||
return ArtisMark.getMarkDetail(profile, withDetail)
|
||||
setArtisBase (idx = 1, ds = {}) {
|
||||
this.artis[idx] = this.artis[idx] || {}
|
||||
let arti = this.artis[idx]
|
||||
|
||||
if (this.isSr) {
|
||||
let artiObj = Artifact.get(ds.id, this.game)
|
||||
if (!artiObj) {
|
||||
return false
|
||||
}
|
||||
arti.id = artiObj.id || ds.id || arti.id || ''
|
||||
arti.name = artiObj.name || arti.name || ''
|
||||
arti.set = artiObj.setName || arti.set || ''
|
||||
arti.level = ds.level || arti.level || 1
|
||||
arti.star = artiObj.getStarById(ds.id) || arti.star || 5
|
||||
} else {
|
||||
arti.name = ds.name || arti.name || ''
|
||||
arti.set = ds.set || Artifact.getSetNameByArti(arti.name) || ''
|
||||
arti.level = ds.level || 1
|
||||
arti.star = ds.star || 5
|
||||
}
|
||||
}
|
||||
|
||||
setArtis (idx = 1, ds = {}) {
|
||||
idx = idx.toString().replace('arti', '') * 1 || 1
|
||||
super.setArtis(idx, ds)
|
||||
this.setArtisBase(idx, ds)
|
||||
if (!this.isProfile) {
|
||||
return
|
||||
}
|
||||
@ -55,14 +159,24 @@ export default class Artis extends ArtisBase {
|
||||
toJSON () {
|
||||
let ret = {}
|
||||
this.eachIdx((ds, idx) => {
|
||||
let tmp = this.isGs ? { name: ds.name } : { id: ds.id }
|
||||
tmp.level = ds.level || 1
|
||||
tmp.star = ds.star || 5
|
||||
ret[idx] = tmp
|
||||
// 如果不为面板数据,则不保存mainId和attrIds
|
||||
if (!this.isProfile) {
|
||||
let key = this.isGs ? 'name' : 'id'
|
||||
let tmp = {
|
||||
level: ds.level || 1,
|
||||
star: ds.star || 5
|
||||
}
|
||||
if (!ds[key]) {
|
||||
return true
|
||||
}
|
||||
tmp[key] = ds[key]
|
||||
// 如果不为面板数据,则不保存mainId和attrIds
|
||||
if (!this.isProfile) {
|
||||
ret[idx] = tmp
|
||||
return true
|
||||
}
|
||||
if (!ds.mainId || !ds.attrIds) {
|
||||
return true
|
||||
}
|
||||
ret[idx] = tmp
|
||||
tmp.mainId = ds.mainId || ds.main?.id
|
||||
if (this.isSr) {
|
||||
tmp.attrIds = []
|
||||
@ -126,7 +240,7 @@ export default class Artis extends ArtisBase {
|
||||
let k = (ds) => [ds?.name || '', ds?.level || '', ds?.star || ''].join('|')
|
||||
let ret = true
|
||||
this.eachIdx((ds, idx) => {
|
||||
if (k[ds] !== k(target[idx])) {
|
||||
if (k(ds) !== k(target[idx])) {
|
||||
return ret = false
|
||||
}
|
||||
})
|
||||
|
@ -1,120 +0,0 @@
|
||||
/**
|
||||
* 面板圣遗物
|
||||
*/
|
||||
import lodash from 'lodash'
|
||||
import Base from '../Base.js'
|
||||
import { Artifact, ArtifactSet } from '#miao.models'
|
||||
import ArtisMark from './ArtisMark.js'
|
||||
import ArtisSet from './ArtisSet.js'
|
||||
|
||||
export default class ArtisBase extends Base {
|
||||
constructor (game = 'gs') {
|
||||
super()
|
||||
this.game = game
|
||||
this.artis = {}
|
||||
}
|
||||
|
||||
// 获取圣遗物套装数据
|
||||
getSetData () {
|
||||
return ArtisSet.getSetData(this)
|
||||
}
|
||||
|
||||
get sets () {
|
||||
return this.getSetData().sets || {}
|
||||
}
|
||||
|
||||
get names () {
|
||||
return this.getSetData().names || []
|
||||
}
|
||||
|
||||
// 有圣遗物数据
|
||||
get hasArtis () {
|
||||
return !lodash.isEmpty(this.artis)
|
||||
}
|
||||
|
||||
_get (key) {
|
||||
let artis = this.artis
|
||||
switch (key) {
|
||||
case 'length':
|
||||
return lodash.keys(artis).length
|
||||
}
|
||||
if (artis[key]) {
|
||||
return artis[key]
|
||||
}
|
||||
}
|
||||
|
||||
forEach (fn) {
|
||||
lodash.forEach(this.artis, (ds, idx) => {
|
||||
if (ds.name) {
|
||||
return fn(ds, idx)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
eachIdx (fn) {
|
||||
for (let idx = 1; idx <= (this.isGs ? 5 : 6); idx++) {
|
||||
this.artis[idx] = this.artis[idx] || {}
|
||||
let ret = fn(this.artis[idx], idx)
|
||||
if (ret === false) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setArtisData (ds = {}) {
|
||||
this.eachIdx((arti, idx) => {
|
||||
this.setArtis(idx, ds[idx] || ds[`arti${idx}`] || {})
|
||||
})
|
||||
}
|
||||
|
||||
setArtis (idx = 1, ds = {}) {
|
||||
this.artis[idx] = this.artis[idx] || {}
|
||||
let arti = this.artis[idx]
|
||||
|
||||
if (this.isSr) {
|
||||
let artiObj = Artifact.get(ds.id, this.game)
|
||||
if (!artiObj) {
|
||||
return false
|
||||
}
|
||||
arti.id = artiObj.id || ds.id || arti.id || ''
|
||||
arti.name = artiObj.name || arti.name || ''
|
||||
arti.set = artiObj.setName || arti.set || ''
|
||||
arti.level = ds.level || arti.level || 1
|
||||
arti.star = artiObj.getStarById(ds.id) || arti.star || 5
|
||||
} else {
|
||||
arti.name = ds.name || arti.name || ''
|
||||
arti.set = ds.set || Artifact.getSetNameByArti(arti.name) || ''
|
||||
arti.level = ds.level || 1
|
||||
arti.star = ds.star || 5
|
||||
}
|
||||
}
|
||||
|
||||
getDetail () {
|
||||
let ret = {}
|
||||
for (let idx = 1; idx <= 5; idx++) {
|
||||
let ds = this.artis[idx]
|
||||
if (ds) {
|
||||
let artis = Artifact.get(ds.name)
|
||||
let tmp = {
|
||||
...artis?.getData('img,name,set'),
|
||||
level: ds.level || 1
|
||||
}
|
||||
if (ds.main && ds.attrs) {
|
||||
tmp.main = ds.main || null
|
||||
tmp.attrs = []
|
||||
for (let attrIdx in ds.attrs || []) {
|
||||
if (ds.attrs[attrIdx]) {
|
||||
tmp.attrs.push(ArtisMark.formatAttr(ds.attrs[attrIdx]))
|
||||
}
|
||||
}
|
||||
}
|
||||
ret[idx] = tmp
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
eachArtisSet (fn) {
|
||||
ArtifactSet.eachSet(this.sets, fn, this.game)
|
||||
}
|
||||
}
|
@ -1,276 +0,0 @@
|
||||
import lodash from 'lodash'
|
||||
import Base from '../Base.js'
|
||||
import moment from 'moment'
|
||||
import { Character, Avatar, Weapon } from '#miao.models'
|
||||
import { Data, Format } from '#miao'
|
||||
import Attr from '../attr/Attr.js'
|
||||
import Artis from '../artis/Artis.js'
|
||||
|
||||
const charKey = 'name,abbr,sName,star,imgs,face,side,gacha,weaponTypeName'.split(',')
|
||||
|
||||
export default class AvatarBase extends Base {
|
||||
constructor (ds = {}, game = 'gs') {
|
||||
super()
|
||||
let char = Character.get({ id: ds.id, elem: ds.elem })
|
||||
if (!char) {
|
||||
return
|
||||
}
|
||||
this.id = char.id
|
||||
this.char = char
|
||||
this.game = char.game || game
|
||||
this._mysArtis = new Artis(this.game)
|
||||
}
|
||||
|
||||
get hasTalent () {
|
||||
return this.talent && !lodash.isEmpty(this.talent) && !!this._talent
|
||||
}
|
||||
|
||||
get name () {
|
||||
return this.char?.name || ''
|
||||
}
|
||||
|
||||
get costume () {
|
||||
let costume = this._costume
|
||||
if (lodash.isArray(costume)) {
|
||||
costume = costume[0]
|
||||
}
|
||||
return costume
|
||||
}
|
||||
|
||||
get originalTalent () {
|
||||
return lodash.mapValues(this.talent, (ds) => ds.original)
|
||||
}
|
||||
|
||||
// 已经到达当前等级的最大天赋
|
||||
get isMaxTalent () {
|
||||
let maxLv = [1, 2, 4, 6, 8, 10]?.[this.promote - 1] || 10
|
||||
let minTalent = lodash.min(lodash.map(this.talent, (ds) => ds.original))
|
||||
return minTalent >= maxLv
|
||||
}
|
||||
|
||||
get artis () {
|
||||
return this._mysArtis
|
||||
}
|
||||
|
||||
get mysArtis () {
|
||||
return this._mysArtis
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取圣遗物套装属性
|
||||
* @returns {boolean|*|{imgs: *[], names: *[], sets: {}, abbrs: *[], sName: string, name: (string|*)}|{}}
|
||||
*/
|
||||
get artisSet () {
|
||||
return this.artis.getSetData()
|
||||
}
|
||||
|
||||
get dataSource () {
|
||||
return {
|
||||
enka: 'Enka.Network',
|
||||
miao: '喵喵Api',
|
||||
mgg: 'MiniGG-Api',
|
||||
hutao: 'Hutao-Enka',
|
||||
mys: '米游社',
|
||||
homo: 'Mihomo'
|
||||
}[this._source] || this._source
|
||||
}
|
||||
|
||||
get updateTime () {
|
||||
let time = this._time
|
||||
if (!time) {
|
||||
return ''
|
||||
}
|
||||
if (lodash.isString(time)) {
|
||||
return moment(time).format('MM-DD HH:mm')
|
||||
}
|
||||
if (lodash.isNumber(time)) {
|
||||
return moment(new Date(time)).format('MM-DD HH:mm')
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
static create (ds, game = 'gs') {
|
||||
let avatar = new AvatarBase(ds, game)
|
||||
if (!avatar) {
|
||||
return false
|
||||
}
|
||||
return avatar
|
||||
}
|
||||
|
||||
_get (key) {
|
||||
if (charKey.includes(key)) {
|
||||
return this.char[key]
|
||||
}
|
||||
}
|
||||
|
||||
setAvatar (ds, source = '') {
|
||||
this._now = new Date() * 1
|
||||
this.setBasic(ds, source)
|
||||
ds.weapon && this.setWeapon(ds.weapon)
|
||||
ds.talent && this.setTalent(ds.talent, 'original', source)
|
||||
let artis = ds.mysArtis || ds.artis
|
||||
// 只要具备圣遗物信息,就更新mysArtis
|
||||
this._mysArtis.setArtisData(artis)
|
||||
delete this._now
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置角色基础数据
|
||||
* @param ds
|
||||
* @param source
|
||||
*/
|
||||
setBasic (ds = {}, source = '') {
|
||||
const now = this._now || (new Date()) * 1
|
||||
this.level = ds.lv || ds.level || this.level || 1
|
||||
this.cons = ds.cons || this.cons || 0
|
||||
this.fetter = ds.fetter || this.fetter || 0
|
||||
this._costume = ds.costume || this._costume || 0
|
||||
this.elem = ds.elem || this.elem || this.char.elem || ''
|
||||
this.promote = lodash.isUndefined(ds.promote) ? (this.promote || Attr.calcPromote(this.level)) : (ds.promote || 0)
|
||||
this.trees = this.trees || []
|
||||
this._source = ds._source || this._source || '' // 数据源
|
||||
this._time = ds._time || this._time || now // 面板最后更新时间
|
||||
this._update = ds._update || this._update || ds._time || now //最后更新时间,包括mys
|
||||
this._talent = ds._talent || this._talent || ds._time || now // 最后天赋更新时间,包括mys
|
||||
|
||||
if (ds.trees) {
|
||||
this.setTrees(ds.trees)
|
||||
}
|
||||
|
||||
// 存在数据源时更新时间
|
||||
if (source) {
|
||||
this._update = now
|
||||
if (source !== 'mys') {
|
||||
this._source = source
|
||||
this._time = now
|
||||
} else {
|
||||
this._source = this._source || source
|
||||
this._time = this._source !== 'mys' ? (this._time || now) : now
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 星铁的行迹数据
|
||||
setTrees (ds) {
|
||||
this.trees = []
|
||||
let prefix = ''
|
||||
let map = {}
|
||||
lodash.forEach(this.char?.detail?.tree || {}, (ds, key) => {
|
||||
let ret = /(\d{4})(\d{3})/.exec(key)
|
||||
if (ret && ret[1] && ret[2]) {
|
||||
prefix = prefix || ret[1]
|
||||
map[ret[2]] = key
|
||||
}
|
||||
})
|
||||
if (prefix) {
|
||||
for (let i = 0; i <= 3; i++) {
|
||||
map[`10${i}`] = `${prefix}10${i}`
|
||||
}
|
||||
}
|
||||
lodash.forEach(ds, (id) => {
|
||||
let ret = /\d{4}(\d{3})/.exec(id)
|
||||
this.trees.push(map[ret?.[1] || id] || id)
|
||||
})
|
||||
}
|
||||
|
||||
// 设置武器
|
||||
setWeapon (ds = {}) {
|
||||
let w = Weapon.get(ds.name || ds.id, this.game)
|
||||
if (!w) {
|
||||
return false
|
||||
}
|
||||
this.weapon = {
|
||||
id: ds.id || w.id,
|
||||
name: ds.name || w.name,
|
||||
level: ds.level || ds.lv || 1,
|
||||
promote: lodash.isUndefined(ds.promote) ? Attr.calcPromote(ds.level || ds.lv || 1) : (ds.promote || 0),
|
||||
affix: ds.affix,
|
||||
...w.getData('star,abbr,type,img')
|
||||
}
|
||||
if (this.weapon.level < 20) {
|
||||
this.weapon.promote = 0
|
||||
}
|
||||
}
|
||||
|
||||
// 获取武器详情信息
|
||||
getWeaponDetail () {
|
||||
let ret = {
|
||||
...this.weapon
|
||||
}
|
||||
if (!ret.id) {
|
||||
return {}
|
||||
}
|
||||
let wData = Weapon.get(ret.id, this.game)
|
||||
ret.splash = wData.imgs.gacha
|
||||
let wAttr = wData.calcAttr(ret.level, ret.promote)
|
||||
let attrs = {}
|
||||
if (this.isSr) {
|
||||
lodash.forEach(wAttr, (val, key) => {
|
||||
attrs[key] = Format.comma(val, 1)
|
||||
})
|
||||
} else if (this.isGs) {
|
||||
attrs.atkBase = Format.comma(wAttr.atkBase, 1)
|
||||
if (wAttr?.attr?.key) {
|
||||
let keyType = {
|
||||
mastery: 'comma'
|
||||
}
|
||||
attrs[wAttr.attr.key] = Format[keyType[wAttr.attr.key] || 'pct'](wAttr.attr.value, 1)
|
||||
}
|
||||
}
|
||||
ret.attrs = attrs
|
||||
ret.desc = wData.getAffixDesc(ret.affix)
|
||||
return ret
|
||||
}
|
||||
|
||||
// 设置天赋
|
||||
setTalent (ds = false, mode = 'original', updateTime = '') {
|
||||
const now = this._now || (new Date()) * 1
|
||||
if (ds) {
|
||||
let ret = this.char.getAvatarTalent(ds, this.cons, mode)
|
||||
if (ret) {
|
||||
this.talent = ret || this.talent
|
||||
// 设置天赋更新时间
|
||||
this._talent = ds._talent || this._talent || ds._time || now
|
||||
}
|
||||
}
|
||||
if (updateTime) {
|
||||
this._talent = now
|
||||
}
|
||||
}
|
||||
|
||||
setArtis (ds) {
|
||||
this.mysArtis.setArtisData(ds.mysArtis || ds.artis)
|
||||
}
|
||||
|
||||
getProfile () {
|
||||
if (!this.isProfile) {
|
||||
return false
|
||||
}
|
||||
return Avatar.create(this, this.game)
|
||||
}
|
||||
|
||||
// 判断当前profileData是否具备有效圣遗物信息
|
||||
hasArtis () {
|
||||
return this.isProfile && this.artis.length > 0
|
||||
}
|
||||
|
||||
// 获取数据详情
|
||||
getDetail (keys = '') {
|
||||
let imgs = this.char.getImgs(this.costume)
|
||||
if (this.isGs) {
|
||||
return {
|
||||
...(this.getData(keys || 'id,name,level,star,cons,fetter,elem,abbr,weapon,talent,artisSet') || {}),
|
||||
...Data.getData(imgs, 'face,qFace,side,gacha')
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
...(this.getData(keys || 'id,name,level,star,cons,elem,abbr,weapon,talent,artisSet,trees') || {}),
|
||||
...Data.getData(imgs, 'face,qFace,gacha,preview')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getArtisDetail () {
|
||||
return this.artis.getDetail()
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import { chestInfo } from '../../resources/meta/info/index.js'
|
||||
import AvatarUtil from './AvatarUtil.js'
|
||||
|
||||
const MysAvatar = {
|
||||
// 检查更新force值
|
||||
checkForce (player, force) {
|
||||
let e = player?.e
|
||||
let mys = e?._mys
|
||||
@ -15,6 +16,8 @@ const MysAvatar = {
|
||||
if (!ck || player._ck === ck) {
|
||||
return force
|
||||
}
|
||||
return force
|
||||
// 暂时不处理ck变更
|
||||
player._info = 0
|
||||
player._mys = 0
|
||||
player.forEachAvatar((avatar) => {
|
||||
@ -209,10 +212,10 @@ const MysAvatar = {
|
||||
// 并发5,请求天赋数据
|
||||
await Data.asyncPool(5, needReqIds, async (id) => {
|
||||
let avatar = player.getAvatar(id)
|
||||
if (!avatar || avatar.isMaxTalent) {
|
||||
if (avatar) {
|
||||
return false
|
||||
}
|
||||
if (failCount > 5) {
|
||||
if (avatar.isMaxTalent || failCount > 5) {
|
||||
avatar.setTalent(false, 'original', true)
|
||||
return false
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user