This commit is contained in:
2025-04-14 00:46:49 +08:00
parent 8838ea846b
commit e9fa639192
28 changed files with 443 additions and 12 deletions
+1
View File
@@ -100,6 +100,7 @@ class CharacterProperty(ABC):
角色类型: str
职业: str
武器选项: list[str]
副武器选项: list[str]
输出类型选项: list[str]
防具精通属性: list[str]
输出类型: str
+3 -1
View File
@@ -142,6 +142,7 @@ class Character(CharacterProperty):
角色类型: str = ''
职业: str = ''
武器选项: list[str] = []
副武器选项: list[str] = []
输出类型选项: list[str] = []
防具精通属性: list[str] = []
@@ -417,6 +418,7 @@ class Character(CharacterProperty):
info['equVersion'] = self.equVersion
info['name'] = self.nameCN
info['weapons'] = self.武器选项
info['subweapons'] = self.副武器选项
skillInfo = []
skill_clothes = []
platinum = []
@@ -462,7 +464,7 @@ class Character(CharacterProperty):
info['stones'] = stones
key = '辅助' if self.buffer else '输出'
info['enchants'] = list(filter(lambda x: key in x["categorize"], equInfos.enchants))
info['emblems'] = list(filter(lambda x: key in x["categorize"], equInfos.emblems))
info['emblems'] = equInfos.emblems
info['avatar'] = equInfos.funs.get_dress_list(skill_clothes)
info['jades'] = equInfos.jades
info['sundry'] = equInfos.funs.sundryList
@@ -449,6 +449,7 @@ class classChange(Character):
# 用来筛CP武器的
# self.转职 = '弹药专家(女)'
self.武器选项 = ['光剑', '巨剑', '钝器', '太刀', '短剑']
self.副武器选项 = ['光剑']
self.输出类型选项 = ['物理百分比']
self.输出类型 = '物理百分比'
self.防具精通属性 = ['力量']
+17
View File
@@ -2888,6 +2888,8 @@ def equ_182(char: CharacterProperty):
所有速度+15%
"""
char.equ_effect.append(EquEffect(name='流星念珠', icon='/equipment/icon/weapon/priest/rosary/00196.png', cd=10,data=15000))
char.SetStatus(SpeedM=0.15,SpeedA=0.15,SpeedR=0.15)
if char.buffer:
char.AddSkillLv(1,100,2)
char.BuffSkill.lv += 3
@@ -2907,6 +2909,8 @@ def equ_183(char: CharacterProperty):
所有速度+20%
"""
char.equ_effect.append(EquEffect(name='流星念珠', icon='/equipment/icon/weapon/priest/rosary/00197.png', cd=5,data=15000))
char.SetStatus(SpeedM=0.15,SpeedA=0.15,SpeedR=0.15)
if char.buffer:
char.AddSkillLv(1,100,2)
char.BuffSkill.lv += 3
@@ -2926,6 +2930,7 @@ def equ_184(char: CharacterProperty):
所有速度+30%
"""
char.equ_effect.append(EquEffect(name='流星念珠', icon='/equipment/icon/weapon/priest/rosary/00198.png', cd=20,data=340200))
if char.buffer:
char.AddSkillLv(1,100,2)
char.BuffSkill.lv += 3
@@ -3021,6 +3026,7 @@ def equ_190(char: CharacterProperty):
-行星破坏伤害量:113400%
-冷却时间:40秒
"""
char.equ_effect.append(EquEffect(name='行星破坏', icon='/equipment/skill/40.png', cd=40,data=340200))
if char.buffer:
char.AddSkillLv(1,100,2)
char.BuffSkill.lv += 3
@@ -3041,6 +3047,7 @@ def equ_191(char: CharacterProperty):
-行星破坏伤害量:226800%
-冷却时间:40秒
"""
char.equ_effect.append(EquEffect(name='行星破坏', icon='/equipment/skill/40.png', cd=40,data=340200))
if char.buffer:
char.AddSkillLv(1,100,2)
char.BuffSkill.lv += 3
@@ -3061,6 +3068,7 @@ def equ_192(char: CharacterProperty):
-行星破坏伤害量:340200%
-冷却时间:40秒
"""
char.equ_effect.append(EquEffect(name='行星破坏', icon='/equipment/skill/40.png', cd=40,data=340200))
if char.buffer:
char.AddSkillLv(1,100,2)
char.BuffSkill.lv += 3
@@ -3149,6 +3157,8 @@ def equ_198(char: CharacterProperty):
攻击时,向前方施放怒击。(冷却时间1秒)
-怒击伤害量:6000%
"""
char.SetSkillCD(1,100,0.2)
char.equ_effect.append(EquEffect(name='威严怒击', icon='/equipment/icon/weapon/priest/totem/00280.png', cd=1,data=6000))
if char.buffer:
char.AddSkillLv(1,100,2)
char.BuffSkill.lv += 3
@@ -3171,6 +3181,9 @@ def equ_199(char: CharacterProperty):
施放技能时,向前方施放猛烈的连击。(冷却时间5秒)
-猛烈连击伤害量:32400%
"""
char.equ_effect.append(EquEffect(name='威严怒击', icon='/equipment/icon/weapon/priest/totem/00281.png', cd=1,data=6000))
char.equ_effect.append(EquEffect(name='威严猛击', icon='/equipment/icon/weapon/priest/totem/00281.png', cd=5,data=32400))
char.SetSkillCD(1,100,0.2)
if char.buffer:
char.AddSkillLv(1,100,2)
char.BuffSkill.lv += 3
@@ -3197,6 +3210,10 @@ def equ_200(char: CharacterProperty):
施放无色小晶块技能时,发动威严痛击。(冷却时间10秒)
-威严痛击伤害量:90000%
"""
char.equ_effect.append(EquEffect(name='威严怒击', icon='/equipment/icon/weapon/priest/totem/00282.png', cd=1,data=6000))
char.equ_effect.append(EquEffect(name='威严猛击', icon='/equipment/icon/weapon/priest/totem/00282.png', cd=5,data=32400))
char.equ_effect.append(EquEffect(name='威严痛击', icon='/equipment/icon/weapon/priest/totem/00282.png', cd=5,data=90000))
char.SetSkillCD(1,100,0.2)
if char.buffer:
char.AddSkillLv(1,100,2)
char.BuffSkill.lv += 3
+1 -1
View File
@@ -74,7 +74,7 @@ def jade_14(char: CharacterProperty = {}, value=0):
def jade_15(char: CharacterProperty = {}, value=0):
char.BuffSkill.ATKPLUS += value
char.SetStatus(Buffer=value/1000)
char.SetStatus(BufferP=value/200)
def jade_16(char: CharacterProperty = {}, value=0):
char.BuffSkill.ATKRatio *= 1 + value/100
Binary file not shown.
+1
View File
@@ -30,6 +30,7 @@ export interface ICharacterInfo {
enchants: IEnchantingInfo[]
emblems: IEnchantingInfo[]
weapons: string[]
subweapons: string[]
skills: ISkill[]
suits: ISuit[]
avatar: Record<string, IAvatarInfo[]>
@@ -0,0 +1,124 @@
<template>
<calc-cascader class="!h-5 flex-1" v-model="selected" :items="items" placeholder="请输入名称搜索"></calc-cascader>
</template>
<script lang="ts" setup>
import type { TreeNode } from "@/components/calc/tree/types"
import { useInfoStore } from "@/stores"
import { syncRef, useVModel } from "@vueuse/core"
const props = defineProps({
partList: {
type: Array as () => String[],
default: () => [],
},
})
const armor_parts = ['上衣', '头肩', '下装', '鞋', '腰带']
const jewel_parts = ['项链', '戒指', '手镯']
const special_parts = ['辅助装备', '魔法石', '耳环']
const else_parts = ['称号', '宠物']
const emit = defineEmits([])
const choose_part = useVModel(props, "partList",emit,{passive:true})
const selected = ref("")
const infoStore = useInfoStore()
const items = computed<TreeNode[]>(() => {
return [
{
label: '全部类别',
value: '',
onSelect() {
choose_part.value = []
},
},
{
label: '武器',
value: '武器',
onSelect() {
choose_part.value = infoStore.infos?.weapons ?? []
},
children: infoStore.infos?.weapons.map((r) => {
return {
label: r,
value: r,
onSelect() {
choose_part.value = [r]
},
}
}),
},
{
label: '防具',
value: '防具',
onSelect() {
choose_part.value = [...armor_parts]
},
children: armor_parts.map((part) => {
return {
label: part,
value: part,
onSelect() {
choose_part.value = [part]
},
}
}),
},
{
label: '首饰',
value: '首饰',
onSelect() {
choose_part.value = [...jewel_parts]
},
children: jewel_parts.map((part) => {
return {
label: part,
value: part,
onSelect() {
choose_part.value = [part]
},
}
}),
},
{
label: '特殊装备',
value: '特殊装备',
onSelect() {
choose_part.value = [...special_parts]
},
children: special_parts.map((part) => {
return {
label: part,
value: part,
onSelect() {
choose_part.value = [part]
},
}
}),
},
{
label: '其它',
value: '其它',
onSelect() {
choose_part.value = [...else_parts]
},
children: else_parts.map((part) => {
return {
label: part,
value: part,
onSelect() {
choose_part.value = [part]
},
}
}),
},
]
})
</script>
@@ -0,0 +1,2 @@
<template></template>
<script lang="ts"></script>
@@ -0,0 +1,18 @@
<template>
<div>
<!-- 头部 选择是装备还是融合石 -->
<div class="flex">
<div :class="{active: category === 'equ'}">装备</div>
|
<div :class="{active: category === 'stone'}">融合石</div>
</div>
<!-- 筛选条件 -->
<!-- 装备列表 -->
</div>
</template>
<script lang="ts">
const category = ref("equ")
</script>
@@ -0,0 +1,265 @@
<template>
<div class="w-330px bg-black">
<!-- 头部 选择是装备还是融合石 -->
<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">
<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">
<div class="flex items-center">
套装:
<template v-for="(suit, _) in suits" :key="_">
<div class="flex items-center justify-center gap-2">
<img
class="w-20px h-auto object-cover"
:src="getImageURL('equipment' + suit.imageUrl)"
:alt="suit.name"
:style="{
filter: curSuit == suit.value ? '' : 'grayscale(100%)',
}"
@click="curSuit = suit.value"
/>
</div>
</template>
</div>
</div>
<template v-for="item in equs" :key="item.name">
<template v-if="item.equs.length > 0">
<div class="item-head">{{ item.name }}</div>
<div class="flex flex-wrap gap-4px content-start w-full">
<template v-for="(weapon, _) in item.equs" :key="_">
<EquipmentIcon :equipment="weapon" />
</template>
</div>
</template>
</template>
</div>
<!-- 筛选条件 -->
<!-- 装备列表 -->
</div>
</template>
<script lang="ts" setup>
import { 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 type { IEquipment } from '@/api/info/type'
import EquipmentIcon from '@/components/dnf/Equipment/Icon/index.vue'
const infoStore = useInfoStore()
const type = ref('equ')
const curRarity = ref('')
const curSuit = ref(16203)
const choose_part = ref<string[]>([])
const chooseCategory = (cat: string) => {
type.value = cat
}
const rowCount = 10
const suits = 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.name,
value: a.suitId,
imageUrl: a.imageUrl.replace('/suit', '/suit/little'),
})
}
})
const res = Array.from(uniqueSuits.values())
res.push({
name: '通宝',
value: -1,
imageUrl: '/suit/little/-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) ||
(a.suit.includes(curSuit.value.toString()) && a.suit.length === 1)),
)
// 武器
const item_weapon = total.filter((a) => a.itemType == '武器') ?? []
const weapons: (IEquipment | undefined)[] = []
if (item_weapon.length > 0) {
Array.from(new Set(item_weapon.map((item) => item.rarity))).forEach((rarity) => {
const weapon = item_weapon
.filter((item) => item.rarity === rarity)
.sort((a, b) => {
if (a.categorize == b.categorize) {
return a.itemDetailType.localeCompare(b.itemDetailType)
}
return b.categorize.localeCompare(a.categorize)
})
weapons.push(...weapon)
const remind = weapons.length % rowCount
remind > 0 && weapons.push(...Array(rowCount - remind).fill(undefined))
})
}
// # region 副武器
const subWeapons: (IEquipment | undefined)[] = []
const item_sub_weapon = (
total.filter((a) => infoStore.infos?.subweapons?.includes(a.itemDetailType)) ?? []
).sort((a, b) => {
if (a.categorize == b.categorize) {
return a.itemDetailType.localeCompare(b.itemDetailType)
}
return b.categorize.localeCompare(a.categorize)
})
if (item_sub_weapon.length > 0) {
subWeapons.push(
...item_sub_weapon,
...Array(rowCount - (item_sub_weapon.length % rowCount)).fill(undefined),
)
}
// # endregion
// 秘宝
const item_treasure = total.filter((equip) => equip.categorize.includes('秘宝'))
const treasures: (IEquipment | undefined)[] = []
if (item_treasure.length > 0) {
treasures.push(
...item_treasure,
...Array(rowCount - (item_treasure.length % rowCount)).fill(undefined),
)
}
// 套装
const item_suits = total.filter(
(equip) => equip.categorize.includes('套装') || equip.categorize.includes('通宝'),
)
const suits: (IEquipment | undefined)[] = []
const raritiyList = Array.from(new Set(item_suits.map((item) => item.rarity)))
raritiyList.forEach((rarity) => {
const armor = item_suits.filter((item) => item.rarity === rarity && item.itemType === '防具')
if (armor.length > 0) {
suits.push(...armor, undefined)
}
const special = item_suits.filter(
(item) => item.rarity === rarity && item.itemType === '特殊装备',
)
if (special.length > 0) {
suits.push(...special)
if (suits.length % rowCount > 0) {
suits.push(...Array(rowCount - (suits.length % rowCount)).fill(undefined))
}
}
const jewelry = item_suits.filter((item) => item.rarity === rarity && item.itemType === '首饰')
const jewelryNormal = jewelry.filter((a) => !a.name.includes('黑牙')) ?? []
const jewelryHY = jewelry.filter((a) => a.name.includes('黑牙')) ?? []
if (jewelry.length > 0) {
suits.push(
...Array(3 - jewelryHY.length + 2).fill(undefined),
...jewelryHY,
undefined,
...jewelryNormal,
)
suits.push(...Array(rowCount - (suits.length % rowCount)).fill(undefined))
}
})
// 称号
const item_title = total.filter((equip) => equip.itemDetailType == '称号')
const title: (IEquipment | undefined)[] = []
if (item_title.length > 0) {
title.push(...item_title, ...Array(rowCount - (item_title.length % rowCount)).fill(undefined))
}
// 宠物
const item_pets = total.filter((equip) => equip.itemDetailType == '宠物')
const pet: (IEquipment | undefined)[] = []
if (item_pets.length > 0) {
pet.push(...item_pets, ...Array(rowCount - (item_pets.length % rowCount)).fill(undefined))
}
// 称号
return [
{
name: '武器',
equs: weapons,
},
{
name: '副武器',
equs: subWeapons,
},
{
name: '秘宝',
equs: treasures,
},
{
name: '套装',
equs: suits,
},
{
name: '称号',
equs: title,
},
{
name: '宠物',
equs: pet,
},
]
})
</script>
<style lang="scss" scoped>
.active {
color: #ccc088;
&::after {
content: '';
position: absolute;
width: 60px;
height: 15px;
opacity: 0.35;
background: #bf8d20;
filter: blur(7px);
}
}
.item-head {
background: linear-gradient(#2b2817, #171407);
border-top: 1px solid #423d2c;
border-bottom: 1px solid #211d15;
text-align: center;
}
</style>
+1
View File
@@ -2,6 +2,7 @@
<div class="w-100% h-100% main flex" :class="infoStore.infos?.alter">
<div class="header">
<calc-tabs route>
<calc-tab :value="`/character/EquipmentDictionary/${props.alter}`">装备设置</calc-tab>
<calc-tab :value="`/character/equipment/${props.alter}`">装备设置</calc-tab>
<calc-tab :value="`/character/skill/${props.alter}`">技能设置</calc-tab>
<calc-tab :value="`/character/forge/${props.alter}`">打造设置</calc-tab>
+2 -9
View File
@@ -13,13 +13,6 @@ function job_icon(child: IAlterInfo) {
export default defineComponent(async () => {
const ignores = ['empty']
const zoom = computed(() =>
/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(
navigator.userAgent || navigator.vendor || (window as any).opera,
)
? 1
: Math.max(Math.min((window.innerHeight * 0.8) / 750, (window.innerWidth * 0.85) / 1100), 1),
)
// 获取角色相关信息,判定是否开放
function choose_job(child: IAlterInfo) {
@@ -51,7 +44,7 @@ export default defineComponent(async () => {
return () => (
<Fragment>
<div class="bg-no-repeat h-auto min-h-full pt-8 pb-12 pl-4" style={`zoom:${zoom.value};background-image: url('${getImageURL('home.jpg')}');background-size: 100% 100%;`}>
<div class="bg-no-repeat h-auto min-h-full pt-8 pb-12 pl-4" style={`background-image: url('${getImageURL('home.jpg')}');background-size: 100% 100%;`}>
{renderList(adventure, (job) => (
<div class="flex flex-row">
<div
@@ -100,7 +93,7 @@ export default defineComponent(async () => {
<div
class="flex flex-col"
style={`position: absolute;top: ${30 + 82 * 0}px;left: 775px;width: 160px;height: 150px;zoom:${zoom.value}`}
style={`position: absolute;top: ${30 + 82 * 0}px;left: 775px;width: 160px;height: 150px;`}
>
<div
class="w-70px h-50px bg-no-repeat"
+6
View File
@@ -18,6 +18,12 @@ const routes: RouteRecordRaw[] = [
name:'character',
component: (() => import('@/pages/Character/Index.vue')),
children: [
{
path: '/character/EquipmentDictionary/:alter',
name: 'EquipmentDictionary',
props: true,
component: (() => import('@/pages/Character/EquipmentDictionary/Index.vue')),
},
{
path: '/character/equipment/:alter',
name: 'equipment',
+1 -1
View File
@@ -39,7 +39,7 @@ body,
* {
// font-family: "ArkPixel", "Consola", sans-serif;
font-family: "dcalc", "SimHei";
font-family: "dcalc", "SimSun";
// font-family: "STSong";
font-size: 12px;
text-shadow: 0 0 1px #000, 0 0 1px #000, 0 0 1px #000, 0 0 1px #000,
Binary file not shown.

After

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 325 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 325 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B