♻️ 重构伤害计算

This commit is contained in:
qwerdvd 2023-09-05 00:32:06 +08:00
parent 776e936119
commit 433af75eee
26 changed files with 380 additions and 243 deletions

View File

@ -15,12 +15,17 @@ from ..utils.error_reply import UID_HINT
from ..utils.image.convert import convert_img from ..utils.image.convert import convert_img
from ..utils.resource.RESOURCE_PATH import TEMP_PATH from ..utils.resource.RESOURCE_PATH import TEMP_PATH
from ..utils.sr_prefix import PREFIX from ..utils.sr_prefix import PREFIX
from .draw_char_img import draw_char_info_img from .cal_damage import cal
from .draw_char_img import (
draw_char_info_img,
get_char_data,
)
from .to_card import api_to_card from .to_card import api_to_card
sv_char_info_config = SV('sr面板设置', pm=2) sv_char_info_config = SV('sr面板设置', pm=2)
sv_get_char_info = SV('sr面板查询', priority=10) sv_get_char_info = SV('sr面板查询', priority=10)
sv_get_sr_original_pic = SV('sr查看面板原图', priority=5) sv_get_sr_original_pic = SV('sr查看面板原图', priority=5)
sv_char_damage_cal = SV('sr伤害计算')
@sv_get_char_info.on_prefix(f'{PREFIX}查询') @sv_get_char_info.on_prefix(f'{PREFIX}查询')
@ -72,3 +77,25 @@ async def send_card_info(bot: Bot, ev: Event):
await bot.logger.info(f'UID{uid}获取角色数据成功!') await bot.logger.info(f'UID{uid}获取角色数据成功!')
await bot.send(im) await bot.send(im)
return None return None
@sv_char_damage_cal.on_prefix(f'{PREFIX}伤害计算')
async def send_damage_msg(bot: Bot, ev: Event):
msg = ''.join(re.findall('[\u4e00-\u9fa5 ]', ev.text))
if not msg:
return None
await bot.logger.info('开始执行[角色伤害计算]')
# 获取uid
sr_uid = await get_uid(bot, ev)
if sr_uid is None:
return await bot.send(UID_HINT)
await bot.logger.info(f'[角色伤害计算]uid: {sr_uid}')
char_name = ' '.join(re.findall('[\u4e00-\u9fa5]+', msg))
char_data = await get_char_data(sr_uid, char_name)
if isinstance(char_data, str):
return await bot.send(char_data)
im = await cal(char_data)
await bot.send(im)
return None

View File

@ -0,0 +1,20 @@
from typing import Dict
from mpmath import mp
from .draw_char_img import cal_char_info
from .effect.Role import RoleInstance
mp.dps = 14
async def cal(char_data: Dict):
char = await cal_char_info(char_data)
im = []
for skill_type in ['Normal', 'BPSkill', 'Ultra']:
role = RoleInstance(char)
im_tmp = await role.cal_damage(skill_type)
im.append(im_tmp)
return im

View File

@ -37,7 +37,7 @@ from ..utils.resource.RESOURCE_PATH import (
SKILL_PATH, SKILL_PATH,
WEAPON_PATH, WEAPON_PATH,
) )
from .mono.Character import Character from .effect.Base.Character import Character
from .to_data import api_to_dict from .to_data import api_to_dict
mp.dps = 14 mp.dps = 14

View File

@ -1,8 +1,12 @@
from typing import Dict, List from typing import List
from mpmath import mp from mpmath import mp
from ..Base.AvatarBase import BaseAvatar, BaseAvatarBuff from ..Base.AvatarBase import BaseAvatar, BaseAvatarBuff
from ..Base.model import (
DamageInstanceAvatar,
DamageInstanceSkill,
)
mp.dps = 14 mp.dps = 14
@ -10,7 +14,7 @@ mp.dps = 14
class Seele(BaseAvatar): class Seele(BaseAvatar):
Buff: BaseAvatarBuff Buff: BaseAvatarBuff
def __init__(self, char: Dict, skills: List): def __init__(self, char: DamageInstanceAvatar, skills: List[DamageInstanceSkill]):
super().__init__(char=char, skills=skills) super().__init__(char=char, skills=skills)
self.eidolon_attribute = {} self.eidolon_attribute = {}
self.extra_ability_attribute = {} self.extra_ability_attribute = {}
@ -35,7 +39,8 @@ class Seele(BaseAvatar):
class Avatar(Seele): class Avatar(Seele):
def __init__(self, char: Dict, skills: List): @classmethod
if char['id'] == 1102: def create(cls, char: DamageInstanceAvatar, skills: List[DamageInstanceSkill]):
if char.id_ == 1102:
return Seele(char, skills) return Seele(char, skills)
return None raise Exception('角色不存在')

View File

@ -1,11 +1,12 @@
import json import json
from abc import abstractmethod from abc import abstractmethod
from pathlib import Path from pathlib import Path
from typing import Dict, List from typing import List
from mpmath import mp from mpmath import mp
from ....utils.excel.read_excel import AvatarPromotion from ....utils.excel.read_excel import AvatarPromotion
from .model import DamageInstanceAvatar, DamageInstanceSkill
from .SkillBase import BaseSkills from .SkillBase import BaseSkills
path = Path(__file__).parent.parent path = Path(__file__).parent.parent
@ -16,10 +17,13 @@ mp.dps = 14
class BaseAvatarBuff: class BaseAvatarBuff:
def __init__(self, char: Dict, skills: List): @classmethod
self.extra_ability_id = [] def create(cls, char: DamageInstanceAvatar, skills: List[DamageInstanceSkill]):
for extra_ability in char['extra_ability']: cls.extra_ability_id = []
self.extra_ability_id.append(extra_ability['extraAbilityId']) if char.extra_ability:
for extra_ability in char.extra_ability:
cls.extra_ability_id.append(extra_ability['extraAbilityId'])
return cls
@abstractmethod @abstractmethod
async def Technique(self): async def Technique(self):
@ -35,19 +39,16 @@ class BaseAvatarBuff:
class BaseAvatar: class BaseAvatar:
Skill: BaseSkills def __init__(self, char: DamageInstanceAvatar, skills: List[DamageInstanceSkill]):
Buff: BaseAvatarBuff self.Skill = BaseSkills.create(char=char, skills=skills)
self.Buff = BaseAvatarBuff.create(char=char, skills=skills)
def __init__(self, char: Dict, skills: List): self.avatar_id = char.id_
self.Skill = BaseSkills(char=char, skills=skills) self.avatar_level = char.level
self.Buff = BaseAvatarBuff(char=char, skills=skills) self.avatar_rank = char.rank
self.avatar_id = char['id'] self.avatar_element = char.element
self.avatar_level = char['level'] self.avatar_promotion = char.promotion
self.avatar_rank = char['rank'] self.avatar_attribute_bonus = char.attribute_bonus
self.avatar_element = char['element'] self.avatar_extra_ability = char.extra_ability
self.avatar_promotion = char['promotion']
self.avatar_attribute_bonus = char['attribute_bonus']
self.avatar_extra_ability = char['extra_ability']
self.avatar_attribute = {} self.avatar_attribute = {}
self.get_attribute() self.get_attribute()

View File

@ -5,11 +5,10 @@ from typing import Dict
from loguru import logger from loguru import logger
from mpmath import mp from mpmath import mp
from ...utils.map.SR_MAP_PATH import EquipmentID2AbilityProperty, RelicSetSkill from ....utils.map.SR_MAP_PATH import EquipmentID2AbilityProperty, RelicSetSkill
mp.dps = 14 mp.dps = 14
class Character: class Character:
def __init__(self, card_prop: Dict): def __init__(self, card_prop: Dict):
# 面板数据 # 面板数据
@ -138,4 +137,4 @@ class Character:
self.add_attr[set_property] = str(set_value) self.add_attr[set_property] = str(set_value)
logger.info(json.dumps(self.base_attributes)) logger.info(json.dumps(self.base_attributes))
logger.info(json.dumps(self.add_attr)) logger.info(json.dumps(self.add_attr))

View File

@ -1,42 +1,44 @@
from typing import Dict
from abc import abstractmethod from abc import abstractmethod
from typing import Dict
from mpmath import mp from mpmath import mp
from gsuid_core.logger import logger from gsuid_core.logger import logger
from ....utils.map.SR_MAP_PATH import RelicSetSkill from ....utils.map.SR_MAP_PATH import RelicSetSkill
from .model import DamageInstanceRelic
mp.dps = 14 mp.dps = 14
class SingleRelic: class SingleRelic:
def __init__(self, relic: Dict): def __init__(self, relic: DamageInstanceRelic):
self.raw_relic = relic self.raw_relic = relic
self.relic_id = relic['relicId'] self.relic_id = relic.relicId
self.set_id = relic['SetId'] self.set_id = relic.SetId
self.relic_type = relic['Type'] self.relic_type = relic.Type
self.relic_level = relic.get('Level', 0) self.relic_level = relic.Level
self.relic_attribute_bonus = {} self.relic_attribute_bonus = {}
def get_attribute_(self): def get_attribute_(self):
# MainAffix # MainAffix
if ( if (
self.raw_relic['MainAffix']['Property'] self.raw_relic.MainAffix.Property
in self.relic_attribute_bonus in self.relic_attribute_bonus
): ):
self.relic_attribute_bonus[ self.relic_attribute_bonus[
self.raw_relic['MainAffix']['Property'] self.raw_relic.MainAffix.Property
] += mp.mpf(self.raw_relic['MainAffix']['Value']) ] += mp.mpf(self.raw_relic.MainAffix.Value)
else: else:
self.relic_attribute_bonus[ self.relic_attribute_bonus[
self.raw_relic['MainAffix']['Property'] self.raw_relic.MainAffix.Property
] = mp.mpf(self.raw_relic['MainAffix']['Value']) ] = mp.mpf(self.raw_relic.MainAffix.Value)
# SubAffix # SubAffix
if self.raw_relic.get('SubAffixList'): if self.raw_relic.SubAffixList:
for sub_affix in self.raw_relic['SubAffixList']: for sub_affix in self.raw_relic.SubAffixList:
sub_affix_property = sub_affix['Property'] sub_affix_property = sub_affix.Property
value = mp.mpf(sub_affix['Value']) value = mp.mpf(sub_affix.Value)
if sub_affix_property in self.relic_attribute_bonus: if sub_affix_property in self.relic_attribute_bonus:
self.relic_attribute_bonus[sub_affix_property] += value self.relic_attribute_bonus[sub_affix_property] += value
else: else:

View File

@ -1,9 +1,11 @@
import json import json
from pathlib import Path from pathlib import Path
from typing import Dict, List from typing import List
from mpmath import mp from mpmath import mp
from .model import DamageInstanceAvatar, DamageInstanceSkill
mp.dps = 14 mp.dps = 14
@ -13,9 +15,9 @@ with Path.open(path / 'Excel' / 'seele.json', encoding='utf-8') as f:
class SingleSkill: class SingleSkill:
def __init__(self, skill: Dict): def __init__(self, skill: DamageInstanceSkill):
self.id = skill['skillId'] self.id = skill.skillId
self.level = skill['skillLevel'] self.level = skill.skillLevel
class BaseSkills: class BaseSkills:
@ -25,20 +27,22 @@ class BaseSkills:
Maze_: SingleSkill Maze_: SingleSkill
Talent_: SingleSkill Talent_: SingleSkill
def __init__(self, char: Dict, skills: List): @classmethod
def create(cls, char: DamageInstanceAvatar, skills: List[DamageInstanceSkill]):
for skill in skills: for skill in skills:
skill_attack_type = skill['skillAttackType'] skill_attack_type = skill.skillAttackType
if skill_attack_type == 'Normal': if skill_attack_type == 'Normal':
self.Normal_ = SingleSkill(skill) cls.Normal_ = SingleSkill(skill)
elif skill_attack_type == 'BPSkill': elif skill_attack_type == 'BPSkill':
self.BPSkill_ = SingleSkill(skill) cls.BPSkill_ = SingleSkill(skill)
elif skill_attack_type == 'Ultra': elif skill_attack_type == 'Ultra':
self.Ultra_ = SingleSkill(skill) cls.Ultra_ = SingleSkill(skill)
elif skill_attack_type == 'Maze': elif skill_attack_type == 'Maze':
self.Maze_ = SingleSkill(skill) cls.Maze_ = SingleSkill(skill)
elif skill_attack_type == '': elif skill_attack_type == '':
self.Talent_ = SingleSkill(skill) cls.Talent_ = SingleSkill(skill)
else: else:
raise ValueError( raise ValueError(
f'Unknown skillAttackType: {skill_attack_type}' f'Unknown skillAttackType: {skill_attack_type}'
) )
return cls

View File

@ -1,20 +1,21 @@
from typing import Dict
from abc import abstractmethod from abc import abstractmethod
from typing import Dict
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 from ....utils.map.SR_MAP_PATH import EquipmentID2AbilityProperty
from .model import DamageInstanceWeapon
mp.dps = 14 mp.dps = 14
class BaseWeapon: class BaseWeapon:
def __init__(self, weapon: Dict): def __init__(self, weapon: DamageInstanceWeapon):
self.weapon_id = weapon['id'] self.weapon_id = weapon.id_
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_base_attribute = {}
self.weapon_attribute = {} self.weapon_attribute = {}
self.get_attribute() self.get_attribute()

View File

@ -0,0 +1,101 @@
from typing import List
from msgspec import Struct, field
class DamageInstanceSkill(Struct):
skillId: int
skillName: str
skillEffect: str
skillAttackType: str
skillLevel: int
class DamageInstanceRelicSubAffix(Struct):
SubAffixID: int
Property: str
Name: str
Cnt: int
Step: int
Value: str
class DamageInstanceRelicMainAffix(Struct):
AffixID: int
Property: str
Name: str
Value: str
class DamageInstanceRelic(Struct):
relicId: int
relicName: str
SetId: int
SetName: str
Type: int
MainAffix: DamageInstanceRelicMainAffix
SubAffixList: List[DamageInstanceRelicSubAffix] | None
Level: int = 0
class DamageInstanceWeapon(Struct):
id_: str = field(name='id')
level: int
rank: int
promotion: int
class AttributeBounsStatusAdd(Struct):
property: str
name: str
value: int
class DamageInstanceAvatarAttributeBouns(Struct):
attributeBonusId: int
attributeBonusLevel: int
statusAdd: AttributeBounsStatusAdd
class DamageInstanceAvatar(Struct):
id_: str = field(name='id')
level: int
rank: int
element: str
promotion: int
attribute_bonus: List[DamageInstanceAvatarAttributeBouns] | None
extra_ability: List | None
class DamageInstance:
avatar: DamageInstanceAvatar
weapon: DamageInstanceWeapon
relic: List[DamageInstanceRelic]
skill: List[DamageInstanceSkill]
def __init__(self, char):
self.avatar = DamageInstanceAvatar(
id_=char.char_id,
level=char.char_level,
rank=char.char_rank,
element=char.char_element,
promotion=char.char_promotion,
attribute_bonus=char.attribute_bonus,
extra_ability=char.extra_ability,
)
self.weapon = DamageInstanceWeapon(
id_=char.equipment['equipmentID'],
level=char.equipment['equipmentLevel'],
rank=char.equipment['equipmentRank'],
promotion=char.equipment['equipmentPromotion'],
)
self.relic = []
for relic in char.char_relic:
self.relic.append(
DamageInstanceRelic(**relic)
)
self.skill = []
for skill in char.char_skill:
self.skill.append(
DamageInstanceSkill(**skill)
)

View File

@ -5,6 +5,7 @@ from mpmath import mp
from gsuid_core.logger import logger from gsuid_core.logger import logger
from ..Base.model import DamageInstanceRelic
from ..Base.RelicBase import BaseRelicSetSkill, SingleRelic from ..Base.RelicBase import BaseRelicSetSkill, SingleRelic
from ..utils import merge_attribute from ..utils import merge_attribute
@ -450,81 +451,86 @@ class RelicSet:
set_id_counter: List = [] set_id_counter: List = []
SetSkill: List SetSkill: List
def __init__(self, relic_list: List): @classmethod
self.SetSkill = [] def create(cls, relic_list: List[DamageInstanceRelic]):
cls.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)
if relic['Type'] == 1: if relic.Type == 1:
self.HEAD = SingleRelic(relic) cls.HEAD = SingleRelic(relic)
elif relic['Type'] == 2: elif relic.Type == 2:
self.HAND = SingleRelic(relic) cls.HAND = SingleRelic(relic)
elif relic['Type'] == 3: elif relic.Type == 3:
self.BODY = SingleRelic(relic) cls.BODY = SingleRelic(relic)
elif relic['Type'] == 4: elif relic.Type == 4:
self.FOOT = SingleRelic(relic) cls.FOOT = SingleRelic(relic)
elif relic['Type'] == 5: elif relic.Type == 5:
self.NECK = SingleRelic(relic) cls.NECK = SingleRelic(relic)
elif relic['Type'] == 6: elif relic.Type == 6:
self.OBJECT = SingleRelic(relic) cls.OBJECT = SingleRelic(relic)
else: else:
self.Unknow = SingleRelic(relic) cls.Unknow = SingleRelic(relic)
self.set_id_counter: List = Counter(set_id_list).most_common() cls.set_id_counter: List = Counter(set_id_list).most_common()
self.check_set() cls.check_set()
self.get_attribute() cls.get_attribute()
return cls
def get_attribute(self): @classmethod
for item in self.__dict__: def get_attribute(cls):
if type(self.__dict__[item]) == SingleRelic: for item in cls.__dict__:
self.__dict__[item].get_attribute_() if type(cls.__dict__[item]) == SingleRelic:
itme__: SingleRelic = cls.__dict__[item]
itme__.get_attribute_()
def check_set(self): @classmethod
for item in self.set_id_counter: def check_set(cls):
for item in cls.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 == 101: if set_id == 101:
self.SetSkill.append(Relic101(set_id, count)) cls.SetSkill.append(Relic101(set_id, count))
elif set_id == 102: elif set_id == 102:
self.SetSkill.append(Relic102(set_id, count)) cls.SetSkill.append(Relic102(set_id, count))
elif set_id == 103: elif set_id == 103:
self.SetSkill.append(Relic103(set_id, count)) cls.SetSkill.append(Relic103(set_id, count))
elif set_id == 104: elif set_id == 104:
self.SetSkill.append(Relic104(set_id, count)) cls.SetSkill.append(Relic104(set_id, count))
elif set_id == 105: elif set_id == 105:
self.SetSkill.append(Relic105(set_id, count)) cls.SetSkill.append(Relic105(set_id, count))
elif set_id == 106: elif set_id == 106:
self.SetSkill.append(Relic106(set_id, count)) cls.SetSkill.append(Relic106(set_id, count))
elif set_id == 107: elif set_id == 107:
self.SetSkill.append(Relic107(set_id, count)) cls.SetSkill.append(Relic107(set_id, count))
elif set_id == 108: elif set_id == 108:
self.SetSkill.append(Relic108(set_id, count)) cls.SetSkill.append(Relic108(set_id, count))
elif set_id == 109: elif set_id == 109:
self.SetSkill.append(Relic109(set_id, count)) cls.SetSkill.append(Relic109(set_id, count))
elif set_id == 110: elif set_id == 110:
self.SetSkill.append(Relic110(set_id, count)) cls.SetSkill.append(Relic110(set_id, count))
elif set_id == 111: elif set_id == 111:
self.SetSkill.append(Relic111(set_id, count)) cls.SetSkill.append(Relic111(set_id, count))
elif set_id == 112: elif set_id == 112:
self.SetSkill.append(Relic112(set_id, count)) cls.SetSkill.append(Relic112(set_id, count))
elif set_id == 301: elif set_id == 301:
self.SetSkill.append(Relic301(set_id, count)) cls.SetSkill.append(Relic301(set_id, count))
elif set_id == 302: elif set_id == 302:
self.SetSkill.append(Relic302(set_id, count)) cls.SetSkill.append(Relic302(set_id, count))
elif set_id == 303: elif set_id == 303:
self.SetSkill.append(Relic303(set_id, count)) cls.SetSkill.append(Relic303(set_id, count))
elif set_id == 304: elif set_id == 304:
self.SetSkill.append(Relic304(set_id, count)) cls.SetSkill.append(Relic304(set_id, count))
elif set_id == 305: elif set_id == 305:
self.SetSkill.append(Relic305(set_id, count)) cls.SetSkill.append(Relic305(set_id, count))
elif set_id == 306: elif set_id == 306:
self.SetSkill.append(Relic306(set_id, count)) cls.SetSkill.append(Relic306(set_id, count))
elif set_id == 307: elif set_id == 307:
self.SetSkill.append(Relic307(set_id, count)) cls.SetSkill.append(Relic307(set_id, count))
elif set_id == 308: elif set_id == 308:
self.SetSkill.append(Relic308(set_id, count)) cls.SetSkill.append(Relic308(set_id, count))
else: else:
raise Exception(f'Unknow SetId: {set_id}') raise Exception(f'Unknow SetId: {set_id}')

View File

@ -1,10 +1,9 @@
from typing import Dict
from mpmath import mp from mpmath import mp
from gsuid_core.logger import logger from gsuid_core.logger import logger
from .Avatar.Avatar import Avatar from .Avatar.Avatar import Avatar
from .Base.model import DamageInstance
from .Relic.Relic import RelicSet, SingleRelic from .Relic.Relic import RelicSet, SingleRelic
from .utils import merge_attribute from .utils import merge_attribute
from .Weapon.Weapon import Weapon from .Weapon.Weapon import Weapon
@ -13,12 +12,12 @@ mp.dps = 14
class RoleInstance: class RoleInstance:
def __init__(self, raw_data: Dict): def __init__(self, raw_data):
self.raw_data = raw_data self.raw_data = DamageInstance(raw_data)
self.avatar = Avatar(raw_data['avatar'], raw_data['skill']) self.avatar = Avatar.create(self.raw_data.avatar, self.raw_data.skill)
self.weapon = Weapon(raw_data['weapon']) self.weapon = Weapon.create(self.raw_data.weapon)
self.relic_set = RelicSet(raw_data['relic']) self.relic_set = RelicSet.create(self.raw_data.relic)
self.base_attr = {} self.base_attr = {}
self.attribute_bonus = {} self.attribute_bonus = {}
@ -31,7 +30,7 @@ class RoleInstance:
def cal_role_base_attr(self): def cal_role_base_attr(self):
logger.info('cal_role_base_attr') logger.info('cal_role_base_attr')
avatar_attribute = self.avatar.__dict__['avatar_attribute'] avatar_attribute = self.avatar.avatar_attribute
logger.info(avatar_attribute) logger.info(avatar_attribute)
for attribute in avatar_attribute: for attribute in avatar_attribute:
if attribute in self.base_attr: if attribute in self.base_attr:
@ -39,7 +38,7 @@ class RoleInstance:
else: else:
self.base_attr[attribute] = avatar_attribute[attribute] self.base_attr[attribute] = avatar_attribute[attribute]
weapon_attribute = self.weapon.__dict__['weapon_base_attribute'] weapon_attribute = self.weapon.weapon_base_attributes
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]
@ -47,6 +46,8 @@ class RoleInstance:
self.base_attr[attribute] = weapon_attribute[attribute] self.base_attr[attribute] = weapon_attribute[attribute]
def cal_relic_attr_add(self): def cal_relic_attr_add(self):
if self.attribute_bonus is None:
raise Exception('attribute_bonus is None')
# 单件属性 # 单件属性
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:
@ -75,16 +76,21 @@ class RoleInstance:
def cal_avatar_attr_add(self): 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: if attribute_bonus:
status_add = bonus['statusAdd'] for bonus in attribute_bonus:
bonus_property = status_add['property'] status_add = bonus.statusAdd
value = mp.mpf(status_add['value']) bonus_property = status_add.property
if bonus_property in self.attribute_bonus: value = mp.mpf(status_add.value)
self.attribute_bonus[bonus_property] += value if self.attribute_bonus is None:
else: raise Exception('attribute_bonus is None')
self.attribute_bonus[bonus_property] = value if bonus_property in self.attribute_bonus:
self.attribute_bonus[bonus_property] += value
else:
self.attribute_bonus[bonus_property] = value
def cal_avatar_eidolon_add(self): def cal_avatar_eidolon_add(self):
if self.attribute_bonus is None:
raise Exception('attribute_bonus is None')
for attribute in self.avatar.eidolon_attribute: for attribute in self.avatar.eidolon_attribute:
if attribute in self.attribute_bonus: if attribute in self.attribute_bonus:
self.attribute_bonus[ self.attribute_bonus[
@ -105,6 +111,8 @@ class RoleInstance:
] = self.avatar.extra_ability_attribute[attribute] ] = self.avatar.extra_ability_attribute[attribute]
def cal_weapon_attr_add(self): def cal_weapon_attr_add(self):
if self.attribute_bonus is None:
raise Exception('attribute_bonus is None')
for attribute in self.weapon.weapon_attribute: for attribute in self.weapon.weapon_attribute:
if attribute in self.attribute_bonus: if attribute in self.attribute_bonus:
self.attribute_bonus[ self.attribute_bonus[
@ -120,6 +128,8 @@ class RoleInstance:
logger.info(self.attribute_bonus) logger.info(self.attribute_bonus)
# 检查武器战斗生效的buff # 检查武器战斗生效的buff
logger.info('检查武器战斗生效的buff') logger.info('检查武器战斗生效的buff')
if self.attribute_bonus is None:
raise Exception('attribute_bonus is None')
self.attribute_bonus = await self.weapon.weapon_ability( self.attribute_bonus = await self.weapon.weapon_ability(
self.base_attr, self.attribute_bonus self.base_attr, self.attribute_bonus
) )
@ -130,6 +140,8 @@ class RoleInstance:
) )
logger.info('merge_attribute') logger.info('merge_attribute')
logger.info(self.base_attr) logger.info(self.base_attr)
if self.attribute_bonus is None:
raise Exception('attribute_bonus is None')
merged_attr = await merge_attribute( merged_attr = await merge_attribute(
self.base_attr, self.attribute_bonus self.base_attr, self.attribute_bonus
) )

View File

@ -4,6 +4,7 @@ from typing import Dict
from mpmath import mp from mpmath import mp
from ..Base.model import DamageInstanceWeapon
from ..Base.WeaponBase import BaseWeapon from ..Base.WeaponBase import BaseWeapon
path = Path(__file__).parent.parent path = Path(__file__).parent.parent
@ -15,7 +16,8 @@ mp.dps = 14
class Arrows(BaseWeapon): class Arrows(BaseWeapon):
def __init__(self, weapon: Dict): weapon_base_attributes: Dict
def __init__(self, weapon: DamageInstanceWeapon):
super().__init__(weapon) super().__init__(weapon)
async def check(self): async def check(self):
@ -34,7 +36,8 @@ class Arrows(BaseWeapon):
class ReturntoDarkness(BaseWeapon): class ReturntoDarkness(BaseWeapon):
def __init__(self, weapon: Dict): weapon_base_attributes: Dict
def __init__(self, weapon: DamageInstanceWeapon):
super().__init__(weapon) super().__init__(weapon)
async def check(self): async def check(self):
@ -48,7 +51,8 @@ class ReturntoDarkness(BaseWeapon):
class Swordplay(BaseWeapon): class Swordplay(BaseWeapon):
def __init__(self, weapon: Dict): weapon_base_attributes: Dict
def __init__(self, weapon: DamageInstanceWeapon):
super().__init__(weapon) super().__init__(weapon)
async def check(self): async def check(self):
@ -71,7 +75,8 @@ class Swordplay(BaseWeapon):
class DartingArrow(BaseWeapon): class DartingArrow(BaseWeapon):
def __init__(self, weapon: Dict): weapon_base_attributes: Dict
def __init__(self, weapon: DamageInstanceWeapon):
super().__init__(weapon) super().__init__(weapon)
async def check(self): async def check(self):
@ -90,7 +95,8 @@ class DartingArrow(BaseWeapon):
class Adversarial(BaseWeapon): class Adversarial(BaseWeapon):
def __init__(self, weapon: Dict): weapon_base_attributes: Dict
def __init__(self, weapon: DamageInstanceWeapon):
super().__init__(weapon) super().__init__(weapon)
async def check(self): async def check(self):
@ -110,7 +116,8 @@ class Adversarial(BaseWeapon):
class SubscribeforMore(BaseWeapon): class SubscribeforMore(BaseWeapon):
def __init__(self, weapon: Dict): weapon_base_attributes: Dict
def __init__(self, weapon: DamageInstanceWeapon):
super().__init__(weapon) super().__init__(weapon)
async def check(self): async def check(self):
@ -142,7 +149,8 @@ class SubscribeforMore(BaseWeapon):
class RiverFlowsinSpring(BaseWeapon): class RiverFlowsinSpring(BaseWeapon):
def __init__(self, weapon: Dict): weapon_base_attributes: Dict
def __init__(self, weapon: DamageInstanceWeapon):
super().__init__(weapon) super().__init__(weapon)
async def check(self): async def check(self):
@ -173,7 +181,8 @@ class RiverFlowsinSpring(BaseWeapon):
class SleepLiketheDead(BaseWeapon): class SleepLiketheDead(BaseWeapon):
def __init__(self, weapon: Dict): weapon_base_attributes: Dict
def __init__(self, weapon: DamageInstanceWeapon):
super().__init__(weapon) super().__init__(weapon)
async def check(self): async def check(self):
@ -188,7 +197,8 @@ class SleepLiketheDead(BaseWeapon):
class OnlySilenceRemains(BaseWeapon): class OnlySilenceRemains(BaseWeapon):
def __init__(self, weapon: Dict): weapon_base_attributes: Dict
def __init__(self, weapon: DamageInstanceWeapon):
super().__init__(weapon) super().__init__(weapon)
async def check(self): async def check(self):
@ -210,7 +220,8 @@ class OnlySilenceRemains(BaseWeapon):
class IntheNight(BaseWeapon): class IntheNight(BaseWeapon):
def __init__(self, weapon: Dict): weapon_base_attributes: Dict
def __init__(self, weapon: DamageInstanceWeapon):
super().__init__(weapon) super().__init__(weapon)
async def check(self): async def check(self):
@ -250,7 +261,8 @@ class IntheNight(BaseWeapon):
class CruisingintheStellarSea(BaseWeapon): class CruisingintheStellarSea(BaseWeapon):
def __init__(self, weapon: Dict): weapon_base_attributes: Dict
def __init__(self, weapon: DamageInstanceWeapon):
super().__init__(weapon) super().__init__(weapon)
async def check(self): async def check(self):
@ -278,39 +290,45 @@ class CruisingintheStellarSea(BaseWeapon):
return attribute_bonus return attribute_bonus
class HuntWeapon( # class HuntWeapon(
CruisingintheStellarSea, IntheNight, OnlySilenceRemains, SleepLiketheDead, # IntheNight, OnlySilenceRemains, SleepLiketheDead,
# SubscribeforMore, Swordplay, DartingArrow, Adversarial,
# RiverFlowsinSpring, Arrows, ReturntoDarkness
# ):
# @classmethod
# def create(cls, weapon: DamageInstanceWeapon):
# if weapon.id_ == 24001:
# return SleepLiketheDead(weapon)
# if weapon.id_ == 23001:
# return IntheNight(weapon)
# if weapon.id_ == 21003:
# return OnlySilenceRemains(weapon)
# if weapon.id_ == 21024:
# return RiverFlowsinSpring(weapon)
# if weapon.id_ == 20014:
# return Adversarial(weapon)
# if weapon.id_ == 20007:
# return DartingArrow(weapon)
# if weapon.id_ == 21010:
# return Swordplay(weapon)
# if weapon.id_ == 21031:
# return ReturntoDarkness(weapon)
# if weapon.id_ == 20000:
# return Arrows(weapon)
# raise ValueError(f'未知武器id: {weapon.id_}')
# async def check_ability(self):
# pass
class Weapon(
IntheNight, OnlySilenceRemains, SleepLiketheDead,
SubscribeforMore, Swordplay, DartingArrow, Adversarial, SubscribeforMore, Swordplay, DartingArrow, Adversarial,
RiverFlowsinSpring, Arrows, ReturntoDarkness RiverFlowsinSpring, Arrows, ReturntoDarkness
): ):
def __init__(self, weapon: Dict): @classmethod
if weapon['id'] == 24001: def create(cls, weapon: DamageInstanceWeapon):
return CruisingintheStellarSea(weapon) if weapon.id_ in [
if weapon['id'] == 23001:
return IntheNight(weapon)
if weapon['id'] == 21003:
return OnlySilenceRemains(weapon)
if weapon['id'] == 21024:
return RiverFlowsinSpring(weapon)
if weapon['id'] == 20014:
return Adversarial(weapon)
if weapon['id'] == 20007:
return DartingArrow(weapon)
if weapon['id'] == 21010:
return Swordplay(weapon)
if weapon['id'] == 21031:
return ReturntoDarkness(weapon)
if weapon['id'] == 20000:
return Arrows(weapon)
raise ValueError(f'未知武器id: {weapon["id"]}')
async def check_ability(self):
pass
class Weapon(HuntWeapon):
def __init__(self, weapon: Dict):
if weapon['id'] in [
23001, 23001,
21003, 21003,
23012, 23012,
@ -323,6 +341,24 @@ class Weapon(HuntWeapon):
21031, 21031,
20000, 20000,
]: ]:
return HuntWeapon(weapon) if weapon.id_ == 24001:
return SleepLiketheDead(weapon)
if weapon.id_ == 23001:
return IntheNight(weapon)
if weapon.id_ == 21003:
return OnlySilenceRemains(weapon)
if weapon.id_ == 21024:
return RiverFlowsinSpring(weapon)
if weapon.id_ == 20014:
return Adversarial(weapon)
if weapon.id_ == 20007:
return DartingArrow(weapon)
if weapon.id_ == 21010:
return Swordplay(weapon)
if weapon.id_ == 21031:
return ReturntoDarkness(weapon)
if weapon.id_ == 20000:
return Arrows(weapon)
raise ValueError(f'未知武器id: {weapon.id_}')
else: else:
raise ValueError(f'不支持的武器种类: {weapon["id"]}') raise ValueError(f'不支持的武器种类: {weapon.id_}')

View File

@ -5,11 +5,8 @@ from typing import List, Optional, Union
from httpx import ReadTimeout from httpx import ReadTimeout
from mpmath import mp from mpmath import mp
from gsuid_core.plugins.StarRailUID.StarRailUID.sruid_utils.api.mihomo.models import (
Avatar,
)
from ..sruid_utils.api.mihomo import MihomoData from ..sruid_utils.api.mihomo import MihomoData
from ..sruid_utils.api.mihomo.models import Avatar
from ..sruid_utils.api.mihomo.requests import get_char_card_info from ..sruid_utils.api.mihomo.requests import get_char_card_info
from ..utils.error_reply import UID_HINT from ..utils.error_reply import UID_HINT
from ..utils.excel.read_excel import AvatarPromotion, EquipmentPromotion from ..utils.excel.read_excel import AvatarPromotion, EquipmentPromotion

View File

@ -1,35 +0,0 @@
import re
from gsuid_core.bot import Bot
from gsuid_core.models import Event
from gsuid_core.sv import SV
from ..starrailuid_charinfo.draw_char_img import get_char_data
from ..utils.convert import get_uid
from ..utils.error_reply import UID_HINT
from ..utils.sr_prefix import PREFIX
from .cal_damage import cal
sv_char_damage_cal = SV('sr伤害计算')
@sv_char_damage_cal.on_prefix(f'{PREFIX}伤害计算')
async def send_damage_msg(bot: Bot, ev: Event):
msg = ''.join(re.findall('[\u4e00-\u9fa5 ]', ev.text))
if not msg:
return None
await bot.logger.info('开始执行[角色伤害计算]')
# 获取uid
sr_uid = await get_uid(bot, ev)
if sr_uid is None:
return await bot.send(UID_HINT)
await bot.logger.info(f'[角色伤害计算]uid: {sr_uid}')
char_name = ' '.join(re.findall('[\u4e00-\u9fa5]+', msg))
char_data = await get_char_data(sr_uid, char_name)
if isinstance(char_data, str):
return await bot.send(char_data)
im = await cal(char_data)
await bot.send(im)
return None

View File

@ -1,39 +0,0 @@
from typing import Dict
from mpmath import mp
from ..starrailuid_charinfo.draw_char_img import cal_char_info
from ..starrailuid_charinfo.mono.Character import Character
from .effect.Role import RoleInstance
mp.dps = 14
async def cal(char_data: Dict):
char: Character = await cal_char_info(char_data)
raw_data = {"avatar": {}, "weapon": {}, "relic": []}
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']
raw_data['weapon']['rank'] = char.equipment['equipmentRank']
raw_data['weapon']['promotion'] = char.equipment['equipmentPromotion']
raw_data['relic'] = char.char_relic
raw_data['skill'] = char.char_skill
im = []
for skill_type in ['Normal', 'BPSkill', 'Ultra']:
role = RoleInstance(raw_data)
im_tmp = await role.cal_damage(skill_type)
im.append(im_tmp)
return im