This commit is contained in:
2025-04-06 15:06:11 +08:00
parent 101a873322
commit eddc7f16b8
13 changed files with 241 additions and 103 deletions
+51 -40
View File
@@ -1,6 +1,7 @@
from functools import cache
import importlib
from typing import Any, Literal, Mapping, Union
from uuid import uuid1
from core.basic.property import CharacterInfo
from core.basic.skill import Skill
@@ -342,6 +343,10 @@ class Character:
"""
if element not in self.ElementDB:
raise ValueError(f'Invalid element: {element}')
if type == 0:
value = value * (1 + self.jade_effect.ElementIncrease)
if type == 1:
value = int(value * (1 + self.jade_effect.ElementIncrease))
self.ElementDB[element] += value
pass
@@ -371,14 +376,14 @@ class Character:
if min <= skill.learnLv <= max and skill.damage and skill.learnLv not in exclude:
skill.cdRecover += cd
def SetSkillRation(self, min=1, max=100, ratio=0 ,type = 0) -> None:
def SetSkillRation(self, min=1, max=100, ratio=0, type=0) -> None:
"""设置技能倍率 0 修改技能面板 1 不修改技能面板"""
for skill in self.skills:
if min <= skill.learnLv <= max and skill.damage:
if type == 0:
skill.skillRation *= (1 + ratio)
skill.skillRation *= 1 + ratio
else:
skill.skillDamage *= (1 + ratio)
skill.skillDamage *= 1 + ratio
def GetSkillByName(self, name) -> Skill:
"""通过技能名获取技能"""
@@ -402,12 +407,6 @@ class Character:
for key in info['equips']:
# 导入部位打造信息、装备信息、贴膜信息
self.charEquipInfo[key] = CharacterEquipInfo(info['equips'][key], self.equVersion, key)
"""辟邪玉"""
self.jadeInfo = {}
for key in info.get('jades', {}):
self.jadeInfo[key] = info['jades'][key]
"""时装"""
"""杂项"""
def getInfo(self):
"""返回到前端信息"""
@@ -422,7 +421,7 @@ class Character:
platinum = []
for skill in self.skills:
# 白金
if 15 <= skill.learnLv <= 70 and skill.learnLv not in [48,50]:
if 15 <= skill.learnLv <= 70 and skill.learnLv not in [48, 50]:
platinum.append(skill.name)
# 时装
if skill.learnLv <= 95:
@@ -462,17 +461,19 @@ class Character:
info['stones'] = stones
info['enchants'] = equInfos.enchants
info['emblems'] = equInfos.emblems
info["avatar"] = equInfos.funs.get_dress_list(skill_clothes)
info['avatar'] = equInfos.funs.get_dress_list(skill_clothes)
info['jades'] = equInfos.jades
for skill in platinum:
info['emblems'].append({
'id': skill,
'fame':232,
'position':["辅助装备", "魔法石"],
"detail": skill + " Lv+1" + " 四维 + 8",
"categorize": ["技能"],
"rarity": "白金",
})
info['emblems'].append(
{
'id': skill,
'fame': 232,
'position': ['辅助装备', '魔法石'],
'detail': skill + ' Lv+1' + ' 四维 + 8',
'categorize': ['技能'],
'rarity': '白金',
}
)
return info
def getBasicInos(self):
@@ -576,16 +577,18 @@ class Character:
suitList += equs.get_suit_info(suit, suitInfo[suit]['point'], 0)
# suits_effect += [i.id for i in equs.get_suit_info(suit, suitInfo[suit]['point'], 0)]
temp = suitList[-1]
res.append({
'id': temp.id,
'name': temp.name,
'rarity': temp.rarity,
'point': suitInfo[suit]['point'],
'count': suitInfo[suit]['count'],
'level': temp.level,
'imageUrl': temp.imageUrl,
'value': temp.value,
})
res.append(
{
'id': temp.id,
'name': temp.name,
'rarity': temp.rarity,
'point': suitInfo[suit]['point'],
'count': suitInfo[suit]['count'],
'level': temp.level,
'imageUrl': temp.imageUrl,
'value': temp.value,
}
)
suits_effect = [i.id for i in suitList]
for i in suits_effect:
func = equs.funs.suit_func_list.get(str(i), None)
@@ -600,7 +603,7 @@ class Character:
def calc_equs(self):
"""计算装备基础效果、附魔、贴膜"""
effects = get_equipment(self.equVersion).funs
for detail in [(item.equInfo,item.fusionInfo,item.enchant,item.emblem_0,item.emblem_1) for item in filter(lambda x: x.equInfo is not None, self.charEquipInfo.values())]:
for detail in [(item.equInfo, item.fusionInfo, item.enchant, item.emblem_0, item.emblem_1) for item in filter(lambda x: x.equInfo is not None, self.charEquipInfo.values())]:
equ = detail[0]
fusion = detail[1]
enchat = detail[2]
@@ -648,9 +651,9 @@ class Character:
def calc_avatar(self, avatar: dict):
"""计算时装效果"""
equ = get_equipment(self.equVersion)
dress = {key: value for key, value in avatar.items() if key in ['头发', '帽子', '脸部','胸部','上衣','腰带','下装','鞋']}
equ.funs.calc_dress_effect(dress,self)
avatarElse = {key: value for key, value in avatar.items() if key not in ['头发', '帽子', '脸部','胸部','上衣','腰带','下装','鞋']}
dress = {key: value for key, value in avatar.items() if key in ['头发', '帽子', '脸部', '胸部', '上衣', '腰带', '下装', '鞋']}
equ.funs.calc_dress_effect(dress, self)
avatarElse = {key: value for key, value in avatar.items() if key not in ['头发', '帽子', '脸部', '胸部', '上衣', '腰带', '下装', '鞋']}
for key in avatarElse:
value = avatarElse[key].get('enchant', None)
emblem_0 = avatarElse[key].get('emblem_0', None)
@@ -721,8 +724,14 @@ class Character:
pass
pass
def calc_jade(self,jade):
def calc_jade(self, jades):
"""计算辟邪玉效果"""
funs = get_equipment(self.equVersion).funs
for key in jades:
jade = jades[key]
fun = funs.jade_func_list.get(str(jade.get('id',0)), None)
if fun is not None:
fun(self,jade.get('value', 0))
pass
def calc(self, setInfo: dict[str, dict]):
@@ -799,10 +808,7 @@ class Character:
for attr in attrs:
temp = getattr(CharacterInfo, attr)
if attr.startswith('Atk'):
info.append({
'name':temp.name,
'value':temp.value(getattr(self, attr)*getattr(self, f'P{attr}'))}
)
info.append({'name': temp.name, 'value': temp.value(getattr(self, attr) * getattr(self, f'P{attr}'))})
pass
else:
info.append(
@@ -812,7 +818,12 @@ class Character:
}
)
pass
return {'skills': skillInfos, 'info': info,"suits": suit}
return {
'uuid': uuid1().hex,
'skills': skillInfos,
'info': info,
'suits': suit,
}
# 技能影响角色的属性,如属强、抗性等
def calc_damage_ration(self):
@@ -841,7 +852,7 @@ class Character:
# BUFF系数
ratio_5 = self.buff
# 技攻系数
ratio_6 = self.SkillAttack + self.jade_effect.SkillAttack
ratio_6 = self.SkillAttack *( self.jade_effect.SkillAttack + 1)
# 攻击强化
ratio_7 = 1 + self.Attack * (self.AttackP + self.jade_effect.AttackP)
# 防御系数,暂定145沙袋防御
+8 -2
View File
@@ -115,7 +115,10 @@ class Skill:
def _apply_association(self, type, old, new, data, skills, exceptSkills
):
if type.startswith('$*'):
value = (1 + data[new] / 100) / (1 + data[old] / 100)
if 'cdReduce' in type:
value = (1 - data[new] / 100) / (1 - data[old] / 100)
else:
value = (1 + data[new] / 100) / (1 + data[old] / 100)
eval(f'self.char.SetStatus({type[2:]}={value})')
elif type.startswith('$+'):
value = data[new] / 100 - data[old] / 100
@@ -132,7 +135,10 @@ class Skill:
def _update_skill_attribute(self,skill, type, old, new, data):
if type.startswith('*'):
setattr(skill, type[1:], getattr(skill, type[1:]) * (1 + data[new] / 100) / (1 + data[old] / 100))
if 'cdReduce' in type:
setattr(skill, type[1:], getattr(skill, type[1:]) * (1 - data[new] / 100) / (1 - data[old] / 100))
else:
setattr(skill, type[1:], getattr(skill, type[1:]) * (1 + data[new] / 100) / (1 + data[old] / 100))
elif type.startswith('+'):
setattr(skill, type[1:], getattr(skill, type[1:]) + data[new] / 100 - data[old] / 100)
@@ -172,6 +172,11 @@ class Skill9(ActiveSkill):
data0 = [0, 1034, 1200, 1364, 1528, 1693, 1857, 2021, 2187, 2352, 2516, 2682, 2846, 3010, 3175, 3339, 3505, 3671, 3835, 4000, 4164]# noqa: E501
hit0 = 1
def getSkillCD(self):
if self.char.charEquipInfo['武器'].equInfo.itemDetailType == '手弩':
return 0.115
return 0.14
# G-18C冰冻手雷 G-18C 빙결류탄
# https://api.neople.co.kr/df/skills/944b9aab492c15a8474f96947ceeb9e4/202edb928046f4fa6dedf6337377efd5?apikey=fdvit1Kj64EAJm0qfB3JEAD8FLExLDD0
class Skill10(ActiveSkill):
+9 -18
View File
@@ -2,26 +2,19 @@ from core.basic.character import Character
jade_func_list = {}
for i in range(0,20):
try:
if i not in jade_func_list.keys():
jade_func_list[i] = eval(f'jade_{i}')
except Exception:
pass
def jade_0(char: Character = {}, value=0):
pass
def jade_1(char: Character = {}, value=0):
char.SetStatus(SkillAttack=value/100)
char.jade_effect.SkillAttack += value/100
def jade_2(char: Character = {}, value=0):
char.SetStatus(AttackP=value/100)
char.jade_effect.AttackP += value/100
pass
def jade_3(char: Character = {}, value=0):
char.ElementIncrease += value/100
char.jade_effect.ElementIncrease += value/100
pass
def jade_4(char: Character = {}, value=0):
@@ -123,14 +116,12 @@ def jade_12(char: Character = {}, value=0):
# char.攻击速度增加(value/100)
# for i in range(26201, 26210):
# try:
# if i not in jade_func_list.keys():
# jade_func_list[i] = eval('jade_{}'.format(i))
# sorted(jade_func_list, key=lambda x: eval(x(text=True))[6])
# except Exception:
# pass
for i in range(0,20):
try:
if str(i) not in jade_func_list.keys():
jade_func_list[str(i)] = eval(f'jade_{i}')
except Exception:
pass
# def get_jadefunc_by_id(id):
# return jade_func_list.get(int(id), jade_26000)
Binary file not shown.
+1
View File
@@ -1,4 +1,5 @@
export interface IResult {
uuid: string
skills: IResultSkill[]
info:IResultUserInfo[]
suits:IResultSuit[]
@@ -130,7 +130,7 @@ export default defineComponent({
return (
<>
<div class="h-150px flex justify-center items-center">
<EquList v-model:part={part.value} withBg={false} /></div>
<EquList v-model:part={part.value} withBg={false} withPet={false}/></div>
<div class="flex flex-wrap equ-profile">
<div class="equ-profile-item">
@@ -3,6 +3,7 @@
<template v-for="key in ['0','1','2','3']" :key="key">
<div class="flex gap-2 mt-5px">
<calc-select class="flex-1 !h-20px" v-model="configStore.config.jades[key].id">
<calc-option :value="0">无</calc-option>
<calc-option v-for="(item, index) in infoStore.jades" :key="item.id" :value="item.id">
{{item.name}}
</calc-option>
+27 -9
View File
@@ -1,18 +1,36 @@
<template>
<div class="flex gap-2" v-if="configStore.result.state">
<Info :suits="configStore.result.state.suits" :info="configStore.result.state.info" :equs="configStore.config.equips"></Info>
<Skill :data="configStore.result.state.skills"></Skill>
<div class="flex flex-col justify-between">
<div class="flex gap-5 items-center">
<calc-button class="flex-1" @click="setStandard">设为基准</calc-button>
<calc-button class="flex-1" @click="clearStandard">清空基准</calc-button>
</div>
<Info
:suits="configStore.result.state.suits"
:info="configStore.result.state.info"
:equs="configStore.config.equips"
></Info>
</div>
<Skill :data="configStore.result.state.skills" :standard="infoStore.standard"></Skill>
</div>
</template>
<script setup lang="ts">
import { useConfigStore } from '@/stores';
import Info from './components/Info.vue';
import Skill from './components/Skill.vue';
import { useConfigStore, useInfoStore } from '@/stores'
import Info from './components/Info.vue'
import Skill from './components/Skill.vue'
const configStore = useConfigStore();
const configStore = useConfigStore()
const infoStore = useInfoStore()
const setStandard = () => {
if(!configStore?.result?.state?.uuid) return
infoStore.setStandard(configStore.result.state)
}
const clearStandard = () => {
infoStore.setStandard(undefined)
}
</script>
<style scoped lang="scss">
</style>
<style scoped lang="scss"></style>
@@ -54,6 +54,7 @@
</div>
</template>
</div>
<div class="h-40px w-full"></div>
</div>
</template>
@@ -7,22 +7,27 @@
<div class="item-head w-150px">伤害</div>
<div class="item-head w-150px">秒伤</div>
</div>
<div class="overflow-y-auto max-h-580px">
<div class="overflow-y-auto max-h-600px">
<div class="flex px-1px gap-1px h-8.5" v-for="skill in data" :key="skill.name">
<div class="flex w-150px items-center gap-10px">
<div class="w-28px h-28px relative">
<img :src="getImageURL(skill.icon)" alt="" class="w-28px h-28px" />
<div v-if="skill.lv" class="skill-lv-min" :data-text="`Lv ${ skill.lv }`">Lv {{ skill.lv }}</div>
<div v-if="skill.lv" class="skill-lv-min" :data-text="`Lv ${skill.lv}`">
Lv {{ skill.lv }}
</div>
</div>
<div>{{ skill.name }}</div>
</div>
<div class="w-80px flex items-center justify-center">{{ skill.cd.toFixed(1) }}s</div>
<div class="w-150px flex items-center justify-center">
{{ Math.round(skill.damage).toLocaleString() }}
</div>
<div class="w-150px flex items-center justify-center">
{{ Math.round(skill.damage / skill.cd).toLocaleString() }}
</div>
<!-- <div class="flex">
<div class="w-150px flex items-center justify-center">
{{ Math.round(skill.damage).toLocaleString() }}
</div>
<div class="w-150px flex items-center justify-center">
{{ Math.round(skill.damage / skill.cd).toLocaleString() }}
</div>
</div> -->
<component :is="formatDamage(skill)"></component>
</div>
</div>
</div>
@@ -32,13 +37,90 @@
<script setup lang="ts" name="Skill">
import type { IResultSkill } from '@/api/calc/type'
import { getImageURL } from '@/utils/images'
import { h } from 'vue'
const props = defineProps<{
data: IResultSkill[]
standard?: IResultSkill[]
}>()
const data = computed(() => {
return props.data.sort((a, b) => b.damage - a.damage)
})
const formatDamage = (skill: IResultSkill) => {
const standardSkill = props.standard?.find((a) => a.name == skill.name)
if (standardSkill && standardSkill.damage > 0 && standardSkill.cd > 0) {
const damageValue = (skill.damage - standardSkill.damage) / standardSkill.damage
const damage = h(
'div',
{
style: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '150px',
color: damageValue >= 0 ? '#37fa38' : '#ff0000',
},
},
(damageValue * 100).toFixed(2) + '%',
)
const dpsValue =
(skill.damage / skill.cd - standardSkill.damage / standardSkill.cd) /
(standardSkill.damage / standardSkill.cd)
const dps = h(
'div',
{
style: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '150px',
color: damageValue >= 0 ? '#37fa38' : '#ff0000',
},
},
(dpsValue * 100).toFixed(2) + '%',
)
return h(
'div',
{
class: 'flex items-center justify-center',
},
[damage, dps],
)
} else {
const damage = h(
'div',
{
style: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '150px',
},
},
Math.round(skill.damage).toLocaleString(),
)
const dps = h(
'div',
{
style: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '150px',
},
},
Math.round(skill.damage / skill.cd).toLocaleString(),
)
return h(
'div',
{
class: 'flex items-center justify-center',
},
[damage, dps],
)
}
}
</script>
<style scoped lang="scss">
@@ -50,27 +132,27 @@ const data = computed(() => {
}
.skill-lv-min {
position: absolute;
z-index: 0;
top: -3px;
right: -4px;
font-size: 12px;
transform: scale(0.7);
color: black;
text-shadow: none;
font-weight: bolder;
font-family: Arial;
}
position: absolute;
z-index: 0;
top: -3px;
right: -4px;
font-size: 12px;
transform: scale(0.7);
color: black;
text-shadow: none;
font-weight: bolder;
font-family: Arial;
}
.skill-lv-min::before {
// text-shadow: #37fa38 2px 0 0, #37fa38 0 2px 0, #37fa38 -2px 0 0, #37fa38 0 -2px 0;
// -webkit-text-stroke-width: 1px;
// -webkit-text-stroke-color: #37fa38;
content: attr(data-text);
position: absolute;
-webkit-text-stroke: 2.5px #37fa38;
font-family: Arial;
text-shadow: none;
z-index: -1;
}
.skill-lv-min::before {
// text-shadow: #37fa38 2px 0 0, #37fa38 0 2px 0, #37fa38 -2px 0 0, #37fa38 0 -2px 0;
// -webkit-text-stroke-width: 1px;
// -webkit-text-stroke-color: #37fa38;
content: attr(data-text);
position: absolute;
-webkit-text-stroke: 2.5px #37fa38;
font-family: Arial;
text-shadow: none;
z-index: -1;
}
</style>
+1
View File
@@ -165,6 +165,7 @@ export const useConfigStore = defineStore('configStore', () => {
return calc()
},
{
uuid: '',
skills: [],
info: [],
suits: [],
+24 -3
View File
@@ -2,6 +2,7 @@ import api from '@/api'
import type { ICharacterInfo } from '@/api/info/type'
import { defineStore } from 'pinia'
import { useConfigStore } from './config'
import type { IResult, IResultSkill } from '@/api/calc/type'
export const useInfoStore = defineStore('infoStore', () => {
const alter_token = ref<string>('')
@@ -23,6 +24,24 @@ export const useInfoStore = defineStore('infoStore', () => {
const jades = computed(() => infos.value?.jades ?? [])
const standardUUID = ref<string>()
const setStandard = (result?: IResult) => {
if (!result) {
!!standardUUID.value && sessionStorage.removeItem(standardUUID.value)
standardUUID.value = undefined
} else {
standardUUID.value = result.uuid
sessionStorage.setItem(result.uuid, JSON.stringify(result.skills))
}
}
const standard = computed(()=>{
const value = sessionStorage.getItem(standardUUID.value ?? '')
if(!value) return undefined
else return JSON.parse(value) as IResultSkill[]
})
const parts = [
'头肩',
'上衣',
@@ -37,7 +56,7 @@ export const useInfoStore = defineStore('infoStore', () => {
'戒指',
'耳环',
'魔法石',
'宠物'
'宠物',
]
const avatarParts = [
@@ -56,7 +75,7 @@ export const useInfoStore = defineStore('infoStore', () => {
'宠物',
'宠物装备-红',
'宠物装备-绿',
'宠物装备-蓝'
'宠物装备-蓝',
]
const createCharacter = async (alter: string, equVersion?: string) => {
@@ -79,6 +98,8 @@ export const useInfoStore = defineStore('infoStore', () => {
stones,
avatarParts,
avatars,
jades
jades,
setStandard,
standard
}
})