实验性支持希儿伤害计算

This commit is contained in:
qwerdvd 2023-05-27 21:34:17 +08:00
parent cd6a6316ee
commit f3273bfec4
15 changed files with 595 additions and 178 deletions

View File

@ -29,6 +29,9 @@ class Character:
self.add_attr = {} self.add_attr = {}
self.equipment = card_prop['equipmentInfo'] self.equipment = card_prop['equipmentInfo']
self.rarity = card_prop['avatarRarity'] self.rarity = card_prop['avatarRarity']
self.eidolons = (
card_prop['rankList'] if card_prop.get('rankList') else []
)
# 伤害计算 # 伤害计算
self.def_ignore = 0 self.def_ignore = 0

View File

@ -16,8 +16,10 @@ async def cal(char_data: Dict):
raw_data['avatar']['id'] = char.char_id raw_data['avatar']['id'] = char.char_id
raw_data['avatar']['level'] = char.char_level raw_data['avatar']['level'] = char.char_level
raw_data['avatar']['rank'] = char.char_rank raw_data['avatar']['rank'] = char.char_rank
raw_data['avatar']['element'] = char.char_element
raw_data['avatar']['promotion'] = char.char_promotion raw_data['avatar']['promotion'] = char.char_promotion
raw_data['avatar']['attribute_bonus'] = char.attribute_bonus 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']['id'] = char.equipment['equipmentID']
raw_data['weapon']['level'] = char.equipment['equipmentLevel'] raw_data['weapon']['level'] = char.equipment['equipmentLevel']
@ -26,8 +28,10 @@ async def cal(char_data: Dict):
raw_data['relic'] = char.char_relic raw_data['relic'] = char.char_relic
role = RoleInstance(raw_data) raw_data['skill'] = char.char_skill
await role.cal_role_base_attr()
await role.cal_relic_attr_add() for skill_type in ['Normal', 'BPSkill', 'Ultra']:
await role.cal_avatar_attr_add() role = RoleInstance(raw_data)
print(role)
await role.cal_damage(skill_type)
return '还没写完呢' return '还没写完呢'

View File

@ -1,45 +1,54 @@
from typing import Dict import json
from pathlib import Path
from typing import Dict, List
from abc import abstractmethod from abc import abstractmethod
from mpmath import mp from mpmath import mp
from .Skill import BaseSkills
from ....utils.excel.read_excel import AvatarPromotion 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 mp.dps = 14
class BaseSkills: class BaseAvatarBuff:
@abstractmethod def __init__(self, char: Dict, skills: List):
async def Basic_ATK(self): self.extra_ability_id = []
... for extra_ability in char['extra_ability']:
self.extra_ability_id.append(extra_ability['extraAbilityId'])
@abstractmethod
async def Skill(self):
...
@abstractmethod
async def Ultimate(self):
...
@abstractmethod
async def Talent(self):
...
@abstractmethod @abstractmethod
async def Technique(self): async def Technique(self):
... ...
@abstractmethod
async def eidolons(self):
...
@abstractmethod
async def extra_ability(self):
...
class BaseAvatar: 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_id = char['id']
self.avatar_level = char['level'] self.avatar_level = char['level']
self.avatar_rank = char['rank'] self.avatar_rank = char['rank']
self.avatar_element = char['element']
self.avatar_promotion = char['promotion'] self.avatar_promotion = char['promotion']
self.avatar_attribute_bonus = char['attribute_bonus'] self.avatar_attribute_bonus = char['attribute_bonus']
self.avatar_extra_ability = char['extra_ability']
self.avatar_attribute = {} self.avatar_attribute = {}
async def get_attribute(self): def get_attribute(self):
promotion = AvatarPromotion[str(self.avatar_id)][ promotion = AvatarPromotion[str(self.avatar_id)][
str(self.avatar_promotion) str(self.avatar_promotion)
] ]
@ -73,28 +82,67 @@ class BaseAvatar:
promotion["BaseAggro"]['Value'] 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 BPSkill(self):
def __init__(self, char: Dict): return mp.mpf(
super().__init__(char) 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 pass
async def Skill(self): def eidolons(self):
pass 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): def extra_ability(self):
pass # 额外能力 割裂 抗性穿透提高20
if 1102102 in self.Buff.extra_ability_id:
async def Talent(self): self.extra_ability_attribute[
pass 'QuantumResistancePenetration'
] = mp.mpf(0.2)
async def Technique(self):
pass
class Avatar: class Avatar:
def __new__(cls, char: Dict): def __new__(cls, char: Dict, skills: List):
if char['id'] == 1102: if char['id'] == 1102:
return Seele(char) return Seele(char, skills)

View File

@ -0,0 +1,9 @@
{
"1102": [
{
"id": 1102102,
"property": "QuantumResistancePenetration",
"value": 0.2
}
]
}

View File

@ -0,0 +1,9 @@
{
"1102": [
{
"rank": 1,
"property" :"CriticalDamageBase",
"value": 0.2
}
]
}

View File

@ -3,6 +3,10 @@ from abc import abstractmethod
from collections import Counter from collections import Counter
from mpmath import mp 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 mp.dps = 14
@ -16,11 +20,19 @@ class SingleRelic:
self.relic_level = relic.get('Level', 0) self.relic_level = relic.get('Level', 0)
self.relic_attribute_bonus = {} self.relic_attribute_bonus = {}
async def get_attribute_(self): def get_attribute_(self):
# MainAffix # MainAffix
self.relic_attribute_bonus[ if (
self.raw_relic['MainAffix']['Property'] 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 # SubAffix
if self.raw_relic.get('SubAffixList'): if self.raw_relic.get('SubAffixList'):
@ -34,45 +46,93 @@ class SingleRelic:
class BaseRelicSetSkill: 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 @abstractmethod
async def check(self): async def check(self, base_attr: Dict, attribute_bonus: Dict):
... ...
@abstractmethod @abstractmethod
async def set_skill_ability(self, char): async def set_skill_ability(self, base_attr: Dict, attribute_bonus: Dict):
''' '''
战斗加成属性, set_skill_property() 互斥 战斗加成属性, set_skill_property() 互斥
''' '''
... ...
@abstractmethod def set_skill_property_ability(self):
async def set_skill_property_ability(self, char): set_property = ''
''' set_value = mp.mpf(0)
面板加成属性, set_skill_ability_param() 互斥 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): class Relic108(BaseRelicSetSkill):
async def check(self): def __init__(self, set_id: int, count: int):
pass super().__init__(set_id, count)
async def set_skill_ability(self, char): async def check(self, base_attr: Dict, attribute_bonus: Dict):
pass '''
装备者对敌方目标造成伤害
目标拥有量子属性弱点
'''
logger.info('Relic108 check success')
return True
async def set_skill_property_ability(self, char): async def set_skill_ability(self, base_attr: Dict, attribute_bonus: Dict):
pass 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): class Relic306(BaseRelicSetSkill):
async def check(self): def __init__(self, set_id: int, count: int):
pass super().__init__(set_id, count)
async def set_skill_ability(self, char): async def check(self, base_attr: Dict, attribute_bonus: Dict):
pass '''
装备者当前暴击率大于等于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): async def set_skill_ability(self, base_attr: Dict, attribute_bonus: Dict):
pass 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: class RelicSet:
@ -84,10 +144,11 @@ class RelicSet:
OBJECT: SingleRelic OBJECT: SingleRelic
Unknow: SingleRelic Unknow: SingleRelic
set_id_counter: List set_id_counter: List = []
SetSkill: List = [] SetSkill: List
def __init__(self, relic_list: List): def __init__(self, relic_list: List):
self.SetSkill = []
set_id_list = [] set_id_list = []
for relic in relic_list: for relic in relic_list:
set_id_list.append(relic['SetId']) set_id_list.append(relic['SetId'])
@ -108,20 +169,21 @@ class RelicSet:
self.Unknow = SingleRelic(relic) self.Unknow = SingleRelic(relic)
self.set_id_counter: List = Counter(set_id_list).most_common() 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__: for item in self.__dict__:
if type(self.__dict__[item]) != SingleRelic: if type(self.__dict__[item]) != SingleRelic:
break 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: for item in self.set_id_counter:
set_id = item[0] set_id = item[0]
count = item[1] count = item[1]
if count == 1: if count == 1:
break break
if set_id == 108: if set_id == 108:
self.SetSkill.append(Relic108()) self.SetSkill.append(Relic108(set_id, count))
if set_id == 306: if set_id == 306:
self.SetSkill.append(Relic306()) self.SetSkill.append(Relic306(set_id, count))

View File

@ -1,9 +1,11 @@
from typing import Dict from typing import Dict
from mpmath import mp from mpmath import mp
from gsuid_core.logger import logger
from .Avatar import Avatar from .Avatar import Avatar
from .Weapon import Weapon from .Weapon import Weapon
from .utils import merge_attribute
from .Relic import RelicSet, SingleRelic from .Relic import RelicSet, SingleRelic
mp.dps = 14 mp.dps = 14
@ -13,15 +15,21 @@ class RoleInstance:
def __init__(self, raw_data: Dict): def __init__(self, raw_data: Dict):
self.raw_data = raw_data 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.weapon = Weapon(raw_data['weapon'])
self.relic_set = RelicSet(raw_data['relic']) self.relic_set = RelicSet(raw_data['relic'])
self.base_attr = {} self.base_attr = {}
self.attribute_bonus = {} self.attribute_bonus = {}
async def cal_role_base_attr(self): self.cal_role_base_attr()
await self.avatar.get_attribute() 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'] avatar_attribute = self.avatar.__dict__['avatar_attribute']
for attribute in avatar_attribute: for attribute in avatar_attribute:
if attribute in self.base_attr: if attribute in self.base_attr:
@ -29,16 +37,17 @@ class RoleInstance:
else: else:
self.base_attr[attribute] = avatar_attribute[attribute] self.base_attr[attribute] = avatar_attribute[attribute]
await self.weapon.get_attribute() self.weapon.get_attribute()
weapon_attribute = self.weapon.__dict__['weapon_attribute'] weapon_attribute = self.weapon.__dict__['weapon_base_attribute']
for attribute in weapon_attribute: for attribute in weapon_attribute:
if attribute in self.base_attr: if attribute in self.base_attr:
self.base_attr[attribute] += weapon_attribute[attribute] self.base_attr[attribute] += weapon_attribute[attribute]
else: else:
self.base_attr[attribute] = weapon_attribute[attribute] self.base_attr[attribute] = weapon_attribute[attribute]
async def cal_relic_attr_add(self): def cal_relic_attr_add(self):
await self.relic_set.get_attribute() # 单件属性
self.relic_set.get_attribute()
for relic_type in self.relic_set.__dict__: for relic_type in self.relic_set.__dict__:
if type(self.relic_set.__dict__[relic_type]) != SingleRelic: if type(self.relic_set.__dict__[relic_type]) != SingleRelic:
break break
@ -53,7 +62,19 @@ class RoleInstance:
attribute attribute
] = relic.relic_attribute_bonus[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 attribute_bonus = self.avatar.avatar_attribute_bonus
for bonus in attribute_bonus: for bonus in attribute_bonus:
status_add = bonus['statusAdd'] status_add = bonus['statusAdd']
@ -63,3 +84,144 @@ class RoleInstance:
self.attribute_bonus[bonus_property] += value self.attribute_bonus[bonus_property] += value
else: else:
self.attribute_bonus[bonus_property] = value 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}')

View File

@ -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

View File

@ -21,31 +21,37 @@ class IntheNight(BaseWeapon):
async def check(self): async def check(self):
pass pass
async def weapon_ability(self, char): async def weapon_ability(self, base_attr: Dict, attribute_bonus: Dict):
char = await self.weapon_property_ability(char) char_speed = mp.mpf(base_attr.get('speed', 0))
char_speed = mp.mpf(char.base_attributes['speed'])
count_ = min(6, int(mp.floor((char_speed - 100) / 10))) count_ = min(6, int(mp.floor((char_speed - 100) / 10)))
char.a_dmg += ( normal_dmg_add = attribute_bonus.get('NormalDmgAdd', 0)
mp.mpf(weapon_effect['23001']['Param']['a_dmg'][self.weapon_rank]) attribute_bonus['NormalDmgAdd'] = normal_dmg_add + (
* count_
)
char.e_dmg += (
mp.mpf(weapon_effect['23001']['Param']['e_dmg'][self.weapon_rank])
* count_
)
char.q_crit_dmg += (
mp.mpf( mp.mpf(
weapon_effect['23001']['Param']['q_crit_dmg'][self.weapon_rank] weapon_effect['23001']['Param']['a_dmg'][self.weapon_rank - 1]
) )
* count_ * count_
) )
return char bp_skill_dmg_add = attribute_bonus.get('BPSkillDmgAdd', 0)
attribute_bonus['BPSkillDmgAdd'] = bp_skill_dmg_add + (
async def weapon_property_ability(self, char): mp.mpf(
char.CriticalChanceBase += mp.mpf( weapon_effect['23001']['Param']['e_dmg'][self.weapon_rank - 1]
weapon_effect['23001']['AbilityProperty'][self.weapon_rank] )
* 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): class CruisingintheStellarSea(BaseWeapon):
@ -57,26 +63,23 @@ class CruisingintheStellarSea(BaseWeapon):
# 装备者消灭敌方目标 # 装备者消灭敌方目标
return True return True
async def weapon_ability(self, char): async def weapon_ability(self, base_attr: Dict, attribute_bonus: Dict):
char = await self.weapon_property_ability(char) if await self.check():
if self.check(): critical_chance_base = attribute_bonus.get('CriticalChanceBase', 0)
char.CriticalChanceBase += mp.mpf( attribute_bonus[
'CriticalChanceBase'
] = critical_chance_base + mp.mpf(
weapon_effect['24001']['Param']['CriticalChance'][ 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'][ weapon_effect['24001']['Param']['AttackAddedRatio'][
self.weapon_rank self.weapon_rank - 1
] ]
) )
return char return attribute_bonus
async def weapon_property_ability(self, char):
char.CriticalChanceBase += mp.mpf(
weapon_effect['24001']['AbilityProperty'][self.weapon_rank]
)
return char
class HuntWeapon: class HuntWeapon:

View File

@ -4,6 +4,7 @@ from abc import abstractmethod
from mpmath import mp from mpmath import mp
from ....utils.excel.read_excel import EquipmentPromotion from ....utils.excel.read_excel import EquipmentPromotion
from ....utils.map.SR_MAP_PATH import EquipmentID2AbilityProperty
mp.dps = 14 mp.dps = 14
@ -14,42 +15,51 @@ class BaseWeapon:
self.weapon_level = weapon['level'] self.weapon_level = weapon['level']
self.weapon_rank = weapon['rank'] self.weapon_rank = weapon['rank']
self.weapon_promotion = weapon['promotion'] self.weapon_promotion = weapon['promotion']
self.weapon_base_attribute = {}
self.weapon_attribute = {} self.weapon_attribute = {}
self.weapon_property_ability()
@abstractmethod @abstractmethod
async def weapon_ability(self, char): async def weapon_ability(self, base_attr: Dict, attribute_bonus: Dict):
''' '''
战斗加成属性, weapon_property_ability() 互斥 战斗加成属性, weapon_property_ability() 互斥
''' '''
... ...
@abstractmethod def weapon_property_ability(self):
async def weapon_property_ability(self, char):
''' '''
面板加成属性, weapon_ability() 互斥 面板加成属性, 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 @abstractmethod
async def check(self): async def check(self):
... ...
async def get_attribute(self): def get_attribute(self):
promotion = EquipmentPromotion[str(self.weapon_id)][ promotion = EquipmentPromotion[str(self.weapon_id)][
str(self.weapon_promotion) str(self.weapon_promotion)
] ]
self.weapon_attribute['hp'] = mp.mpf( self.weapon_base_attribute['hp'] = mp.mpf(
promotion["BaseHP"]['Value'] promotion["BaseHP"]['Value']
) + mp.mpf(promotion["BaseHPAdd"]['Value']) * (self.weapon_level - 1) ) + 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'] promotion["BaseAttack"]['Value']
) + mp.mpf(promotion["BaseAttackAdd"]['Value']) * ( ) + mp.mpf(promotion["BaseAttackAdd"]['Value']) * (
self.weapon_level - 1 self.weapon_level - 1
) )
self.weapon_attribute['defence'] = mp.mpf( self.weapon_base_attribute['defence'] = mp.mpf(
promotion["BaseDefence"]['Value'] promotion["BaseDefence"]['Value']
) + mp.mpf(promotion["BaseDefenceAdd"]['Value']) * ( ) + mp.mpf(promotion["BaseDefenceAdd"]['Value']) * (
self.weapon_level - 1 self.weapon_level - 1

View File

@ -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
]
}
}

View File

@ -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

View File

@ -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
}
]
}
}

View File

@ -3,10 +3,14 @@ import threading
from gsuid_core.logger import logger from gsuid_core.logger import logger
from ..utils.api import get_sqla
from ..starrailuid_resource import startup
async def all_start(): async def all_start():
try: try:
pass get_sqla('TEMP')
await startup()
except Exception as e: except Exception as e:
logger.exception(e) logger.exception(e)

View File

@ -66,7 +66,7 @@ async def download_all_file_from_cos():
else: else:
path = Path(WIKI_PATH / resource_type / name) path = Path(WIKI_PATH / resource_type / name)
if path.exists(): if path.exists():
is_diff = size == str(os.stat(path).st_size) is_diff = size == os.stat(path).st_size
else: else:
is_diff = True is_diff = True
if ( if (