From f65dc0a928799a746d604720d18debc901a3681f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A5=BF=E7=93=9C=C2=B0?= Date: Tue, 11 Aug 2026 18:31:10 +0800 Subject: [PATCH] init --- backend/core/abstract/character.py | 6 +++ backend/core/basic/character/base.py | 2 + backend/core/basic/character/calc_carry.py | 33 ++++++++----- .../core/character/GF/extra/dark_knight.py | 32 +++++++++--- backend/test.py | 49 ++++++++++--------- .../src/components/calc/loading/index.vue | 2 - frontend/src/components/calc/tabs/index.vue | 12 ++--- frontend/src/components/calc/tree/node.vue | 18 ++++--- .../src/pages/Character/Equipment/Index.vue | 3 -- .../Character/Equipment/components/Stone.vue | 2 +- .../Equipment/components/StoneUniversal.vue | 3 +- frontend/src/utils/position.ts | 8 +-- 12 files changed, 102 insertions(+), 68 deletions(-) diff --git a/backend/core/abstract/character.py b/backend/core/abstract/character.py index 79287743..42f6903c 100644 --- a/backend/core/abstract/character.py +++ b/backend/core/abstract/character.py @@ -12,9 +12,15 @@ class CharacterProperty(ABC): STR: float """力量""" + PSTR: float + """力量%""" + INT: float """智力""" + PINT: float + """智力%""" + Spirit: float """精神""" diff --git a/backend/core/basic/character/base.py b/backend/core/basic/character/base.py index 78dbef78..a9aa2a7a 100644 --- a/backend/core/basic/character/base.py +++ b/backend/core/basic/character/base.py @@ -110,6 +110,8 @@ class CharacterBase(CharacterProperty): # 工会四维 self.STR = 0 + 120 self.INT = 0 + 120 + self.PSTR = 1.0 + self.PINT = 1.0 self.Spirit = 0 + 120 self.Vitality = 0 + 120 # 唤醒的情况下的基础数据 diff --git a/backend/core/basic/character/calc_carry.py b/backend/core/basic/character/calc_carry.py index fdcb7d2d..74da7fff 100644 --- a/backend/core/basic/character/calc_carry.py +++ b/backend/core/basic/character/calc_carry.py @@ -27,23 +27,25 @@ class CalcCarryMixin(CharacterBase): """计算属性系数""" attrs = [] if self.输出类型 == '物理百分比': - attrs.extend(['STR', 'AtkP', 'PAtkP']) + attrs.extend(['STR', 'PSTR', 'AtkP', 'PAtkP']) if self.输出类型 == '魔法百分比': - attrs.extend(['INT', 'AtkM', 'PAtkM']) + attrs.extend(['INT', 'PINT', 'AtkM', 'PAtkM']) if self.输出类型 == '物理固伤': - attrs.extend(['STR', 'AtkI', 'PAtkI']) + attrs.extend(['STR', 'PSTR', 'AtkI', 'PAtkI']) if self.输出类型 == '魔法固伤': - attrs.extend(['INT', 'AtkI', 'PAtkI']) + attrs.extend(['INT', 'PINT', 'AtkI', 'PAtkI']) # 力智系数 value0_1 = getattr(self, attrs[0]) - value0_2 = get_base_attributes(self.role, self.name)[0] if attrs[0] == 'STR' else get_base_attributes(self.role, self.name)[1] + value0_2 = get_base_attributes(self.role, self.name)[0 if attrs[0] == 'STR' else 1] # 系统奶及奶系增幅 value = value0_1 + ((value0_1 - value0_2) * 3.08 + 2886) * (1 if DSB else 0) + (170000 + 300000) * (1 if BUFF else 0) ratio_0: float = value / 250 + 1 + # 黑暗武士力智系数部分,特效不享受这部分 + ratio_10 = (value * (getattr(self, attrs[1]) + 1) / 250 + 1) / ratio_0 # 物理/魔法/独立攻击力 - ratio_1: float = getattr(self, attrs[1]) + 30000 * (1 if BUFF else 0) + ratio_1: float = getattr(self, attrs[2]) + 30000 * (1 if BUFF else 0) # 技能 物理/魔法/独立攻击力% - ratio_2: float = getattr(self, attrs[2]) + ratio_2: float = getattr(self, attrs[3]) # 属强系数 ratio_3 = max(self.ElementDB.values()) * 0.0045 + 1.05 # 暴击系数 @@ -59,9 +61,9 @@ class CalcCarryMixin(CharacterBase): ratio_8 = 1 - monster_defense / (monster_defense + 200 * 100) # 杂项 ratio_9 = 1.0 * self.ElementIncrease - return (ratio_0, ratio_1, ratio_2, ratio_3, ratio_4, ratio_5, ratio_6, ratio_7, ratio_8, ratio_9) + return (ratio_0, ratio_1, ratio_2, ratio_3, ratio_4, ratio_5, ratio_6, ratio_7, ratio_8, ratio_9, ratio_10) - def calc_carry_skills(self, DSB: bool, BUFF: bool): + def calc_character_skill(self): skillInfos = [] for i in self.skills: if i.damage and i.lv > 0: @@ -84,13 +86,20 @@ class CalcCarryMixin(CharacterBase): 'type': i.type, } ) + return skillInfos + + def calc_equipment_skill(self): + ... + + def calc_carry_skills(self, DSB: bool, BUFF: bool): + skillInfos = self.calc_character_skill() ratios = self.calc_damage_ration(DSB, BUFF) - ratio_char_skill = ratios[0] * ratios[1] * ratios[2] * ratios[3] * ratios[4] * ratios[5] * ratios[6] * ratios[7] * ratios[8] * ratios[9] / 1000 - ratuio_equ_skill = ratios[0] * ratios[1] * ratios[3] * ratios[4] * ratios[6] * ratios[7] * ratios[8] * ratios[9] / 1000 + ratio_char_skill = ratios[0] * ratios[1] * ratios[2] * ratios[3] * ratios[4] * ratios[5] * ratios[6] * ratios[7] * ratios[8] * ratios[9] * ratios[10] / 1000 + ratio_equ_skill = ratios[0] * ratios[1] * ratios[3] * ratios[4] * ratios[6] * ratios[7] * ratios[8] * ratios[9] / 1000 for i in skillInfos: i['damage'] = ratio_char_skill * i['data'] * i['ratio'] / 100 for i in self.equ_effect: - skillInfos.append({'name': i.name, 'icon': i.icon, 'lv': 0, 'data': i.data, 'ratio': 10.0, 'cd': i.cd, 'damage': ratuio_equ_skill * i.data * 10 * self.EquEffectRatio / 100, 'mode': ''}) + skillInfos.append({'name': i.name, 'icon': i.icon, 'lv': 0, 'data': i.data, 'ratio': 10.0, 'cd': i.cd, 'damage': ratio_equ_skill * i.data * 10 * self.EquEffectRatio / 100, 'mode': ''}) return skillInfos def get_carry_info(self): diff --git a/backend/core/character/GF/extra/dark_knight.py b/backend/core/character/GF/extra/dark_knight.py index ec0a34b0..a3b1e16c 100644 --- a/backend/core/character/GF/extra/dark_knight.py +++ b/backend/core/character/GF/extra/dark_knight.py @@ -1,4 +1,5 @@ # 17e417b31686389eebff6d754c3401ea +from core.basic.character.calc_carry import _skill_error_context from core.basic.skill import PassiveSkill, ActiveSkill, get_data from core.basic.character import Character @@ -23,6 +24,19 @@ class DarkKnightSkill(ActiveSkill): # 连续技所在列,-1表示不在连续技中 comboCol = -1 + def getSkillCD(self, mode=None): + # 排列技能,先不计算冷却时间恢复 + cdRecover = self.cdRecover if self.comboCol >= 0 else 1 + return max(0, round(max(self.cd * 0.3, self.cd * self.cdReduce / cdRecover * self.getWeaponCDRatio() * self.getQuickCDRatio()) * self.cdRatio - self.cdCut / cdRecover , 2)) + + def skillInfo(self, mode = None): + res = super().skillInfo(mode) + powers = [1,1.3,1.5,1.8,2] + power = 1.0 + if self.stage > 0: + power = powers[self.stage - 1] + return res[0], res[1] * power, res[2] + # 暗影斩 # extra/dark_knight/eb71e1d82d92c7e1d40500a0dcd77aa6 # 17e417b31686389eebff6d754c3401ea/eb71e1d82d92c7e1d40500a0dcd77aa6 @@ -2183,7 +2197,7 @@ class classChange(Character): if (skillType == 'all' or skill.type == skillType) and skill.lv > 0: skill.lv += lv - def calc_carry_skills(self, DSB: bool, BUFF: bool): + def calc_character_skill(self): skillInfos = [] for i in self.skills: if i.damage and i.lv > 0: @@ -2204,13 +2218,15 @@ class classChange(Character): 'mode': mode, 'learnLv': i.learnLv, 'type': i.type, + 'cdRecover': i.cdRecover, + 'combo': getattr(i, 'comboCol', None), } ) - ratios = self.calc_damage_ration(DSB, BUFF) - ratio_char_skill = ratios[0] * ratios[1] * ratios[2] * ratios[3] * ratios[4] * ratios[5] * ratios[6] * ratios[7] * ratios[8] * ratios[9] / 1000 - ratuio_equ_skill = ratios[0] * ratios[1] * ratios[3] * ratios[4] * ratios[6] * ratios[7] * ratios[8] * ratios[9] / 1000 - for i in skillInfos: - i['damage'] = ratio_char_skill * i['data'] * i['ratio'] / 100 - for i in self.equ_effect: - skillInfos.append({'name': i.name, 'icon': i.icon, 'lv': 0, 'data': i.data, 'ratio': 10.0, 'cd': i.cd, 'damage': ratuio_equ_skill * i.data * 10 * self.EquEffectRatio / 100, 'mode': ''}) + for comboCol in [0,1,2,3,4,5]: + skills = list(filter(lambda x: x['combo'] == comboCol, skillInfos)) + cdList = [x['cd'] for x in skills] + cdRecoverList = [x['cdRecover'] for x in skills] + total = sum(cdList) + totalRecover = sum(cdRecoverList) return skillInfos + \ No newline at end of file diff --git a/backend/test.py b/backend/test.py index c8337630..a96df09e 100644 --- a/backend/test.py +++ b/backend/test.py @@ -1,31 +1,34 @@ from core.basic.character import createCharacter - +from core.open.skillTree import decode_skill_hash,get_skill_tree_info char = createCharacter('GF.gunner_female.spitfire_female') -setInfo = { - 'oaths': {'0': {'id': '2030201', 'adaptation': 3}, '1': {'id': '2030201', 'adaptation': 3}, '2': {'id': '2030201', 'adaptation': 3}, '3': {'id': '2030201', 'adaptation': 3}, '4': {'id': '2030201', 'adaptation': 3}, '11': {'id': '2030200', 'adaptation': 0}}, - 'oathSkill': 1, - 'equips': { - '武器': {'id': '88', 'reinforce': 14, 'reinforceType': 1, 'enchant': 512, 'fusion': 0, 'refine': 8, 'adaptation': 3, 'precision': 100}, - '称号': {'id': '3017', 'reinforce': 0, 'reinforceType': 0, 'enchant': 1201, 'fusion': 0, 'refine': 0, 'adaptation': 3, 'precision': 100}, - '上衣': {'id': '999', 'reinforce': 13, 'reinforceType': 1, 'enchant': 105, 'fusion': '26', 'refine': 0, 'adaptation': 3, 'precision': 100}, - '头肩': {'id': '1001', 'reinforce': 14, 'reinforceType': 1, 'enchant': 5, 'fusion': '28', 'refine': 0, 'adaptation': 3, 'precision': 100}, - '下装': {'id': '1000', 'reinforce': 14, 'reinforceType': 1, 'enchant': 202, 'fusion': '27', 'refine': 0, 'adaptation': 3, 'precision': 100}, - '鞋': {'id': '1003', 'reinforce': 14, 'reinforceType': 1, 'enchant': 309, 'fusion': '30', 'refine': 0, 'adaptation': 3, 'precision': 100}, - '腰带': {'id': '1002', 'reinforce': 14, 'reinforceType': 1, 'enchant': 309, 'fusion': '29', 'refine': 0, 'adaptation': 3, 'precision': 100}, - '项链': {'id': '477', 'reinforce': 13, 'reinforceType': 1, 'enchant': 609, 'fusion': '180', 'refine': 0, 'adaptation': 3, 'precision': 100}, - '手镯': {'id': '483', 'reinforce': 14, 'reinforceType': 1, 'enchant': 609, 'fusion': '302', 'refine': 0, 'adaptation': 3, 'precision': 100}, - '戒指': {'id': '489', 'reinforce': 14, 'reinforceType': 1, 'enchant': 609, 'fusion': '304', 'refine': 0, 'adaptation': 3, 'precision': 100}, - '辅助装备': {'id': '492', 'reinforce': 14, 'reinforceType': 1, 'enchant': 905, 'fusion': '182', 'refine': 3, 'adaptation': 3, 'precision': 100}, - '魔法石': {'id': '495', 'reinforce': 14, 'reinforceType': 1, 'enchant': 1003, 'fusion': '184', 'refine': 3, 'adaptation': 3, 'precision': 100}, - '耳环': {'id': '498', 'reinforce': 14, 'reinforceType': 1, 'enchant': 1104, 'fusion': '186', 'refine': 0, 'adaptation': 3, 'precision': 100}, - '宠物': {'id': '4022', 'reinforce': 0, 'reinforceType': 0, 'enchant': 1304, 'fusion': 0, 'refine': 0, 'adaptation': 3, 'precision': 100}, - }, - 'emblems': {'彩色': {'lv': 1, 'items': ['4401', '4401', '4401', '4401', '4401', '4401']}, '红色': {'lv': 2, 'items': ['4101', '4101', '4101', '4101']}, '蓝色': {'lv': 2, 'items': []}, '绿色': {'lv': 3, 'items': []}, '黄色': {'lv': 4, 'items': []}}, -} +# setInfo = { +# 'oaths': {'0': {'id': '2030201', 'adaptation': 3}, '1': {'id': '2030201', 'adaptation': 3}, '2': {'id': '2030201', 'adaptation': 3}, '3': {'id': '2030201', 'adaptation': 3}, '4': {'id': '2030201', 'adaptation': 3}, '11': {'id': '2030200', 'adaptation': 0}}, +# 'oathSkill': 1, +# 'equips': { +# '武器': {'id': '88', 'reinforce': 14, 'reinforceType': 1, 'enchant': 512, 'fusion': 0, 'refine': 8, 'adaptation': 3, 'precision': 100}, +# '称号': {'id': '3017', 'reinforce': 0, 'reinforceType': 0, 'enchant': 1201, 'fusion': 0, 'refine': 0, 'adaptation': 3, 'precision': 100}, +# '上衣': {'id': '999', 'reinforce': 13, 'reinforceType': 1, 'enchant': 105, 'fusion': '26', 'refine': 0, 'adaptation': 3, 'precision': 100}, +# '头肩': {'id': '1001', 'reinforce': 14, 'reinforceType': 1, 'enchant': 5, 'fusion': '28', 'refine': 0, 'adaptation': 3, 'precision': 100}, +# '下装': {'id': '1000', 'reinforce': 14, 'reinforceType': 1, 'enchant': 202, 'fusion': '27', 'refine': 0, 'adaptation': 3, 'precision': 100}, +# '鞋': {'id': '1003', 'reinforce': 14, 'reinforceType': 1, 'enchant': 309, 'fusion': '30', 'refine': 0, 'adaptation': 3, 'precision': 100}, +# '腰带': {'id': '1002', 'reinforce': 14, 'reinforceType': 1, 'enchant': 309, 'fusion': '29', 'refine': 0, 'adaptation': 3, 'precision': 100}, +# '项链': {'id': '477', 'reinforce': 13, 'reinforceType': 1, 'enchant': 609, 'fusion': '180', 'refine': 0, 'adaptation': 3, 'precision': 100}, +# '手镯': {'id': '483', 'reinforce': 14, 'reinforceType': 1, 'enchant': 609, 'fusion': '302', 'refine': 0, 'adaptation': 3, 'precision': 100}, +# '戒指': {'id': '489', 'reinforce': 14, 'reinforceType': 1, 'enchant': 609, 'fusion': '304', 'refine': 0, 'adaptation': 3, 'precision': 100}, +# '辅助装备': {'id': '492', 'reinforce': 14, 'reinforceType': 1, 'enchant': 905, 'fusion': '182', 'refine': 3, 'adaptation': 3, 'precision': 100}, +# '魔法石': {'id': '495', 'reinforce': 14, 'reinforceType': 1, 'enchant': 1003, 'fusion': '184', 'refine': 3, 'adaptation': 3, 'precision': 100}, +# '耳环': {'id': '498', 'reinforce': 14, 'reinforceType': 1, 'enchant': 1104, 'fusion': '186', 'refine': 0, 'adaptation': 3, 'precision': 100}, +# '宠物': {'id': '4022', 'reinforce': 0, 'reinforceType': 0, 'enchant': 1304, 'fusion': 0, 'refine': 0, 'adaptation': 3, 'precision': 100}, +# }, +# 'emblems': {'彩色': {'lv': 1, 'items': ['4401', '4401', '4401', '4401', '4401', '4401']}, '红色': {'lv': 2, 'items': ['4101', '4101', '4101', '4101']}, '蓝色': {'lv': 2, 'items': []}, '绿色': {'lv': 3, 'items': []}, '黄色': {'lv': 4, 'items': []}}, +# } -char.calc(setInfo) +# char.calc(setInfo) + +print( + get_skill_tree_info('eJyNjL1KgmEARs+x3vCL1CAlq0EIMqIQM4KShoIGNSRy6wqCEhSi8mfqKrqHFu+gm3LTTwprCVo60/Oc4YxDxMIjvSuQ5O7b4e3a/eS1UiZjIG3KlBEzcuIqUzaNyTkhj25wQ5EGResUbbHHGRqx5x16ih6w75LLXKIFNEHJa8rUKPvEkR222SJLnmMzSBpJISvIIjJC3pEuOz6gF2gVrXBik3XP0SxVP5A2WkKTJAxoaEAdY2jhDBdimM0P6Wde6NFnwJA5CRqk/Z4sPeMZL4QkgSpPtOgR2pxzQYkZfUKNCh3y1BkQHmiSpUDMkHBJlwMipky4IeMn19/Rd0Y/9V98/DH/ZPwFNF4wuQ==')) # for oath in char.charOathInfo: # print(oath.id, oath.adaptation, oath.oathInfo.position, oath.oathInfo.max_adaptation, oath.oathInfo.Point) diff --git a/frontend/src/components/calc/loading/index.vue b/frontend/src/components/calc/loading/index.vue index 69eefe0a..d62380f4 100644 --- a/frontend/src/components/calc/loading/index.vue +++ b/frontend/src/components/calc/loading/index.vue @@ -25,11 +25,9 @@ export default defineComponent({ class="i-loading-spin" version="1.1" xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" width="200px" height="200px" viewBox="0 0 200 200" - xml:space="preserve" > import { HiSelection, selectionProps } from 'hoci' import type { PropType } from 'vue' -import { computed, defineComponent, renderSlot } from 'vue' +import { computed, defineComponent, normalizeClass, renderSlot } from 'vue' import type { LocationQuery } from 'vue-router' import { parseQuery, useRouter } from 'vue-router' import type { BaseType } from '@/components/hooks/types' @@ -54,7 +54,7 @@ export default defineComponent({ v-model={modelValue.value} class={{ 'i-tabs': true, vertical: !!props.vertical }} activeClass="active" - itemClass={['i-tab cursor-pointer'].concat(props.itemClass)} + itemClass={normalizeClass(['i-tab cursor-pointer', props.itemClass])} > {renderSlot(slots, 'default')} @@ -99,7 +99,7 @@ export default defineComponent({ // font-size: 12px; margin-left: 1px; width: fit-content; - padding:0px 10px; + padding: 0px 10px; padding-bottom: 2px; height: 20px; text-align: center; @@ -132,9 +132,9 @@ export default defineComponent({ // color: #ffb400; } - &.disabled{ - filter: grayscale(100%); - cursor: not-allowed; + &.disabled { + filter: grayscale(100%); + cursor: not-allowed; } } } diff --git a/frontend/src/components/calc/tree/node.vue b/frontend/src/components/calc/tree/node.vue index 785a7c93..181e7d1a 100644 --- a/frontend/src/components/calc/tree/node.vue +++ b/frontend/src/components/calc/tree/node.vue @@ -5,6 +5,7 @@ import { Transition, computed, defineComponent, ref, renderList } from 'vue' import type { TreeNode } from './types' const NTreeNode = defineComponent({ + emits: ['select'], props: { label: { type: String, @@ -56,15 +57,16 @@ const NTreeNode = defineComponent({ value={props.value} style={depthStyle.value} class="flex i-tree-item-label items-center" - onClick={open} > -
-
- -
{props.label}
+
+
+
+ +
{props.label}
+
diff --git a/frontend/src/pages/Character/Equipment/Index.vue b/frontend/src/pages/Character/Equipment/Index.vue index 9f6679ef..fc4110d0 100644 --- a/frontend/src/pages/Character/Equipment/Index.vue +++ b/frontend/src/pages/Character/Equipment/Index.vue @@ -22,11 +22,9 @@ 套装 通宝 - 其他 -
@@ -37,7 +35,6 @@ import Weapon from './components/Weapon.vue' import Stone from './components/Stone.vue' import Universal from './components/Universal.vue' import StoneUniversal from './components/StoneUniversal.vue' -import StoneOld from './components/StoneOld.vue' import Else from './components/Else.vue' import { useInfoStore } from '@/stores' import SubWeapon from './components/SubWeapon.vue' diff --git a/frontend/src/pages/Character/Equipment/components/Stone.vue b/frontend/src/pages/Character/Equipment/components/Stone.vue index 629c1695..511d06d9 100644 --- a/frontend/src/pages/Character/Equipment/components/Stone.vue +++ b/frontend/src/pages/Character/Equipment/components/Stone.vue @@ -68,7 +68,7 @@ const suits = computed(() => { }) const suitEquipments = computed(() => { - const equs = infoStore.stones.filter( + const equs = infoStore.oaths.filter( (a) => a.suit.includes(curSuit.value.toString()) && a.suit.length === 1, ) diff --git a/frontend/src/pages/Character/Equipment/components/StoneUniversal.vue b/frontend/src/pages/Character/Equipment/components/StoneUniversal.vue index 7ce2acef..2f4a55d6 100644 --- a/frontend/src/pages/Character/Equipment/components/StoneUniversal.vue +++ b/frontend/src/pages/Character/Equipment/components/StoneUniversal.vue @@ -15,7 +15,6 @@