497 lines
16 KiB
Vue
497 lines
16 KiB
Vue
<template>
|
||
<div class="w-340px min-w-340px shrink-0 bg-black flex flex-col">
|
||
<calc-dialog lazy header="装备条件" v-model:visible="triggerVisible">
|
||
<options />
|
||
</calc-dialog>
|
||
<!-- 头部 选择是装备还是融合石 -->
|
||
<div class="flex bg-#101012 h-40px text-#6C5E4A font-bold">
|
||
<div
|
||
class="flex-1 text-15px flex items-center justify-center"
|
||
@click="chooseCategory('equ')"
|
||
:class="{ active: type === 'equ' }"
|
||
>
|
||
装备
|
||
</div>
|
||
<div class="w-auto text-18px flex items-center justify-center !font-normal">|</div>
|
||
<div
|
||
class="flex-1 text-15px flex items-center justify-center"
|
||
@click="chooseCategory('oath')"
|
||
:class="{ active: type === 'oath' }"
|
||
>
|
||
誓约
|
||
</div>
|
||
</div>
|
||
<div
|
||
class="w-full h-1px bg-gradient-to-r from-[rgba(52,43,27,0.05)] via-[rgba(52,43,27,1)] to-[rgba(52,43,27,0.05)]"
|
||
></div>
|
||
<div class="p-1 space-y-1 mt-10px">
|
||
<div class="flex w-full">
|
||
<div class="flex flex-1 items-center">
|
||
部位:<part-select class="!max-w-25 !w-25" v-model:partList="choose_part"></part-select>
|
||
</div>
|
||
<div class="flex flex-1 items-center">
|
||
品质:<EquipmentRaritySelect v-model="curRarity" />
|
||
</div>
|
||
</div>
|
||
<div class="flex flex-1 items-center justify-between">
|
||
<div class="flex items-center">
|
||
套装:
|
||
<div class="flex items-center justify-center gap-2px">
|
||
<template v-for="(suit, _) in suitList" :key="_">
|
||
<img
|
||
class="w-auto h-15px"
|
||
:src="getImageURL('equipment' + suit.imageUrl)"
|
||
:alt="suit.name"
|
||
:style="{
|
||
filter: curSuit == suit.value ? '' : 'grayscale(100%)',
|
||
}"
|
||
@click="curSuit = suit.value"
|
||
/>
|
||
</template>
|
||
</div>
|
||
</div>
|
||
<calc-button
|
||
icon="set"
|
||
title="装备触发条件"
|
||
@click="triggerVisible = !triggerVisible"
|
||
></calc-button>
|
||
</div>
|
||
</div>
|
||
<div class="overflow-y-auto gap-1 p-1 flex flex-col items-center flex-1 h-0">
|
||
<template v-for="item in equs" :key="item.name">
|
||
<template v-if="item.equs.length > 0">
|
||
<div class="item-head w-full">{{ item.name }}</div>
|
||
<div class="grid grid-cols-10 gap-4px w-316px">
|
||
<template
|
||
v-for="(equ, index) in item.equs"
|
||
:key="equ ? `${equ.id}-${equ.oathPos ?? 'equ'}-${index}` : `empty-${index}`"
|
||
>
|
||
<EquipmentIcon :inactive="!isActive(equ)" :equipment="equ" @click="chooseEqu(equ)" />
|
||
</template>
|
||
</div>
|
||
</template>
|
||
</template>
|
||
</div>
|
||
</div>
|
||
<div class="px-5px flex flex-col">
|
||
<!-- 基础信息 -->
|
||
<div
|
||
class="flex flex-col overflow-hidden bg-black"
|
||
:class="!hideBase ? '' : 'mb-4px'"
|
||
v-if="curEquInfo"
|
||
>
|
||
<div class="item-head" @click="hideBase = !hideBase">
|
||
基础信息{{ hideBase ? ' (点击显示)' : '(点击隐藏)' }}
|
||
</div>
|
||
<div v-show="!hideBase" class="overflow-y-auto overflow-x-hidden bg-black w-240px">
|
||
<Info v-if="curEquInfo" :equipment="curEquInfo" />
|
||
</div>
|
||
</div>
|
||
<!-- 套装信息 -->
|
||
<div
|
||
class="flex flex-col overflow-hidden bg-black"
|
||
:class="!hideSuit ? 'flex-1' : 'mb-4px'"
|
||
v-if="curSuitInfo"
|
||
>
|
||
<div class="item-head" @click="hideSuit = !hideSuit">
|
||
套装信息{{ hideSuit ? ' (点击显示)' : '(点击隐藏)' }}
|
||
</div>
|
||
<template v-if="!hideSuit">
|
||
<div class="flex bg-#191918 items-center justify-center gap-2px p-5px">
|
||
<calc-button
|
||
:disabled="raritiyList.findIndex((rarity) => rarity === curSuitLv.rarity) <= 0"
|
||
icon="min-little"
|
||
@click="changeSuitLv('preRarity')"
|
||
></calc-button>
|
||
<calc-button
|
||
icon="reduce-little"
|
||
:disabled="
|
||
raritiyList.findIndex((rarity) => rarity === curSuitLv.rarity) <= 0 &&
|
||
curSuitLv.lv <= 1
|
||
"
|
||
@click="changeSuitLv('preLv')"
|
||
></calc-button>
|
||
<div class="flex px-20px gap-x-10px" :class="rarityClass(curSuitLv.rarity)">
|
||
<span>{{ curSuitLv.rarity }}</span>
|
||
<span>{{ formatLv(curSuitLv.lv, curSuitLv.rarity) }}</span>
|
||
</div>
|
||
<calc-button
|
||
:disabled="
|
||
raritiyList.findIndex((rarity) => rarity === curSuitLv.rarity) >=
|
||
raritiyList.length - 1
|
||
"
|
||
@click="changeSuitLv('nextLv')"
|
||
icon="increase-little"
|
||
></calc-button>
|
||
<calc-button
|
||
:disabled="
|
||
raritiyList.findIndex((rarity) => rarity === curSuitLv.rarity) >=
|
||
raritiyList.length - 1
|
||
"
|
||
@click="changeSuitLv('nextRarity')"
|
||
icon="max-little"
|
||
></calc-button>
|
||
</div>
|
||
<div
|
||
class="w-80% m-auto h-1px bg-gradient-to-r from-[rgba(52,43,27,0.05)] via-[rgba(52,43,27,1)] to-[rgba(52,43,27,0.05)]"
|
||
></div>
|
||
<div class="flex-1 overflow-y-auto overflow-x-hidden bg-black w-240px">
|
||
<SuitInfo v-if="curSuitInfo" :suit="curSuitInfo" />
|
||
</div>
|
||
</template>
|
||
</div>
|
||
<div class="flex flex-col flex-1 overflow-hidden bg-black" v-if="curOathInfo">
|
||
<div class="item-head">誓约信息</div>
|
||
|
||
<div class="flex bg-#191918 items-center justify-center gap-2px p-5px">
|
||
<calc-button
|
||
:disabled="raritiyList.findIndex((rarity) => rarity === curOathSkillLv.rarity) <= 0"
|
||
icon="min-little"
|
||
@click="changeOathSkillLv('preRarity')"
|
||
></calc-button>
|
||
<calc-button
|
||
icon="reduce-little"
|
||
:disabled="
|
||
raritiyList.findIndex((rarity) => rarity === curOathSkillLv.rarity) <= 0 &&
|
||
curOathSkillLv.lv <= 1
|
||
"
|
||
@click="changeOathSkillLv('preLv')"
|
||
></calc-button>
|
||
<div class="flex px-20px gap-x-10px" :class="rarityClass(curOathSkillLv.rarity)">
|
||
<span>{{ curOathSkillLv.rarity }}</span>
|
||
<span>{{ formatLv(curOathSkillLv.lv, curOathSkillLv.rarity) }}</span>
|
||
</div>
|
||
<calc-button
|
||
:disabled="
|
||
raritiyList.findIndex((rarity) => rarity === curOathSkillLv.rarity) >=
|
||
raritiyList.length - 1
|
||
"
|
||
@click="changeOathSkillLv('nextLv')"
|
||
icon="increase-little"
|
||
></calc-button>
|
||
<calc-button
|
||
:disabled="
|
||
raritiyList.findIndex((rarity) => rarity === curOathSkillLv.rarity) >=
|
||
raritiyList.length - 1
|
||
"
|
||
@click="changeOathSkillLv('nextRarity')"
|
||
icon="max-little"
|
||
></calc-button>
|
||
</div>
|
||
|
||
<!-- 技能信息 -->
|
||
<div class="flex items-center justify-center py-5px">
|
||
<template v-for="skill in curOathInfo.skills" :key="skill.name">
|
||
<div
|
||
class="flex-1 flex flex-col items-center justify-center"
|
||
:class="{ unActive: skill.skillId != oathSkillId }"
|
||
@click="oathSkillId = skill.skillId"
|
||
>
|
||
<img class="w-40px h-40px" :src="getImageURL(skill.icon)" :alt="skill.name" />
|
||
<div class="text-#DED29A">{{ skill.name }}</div>
|
||
</div>
|
||
</template>
|
||
</div>
|
||
<div
|
||
class="w-80% m-auto h-1px bg-gradient-to-r from-[rgba(52,43,27,0.05)] via-[rgba(52,43,27,1)] to-[rgba(52,43,27,0.05)]"
|
||
></div>
|
||
<div class="flex-1 overflow-y-auto overflow-x-hidden bg-black w-240px">
|
||
<SuitInfo v-if="curOathSkillInfo" :suit="curOathSkillInfo" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<script lang="ts" setup>
|
||
import { useConfigStore, useInfoStore } from '@/stores'
|
||
import PartSelect from '@/components/dnf/Equipment/PartSelect/index.vue'
|
||
import EquipmentRaritySelect from '@/components/dnf/Equipment/RaritySelect/index.vue'
|
||
import { getImageURL } from '@/utils/images'
|
||
import { rarityClass } from '@/utils'
|
||
import type { IEquipment } from '@/api/info/type'
|
||
import EquipmentIcon from '@/components/dnf/Equipment/Icon/index.vue'
|
||
import Info from '@/components/dnf/Equipment/Info/index.vue'
|
||
import SuitInfo from '@/components/dnf/Equipment/SuitInfo/index.vue'
|
||
import { formatEqu, formatOath } from './formatData'
|
||
import options from './components/options.vue'
|
||
|
||
// const props = defineProps<{
|
||
// alter: string
|
||
// }>()
|
||
|
||
const infoStore = useInfoStore()
|
||
const type = ref('equ')
|
||
const curRarity = ref('')
|
||
const curSuit = ref(16203)
|
||
const curEquId = ref()
|
||
const curSuitLv = ref({
|
||
rarity: '太初',
|
||
lv: 1,
|
||
})
|
||
const curOathSkillLv = ref({
|
||
rarity: '史诗',
|
||
lv: 1,
|
||
})
|
||
const triggerVisible = ref(false)
|
||
|
||
const hideBase = ref(false)
|
||
const hideSuit = ref(false)
|
||
const oathSkillId = ref('1')
|
||
|
||
const raritiyList = ['稀有', '神器', '传说', '史诗', '太初']
|
||
|
||
const formatLv = (number: number, raritiy?: string) => {
|
||
if (raritiy == '太初') return ''
|
||
const greekNumerals = ['Ι', 'ΙΙ', 'ΙΙΙ', 'ΙV', 'V', 'VΙ', 'VΙΙ', 'VΙΙΙ', 'ΙX', 'X']
|
||
return greekNumerals[number - 1] || number.toString()
|
||
}
|
||
|
||
const changeSuitLv = (
|
||
type: 'preRarity' | 'nextRarity' | 'preLv' | 'nextLv',
|
||
resetLv: boolean = true,
|
||
) => {
|
||
if (type == 'preRarity') {
|
||
const index = raritiyList.findIndex((a) => a == curSuitLv.value.rarity)
|
||
if (index > 0) {
|
||
curSuitLv.value.rarity = raritiyList[index - 1]
|
||
curSuitLv.value.lv = resetLv ? 1 : 5
|
||
return
|
||
}
|
||
} else if (type == 'nextRarity') {
|
||
const index = raritiyList.findIndex((a) => a == curSuitLv.value.rarity)
|
||
if (index < raritiyList.length - 1) {
|
||
curSuitLv.value.rarity = raritiyList[index + 1]
|
||
curSuitLv.value.lv = 1
|
||
return
|
||
}
|
||
} else if (type == 'preLv') {
|
||
if (curSuitLv.value.lv > 1) {
|
||
curSuitLv.value.lv--
|
||
return
|
||
} else {
|
||
changeSuitLv('preRarity', false)
|
||
}
|
||
} else if (type == 'nextLv') {
|
||
if (curSuitLv.value.lv < 5) {
|
||
curSuitLv.value.lv++
|
||
return
|
||
} else {
|
||
changeSuitLv('nextRarity')
|
||
}
|
||
}
|
||
}
|
||
|
||
const changeOathSkillLv = (
|
||
type: 'preRarity' | 'nextRarity' | 'preLv' | 'nextLv',
|
||
resetLv: boolean = true,
|
||
) => {
|
||
if (type == 'preRarity') {
|
||
const index = raritiyList.findIndex((a) => a == curOathSkillLv.value.rarity)
|
||
if (index > 0) {
|
||
curOathSkillLv.value.rarity = raritiyList[index - 1]
|
||
curOathSkillLv.value.lv = resetLv ? 1 : 5
|
||
return
|
||
}
|
||
} else if (type == 'nextRarity') {
|
||
const index = raritiyList.findIndex((a) => a == curOathSkillLv.value.rarity)
|
||
if (index < raritiyList.length - 1) {
|
||
curOathSkillLv.value.rarity = raritiyList[index + 1]
|
||
curOathSkillLv.value.lv = 1
|
||
return
|
||
}
|
||
} else if (type == 'preLv') {
|
||
if (curOathSkillLv.value.lv > 1) {
|
||
curOathSkillLv.value.lv--
|
||
return
|
||
} else {
|
||
changeOathSkillLv('preRarity', false)
|
||
}
|
||
} else if (type == 'nextLv') {
|
||
if (curOathSkillLv.value.lv < 5) {
|
||
curOathSkillLv.value.lv++
|
||
return
|
||
} else {
|
||
changeOathSkillLv('nextRarity')
|
||
}
|
||
}
|
||
}
|
||
|
||
const choose_part = ref<string[]>([])
|
||
|
||
const curEquInfo = computed(() => {
|
||
if (type.value == 'equ') {
|
||
return infoStore.equips.find((a) => a.id == curEquId.value)
|
||
} else {
|
||
return infoStore.oaths.find((a) => a.id == curEquId.value)
|
||
}
|
||
})
|
||
|
||
const curSuitInfo = computed(() => {
|
||
if (curEquInfo.value?.suit.length != 1) {
|
||
return undefined
|
||
}
|
||
return infoStore.suits.find(
|
||
(a) =>
|
||
a.suitId.toString() == curEquInfo.value?.suit[0] &&
|
||
a.rarity == curSuitLv.value.rarity &&
|
||
a.level == curSuitLv.value.lv,
|
||
)
|
||
})
|
||
|
||
const curOathInfo = computed(() => {
|
||
if (curEquInfo.value?.suit.length != 1 || curEquInfo.value?.oathPos == undefined) {
|
||
return undefined
|
||
}
|
||
return infoStore.oathSkills?.[curEquInfo.value?.suit[0]]
|
||
})
|
||
|
||
const curOathSkillInfo = asyncComputed(async () => {
|
||
if (!curOathInfo.value || !curEquInfo.value?.suit[0]) {
|
||
return undefined
|
||
}
|
||
const res = await infoStore.getOathInfo(
|
||
curEquInfo.value?.suit[0],
|
||
oathSkillId.value,
|
||
curOathSkillLv.value.rarity,
|
||
curOathSkillLv.value.lv,
|
||
)
|
||
return res
|
||
})
|
||
|
||
// const curOathSkillInfo = computed(() => {
|
||
// const res = curOathSkillLvs.value
|
||
// if (!res) {
|
||
// return undefined
|
||
// }
|
||
// // console.log(curEquInfo.value?.suit[0])
|
||
// return {
|
||
// ...res,
|
||
// SkillAttack: parseFloat(res.SkillAttack.toString().split(',')[curOathSkillLv.value.lv - 1]),
|
||
// Buffer: parseFloat(res.Buffer.toString().split(',')[curOathSkillLv.value.lv - 1]),
|
||
// point: parseFloat(res.point.toString().split(',')[curOathSkillLv.value.lv - 1]),
|
||
// }
|
||
// })
|
||
|
||
const chooseCategory = (cat: string) => {
|
||
type.value = cat
|
||
if (type.value == 'oath' && curSuit.value == -1) {
|
||
curSuit.value = 16203
|
||
}
|
||
}
|
||
|
||
const configStore = useConfigStore()
|
||
|
||
const suitList = computed(() => {
|
||
const uniqueSuits = new Map<number, { name: string; value: number; imageUrl: string }>()
|
||
infoStore.suits.forEach((a) => {
|
||
if (!uniqueSuits.has(a.suitId)) {
|
||
uniqueSuits.set(a.suitId, {
|
||
name: a.suitName,
|
||
value: a.suitId,
|
||
imageUrl: a.imageUrl.replace('/suit/', '/suit/icon/'),
|
||
})
|
||
}
|
||
})
|
||
const res = Array.from(uniqueSuits.values())
|
||
if (type.value == 'equ') res.push({ name: '通宝', value: -1, imageUrl: '/suit/icon/-1.png' })
|
||
return res
|
||
})
|
||
|
||
const equs = computed(() => {
|
||
// 筛选出装备
|
||
const total = (type.value == 'equ' ? infoStore.equips : infoStore.oaths).filter(
|
||
(a) =>
|
||
(!curRarity.value || a.rarity === curRarity.value) &&
|
||
(choose_part.value.length === 0 ||
|
||
choose_part.value.includes(a.itemDetailType || a.itemType)) &&
|
||
(a.suit.length == 0 ||
|
||
(curSuit.value == -1 && a.suit.length > 1 && type.value == 'equ') ||
|
||
(a.suit.length > 1 && type.value == 'oath') ||
|
||
(a.suit.includes(curSuit.value.toString()) && a.suit.length === 1)),
|
||
)
|
||
|
||
if (type.value == 'equ') {
|
||
return formatEqu(
|
||
total,
|
||
infoStore.infos?.subweapons,
|
||
suitList.value.find((a) => a.value == curSuit.value)?.name,
|
||
)
|
||
} else {
|
||
return formatOath(
|
||
total as unknown as IEquipment[],
|
||
suitList.value.find((a) => a.value == curSuit.value),
|
||
)
|
||
}
|
||
})
|
||
|
||
const isActive = computed(() => {
|
||
return (item?: IEquipment) => {
|
||
if (!item) return false
|
||
if (type.value == 'equ') {
|
||
if (item.itemType.includes('武器')) {
|
||
return configStore.config.equips[item.itemType].id == item.id
|
||
} else {
|
||
return configStore.config.equips[item.itemDetailType].id == item.id
|
||
}
|
||
} else {
|
||
return configStore.config.oaths[item.oathPos].id == item.id
|
||
}
|
||
}
|
||
})
|
||
|
||
const chooseEqu = (item?: IEquipment) => {
|
||
if (!item) return
|
||
curEquId.value = item.id
|
||
const target =
|
||
type.value === 'equ'
|
||
? configStore.config.equips[
|
||
item.itemType.includes('武器') ? item.itemType : item.itemDetailType
|
||
]
|
||
: configStore.config.oaths[item.oathPos]
|
||
if (isActive.value(item) && type.value == 'oath') {
|
||
// 誓约和星蕴石 有默认穿戴
|
||
target['id'] = item.oathPos == '11' ? '2000500' : '2000101'
|
||
} else {
|
||
target['id'] = isActive.value(item) ? '' : item.id
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.active {
|
||
color: #ccc088;
|
||
position: relative;
|
||
|
||
&::before {
|
||
content: '';
|
||
position: absolute;
|
||
width: 60px;
|
||
height: 15px;
|
||
opacity: 0.35;
|
||
background: #bf8d20;
|
||
filter: blur(7px);
|
||
z-index: 2;
|
||
}
|
||
|
||
&::after {
|
||
content: '';
|
||
position: absolute;
|
||
background: url('@/assets/img/active.png') no-repeat;
|
||
width: 148px;
|
||
height: 16px;
|
||
bottom: 2px;
|
||
transform: translate(0, 50%);
|
||
}
|
||
}
|
||
|
||
.item-head {
|
||
background: linear-gradient(#2b2817, #171407);
|
||
border-top: 1px solid #423d2c;
|
||
border-bottom: 1px solid #211d15;
|
||
text-align: center;
|
||
}
|
||
|
||
.unActive {
|
||
filter: grayscale(100%);
|
||
}
|
||
</style>
|