mirror of
https://github.com/baiqwerdvd/StarRailUID.git
synced 2025-05-04 18:57:33 +08:00
🔥 独立伤害计算模块,需要安装依赖
This commit is contained in:
parent
327d14474c
commit
6490a41030
@ -2,18 +2,18 @@ import re
|
||||
from pathlib import Path
|
||||
from typing import Tuple, cast
|
||||
|
||||
from PIL import Image
|
||||
from gsuid_core.sv import SV
|
||||
from gsuid_core.bot import Bot
|
||||
from gsuid_core.models import Event
|
||||
from gsuid_core.sv import SV
|
||||
from PIL import Image
|
||||
|
||||
from .to_card import api_to_card
|
||||
from ..utils.convert import get_uid
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
from ..utils.error_reply import UID_HINT
|
||||
from .get_char_img import draw_char_info_img
|
||||
from ..utils.image.convert import convert_img
|
||||
from ..utils.resource.RESOURCE_PATH import TEMP_PATH
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
from .get_char_img import draw_char_info_img
|
||||
from .to_card import api_to_card
|
||||
|
||||
sv_char_info_config = SV('sr面板设置', pm=2)
|
||||
sv_get_char_info = SV('sr面板查询', priority=10)
|
||||
|
@ -1,18 +0,0 @@
|
||||
from typing import Dict
|
||||
|
||||
from .mono.Character import Character
|
||||
from .damage.Avatar import AvatarInstance
|
||||
|
||||
|
||||
async def cal_char_info(char_data: Dict):
|
||||
char: Character = Character(char_data)
|
||||
await char.get_equipment_info()
|
||||
await char.get_char_attribute_bonus()
|
||||
await char.get_relic_info()
|
||||
return char
|
||||
|
||||
|
||||
async def cal_info(char_data: Dict):
|
||||
char = await cal_char_info(char_data)
|
||||
avatar = AvatarInstance(char)
|
||||
return await avatar.gat_damage()
|
@ -1,34 +0,0 @@
|
||||
from ..utils.map.SR_MAP_PATH import RelicId2MainAffixGroup
|
||||
from ..utils.excel.model import RelicSubAffixConfig, RelicMainAffixConfig
|
||||
|
||||
|
||||
async def cal_relic_main_affix(
|
||||
relic_id: int,
|
||||
set_id: str,
|
||||
affix_id: int,
|
||||
relic_type: int,
|
||||
relic_level: int,
|
||||
):
|
||||
if set_id[0] == 3:
|
||||
rarity = int(str(relic_id)[0]) - 1
|
||||
group_id = str(rarity) + str(relic_type)
|
||||
else:
|
||||
group_id = str(RelicId2MainAffixGroup[str(relic_id)])
|
||||
relic_data = RelicMainAffixConfig.Relic[group_id][str(affix_id)]
|
||||
base_value = relic_data.BaseValue.Value
|
||||
level_add = relic_data.LevelAdd.Value
|
||||
value = base_value + level_add * relic_level
|
||||
affix_property = relic_data.Property
|
||||
return affix_property, value
|
||||
|
||||
|
||||
async def cal_relic_sub_affix(
|
||||
relic_id: int, affix_id: int, cnt: int, step: int
|
||||
):
|
||||
rarity = int(str(relic_id)[0]) - 1
|
||||
relic_data = RelicSubAffixConfig.Relic[str(rarity)][str(affix_id)]
|
||||
base_value = relic_data.BaseValue.Value
|
||||
step_value = relic_data.StepValue.Value
|
||||
value = base_value * cnt + step_value * step
|
||||
affix_property = relic_data.Property
|
||||
return affix_property, value
|
@ -1,117 +0,0 @@
|
||||
import json
|
||||
from typing import Dict
|
||||
from pathlib import Path
|
||||
|
||||
from gsuid_core.logger import logger
|
||||
|
||||
from .Weapon.Weapon import Weapon
|
||||
from ..mono.Character import Character
|
||||
from .Base.model import DamageInstance
|
||||
from .Base.AvatarBase import BaseAvatarinfo
|
||||
from .Relic.Relic import RelicSet, SingleRelic
|
||||
from .AvatarDamage.AvatarDamage import AvatarDamage
|
||||
|
||||
Excel_path = Path(__file__).parent
|
||||
with Path.open(Excel_path / 'Excel' / 'SkillData.json', encoding='utf-8') as f:
|
||||
skill_dict = json.load(f)
|
||||
|
||||
|
||||
class AvatarInstance:
|
||||
def __init__(self, raw_data: Character):
|
||||
self.raw_data = DamageInstance(raw_data)
|
||||
self.avatardamage = AvatarDamage.create(
|
||||
self.raw_data.avatar, self.raw_data.skill
|
||||
)
|
||||
self.avatar = BaseAvatarinfo(self.raw_data.avatar)
|
||||
self.weapon = Weapon.create(self.raw_data.weapon)
|
||||
self.relic_set = RelicSet().create(self.raw_data.relic)
|
||||
|
||||
self.base_attr = self.cal_role_base_attr()
|
||||
self.attribute_bonus: dict[str, float] = {}
|
||||
|
||||
self.cal_relic_attr_add()
|
||||
self.cal_avatar_attr_add()
|
||||
self.cal_avatar_eidolon_add()
|
||||
self.cal_weapon_attr_add()
|
||||
|
||||
def merge_attribute_bonus(self, add_attribute: Dict[str, float]):
|
||||
for attribute in add_attribute:
|
||||
if attribute in self.attribute_bonus:
|
||||
self.attribute_bonus[attribute] += add_attribute[attribute]
|
||||
else:
|
||||
self.attribute_bonus[attribute] = add_attribute[attribute]
|
||||
|
||||
def cal_role_base_attr(self):
|
||||
logger.info('cal_role_base_attr')
|
||||
base_attr: dict[str, float] = {}
|
||||
avatar_attribute = self.avatar.avatar_attribute
|
||||
for attr_name, attr_value in avatar_attribute.items():
|
||||
if attr_name in base_attr:
|
||||
base_attr[attr_name] += attr_value
|
||||
else:
|
||||
base_attr[attr_name] = attr_value
|
||||
|
||||
weapon_attribute = self.weapon.weapon_base_attribute
|
||||
for attr_name, attr_value in weapon_attribute.items():
|
||||
if attr_name in base_attr:
|
||||
base_attr[attr_name] += attr_value
|
||||
else:
|
||||
base_attr[attr_name] = attr_value
|
||||
return base_attr
|
||||
|
||||
def cal_relic_attr_add(self):
|
||||
# 单件属性
|
||||
for relic_type in self.relic_set.__dict__:
|
||||
if type(self.relic_set.__dict__[relic_type]) == SingleRelic:
|
||||
relic: SingleRelic = self.relic_set.__dict__[relic_type]
|
||||
self.merge_attribute_bonus(relic.relic_attribute_bonus)
|
||||
|
||||
# 套装面板加成属性
|
||||
for set_skill in self.relic_set.SetSkill:
|
||||
self.merge_attribute_bonus(set_skill.relicSetAttribute)
|
||||
|
||||
def cal_avatar_eidolon_add(self):
|
||||
self.merge_attribute_bonus(self.avatardamage.eidolon_attribute)
|
||||
self.merge_attribute_bonus(self.avatardamage.extra_ability_attribute)
|
||||
|
||||
def cal_avatar_attr_add(self):
|
||||
attribute_bonus = self.avatar.avatar_attribute_bonus
|
||||
if attribute_bonus:
|
||||
for bonus in attribute_bonus:
|
||||
status_add = bonus.statusAdd
|
||||
bonus_property = status_add.property
|
||||
value = status_add.value
|
||||
if bonus_property in self.attribute_bonus:
|
||||
self.attribute_bonus[bonus_property] += value
|
||||
else:
|
||||
self.attribute_bonus[bonus_property] = value
|
||||
|
||||
def cal_weapon_attr_add(self):
|
||||
self.merge_attribute_bonus(self.weapon.weapon_attribute)
|
||||
|
||||
async def gat_damage(self):
|
||||
# logger.info('base_attr')
|
||||
# logger.info(self.base_attr)
|
||||
# logger.info('attribute_bonus')
|
||||
# logger.info(self.attribute_bonus)
|
||||
|
||||
logger.info('检查武器战斗生效的buff')
|
||||
Ultra_Use = self.avatar.Ultra_Use()
|
||||
logger.info('Ultra_Use')
|
||||
logger.info(Ultra_Use)
|
||||
self.attribute_bonus = await self.weapon.weapon_ability(
|
||||
Ultra_Use, self.base_attr, self.attribute_bonus
|
||||
)
|
||||
logger.info(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
|
||||
)
|
||||
if self.attribute_bonus is None:
|
||||
raise Exception('attribute_bonus is None')
|
||||
logger.info(self.attribute_bonus)
|
||||
|
||||
return await self.avatardamage.getdamage(
|
||||
self.base_attr, self.attribute_bonus
|
||||
)
|
File diff suppressed because it is too large
Load Diff
@ -1,171 +0,0 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
from abc import abstractmethod
|
||||
from typing import List, Tuple, Union
|
||||
|
||||
import msgspec
|
||||
from msgspec import Struct
|
||||
|
||||
from .SkillBase import BaseSkills
|
||||
from ....utils.excel.model import AvatarPromotionConfig
|
||||
from .model import DamageInstanceSkill, DamageInstanceAvatar
|
||||
|
||||
path = Path(__file__).parent.parent
|
||||
with Path.open(path / 'Excel' / 'SkillData.json', encoding='utf-8') as f:
|
||||
skill_dict = json.load(f)
|
||||
|
||||
|
||||
class BaseAvatarAttribute(Struct):
|
||||
attack: float
|
||||
defence: float
|
||||
hp: float
|
||||
speed: float
|
||||
CriticalChanceBase: float
|
||||
CriticalDamageBase: float
|
||||
BaseAggro: float
|
||||
|
||||
def items(self) -> List[Tuple[str, float]]:
|
||||
return [
|
||||
('attack', self.attack),
|
||||
('defence', self.defence),
|
||||
('hp', self.hp),
|
||||
('speed', self.speed),
|
||||
('CriticalChanceBase', self.CriticalChanceBase),
|
||||
('CriticalDamageBase', self.CriticalDamageBase),
|
||||
('BaseAggro', self.BaseAggro),
|
||||
]
|
||||
|
||||
|
||||
class BaseAvatarBuff:
|
||||
@classmethod
|
||||
def create(
|
||||
cls, char: DamageInstanceAvatar, skills: List[DamageInstanceSkill]
|
||||
):
|
||||
cls.extra_ability_id = []
|
||||
if char.extra_ability:
|
||||
for extra_ability in char.extra_ability:
|
||||
cls.extra_ability_id.append(extra_ability['extraAbilityId'])
|
||||
return cls
|
||||
|
||||
@abstractmethod
|
||||
async def Technique(self):
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
async def eidolons(self):
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
async def extra_ability(self):
|
||||
...
|
||||
|
||||
|
||||
class BaseAvatarinfo:
|
||||
def __init__(self, char: DamageInstanceAvatar):
|
||||
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 = self.get_attribute()
|
||||
|
||||
def get_attribute(self):
|
||||
promotion = AvatarPromotionConfig.Avatar[str(self.avatar_id)][
|
||||
str(self.avatar_promotion)
|
||||
]
|
||||
|
||||
return BaseAvatarAttribute(
|
||||
# 攻击力
|
||||
attack=(
|
||||
promotion.AttackBase.Value
|
||||
+ promotion.AttackAdd.Value * (self.avatar_level - 1)
|
||||
),
|
||||
# 防御力
|
||||
defence=(
|
||||
promotion.DefenceBase.Value
|
||||
+ promotion.DefenceAdd.Value * (self.avatar_level - 1)
|
||||
),
|
||||
# 血量
|
||||
hp=(
|
||||
promotion.HPBase.Value
|
||||
+ promotion.HPAdd.Value * (self.avatar_level - 1)
|
||||
),
|
||||
# 速度
|
||||
speed=promotion.SpeedBase.Value,
|
||||
# 暴击率
|
||||
CriticalChanceBase=promotion.CriticalChance.Value,
|
||||
# 暴击伤害
|
||||
CriticalDamageBase=promotion.CriticalDamage.Value,
|
||||
# 嘲讽
|
||||
BaseAggro=promotion.BaseAggro.Value,
|
||||
)
|
||||
|
||||
def Ultra_Use(self):
|
||||
skill_info = skill_dict[str(self.avatar_id)]['Ultra_Use'][0]
|
||||
return msgspec.convert(skill_info, type=float)
|
||||
|
||||
|
||||
class BaseAvatar:
|
||||
def __init__(
|
||||
self, char: DamageInstanceAvatar, skills: List[DamageInstanceSkill]
|
||||
):
|
||||
self.Skill = BaseSkills.create(char=char, skills=skills)
|
||||
self.Buff = BaseAvatarBuff.create(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 = self.get_attribute()
|
||||
|
||||
def get_attribute(self):
|
||||
promotion = AvatarPromotionConfig.Avatar[str(self.avatar_id)][
|
||||
str(self.avatar_promotion)
|
||||
]
|
||||
|
||||
return BaseAvatarAttribute(
|
||||
# 攻击力
|
||||
attack=(
|
||||
promotion.AttackBase.Value
|
||||
+ promotion.AttackAdd.Value * (self.avatar_level - 1)
|
||||
),
|
||||
# 防御力
|
||||
defence=(
|
||||
promotion.DefenceBase.Value
|
||||
+ promotion.DefenceAdd.Value * (self.avatar_level - 1)
|
||||
),
|
||||
# 血量
|
||||
hp=(
|
||||
promotion.HPBase.Value
|
||||
+ promotion.HPAdd.Value * (self.avatar_level - 1)
|
||||
),
|
||||
# 速度
|
||||
speed=promotion.SpeedBase.Value,
|
||||
# 暴击率
|
||||
CriticalChanceBase=promotion.CriticalChance.Value,
|
||||
# 暴击伤害
|
||||
CriticalDamageBase=promotion.CriticalDamage.Value,
|
||||
# 嘲讽
|
||||
BaseAggro=promotion.BaseAggro.Value,
|
||||
)
|
||||
|
||||
def Skill_Info(self, skill_type: str):
|
||||
skill_info = skill_dict[str(self.avatar_id)]['skillList'][skill_type]
|
||||
return msgspec.convert(skill_info, type=List[Union[str, int]])
|
||||
|
||||
def Skill_num(self, skill: Union[str, int], skill_type: str):
|
||||
skill_level = 0
|
||||
if skill == 'Normal':
|
||||
skill_level = self.Skill.Normal_.level - 1
|
||||
if skill == 'BPSkill':
|
||||
skill_level = self.Skill.BPSkill_.level - 1
|
||||
if skill == 'Ultra':
|
||||
skill_level = self.Skill.Ultra_.level - 1
|
||||
if skill == 'Talent':
|
||||
skill_level = self.Skill.Talent_.level - 1
|
||||
skill_info = skill_dict[str(self.avatar_id)][skill_type][skill_level]
|
||||
return msgspec.convert(skill_info, type=float)
|
@ -1,92 +0,0 @@
|
||||
from typing import Dict
|
||||
from abc import abstractmethod
|
||||
|
||||
from gsuid_core.logger import logger
|
||||
|
||||
from .model import DamageInstanceRelic
|
||||
from ....utils.map.SR_MAP_PATH import RelicSetSkill
|
||||
from ....utils.map.model.RelicSetSkill import RelicSetStatusAdd
|
||||
|
||||
|
||||
class SingleRelic:
|
||||
def __init__(self, relic: DamageInstanceRelic):
|
||||
self.raw_relic = relic
|
||||
self.relic_id = relic.relicId
|
||||
self.set_id = relic.SetId
|
||||
self.relic_type = relic.Type
|
||||
self.relic_level = relic.Level
|
||||
self.relic_attribute_bonus: Dict[str, float] = {}
|
||||
|
||||
def get_attribute_(self):
|
||||
# MainAffix
|
||||
if self.raw_relic.MainAffix.Property in self.relic_attribute_bonus:
|
||||
self.relic_attribute_bonus[
|
||||
self.raw_relic.MainAffix.Property
|
||||
] += self.raw_relic.MainAffix.Value
|
||||
else:
|
||||
self.relic_attribute_bonus[
|
||||
self.raw_relic.MainAffix.Property
|
||||
] = self.raw_relic.MainAffix.Value
|
||||
|
||||
# SubAffix
|
||||
if self.raw_relic.SubAffixList:
|
||||
for sub_affix in self.raw_relic.SubAffixList:
|
||||
sub_affix_property = sub_affix.Property
|
||||
value = sub_affix.Value
|
||||
if sub_affix_property in self.relic_attribute_bonus:
|
||||
self.relic_attribute_bonus[sub_affix_property] += value
|
||||
else:
|
||||
self.relic_attribute_bonus[sub_affix_property] = value
|
||||
|
||||
|
||||
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, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
战斗加成属性, 与 set_skill_property() 互斥
|
||||
"""
|
||||
...
|
||||
|
||||
def set_skill_property_ability(self):
|
||||
def add_relic_set_attribute(status_add: RelicSetStatusAdd):
|
||||
set_property = status_add.Property
|
||||
set_value = status_add.Value
|
||||
if set_property != '':
|
||||
relic_set_attribute[set_property] = (
|
||||
relic_set_attribute.get(set_property, 0) + set_value
|
||||
)
|
||||
|
||||
relic_set_attribute: Dict[str, float] = {}
|
||||
if self.pieces2:
|
||||
status_add = RelicSetSkill.RelicSet[str(self.setId)]['2']
|
||||
if status_add:
|
||||
add_relic_set_attribute(status_add)
|
||||
|
||||
if self.pieces4:
|
||||
status_add = RelicSetSkill.RelicSet[str(self.setId)]['4']
|
||||
if status_add:
|
||||
add_relic_set_attribute(status_add)
|
||||
|
||||
return relic_set_attribute
|
@ -1,45 +0,0 @@
|
||||
import json
|
||||
from typing import List
|
||||
from pathlib import Path
|
||||
|
||||
from .model import DamageInstanceSkill, DamageInstanceAvatar
|
||||
|
||||
path = Path(__file__).parent.parent
|
||||
with Path.open(path / 'Excel' / 'SkillData.json', encoding='utf-8') as f:
|
||||
skill_dict = json.load(f)
|
||||
|
||||
|
||||
skill_types = {
|
||||
'Normal': 'Normal_',
|
||||
'BPSkill': 'BPSkill_',
|
||||
'Ultra': 'Ultra_',
|
||||
'Maze': 'Maze_',
|
||||
'': 'Talent_',
|
||||
}
|
||||
|
||||
|
||||
class SingleSkill:
|
||||
def __init__(self, skill: DamageInstanceSkill):
|
||||
self.id = skill.skillId
|
||||
self.level = skill.skillLevel
|
||||
|
||||
|
||||
class BaseSkills:
|
||||
Normal_: SingleSkill
|
||||
BPSkill_: SingleSkill
|
||||
Ultra_: SingleSkill
|
||||
Maze_: SingleSkill
|
||||
Talent_: SingleSkill
|
||||
|
||||
@classmethod
|
||||
def create(
|
||||
cls, char: DamageInstanceAvatar, skills: List[DamageInstanceSkill]
|
||||
):
|
||||
for skill in skills:
|
||||
skill_attack_type = skill.skillAttackType
|
||||
if skill_attack_type not in skill_types:
|
||||
raise ValueError(
|
||||
f'Unknown skillAttackType: {skill_attack_type}'
|
||||
)
|
||||
setattr(cls, skill_types[skill_attack_type], SingleSkill(skill))
|
||||
return cls
|
@ -1,78 +0,0 @@
|
||||
from abc import abstractmethod
|
||||
from typing import Dict, List, Tuple
|
||||
|
||||
from msgspec import Struct
|
||||
|
||||
from .model import DamageInstanceWeapon
|
||||
from ....utils.excel.model import EquipmentPromotionConfig
|
||||
from ....utils.map.SR_MAP_PATH import EquipmentID2AbilityProperty
|
||||
|
||||
|
||||
class BaseWeaponAttribute(Struct):
|
||||
hp: float
|
||||
attack: float
|
||||
defence: float
|
||||
|
||||
def items(self) -> List[Tuple[str, float]]:
|
||||
return [
|
||||
('hp', self.hp),
|
||||
('attack', self.attack),
|
||||
('defence', self.defence),
|
||||
]
|
||||
|
||||
|
||||
class BaseWeapon:
|
||||
def __init__(self, weapon: DamageInstanceWeapon):
|
||||
self.weapon_id = weapon.id_
|
||||
self.weapon_level = weapon.level
|
||||
self.weapon_rank = weapon.rank
|
||||
self.weapon_promotion = weapon.promotion
|
||||
self.weapon_base_attribute = self.get_attribute()
|
||||
self.weapon_attribute: Dict[str, float] = {}
|
||||
self.get_attribute()
|
||||
self.weapon_property_ability()
|
||||
|
||||
@abstractmethod
|
||||
async def weapon_ability(self, base_attr: Dict, attribute_bonus: Dict):
|
||||
"""
|
||||
战斗加成属性, 与 weapon_property_ability() 互斥
|
||||
"""
|
||||
...
|
||||
|
||||
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):
|
||||
...
|
||||
|
||||
def get_attribute(self):
|
||||
promotion = EquipmentPromotionConfig.Equipment[str(self.weapon_id)][
|
||||
str(self.weapon_promotion)
|
||||
]
|
||||
|
||||
return BaseWeaponAttribute(
|
||||
hp=(
|
||||
promotion.BaseHP.Value
|
||||
+ promotion.BaseHPAdd.Value * (self.weapon_level - 1)
|
||||
),
|
||||
attack=(
|
||||
promotion.BaseAttack.Value
|
||||
+ promotion.BaseAttackAdd.Value * (self.weapon_level - 1)
|
||||
),
|
||||
defence=(
|
||||
promotion.BaseDefence.Value
|
||||
+ promotion.BaseDefenceAdd.Value * (self.weapon_level - 1)
|
||||
),
|
||||
)
|
@ -1,103 +0,0 @@
|
||||
from typing import List, Union
|
||||
|
||||
import msgspec
|
||||
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: float
|
||||
|
||||
|
||||
class DamageInstanceRelicMainAffix(Struct):
|
||||
AffixID: int
|
||||
Property: str
|
||||
Name: str
|
||||
Value: float
|
||||
|
||||
|
||||
class DamageInstanceRelic(Struct):
|
||||
relicId: int
|
||||
relicName: str
|
||||
SetId: int
|
||||
SetName: str
|
||||
Type: int
|
||||
MainAffix: DamageInstanceRelicMainAffix
|
||||
SubAffixList: Union[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: float
|
||||
|
||||
|
||||
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: Union[List[DamageInstanceAvatarAttributeBouns], None]
|
||||
extra_ability: Union[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=msgspec.convert(
|
||||
char.attribute_bonus,
|
||||
Union[List[DamageInstanceAvatarAttributeBouns], None],
|
||||
),
|
||||
extra_ability=msgspec.convert(
|
||||
char.extra_ability, Union[List, None]
|
||||
),
|
||||
)
|
||||
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(msgspec.convert(relic, DamageInstanceRelic))
|
||||
self.skill = []
|
||||
for skill in char.char_skill:
|
||||
self.skill.append(msgspec.convert(skill, DamageInstanceSkill))
|
@ -1,576 +0,0 @@
|
||||
{
|
||||
"23001": {
|
||||
"Param": {
|
||||
"CriticalChance": [
|
||||
0.18000000016763806, 0.21000000019557774, 0.24000000022351742,
|
||||
0.2700000002514571, 0.3000000002793968
|
||||
],
|
||||
"a_dmg": [
|
||||
0.060000000055879354, 0.07000000006519258, 0.0800000000745058,
|
||||
0.09000000008381903, 0.10000000009313226
|
||||
],
|
||||
"e_dmg": [
|
||||
0.060000000055879354, 0.07000000006519258, 0.0800000000745058,
|
||||
0.09000000008381903, 0.10000000009313226
|
||||
],
|
||||
"q_crit_dmg": [
|
||||
0.12000000011175871, 0.14000000013038516, 0.1600000001490116,
|
||||
0.18000000016763806, 0.20000000018626451
|
||||
]
|
||||
},
|
||||
"AbilityProperty": [
|
||||
0.18000000016763806, 0.21000000019557774, 0.24000000022351742,
|
||||
0.2700000002514571, 0.3000000002793968
|
||||
]
|
||||
},
|
||||
"21003": {
|
||||
"Param": {
|
||||
"CriticalChance": [
|
||||
0.12000000011175871, 0.1500000001396984, 0.18000000016763806,
|
||||
0.21000000019557774, 0.24000000022351742
|
||||
]
|
||||
}
|
||||
},
|
||||
"24001": {
|
||||
"Param": {
|
||||
"CriticalChance": [
|
||||
0.0800000000745058, 0.10000000009313226, 0.12000000011175871,
|
||||
0.14000000013038516, 0.1600000001490116
|
||||
],
|
||||
"AttackAddedRatio": [
|
||||
0.20000000018626451, 0.25000000023283064, 0.3000000002793968,
|
||||
0.3500000003259629, 0.40000000037252903
|
||||
]
|
||||
},
|
||||
"AbilityProperty": [
|
||||
0.0800000000745058, 0.10000000009313226, 0.12000000011175871,
|
||||
0.14000000013038516, 0.1600000001490116
|
||||
]
|
||||
},
|
||||
"21024": {
|
||||
"Param": {
|
||||
"SpeedAddedRatio": [
|
||||
0.0800000000745058, 0.09000000008381903, 0.10000000009313226,
|
||||
0.11000000010244548, 0.12000000011175871
|
||||
],
|
||||
"AllDamageAddedRatio": [
|
||||
0.12000000011175871, 0.1500000001396984, 0.18000000016763806,
|
||||
0.21000000019557774, 0.24000000022351742
|
||||
]
|
||||
}
|
||||
},
|
||||
"21017": {
|
||||
"Param": {
|
||||
"a_dmg": [
|
||||
0.24000000022351742, 0.3000000002793968, 0.3600000003352761,
|
||||
0.4200000003911555, 0.48000000044703484
|
||||
],
|
||||
"e_dmg": [
|
||||
0.24000000022351742, 0.3000000002793968, 0.3600000003352761,
|
||||
0.4200000003911555, 0.48000000044703484
|
||||
]
|
||||
}
|
||||
},
|
||||
"23010": {
|
||||
"Param": {
|
||||
"CriticalDamageBase": [
|
||||
0.36000000022351742, 0.4200000002793968, 0.4800000003352761,
|
||||
0.5400000003911555, 0.60000000044703484
|
||||
],
|
||||
"e_dmg": [
|
||||
0.18000000022351742, 0.2100000002793968, 0.2400000003352761,
|
||||
0.2700000003911555, 0.30000000044703484
|
||||
],
|
||||
"r_dmg": [
|
||||
0.18000000022351742, 0.2100000002793968, 0.2400000003352761,
|
||||
0.2700000003911555, 0.30000000044703484
|
||||
],
|
||||
"t_dmg": [
|
||||
0.48000000022351742, 0.5600000002793968, 0.6400000003352761,
|
||||
0.7200000003911555, 0.80000000044703484
|
||||
]
|
||||
}
|
||||
},
|
||||
"23018": {
|
||||
"Param": {
|
||||
"r_dmg": [
|
||||
0.0036000001709908247, 0.00419999985024333, 0.004800000227987766,
|
||||
0.005399999907240272, 0.005999999586492777
|
||||
]
|
||||
}
|
||||
},
|
||||
"20002": {
|
||||
"Param": {
|
||||
"a_dmg": [
|
||||
0.20000000022351742, 0.2500000002793968, 0.3000000003352761,
|
||||
0.3500000003911555, 0.40000000044703484
|
||||
],
|
||||
"e_dmg": [
|
||||
0.20000000022351742, 0.2500000002793968, 0.3000000003352761,
|
||||
0.3500000003911555, 0.40000000044703484
|
||||
]
|
||||
}
|
||||
},
|
||||
"21006": {
|
||||
"Param": {
|
||||
"t_dmg": [
|
||||
0.48000000022351742, 0.6000000002793968, 0.7200000003352761,
|
||||
0.8400000003911555, 0.96000000044703484
|
||||
]
|
||||
}
|
||||
},
|
||||
"21012": {
|
||||
"Param": {
|
||||
"AllDamageAddedRatio": [
|
||||
0.40000000022351742, 0.5000000002793968, 0.6000000003352761,
|
||||
0.7000000003911555, 0.80000000044703484
|
||||
]
|
||||
}
|
||||
},
|
||||
"20011": {
|
||||
"Param": {
|
||||
"AllDamageAddedRatio": [
|
||||
0.24000000022351742, 0.3000000002793968, 0.3600000003352761,
|
||||
0.4200000003911555, 0.48000000044703484
|
||||
]
|
||||
}
|
||||
},
|
||||
"20004": {
|
||||
"Param": {
|
||||
"StatusProbability": [
|
||||
0.20000000022351742, 0.2500000002793968, 0.3000000003352761,
|
||||
0.3500000003911555, 0.40000000044703484
|
||||
]
|
||||
}
|
||||
},
|
||||
"20020": {
|
||||
"Param": {
|
||||
"A3_AttackAddedRatio": [
|
||||
0.24000000022351742, 0.3000000002793968, 0.3600000003352761,
|
||||
0.4200000003911555, 0.48000000044703484
|
||||
]
|
||||
}
|
||||
},
|
||||
"21013": {
|
||||
"Param": {
|
||||
"r_dmg": [
|
||||
0.32000000022351742, 0.4000000002793968, 0.4800000003352761,
|
||||
0.5600000003911555, 0.64000000044703484
|
||||
]
|
||||
}
|
||||
},
|
||||
"20006": {
|
||||
"Param": {
|
||||
"r_dmg": [
|
||||
0.28000000022351742, 0.3500000002793968, 0.4200000003352761,
|
||||
0.4900000003911555, 0.56000000044703484
|
||||
]
|
||||
}
|
||||
},
|
||||
"20014": {
|
||||
"Param": {
|
||||
"SpeedAddedRatio": [
|
||||
0.10000000009313226, 0.12000000011175871, 0.14000000013038516,
|
||||
0.1600000001490116, 0.18000000016763806
|
||||
]
|
||||
}
|
||||
},
|
||||
"20007": {
|
||||
"Param": {
|
||||
"AttackAddedRatio": [
|
||||
0.24000000022351742, 0.3000000002793968, 0.3600000003352761,
|
||||
0.4200000003911555, 0.48000000044703484
|
||||
]
|
||||
}
|
||||
},
|
||||
"23000": {
|
||||
"Param": {
|
||||
"AttackAddedRatio": [
|
||||
0.09000000022351742, 0.1050000002793968, 0.1200000003352761,
|
||||
0.1350000003911555, 0.15000000044703484
|
||||
],
|
||||
"AllDamageAddedRatio": [
|
||||
0.30000000022351742, 0.3500000002793968, 0.4000000003352761,
|
||||
0.4500000003911555, 0.50000000044703484
|
||||
]
|
||||
}
|
||||
},
|
||||
"21001": {
|
||||
"Param": {
|
||||
"AllDamageAddedRatio": [
|
||||
0.12000000022351742, 0.1500000002793968, 0.1800000003352761,
|
||||
0.2100000003911555, 0.24000000044703484
|
||||
]
|
||||
}
|
||||
},
|
||||
"23011": {
|
||||
"Param": {
|
||||
"AllDamageAddedRatio": [
|
||||
0.09000000022351742, 0.1050000002793968, 0.1200000003352761,
|
||||
0.1350000003911555, 0.15000000044703484
|
||||
]
|
||||
}
|
||||
},
|
||||
"23005": {
|
||||
"Param": {
|
||||
"DefenceAddedRatio": [
|
||||
0.2400000000745058, 0.28000000009313226, 0.32000000011175871,
|
||||
0.36000000013038516, 0.4000000001490116
|
||||
]
|
||||
}
|
||||
},
|
||||
"20003": {
|
||||
"Param": {
|
||||
"DefenceAddedRatio": [
|
||||
0.1600000000745058, 0.20000000009313226, 0.24000000011175871,
|
||||
0.28000000013038516, 0.3200000001490116
|
||||
]
|
||||
}
|
||||
},
|
||||
"21022": {
|
||||
"Param": {
|
||||
"AllDamageAddedRatio": [
|
||||
0.16000000022351742, 0.2050000002793968, 0.2400000003352761,
|
||||
0.2850000003911555, 0.32000000044703484
|
||||
]
|
||||
}
|
||||
},
|
||||
"21015": {
|
||||
"Param": {
|
||||
"ignore_defence": [
|
||||
0.12000000022351742, 0.1300000002793968, 0.1400000003352761,
|
||||
0.1500000003911555, 0.16000000044703484
|
||||
]
|
||||
}
|
||||
},
|
||||
"23004": {
|
||||
"Param": {
|
||||
"AllDamageAddedRatio": [
|
||||
0.2400000000745058, 0.28000000009313226, 0.32000000011175871,
|
||||
0.36000000013038516, 0.4000000001490116
|
||||
],
|
||||
"A2_StatusProbability": [
|
||||
0.18000000022351742, 0.2100000002793968, 0.2400000003352761,
|
||||
0.2700000003911555, 0.30000000044703484
|
||||
],
|
||||
"A2_AttackAddedRatio": [
|
||||
0.2400000000745058, 0.28000000009313226, 0.32000000011175871,
|
||||
0.36000000013038516, 0.4000000001490116
|
||||
]
|
||||
}
|
||||
},
|
||||
"23007": {
|
||||
"Param": {
|
||||
"DmgRatio": [
|
||||
0.12000000022351742, 0.1400000002793968, 0.1600000003352761,
|
||||
0.1800000003911555, 0.20000000044703484
|
||||
],
|
||||
"CriticalChance": [
|
||||
0.12000000022351742, 0.1400000002793968, 0.1600000003352761,
|
||||
0.1800000003911555, 0.20000000044703484
|
||||
]
|
||||
}
|
||||
},
|
||||
"23006": {
|
||||
"Param": {
|
||||
"SpeedAddedRatio": [
|
||||
0.04800000022351742, 0.0560000002793968, 0.0640000003352761,
|
||||
0.0720000003911555, 0.0800000044703484
|
||||
],
|
||||
"AllDamageAddedRatio": [
|
||||
0.2400000000745058, 0.28000000009313226, 0.32000000011175871,
|
||||
0.36000000013038516, 0.4000000001490116
|
||||
]
|
||||
}
|
||||
},
|
||||
"21020": {
|
||||
"Param": {
|
||||
"AttackAddedRatio": [
|
||||
0.16000000022351742, 0.2050000002793968, 0.2400000003352761,
|
||||
0.2850000003911555, 0.32000000044703484
|
||||
],
|
||||
"CriticalDamageBase": [
|
||||
0.24000000022351742, 0.3000000002793968, 0.3600000003352761,
|
||||
0.4200000003911555, 0.48000000044703484
|
||||
]
|
||||
}
|
||||
},
|
||||
"23015": {
|
||||
"Param": {
|
||||
"AttackAddedRatio": [
|
||||
0.18000000022351742, 0.2150000002793968, 0.2400000003352761,
|
||||
0.2750000003911555, 0.30000000044703484
|
||||
],
|
||||
"CriticalChance": [
|
||||
0.18000000022351742, 0.2100000002793968, 0.2400000003352761,
|
||||
0.2700000003911555, 0.30000000044703484
|
||||
]
|
||||
}
|
||||
},
|
||||
"20016": {
|
||||
"Param": {
|
||||
"CriticalChance": [
|
||||
0.12000000022351742, 0.1500000002793968, 0.1800000003352761,
|
||||
0.2100000003911555, 0.24000000044703484
|
||||
]
|
||||
}
|
||||
},
|
||||
"21005": {
|
||||
"Param": {
|
||||
"AttackAddedRatio": [
|
||||
0.12000000022351742, 0.1500000002793968, 0.1800000003352761,
|
||||
0.2100000003911555, 0.24000000044703484
|
||||
]
|
||||
}
|
||||
},
|
||||
"21019": {
|
||||
"Param": {
|
||||
"AttackAddedRatio": [
|
||||
0.16000000022351742, 0.200000002793968, 0.2400000003352761,
|
||||
0.2850000003911555, 0.32000000044703484
|
||||
],
|
||||
"CriticalChance": [
|
||||
0.12000000022351742, 0.1500000002793968, 0.1800000003352761,
|
||||
0.2100000003911555, 0.24000000044703484
|
||||
]
|
||||
}
|
||||
},
|
||||
"23009": {
|
||||
"Param": {
|
||||
"CriticalChance": [
|
||||
0.18000000022351742, 0.2100000002793968, 0.2400000003352761,
|
||||
0.2700000003911555, 0.30000000044703484
|
||||
],
|
||||
"HPAddedRatio": [
|
||||
0.18000000022351742, 0.2100000002793968, 0.2400000003352761,
|
||||
0.2700000003911555, 0.30000000044703484
|
||||
],
|
||||
"AllDamageAddedRatio": [
|
||||
0.2400000000745058, 0.28000000009313226, 0.32000000011175871,
|
||||
0.36000000013038516, 0.4000000001490116
|
||||
]
|
||||
}
|
||||
},
|
||||
"21008": {
|
||||
"Param": {
|
||||
"DOTDmgAdd": [
|
||||
0.2400000000745058, 0.28000000009313226, 0.32000000011175871,
|
||||
0.36000000013038516, 0.4000000001490116
|
||||
]
|
||||
}
|
||||
},
|
||||
"22001": {
|
||||
"Param": {
|
||||
"HealRatioBase": [0.16, 0.19, 0.22, 0.25, 0.28]
|
||||
}
|
||||
},
|
||||
"21034": {
|
||||
"Param": {
|
||||
"AllDamageAddedRatio": [
|
||||
0.0020000022351742, 0.0025000002793968, 0.0030000003352761,
|
||||
0.0035000003911555, 0.0040000044703484
|
||||
]
|
||||
}
|
||||
},
|
||||
"20009": {
|
||||
"Param": {
|
||||
"AllDamageAddedRatio": [
|
||||
0.2000000000745058, 0.25000000009313226, 0.30000000011175871,
|
||||
0.35000000013038516, 0.4100000001490116
|
||||
]
|
||||
}
|
||||
},
|
||||
"23008": {
|
||||
"Param": {
|
||||
"speed": [
|
||||
12, 14, 16, 18, 20
|
||||
]
|
||||
}
|
||||
},
|
||||
"20019": {
|
||||
"Param": {
|
||||
"speed": [
|
||||
12, 14, 16, 18, 20
|
||||
]
|
||||
}
|
||||
},
|
||||
"23017": {
|
||||
"Param": {
|
||||
"AttackAddedRatio": [
|
||||
0.02399999974295497, 0.027999999467283487, 0.031999999890103936,
|
||||
0.035999999614432454, 0.0400000000372529
|
||||
]
|
||||
}
|
||||
},
|
||||
"21000": {
|
||||
"Param": {
|
||||
"Ultra_HealRatioBase": [
|
||||
0.12000000011175871, 0.1500000001396984, 0.18000000016763806,
|
||||
0.21000000019557774, 0.24000000022351742
|
||||
]
|
||||
}
|
||||
},
|
||||
"21014": {
|
||||
"Param": {
|
||||
"StatusResistance": [
|
||||
0.33000000030733645, 0.3600000003352761, 0.3900000003632158,
|
||||
0.4200000003911555, 0.45000000041909516
|
||||
],
|
||||
"HealRatioBase": [
|
||||
0.1500000001396984, 0.18000000016763806, 0.21000000019557774,
|
||||
0.24000000022351742, 0.2700000002514571
|
||||
]
|
||||
}
|
||||
},
|
||||
"21032": {
|
||||
"Param": {
|
||||
"AttackAddedRatio": [
|
||||
0.10000000009313226, 0.12499999976716936, 0.1500000001396984,
|
||||
0.17499999981373549, 0.20000000018626451
|
||||
],
|
||||
"CriticalDamage": [
|
||||
0.12000000011175871, 0.1500000001396984, 0.18000000016763806,
|
||||
0.21000000019557774, 0.24000000022351742
|
||||
]
|
||||
}
|
||||
},
|
||||
"20005": {
|
||||
"Param": {
|
||||
"AttackAddedRatio": [
|
||||
0.0800000000745058, 0.09000000008381903, 0.10000000009313226,
|
||||
0.11000000010244548, 0.12000000011175871
|
||||
]
|
||||
}
|
||||
},
|
||||
"22001": {
|
||||
"Param": {
|
||||
"HealRatioBase": [
|
||||
0.1600000001490116, 0.1900000001769513, 0.22000000020489097,
|
||||
0.25000000023283064, 0.2800000002607703
|
||||
]
|
||||
}
|
||||
},
|
||||
"20001": {
|
||||
"Param": {
|
||||
"HealRatioBase": [
|
||||
0.12000000011175871, 0.1500000001396984, 0.18000000016763806,
|
||||
0.21000000019557774, 0.24000000022351742
|
||||
]
|
||||
}
|
||||
},
|
||||
"21011": {
|
||||
"Param": {
|
||||
"AllDamageAddedRatio": [
|
||||
0.12000000011175871, 0.1500000001396984, 0.18000000016763806,
|
||||
0.21000000019557774, 0.24000000022351742
|
||||
]
|
||||
}
|
||||
},
|
||||
"21010": {
|
||||
"Param": {
|
||||
"AllDamageAddedRatio": [
|
||||
0.0800000000745058, 0.10000000009313226, 0.12000000011175871,
|
||||
0.14000000013038516, 0.1600000001490116
|
||||
]
|
||||
}
|
||||
},
|
||||
"21033": {
|
||||
"Param": {
|
||||
"AllDamageAddedRatio": [
|
||||
0.2400000000745058, 0.28000000009313226, 0.32000000011175871,
|
||||
0.36000000013038516, 0.4000000001490116
|
||||
],
|
||||
"AttackAddedRatio": [
|
||||
0.2400000000745058, 0.28000000009313226, 0.32000000011175871,
|
||||
0.36000000013038516, 0.4000000001490116
|
||||
]
|
||||
}
|
||||
},
|
||||
"23014": {
|
||||
"Param": {
|
||||
"AllDamageAddedRatio": [
|
||||
0.1400000000745058, 0.16400000009313226, 0.19000000011175871,
|
||||
0.21400000013038516, 0.2400000001490116
|
||||
],
|
||||
"ResistancePenetration": [
|
||||
0.1200000000745058, 0.14000000009313226, 0.16000000011175871,
|
||||
0.18000000013038516, 0.2000000001490116
|
||||
]
|
||||
}
|
||||
},
|
||||
"23002": {
|
||||
"Param": {
|
||||
"AllDamageAddedRatio": [
|
||||
0.2400000000745058, 0.28000000009313226, 0.32000000011175871,
|
||||
0.36000000013038516, 0.4000000001490116
|
||||
]
|
||||
}
|
||||
},
|
||||
"21026": {
|
||||
"Param": {
|
||||
"AllDamageAddedRatio": [
|
||||
0.16000000011175871, 0.2000000001396984, 0.24000000016763806,
|
||||
0.28000000019557774, 0.32000000022351742
|
||||
],
|
||||
"AttackAddedRatio": [
|
||||
0.1000000000745058, 0.12500000009313226, 0.15000000011175871,
|
||||
0.17500000013038516, 0.2000000001490116
|
||||
]
|
||||
}
|
||||
},
|
||||
"24000": {
|
||||
"Param": {
|
||||
"AllDamageAddedRatio": [
|
||||
0.12000000011175871, 0.1500000001396984, 0.18000000016763806,
|
||||
0.21000000019557774, 0.24000000022351742
|
||||
],
|
||||
"AttackAddedRatio": [
|
||||
0.0800000000745058, 0.10000000009313226, 0.12000000011175871,
|
||||
0.14000000013038516, 0.1600000001490116
|
||||
]
|
||||
}
|
||||
},
|
||||
"21027": {
|
||||
"Param": {
|
||||
"AllDamageAddedRatio": [
|
||||
0.12000000011175871, 0.1500000001396984, 0.18000000016763806,
|
||||
0.21000000019557774, 0.24000000022351742
|
||||
],
|
||||
"AttackAddedRatio": [
|
||||
0.04000000011175871, 0.0500000001396984, 0.06000000016763806,
|
||||
0.07000000019557774, 0.08000000022351742
|
||||
]
|
||||
}
|
||||
},
|
||||
"23012": {
|
||||
"Param": {
|
||||
"CriticalChance": [
|
||||
0.36000000011175871, 0.4200000001396984, 0.48000000016763806,
|
||||
0.54000000019557774, 0.60000000022351742
|
||||
]
|
||||
}
|
||||
},
|
||||
"23016": {
|
||||
"Param": {
|
||||
"CriticalDamageBase": [
|
||||
0.12000000011175871, 0.14000000013038516, 0.1600000001490116,
|
||||
0.18000000016763806, 0.20000000018626451
|
||||
],
|
||||
"TalentDmgAdd": [
|
||||
0.30000000011175871, 0.3500000001396984, 0.40000000016763806,
|
||||
0.45000000019557774, 0.50000000022351742
|
||||
]
|
||||
}
|
||||
},
|
||||
"21031": {
|
||||
"enable": false
|
||||
},
|
||||
"20000": {
|
||||
"Param": {
|
||||
"CriticalChance": [
|
||||
0.12000000011175871, 0.1500000001396984, 0.18000000016763806,
|
||||
0.21000000019557774, 0.24000000022351742
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@ -1,742 +0,0 @@
|
||||
from collections import Counter
|
||||
from typing import Dict, List, Union
|
||||
|
||||
from gsuid_core.logger import logger
|
||||
|
||||
from ..utils import merge_attribute
|
||||
from ..Base.model import DamageInstanceRelic
|
||||
from ..Base.RelicBase import SingleRelic, BaseRelicSetSkill
|
||||
|
||||
|
||||
class Relic101(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
在战斗开始时
|
||||
"""
|
||||
logger.info('Relic101 check success')
|
||||
return True
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces4 and await self.check(base_attr, attribute_bonus):
|
||||
pass
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class Relic102(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
无
|
||||
"""
|
||||
logger.info('Relic102 check success')
|
||||
return True
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces4 and await self.check(base_attr, attribute_bonus):
|
||||
a_dmg = attribute_bonus.get('NormalDmgAdd', 0)
|
||||
attribute_bonus['NormalDmgAdd'] = a_dmg + 0.10000000018626451
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class Relic103(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
战斗中生效:装备者提供的护盾量提高
|
||||
"""
|
||||
logger.info('Relic103 check success')
|
||||
return True
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces4 and await self.check(base_attr, attribute_bonus):
|
||||
shield_added_ratio = attribute_bonus.get('shield_added_ratio', 0)
|
||||
attribute_bonus['shield_added_ratio'] = (
|
||||
shield_added_ratio + 0.20000000018626451
|
||||
)
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class Relic104(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
装备者施放终结技
|
||||
"""
|
||||
logger.info('Relic104 check success')
|
||||
return True
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces4 and await self.check(base_attr, attribute_bonus):
|
||||
critical_damage_base = attribute_bonus.get('CriticalDamageBase', 0)
|
||||
attribute_bonus['CriticalDamageBase'] = (
|
||||
critical_damage_base + 0.25000000023283064
|
||||
)
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class Relic105(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
施放攻击或受到攻击时, 默认叠满
|
||||
"""
|
||||
logger.info('Relic105 check success')
|
||||
return True
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces4 and await self.check(base_attr, attribute_bonus):
|
||||
attack_added_ratio = attribute_bonus.get('AttackAddedRatio', 0)
|
||||
attribute_bonus['AttackAddedRatio'] = (
|
||||
attack_added_ratio + 0.05000000004656613 * 5
|
||||
)
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class Relic106(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
无
|
||||
"""
|
||||
logger.info('Relic106 check success')
|
||||
return True
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces4 and await self.check(base_attr, attribute_bonus):
|
||||
pass
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class Relic107(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
TODO: 检查是否是火属性伤害
|
||||
"""
|
||||
logger.info('Relic107 check success')
|
||||
return True
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces4:
|
||||
e_dmg = attribute_bonus.get('BPSkillDmgAdd', 0)
|
||||
attribute_bonus['BPSkillDmgAdd'] = e_dmg + 0.12000000011175871
|
||||
if self.pieces4 and await self.check(base_attr, attribute_bonus):
|
||||
fire_added_ratio = attribute_bonus.get('FireAddedRatio', 0)
|
||||
attribute_bonus['FireAddedRatio'] = (
|
||||
fire_added_ratio + 0.12000000011175871
|
||||
)
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class Relic108(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
装备者对敌方目标造成伤害
|
||||
目标拥有量子属性弱点
|
||||
"""
|
||||
logger.info('Relic108 check success')
|
||||
return True
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces4 and await self.check(base_attr, attribute_bonus):
|
||||
logger.info(attribute_bonus)
|
||||
ignore_defence = attribute_bonus.get('ignore_defence', 0)
|
||||
attribute_bonus['ignore_defence'] = (
|
||||
ignore_defence + 0.10000000009313226 * 2
|
||||
)
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class Relic109(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
TODO: 检查是否释放战技
|
||||
"""
|
||||
logger.info('Relic109 check success')
|
||||
return True
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces4 and await self.check(base_attr, attribute_bonus):
|
||||
logger.info(attribute_bonus)
|
||||
attack_added_ratio = attribute_bonus.get('AttackAddedRatio', 0)
|
||||
attribute_bonus['AttackAddedRatio'] = (
|
||||
attack_added_ratio + 0.20000000018626451
|
||||
)
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class Relic110(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
装备者施放终结技
|
||||
"""
|
||||
logger.info('Relic110 check success')
|
||||
return True
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces4 and await self.check(base_attr, attribute_bonus):
|
||||
logger.info('ModifyActionDelay')
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class Relic111(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
self._count = count
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
装备者击破敌方目标弱点
|
||||
"""
|
||||
logger.info('Relic111 check success')
|
||||
return True
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces4 and await self.check(base_attr, attribute_bonus):
|
||||
logger.info('ModifySPNew')
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class Relic112(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
self._count = count
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
装备者对陷入负面效果的敌方目标造成伤害
|
||||
对陷入禁锢状态的敌方目标造成伤害
|
||||
"""
|
||||
logger.info('Relic111 check success')
|
||||
return True
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces4 and await self.check(base_attr, attribute_bonus):
|
||||
logger.info('对陷入负面效果的敌方目标造成伤害')
|
||||
critical_chance_base = attribute_bonus.get('CriticalChanceBase', 0)
|
||||
attribute_bonus['CriticalChanceBase'] = (
|
||||
critical_chance_base + 0.10000000009313226
|
||||
)
|
||||
if self.pieces4 and await self.check(base_attr, attribute_bonus):
|
||||
logger.info('对陷入禁锢状态的敌方目标造成伤害')
|
||||
critical_damage_base = attribute_bonus.get('CriticalDamageBase', 0)
|
||||
attribute_bonus['CriticalDamageBase'] = (
|
||||
critical_damage_base + 0.20000000018626451
|
||||
)
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class Relic113(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
self._count = count
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
当装备者受到攻击或被我方目标消耗生命值后, 暴击率提高8%, 持续2回合, 该效果最多叠加2层。
|
||||
"""
|
||||
logger.info('Relic113 check success')
|
||||
return True
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces4 and await self.check(base_attr, attribute_bonus):
|
||||
logger.info('当装备者受到攻击或被我方目标消耗生命值后')
|
||||
critical_chance_base = attribute_bonus.get('CriticalChanceBase', 0)
|
||||
attribute_bonus['CriticalChanceBase'] = (
|
||||
critical_chance_base + 0.08000000009313226 * 2
|
||||
)
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class Relic114(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
self._count = count
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
当装备者对我方目标施放终结技时, 我方全体速度提高12%, 持续1回合, 该效果无法叠加。
|
||||
"""
|
||||
logger.info('Relic114 check success')
|
||||
return True
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces4 and await self.check(base_attr, attribute_bonus):
|
||||
speed_added_ratio = attribute_bonus.get('SpeedAddedRatio', 0)
|
||||
attribute_bonus['SpeedAddedRatio'] = (
|
||||
speed_added_ratio + 0.12000000011175871
|
||||
)
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class Relic301(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
装备者的速度大于等于120
|
||||
"""
|
||||
merged_attr = await merge_attribute(base_attr, attribute_bonus)
|
||||
if merged_attr['speed'] >= 120:
|
||||
logger.info('Relic306 check success')
|
||||
return True
|
||||
return False
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces2 and await self.check(base_attr, attribute_bonus):
|
||||
attack_added_ratio = attribute_bonus.get('AttackAddedRatio', 0)
|
||||
attribute_bonus['AttackAddedRatio'] = (
|
||||
attack_added_ratio + 0.12000000011175871
|
||||
)
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class Relic302(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
装备者的速度大于等于120
|
||||
"""
|
||||
merged_attr = await merge_attribute(base_attr, attribute_bonus)
|
||||
if merged_attr['speed'] >= 120:
|
||||
logger.info('Relic306 check success')
|
||||
return True
|
||||
return False
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces2 and await self.check(base_attr, attribute_bonus):
|
||||
attack_added_ratio = attribute_bonus.get('AttackAddedRatio', 0)
|
||||
attribute_bonus['AttackAddedRatio'] = (
|
||||
attack_added_ratio + 0.0800000000745058
|
||||
)
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class Relic303(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
# 提高装备者等同于当前效果命中25%的攻击力,最多提高25%
|
||||
return True
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces2 and await self.check(base_attr, attribute_bonus):
|
||||
attack_added_ratio = attribute_bonus.get('AttackAddedRatio', 0)
|
||||
merged_attr = await merge_attribute(base_attr, attribute_bonus)
|
||||
status_probability = merged_attr.get('StatusProbabilityBase', 0)
|
||||
# 提高装备者等同于当前效果命中25%的攻击力,最多提高25%
|
||||
attribute_bonus['AttackAddedRatio'] = attack_added_ratio + min(
|
||||
0.25000000023283064, status_probability / 0.25
|
||||
)
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class Relic304(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
备者的效果命中大于等于50%
|
||||
"""
|
||||
merged_attr = await merge_attribute(base_attr, attribute_bonus)
|
||||
if merged_attr['StatusResistanceBase'] >= 0.5000000004656613:
|
||||
logger.info('Relic306 check success')
|
||||
return True
|
||||
return False
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces2 and await self.check(base_attr, attribute_bonus):
|
||||
defence_added_ratio = attribute_bonus.get('DefenceAddedRatio', 0)
|
||||
attribute_bonus['DefenceAddedRatio'] = (
|
||||
defence_added_ratio + 0.1500000001396984
|
||||
)
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class Relic305(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
装备者的暴击伤害大于等于120%
|
||||
"""
|
||||
merged_attr = await merge_attribute(base_attr, attribute_bonus)
|
||||
if merged_attr['CriticalDamageBase'] >= 1.2000000001862645:
|
||||
logger.info('Relic306 check success')
|
||||
return True
|
||||
return False
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces2 and await self.check(base_attr, attribute_bonus):
|
||||
critical_chance_base = attribute_bonus.get('CriticalChanceBase', 0)
|
||||
attribute_bonus['CriticalChanceBase'] = (
|
||||
critical_chance_base + 0.6000000005587935
|
||||
)
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class Relic306(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
装备者当前暴击率大于等于50%
|
||||
"""
|
||||
merged_attr = await merge_attribute(base_attr, attribute_bonus)
|
||||
if merged_attr['CriticalChanceBase'] >= 0.5:
|
||||
logger.info('Relic306 check success')
|
||||
return True
|
||||
return False
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces2 and await self.check(base_attr, attribute_bonus):
|
||||
q_dmg = attribute_bonus.get('UltraDmgAdd', 0)
|
||||
attribute_bonus['UltraDmgAdd'] = q_dmg + 0.1500000001396984
|
||||
a3_dmg = attribute_bonus.get('TalentDmgAdd', 0)
|
||||
attribute_bonus['TalentDmgAdd'] = a3_dmg + 0.1500000001396984
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class Relic307(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
装备者的速度大于等于145
|
||||
"""
|
||||
merged_attr = await merge_attribute(base_attr, attribute_bonus)
|
||||
if merged_attr['speed'] >= 145:
|
||||
logger.info('Relic306 check success')
|
||||
return True
|
||||
return False
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces2 and await self.check(base_attr, attribute_bonus):
|
||||
break_damage_added_ratio_base = attribute_bonus.get(
|
||||
'BreakDamageAddedRatioBase', 0
|
||||
)
|
||||
attribute_bonus['BreakDamageAddedRatioBase'] = (
|
||||
break_damage_added_ratio_base + 0.20000000018626451
|
||||
)
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class Relic308(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
装备者的速度大于等于120
|
||||
"""
|
||||
merged_attr = await merge_attribute(base_attr, attribute_bonus)
|
||||
if merged_attr['speed'] >= 120:
|
||||
logger.info('Relic306 check success')
|
||||
return True
|
||||
return False
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces2 and await self.check(base_attr, attribute_bonus):
|
||||
logger.info('ModifyActionDelay')
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class Relic309(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
当装备者的当前暴击率大于等于70%时, 普攻和战技造成的伤害提高20%。
|
||||
"""
|
||||
merged_attr = await merge_attribute(base_attr, attribute_bonus)
|
||||
if merged_attr['CriticalChanceBase'] >= 0.7:
|
||||
logger.info('Relic309 check success')
|
||||
return True
|
||||
return False
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces2 and await self.check(base_attr, attribute_bonus):
|
||||
a_dmg = attribute_bonus.get('NormalDmgAdd', 0)
|
||||
attribute_bonus['NormalDmgAdd'] = a_dmg + 0.20000000018626451
|
||||
a2_dmg = attribute_bonus.get('BPSkillDmgAdd', 0)
|
||||
attribute_bonus['BPSkillDmgAdd'] = a2_dmg + 0.20000000018626451
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class Relic310(BaseRelicSetSkill):
|
||||
def __init__(self, set_id: int, count: int):
|
||||
super().__init__(set_id, count)
|
||||
|
||||
async def check(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
"""
|
||||
当装备者的效果抵抗大于等于30%时, 我方全体暴击伤害提高10%。
|
||||
"""
|
||||
merged_attr = await merge_attribute(base_attr, attribute_bonus)
|
||||
if merged_attr['StatusResistanceBase'] >= 0.3:
|
||||
logger.info('Relic310 check success')
|
||||
return True
|
||||
return False
|
||||
|
||||
async def set_skill_ability(
|
||||
self, base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
):
|
||||
if self.pieces2 and await self.check(base_attr, attribute_bonus):
|
||||
critical_damage_base = attribute_bonus.get('CriticalDamageBase', 0)
|
||||
attribute_bonus['CriticalDamageBase'] = (
|
||||
critical_damage_base + 0.10000000018626451
|
||||
)
|
||||
return attribute_bonus
|
||||
|
||||
|
||||
class RelicSet:
|
||||
HEAD: SingleRelic
|
||||
HAND: SingleRelic
|
||||
BODY: SingleRelic
|
||||
FOOT: SingleRelic
|
||||
NECK: SingleRelic
|
||||
OBJECT: SingleRelic
|
||||
Unknow: SingleRelic
|
||||
|
||||
SetSkill: List[
|
||||
Union[
|
||||
Relic101,
|
||||
Relic102,
|
||||
Relic103,
|
||||
Relic104,
|
||||
Relic105,
|
||||
Relic106,
|
||||
Relic107,
|
||||
Relic108,
|
||||
Relic109,
|
||||
Relic110,
|
||||
Relic111,
|
||||
Relic112,
|
||||
Relic113,
|
||||
Relic114,
|
||||
Relic301,
|
||||
Relic302,
|
||||
Relic303,
|
||||
Relic304,
|
||||
Relic305,
|
||||
Relic306,
|
||||
Relic307,
|
||||
Relic308,
|
||||
Relic309,
|
||||
Relic310,
|
||||
]
|
||||
]
|
||||
|
||||
def create(self, relic_list: List[DamageInstanceRelic]):
|
||||
set_id_list: List[int] = []
|
||||
for relic in relic_list:
|
||||
set_id_list.append(relic.SetId)
|
||||
|
||||
if relic.Type == 1:
|
||||
self.HEAD = SingleRelic(relic)
|
||||
elif relic.Type == 2:
|
||||
self.HAND = SingleRelic(relic)
|
||||
elif relic.Type == 3:
|
||||
self.BODY = SingleRelic(relic)
|
||||
elif relic.Type == 4:
|
||||
self.FOOT = SingleRelic(relic)
|
||||
elif relic.Type == 5:
|
||||
self.NECK = SingleRelic(relic)
|
||||
elif relic.Type == 6:
|
||||
self.OBJECT = SingleRelic(relic)
|
||||
else:
|
||||
self.Unknow = SingleRelic(relic)
|
||||
|
||||
self.set_id_counter = Counter(set_id_list).most_common()
|
||||
self.check_set()
|
||||
self.get_attribute()
|
||||
return self
|
||||
|
||||
def get_attribute(self):
|
||||
for item in self.__dict__:
|
||||
if type(self.__dict__[item]) == SingleRelic:
|
||||
itme__: SingleRelic = self.__dict__[item]
|
||||
itme__.get_attribute_()
|
||||
|
||||
def check_set(self):
|
||||
self.SetSkill = []
|
||||
for item in self.set_id_counter:
|
||||
set_id = item[0]
|
||||
count = item[1]
|
||||
|
||||
if set_id == 101:
|
||||
self.SetSkill.append(Relic101(set_id, count))
|
||||
elif set_id == 102:
|
||||
self.SetSkill.append(Relic102(set_id, count))
|
||||
elif set_id == 103:
|
||||
self.SetSkill.append(Relic103(set_id, count))
|
||||
elif set_id == 104:
|
||||
self.SetSkill.append(Relic104(set_id, count))
|
||||
elif set_id == 105:
|
||||
self.SetSkill.append(Relic105(set_id, count))
|
||||
elif set_id == 106:
|
||||
self.SetSkill.append(Relic106(set_id, count))
|
||||
elif set_id == 107:
|
||||
self.SetSkill.append(Relic107(set_id, count))
|
||||
elif set_id == 108:
|
||||
self.SetSkill.append(Relic108(set_id, count))
|
||||
elif set_id == 109:
|
||||
self.SetSkill.append(Relic109(set_id, count))
|
||||
elif set_id == 110:
|
||||
self.SetSkill.append(Relic110(set_id, count))
|
||||
elif set_id == 111:
|
||||
self.SetSkill.append(Relic111(set_id, count))
|
||||
elif set_id == 112:
|
||||
self.SetSkill.append(Relic112(set_id, count))
|
||||
elif set_id == 113:
|
||||
self.SetSkill.append(Relic113(set_id, count))
|
||||
elif set_id == 114:
|
||||
self.SetSkill.append(Relic114(set_id, count))
|
||||
elif set_id == 301:
|
||||
self.SetSkill.append(Relic301(set_id, count))
|
||||
elif set_id == 302:
|
||||
self.SetSkill.append(Relic302(set_id, count))
|
||||
elif set_id == 303:
|
||||
self.SetSkill.append(Relic303(set_id, count))
|
||||
elif set_id == 304:
|
||||
self.SetSkill.append(Relic304(set_id, count))
|
||||
elif set_id == 305:
|
||||
self.SetSkill.append(Relic305(set_id, count))
|
||||
elif set_id == 306:
|
||||
self.SetSkill.append(Relic306(set_id, count))
|
||||
elif set_id == 307:
|
||||
self.SetSkill.append(Relic307(set_id, count))
|
||||
elif set_id == 308:
|
||||
self.SetSkill.append(Relic308(set_id, count))
|
||||
elif set_id == 309:
|
||||
self.SetSkill.append(Relic309(set_id, count))
|
||||
elif set_id == 310:
|
||||
self.SetSkill.append(Relic310(set_id, count))
|
||||
else:
|
||||
raise Exception(f'Unknow SetId: {set_id}')
|
@ -1,397 +0,0 @@
|
||||
import copy
|
||||
from typing import Dict
|
||||
|
||||
from gsuid_core.logger import logger
|
||||
|
||||
from .utils import merge_attribute
|
||||
|
||||
|
||||
async def calculate_heal(
|
||||
base_attr: Dict[str, float],
|
||||
attribute_bonus: Dict[str, float],
|
||||
skill_type: str,
|
||||
skill_multiplier: float,
|
||||
skill_num: float,
|
||||
is_atk=0,
|
||||
):
|
||||
add_attr_bonus = copy.deepcopy(attribute_bonus)
|
||||
merged_attr = await merge_attribute(base_attr, add_attr_bonus)
|
||||
|
||||
if is_atk == 1:
|
||||
hp = merged_attr.get('attack', 0)
|
||||
else:
|
||||
hp = merged_attr.get('hp', 0)
|
||||
logger.info(f'生命: {hp}')
|
||||
|
||||
# 检查是否有治疗量加成
|
||||
heal_ratio_base = merged_attr.get('HealRatioBase', 0)
|
||||
for attr in merged_attr:
|
||||
if '_HealRatioBase' in attr and attr.split('_')[0] in (skill_type):
|
||||
heal_ratio_base += merged_attr[attr]
|
||||
heal_ratio = heal_ratio_base + 1
|
||||
logger.info(f'治疗量加成: {heal_ratio}')
|
||||
|
||||
heal_num = (hp * skill_multiplier + skill_num) * heal_ratio
|
||||
|
||||
return [heal_num]
|
||||
|
||||
|
||||
async def calculate_shield(
|
||||
base_attr: Dict[str, float],
|
||||
attribute_bonus: Dict[str, float],
|
||||
skill_multiplier: float,
|
||||
skill_num: float,
|
||||
is_atk=0,
|
||||
):
|
||||
add_attr_bonus = copy.deepcopy(attribute_bonus)
|
||||
merged_attr = await merge_attribute(base_attr, add_attr_bonus)
|
||||
|
||||
if is_atk == 1:
|
||||
defence = merged_attr.get('attack', 0)
|
||||
else:
|
||||
defence = merged_attr.get('defence', 0)
|
||||
logger.info(f'防御力: {defence}')
|
||||
|
||||
# 检查是否有护盾加成
|
||||
shield_added_ratio = merged_attr.get('shield_added_ratio', 0)
|
||||
shield_added = shield_added_ratio + 1
|
||||
logger.info(f'护盾加成: {shield_added}')
|
||||
|
||||
defence_num = (defence * skill_multiplier + skill_num) * shield_added
|
||||
|
||||
return [defence_num]
|
||||
|
||||
|
||||
async def calculate_damage(
|
||||
base_attr: Dict[str, float],
|
||||
attribute_bonus: Dict[str, float],
|
||||
skill_type: str,
|
||||
add_skill_type: str,
|
||||
element: str,
|
||||
skill_multiplier: float,
|
||||
level: int,
|
||||
is_hp=0,
|
||||
):
|
||||
logger.info(f'Skill Multiplier: {skill_multiplier}')
|
||||
logger.info(f'Skill Type: {skill_type}')
|
||||
logger.info(f'Level: {level}')
|
||||
# logger.info(f'attribute_bonus: {attribute_bonus}')
|
||||
|
||||
add_attr_bonus = copy.deepcopy(attribute_bonus)
|
||||
|
||||
add_attr_bonus = apply_attribute_bonus(
|
||||
add_attr_bonus, skill_type, add_skill_type
|
||||
)
|
||||
|
||||
merged_attr = await merge_attribute(base_attr, add_attr_bonus)
|
||||
# logger.info(f'merged_attr: {merged_attr}')
|
||||
if is_hp == 1:
|
||||
attack = merged_attr.get('hp', 0)
|
||||
elif is_hp == 2:
|
||||
attack = merged_attr.get('defence', 0)
|
||||
else:
|
||||
attack = merged_attr.get('attack', 0)
|
||||
logger.info(f'Attack: {attack}')
|
||||
|
||||
damage_reduction = calculate_damage_reduction(level)
|
||||
logger.info(f'韧性区: {damage_reduction}')
|
||||
|
||||
resistance_area = calculate_resistance_area(
|
||||
merged_attr, skill_type, add_skill_type, element
|
||||
)
|
||||
logger.info(f'抗性区: {resistance_area}')
|
||||
|
||||
defence_multiplier = calculate_defence_multiplier(level, merged_attr)
|
||||
logger.info(f'防御区: {defence_multiplier}')
|
||||
|
||||
injury_area, element_area = calculate_injury_area(
|
||||
merged_attr, skill_type, add_skill_type, element
|
||||
)
|
||||
logger.info(f'增伤区: {injury_area}')
|
||||
|
||||
damage_ratio = calculate_damage_ratio(
|
||||
merged_attr, skill_type, add_skill_type
|
||||
)
|
||||
logger.info(f'易伤区: {damage_ratio}')
|
||||
|
||||
critical_damage = calculate_critical_damage(
|
||||
merged_attr, skill_type, add_skill_type
|
||||
)
|
||||
logger.info(f'爆伤区: {critical_damage}')
|
||||
|
||||
critical_chance = calculate_critical_chance(
|
||||
merged_attr, skill_type, add_skill_type
|
||||
)
|
||||
logger.info(f'暴击区: {critical_chance}')
|
||||
|
||||
expected_damage = calculate_expected_damage(
|
||||
critical_chance, critical_damage
|
||||
)
|
||||
logger.info(f'暴击期望: {expected_damage}')
|
||||
|
||||
damage_cd = calculate_damage_cd(
|
||||
attack,
|
||||
skill_multiplier,
|
||||
damage_ratio,
|
||||
injury_area,
|
||||
defence_multiplier,
|
||||
resistance_area,
|
||||
damage_reduction,
|
||||
critical_damage,
|
||||
)
|
||||
damage_qw = calculate_damage_qw(
|
||||
attack,
|
||||
skill_multiplier,
|
||||
damage_ratio,
|
||||
injury_area,
|
||||
defence_multiplier,
|
||||
resistance_area,
|
||||
damage_reduction,
|
||||
expected_damage,
|
||||
)
|
||||
|
||||
damage_tz = calculate_damage_tz(
|
||||
attack,
|
||||
skill_multiplier,
|
||||
damage_ratio,
|
||||
injury_area,
|
||||
defence_multiplier,
|
||||
resistance_area,
|
||||
damage_reduction,
|
||||
critical_damage,
|
||||
element,
|
||||
element_area,
|
||||
base_attr,
|
||||
)
|
||||
|
||||
skill_info_list = [damage_cd, damage_qw, damage_tz]
|
||||
|
||||
logger.info(
|
||||
f'Critical Damage: {damage_cd} Expected Damage: {damage_qw} Apocalypse Damage: {damage_tz}'
|
||||
)
|
||||
|
||||
return skill_info_list
|
||||
|
||||
|
||||
def apply_attribute_bonus(
|
||||
add_attr_bonus: Dict[str, float],
|
||||
skill_type: str,
|
||||
add_skill_type: str,
|
||||
):
|
||||
# Apply attribute bonuses to attack and status probability
|
||||
for attr in add_attr_bonus:
|
||||
if 'AttackAddedRatio' in attr and attr.split('AttackAddedRatio')[
|
||||
0
|
||||
] in (skill_type, add_skill_type):
|
||||
add_attr_bonus['AttackAddedRatio'] += add_attr_bonus[attr]
|
||||
if 'StatusProbabilityBase' in attr and attr.split(
|
||||
'StatusProbabilityBase'
|
||||
)[0] in (skill_type, add_skill_type):
|
||||
add_attr_bonus['StatusProbabilityBase'] += add_attr_bonus[attr]
|
||||
return add_attr_bonus
|
||||
|
||||
|
||||
def calculate_damage_reduction(level: int):
|
||||
enemy_damage_reduction = 0.1
|
||||
return 1 - enemy_damage_reduction
|
||||
|
||||
|
||||
def calculate_resistance_area(
|
||||
merged_attr: Dict[str, float],
|
||||
skill_type: str,
|
||||
add_skill_type: str,
|
||||
element: str,
|
||||
):
|
||||
enemy_status_resistance = 0.0
|
||||
for attr in merged_attr:
|
||||
if 'ResistancePenetration' in attr:
|
||||
# 检查是否有某一属性的抗性穿透
|
||||
attr_name = attr.split('ResistancePenetration')[0]
|
||||
if attr_name in (element, 'AllDamage'):
|
||||
# logger.info(f'{attr_name}属性有{merged_attr[attr]}穿透加成')
|
||||
enemy_status_resistance += merged_attr[attr]
|
||||
# 检查是否有某一技能属性的抗性穿透
|
||||
if '_' in attr_name:
|
||||
skill_name = attr_name.split('_')[0]
|
||||
skillattr_name = attr_name.split('_')[1]
|
||||
if skill_name == add_skill_type and skillattr_name in (
|
||||
element,
|
||||
'AllDamage',
|
||||
):
|
||||
enemy_status_resistance += merged_attr[attr]
|
||||
# logger.info(
|
||||
# f'{skill_name}对{skillattr_name}属性有{merged_attr[attr]}穿透加成'
|
||||
# )
|
||||
return 1.0 - (0 - enemy_status_resistance)
|
||||
|
||||
|
||||
def calculate_defence_multiplier(
|
||||
level: int,
|
||||
merged_attr: Dict[str, float],
|
||||
):
|
||||
ignore_defence = merged_attr.get('ignore_defence', 0.0)
|
||||
enemy_defence = (level * 10 + 200) * (1 - ignore_defence)
|
||||
return (level * 10 + 200) / (level * 10 + 200 + enemy_defence)
|
||||
|
||||
|
||||
def calculate_injury_area(
|
||||
merged_attr: Dict[str, float],
|
||||
skill_type: str,
|
||||
add_skill_type: str,
|
||||
element: str,
|
||||
):
|
||||
injury_area = 0.0
|
||||
element_area = 0.0
|
||||
for attr in merged_attr:
|
||||
attr_name = attr.split('AddedRatio')[0]
|
||||
skill_name = attr.split('DmgAdd')[0]
|
||||
if 'DmgAdd' in attr and skill_name in (
|
||||
skill_type,
|
||||
add_skill_type,
|
||||
):
|
||||
# logger.info(
|
||||
# f'{attr} 对 {skill_type} 有 {merged_attr[attr]} 伤害加成'
|
||||
# )
|
||||
injury_area += merged_attr[attr]
|
||||
|
||||
if 'AddedRatio' in attr and attr_name in (
|
||||
element,
|
||||
'AllDamage',
|
||||
):
|
||||
# logger.info(
|
||||
# f'{attr} 对 {element} 属性有 {merged_attr[attr]} 伤害加成'
|
||||
# )
|
||||
if attr_name == element:
|
||||
element_area += merged_attr[attr]
|
||||
injury_area += merged_attr[attr]
|
||||
return injury_area + 1, element_area
|
||||
|
||||
|
||||
def calculate_damage_ratio(
|
||||
merged_attr: Dict[str, float],
|
||||
skill_type: str,
|
||||
add_skill_type: str,
|
||||
):
|
||||
damage_ratio = merged_attr.get('DmgRatio', 0)
|
||||
for attr in merged_attr:
|
||||
if '_DmgRatio' in attr and attr.split('_')[0] in (
|
||||
skill_type,
|
||||
add_skill_type,
|
||||
):
|
||||
damage_ratio += merged_attr[attr]
|
||||
return damage_ratio + 1
|
||||
|
||||
|
||||
def calculate_critical_damage(
|
||||
merged_attr: Dict[str, float],
|
||||
skill_type: str,
|
||||
add_skill_type: str,
|
||||
):
|
||||
if skill_type == 'DOT':
|
||||
return 1.0
|
||||
critical_damage_base = merged_attr.get('CriticalDamageBase', 0)
|
||||
for attr in merged_attr:
|
||||
if '_CriticalDamageBase' in attr and attr.split('_')[0] in (
|
||||
skill_type,
|
||||
add_skill_type,
|
||||
):
|
||||
critical_damage_base += merged_attr[attr]
|
||||
return critical_damage_base + 1
|
||||
|
||||
|
||||
def calculate_critical_chance(
|
||||
merged_attr: Dict[str, float],
|
||||
skill_type: str,
|
||||
add_skill_type: str,
|
||||
):
|
||||
critical_chance_base = merged_attr['CriticalChanceBase']
|
||||
for attr in merged_attr:
|
||||
if '_CriticalChance' in attr and attr.split('_')[0] in (
|
||||
skill_type,
|
||||
add_skill_type,
|
||||
):
|
||||
critical_chance_base += merged_attr[attr]
|
||||
return min(1, critical_chance_base)
|
||||
|
||||
|
||||
def calculate_expected_damage(
|
||||
critical_chance_base: float,
|
||||
critical_damage_base: float,
|
||||
):
|
||||
return critical_chance_base * (critical_damage_base - 1) + 1
|
||||
|
||||
|
||||
def calculate_damage_cd(
|
||||
attack: float,
|
||||
skill_multiplier: float,
|
||||
damage_ratio: float,
|
||||
injury_area: float,
|
||||
defence_multiplier: float,
|
||||
resistance_area: float,
|
||||
damage_reduction: float,
|
||||
critical_damage: float,
|
||||
):
|
||||
return (
|
||||
attack
|
||||
* skill_multiplier
|
||||
* damage_ratio
|
||||
* injury_area
|
||||
* defence_multiplier
|
||||
* resistance_area
|
||||
* damage_reduction
|
||||
* critical_damage
|
||||
)
|
||||
|
||||
|
||||
def calculate_damage_qw(
|
||||
attack: float,
|
||||
skill_multiplier: float,
|
||||
damage_ratio: float,
|
||||
injury_area: float,
|
||||
defence_multiplier: float,
|
||||
resistance_area: float,
|
||||
damage_reduction: float,
|
||||
expected_damage: float,
|
||||
):
|
||||
return (
|
||||
attack
|
||||
* skill_multiplier
|
||||
* damage_ratio
|
||||
* injury_area
|
||||
* defence_multiplier
|
||||
* resistance_area
|
||||
* damage_reduction
|
||||
* expected_damage
|
||||
)
|
||||
|
||||
|
||||
def calculate_damage_tz(
|
||||
attack: float,
|
||||
skill_multiplier: float,
|
||||
damage_ratio: float,
|
||||
injury_area: float,
|
||||
defence_multiplier: float,
|
||||
resistance_area: float,
|
||||
damage_reduction: float,
|
||||
critical_damage: float,
|
||||
element: str,
|
||||
element_area: float,
|
||||
base_attr: Dict[str, float],
|
||||
):
|
||||
injury_add_tz = 0.0
|
||||
|
||||
attack_tz = attack + 355 + base_attr['attack'] * 2.334
|
||||
# logger.info(f'attack_tz: {attack_tz}')
|
||||
if element == 'Imaginary':
|
||||
injury_add_tz = 0.12
|
||||
return (
|
||||
attack_tz
|
||||
* skill_multiplier
|
||||
* damage_ratio
|
||||
* (injury_area + injury_add_tz + 2.626)
|
||||
* defence_multiplier
|
||||
* resistance_area
|
||||
* damage_reduction
|
||||
* (critical_damage + 1.794)
|
||||
* 10
|
||||
)
|
File diff suppressed because it is too large
Load Diff
@ -1,39 +0,0 @@
|
||||
from typing import Dict
|
||||
|
||||
from gsuid_core.logger import logger
|
||||
|
||||
|
||||
async def merge_attribute(
|
||||
base_attr: Dict[str, float], attribute_bonus: Dict[str, float]
|
||||
) -> Dict[str, float]:
|
||||
merged_attr = base_attr.copy()
|
||||
for attribute, value in attribute_bonus.items():
|
||||
if attribute.endswith('Delta'):
|
||||
attr = attribute.split('Delta')[0].lower()
|
||||
if attr in merged_attr:
|
||||
merged_attr[attr] += value
|
||||
else:
|
||||
merged_attr[attribute] = attribute_bonus[attribute]
|
||||
elif attribute.endswith('AddedRatio'):
|
||||
attr = attribute.split('AddedRatio')[0].lower()
|
||||
if attr in merged_attr:
|
||||
merged_attr[attr] += base_attr[attr] * value
|
||||
else:
|
||||
merged_attr[attribute] = attribute_bonus[attribute]
|
||||
elif attribute in [
|
||||
'ignore_defence',
|
||||
'Atk_buff',
|
||||
'Normal_buff',
|
||||
'shield_added_ratio',
|
||||
]:
|
||||
merged_attr[attribute] = base_attr.get(attribute, 0) + value
|
||||
elif attribute.endswith(
|
||||
('ResistancePenetration', 'DmgAdd', 'DmgRatio')
|
||||
):
|
||||
merged_attr[attribute] = base_attr.get(attribute, 0) + value
|
||||
elif attribute.endswith('Base'):
|
||||
merged_attr[attribute] = base_attr.get(attribute, 0) + value
|
||||
else:
|
||||
logger.info(f'未知的属性加成: {attribute}, 采用覆盖模式')
|
||||
merged_attr[attribute] = attribute_bonus[attribute]
|
||||
return merged_attr
|
@ -9,6 +9,8 @@ from gsuid_core.logger import logger
|
||||
from gsuid_core.utils.image.convert import convert_img
|
||||
from gsuid_core.utils.image.image_tools import draw_text_by_line
|
||||
from PIL import Image, ImageDraw
|
||||
from starrail_damage_cal.cal_damage import cal_char_info, cal_info
|
||||
from starrail_damage_cal.to_data import api_to_dict
|
||||
|
||||
from ..utils.error_reply import CHAR_HINT
|
||||
from ..utils.excel.read_excel import light_cone_ranks
|
||||
@ -36,10 +38,8 @@ from ..utils.resource.RESOURCE_PATH import (
|
||||
SKILL_PATH,
|
||||
WEAPON_PATH,
|
||||
)
|
||||
from .cal_damage import cal_char_info, cal_info
|
||||
from .to_data import api_to_dict
|
||||
|
||||
Excel_path = Path(__file__).parent / 'damage'
|
||||
Excel_path = Path(__file__).parent
|
||||
with Path.open(Excel_path / 'Excel' / 'SkillData.json', encoding='utf-8') as f:
|
||||
skill_dict = json.load(f)
|
||||
|
||||
@ -367,8 +367,10 @@ async def draw_char_img(char_data: Dict, sr_uid: str, msg: str):
|
||||
if char.equipment != {}:
|
||||
weapon_bg = Image.open(TEXT_PATH / 'weapon_bg.png')
|
||||
weapon_id = char.equipment['equipmentID']
|
||||
weapon_img = Image.open(WEAPON_PATH / f'{weapon_id}.png').convert('RGBA').resize(
|
||||
(170, 180)
|
||||
weapon_img = (
|
||||
Image.open(WEAPON_PATH / f'{weapon_id}.png')
|
||||
.convert('RGBA')
|
||||
.resize((170, 180))
|
||||
)
|
||||
weapon_bg.paste(weapon_img, (20, 90), weapon_img)
|
||||
weapon_bg_draw = ImageDraw.Draw(weapon_bg)
|
||||
@ -757,11 +759,13 @@ async def get_char_data(
|
||||
elif enable_self and char_self_path.exists():
|
||||
path = char_self_path
|
||||
else:
|
||||
char_data_list = await api_to_dict(sr_uid)
|
||||
char_id_list, _ = await api_to_dict(
|
||||
sr_uid, save_path=PLAYER_PATH
|
||||
)
|
||||
charname_list = []
|
||||
if isinstance(char_data_list, str):
|
||||
return char_data_list
|
||||
for char in char_data_list:
|
||||
if isinstance(char_id_list, str):
|
||||
return char_id_list
|
||||
for char in char_id_list:
|
||||
charname = avatarId2Name[str(char)]
|
||||
charname_list.append(charname)
|
||||
if str(char_name) in charname_list:
|
||||
|
@ -1,36 +1,40 @@
|
||||
import re
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
from typing import Dict, Tuple, Union, Optional
|
||||
from typing import Dict, Optional, Tuple, Union
|
||||
|
||||
from gsuid_core.logger import logger
|
||||
|
||||
from .to_data import api_to_dict
|
||||
from .draw_char_img import draw_char_img
|
||||
from ..utils.error_reply import CHAR_HINT
|
||||
from ..utils.resource.RESOURCE_PATH import PLAYER_PATH
|
||||
from ..utils.excel.model import AvatarPromotionConfig, EquipmentPromotionConfig
|
||||
from ..utils.map.name_covert import (
|
||||
name_to_avatar_id,
|
||||
name_to_weapon_id,
|
||||
alias_to_char_name,
|
||||
alias_to_weapon_name,
|
||||
from starrail_damage_cal.excel.model import (
|
||||
AvatarPromotionConfig,
|
||||
EquipmentPromotionConfig,
|
||||
)
|
||||
from starrail_damage_cal.to_data import api_to_dict
|
||||
|
||||
|
||||
from ..utils.map.SR_MAP_PATH import (
|
||||
Property2Name,
|
||||
EquipmentID2Name,
|
||||
AvatarRankSkillUp,
|
||||
EquipmentID2Name,
|
||||
EquipmentID2Rarity,
|
||||
rankId2Name,
|
||||
skillId2Name,
|
||||
avatarId2Name,
|
||||
skillId2Effect,
|
||||
Property2Name,
|
||||
avatarId2DamageType,
|
||||
avatarId2EnName,
|
||||
avatarId2Name,
|
||||
avatarId2Rarity,
|
||||
characterSkillTree,
|
||||
rankId2Name,
|
||||
skillId2AttackType,
|
||||
avatarId2DamageType,
|
||||
skillId2Effect,
|
||||
skillId2Name,
|
||||
)
|
||||
from ..utils.error_reply import CHAR_HINT
|
||||
from ..utils.map.name_covert import (
|
||||
alias_to_char_name,
|
||||
alias_to_weapon_name,
|
||||
name_to_avatar_id,
|
||||
name_to_weapon_id,
|
||||
)
|
||||
from ..utils.resource.RESOURCE_PATH import PLAYER_PATH
|
||||
from .draw_char_img import draw_char_img
|
||||
|
||||
WEAPON_TO_INT = {
|
||||
'一': 1,
|
||||
@ -130,9 +134,7 @@ async def get_char_args(
|
||||
if isinstance(char_data, str):
|
||||
return char_data
|
||||
else:
|
||||
for i, s in enumerate(
|
||||
['头部', '手部', '躯干', '腿部', '位面球', '连结绳']
|
||||
):
|
||||
for i, s in enumerate(['头部', '手部', '躯干', '腿部', '位面球', '连结绳']):
|
||||
if '赤沙' in part:
|
||||
continue
|
||||
if part[-1] in PieceName_ilst[i]:
|
||||
@ -228,11 +230,11 @@ async def get_char_data(
|
||||
elif enable_self and char_self_path.exists():
|
||||
path = char_self_path
|
||||
else:
|
||||
char_data_list = await api_to_dict(sr_uid)
|
||||
char_id_list, _ = await api_to_dict(sr_uid, save_path=PLAYER_PATH)
|
||||
charname_list = []
|
||||
if isinstance(char_data_list, str):
|
||||
return char_data_list
|
||||
for char in char_data_list:
|
||||
if isinstance(char_id_list, str):
|
||||
return char_id_list
|
||||
for char in char_id_list:
|
||||
charname = avatarId2Name[str(char)]
|
||||
charname_list.append(charname)
|
||||
if str(char_name) in charname_list:
|
||||
|
@ -1,113 +0,0 @@
|
||||
from typing import Dict, List
|
||||
from collections import Counter
|
||||
|
||||
from ...utils.map.SR_MAP_PATH import RelicSetSkill, EquipmentID2AbilityProperty
|
||||
|
||||
|
||||
class Character:
|
||||
def __init__(self, card_prop: Dict):
|
||||
self.char_level: int = int(card_prop['avatarLevel'])
|
||||
self.char_id: str = card_prop['avatarId']
|
||||
self.char_name: str = card_prop['avatarName']
|
||||
self.char_rank = card_prop['rank'] if card_prop.get('rank') else 0
|
||||
self.char_rarity = card_prop['avatarRarity']
|
||||
self.char_element = card_prop['avatarElement']
|
||||
self.char_promotion = card_prop['avatarPromotion']
|
||||
self.char_skill = card_prop['avatarSkill']
|
||||
self.extra_ability = card_prop['avatarExtraAbility']
|
||||
self.attribute_bonus = card_prop['avatarAttributeBonus']
|
||||
self.char_relic = card_prop['RelicInfo']
|
||||
self.base_attributes = card_prop['baseAttributes']
|
||||
self.add_attr = {}
|
||||
self.equipment = card_prop['equipmentInfo']
|
||||
self.rarity = card_prop['avatarRarity']
|
||||
self.eidolons = (
|
||||
card_prop['rankList'] if card_prop.get('rankList') else []
|
||||
)
|
||||
|
||||
async def get_equipment_info(self):
|
||||
if self.equipment == {}:
|
||||
return
|
||||
base_attr = self.base_attributes
|
||||
equip = self.equipment
|
||||
ability_property = EquipmentID2AbilityProperty[
|
||||
str(equip['equipmentID'])
|
||||
]
|
||||
equip_rank = equip['equipmentRank']
|
||||
|
||||
equip_ability_property = ability_property[str(equip_rank)]
|
||||
|
||||
equip_add_base_attr = equip['baseAttributes']
|
||||
base_attr['hp'] = base_attr['hp'] + equip_add_base_attr['hp']
|
||||
base_attr['attack'] = (
|
||||
base_attr['attack'] + equip_add_base_attr['attack']
|
||||
)
|
||||
base_attr['defence'] = (
|
||||
base_attr['defence'] + equip_add_base_attr['defence']
|
||||
)
|
||||
self.base_attributes = base_attr
|
||||
|
||||
for equip_ability in equip_ability_property:
|
||||
property_type = equip_ability['PropertyType']
|
||||
value = equip_ability['Value']['Value']
|
||||
self.add_attr[property_type] = value + self.add_attr.get(
|
||||
property_type, 0
|
||||
)
|
||||
|
||||
async def get_char_attribute_bonus(self):
|
||||
attribute_bonus = self.attribute_bonus
|
||||
for bonus in attribute_bonus:
|
||||
status_add = bonus['statusAdd']
|
||||
bonus_property = status_add['property']
|
||||
value = status_add['value']
|
||||
self.add_attr[bonus_property] = value + self.add_attr.get(
|
||||
bonus_property, 0
|
||||
)
|
||||
|
||||
async def get_relic_info(self):
|
||||
# 计算圣遗物效果
|
||||
set_id_list: List[int] = []
|
||||
for relic in self.char_relic:
|
||||
set_id_list.append(relic['SetId'])
|
||||
# 处理主属性
|
||||
relic_property = relic['MainAffix']['Property']
|
||||
property_value = relic['MainAffix']['Value']
|
||||
self.add_attr[relic_property] = property_value + self.add_attr.get(
|
||||
relic_property, 0
|
||||
)
|
||||
# 处理副词条
|
||||
for sub in relic['SubAffixList']:
|
||||
sub_property = sub['Property']
|
||||
sub_value = sub['Value']
|
||||
self.add_attr[sub_property] = sub_value + self.add_attr.get(
|
||||
sub_property, 0
|
||||
)
|
||||
# 处理套装属性
|
||||
set_id_dict = Counter(set_id_list)
|
||||
# logger.info(set_id_dict.most_common())
|
||||
for item in set_id_dict.most_common():
|
||||
set_property = ''
|
||||
set_id = item[0]
|
||||
count = item[1]
|
||||
set_value = 0
|
||||
if count >= 2:
|
||||
status_add = RelicSetSkill.RelicSet[str(set_id)]['2']
|
||||
if status_add:
|
||||
set_property = status_add.Property
|
||||
set_value = status_add.Value
|
||||
if set_property != '':
|
||||
self.add_attr[set_property] = (
|
||||
set_value + self.add_attr.get(set_property, 0)
|
||||
)
|
||||
if count == 4:
|
||||
status_add = RelicSetSkill.RelicSet[str(set_id)]['4']
|
||||
if status_add:
|
||||
set_property = status_add.Property
|
||||
set_value = status_add.Value
|
||||
if set_property != '':
|
||||
self.add_attr[set_property] = (
|
||||
set_value + self.add_attr.get(set_property, 0)
|
||||
)
|
||||
|
||||
# logger.info(json.dumps(self.base_attributes))
|
||||
# logger.info(json.dumps(self.add_attr))
|
@ -3,14 +3,18 @@ from pathlib import Path
|
||||
from typing import Dict, List, Union
|
||||
|
||||
from PIL import Image, ImageDraw
|
||||
from starrail_damage_cal.map.SR_MAP_PATH import avatarId2Name
|
||||
from starrail_damage_cal.to_data import api_to_dict
|
||||
|
||||
from .to_data import api_to_dict
|
||||
from ..utils.image.convert import convert_img
|
||||
from ..utils.fonts.first_world import fw_font_28
|
||||
from ..utils.map.SR_MAP_PATH import avatarId2Name
|
||||
from ..utils.map.name_covert import avatar_id_to_char_star
|
||||
from ..utils.fonts.starrail_fonts import sr_font_24, sr_font_30, sr_font_58
|
||||
from ..utils.resource.RESOURCE_PATH import CHAR_ICON_PATH, CHAR_PREVIEW_PATH
|
||||
from ..utils.image.convert import convert_img
|
||||
from ..utils.map.name_covert import avatar_id_to_char_star
|
||||
from ..utils.resource.RESOURCE_PATH import (
|
||||
CHAR_ICON_PATH,
|
||||
CHAR_PREVIEW_PATH,
|
||||
PLAYER_PATH,
|
||||
)
|
||||
|
||||
half_color = (255, 255, 255, 120)
|
||||
first_color = (29, 29, 29)
|
||||
@ -27,15 +31,18 @@ pic_500 = Image.open(TEXT_PATH / '500.png')
|
||||
|
||||
|
||||
async def api_to_card(uid: str) -> Union[str, bytes]:
|
||||
char_data_list = await api_to_dict(uid)
|
||||
char_id_list, _ = await api_to_dict(
|
||||
sr_uid=uid,
|
||||
save_path=PLAYER_PATH,
|
||||
)
|
||||
if (
|
||||
not isinstance(char_data_list, str)
|
||||
and char_data_list == []
|
||||
or isinstance(char_data_list, str)
|
||||
not isinstance(char_id_list, str)
|
||||
and char_id_list == []
|
||||
or isinstance(char_id_list, str)
|
||||
):
|
||||
return await convert_img(pic_500)
|
||||
|
||||
return await draw_enka_card(uid=uid, char_list=char_data_list, showfrom=1)
|
||||
return await draw_enka_card(uid=uid, char_list=char_id_list, showfrom=1)
|
||||
|
||||
|
||||
async def draw_enka_card(uid: str, char_list: List, showfrom: int = 0):
|
||||
@ -54,9 +61,7 @@ async def draw_enka_card(uid: str, char_list: List, showfrom: int = 0):
|
||||
return await convert_img(Image.new('RGBA', (0, 1), (255, 255, 255)))
|
||||
else:
|
||||
line1 = f'UID {uid} 刷新成功'
|
||||
line2 = (
|
||||
f'可以使用 sr查询{char_data_list[0]["avatarName"]} 查询详情角色面板'
|
||||
)
|
||||
line2 = f'可以使用 sr查询{char_data_list[0]["avatarName"]} 查询详情角色面板'
|
||||
char_num = len(char_data_list)
|
||||
if char_num <= 4:
|
||||
based_w, based_h = 1380, 926
|
||||
|
@ -1,339 +0,0 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Union, Optional
|
||||
|
||||
from httpx import ReadTimeout
|
||||
from msgspec import json as msgjson
|
||||
|
||||
from ..utils.error_reply import UID_HINT
|
||||
from ..sruid_utils.api.mihomo import MihomoData
|
||||
from ..sruid_utils.api.mihomo.models import Avatar
|
||||
from ..utils.resource.RESOURCE_PATH import PLAYER_PATH
|
||||
from ..sruid_utils.api.mihomo.requests import get_char_card_info
|
||||
from .cal_value import cal_relic_sub_affix, cal_relic_main_affix
|
||||
from ..utils.excel.model import AvatarPromotionConfig, EquipmentPromotionConfig
|
||||
from ..utils.map.SR_MAP_PATH import (
|
||||
SetId2Name,
|
||||
ItemId2Name,
|
||||
Property2Name,
|
||||
RelicId2SetId,
|
||||
EquipmentID2Name,
|
||||
AvatarRankSkillUp,
|
||||
EquipmentID2Rarity,
|
||||
rankId2Name,
|
||||
skillId2Name,
|
||||
avatarId2Name,
|
||||
skillId2Effect,
|
||||
avatarId2EnName,
|
||||
avatarId2Rarity,
|
||||
characterSkillTree,
|
||||
skillId2AttackType,
|
||||
avatarId2DamageType,
|
||||
)
|
||||
|
||||
|
||||
async def api_to_dict(
|
||||
sr_uid: str, sr_data: Optional[MihomoData] = None
|
||||
) -> Union[List[Dict], str]:
|
||||
"""
|
||||
:说明:
|
||||
访问Mihomo.me API并转换为StarRailUID的数据Json。
|
||||
:参数:
|
||||
* ``uid: str``: 玩家uid。
|
||||
* ``sr_data: Optional[Dict] = None``: 来自Mihomo.me的dict, 可留空。
|
||||
:返回:
|
||||
* ``刷新完成提示语: str``: 包含刷新成功的角色列表。
|
||||
"""
|
||||
if '未找到绑定的UID' in sr_uid:
|
||||
return UID_HINT
|
||||
if not sr_data:
|
||||
try:
|
||||
sr_data = await get_char_card_info(sr_uid)
|
||||
except ReadTimeout:
|
||||
return '网络不太稳定...'
|
||||
except json.decoder.JSONDecodeError:
|
||||
return '网络不太稳定...'
|
||||
if isinstance(sr_data, str):
|
||||
return []
|
||||
if isinstance(sr_data, Dict):
|
||||
if 'detailInfo' not in sr_data:
|
||||
return '服务器正在维护或者关闭中...\n检查Mihomo.me是否可以访问\n如可以访问,尝试上报Bug!'
|
||||
elif sr_data is None:
|
||||
return []
|
||||
|
||||
PlayerDetailInfo = sr_data.detailInfo
|
||||
path = PLAYER_PATH / str(sr_uid)
|
||||
path.mkdir(parents=True, exist_ok=True)
|
||||
with Path.open(path / f'{sr_uid!s}.json', 'wb') as file:
|
||||
file.write(msgjson.format(msgjson.encode(PlayerDetailInfo), indent=4))
|
||||
with Path.open(path / 'rawData.json', 'wb') as file:
|
||||
file.write(msgjson.format(msgjson.encode(sr_data), indent=4))
|
||||
|
||||
if sr_data.detailInfo is None:
|
||||
return f'SR_UID{sr_uid}刷新失败!未打开角色展柜!'
|
||||
|
||||
char_name_list = []
|
||||
char_id_list = []
|
||||
im = f'UID: {sr_uid} 的角色展柜刷新成功\n'
|
||||
if PlayerDetailInfo.assistAvatarDetail:
|
||||
if PlayerDetailInfo.assistAvatarDetail.avatarId not in char_id_list:
|
||||
char_dict, avatarName = await get_data(
|
||||
PlayerDetailInfo.assistAvatarDetail, sr_data, sr_uid
|
||||
)
|
||||
im += f'支援角色 {avatarName}\n'
|
||||
char_name_list.append(avatarName)
|
||||
char_id_list.append(PlayerDetailInfo.assistAvatarDetail.avatarId)
|
||||
if PlayerDetailInfo.avatarDetailList:
|
||||
im += '星海同行'
|
||||
if PlayerDetailInfo.avatarDetailList is not None:
|
||||
for char in PlayerDetailInfo.avatarDetailList:
|
||||
if char.avatarId not in char_id_list:
|
||||
_, avatarName = await get_data(char, sr_data, sr_uid)
|
||||
im += f' {avatarName}'
|
||||
char_name_list.append(avatarName)
|
||||
char_id_list.append(char.avatarId)
|
||||
|
||||
if not char_name_list:
|
||||
return f'UID: {sr_uid} 的角色展柜刷新失败!\n请检查UID是否正确或者角色展柜是否打开!'
|
||||
|
||||
return char_id_list
|
||||
|
||||
|
||||
async def get_data(char: Avatar, sr_data: MihomoData, sr_uid: str):
|
||||
PlayerDetailInfo = sr_data.detailInfo
|
||||
path = PLAYER_PATH / str(sr_uid)
|
||||
# 处理基本信息
|
||||
char_data = {
|
||||
'uid': str(sr_uid),
|
||||
'nickName': PlayerDetailInfo.nickname,
|
||||
'avatarId': char.avatarId,
|
||||
'avatarName': avatarId2Name[str(char.avatarId)],
|
||||
'avatarElement': avatarId2DamageType[str(char.avatarId)],
|
||||
'avatarRarity': avatarId2Rarity[str(char.avatarId)],
|
||||
'avatarPromotion': char.promotion,
|
||||
'avatarLevel': char.level,
|
||||
'avatarSkill': [],
|
||||
'avatarExtraAbility': [],
|
||||
'avatarAttributeBonus': [],
|
||||
'RelicInfo': [],
|
||||
}
|
||||
avatarName = avatarId2Name[str(char.avatarId)]
|
||||
char_data['avatarEnName'] = avatarId2EnName[str(char.avatarId)]
|
||||
# 处理技能
|
||||
for behavior in char.skillTreeList:
|
||||
# 处理技能
|
||||
if f'{char.avatarId}0' == str(behavior.pointId)[0:5]:
|
||||
skill_temp = {}
|
||||
skill_temp['skillId'] = char.avatarId * 100 + behavior.pointId % 10
|
||||
skill_temp['skillName'] = skillId2Name[str(skill_temp['skillId'])]
|
||||
skill_temp['skillEffect'] = skillId2Effect[
|
||||
str(skill_temp['skillId'])
|
||||
]
|
||||
skill_temp['skillAttackType'] = skillId2AttackType[
|
||||
str(skill_temp['skillId'])
|
||||
]
|
||||
skill_temp['skillLevel'] = behavior.level
|
||||
char_data['avatarSkill'].append(skill_temp)
|
||||
|
||||
# 处理技能树中的额外能力
|
||||
if f'{char.avatarId}1' == str(behavior.pointId)[0:5]:
|
||||
extra_ability_temp = {}
|
||||
extra_ability_temp['extraAbilityId'] = behavior.pointId
|
||||
extra_ability_temp['extraAbilityLevel'] = behavior.level
|
||||
char_data['avatarExtraAbility'].append(extra_ability_temp)
|
||||
|
||||
# 处理技能树中的属性加成
|
||||
if f'{char.avatarId}2' == str(behavior.pointId)[0:5]:
|
||||
attribute_bonus_temp = {}
|
||||
attribute_bonus_temp['attributeBonusId'] = behavior.pointId
|
||||
attribute_bonus_temp['attributeBonusLevel'] = behavior.level
|
||||
status_add = characterSkillTree[str(char.avatarId)][
|
||||
str(behavior.pointId)
|
||||
]['levels'][behavior.level - 1]['properties']
|
||||
attribute_bonus_temp['statusAdd'] = {}
|
||||
if status_add:
|
||||
for property_ in status_add:
|
||||
attribute_bonus_temp['statusAdd']['property'] = property_[
|
||||
'type'
|
||||
]
|
||||
attribute_bonus_temp['statusAdd']['name'] = Property2Name[
|
||||
property_['type']
|
||||
]
|
||||
attribute_bonus_temp['statusAdd']['value'] = property_[
|
||||
'value'
|
||||
]
|
||||
char_data['avatarAttributeBonus'].append(
|
||||
attribute_bonus_temp
|
||||
)
|
||||
|
||||
# 处理遗器
|
||||
if char.relicList:
|
||||
for relic in char.relicList:
|
||||
relic_temp = {}
|
||||
relic_temp['relicId'] = relic.tid
|
||||
relic_temp['relicName'] = ItemId2Name[str(relic.tid)]
|
||||
relic_temp['SetId'] = int(RelicId2SetId[str(relic.tid)])
|
||||
relic_temp['SetName'] = SetId2Name[str(relic_temp['SetId'])]
|
||||
relic_temp['Level'] = relic.level if relic.level else 0
|
||||
relic_temp['Type'] = relic.type
|
||||
|
||||
relic_temp['MainAffix'] = {}
|
||||
relic_temp['MainAffix']['AffixID'] = relic.mainAffixId
|
||||
affix_property, value = await cal_relic_main_affix(
|
||||
relic_id=relic.tid,
|
||||
set_id=str(relic_temp['SetId']),
|
||||
affix_id=relic.mainAffixId,
|
||||
relic_type=relic.type,
|
||||
relic_level=relic_temp['Level'],
|
||||
)
|
||||
relic_temp['MainAffix']['Property'] = affix_property
|
||||
relic_temp['MainAffix']['Name'] = Property2Name[affix_property]
|
||||
relic_temp['MainAffix']['Value'] = value
|
||||
|
||||
relic_temp['SubAffixList'] = []
|
||||
if relic.subAffixList:
|
||||
for sub_affix in relic.subAffixList:
|
||||
sub_affix_temp = {}
|
||||
sub_affix_temp['SubAffixID'] = sub_affix.affixId
|
||||
sub_affix_property, value = await cal_relic_sub_affix(
|
||||
relic_id=relic.tid,
|
||||
affix_id=sub_affix.affixId,
|
||||
cnt=sub_affix.cnt,
|
||||
step=sub_affix.step if sub_affix.step else 0,
|
||||
)
|
||||
sub_affix_temp['Property'] = sub_affix_property
|
||||
sub_affix_temp['Name'] = Property2Name[sub_affix_property]
|
||||
sub_affix_temp['Cnt'] = sub_affix.cnt
|
||||
sub_affix_temp['Step'] = (
|
||||
sub_affix.step if sub_affix.step else 0
|
||||
)
|
||||
sub_affix_temp['Value'] = value
|
||||
relic_temp['SubAffixList'].append(sub_affix_temp)
|
||||
char_data['RelicInfo'].append(relic_temp)
|
||||
|
||||
# 处理命座
|
||||
rank_temp = []
|
||||
if char.rank and char.rank is not None:
|
||||
char_data['rank'] = char.rank
|
||||
for index in range(char.rank):
|
||||
rankTemp = {}
|
||||
rank_id = int(str(char.avatarId) + '0' + str(index + 1))
|
||||
rankTemp['rankId'] = rank_id
|
||||
rankTemp['rankName'] = rankId2Name[str(rank_id)]
|
||||
rank_temp.append(rankTemp)
|
||||
char_data['rankList'] = rank_temp
|
||||
|
||||
# 处理命座中的 level_up_skills
|
||||
if char_data.get('rankList'):
|
||||
for rank_item in char_data['rankList']:
|
||||
rank_id = rank_item['rankId']
|
||||
level_up_skill = AvatarRankSkillUp[str(rank_id)]
|
||||
if level_up_skill:
|
||||
for item in level_up_skill:
|
||||
skill_id = item['id']
|
||||
skill_up_num = item['num']
|
||||
# 查找skill_id在不在avatarSkill中
|
||||
for index, skill_item in enumerate(
|
||||
char_data['avatarSkill']
|
||||
):
|
||||
if str(skill_id) == str(skill_item['skillId']):
|
||||
char_data['avatarSkill'][index][
|
||||
'skillLevel'
|
||||
] += skill_up_num
|
||||
break
|
||||
|
||||
# 处理基础属性
|
||||
base_attributes = {}
|
||||
avatar_promotion_base = AvatarPromotionConfig.Avatar[str(char.avatarId)][
|
||||
str(char.promotion)
|
||||
]
|
||||
|
||||
# 攻击力
|
||||
base_attributes['attack'] = (
|
||||
avatar_promotion_base.AttackBase.Value
|
||||
+ avatar_promotion_base.AttackAdd.Value * (char.level - 1)
|
||||
)
|
||||
# 防御力
|
||||
base_attributes['defence'] = (
|
||||
avatar_promotion_base.DefenceBase.Value
|
||||
+ avatar_promotion_base.DefenceAdd.Value * (char.level - 1)
|
||||
)
|
||||
# 血量
|
||||
base_attributes['hp'] = (
|
||||
avatar_promotion_base.HPBase.Value
|
||||
+ avatar_promotion_base.HPAdd.Value * (char.level - 1)
|
||||
)
|
||||
# 速度
|
||||
base_attributes['speed'] = avatar_promotion_base.SpeedBase.Value
|
||||
# 暴击率
|
||||
base_attributes[
|
||||
'CriticalChanceBase'
|
||||
] = avatar_promotion_base.CriticalChance.Value
|
||||
# 暴击伤害
|
||||
base_attributes[
|
||||
'CriticalDamageBase'
|
||||
] = avatar_promotion_base.CriticalDamage.Value
|
||||
# 嘲讽
|
||||
base_attributes['BaseAggro'] = avatar_promotion_base.BaseAggro.Value
|
||||
|
||||
char_data['baseAttributes'] = base_attributes
|
||||
|
||||
# 处理武器
|
||||
|
||||
equipment_info = {}
|
||||
if char.equipment and char.equipment.tid is not None:
|
||||
equipment_info['equipmentID'] = char.equipment.tid
|
||||
equipment_info['equipmentName'] = EquipmentID2Name[
|
||||
str(char.equipment.tid)
|
||||
]
|
||||
|
||||
equipment_info['equipmentLevel'] = char.equipment.level
|
||||
equipment_info['equipmentPromotion'] = char.equipment.promotion
|
||||
equipment_info['equipmentRank'] = char.equipment.rank
|
||||
equipment_info['equipmentRarity'] = EquipmentID2Rarity[
|
||||
str(char.equipment.tid)
|
||||
]
|
||||
equipment_base_attributes = {}
|
||||
equipment_promotion_base = EquipmentPromotionConfig.Equipment[
|
||||
str(char.equipment.tid)
|
||||
][str(equipment_info['equipmentPromotion'])]
|
||||
|
||||
equipment_level = char.equipment.level if char.equipment.level else 1
|
||||
# 生命值
|
||||
equipment_base_attributes['hp'] = (
|
||||
equipment_promotion_base.BaseHP.Value
|
||||
+ equipment_promotion_base.BaseHPAdd.Value * (equipment_level - 1)
|
||||
)
|
||||
# 攻击力
|
||||
equipment_base_attributes['attack'] = (
|
||||
equipment_promotion_base.BaseAttack.Value
|
||||
+ equipment_promotion_base.BaseAttackAdd.Value
|
||||
* (equipment_level - 1)
|
||||
)
|
||||
# 防御力
|
||||
equipment_base_attributes['defence'] = (
|
||||
equipment_promotion_base.BaseDefence.Value
|
||||
+ equipment_promotion_base.BaseDefenceAdd.Value
|
||||
* (equipment_level - 1)
|
||||
)
|
||||
equipment_info['baseAttributes'] = equipment_base_attributes
|
||||
|
||||
char_data['equipmentInfo'] = equipment_info
|
||||
|
||||
with Path.open(path / f'{avatarName}.json', 'w', encoding='UTF-8') as file:
|
||||
json.dump(char_data, file, ensure_ascii=False)
|
||||
return char_data, avatarName
|
||||
|
||||
|
||||
async def api_to_data(
|
||||
uid: str, mihomo_data: Optional[MihomoData] = None
|
||||
) -> Union[Dict, str]:
|
||||
raw_data = await api_to_dict(uid, mihomo_data)
|
||||
if isinstance(raw_data, str):
|
||||
return raw_data
|
||||
char_name_list = []
|
||||
char_name_list_str = ''
|
||||
for char_data in raw_data:
|
||||
char_name_list.append(char_data['avatarName'])
|
||||
char_name_list_str = ','.join(char_name_list)
|
||||
return f'UID{uid}刷新完成!\n本次缓存:{char_name_list_str}'
|
16
pdm.lock
generated
16
pdm.lock
generated
@ -6,7 +6,7 @@ groups = ["default"]
|
||||
cross_platform = true
|
||||
static_urls = false
|
||||
lock_version = "4.3"
|
||||
content_hash = "sha256:4b46a9f0d8d192c3cdb2b0caa6e5bc8783bbd61c95254ec959fecc29e73fb2d6"
|
||||
content_hash = "sha256:95f715290809f5d3a83e79c40bd55087875dd058f16a7da9771c275752176f37"
|
||||
|
||||
[[package]]
|
||||
name = "aiofiles"
|
||||
@ -627,6 +627,20 @@ files = [
|
||||
{file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "starrail-damage-cal"
|
||||
version = "1.0.0"
|
||||
requires_python = ">=3.8"
|
||||
summary = "For StarRail Role Damage Cal"
|
||||
dependencies = [
|
||||
"httpx>=0.25.0",
|
||||
"msgspec>=0.18.4",
|
||||
]
|
||||
files = [
|
||||
{file = "starrail_damage_cal-1.0.0-py3-none-any.whl", hash = "sha256:95c1757accd60bc9eda97d51399b9f26fa39ae112927c94f68da385f88defa17"},
|
||||
{file = "starrail_damage_cal-1.0.0.tar.gz", hash = "sha256:ff4287c56304e996981b851e9bfe47bc898feead5511c3b831dd7e099516cef4"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.8.0"
|
||||
|
@ -118,6 +118,7 @@ dependencies = [
|
||||
"aiofiles>=23.2.1",
|
||||
"aiohttp>=3.8.6",
|
||||
"qrcode[pil]>=7.4.2",
|
||||
"starrail-damage-cal>=1.0.0",
|
||||
]
|
||||
requires-python = ">=3.8.1,<4.0"
|
||||
readme = "README.md"
|
||||
|
@ -405,6 +405,9 @@ sniffio==1.3.0 \
|
||||
soupsieve==2.5 \
|
||||
--hash=sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690 \
|
||||
--hash=sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7
|
||||
starrail-damage-cal==1.0.0 \
|
||||
--hash=sha256:95c1757accd60bc9eda97d51399b9f26fa39ae112927c94f68da385f88defa17 \
|
||||
--hash=sha256:ff4287c56304e996981b851e9bfe47bc898feead5511c3b831dd7e099516cef4
|
||||
typing-extensions==4.8.0 \
|
||||
--hash=sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0 \
|
||||
--hash=sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef
|
||||
|
Loading…
x
Reference in New Issue
Block a user