2022-09-04 21:03:23 +00:00
|
|
|
|
import Base from './Base.js'
|
2023-10-21 18:54:45 +00:00
|
|
|
|
import { Data, Format, Meta } from '#miao'
|
2024-04-05 03:28:51 +00:00
|
|
|
|
import lodash from 'lodash'
|
2023-10-21 18:54:45 +00:00
|
|
|
|
|
|
|
|
|
let weaponSet
|
2023-05-16 05:04:43 +00:00
|
|
|
|
|
2022-09-04 21:03:23 +00:00
|
|
|
|
class Weapon extends Base {
|
2024-05-21 16:56:21 +00:00
|
|
|
|
constructor (meta, game = 'gs') {
|
2023-10-21 18:54:45 +00:00
|
|
|
|
if (!meta || !meta.name) {
|
2022-09-04 21:03:23 +00:00
|
|
|
|
return false
|
|
|
|
|
}
|
2023-10-21 18:54:45 +00:00
|
|
|
|
super()
|
|
|
|
|
let cache = this._getCache(`weapon:${game}:${meta.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 title () {
|
|
|
|
|
return this.name
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get img () {
|
2023-10-24 19:34:36 +00:00
|
|
|
|
return `${this.isGs ? 'meta-gs' : 'meta-sr'}/weapon/${this.type}/${this.name}/icon.webp`
|
2022-09-04 21:03:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-23 14:14:09 +00:00
|
|
|
|
get abbr () {
|
|
|
|
|
let name = this.name
|
|
|
|
|
let abbr = this.meta?.abbr
|
|
|
|
|
return name.length <= 4 ? name : (abbr || name)
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-10 20:35:41 +00:00
|
|
|
|
get sName () {
|
|
|
|
|
let name = this.name
|
|
|
|
|
let abbr = this.meta?.abbr
|
|
|
|
|
name = name.replaceAll(/[「」]/g, '')
|
|
|
|
|
return name.length <= 8 ? name : (abbr || name)
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-21 19:49:49 +00:00
|
|
|
|
get imgs () {
|
2023-05-16 05:04:43 +00:00
|
|
|
|
if (this.isGs) {
|
|
|
|
|
return {
|
2023-10-24 19:34:36 +00:00
|
|
|
|
icon: `meta-gs/weapon/${this.type}/${this.name}/icon.webp`,
|
|
|
|
|
icon2: `meta-gs/weapon/${this.type}/${this.name}/awaken.webp`,
|
|
|
|
|
gacha: `meta-gs/weapon/${this.type}/${this.name}/gacha.webp`
|
2023-05-16 05:04:43 +00:00
|
|
|
|
}
|
|
|
|
|
} 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
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-06 20:58:41 +00:00
|
|
|
|
get materials () {
|
|
|
|
|
return this.getDetail()?.materials || {}
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-27 20:01:22 +00:00
|
|
|
|
get maxAffix () {
|
2023-10-14 13:17:27 +00:00
|
|
|
|
if (this.isSr) {
|
2023-10-14 06:00:01 +00:00
|
|
|
|
return 5
|
|
|
|
|
}
|
|
|
|
|
let data = this.detail?.affixData?.datas || {}
|
|
|
|
|
return (data['0'] && data['0'][4]) ? 5 : 1
|
2022-12-27 20:01:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-26 21:51:36 +00:00
|
|
|
|
static isWeaponSet (name) {
|
2023-10-21 18:54:45 +00:00
|
|
|
|
weaponSet = weaponSet || Meta.getMeta('gs', 'weapon', 'weaponSet')
|
2022-11-26 21:51:36 +00:00
|
|
|
|
return weaponSet.includes(name)
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-16 05:04:43 +00:00
|
|
|
|
static get (name, game = 'gs', type = '') {
|
2023-10-21 18:54:45 +00:00
|
|
|
|
let data = Meta.getData(game, 'weapon', name)
|
|
|
|
|
if (data) {
|
|
|
|
|
return new Weapon(data, game)
|
2022-11-26 21:51:36 +00:00
|
|
|
|
}
|
2023-10-21 18:54:45 +00:00
|
|
|
|
|
2023-05-16 05:04:43 +00:00
|
|
|
|
if (type && game === 'gs') {
|
2023-10-21 18:54:45 +00:00
|
|
|
|
const { weaponType } = Meta.getMeta(game, 'weapon')
|
2022-11-26 21:51:36 +00:00
|
|
|
|
let name2 = name + (weaponType[type] || type)
|
2023-10-21 18:54:45 +00:00
|
|
|
|
let data = Meta.getData(game, 'weapon', name2)
|
|
|
|
|
if (data) {
|
|
|
|
|
return new Weapon(data, game)
|
2022-11-26 21:51:36 +00:00
|
|
|
|
}
|
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-10-21 18:54:45 +00:00
|
|
|
|
static async forEach (fn, type = '', game = 'gs') {
|
|
|
|
|
Meta.forEach(game, 'weapon', async (ds, id) => {
|
2023-04-12 19:44:56 +00:00
|
|
|
|
let w = Weapon.get(ds.name)
|
|
|
|
|
if (!w || (type && type !== w.type)) {
|
2023-10-21 18:54:45 +00:00
|
|
|
|
return true
|
2023-04-12 19:44:56 +00:00
|
|
|
|
}
|
2023-10-21 18:54:45 +00:00
|
|
|
|
return await fn(w)
|
|
|
|
|
})
|
2023-04-12 19:44:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-02-21 19:49:49 +00:00
|
|
|
|
getDetail () {
|
|
|
|
|
if (this._detail) {
|
|
|
|
|
return this._detail
|
|
|
|
|
}
|
2023-10-24 19:34:36 +00:00
|
|
|
|
const path = this.isGs ? 'resources/meta-gs/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
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-23 14:14:09 +00:00
|
|
|
|
/**
|
|
|
|
|
* 计算武器主属性
|
|
|
|
|
* @param level 武器等级
|
|
|
|
|
* @param promote 武器突破
|
|
|
|
|
* @returns {{atkBase: number, attr: {value: *, key: *}}|{}|boolean}
|
|
|
|
|
*/
|
2023-02-21 19:49:49 +00:00
|
|
|
|
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-10-23 14:14:09 +00:00
|
|
|
|
/**
|
|
|
|
|
* 获取武器精炼描述
|
|
|
|
|
* @param affix 精炼
|
|
|
|
|
* @returns {{name, desc: *}|{}}
|
|
|
|
|
*/
|
2023-05-19 18:50:39 +00:00
|
|
|
|
getAffixDesc (affix = 1) {
|
2023-10-14 13:17:27 +00:00
|
|
|
|
if (this.isGs) {
|
2023-10-23 14:14:09 +00:00
|
|
|
|
let { text, datas } = this.detail?.affixData || {}
|
|
|
|
|
let { descFix } = Meta.getMeta('gs', 'weapon')
|
|
|
|
|
let reg = /\$\[(\d)\]/g
|
|
|
|
|
let ret
|
|
|
|
|
let desc = descFix[this.name] || text || ''
|
|
|
|
|
while ((ret = reg.exec(desc)) !== null) {
|
|
|
|
|
let idx = ret[1]
|
|
|
|
|
let value = datas?.[idx]?.[affix - 1]
|
|
|
|
|
desc = desc.replaceAll(ret[0], `<nobr>${value}</nobr>`)
|
|
|
|
|
}
|
|
|
|
|
return {
|
|
|
|
|
name: '',
|
|
|
|
|
desc
|
|
|
|
|
}
|
2023-10-14 13:17:27 +00:00
|
|
|
|
}
|
2023-05-19 18:50:39 +00:00
|
|
|
|
let skill = this.detail.skill
|
2023-10-23 14:14:09 +00:00
|
|
|
|
let { desc, tables } = skill
|
2023-11-15 21:07:55 +00:00
|
|
|
|
let reg = /\$(\d)\[(i|f1|f2)\](\%?)/g
|
2023-05-19 18:50:39 +00:00
|
|
|
|
let ret
|
|
|
|
|
while ((ret = reg.exec(desc)) !== null) {
|
2023-11-15 21:07:55 +00:00
|
|
|
|
let [txt, idx, format, pct] = ret
|
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-11-15 21:07:55 +00:00
|
|
|
|
value = Format.pct(value, format === 'f2' ? 2 : 1)
|
2023-05-20 17:14:07 +00:00
|
|
|
|
} else {
|
|
|
|
|
value = Format.comma(value)
|
2023-05-19 18:50:39 +00:00
|
|
|
|
}
|
2023-11-15 21:07:55 +00:00
|
|
|
|
desc = desc.replaceAll(txt, value)
|
2023-05-19 18:50:39 +00:00
|
|
|
|
}
|
|
|
|
|
return {
|
2023-10-23 14:14:09 +00:00
|
|
|
|
name: skill.name || '',
|
2023-05-19 18:50:39 +00:00
|
|
|
|
desc
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-05-20 13:51:44 +00:00
|
|
|
|
|
2023-10-23 14:14:09 +00:00
|
|
|
|
/**
|
|
|
|
|
* 获取当前武器Buff配置
|
|
|
|
|
* @returns {*|boolean}
|
|
|
|
|
*/
|
2023-05-21 18:13:38 +00:00
|
|
|
|
getWeaponBuffs () {
|
2023-10-21 18:54:45 +00:00
|
|
|
|
let { game } = this
|
|
|
|
|
let { weaponBuffs } = Meta.getMeta(game, 'weapon')
|
|
|
|
|
let buffs = weaponBuffs[this.id] || weaponBuffs[this.name]
|
2023-05-20 13:51:44 +00:00
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-23 14:14:09 +00:00
|
|
|
|
/**
|
|
|
|
|
* 获取武器精炼 Buff
|
|
|
|
|
* @param affix
|
|
|
|
|
* @param isStatic
|
|
|
|
|
* @returns {*[]}
|
|
|
|
|
*/
|
2023-05-21 18:13:38 +00:00
|
|
|
|
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
|