From f3273bfec44ea2a0b49d5410859d24e34dfb5ef0 Mon Sep 17 00:00:00 2001 From: qwerdvd <2450899274@qq.com> Date: Sat, 27 May 2023 21:34:17 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=E5=AE=9E=E9=AA=8C=E6=80=A7=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=B8=8C=E5=84=BF=E4=BC=A4=E5=AE=B3=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../starrailuid_charinfo/mono/Character.py | 3 + .../starrailuid_damagecal/cal_damage.py | 12 +- .../effect/Base/Avatar.py | 118 ++++++++---- .../effect/Base/AvatarExtraAbility.json | 9 + .../effect/Base/Rank.json | 9 + .../effect/Base/Relic.py | 122 +++++++++--- .../starrailuid_damagecal/effect/Base/Role.py | 178 +++++++++++++++++- .../effect/Base/Skill.py | 48 +++++ .../effect/Base/Weapon.py | 69 +++---- .../effect/Base/WeaponBase.py | 26 ++- .../effect/Base/seele.json | 68 +++++++ .../effect/Base/utils.py | 45 +++++ .../effect/Hunt/seele.json | 58 ------ StarRailUID/starrailuid_start/__init__.py | 6 +- .../utils/resource/download_from_cos.py | 2 +- 15 files changed, 595 insertions(+), 178 deletions(-) create mode 100644 StarRailUID/starrailuid_damagecal/effect/Base/AvatarExtraAbility.json create mode 100644 StarRailUID/starrailuid_damagecal/effect/Base/Rank.json create mode 100644 StarRailUID/starrailuid_damagecal/effect/Base/Skill.py create mode 100644 StarRailUID/starrailuid_damagecal/effect/Base/seele.json create mode 100644 StarRailUID/starrailuid_damagecal/effect/Base/utils.py delete mode 100644 StarRailUID/starrailuid_damagecal/effect/Hunt/seele.json diff --git a/StarRailUID/starrailuid_charinfo/mono/Character.py b/StarRailUID/starrailuid_charinfo/mono/Character.py index 9879ab4..9199aef 100644 --- a/StarRailUID/starrailuid_charinfo/mono/Character.py +++ b/StarRailUID/starrailuid_charinfo/mono/Character.py @@ -29,6 +29,9 @@ class Character: self.add_attr = {} self.equipment = card_prop['equipmentInfo'] self.rarity = card_prop['avatarRarity'] + self.eidolons = ( + card_prop['rankList'] if card_prop.get('rankList') else [] + ) # 伤害计算 self.def_ignore = 0 diff --git a/StarRailUID/starrailuid_damagecal/cal_damage.py b/StarRailUID/starrailuid_damagecal/cal_damage.py index c3ff753..6fd2274 100644 --- a/StarRailUID/starrailuid_damagecal/cal_damage.py +++ b/StarRailUID/starrailuid_damagecal/cal_damage.py @@ -16,8 +16,10 @@ async def cal(char_data: Dict): raw_data['avatar']['id'] = char.char_id raw_data['avatar']['level'] = char.char_level raw_data['avatar']['rank'] = char.char_rank + raw_data['avatar']['element'] = char.char_element raw_data['avatar']['promotion'] = char.char_promotion raw_data['avatar']['attribute_bonus'] = char.attribute_bonus + raw_data['avatar']['extra_ability'] = char.extra_ability raw_data['weapon']['id'] = char.equipment['equipmentID'] raw_data['weapon']['level'] = char.equipment['equipmentLevel'] @@ -26,8 +28,10 @@ async def cal(char_data: Dict): raw_data['relic'] = char.char_relic - role = RoleInstance(raw_data) - await role.cal_role_base_attr() - await role.cal_relic_attr_add() - await role.cal_avatar_attr_add() + raw_data['skill'] = char.char_skill + + for skill_type in ['Normal', 'BPSkill', 'Ultra']: + role = RoleInstance(raw_data) + print(role) + await role.cal_damage(skill_type) return '还没写完呢' diff --git a/StarRailUID/starrailuid_damagecal/effect/Base/Avatar.py b/StarRailUID/starrailuid_damagecal/effect/Base/Avatar.py index eff9c1a..51a1f3b 100644 --- a/StarRailUID/starrailuid_damagecal/effect/Base/Avatar.py +++ b/StarRailUID/starrailuid_damagecal/effect/Base/Avatar.py @@ -1,45 +1,54 @@ -from typing import Dict +import json +from pathlib import Path +from typing import Dict, List from abc import abstractmethod from mpmath import mp +from .Skill import BaseSkills from ....utils.excel.read_excel import AvatarPromotion +path = Path(__file__).parent +with open(path / 'seele.json', 'r', encoding='utf-8') as f: + skill_dict = json.load(f) + mp.dps = 14 -class BaseSkills: - @abstractmethod - async def Basic_ATK(self): - ... - - @abstractmethod - async def Skill(self): - ... - - @abstractmethod - async def Ultimate(self): - ... - - @abstractmethod - async def Talent(self): - ... +class BaseAvatarBuff: + def __init__(self, char: Dict, skills: List): + self.extra_ability_id = [] + for extra_ability in char['extra_ability']: + self.extra_ability_id.append(extra_ability['extraAbilityId']) @abstractmethod async def Technique(self): ... + @abstractmethod + async def eidolons(self): + ... + + @abstractmethod + async def extra_ability(self): + ... + class BaseAvatar: - def __init__(self, char: Dict): + Skill: BaseSkills + + def __init__(self, char: Dict, skills: List): + self.Skill = BaseSkills(char=char, skills=skills) self.avatar_id = char['id'] self.avatar_level = char['level'] self.avatar_rank = char['rank'] + self.avatar_element = char['element'] self.avatar_promotion = char['promotion'] self.avatar_attribute_bonus = char['attribute_bonus'] + self.avatar_extra_ability = char['extra_ability'] self.avatar_attribute = {} - async def get_attribute(self): + def get_attribute(self): promotion = AvatarPromotion[str(self.avatar_id)][ str(self.avatar_promotion) ] @@ -73,28 +82,67 @@ class BaseAvatar: promotion["BaseAggro"]['Value'] ) + def Normal(self): + return mp.mpf( + skill_dict[str(self.avatar_id)]['Normal'][ + self.Skill.Normal_.level - 1 + ] + ) -class Seele(BaseAvatar, BaseSkills): - def __init__(self, char: Dict): - super().__init__(char) + def BPSkill(self): + return mp.mpf( + skill_dict[str(self.avatar_id)]['BPSkill'][ + self.Skill.BPSkill_.level - 1 + ] + ) - async def Basic_ATK(self): + def Ultra(self): + return mp.mpf( + skill_dict[str(self.avatar_id)]['Ultra'][ + self.Skill.Ultra_.level - 1 + ] + ) + + def Maze(self): + return mp.mpf( + skill_dict[str(self.avatar_id)]['Maze'][self.Skill.Maze_.level - 1] + ) + + def Talent(self): + return mp.mpf( + skill_dict[str(self.avatar_id)][''][self.Skill.Talent_.level - 1] + ) + + +class Seele(BaseAvatar): + Buff: BaseAvatarBuff + + def __init__(self, char: Dict, skills: List): + super().__init__(char=char, skills=skills) + self.Buff = BaseAvatarBuff(char=char, skills=skills) + self.eidolon_attribute = {} + self.extra_ability_attribute = {} + self.eidolons() + self.extra_ability() + + def Technique(self): pass - async def Skill(self): - pass + def eidolons(self): + if self.avatar_rank >= 1: + self.eidolon_attribute['CriticalDamageBase'] = mp.mpf(0.15) + if self.avatar_rank >= 2: + self.eidolon_attribute['SpeedAddedRatio'] = mp.mpf(0.5) - async def Ultimate(self): - pass - - async def Talent(self): - pass - - async def Technique(self): - pass + def extra_ability(self): + # 额外能力 割裂 抗性穿透提高20 + if 1102102 in self.Buff.extra_ability_id: + self.extra_ability_attribute[ + 'QuantumResistancePenetration' + ] = mp.mpf(0.2) class Avatar: - def __new__(cls, char: Dict): + def __new__(cls, char: Dict, skills: List): if char['id'] == 1102: - return Seele(char) + return Seele(char, skills) diff --git a/StarRailUID/starrailuid_damagecal/effect/Base/AvatarExtraAbility.json b/StarRailUID/starrailuid_damagecal/effect/Base/AvatarExtraAbility.json new file mode 100644 index 0000000..a387678 --- /dev/null +++ b/StarRailUID/starrailuid_damagecal/effect/Base/AvatarExtraAbility.json @@ -0,0 +1,9 @@ +{ + "1102": [ + { + "id": 1102102, + "property": "QuantumResistancePenetration", + "value": 0.2 + } + ] +} diff --git a/StarRailUID/starrailuid_damagecal/effect/Base/Rank.json b/StarRailUID/starrailuid_damagecal/effect/Base/Rank.json new file mode 100644 index 0000000..c55e6e2 --- /dev/null +++ b/StarRailUID/starrailuid_damagecal/effect/Base/Rank.json @@ -0,0 +1,9 @@ +{ + "1102": [ + { + "rank": 1, + "property" :"CriticalDamageBase", + "value": 0.2 + } + ] +} diff --git a/StarRailUID/starrailuid_damagecal/effect/Base/Relic.py b/StarRailUID/starrailuid_damagecal/effect/Base/Relic.py index ba8685c..d78c552 100644 --- a/StarRailUID/starrailuid_damagecal/effect/Base/Relic.py +++ b/StarRailUID/starrailuid_damagecal/effect/Base/Relic.py @@ -3,6 +3,10 @@ from abc import abstractmethod from collections import Counter from mpmath import mp +from gsuid_core.logger import logger + +from .utils import merge_attribute +from ....utils.map.SR_MAP_PATH import RelicSetSkill mp.dps = 14 @@ -16,11 +20,19 @@ class SingleRelic: self.relic_level = relic.get('Level', 0) self.relic_attribute_bonus = {} - async def get_attribute_(self): + def get_attribute_(self): # MainAffix - self.relic_attribute_bonus[ + if ( self.raw_relic['MainAffix']['Property'] - ] = mp.mpf(self.raw_relic['MainAffix']['Value']) + in self.relic_attribute_bonus + ): + self.relic_attribute_bonus[ + self.raw_relic['MainAffix']['Property'] + ] += mp.mpf(self.raw_relic['MainAffix']['Value']) + else: + self.relic_attribute_bonus[ + self.raw_relic['MainAffix']['Property'] + ] = mp.mpf(self.raw_relic['MainAffix']['Value']) # SubAffix if self.raw_relic.get('SubAffixList'): @@ -34,45 +46,93 @@ class SingleRelic: class BaseRelicSetSkill: + setId: int + pieces2: bool = False + pieces4: bool = False + + def __init__(self, set_id: int, count: int): + self.setId = set_id + if count >= 2: + self.pieces2 = True + logger.info(f'Relic {set_id} 2 pieces set activated') + if count == 4: + self.pieces4 = True + logger.info(f'Relic {set_id} 4 pieces set activated') + self.relicSetAttribute = {} + self.set_skill_property_ability() + @abstractmethod - async def check(self): + async def check(self, base_attr: Dict, attribute_bonus: Dict): ... @abstractmethod - async def set_skill_ability(self, char): + async def set_skill_ability(self, base_attr: Dict, attribute_bonus: Dict): ''' 战斗加成属性, 与 set_skill_property() 互斥 ''' ... - @abstractmethod - async def set_skill_property_ability(self, char): - ''' - 面板加成属性, 与 set_skill_ability_param() 互斥 - ''' - ... + def set_skill_property_ability(self): + set_property = '' + set_value = mp.mpf(0) + if self.pieces2 and RelicSetSkill[str(self.setId)]['2'] != {}: + set_property = RelicSetSkill[str(self.setId)]['2']['Property'] + set_value = mp.mpf(RelicSetSkill[str(self.setId)]['2']['Value']) + if self.pieces4 and RelicSetSkill[str(self.setId)]['4'] != {}: + set_property = RelicSetSkill[str(self.setId)]['4']['Property'] + set_value = mp.mpf(RelicSetSkill[str(self.setId)]['4']['Value']) + if set_property != '': + if set_property in self.relicSetAttribute: + self.relicSetAttribute[set_property] = ( + self.relicSetAttribute[set_property] + set_value + ) + else: + self.relicSetAttribute[set_property] = set_value class Relic108(BaseRelicSetSkill): - async def check(self): - pass + def __init__(self, set_id: int, count: int): + super().__init__(set_id, count) - async def set_skill_ability(self, char): - pass + async def check(self, base_attr: Dict, attribute_bonus: Dict): + ''' + 装备者对敌方目标造成伤害 + 目标拥有量子属性弱点 + ''' + logger.info('Relic108 check success') + return True - async def set_skill_property_ability(self, char): - pass + async def set_skill_ability(self, base_attr: Dict, attribute_bonus: Dict): + if self.pieces4 and await self.check(base_attr, attribute_bonus): + ignore_defence = attribute_bonus.get('ignore_defence', 0) + attribute_bonus['ignore_defence'] = ( + ignore_defence + mp.mpf(0.10000000009313226) * 2 + ) + return attribute_bonus class Relic306(BaseRelicSetSkill): - async def check(self): - pass + def __init__(self, set_id: int, count: int): + super().__init__(set_id, count) - async def set_skill_ability(self, char): - pass + async def check(self, base_attr: Dict, attribute_bonus: Dict): + ''' + 装备者当前暴击率大于等于50% + ''' + merged_attr = await merge_attribute(base_attr, attribute_bonus) + if merged_attr['CriticalChance'] >= mp.mpf(0.5): + logger.info('Relic306 check success') + return True - async def set_skill_property_ability(self, char): - pass + async def set_skill_ability(self, base_attr: Dict, attribute_bonus: Dict): + if self.pieces2 and await self.check(base_attr, attribute_bonus): + q_dmg = attribute_bonus.get('UltraDmgAdd', 0) + attribute_bonus['UltraDmgAdd'] = q_dmg + mp.mpf(0.1500000001396984) + a3_dmg = attribute_bonus.get('Follow-UpAttackDmgAdd', 0) + attribute_bonus['Follow-UpDmgAdd'] = a3_dmg + mp.mpf( + 0.1500000001396984 + ) + return attribute_bonus class RelicSet: @@ -84,10 +144,11 @@ class RelicSet: OBJECT: SingleRelic Unknow: SingleRelic - set_id_counter: List - SetSkill: List = [] + set_id_counter: List = [] + SetSkill: List def __init__(self, relic_list: List): + self.SetSkill = [] set_id_list = [] for relic in relic_list: set_id_list.append(relic['SetId']) @@ -108,20 +169,21 @@ class RelicSet: self.Unknow = SingleRelic(relic) self.set_id_counter: List = Counter(set_id_list).most_common() + self.check_set() - async def get_attribute(self): + def get_attribute(self): for item in self.__dict__: if type(self.__dict__[item]) != SingleRelic: break - await self.__dict__[item].get_attribute_() + self.__dict__[item].get_attribute_() - async def check_set(self): + def check_set(self): for item in self.set_id_counter: set_id = item[0] count = item[1] if count == 1: break if set_id == 108: - self.SetSkill.append(Relic108()) + self.SetSkill.append(Relic108(set_id, count)) if set_id == 306: - self.SetSkill.append(Relic306()) + self.SetSkill.append(Relic306(set_id, count)) diff --git a/StarRailUID/starrailuid_damagecal/effect/Base/Role.py b/StarRailUID/starrailuid_damagecal/effect/Base/Role.py index c7a5097..53fd9f6 100644 --- a/StarRailUID/starrailuid_damagecal/effect/Base/Role.py +++ b/StarRailUID/starrailuid_damagecal/effect/Base/Role.py @@ -1,9 +1,11 @@ from typing import Dict from mpmath import mp +from gsuid_core.logger import logger from .Avatar import Avatar from .Weapon import Weapon +from .utils import merge_attribute from .Relic import RelicSet, SingleRelic mp.dps = 14 @@ -13,15 +15,21 @@ class RoleInstance: def __init__(self, raw_data: Dict): self.raw_data = raw_data - self.avatar = Avatar(raw_data['avatar']) + self.avatar = Avatar(raw_data['avatar'], raw_data['skill']) self.weapon = Weapon(raw_data['weapon']) self.relic_set = RelicSet(raw_data['relic']) self.base_attr = {} self.attribute_bonus = {} - async def cal_role_base_attr(self): - await self.avatar.get_attribute() + self.cal_role_base_attr() + self.cal_relic_attr_add() + self.cal_avatar_attr_add() + self.cal_avatar_eidolon_add() + self.cal_weapon_attr_add() + + def cal_role_base_attr(self): + self.avatar.get_attribute() avatar_attribute = self.avatar.__dict__['avatar_attribute'] for attribute in avatar_attribute: if attribute in self.base_attr: @@ -29,16 +37,17 @@ class RoleInstance: else: self.base_attr[attribute] = avatar_attribute[attribute] - await self.weapon.get_attribute() - weapon_attribute = self.weapon.__dict__['weapon_attribute'] + self.weapon.get_attribute() + weapon_attribute = self.weapon.__dict__['weapon_base_attribute'] for attribute in weapon_attribute: if attribute in self.base_attr: self.base_attr[attribute] += weapon_attribute[attribute] else: self.base_attr[attribute] = weapon_attribute[attribute] - async def cal_relic_attr_add(self): - await self.relic_set.get_attribute() + def cal_relic_attr_add(self): + # 单件属性 + self.relic_set.get_attribute() for relic_type in self.relic_set.__dict__: if type(self.relic_set.__dict__[relic_type]) != SingleRelic: break @@ -53,7 +62,19 @@ class RoleInstance: attribute ] = relic.relic_attribute_bonus[attribute] - async def cal_avatar_attr_add(self): + # 套装面板加成属性 + for set_skill in self.relic_set.SetSkill: + for attribute in set_skill.relicSetAttribute: + if attribute in self.attribute_bonus: + self.attribute_bonus[ + attribute + ] += set_skill.relicSetAttribute[attribute] + else: + self.attribute_bonus[ + attribute + ] = set_skill.relicSetAttribute[attribute] + + def cal_avatar_attr_add(self): attribute_bonus = self.avatar.avatar_attribute_bonus for bonus in attribute_bonus: status_add = bonus['statusAdd'] @@ -63,3 +84,144 @@ class RoleInstance: self.attribute_bonus[bonus_property] += value else: self.attribute_bonus[bonus_property] = value + + def cal_avatar_eidolon_add(self): + for attribute in self.avatar.eidolon_attribute: + if attribute in self.attribute_bonus: + self.attribute_bonus[ + attribute + ] += self.avatar.eidolon_attribute[attribute] + else: + self.attribute_bonus[ + attribute + ] = self.avatar.eidolon_attribute[attribute] + for attribute in self.avatar.extra_ability_attribute: + if attribute in self.attribute_bonus: + self.attribute_bonus[ + attribute + ] += self.avatar.extra_ability_attribute[attribute] + else: + self.attribute_bonus[ + attribute + ] = self.avatar.extra_ability_attribute[attribute] + + def cal_weapon_attr_add(self): + for attribute in self.weapon.weapon_attribute: + if attribute in self.attribute_bonus: + self.attribute_bonus[ + attribute + ] += self.weapon.weapon_attribute[attribute] + else: + self.attribute_bonus[attribute] = self.weapon.weapon_attribute[ + attribute + ] + + async def cal_damage(self, skill_type): + print(self.base_attr) + print(self.attribute_bonus) + # 检查武器战斗生效的buff + logger.info('检查武器战斗生效的buff') + self.attribute_bonus = await self.weapon.weapon_ability( + self.base_attr, self.attribute_bonus + ) + logger.info('检查遗器套装战斗生效的buff') + for set_skill in self.relic_set.SetSkill: + self.attribute_bonus = await set_skill.set_skill_ability( + self.base_attr, self.attribute_bonus + ) + merged_attr = await merge_attribute( + self.base_attr, self.attribute_bonus + ) + print(merged_attr) + attack = merged_attr['attack'] + logger.info(f'攻击力: {attack}') + # 模拟 同属性弱点 同等级 的怪物 + # 韧性条减伤 + enemy_damage_reduction = 0.1 + damage_reduction = 1 - enemy_damage_reduction + logger.info(f'韧性区: {damage_reduction}') + # 抗性区 + enemy_status_resistance = 0 + for attr in merged_attr: + if attr.__contains__('ResistancePenetration'): + # 先默认触发 + enemy_status_resistance = merged_attr[attr] + resistance_area = 1 - (0 - enemy_status_resistance) + logger.info(f'抗性区: {resistance_area}') + + # 防御区 + # 检查是否有 ignore_defence + logger.info('检查是否有 ignore_defence') + ignore_defence = 1 + for attr in merged_attr: + if attr == 'ignore_defence': + ignore_defence = 1 - merged_attr[attr] + break + logger.info(f'ignore_defence {ignore_defence}') + enemy_defence = (self.avatar.avatar_level * 10 + 200) * ignore_defence + defence_multiplier = (self.avatar.avatar_level * 10 + 200) / ( + self.avatar.avatar_level * 10 + 200 + enemy_defence + ) + logger.info(f'防御区: {defence_multiplier}') + + # 技能区 + if skill_type == 'Normal': + skill_multiplier = self.avatar.Normal() + elif skill_type == 'BPSkill': + skill_multiplier = self.avatar.BPSkill() + elif skill_type == 'Ultra': + skill_multiplier = self.avatar.Ultra() + else: + raise Exception('skill type error') + logger.info(f'技能区: {skill_multiplier}') + + # 增伤区 + # TODO: 这里计算只考虑了希儿,需要重写 injury_area = self.avatar.Talent() + injury_area = self.avatar.Talent() + # 检查是否有对某一个技能的伤害加成 + logger.info('检查是否有对某一个技能的伤害加成') + for attr in merged_attr: + if attr.__contains__('DmgAdd'): + attr_name = attr.split('DmgAdd')[0] + if attr_name == skill_type: + logger.info( + f'{attr} 对 {skill_type} 有 {merged_attr[attr]} 伤害加成' + ) + injury_area += merged_attr[attr] + # 检查球有无符合属性的伤害加成 + logger.info('检查球有无符合属性的伤害加成') + for attr in merged_attr: + if attr.__contains__('AddedRatio'): + attr_name = attr.split('AddedRatio')[0] + if attr_name == self.avatar.avatar_element: + logger.info( + f'{attr} 对 {self.avatar.avatar_element} ' + f'有 {merged_attr[attr]} 伤害加成' + ) + injury_area += merged_attr[attr] + logger.info(f'增伤区: {injury_area}') + + # 爆伤区 + critical_damage = merged_attr['CriticalDamage'] + # 检查是否有对特定技能的爆伤加成 + # Ultra_CriticalChance + for attr in merged_attr: + if attr.__contains__('_CriticalChance'): + skill_name = attr.split('_')[0] + if skill_name == skill_type: + logger.info( + f'{attr} 对 {skill_type} 有 {merged_attr[attr]} 爆伤加成' + ) + critical_damage += merged_attr[attr] + logger.info(f'暴伤: {critical_damage}') + + damage = ( + attack + * skill_multiplier + * injury_area + * defence_multiplier + * resistance_area + * damage_reduction + * critical_damage + ) + logger.info(f'{skill_type} 伤害: {damage}') diff --git a/StarRailUID/starrailuid_damagecal/effect/Base/Skill.py b/StarRailUID/starrailuid_damagecal/effect/Base/Skill.py new file mode 100644 index 0000000..761e72a --- /dev/null +++ b/StarRailUID/starrailuid_damagecal/effect/Base/Skill.py @@ -0,0 +1,48 @@ +import json +from pathlib import Path +from typing import Dict, List + +from mpmath import mp + +mp.dps = 14 + + +path = Path(__file__).parent +with open(path / 'seele.json', 'r', encoding='utf-8') as f: + skill_dict = json.load(f) + + +class SingleSkill: + def __init__(self, skill: Dict): + self.id = skill['skillId'] + self.level = skill['skillLevel'] + + +class BaseSkills: + Normal_: SingleSkill + BPSkill_: SingleSkill + Ultra_: SingleSkill + Maze_: SingleSkill + Talent_: SingleSkill + + def __init__(self, char: Dict, skills: List): + for skill in skills: + skill_attack_type = skill['skillAttackType'] + if skill_attack_type == 'Normal': + self.Normal_ = SingleSkill(skill) + elif skill_attack_type == 'BPSkill': + self.BPSkill_ = SingleSkill(skill) + elif skill_attack_type == 'Ultra': + self.Ultra_ = SingleSkill(skill) + elif skill_attack_type == 'Maze': + self.Maze_ = SingleSkill(skill) + elif skill_attack_type == '': + self.Talent_ = SingleSkill(skill) + else: + raise ValueError( + f'Unknown skillAttackType: {skill_attack_type}' + ) + + +# class SeeleSkill(BaseSkills): +# pass diff --git a/StarRailUID/starrailuid_damagecal/effect/Base/Weapon.py b/StarRailUID/starrailuid_damagecal/effect/Base/Weapon.py index 4d0ec54..33746ca 100644 --- a/StarRailUID/starrailuid_damagecal/effect/Base/Weapon.py +++ b/StarRailUID/starrailuid_damagecal/effect/Base/Weapon.py @@ -21,31 +21,37 @@ class IntheNight(BaseWeapon): async def check(self): pass - async def weapon_ability(self, char): - char = await self.weapon_property_ability(char) - char_speed = mp.mpf(char.base_attributes['speed']) + async def weapon_ability(self, base_attr: Dict, attribute_bonus: Dict): + char_speed = mp.mpf(base_attr.get('speed', 0)) count_ = min(6, int(mp.floor((char_speed - 100) / 10))) - char.a_dmg += ( - mp.mpf(weapon_effect['23001']['Param']['a_dmg'][self.weapon_rank]) - * count_ - ) - char.e_dmg += ( - mp.mpf(weapon_effect['23001']['Param']['e_dmg'][self.weapon_rank]) - * count_ - ) - char.q_crit_dmg += ( + normal_dmg_add = attribute_bonus.get('NormalDmgAdd', 0) + attribute_bonus['NormalDmgAdd'] = normal_dmg_add + ( mp.mpf( - weapon_effect['23001']['Param']['q_crit_dmg'][self.weapon_rank] + weapon_effect['23001']['Param']['a_dmg'][self.weapon_rank - 1] ) * count_ ) - return char - - async def weapon_property_ability(self, char): - char.CriticalChanceBase += mp.mpf( - weapon_effect['23001']['AbilityProperty'][self.weapon_rank] + bp_skill_dmg_add = attribute_bonus.get('BPSkillDmgAdd', 0) + attribute_bonus['BPSkillDmgAdd'] = bp_skill_dmg_add + ( + mp.mpf( + weapon_effect['23001']['Param']['e_dmg'][self.weapon_rank - 1] + ) + * count_ ) - return char + ultra_critical_chance_base = attribute_bonus.get( + 'Ultra_CriticalChanceBase', 0 + ) + attribute_bonus[ + 'Ultra_CriticalChanceBase' + ] = ultra_critical_chance_base + ( + mp.mpf( + weapon_effect['23001']['Param']['q_crit_dmg'][ + self.weapon_rank - 1 + ] + ) + * count_ + ) + return attribute_bonus class CruisingintheStellarSea(BaseWeapon): @@ -57,26 +63,23 @@ class CruisingintheStellarSea(BaseWeapon): # 装备者消灭敌方目标 return True - async def weapon_ability(self, char): - char = await self.weapon_property_ability(char) - if self.check(): - char.CriticalChanceBase += mp.mpf( + async def weapon_ability(self, base_attr: Dict, attribute_bonus: Dict): + if await self.check(): + critical_chance_base = attribute_bonus.get('CriticalChanceBase', 0) + attribute_bonus[ + 'CriticalChanceBase' + ] = critical_chance_base + mp.mpf( weapon_effect['24001']['Param']['CriticalChance'][ - self.weapon_rank + self.weapon_rank - 1 ] ) - char.AttackAddedRatio += mp.mpf( + attack_added_ratio = attribute_bonus.get('AttackAddedRatio', 0) + attribute_bonus['AttackAddedRatio'] = attack_added_ratio + mp.mpf( weapon_effect['24001']['Param']['AttackAddedRatio'][ - self.weapon_rank + self.weapon_rank - 1 ] ) - return char - - async def weapon_property_ability(self, char): - char.CriticalChanceBase += mp.mpf( - weapon_effect['24001']['AbilityProperty'][self.weapon_rank] - ) - return char + return attribute_bonus class HuntWeapon: diff --git a/StarRailUID/starrailuid_damagecal/effect/Base/WeaponBase.py b/StarRailUID/starrailuid_damagecal/effect/Base/WeaponBase.py index 4c42133..bd1aa50 100644 --- a/StarRailUID/starrailuid_damagecal/effect/Base/WeaponBase.py +++ b/StarRailUID/starrailuid_damagecal/effect/Base/WeaponBase.py @@ -4,6 +4,7 @@ from abc import abstractmethod from mpmath import mp from ....utils.excel.read_excel import EquipmentPromotion +from ....utils.map.SR_MAP_PATH import EquipmentID2AbilityProperty mp.dps = 14 @@ -14,42 +15,51 @@ class BaseWeapon: self.weapon_level = weapon['level'] self.weapon_rank = weapon['rank'] self.weapon_promotion = weapon['promotion'] + self.weapon_base_attribute = {} self.weapon_attribute = {} + self.weapon_property_ability() @abstractmethod - async def weapon_ability(self, char): + async def weapon_ability(self, base_attr: Dict, attribute_bonus: Dict): ''' 战斗加成属性, 与 weapon_property_ability() 互斥 ''' ... - @abstractmethod - async def weapon_property_ability(self, char): + def weapon_property_ability(self): ''' 面板加成属性, 与 weapon_ability() 互斥 ''' - ... + ability_property = EquipmentID2AbilityProperty[str(self.weapon_id)] + equip_ability_property = ability_property[str(self.weapon_rank)] + for equip_ability in equip_ability_property: + property_type = equip_ability['PropertyType'] + value = equip_ability['Value']['Value'] + if property_type in self.weapon_attribute: + self.weapon_attribute[property_type] += value + else: + self.weapon_attribute[property_type] = value @abstractmethod async def check(self): ... - async def get_attribute(self): + def get_attribute(self): promotion = EquipmentPromotion[str(self.weapon_id)][ str(self.weapon_promotion) ] - self.weapon_attribute['hp'] = mp.mpf( + self.weapon_base_attribute['hp'] = mp.mpf( promotion["BaseHP"]['Value'] ) + mp.mpf(promotion["BaseHPAdd"]['Value']) * (self.weapon_level - 1) - self.weapon_attribute['attack'] = mp.mpf( + self.weapon_base_attribute['attack'] = mp.mpf( promotion["BaseAttack"]['Value'] ) + mp.mpf(promotion["BaseAttackAdd"]['Value']) * ( self.weapon_level - 1 ) - self.weapon_attribute['defence'] = mp.mpf( + self.weapon_base_attribute['defence'] = mp.mpf( promotion["BaseDefence"]['Value'] ) + mp.mpf(promotion["BaseDefenceAdd"]['Value']) * ( self.weapon_level - 1 diff --git a/StarRailUID/starrailuid_damagecal/effect/Base/seele.json b/StarRailUID/starrailuid_damagecal/effect/Base/seele.json new file mode 100644 index 0000000..3d3c241 --- /dev/null +++ b/StarRailUID/starrailuid_damagecal/effect/Base/seele.json @@ -0,0 +1,68 @@ +{ + "1102": { + "Normal": [ + 0.5000000004656613, + 0.6000000005587935, + 0.7000000006519258, + 0.8000000007450581, + 0.9000000008381903, + 1.1000000000931323, + 1.2000000001862645, + 1.3000000002793968 + ], + "BPSkill": [ + 1.1000000000931323, + 1.2100000001955777, + 1.3200000002980232, + 1.4300000004004687, + 1.5400000005029142, + 1.6500000006053597, + 1.7875000005587935, + 1.9250000005122274, + 2.0625000002328306, + 2.2000000001862645, + 2.31000000028871, + 2.4200000003911555, + 2.530000000493601, + 2.6400000005960464, + 2.750000000698492 + ], + "Ultra": [ + 2.5500000005122274, + 2.7200000006705523, + 2.890000000828877, + 3.0600000000558794, + 3.230000000214204, + 3.400000000372529, + 3.612500000745058, + 3.825000000419095, + 4.037499999860302, + 4.250000000232831, + 4.4200000003911555, + 4.59000000054948, + 4.760000000707805, + 4.93000000086613, + 5.100000000093132 + ], + "": [ + 0.40000000037252903, + 0.44000000040978193, + 0.48000000044703484, + 0.5200000004842877, + 0.5600000005215406, + 0.6000000005587935, + 0.6500000006053597, + 0.7000000006519258, + 0.7500000006984919, + 0.8000000007450581, + 0.840000000782311, + 0.8800000008195639, + 0.9200000008568168, + 0.9600000008940697, + 1 + ], + "Maze": [ + 20 + ] + } +} diff --git a/StarRailUID/starrailuid_damagecal/effect/Base/utils.py b/StarRailUID/starrailuid_damagecal/effect/Base/utils.py new file mode 100644 index 0000000..d0b880a --- /dev/null +++ b/StarRailUID/starrailuid_damagecal/effect/Base/utils.py @@ -0,0 +1,45 @@ +from typing import Dict + + +async def merge_attribute(base_attr: Dict, attribute_bonus: Dict) -> Dict: + # hp attack defence need base_value and add_value + merged_attr = {} + for attribute in attribute_bonus: + if ( + attribute.__contains__('Attack') + or attribute.__contains__('Defence') + or attribute.__contains__('HP') + or attribute.__contains__('Speed') + ): + if attribute.__contains__('Delta'): + attr = attribute.split('Delta')[0].lower() + attr_value = base_attr.get(attr, 0) + merged_attr[attr] = attr_value + attribute_bonus[attribute] + elif attribute.__contains__('AddedRatio'): + attr = attribute.split('AddedRatio')[0].lower() + attr_value = base_attr.get(attr, 0) + merged_attr[attr] = attr_value + base_attr[attr] * ( + 1 + attribute_bonus[attribute] + ) + else: + raise Exception(f'attribute error {attribute}') + elif attribute.__contains__('Base'): + attr = attribute.split('Base')[0] + attr_value = base_attr.get(attr, 0) + merged_attr[attr] = attr_value + attribute_bonus[attribute] + elif attribute.__contains__('AddedRatio'): + # attr = attribute.split('AddedRatio')[0] + attr_value = base_attr.get(attribute, 0) + merged_attr[attribute] = attr_value + attribute_bonus[attribute] + elif attribute.__contains__('DmgAdd'): + attr_value = base_attr.get(attribute, 0) + merged_attr[attribute] = attr_value + attribute_bonus[attribute] + elif attribute == 'ignore_defence': + attr_value = base_attr.get(attribute, 0) + merged_attr[attribute] = attr_value + attribute_bonus[attribute] + elif attribute.__contains__('ResistancePenetration'): + attr_value = base_attr.get(attribute, 0) + merged_attr[attribute] = attr_value + attribute_bonus[attribute] + else: + raise Exception(f'attribute error {attribute}') + return merged_attr diff --git a/StarRailUID/starrailuid_damagecal/effect/Hunt/seele.json b/StarRailUID/starrailuid_damagecal/effect/Hunt/seele.json deleted file mode 100644 index 17a3082..0000000 --- a/StarRailUID/starrailuid_damagecal/effect/Hunt/seele.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "details": { - "A普攻伤害": "a", - "E战技伤害": "e", - "Q终结技伤害": "q" - }, - "buffs": { - "Talent": { - "id": 110204, - "desc": "希儿天赋:击杀敌人进入增幅状态提高伤害", - "type": "skillDmg", - "value": [ - 0.4, - 0.44, - 0.48, - 0.52, - 0.56, - 0.6, - 0.65, - 0.7, - 0.75, - 0.8, - 0.84, - 0.88, - 0.92, - 0.96, - 1.0 - ] - }, - "Skill": { - "desc": "希儿战技:释放战技后,速度提高25%", - "type": "SpeedAddedRatio", - "value": 0.25 - }, - "Eidolons": [ - { - "cons": 1, - "desc": "对生命小于80%的敌人造成伤害时,暴击率提高15%", - "type": "CriticalChance", - "value": 0.15 - }, - { - "cons": 2, - "desc": "释放战技后,2层Buff速度提高50%", - "type": "SpeedAddedRatio", - "value": 0.5 - } - ], - "SkillTree": [ - { - "tree": 2, - "desc": "行迹-割裂:量子抗性穿透提高20", - "type": "QuantumAddedRatio", - "value": 0.2 - } - ] - } -} diff --git a/StarRailUID/starrailuid_start/__init__.py b/StarRailUID/starrailuid_start/__init__.py index c258a46..0238f09 100644 --- a/StarRailUID/starrailuid_start/__init__.py +++ b/StarRailUID/starrailuid_start/__init__.py @@ -3,10 +3,14 @@ import threading from gsuid_core.logger import logger +from ..utils.api import get_sqla +from ..starrailuid_resource import startup + async def all_start(): try: - pass + get_sqla('TEMP') + await startup() except Exception as e: logger.exception(e) diff --git a/StarRailUID/utils/resource/download_from_cos.py b/StarRailUID/utils/resource/download_from_cos.py index 26307f9..37e49e5 100644 --- a/StarRailUID/utils/resource/download_from_cos.py +++ b/StarRailUID/utils/resource/download_from_cos.py @@ -66,7 +66,7 @@ async def download_all_file_from_cos(): else: path = Path(WIKI_PATH / resource_type / name) if path.exists(): - is_diff = size == str(os.stat(path).st_size) + is_diff = size == os.stat(path).st_size else: is_diff = True if (