2022-09-04 21:03:23 +00:00
|
|
|
|
import Base from './Base.js'
|
2023-05-19 18:50:39 +00:00
|
|
|
|
import { Data, Format } from '#miao'
|
2023-05-20 13:51:44 +00:00
|
|
|
|
import { weaponData, weaponAbbr, weaponAlias, weaponType, weaponSet, weaponBuffs } from '../resources/meta/weapon/index.js'
|
|
|
|
|
import {
|
|
|
|
|
weaponData as weaponDataSR,
|
|
|
|
|
weaponAlias as weaponAliasSR,
|
|
|
|
|
weaponBuffs as weaponBuffsSR
|
|
|
|
|
} from '../resources/meta-sr/weapon/index.js'
|
2023-05-16 05:04:43 +00:00
|
|
|
|
|
2022-11-26 21:51:36 +00:00
|
|
|
|
import lodash from 'lodash'
|
2022-09-04 21:03:23 +00:00
|
|
|
|
|
|
|
|
|
class Weapon extends Base {
|
2023-05-16 05:04:43 +00:00
|
|
|
|
constructor (name, game = 'gs') {
|
2022-09-04 21:03:23 +00:00
|
|
|
|
super(name)
|
2023-05-16 05:04:43 +00:00
|
|
|
|
let meta = game === 'gs' ? weaponData[name] : weaponDataSR[name]
|
2022-09-04 21:03:23 +00:00
|
|
|
|
if (!meta) {
|
|
|
|
|
return false
|
|
|
|
|
}
|
2023-05-16 05:04:43 +00:00
|
|
|
|
let cache = this._getCache(`weapon:${game}:${name}`)
|
2022-09-04 21:03:23 +00:00
|
|
|
|
if (cache) {
|
|
|
|
|
return cache
|
|
|
|
|
}
|
2023-02-26 15:42:56 +00:00
|
|
|
|
this.id = meta.id
|
2022-09-04 21:03:23 +00:00
|
|
|
|
this.name = meta.name
|
|
|
|
|
this.meta = meta
|
|
|
|
|
this.type = meta.type
|
|
|
|
|
this.star = meta.star
|
2023-05-16 05:04:43 +00:00
|
|
|
|
this.game = game
|
2022-09-08 20:34:32 +00:00
|
|
|
|
return this._cache()
|
2022-09-04 21:03:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get abbr () {
|
2022-11-26 21:51:36 +00:00
|
|
|
|
return weaponAbbr[this.name] || this.name
|
2022-09-04 21:03:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get title () {
|
|
|
|
|
return this.name
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get img () {
|
2023-05-18 20:23:19 +00:00
|
|
|
|
return `${this.isGs ? 'meta' : 'meta-sr'}/weapon/${this.type}/${this.name}/icon.webp`
|
2022-09-04 21:03:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-02-21 19:49:49 +00:00
|
|
|
|
get imgs () {
|
2023-05-16 05:04:43 +00:00
|
|
|
|
if (this.isGs) {
|
|
|
|
|
return {
|
|
|
|
|
icon: `meta/weapon/${this.type}/${this.name}/icon.webp`,
|
|
|
|
|
icon2: `meta/weapon/${this.type}/${this.name}/awaken.webp`,
|
|
|
|
|
gacha: `meta/weapon/${this.type}/${this.name}/gacha.webp`
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
return {
|
2023-05-18 20:23:19 +00:00
|
|
|
|
icon: `meta-sr/weapon/${this.type}/${this.name}/icon.webp`,
|
|
|
|
|
icon2: `meta-sr/weapon/${this.type}/${this.name}/icon-s.webp`,
|
|
|
|
|
gacha: `meta-sr/weapon/${this.type}/${this.name}/splash.webp`
|
2023-05-16 05:04:43 +00:00
|
|
|
|
}
|
2023-02-21 19:49:49 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-04 21:03:23 +00:00
|
|
|
|
get icon () {
|
|
|
|
|
return this.img
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-20 20:45:27 +00:00
|
|
|
|
get detail () {
|
|
|
|
|
return this.getDetail()
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-27 20:01:22 +00:00
|
|
|
|
get maxLv () {
|
|
|
|
|
return this.star <= 2 ? 70 : 90
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-12 19:44:56 +00:00
|
|
|
|
get maxPromote () {
|
|
|
|
|
return this.star <= 2 ? 4 : 6
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-27 20:01:22 +00:00
|
|
|
|
get maxAffix () {
|
|
|
|
|
let datas = this.detail?.affixData?.datas || {}
|
|
|
|
|
return (datas['0'] && datas['0'][4]) ? 5 : 1
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-26 21:51:36 +00:00
|
|
|
|
static isWeaponSet (name) {
|
|
|
|
|
return weaponSet.includes(name)
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-16 05:04:43 +00:00
|
|
|
|
static get (name, game = 'gs', type = '') {
|
2022-11-26 21:51:36 +00:00
|
|
|
|
name = lodash.trim(name)
|
2023-05-16 05:04:43 +00:00
|
|
|
|
let alias = game === 'gs' ? weaponAlias : weaponAliasSR
|
|
|
|
|
if (alias[name]) {
|
|
|
|
|
return new Weapon(alias[name], game)
|
2022-11-26 21:51:36 +00:00
|
|
|
|
}
|
2023-05-16 05:04:43 +00:00
|
|
|
|
if (type && game === 'gs') {
|
2022-11-26 21:51:36 +00:00
|
|
|
|
let name2 = name + (weaponType[type] || type)
|
|
|
|
|
if (weaponAlias[name2]) {
|
|
|
|
|
return new Weapon(weaponAlias[name2])
|
|
|
|
|
}
|
2022-11-20 20:45:27 +00:00
|
|
|
|
}
|
|
|
|
|
return false
|
2022-09-04 21:03:23 +00:00
|
|
|
|
}
|
2023-02-21 19:49:49 +00:00
|
|
|
|
|
2023-04-12 19:44:56 +00:00
|
|
|
|
static async forEach (fn, type = '') {
|
|
|
|
|
for (let name in weaponData) {
|
|
|
|
|
let ds = weaponData[name]
|
|
|
|
|
let w = Weapon.get(ds.name)
|
|
|
|
|
if (!w || (type && type !== w.type)) {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
await fn(w)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-21 19:49:49 +00:00
|
|
|
|
getDetail () {
|
|
|
|
|
if (this._detail) {
|
|
|
|
|
return this._detail
|
|
|
|
|
}
|
2023-05-18 20:23:19 +00:00
|
|
|
|
const path = this.isGs ? 'resources/meta/weapon' : 'resources/meta-sr/weapon'
|
2023-02-21 19:49:49 +00:00
|
|
|
|
try {
|
2023-04-12 19:44:56 +00:00
|
|
|
|
this._detail = Data.readJSON(`${path}/${this.type}/${this.name}/data.json`, 'miao')
|
2023-02-21 19:49:49 +00:00
|
|
|
|
} catch (e) {
|
|
|
|
|
console.log(e)
|
|
|
|
|
}
|
|
|
|
|
return this._detail
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
calcAttr (level, promote = -1) {
|
2023-05-18 20:23:19 +00:00
|
|
|
|
let metaAttr = this.detail?.attr
|
|
|
|
|
if (!metaAttr) {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
if (this.isSr) {
|
|
|
|
|
let lvAttr = metaAttr[promote]
|
|
|
|
|
let ret = {}
|
|
|
|
|
lodash.forEach(lvAttr.attrs, (v, k) => {
|
|
|
|
|
ret[k] = v * 1
|
|
|
|
|
})
|
|
|
|
|
lodash.forEach(this.detail?.growAttr, (v, k) => {
|
|
|
|
|
ret[k] = ret[k] * 1 + v * (level - 1)
|
|
|
|
|
})
|
|
|
|
|
return ret
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-21 19:49:49 +00:00
|
|
|
|
let lvLeft = 1
|
|
|
|
|
let lvRight = 20
|
|
|
|
|
let lvStep = [1, 20, 40, 50, 60, 70, 80, 90]
|
|
|
|
|
let currPromote = 0
|
|
|
|
|
for (let idx = 0; idx < lvStep.length - 1; idx++) {
|
|
|
|
|
if (promote === -1 || (currPromote === promote)) {
|
|
|
|
|
if (level >= lvStep[idx] && level <= lvStep[idx + 1]) {
|
|
|
|
|
lvLeft = lvStep[idx]
|
|
|
|
|
lvRight = lvStep[idx + 1]
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
currPromote++
|
|
|
|
|
}
|
|
|
|
|
let wAttr = this?.detail?.attr || {}
|
|
|
|
|
let wAtk = wAttr.atk || {}
|
|
|
|
|
let valueLeft = wAtk[lvLeft + '+'] || wAtk[lvLeft] || {}
|
|
|
|
|
let valueRight = wAtk[lvRight] || {}
|
|
|
|
|
let atkBase = valueLeft * 1 + ((valueRight - valueLeft) * (level - lvLeft) / (lvRight - lvLeft))
|
|
|
|
|
let wBonus = wAttr.bonusData || {}
|
|
|
|
|
valueLeft = wBonus[lvLeft + '+'] || wBonus[lvLeft]
|
|
|
|
|
valueRight = wBonus[lvRight]
|
|
|
|
|
let stepCount = Math.ceil((lvRight - lvLeft) / 5)
|
|
|
|
|
let valueStep = (valueRight - valueLeft) / stepCount
|
|
|
|
|
let value = valueLeft + (stepCount - Math.ceil((lvRight - level) / 5)) * valueStep
|
|
|
|
|
return {
|
|
|
|
|
atkBase,
|
|
|
|
|
attr: {
|
|
|
|
|
key: wAttr.bonusKey,
|
|
|
|
|
value
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-20 13:51:44 +00:00
|
|
|
|
// 获取精炼描述
|
2023-05-19 18:50:39 +00:00
|
|
|
|
getAffixDesc (affix = 1) {
|
|
|
|
|
let skill = this.detail.skill
|
|
|
|
|
let { name, desc, tables } = skill
|
|
|
|
|
let reg = /\$(\d)\[[i|f1]\](\%?)/g
|
|
|
|
|
let ret
|
|
|
|
|
while ((ret = reg.exec(desc)) !== null) {
|
|
|
|
|
let idx = ret[1]
|
|
|
|
|
let pct = ret[2]
|
2023-05-20 13:51:44 +00:00
|
|
|
|
let value = tables?.[idx]?.[affix - 1]
|
2023-05-19 18:50:39 +00:00
|
|
|
|
if (pct === '%') {
|
2023-05-20 17:14:07 +00:00
|
|
|
|
value = Format.pct(value)
|
|
|
|
|
} else {
|
|
|
|
|
value = Format.comma(value)
|
2023-05-19 18:50:39 +00:00
|
|
|
|
}
|
|
|
|
|
desc = desc.replaceAll(ret[0], value)
|
|
|
|
|
}
|
|
|
|
|
return {
|
|
|
|
|
name: skill.name,
|
|
|
|
|
desc
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-05-20 13:51:44 +00:00
|
|
|
|
|
2023-05-21 18:13:38 +00:00
|
|
|
|
getWeaponBuffs () {
|
|
|
|
|
let { isSr } = this
|
2023-05-20 13:51:44 +00:00
|
|
|
|
let wBuffs = (isSr ? weaponBuffsSR : weaponBuffs)
|
|
|
|
|
let buffs = wBuffs[this.id] || wBuffs[this.name]
|
|
|
|
|
if (!buffs) {
|
|
|
|
|
return false
|
|
|
|
|
}
|
2023-05-21 18:13:38 +00:00
|
|
|
|
if (lodash.isPlainObject(buffs) || lodash.isFunction(buffs)) {
|
2023-05-20 13:51:44 +00:00
|
|
|
|
buffs = [buffs]
|
|
|
|
|
}
|
2023-05-21 18:13:38 +00:00
|
|
|
|
return buffs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getWeaponAffixBuffs (affix, isStatic = true) {
|
|
|
|
|
let buffs = this.getWeaponBuffs()
|
|
|
|
|
let ret = []
|
|
|
|
|
let self = this
|
|
|
|
|
let { detail } = this
|
|
|
|
|
|
|
|
|
|
let tables = {}
|
|
|
|
|
lodash.forEach(detail?.skill?.tables || {}, (ds, idx) => {
|
|
|
|
|
tables[idx] = ds[affix - 1]
|
|
|
|
|
})
|
|
|
|
|
|
2023-05-20 13:51:44 +00:00
|
|
|
|
lodash.forEach(buffs, (ds) => {
|
2023-05-21 18:13:38 +00:00
|
|
|
|
if (lodash.isFunction(ds)) {
|
|
|
|
|
ds = ds(tables)
|
|
|
|
|
}
|
2023-05-20 13:51:44 +00:00
|
|
|
|
if (!!ds.isStatic !== !!isStatic) {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-21 18:13:38 +00:00
|
|
|
|
// 静态属性
|
|
|
|
|
if (ds.isStatic) {
|
2023-05-20 13:51:44 +00:00
|
|
|
|
let tmp = {}
|
2023-05-21 18:13:38 +00:00
|
|
|
|
// 星铁武器格式
|
|
|
|
|
if (ds.idx && ds.key) {
|
|
|
|
|
if (!ds.idx || !ds.key) return true
|
|
|
|
|
if (!tables[ds.idx]) return true
|
|
|
|
|
tmp[ds.key] = tables[ds.idx]
|
|
|
|
|
}
|
|
|
|
|
if (ds.refine) {
|
|
|
|
|
lodash.forEach(ds.refine, (r, key) => {
|
|
|
|
|
tmp[key] = r[affix - 1] * (ds.buffCount || 1)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
if (!lodash.isEmpty(tmp)) {
|
|
|
|
|
ret.push({
|
|
|
|
|
isStatic: true,
|
|
|
|
|
data: tmp
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 自动拼接标题
|
|
|
|
|
if (!/:/.test(ds.title)) {
|
|
|
|
|
ds.title = `${self.name}:${ds.title}`
|
|
|
|
|
}
|
|
|
|
|
ds.data = ds.data || {}
|
|
|
|
|
// refine
|
|
|
|
|
if (ds.idx && ds.key) {
|
|
|
|
|
if (!ds.idx || !ds.key) return true
|
|
|
|
|
if (!tables[ds.idx]) return true
|
|
|
|
|
ds.data[ds.key] = tables[ds.idx]
|
|
|
|
|
} else if (ds.refine) {
|
|
|
|
|
|
|
|
|
|
lodash.forEach(ds.refine, (r, key) => {
|
|
|
|
|
ds.data[key] = ({ refine }) => r[refine] * (ds.buffCount || 1)
|
2023-05-20 13:51:44 +00:00
|
|
|
|
})
|
|
|
|
|
}
|
2023-05-21 18:13:38 +00:00
|
|
|
|
|
|
|
|
|
ret.push(ds)
|
2023-05-20 13:51:44 +00:00
|
|
|
|
})
|
2023-05-21 18:13:38 +00:00
|
|
|
|
|
2023-05-20 13:51:44 +00:00
|
|
|
|
return ret
|
|
|
|
|
}
|
2022-09-04 21:03:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default Weapon
|