Files
dcalc/frontend/src/pages/Character/EquipmentDictionary/Index.vue
T

327 lines
10 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="w-340px 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('stone')"
:class="{ active: type === 'stone' }"
>
融合石
</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="flex flex-wrap gap-4px justify-around w-full">
<template v-for="(equ, _) in item.equs" :key="_">
<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" v-if="curEquInfo">
<div class="item-head">基础信息</div>
<div class="flex-1 overflow-y-auto overflow-x-hidden bg-black w-240px">
<Info v-if="curEquInfo" :equipment="curEquInfo" />
</div>
</div>
<div class="flex flex-col flex-1 overflow-hidden bg-black" v-if="curSuitInfo">
<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 === 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>
</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, formatStone } 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 triggerVisible = ref(false)
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 choose_part = ref<string[]>([])
const curEquInfo = computed(() => {
if (type.value == 'equ') {
return infoStore.equips.find((a) => a.id == curEquId.value)
} else {
return infoStore.stones.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 chooseCategory = (cat: string) => {
type.value = cat
if (type.value == 'stone' && 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.stones).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 == 'stone') ||
(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 formatStone(total, suitList.value.find((a) => a.value == curSuit.value)?.name)
}
})
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.equips[item.itemDetailType].fusion == 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.equips[item.itemDetailType]
target[type.value === 'equ' ? 'id' : 'fusion'] = 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;
}
</style>