mirror of
https://github.com/baiqwerdvd/StarRailUID.git
synced 2025-05-07 20:45:46 +08:00
WIP
This commit is contained in:
parent
bdc103eab4
commit
a36b6d3a0c
@ -38,7 +38,7 @@ class Avatar(Struct):
|
|||||||
avatarId: int
|
avatarId: int
|
||||||
level: int
|
level: int
|
||||||
equipment: Equipment | None = None
|
equipment: Equipment | None = None
|
||||||
relicList: list[Relic] | None = None
|
relicList: list[Relic] | None = field(default=[])
|
||||||
pos: int | None = field(default=0)
|
pos: int | None = field(default=0)
|
||||||
rank: int | None = field(default=0)
|
rank: int | None = field(default=0)
|
||||||
promotion: int | None = field(default=0)
|
promotion: int | None = field(default=0)
|
||||||
|
@ -2,7 +2,7 @@ import json
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, List, Union
|
from typing import Dict, List, Union
|
||||||
|
|
||||||
from .effect.Role import RoleInstance
|
from .effect.damageCal import DamageCalculator
|
||||||
from .mono.Character import Character
|
from .mono.Character import Character
|
||||||
|
|
||||||
Excel_path = Path(__file__).parent / 'effect'
|
Excel_path = Path(__file__).parent / 'effect'
|
||||||
@ -26,8 +26,7 @@ async def cal(char_data: Dict):
|
|||||||
skill_list = skill_dict[str(char.char_id)]['skillList']
|
skill_list = skill_dict[str(char.char_id)]['skillList']
|
||||||
skill_list = skill_list.keys()
|
skill_list = skill_list.keys()
|
||||||
for skill_type in skill_list:
|
for skill_type in skill_list:
|
||||||
role = RoleInstance(char)
|
im_tmp = await DamageCalculator(char).cal_damage(skill_type)
|
||||||
im_tmp = await role.cal_damage(skill_type)
|
|
||||||
skill_info_list.append(im_tmp)
|
skill_info_list.append(im_tmp)
|
||||||
return skill_info_list
|
return skill_info_list
|
||||||
return '角色伤害计算未完成'
|
return '角色伤害计算未完成'
|
||||||
|
@ -4,29 +4,14 @@ import textwrap
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, Union
|
from typing import Dict, Union
|
||||||
|
|
||||||
from PIL import Image, ImageDraw
|
|
||||||
from gsuid_core.logger import logger
|
from gsuid_core.logger import logger
|
||||||
from gsuid_core.utils.image.convert import convert_img
|
from gsuid_core.utils.image.convert import convert_img
|
||||||
from gsuid_core.utils.image.image_tools import draw_text_by_line
|
from gsuid_core.utils.image.image_tools import draw_text_by_line
|
||||||
|
from PIL import Image, ImageDraw
|
||||||
|
|
||||||
from .to_data import api_to_dict
|
|
||||||
from ..utils.error_reply import CHAR_HINT
|
from ..utils.error_reply import CHAR_HINT
|
||||||
from .cal_damage import cal, cal_char_info
|
|
||||||
from ..utils.fonts.first_world import fw_font_28
|
|
||||||
from ..utils.excel.read_excel import light_cone_ranks
|
from ..utils.excel.read_excel import light_cone_ranks
|
||||||
from ..utils.map.name_covert import name_to_avatar_id, alias_to_char_name
|
from ..utils.fonts.first_world import fw_font_28
|
||||||
from ..utils.map.SR_MAP_PATH import (
|
|
||||||
RelicId2Rarity,
|
|
||||||
AvatarRelicScore,
|
|
||||||
avatarId2Name,
|
|
||||||
)
|
|
||||||
from ..utils.resource.RESOURCE_PATH import (
|
|
||||||
RELIC_PATH,
|
|
||||||
SKILL_PATH,
|
|
||||||
PLAYER_PATH,
|
|
||||||
WEAPON_PATH,
|
|
||||||
CHAR_PORTRAIT_PATH,
|
|
||||||
)
|
|
||||||
from ..utils.fonts.starrail_fonts import (
|
from ..utils.fonts.starrail_fonts import (
|
||||||
sr_font_18,
|
sr_font_18,
|
||||||
sr_font_20,
|
sr_font_20,
|
||||||
@ -37,6 +22,21 @@ from ..utils.fonts.starrail_fonts import (
|
|||||||
sr_font_34,
|
sr_font_34,
|
||||||
sr_font_38,
|
sr_font_38,
|
||||||
)
|
)
|
||||||
|
from ..utils.map.name_covert import alias_to_char_name, name_to_avatar_id
|
||||||
|
from ..utils.map.SR_MAP_PATH import (
|
||||||
|
AvatarRelicScore,
|
||||||
|
RelicId2Rarity,
|
||||||
|
avatarId2Name,
|
||||||
|
)
|
||||||
|
from ..utils.resource.RESOURCE_PATH import (
|
||||||
|
CHAR_PORTRAIT_PATH,
|
||||||
|
PLAYER_PATH,
|
||||||
|
RELIC_PATH,
|
||||||
|
SKILL_PATH,
|
||||||
|
WEAPON_PATH,
|
||||||
|
)
|
||||||
|
from .cal_damage import cal, cal_char_info
|
||||||
|
from .to_data import api_to_dict
|
||||||
|
|
||||||
Excel_path = Path(__file__).parent / 'effect'
|
Excel_path = Path(__file__).parent / 'effect'
|
||||||
with Path.open(Excel_path / 'Excel' / 'SkillData.json', encoding='utf-8') as f:
|
with Path.open(Excel_path / 'Excel' / 'SkillData.json', encoding='utf-8') as f:
|
||||||
@ -99,7 +99,7 @@ async def draw_char_img(char_data: Dict, sr_uid: str, msg: str):
|
|||||||
return char_data
|
return char_data
|
||||||
char = await cal_char_info(char_data)
|
char = await cal_char_info(char_data)
|
||||||
damage_len = 0
|
damage_len = 0
|
||||||
if str(char.char_id) in skill_dict:
|
if char.char_id in skill_dict:
|
||||||
skill_list = skill_dict[str(char.char_id)]['skillList']
|
skill_list = skill_dict[str(char.char_id)]['skillList']
|
||||||
damage_len = len(skill_list)
|
damage_len = len(skill_list)
|
||||||
bg_height = 0
|
bg_height = 0
|
||||||
|
@ -3,7 +3,7 @@ from typing import Dict, List
|
|||||||
from gsuid_core.logger import logger
|
from gsuid_core.logger import logger
|
||||||
|
|
||||||
from ..Base.AvatarBase import BaseAvatar, BaseAvatarBuff
|
from ..Base.AvatarBase import BaseAvatar, BaseAvatarBuff
|
||||||
from ..Base.model import DamageInstanceSkill, DamageInstanceAvatar
|
from ..Base.model import DamageInstanceAvatar, DamageInstanceSkill
|
||||||
|
|
||||||
|
|
||||||
class Seele(BaseAvatar):
|
class Seele(BaseAvatar):
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import json
|
import json
|
||||||
from pathlib import Path
|
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
from typing import List, Union
|
from pathlib import Path
|
||||||
|
from typing import List, Tuple, Union
|
||||||
|
|
||||||
import msgspec
|
import msgspec
|
||||||
from msgspec import Struct
|
from msgspec import Struct
|
||||||
|
|
||||||
from .SkillBase import BaseSkills
|
|
||||||
from ....utils.excel.model import AvatarPromotionConfig
|
from ....utils.excel.model import AvatarPromotionConfig
|
||||||
from .model import DamageInstanceSkill, DamageInstanceAvatar
|
from .model import DamageInstanceAvatar, DamageInstanceSkill
|
||||||
|
from .SkillBase import BaseSkills
|
||||||
|
|
||||||
path = Path(__file__).parent.parent
|
path = Path(__file__).parent.parent
|
||||||
with Path.open(path / 'Excel' / 'SkillData.json', encoding='utf-8') as f:
|
with Path.open(path / 'Excel' / 'SkillData.json', encoding='utf-8') as f:
|
||||||
@ -24,7 +24,7 @@ class BaseAvatarAttribute(Struct):
|
|||||||
CriticalDamageBase: float
|
CriticalDamageBase: float
|
||||||
BaseAggro: float
|
BaseAggro: float
|
||||||
|
|
||||||
def items(self):
|
def items(self) -> List[Tuple[str, float]]:
|
||||||
return [
|
return [
|
||||||
('attack', self.attack),
|
('attack', self.attack),
|
||||||
('defence', self.defence),
|
('defence', self.defence),
|
||||||
|
@ -240,7 +240,6 @@ class Relic110(BaseRelicSetSkill):
|
|||||||
):
|
):
|
||||||
if self.pieces4 and await self.check(base_attr, attribute_bonus):
|
if self.pieces4 and await self.check(base_attr, attribute_bonus):
|
||||||
logger.info('ModifyActionDelay')
|
logger.info('ModifyActionDelay')
|
||||||
pass
|
|
||||||
return attribute_bonus
|
return attribute_bonus
|
||||||
|
|
||||||
|
|
||||||
@ -263,7 +262,6 @@ class Relic111(BaseRelicSetSkill):
|
|||||||
):
|
):
|
||||||
if self.pieces4 and await self.check(base_attr, attribute_bonus):
|
if self.pieces4 and await self.check(base_attr, attribute_bonus):
|
||||||
logger.info('ModifySPNew')
|
logger.info('ModifySPNew')
|
||||||
pass
|
|
||||||
return attribute_bonus
|
return attribute_bonus
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,16 +4,12 @@ from typing import List, Union
|
|||||||
|
|
||||||
from gsuid_core.logger import logger
|
from gsuid_core.logger import logger
|
||||||
|
|
||||||
from .Avatar.Avatar import Avatar
|
|
||||||
from .Weapon.Weapon import Weapon
|
|
||||||
from .utils import merge_attribute
|
|
||||||
from ..mono.Character import Character
|
from ..mono.Character import Character
|
||||||
|
from .Avatar.Avatar import Avatar
|
||||||
from .Base.model import DamageInstance
|
from .Base.model import DamageInstance
|
||||||
from .Relic.Relic import RelicSet, SingleRelic
|
from .Relic.Relic import RelicSet, SingleRelic
|
||||||
|
from .utils import merge_attribute
|
||||||
Excel_path = Path(__file__).parent
|
from .Weapon.Weapon import Weapon
|
||||||
with Path.open(Excel_path / 'Excel' / 'SkillData.json', encoding='utf-8') as f:
|
|
||||||
skill_dict = json.load(f)
|
|
||||||
|
|
||||||
|
|
||||||
class RoleInstance:
|
class RoleInstance:
|
||||||
@ -119,416 +115,3 @@ class RoleInstance:
|
|||||||
self.attribute_bonus[attribute] = self.weapon.weapon_attribute[
|
self.attribute_bonus[attribute] = self.weapon.weapon_attribute[
|
||||||
attribute
|
attribute
|
||||||
]
|
]
|
||||||
|
|
||||||
async def cal_damage(self, skill_type: str):
|
|
||||||
logger.info('base_attr')
|
|
||||||
logger.info(self.base_attr)
|
|
||||||
logger.info('attribute_bonus')
|
|
||||||
logger.info(self.attribute_bonus)
|
|
||||||
logger.info(skill_type)
|
|
||||||
# 技能区
|
|
||||||
skill_info = self.avatar.Skill_Info(skill_type)
|
|
||||||
skill_multiplier = self.avatar.Skill_num(skill_info[4], skill_type)
|
|
||||||
# 检查是否有对某一个技能的倍率加成
|
|
||||||
for attr in self.attribute_bonus:
|
|
||||||
if attr.__contains__('SkillAdd'):
|
|
||||||
skill_name = attr.split('SkillAdd')[0]
|
|
||||||
if skill_name in (skill_type, skill_info[3]):
|
|
||||||
logger.info(
|
|
||||||
f'{skill_name}对{skill_type}有{self.attribute_bonus[attr]}倍率加成'
|
|
||||||
)
|
|
||||||
skill_multiplier = (
|
|
||||||
skill_multiplier + self.attribute_bonus[attr]
|
|
||||||
)
|
|
||||||
|
|
||||||
logger.info(f'技能区总: {skill_multiplier}')
|
|
||||||
|
|
||||||
# 检查武器战斗生效的buff
|
|
||||||
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)
|
|
||||||
|
|
||||||
# 检查是否有对某一个技能的属性加成
|
|
||||||
logger.info('检查是否有对某一个技能的属性加成')
|
|
||||||
for attr in self.attribute_bonus:
|
|
||||||
# 攻击加成
|
|
||||||
if attr.__contains__('AttackAddedRatio'):
|
|
||||||
attr_name = attr.split('AttackAddedRatio')[0]
|
|
||||||
if attr_name in (skill_type, skill_info[3]):
|
|
||||||
attack_added_ratio = self.attribute_bonus.get(
|
|
||||||
'AttackAddedRatio', 0
|
|
||||||
)
|
|
||||||
self.attribute_bonus['AttackAddedRatio'] = (
|
|
||||||
attack_added_ratio + self.attribute_bonus[attr]
|
|
||||||
)
|
|
||||||
# 效果命中加成
|
|
||||||
if attr.__contains__('StatusProbabilityBase'):
|
|
||||||
attr_name = attr.split('StatusProbabilityBase')[0]
|
|
||||||
if attr_name in (skill_type, skill_info[3]):
|
|
||||||
status_probability = self.attribute_bonus.get(
|
|
||||||
'StatusProbabilityBase', 0
|
|
||||||
)
|
|
||||||
self.attribute_bonus['StatusProbabilityBase'] = (
|
|
||||||
status_probability + self.attribute_bonus[attr]
|
|
||||||
)
|
|
||||||
|
|
||||||
merged_attr = await merge_attribute(
|
|
||||||
self.base_attr, self.attribute_bonus
|
|
||||||
)
|
|
||||||
logger.info(f'{merged_attr}')
|
|
||||||
skill_info_list = []
|
|
||||||
# 技能类型为攻击
|
|
||||||
if skill_info[0] == 'attack':
|
|
||||||
if isinstance(skill_info[2], str):
|
|
||||||
raise Exception('skill_info[2] is str')
|
|
||||||
skill_multiplier = skill_multiplier / skill_info[2]
|
|
||||||
logger.info(f'技能区单段: {skill_multiplier}')
|
|
||||||
if self.raw_data.avatar.id_ == 1004:
|
|
||||||
if self.raw_data.avatar.rank >= 6 and skill_type == 'BPSkill':
|
|
||||||
skill_info[2] = skill_info[2] + 1
|
|
||||||
multiplier_add = self.avatar.Talent()
|
|
||||||
skill_multiplier = skill_multiplier + multiplier_add
|
|
||||||
|
|
||||||
if (
|
|
||||||
self.raw_data.avatar.id_ == 1201
|
|
||||||
and self.raw_data.avatar.rank >= 4
|
|
||||||
and skill_type == 'Normal'
|
|
||||||
):
|
|
||||||
skill_info[2] = skill_info[2] + 1
|
|
||||||
|
|
||||||
attack = merged_attr.get('attack', 0)
|
|
||||||
if self.raw_data.avatar.id_ == 1104:
|
|
||||||
# 杰帕德天赋加攻
|
|
||||||
defence = merged_attr['defence']
|
|
||||||
attack = attack + (defence * 0.35)
|
|
||||||
logger.info(f'攻击力: {attack}')
|
|
||||||
damage_add = 0
|
|
||||||
hp_multiplier = 0
|
|
||||||
hp_num = 0
|
|
||||||
if self.raw_data.avatar.id_ in [1205, 1208]:
|
|
||||||
hp_num = merged_attr['hp']
|
|
||||||
skill_type_hp = skill_type + '_HP'
|
|
||||||
if skill_type_hp in skill_dict[str(self.raw_data.avatar.id_)]:
|
|
||||||
hp_multiplier = self.avatar.Skill_num(
|
|
||||||
skill_info[4], skill_type_hp
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
hp_multiplier = 0
|
|
||||||
for attr in self.attribute_bonus:
|
|
||||||
if attr.__contains__('HpSkillAdd'):
|
|
||||||
skill_name = attr.split('HpSkillAdd')[0]
|
|
||||||
if skill_name in (skill_type, skill_info[3]):
|
|
||||||
logger.info(
|
|
||||||
f'{skill_name}对{skill_type}有{self.attribute_bonus[attr]}倍率加成'
|
|
||||||
)
|
|
||||||
hp_multiplier = (
|
|
||||||
hp_multiplier + self.attribute_bonus[attr]
|
|
||||||
)
|
|
||||||
|
|
||||||
if skill_type == 'Talent':
|
|
||||||
if (
|
|
||||||
self.raw_data.avatar.rank >= 6
|
|
||||||
and self.raw_data.avatar.id_ == 1205
|
|
||||||
):
|
|
||||||
damage_add = hp_num * 0.5
|
|
||||||
attack = (skill_multiplier * attack) + (hp_multiplier * hp_num)
|
|
||||||
skill_multiplier = 1
|
|
||||||
logger.info(f'混伤区: {attack}')
|
|
||||||
|
|
||||||
logger.info(f'额外伤害: {damage_add}')
|
|
||||||
# 模拟 同属性弱点 同等级 的怪物
|
|
||||||
# 韧性条减伤
|
|
||||||
enemy_damage_reduction = 0.1
|
|
||||||
damage_reduction = 1 - enemy_damage_reduction
|
|
||||||
logger.info(f'韧性区: {damage_reduction}')
|
|
||||||
# 抗性区
|
|
||||||
enemy_status_resistance = 0.0
|
|
||||||
for attr in merged_attr:
|
|
||||||
if attr.__contains__('ResistancePenetration'):
|
|
||||||
# 检查是否有某一属性的抗性穿透
|
|
||||||
attr_name = attr.split('ResistancePenetration')[0]
|
|
||||||
if attr_name in (self.avatar.avatar_element, 'AllDamage'):
|
|
||||||
logger.info(f'{attr_name}属性有{merged_attr[attr]}穿透加成')
|
|
||||||
enemy_status_resistance += merged_attr[attr]
|
|
||||||
# 检查是否有某一技能属性的抗性穿透
|
|
||||||
if attr_name.__contains__('_'):
|
|
||||||
skill_name = attr_name.split('_')[0]
|
|
||||||
skillattr_name = attr_name.split('_')[1]
|
|
||||||
if skill_name in (
|
|
||||||
skill_type,
|
|
||||||
skill_info[3],
|
|
||||||
) and skillattr_name in (
|
|
||||||
self.avatar.avatar_element,
|
|
||||||
'AllDamage',
|
|
||||||
):
|
|
||||||
enemy_status_resistance += merged_attr[attr]
|
|
||||||
logger.info(
|
|
||||||
f'{skill_name}对{skillattr_name}属性有{merged_attr[attr]}穿透加成'
|
|
||||||
)
|
|
||||||
resistance_area = 1.0 - (0 - enemy_status_resistance)
|
|
||||||
logger.info(f'抗性区: {resistance_area}')
|
|
||||||
|
|
||||||
# 防御区
|
|
||||||
# 检查是否有 ignore_defence
|
|
||||||
logger.info('检查是否有 ignore_defence')
|
|
||||||
ignore_defence = 1.0
|
|
||||||
for attr in merged_attr:
|
|
||||||
if attr == 'ignore_defence':
|
|
||||||
ignore_defence = 1 - merged_attr[attr]
|
|
||||||
break
|
|
||||||
logger.info(f'ignore_defence {ignore_defence}')
|
|
||||||
enemy_defence = (
|
|
||||||
self.avatar.avatar_level * 10 + 200
|
|
||||||
) * ignore_defence
|
|
||||||
defence_multiplier = (self.avatar.avatar_level * 10 + 200) / (
|
|
||||||
self.avatar.avatar_level * 10 + 200 + enemy_defence
|
|
||||||
)
|
|
||||||
logger.info(f'防御区: {defence_multiplier}')
|
|
||||||
|
|
||||||
# 增伤区
|
|
||||||
# TODO: 这里计算只考虑了希儿,需要重写 injury_area = self.avatar.Talent_add()
|
|
||||||
injury_area = self.avatar.Talent_add()
|
|
||||||
# 检查是否有对某一个技能的伤害加成
|
|
||||||
logger.info('检查是否有对某一个技能的伤害加成')
|
|
||||||
for attr in merged_attr:
|
|
||||||
if attr.__contains__('DmgAdd'):
|
|
||||||
attr_name = attr.split('DmgAdd')[0]
|
|
||||||
if attr_name in (skill_type, skill_info[3]):
|
|
||||||
logger.info(
|
|
||||||
f'{attr} 对 {skill_type} 有 {merged_attr[attr]} 伤害加成'
|
|
||||||
)
|
|
||||||
injury_area += merged_attr[attr]
|
|
||||||
# 检查有无符合属性的伤害加成
|
|
||||||
logger.info('检查球有无符合属性的伤害加成')
|
|
||||||
element_area = 0
|
|
||||||
for attr in merged_attr:
|
|
||||||
if attr.__contains__('AddedRatio'):
|
|
||||||
attr_name = attr.split('AddedRatio')[0]
|
|
||||||
if attr_name in (self.avatar.avatar_element, 'AllDamage'):
|
|
||||||
logger.info(
|
|
||||||
f'{attr} 对 {self.avatar.avatar_element} '
|
|
||||||
f'有 {merged_attr[attr]} 伤害加成'
|
|
||||||
)
|
|
||||||
if attr_name == self.avatar.avatar_element:
|
|
||||||
element_area += merged_attr[attr]
|
|
||||||
injury_area += merged_attr[attr]
|
|
||||||
injury_area += 1
|
|
||||||
logger.info(f'增伤区: {injury_area}')
|
|
||||||
|
|
||||||
# 易伤区
|
|
||||||
logger.info('检查是否有易伤加成')
|
|
||||||
damage_ratio = merged_attr.get('DmgRatio', 0)
|
|
||||||
# 检查是否有对特定技能的易伤加成
|
|
||||||
# Talent_DmgRatio
|
|
||||||
for attr in merged_attr:
|
|
||||||
if attr.__contains__('_DmgRatio'):
|
|
||||||
skill_name = attr.split('_')[0]
|
|
||||||
if skill_name in (skill_type, skill_info[3]):
|
|
||||||
logger.info(
|
|
||||||
f'{attr} 对 {skill_type} 有 {merged_attr[attr]} 易伤加成'
|
|
||||||
)
|
|
||||||
damage_ratio += merged_attr[attr]
|
|
||||||
damage_ratio = damage_ratio + 1
|
|
||||||
logger.info(f'易伤: {damage_ratio}')
|
|
||||||
|
|
||||||
# 爆伤区
|
|
||||||
if skill_type == 'DOT':
|
|
||||||
critical_damage_base = 0.0
|
|
||||||
else:
|
|
||||||
logger.info('检查是否有爆伤加成')
|
|
||||||
logger.info(f'{merged_attr}')
|
|
||||||
critical_damage_base = merged_attr.get('CriticalDamageBase', 0)
|
|
||||||
# 检查是否有对特定技能的爆伤加成
|
|
||||||
# Ultra_CriticalChance
|
|
||||||
for attr in merged_attr:
|
|
||||||
if attr.__contains__('_CriticalDamageBase'):
|
|
||||||
skill_name = attr.split('_')[0]
|
|
||||||
if skill_name in (skill_type, skill_info[3]):
|
|
||||||
logger.info(
|
|
||||||
f'{attr} 对 {skill_type} 有 '
|
|
||||||
f'{merged_attr[attr]} 爆伤加成'
|
|
||||||
)
|
|
||||||
critical_damage_base += merged_attr[attr]
|
|
||||||
critical_damage = critical_damage_base + 1
|
|
||||||
logger.info(f'暴伤: {critical_damage}')
|
|
||||||
|
|
||||||
# 暴击区
|
|
||||||
logger.info('检查是否有暴击加成')
|
|
||||||
critical_chance_base = merged_attr['CriticalChanceBase']
|
|
||||||
# 检查是否有对特定技能的爆伤加成
|
|
||||||
# Ultra_CriticalChance
|
|
||||||
for attr in merged_attr:
|
|
||||||
if attr.__contains__('_CriticalChance'):
|
|
||||||
skill_name = attr.split('_')[0]
|
|
||||||
if skill_name in (skill_type, skill_info[3]):
|
|
||||||
logger.info(
|
|
||||||
f'{attr} 对 {skill_type} 有 '
|
|
||||||
f'{merged_attr[attr]} 暴击加成'
|
|
||||||
)
|
|
||||||
critical_chance_base += merged_attr[attr]
|
|
||||||
critical_chance_base = min(1, critical_chance_base)
|
|
||||||
logger.info(f'暴击: {critical_chance_base}')
|
|
||||||
|
|
||||||
# 期望伤害
|
|
||||||
qiwang_damage = (critical_chance_base * critical_damage_base) + 1
|
|
||||||
logger.info(f'暴击期望: {qiwang_damage}')
|
|
||||||
damage_cd_z = 0.0
|
|
||||||
damage_qw_z = 0.0
|
|
||||||
damage_tz_z = 0.0
|
|
||||||
attack_tz = 0.0
|
|
||||||
injury_add = 0.0
|
|
||||||
critical_damage_add = 0
|
|
||||||
for i in range(1, skill_info[2] + 1):
|
|
||||||
injury_add = 0
|
|
||||||
critical_damage_add = 0
|
|
||||||
if self.raw_data.avatar.id_ == 1213:
|
|
||||||
injury_add = self.avatar.Talent()
|
|
||||||
critical_damage_add = self.avatar.BPSkill()
|
|
||||||
normal_buff = merged_attr.get('Normal_buff', 0)
|
|
||||||
if i >= 4:
|
|
||||||
normal_buff = min(4, int(normal_buff + (i - 3)))
|
|
||||||
if normal_buff >= 1:
|
|
||||||
critical_damage_add = normal_buff * critical_damage_add
|
|
||||||
atk_buff = merged_attr.get('Atk_buff', 0)
|
|
||||||
atk_buff = min(10, int((i - 1) * (atk_buff + 1)))
|
|
||||||
injury_add = atk_buff * injury_add
|
|
||||||
qiwang_damage = (
|
|
||||||
critical_chance_base
|
|
||||||
* (critical_damage_base + critical_damage_add)
|
|
||||||
) + 1
|
|
||||||
|
|
||||||
damage_cd = (
|
|
||||||
attack
|
|
||||||
* skill_multiplier
|
|
||||||
* damage_ratio
|
|
||||||
* (injury_area + injury_add)
|
|
||||||
* defence_multiplier
|
|
||||||
* resistance_area
|
|
||||||
* damage_reduction
|
|
||||||
* (critical_damage + critical_damage_add)
|
|
||||||
+ damage_add
|
|
||||||
)
|
|
||||||
damage_cd_z += damage_cd
|
|
||||||
damage_qw = (
|
|
||||||
attack
|
|
||||||
* skill_multiplier
|
|
||||||
* damage_ratio
|
|
||||||
* (injury_area + injury_add)
|
|
||||||
* defence_multiplier
|
|
||||||
* resistance_area
|
|
||||||
* damage_reduction
|
|
||||||
* qiwang_damage
|
|
||||||
+ damage_add
|
|
||||||
)
|
|
||||||
damage_qw_z += damage_qw
|
|
||||||
|
|
||||||
attr_value_tz: float = self.base_attr.get('attack', 0)
|
|
||||||
attribute_atk = self.attribute_bonus.get('AttackDelta', 0)
|
|
||||||
attack_tz = (
|
|
||||||
attr_value_tz
|
|
||||||
+ attr_value_tz
|
|
||||||
* (
|
|
||||||
1
|
|
||||||
+ self.attribute_bonus.get('AttackAddedRatio', 0)
|
|
||||||
+ 2.144
|
|
||||||
)
|
|
||||||
+ attribute_atk
|
|
||||||
)
|
|
||||||
if self.raw_data.avatar.id_ in [1205, 1208]:
|
|
||||||
attack_tz = (skill_multiplier * attack_tz) + (
|
|
||||||
hp_multiplier * hp_num
|
|
||||||
)
|
|
||||||
injury_add_tz = 0
|
|
||||||
if self.avatar.avatar_element == 'Imaginary':
|
|
||||||
injury_add_tz = 0.12
|
|
||||||
damage_tz = (
|
|
||||||
attack_tz
|
|
||||||
* skill_multiplier
|
|
||||||
* damage_ratio
|
|
||||||
* (injury_area + injury_add + injury_add_tz + 2.326)
|
|
||||||
* defence_multiplier
|
|
||||||
* resistance_area
|
|
||||||
* damage_reduction
|
|
||||||
* (critical_damage + critical_damage_add + 1.594)
|
|
||||||
* 10
|
|
||||||
+ damage_add
|
|
||||||
)
|
|
||||||
|
|
||||||
damage_tz_z += damage_tz
|
|
||||||
|
|
||||||
if (
|
|
||||||
self.raw_data.avatar.id_ == 1003
|
|
||||||
and self.raw_data.avatar.rank >= 6
|
|
||||||
):
|
|
||||||
damage_cd_z = damage_cd_z * 1.8
|
|
||||||
damage_qw_z = damage_qw_z * 1.8
|
|
||||||
damage_tz_z = damage_tz_z * 1.8
|
|
||||||
|
|
||||||
if self.avatar.avatar_element == 'Thunder':
|
|
||||||
element_area = 0
|
|
||||||
damage_tz_fj = (
|
|
||||||
attack_tz
|
|
||||||
* 0.44
|
|
||||||
* damage_ratio
|
|
||||||
* (injury_area + injury_add + 2.326 + element_area)
|
|
||||||
* defence_multiplier
|
|
||||||
* resistance_area
|
|
||||||
* damage_reduction
|
|
||||||
* (critical_damage + critical_damage_add + 1.594)
|
|
||||||
* 10
|
|
||||||
)
|
|
||||||
damage_tz_z += damage_tz_fj
|
|
||||||
skill_info_list: List[Union[str, float]] = []
|
|
||||||
skill_info_list.append(skill_info[1])
|
|
||||||
skill_info_list.append(damage_cd_z)
|
|
||||||
skill_info_list.append(damage_qw_z)
|
|
||||||
skill_info_list.append(damage_tz_z)
|
|
||||||
logger.info(
|
|
||||||
f'{skill_info[1]} 暴击伤害: {damage_cd_z} 期望伤害{damage_qw_z}'
|
|
||||||
)
|
|
||||||
|
|
||||||
# 技能类型为防御
|
|
||||||
if skill_info[0] == 'defence':
|
|
||||||
defence = merged_attr['defence']
|
|
||||||
logger.info(f'防御力: {defence}')
|
|
||||||
defence_multiplier = 0
|
|
||||||
|
|
||||||
# 获取技能提供的固定护盾值
|
|
||||||
if skill_type == 'Normal':
|
|
||||||
defence_multiplier = self.avatar.Normalnum('Normal_G')
|
|
||||||
elif skill_type == 'BPSkill':
|
|
||||||
defence_multiplier = self.avatar.BPSkill_num('BPSkill_G')
|
|
||||||
elif skill_type == 'Ultra':
|
|
||||||
defence_multiplier = self.avatar.Ultra_num('Ultra_G')
|
|
||||||
elif skill_type == 'Talent':
|
|
||||||
defence_multiplier = self.avatar.Talent_num('Talent_G')
|
|
||||||
|
|
||||||
# 检查是否有护盾加成
|
|
||||||
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 + defence_multiplier
|
|
||||||
) * shield_added
|
|
||||||
|
|
||||||
skill_info_list: List[Union[str, float]] = []
|
|
||||||
skill_info_list.append(skill_info[1])
|
|
||||||
skill_info_list.append(defence_num)
|
|
||||||
skill_info_list.append(defence_num)
|
|
||||||
skill_info_list.append(defence_num)
|
|
||||||
|
|
||||||
return skill_info_list
|
|
||||||
|
460
StarRailUID/starrailuid_charinfo/effect/damageCal.py
Normal file
460
StarRailUID/starrailuid_charinfo/effect/damageCal.py
Normal file
@ -0,0 +1,460 @@
|
|||||||
|
import json
|
||||||
|
from copy import deepcopy
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import List, Union
|
||||||
|
|
||||||
|
from gsuid_core.logger import logger
|
||||||
|
|
||||||
|
from ..mono.Character import Character
|
||||||
|
from .Role import RoleInstance
|
||||||
|
from .utils import merge_attribute
|
||||||
|
|
||||||
|
Excel_path = Path(__file__).parent
|
||||||
|
with Path.open(Excel_path / 'Excel' / 'SkillData.json', encoding='utf-8') as f:
|
||||||
|
skill_dict = json.load(f)
|
||||||
|
|
||||||
|
|
||||||
|
class DamageCalculator:
|
||||||
|
def __init__(self, char_data: Character):
|
||||||
|
self.char_data = deepcopy(char_data)
|
||||||
|
self.role = RoleInstance(self.char_data)
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
self.role = RoleInstance(self.char_data)
|
||||||
|
self.merged_attr = None
|
||||||
|
|
||||||
|
def get_skill_info(self, skill_type: str):
|
||||||
|
return self.role.avatar.Skill_Info(skill_type)
|
||||||
|
|
||||||
|
async def skill_calculation(self, skill_type: str):
|
||||||
|
skill_info = self.role.avatar.Skill_Info(skill_type)
|
||||||
|
skill_multiplier = self.role.avatar.Skill_num(skill_info[4], skill_type)
|
||||||
|
for attr in self.role.attribute_bonus:
|
||||||
|
if attr.__contains__('SkillAdd'):
|
||||||
|
skill_name = attr.split('SkillAdd')[0]
|
||||||
|
if skill_name in (skill_type, skill_info[3]):
|
||||||
|
logger.info(
|
||||||
|
f'{skill_name}对{skill_type}有{self.role.attribute_bonus[attr]}倍率加成'
|
||||||
|
)
|
||||||
|
skill_multiplier = (
|
||||||
|
skill_multiplier + self.role.attribute_bonus[attr]
|
||||||
|
)
|
||||||
|
|
||||||
|
logger.info(f'技能区总: {skill_multiplier}')
|
||||||
|
|
||||||
|
async def weapon_calculation(self):
|
||||||
|
logger.info('检查武器战斗生效的buff')
|
||||||
|
Ultra_Use = self.role.avatar.Ultra_Use()
|
||||||
|
logger.info('Ultra_Use')
|
||||||
|
logger.info(Ultra_Use)
|
||||||
|
self.role.attribute_bonus = await self.role.weapon.weapon_ability(
|
||||||
|
Ultra_Use, self.role.base_attr, self.role.attribute_bonus
|
||||||
|
)
|
||||||
|
logger.info(self.role.attribute_bonus)
|
||||||
|
logger.info('检查遗器套装战斗生效的buff')
|
||||||
|
for set_skill in self.role.relic_set.SetSkill:
|
||||||
|
self.role.attribute_bonus = await set_skill.set_skill_ability(
|
||||||
|
self.role.base_attr, self.role.attribute_bonus
|
||||||
|
)
|
||||||
|
if self.role.attribute_bonus is None:
|
||||||
|
raise Exception('attribute_bonus is None')
|
||||||
|
logger.info(self.role.attribute_bonus)
|
||||||
|
|
||||||
|
async def attribute_calculation(self, skill_type: str):
|
||||||
|
# 检查是否有对某一个技能的属性加成
|
||||||
|
logger.info('检查是否有对某一个技能的属性加成')
|
||||||
|
for attr in self.role.attribute_bonus:
|
||||||
|
# 攻击加成
|
||||||
|
if attr.__contains__('AttackAddedRatio'):
|
||||||
|
attr_name = attr.split('AttackAddedRatio')[0]
|
||||||
|
if attr_name in (skill_type, self.get_skill_info(skill_type)[3]):
|
||||||
|
attack_added_ratio = self.role.attribute_bonus.get(
|
||||||
|
'AttackAddedRatio', 0
|
||||||
|
)
|
||||||
|
self.role.attribute_bonus['AttackAddedRatio'] = (
|
||||||
|
attack_added_ratio + self.role.attribute_bonus[attr]
|
||||||
|
)
|
||||||
|
# 效果命中加成
|
||||||
|
if attr.__contains__('StatusProbabilityBase'):
|
||||||
|
attr_name = attr.split('StatusProbabilityBase')[0]
|
||||||
|
if attr_name in (skill_type, self.get_skill_info(skill_type)[3]):
|
||||||
|
status_probability = self.role.attribute_bonus.get(
|
||||||
|
'StatusProbabilityBase', 0
|
||||||
|
)
|
||||||
|
self.role.attribute_bonus['StatusProbabilityBase'] = (
|
||||||
|
status_probability + self.role.attribute_bonus[attr]
|
||||||
|
)
|
||||||
|
|
||||||
|
self.merged_attr = await merge_attribute(
|
||||||
|
self.role.base_attr, self.role.attribute_bonus
|
||||||
|
)
|
||||||
|
logger.info(f'{self.merged_attr}')
|
||||||
|
|
||||||
|
async def cal_attack_base_damage(self, skill_type: str):
|
||||||
|
if isinstance(self.get_skill_info(skill_type)[2], str):
|
||||||
|
raise TypeError('skill_info[2] is str')
|
||||||
|
skill_multiplier = self.role.avatar.Skill_num(
|
||||||
|
self.get_skill_info(skill_type)[4],
|
||||||
|
skill_type
|
||||||
|
)
|
||||||
|
skill_multiplier = skill_multiplier / int(self.get_skill_info(skill_type)[2])
|
||||||
|
logger.info(f'技能区单段: {skill_multiplier}')
|
||||||
|
if self.role.raw_data.avatar.id_ == 1004:
|
||||||
|
if self.role.raw_data.avatar.rank >= 6 and skill_type == 'BPSkill':
|
||||||
|
self.get_skill_info(skill_type)[2] = int(self.get_skill_info(skill_type)[2]) + 1
|
||||||
|
multiplier_add = self.role.avatar.Talent()
|
||||||
|
skill_multiplier = skill_multiplier + multiplier_add
|
||||||
|
|
||||||
|
if (
|
||||||
|
self.role.raw_data.avatar.id_ == 1201
|
||||||
|
and self.role.raw_data.avatar.rank >= 4
|
||||||
|
and skill_type == 'Normal'
|
||||||
|
):
|
||||||
|
self.get_skill_info(skill_type)[2] = int(self.get_skill_info(skill_type)[2]) + 1
|
||||||
|
|
||||||
|
assert(self.merged_attr is not None)
|
||||||
|
attack = self.merged_attr.get('attack', 0)
|
||||||
|
if self.role.raw_data.avatar.id_ == 1104:
|
||||||
|
# 杰帕德天赋加攻
|
||||||
|
defence = self.merged_attr['defence']
|
||||||
|
attack = attack + (defence * 0.35)
|
||||||
|
logger.info(f'攻击力: {attack}')
|
||||||
|
damage_add = 0
|
||||||
|
hp_multiplier = 0
|
||||||
|
hp_num = 0
|
||||||
|
if self.role.raw_data.avatar.id_ in [1205, 1208]:
|
||||||
|
hp_num = self.merged_attr['hp']
|
||||||
|
skill_type_hp = skill_type + '_HP'
|
||||||
|
if skill_type_hp in skill_dict[str(self.role.raw_data.avatar.id_)]:
|
||||||
|
hp_multiplier = self.role.avatar.Skill_num(
|
||||||
|
self.get_skill_info(skill_type)[4], skill_type_hp
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
hp_multiplier = 0
|
||||||
|
for attr in self.role.attribute_bonus:
|
||||||
|
if attr.__contains__('HpSkillAdd'):
|
||||||
|
skill_name = attr.split('HpSkillAdd')[0]
|
||||||
|
if skill_name in (skill_type, self.get_skill_info(skill_type)[3]):
|
||||||
|
logger.info(
|
||||||
|
f'{skill_name}对{skill_type}有{self.role.attribute_bonus[attr]}倍率加成'
|
||||||
|
)
|
||||||
|
hp_multiplier = (
|
||||||
|
hp_multiplier + self.role.attribute_bonus[attr]
|
||||||
|
)
|
||||||
|
|
||||||
|
if skill_type == 'Talent':
|
||||||
|
if (
|
||||||
|
self.role.raw_data.avatar.rank >= 6
|
||||||
|
and self.role.raw_data.avatar.id_ == 1205
|
||||||
|
):
|
||||||
|
damage_add = hp_num * 0.5
|
||||||
|
attack = (skill_multiplier * attack) + (hp_multiplier * hp_num)
|
||||||
|
skill_multiplier = 1
|
||||||
|
logger.info(f'混伤区: {attack}')
|
||||||
|
|
||||||
|
logger.info(f'额外伤害: {damage_add}')
|
||||||
|
# 模拟 同属性弱点 同等级 的怪物
|
||||||
|
# 韧性条减伤
|
||||||
|
enemy_damage_reduction = 0.1
|
||||||
|
damage_reduction = 1 - enemy_damage_reduction
|
||||||
|
logger.info(f'韧性区: {damage_reduction}')
|
||||||
|
# 抗性区
|
||||||
|
enemy_status_resistance = 0.0
|
||||||
|
for attr in self.merged_attr:
|
||||||
|
if attr.__contains__('ResistancePenetration'):
|
||||||
|
# 检查是否有某一属性的抗性穿透
|
||||||
|
attr_name = attr.split('ResistancePenetration')[0]
|
||||||
|
if attr_name in (self.role.avatar.avatar_element, 'AllDamage'):
|
||||||
|
logger.info(f'{attr_name}属性有{self.merged_attr[attr]}穿透加成')
|
||||||
|
enemy_status_resistance += self.merged_attr[attr]
|
||||||
|
# 检查是否有某一技能属性的抗性穿透
|
||||||
|
if attr_name.__contains__('_'):
|
||||||
|
skill_name = attr_name.split('_')[0]
|
||||||
|
skillattr_name = attr_name.split('_')[1]
|
||||||
|
if skill_name in (
|
||||||
|
skill_type,
|
||||||
|
self.get_skill_info(skill_type)[3],
|
||||||
|
) and skillattr_name in (
|
||||||
|
self.role.avatar.avatar_element,
|
||||||
|
'AllDamage',
|
||||||
|
):
|
||||||
|
enemy_status_resistance += self.merged_attr[attr]
|
||||||
|
logger.info(
|
||||||
|
f'{skill_name}对{skillattr_name}属性有{self.merged_attr[attr]}穿透加成'
|
||||||
|
)
|
||||||
|
resistance_area = 1.0 - (0 - enemy_status_resistance)
|
||||||
|
logger.info(f'抗性区: {resistance_area}')
|
||||||
|
|
||||||
|
# 防御区
|
||||||
|
# 检查是否有 ignore_defence
|
||||||
|
logger.info('检查是否有 ignore_defence')
|
||||||
|
ignore_defence = 1.0
|
||||||
|
for attr in self.merged_attr:
|
||||||
|
if attr == 'ignore_defence':
|
||||||
|
ignore_defence = 1 - self.merged_attr[attr]
|
||||||
|
break
|
||||||
|
logger.info(f'ignore_defence {ignore_defence}')
|
||||||
|
enemy_defence = (
|
||||||
|
self.role.avatar.avatar_level * 10 + 200
|
||||||
|
) * ignore_defence
|
||||||
|
defence_multiplier = (self.role.avatar.avatar_level * 10 + 200) / (
|
||||||
|
self.role.avatar.avatar_level * 10 + 200 + enemy_defence
|
||||||
|
)
|
||||||
|
logger.info(f'防御区: {defence_multiplier}')
|
||||||
|
|
||||||
|
# 增伤区
|
||||||
|
# TODO: 这里计算只考虑了希儿,需要重写 injury_area = role.avatar.Talent_add()
|
||||||
|
injury_area = self.role.avatar.Talent_add()
|
||||||
|
# 检查是否有对某一个技能的伤害加成
|
||||||
|
logger.info('检查是否有对某一个技能的伤害加成')
|
||||||
|
for attr in self.merged_attr:
|
||||||
|
if attr.__contains__('DmgAdd'):
|
||||||
|
attr_name = attr.split('DmgAdd')[0]
|
||||||
|
if attr_name in (skill_type, self.get_skill_info(skill_type)[3]):
|
||||||
|
logger.info(
|
||||||
|
f'{attr} 对 {skill_type} 有 {self.merged_attr[attr]} 伤害加成'
|
||||||
|
)
|
||||||
|
injury_area += self.merged_attr[attr]
|
||||||
|
# 检查有无符合属性的伤害加成
|
||||||
|
logger.info('检查球有无符合属性的伤害加成')
|
||||||
|
element_area = 0
|
||||||
|
for attr in self.merged_attr:
|
||||||
|
if attr.__contains__('AddedRatio'):
|
||||||
|
attr_name = attr.split('AddedRatio')[0]
|
||||||
|
if attr_name in (self.role.avatar.avatar_element, 'AllDamage'):
|
||||||
|
logger.info(
|
||||||
|
f'{attr} 对 {self.role.avatar.avatar_element} '
|
||||||
|
f'有 {self.merged_attr[attr]} 伤害加成'
|
||||||
|
)
|
||||||
|
if attr_name == self.role.avatar.avatar_element:
|
||||||
|
element_area += self.merged_attr[attr]
|
||||||
|
injury_area += self.merged_attr[attr]
|
||||||
|
injury_area += 1
|
||||||
|
logger.info(f'增伤区: {injury_area}')
|
||||||
|
|
||||||
|
# 易伤区
|
||||||
|
logger.info('检查是否有易伤加成')
|
||||||
|
damage_ratio = self.merged_attr.get('DmgRatio', 0)
|
||||||
|
# 检查是否有对特定技能的易伤加成
|
||||||
|
# Talent_DmgRatio
|
||||||
|
for attr in self.merged_attr:
|
||||||
|
if attr.__contains__('_DmgRatio'):
|
||||||
|
skill_name = attr.split('_')[0]
|
||||||
|
if skill_name in (skill_type, self.get_skill_info(skill_type)[3]):
|
||||||
|
logger.info(
|
||||||
|
f'{attr} 对 {skill_type} 有 {self.merged_attr[attr]} 易伤加成'
|
||||||
|
)
|
||||||
|
damage_ratio += self.merged_attr[attr]
|
||||||
|
damage_ratio = damage_ratio + 1
|
||||||
|
logger.info(f'易伤: {damage_ratio}')
|
||||||
|
|
||||||
|
# 爆伤区
|
||||||
|
if skill_type == 'DOT':
|
||||||
|
critical_damage_base = 0.0
|
||||||
|
else:
|
||||||
|
logger.info('检查是否有爆伤加成')
|
||||||
|
logger.info(f'{self.merged_attr}')
|
||||||
|
critical_damage_base = self.merged_attr.get('CriticalDamageBase', 0)
|
||||||
|
# 检查是否有对特定技能的爆伤加成
|
||||||
|
# Ultra_CriticalChance
|
||||||
|
for attr in self.merged_attr:
|
||||||
|
if attr.__contains__('_CriticalDamageBase'):
|
||||||
|
skill_name = attr.split('_')[0]
|
||||||
|
if skill_name in (skill_type, self.get_skill_info(skill_type)[3]):
|
||||||
|
logger.info(
|
||||||
|
f'{attr} 对 {skill_type} 有 '
|
||||||
|
f'{self.merged_attr[attr]} 爆伤加成'
|
||||||
|
)
|
||||||
|
critical_damage_base += self.merged_attr[attr]
|
||||||
|
critical_damage = critical_damage_base + 1
|
||||||
|
logger.info(f'暴伤: {critical_damage}')
|
||||||
|
|
||||||
|
# 暴击区
|
||||||
|
logger.info('检查是否有暴击加成')
|
||||||
|
critical_chance_base = self.merged_attr['CriticalChanceBase']
|
||||||
|
# 检查是否有对特定技能的爆伤加成
|
||||||
|
# Ultra_CriticalChance
|
||||||
|
for attr in self.merged_attr:
|
||||||
|
if attr.__contains__('_CriticalChance'):
|
||||||
|
skill_name = attr.split('_')[0]
|
||||||
|
if skill_name in (skill_type, self.get_skill_info(skill_type)[3]):
|
||||||
|
logger.info(
|
||||||
|
f'{attr} 对 {skill_type} 有 '
|
||||||
|
f'{self.merged_attr[attr]} 暴击加成'
|
||||||
|
)
|
||||||
|
critical_chance_base += self.merged_attr[attr]
|
||||||
|
critical_chance_base = min(1, critical_chance_base)
|
||||||
|
logger.info(f'暴击: {critical_chance_base}')
|
||||||
|
|
||||||
|
# 期望伤害
|
||||||
|
qiwang_damage = (critical_chance_base * critical_damage_base) + 1
|
||||||
|
logger.info(f'暴击期望: {qiwang_damage}')
|
||||||
|
damage_cd_z = 0.0
|
||||||
|
damage_qw_z = 0.0
|
||||||
|
damage_tz_z = 0.0
|
||||||
|
attack_tz = 0.0
|
||||||
|
injury_add = 0.0
|
||||||
|
critical_damage_add = 0
|
||||||
|
for i in range(1, int(self.get_skill_info(skill_type)[2]) + 1):
|
||||||
|
injury_add = 0
|
||||||
|
critical_damage_add = 0
|
||||||
|
if self.role.raw_data.avatar.id_ == 1213:
|
||||||
|
injury_add = self.role.avatar.Talent()
|
||||||
|
critical_damage_add = self.role.avatar.BPSkill()
|
||||||
|
normal_buff = self.merged_attr.get('Normal_buff', 0)
|
||||||
|
if i >= 4:
|
||||||
|
normal_buff = min(4, int(normal_buff + (i - 3)))
|
||||||
|
if normal_buff >= 1:
|
||||||
|
critical_damage_add = normal_buff * critical_damage_add
|
||||||
|
atk_buff = self.merged_attr.get('Atk_buff', 0)
|
||||||
|
atk_buff = min(10, int((i - 1) * (atk_buff + 1)))
|
||||||
|
injury_add = atk_buff * injury_add
|
||||||
|
qiwang_damage = (
|
||||||
|
critical_chance_base
|
||||||
|
* (critical_damage_base + critical_damage_add)
|
||||||
|
) + 1
|
||||||
|
|
||||||
|
damage_cd = (
|
||||||
|
attack
|
||||||
|
* skill_multiplier
|
||||||
|
* damage_ratio
|
||||||
|
* (injury_area + injury_add)
|
||||||
|
* defence_multiplier
|
||||||
|
* resistance_area
|
||||||
|
* damage_reduction
|
||||||
|
* (critical_damage + critical_damage_add)
|
||||||
|
+ damage_add
|
||||||
|
)
|
||||||
|
damage_cd_z += damage_cd
|
||||||
|
damage_qw = (
|
||||||
|
attack
|
||||||
|
* skill_multiplier
|
||||||
|
* damage_ratio
|
||||||
|
* (injury_area + injury_add)
|
||||||
|
* defence_multiplier
|
||||||
|
* resistance_area
|
||||||
|
* damage_reduction
|
||||||
|
* qiwang_damage
|
||||||
|
+ damage_add
|
||||||
|
)
|
||||||
|
damage_qw_z += damage_qw
|
||||||
|
|
||||||
|
attr_value_tz: float = self.role.base_attr.get('attack', 0)
|
||||||
|
attribute_atk = self.role.attribute_bonus.get('AttackDelta', 0)
|
||||||
|
attack_tz = (
|
||||||
|
attr_value_tz
|
||||||
|
+ attr_value_tz
|
||||||
|
* (
|
||||||
|
1
|
||||||
|
+ self.role.attribute_bonus.get('AttackAddedRatio', 0)
|
||||||
|
+ 2.144
|
||||||
|
)
|
||||||
|
+ attribute_atk
|
||||||
|
)
|
||||||
|
if self.role.raw_data.avatar.id_ in [1205, 1208]:
|
||||||
|
attack_tz = (skill_multiplier * attack_tz) + (
|
||||||
|
hp_multiplier * hp_num
|
||||||
|
)
|
||||||
|
injury_add_tz = 0
|
||||||
|
if self.role.avatar.avatar_element == 'Imaginary':
|
||||||
|
injury_add_tz = 0.12
|
||||||
|
damage_tz = (
|
||||||
|
attack_tz
|
||||||
|
* skill_multiplier
|
||||||
|
* damage_ratio
|
||||||
|
* (injury_area + injury_add + injury_add_tz + 2.326)
|
||||||
|
* defence_multiplier
|
||||||
|
* resistance_area
|
||||||
|
* damage_reduction
|
||||||
|
* (critical_damage + critical_damage_add + 1.594)
|
||||||
|
* 10
|
||||||
|
+ damage_add
|
||||||
|
)
|
||||||
|
|
||||||
|
damage_tz_z += damage_tz
|
||||||
|
|
||||||
|
if (
|
||||||
|
self.role.raw_data.avatar.id_ == 1003
|
||||||
|
and self.role.raw_data.avatar.rank >= 6
|
||||||
|
):
|
||||||
|
damage_cd_z = damage_cd_z * 1.8
|
||||||
|
damage_qw_z = damage_qw_z * 1.8
|
||||||
|
damage_tz_z = damage_tz_z * 1.8
|
||||||
|
|
||||||
|
if self.role.avatar.avatar_element == 'Thunder':
|
||||||
|
element_area = 0
|
||||||
|
damage_tz_fj = (
|
||||||
|
attack_tz
|
||||||
|
* 0.44
|
||||||
|
* damage_ratio
|
||||||
|
* (injury_area + injury_add + 2.326 + element_area)
|
||||||
|
* defence_multiplier
|
||||||
|
* resistance_area
|
||||||
|
* damage_reduction
|
||||||
|
* (critical_damage + critical_damage_add + 1.594)
|
||||||
|
* 10
|
||||||
|
)
|
||||||
|
damage_tz_z += damage_tz_fj
|
||||||
|
skill_info_list: List[Union[str, float]] = []
|
||||||
|
skill_info_list.append(self.get_skill_info(skill_type)[1])
|
||||||
|
skill_info_list.append(damage_cd_z)
|
||||||
|
skill_info_list.append(damage_qw_z)
|
||||||
|
skill_info_list.append(damage_tz_z)
|
||||||
|
logger.info(
|
||||||
|
f'{self.get_skill_info(skill_type)[1]} 暴击伤害: {damage_cd_z} 期望伤害{damage_qw_z}'
|
||||||
|
)
|
||||||
|
return skill_info_list
|
||||||
|
|
||||||
|
async def cal_defense_base_damage(self, skill_type: str):
|
||||||
|
###########################################
|
||||||
|
###########################################
|
||||||
|
# 这里我直接cv的, 记得改 #
|
||||||
|
###########################################
|
||||||
|
###########################################
|
||||||
|
assert(self.merged_attr is not None)
|
||||||
|
defence = self.merged_attr['defence']
|
||||||
|
logger.info(f'防御力: {defence}')
|
||||||
|
defence_multiplier = 0
|
||||||
|
|
||||||
|
# 获取技能提供的固定护盾值
|
||||||
|
if skill_type == 'Normal':
|
||||||
|
defence_multiplier = self.role.avatar.Normalnum('Normal_G')
|
||||||
|
elif skill_type == 'BPSkill':
|
||||||
|
defence_multiplier = self.role.avatar.BPSkill_num('BPSkill_G')
|
||||||
|
elif skill_type == 'Ultra':
|
||||||
|
defence_multiplier = self.role.avatar.Ultra_num('Ultra_G')
|
||||||
|
elif skill_type == 'Talent':
|
||||||
|
defence_multiplier = self.role.avatar.Talent_num('Talent_G')
|
||||||
|
|
||||||
|
# 检查是否有护盾加成
|
||||||
|
shield_added_ratio = self.merged_attr.get('shield_added_ratio', 0)
|
||||||
|
shield_added = shield_added_ratio + 1
|
||||||
|
logger.info(f'护盾加成: {shield_added}')
|
||||||
|
|
||||||
|
skill_multiplier = self.role.avatar.Skill_num(
|
||||||
|
self.get_skill_info(skill_type)[4],
|
||||||
|
skill_type
|
||||||
|
)
|
||||||
|
skill_multiplier = skill_multiplier / int(self.get_skill_info(skill_type)[2])
|
||||||
|
|
||||||
|
defence_num = (
|
||||||
|
defence * skill_multiplier + defence_multiplier
|
||||||
|
) * shield_added
|
||||||
|
|
||||||
|
skill_info_list: List[Union[str, float]] = []
|
||||||
|
skill_info_list.append(self.get_skill_info(skill_type)[1])
|
||||||
|
skill_info_list.append(defence_num)
|
||||||
|
skill_info_list.append(defence_num)
|
||||||
|
skill_info_list.append(defence_num)
|
||||||
|
|
||||||
|
async def cal_heal_base_damage(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def cal_damage(self, skill_type: str):
|
||||||
|
await self.skill_calculation(skill_type)
|
||||||
|
await self.weapon_calculation()
|
||||||
|
await self.attribute_calculation(skill_type)
|
||||||
|
skill_info_list = await self.cal_attack_base_damage(skill_type)
|
||||||
|
self.clear()
|
||||||
|
|
||||||
|
return skill_info_list
|
Loading…
x
Reference in New Issue
Block a user