from functools import cache import importlib from typing import Literal from core.basic.property import CharacterInfo from core.basic.skill import Skill from core.basic.equipment import get_equipment, EquEffect, Equ # from core.basic.equipment import equipments # from core.basic.skill import Skill, ActiveSkill, PassiveSkill from .formula import 增幅计算, 强化技攻, 武器强化计算, 精通计算, 获取基础属性, 耳环计算, 左右计算, 锻造计算 from .roleinfo import CharacterEquipInfo, get_key_by_value # from .property import 精通计算, 角色基础, CharacterInfo class Character: # region 角色属性 STR: float """力量""" INT: float """智力""" Spirit: float """精神""" Vitality: float """体力""" AtkP: float """物理攻击力""" PAtkP: float """物理攻击力%""" AtkM: float """魔法攻击力""" PAtkM: float """魔法攻击力%""" AtkI: float """独立攻击力""" PAtkI: float """独立攻击力%""" ElementA: dict[str, float] """属性攻击""" ElementIncrease: float """属性增幅""" ElementDB: dict[str, float] """属性强化数值""" ElementR: dict[str, float] """属性抗性数值""" CriticalM: float """魔法暴击""" CriticalP: float """物理暴击""" SkillAttack: float """技能攻击力""" SpeedA: float """攻击速度""" SpeedM: float """移动速度""" SpeedR: float """施放速度""" Hit: float """命中率""" Abnormal: dict[str, bool] """敌人异常状态""" MonsterInfo: dict[str, float] Buffer: float """增益量""" BufferP: float """增益量%""" Attack: float """攻击强化""" AttackP: float """攻击强化%""" # endregion skills: list['Skill'] = [] # """技能列表""" skills_dict: dict[str, 'Skill'] = {} # """技能名字对应技能""" equVersion: str = '0' """装备版本""" charEquipInfo: dict[str, 'CharacterEquipInfo'] """装备打造信息""" equ_effect: list['EquEffect'] = [] """装备效果列表""" # region 角色属性 输出类型: str = '物理' buffer: bool = False # endregion # region 职业属性 实际名称: str = '' 名称: str = '' 角色: str = '' 角色类型: str = '' 职业: str = '' 武器选项: list[str] = [] 输出类型选项: list[str] = [] 防具精通属性: list[str] = [] 类型 = '' 输出类型: str = '物理' # endregion def __init__(self, equVersion) -> None: self.equVersion = equVersion # self.equs = get_equ(self.equVersion) self.STR = 0 self.INT = 0 self.Spirit = 0 self.Vitality = 0 self.AtkP = 0 self.AtkM = 0 self.AtkI = 0 self.PAtkP = 1.0 self.PAtkM = 1.0 self.PAtkI = 1.0 self.ElementA = { '火': False, '冰': False, '光': False, '暗': False, } self.ElementDB = { '火': 0, '冰': 0, '光': 0, '暗': 0, } self.ElementR = { '火': 0, '冰': 0, '光': 0, '暗': 0, } self.Abnormal = { '出血': False, '灼伤': False, '感电': False, '中毒': False, } self.CriticalM = 0 self.CriticalP = 0 self.SkillAttack = 1 self.SpeedA = 0 self.SpeedM = 0 self.SpeedR = 0 self.HitP = 0 self.Hit = 0 self.MonsterInfo = { 'DefenseP': 0, 'DefenseM': 0, '火抗': 0, '冰抗': 0, '光抗': 0, '暗抗': 0, } self.Buffer = 0 self.BufferP = 1.0 self.Attack = 0 self.AttackP = 1.0 self.ElementIncrease = 0 self.equs = {} pass # region 角色属性设置 def SetBaseStatus(self) -> None: """设角色基础属性""" # 角色四维 temp = 获取基础属性(self.角色, self.职业) for index, i in enumerate([get_key_by_value(i) for i in ['力量', '体力', '智力', '精神']]): setattr(self, i, temp[index]) # 角色属性抗性 pass # 角色异常抗性 pass def SetStatus( self, 力量=0, 智力=0, 力智=0, 体力=0, 精神=0, 体精=0, 四维=0, 物攻=0, 魔攻=0, 独立=0, 三攻=0, 技攻=0, 全属强=0, 火强=0, 冰强=0, 光强=0, 暗强=0, 全属抗=0, 火抗=0, 冰抗=0, 光抗=0, 暗抗=0, 火属性攻击=False, 冰属性攻击=False, 光属性攻击=False, 暗属性攻击=False, 移速=0, 攻速=0, 施放=0, 命中=0, 命中率=0, 物暴=0, 魔暴=0, 攻击强化=0, 攻击强化P=0, 增益量=0, 增益量P=0, **kwargs, ) -> None: """设置角色属性""" allowed_kwargs = { 'STR', 'INT', 'AtkP', 'AtkM', 'AtkI', 'PAtkP', 'PAtkM', 'PAtkI', 'PATKIPDamage', 'PDamageC', 'PSTR', 'PINT', 'PDamageB', 'ElementA', 'ElementDB', 'ElementR', 'CriticalMP', 'CriticalM', 'CriticalPP', 'CriticalP', 'EquipmentSkillAttack', 'SkillAttack', 'SpeedA', 'SpeedM', 'SpeedR', 'HitP', 'Hit', 'Attack', 'AttackP', 'Buffer', 'BufferP', 'Spirit', 'Vitality' } for key in kwargs: if key not in allowed_kwargs: raise ValueError(f'Invalid keyword argument: {key}') self.STR += 力量 + kwargs.get('STR', 0) + 四维 + 力智 self.INT += 智力 + kwargs.get('INT', 0) + 四维 + 力智 self.Spirit += 精神 + kwargs.get('Spirit', 0) + 四维 + 体精 self.Vitality += 体力 + kwargs.get('Vitality', 0) + 四维 + 体精 self.AtkP += 物攻 + kwargs.get('AtkP', 0) + 三攻 self.AtkM += 魔攻 + kwargs.get('AtkM', 0) + 三攻 self.AtkI += 独立 + kwargs.get('AtkI', 0) + 三攻 self.PAtkP *= kwargs.get('PAtkP', 1.0) self.PAtkM *= kwargs.get('PAtkM', 1.0) self.PAtkI *= kwargs.get('PAtkI', 1.0) for elem in ['火', '冰', '光', '暗']: self.ElementA[elem] = kwargs.get(f'{elem}属性攻击', False) or kwargs.get('ElementA', {}).get(elem, False) or self.ElementA[elem] self.ElementDB[elem] += kwargs.get(f'{elem}强', 0) + kwargs.get('ElementDB', {}).get(elem, 0) + kwargs.get('全属强', 0) self.ElementR[elem] += kwargs.get(f'{elem}抗', 0) + kwargs.get('ElementR', {}).get(elem, 0) + kwargs.get('全属抗', 0) self.CriticalM += kwargs.get('CriticalM', 0) + 魔暴 self.CriticalP += kwargs.get('CriticalP', 0) + 物暴 self.SkillAttack += (1 + 技攻) * (1 + kwargs.get('SkillAttack', 0)) self.SpeedA += 攻速 + kwargs.get('SpeedA', 0) self.SpeedM += 移速 + kwargs.get('SpeedM', 0) self.SpeedR += 施放 + kwargs.get('SpeedR', 0) self.HitP += 命中率 + kwargs.get('HitP', 0) self.Hit += 命中 + kwargs.get('Hit', 0) self.Attack += 攻击强化 + kwargs.get('Attack', 0) self.AttackP += 攻击强化P + kwargs.get('AttackP', 0) self.Buffer += 增益量 + kwargs.get('Buffer', 0) self.BufferP += 增益量P + kwargs.get('BufferP', 0) pass def AddSkillLv(self, min: int, max: int, lv: int, type=-1) -> None: """ 增加技能等级 type: -1 全部, 0 被动, 1 主动 """ for skill in self.skills: if min <= skill.requiredLv <= max: if type == -1 or skill.type == type: skill.AddLv(lv, self) def SetSkillCD(self, min=1, max=100, cd=0, exclude=[50, 85, 100]) -> None: """ 设置技能CD type: -1 全部, 0 被动, 1 主动 """ for skill in self.skills: if min <= skill.requiredLv <= max and skill.damage and skill.requiredLv not in exclude: skill.CDR *= 1 - cd def GetSkillByName(self, name) -> Skill: """通过技能名获取技能""" return self.skills_dict.get(name, None) def GetSkillByID(self, id: str) -> Skill: skill = list(filter(lambda x: str(x.id) == id, self.skills)) """通过技能ID获取技能""" return skill[0] if len(skill) > 0 else None def GetSkillNames(self, type: Literal['active', 'passive', 'all'] = 'all', damage: Literal[True, False, 'all'] = 'all') -> list[str]: """获取技能名字""" return [skill.name for skill in self.skills if (type == 'all' or skill.type == type) and (damage == 'all' or skill.damage == damage)] # endregion # region 计算相关 def SetDetail(self, info: dict[str, dict]) -> None: self.charEquipInfo = {} """打造信息导入""" for key in info['equips']: # 导入部位打造信息、装备信息、贴膜信息 self.charEquipInfo[key] = CharacterEquipInfo(info['equips'][key], self.equVersion, key) """辟邪玉""" self.jadeInfo = {} for key in info.get('jades', {}): self.jadeInfo[key] = info['jades'][key] """时装""" """杂项""" def getInfo(self): """返回到前端信息""" info = {} info['role'] = self.role info['alter'] = self.name info['equVersion'] = self.equVersion info['name'] = self.nameCN info['weapons'] = self.武器选项 skillInfo = [] for skill in self.skills: skillInfo.append( { 'id': skill.id, 'name': skill.name, 'icon': skill.icon, 'type': skill.type, # 'SPCost': skill.SPCost, 'learnLv': skill.learnLv, 'masterLv': skill.masterLv, 'maxLearnLv': skill.calculate_lv(), 'maxLv': skill.maxLv, # 'TPCost': 0 if not skill.hasTP else skill.TPCost, # "masterTPLv":0 if not skill.hasTP else skill.masterTPLv, # 'maxTPLv': 0 if not skill.hasTP else skill.TPLearnMax, 'position': skill.position, } ) info['skills'] = skillInfo equs = [] suits = [] for i in get_equipment(self.equVersion).equs: equs.append(i.__dict__) for i in get_equipment(self.equVersion).suits: suits.append(i.__dict__) info['equips'] = equs info['suits'] = suits enchats = [] emblems = [] return info def getBasicInos(self): res = [] attrs = [] if self.输出类型 == '物理': attrs = ['STR', 'PSTR', 'AtkP', 'PAtkP', 'CriticalPP', 'CriticalP'] if self.输出类型 == '魔法': attrs = ['INT', 'PINT', 'AtkM', 'PAtkM', 'CriticalMP', 'CriticalM'] for attr in attrs + ['PDamage', 'PDamageC', 'PDamageB', 'SpeedA', 'SpeedM', 'SpeedR']: temp = getattr(CharacterInfo, attr) res.append( { 'name': temp.name, 'value': temp.value(getattr(self, attr)), 'icon': temp.icon, } ) keys = ['火', '冰', '光', '暗'] for index in range(0, 4): temp = getattr(CharacterInfo, f'ElementDB{index}') res.append( { 'name': temp.name, 'value': temp.value(getattr(self, 'ElementDB')[keys[index]]), 'icon': temp.icon, } ) temp = getattr(CharacterInfo, f'ElementR{index}') res.append( { 'name': temp.name, 'value': temp.value(getattr(self, 'ElementR')[keys[index]]), 'icon': temp.icon, } ) return res def calc_init(self, setInfo: dict[str, dict]): # 打造信息导入 self.SetDetail(setInfo) # 技能等级设置 self.SetSkills(setInfo.get('skills', {})) pass def SetSkills(self, skills: dict[str, dict]): """设置技能等级""" for key in skills: skill = self.GetSkillByID(key) if skill is not None: skill.lv = skills[key].get('lv', 0) pass def load_skills(self): pass def calc_suits(self): """套装效果统计""" suitInfo = {} equs = get_equipment(self.equVersion) # 设置装备和获取对应的套装属性 for part in self.charEquipInfo.keys(): # 当前部位的打造 cur = self.charEquipInfo[part] # 当前部位适用调试后的属性 partEqu = equs.equ_dict.get(cur.id).adapt(cur.adaptation) # 设置当前部位的装备 self.charEquipInfo[part].equInfo = equs.equ_dict.get(cur.id) # 套装属性设置 for suit in partEqu.suit: if suitInfo.get(suit, None) is None: suitInfo[suit] = { 'point': 0, 'count': 0, } if partEqu.Point == 0: suitInfo[suit]['count'] += 1 else: suitInfo[suit]['point'] += partEqu.Point # 取得点数最高的套装 max_point_suit = max((suit for suit in suitInfo if suitInfo[suit]['point'] > 0), key=lambda suit: suitInfo[suit]['point'], default=None) # 处理没有点数的老套装 zero_point_suits = [suit for suit in suitInfo if suitInfo[suit]['point'] == 0] suits = zero_point_suits + ([max_point_suit] if max_point_suit is not None else []) suits_effect = [] for suit in suits: if suitInfo[suit]['point'] == 0: suits_effect += [i.id for i in equs.get_suit_info(suit, 0, suitInfo[suit]['count'])] else: suits_effect += [i.id for i in equs.get_suit_info(suit, suitInfo[suit]['point'], 0)] return suits_effect def calc_basic(self): """计算基础属性:防具精通、增幅、强化等""" # 防具精通跟随装备品级 for part in ['上衣', '头肩', '下装', '腰带', '鞋']: cur = self.charEquipInfo[part] equ = cur.equInfo reinforce = self.charEquipInfo[part].reinforce value = 精通计算(115, equ.rarity, reinforce, equ.itemDetailType, self.防具类型) for key in self.防具精通属性: key = get_key_by_value(key) setattr(self, key, getattr(self, key) + value) # 115增幅强化品级固定史诗 for part in self.charEquipInfo.keys(): cur = self.charEquipInfo[part] # 增幅 if cur.reinforceType == 1: # 增幅四维 value = 增幅计算(115, '史诗', cur.reinforce) self.SetStatus(STR=value, INT=value, Spirit=value, Vitality=value) # 增幅技攻计算 value = 强化技攻(cur.reinforce, cur.reinforceType, part) self.SetStatus(SkillAttack=value) # 武器强化、武器锻造、特殊装备强化额外效果计算 if part == '武器': # 锻造独立计算 value = 锻造计算(115, '史诗', cur.refine) self.SetStatus(AtkI = value) # 传世武器强化系数取所有武器的最高的1.12 if cur.equInfo.categorize == '传世武器': value = 武器强化计算(115, '史诗', cur.reinforce,cur.equInfo.itemDetailType,'物理',1.12) self.SetStatus(AtkP=value, AtkM=value) else: # 强化计算 value = 武器强化计算(115, '史诗', cur.reinforce, cur.equInfo.itemDetailType, '物理') self.SetStatus(AtkP=value) value = 武器强化计算(115, '史诗', cur.reinforce, cur.equInfo.itemDetailType, '魔法') self.SetStatus(AtkM=value) pass if part == '耳环': value = 耳环计算(115, '史诗', cur.reinforce) self.SetStatus(AtkM=value, AtkP=value,AtkI=value) pass if part in ['辅助装备', '魔法石']: value = 左右计算(115, '史诗', cur.reinforce) self.SetStatus(STR=value, INT=value, Spirit=value, Vitality=value) pass pass def calc_jade(self): """计算辟邪玉效果""" pass def calc(self, setInfo: dict[str, dict]): funcs = [] suits = [] self.calc_init(setInfo) # self.SetDetail(setInfo) # 角色基础属性 self.SetBaseStatus() # 辟邪玉计算 # 精通、增幅、强化计算 self.calc_basic() # 单件效果计算 # 套装效果列表 suits_effect = self.calc_suits() effects = get_equipment(self.equVersion).funs for effect in suits_effect: func = effects.suit_func_list.get(str(effect), None) func(self) # 徽章计算 # 附魔计算 # 技能计算 skill = self.GetSkillByName('G-35L感电手雷') print(skill.getSkillDate(skill.lv), skill.skillDamage, skill.skillRation) # self.calc_damage_ration() return # 技能影响角色的属性,如属强、抗性等 def calc_damage_ration(self): """计算最终属性""" # 计算最终属性 print(self.AtkI, self.PAtkI) # 角色基础属性 # 角色装备属性 # 角色技能属性 # 角色增益属性 # 角色套装属性 # 角色徽章属性 # 角色附魔属性 # 角色辟邪玉属性 pass # endregion def createCharacter(alter: str, equVersion: str = '0'): character: Character = None module_name = 'core.character.' + alter if equVersion is None or equVersion == '': equVersion = '0' try: character = importlib.import_module(module_name).classChange(equVersion) except Exception as ex: print(ex) print('create character ' + module_name + ' error.') pass return character