dev
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
"""
|
||||
core.basic.character 包
|
||||
- jade.py : Jade(辟邪玉)数据类
|
||||
- base.py : CharacterBase — 属性声明、__init__、基础状态设置、技能操作
|
||||
- calc_equip.py : CalcEquipMixin — 套装/装备/时装/基础强化/辟邪玉/杂项计算 + calc 主入口
|
||||
- calc_carry.py : CalcCarryMixin — 输出角色伤害系数与技能伤害计算
|
||||
- calc_buffer.py : CalcBufferMixin — 辅助角色 Buff 技能计算
|
||||
- info.py : CharacterInfoMixin — 前端展示信息查询
|
||||
"""
|
||||
|
||||
import importlib
|
||||
|
||||
from .jade import Jade
|
||||
from .calc_equip import CalcEquipMixin
|
||||
from .calc_carry import CalcCarryMixin
|
||||
from .calc_buffer import CalcBufferMixin
|
||||
from .info import CharacterInfoMixin
|
||||
|
||||
|
||||
class Character(CalcEquipMixin, CalcCarryMixin, CalcBufferMixin, CharacterInfoMixin):
|
||||
"""
|
||||
角色类,通过多重继承组合各模块能力。
|
||||
|
||||
MRO(方法解析顺序):
|
||||
Character → CalcEquipMixin → CalcCarryMixin → CalcBufferMixin
|
||||
→ CharacterInfoMixin → CharacterBase → CharacterProperty
|
||||
"""
|
||||
|
||||
|
||||
def createCharacter(alter: str, equVersion: str = '0') -> 'Character':
|
||||
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.')
|
||||
return character
|
||||
|
||||
|
||||
__all__ = ['Character', 'Jade', 'createCharacter']
|
||||
@@ -0,0 +1,338 @@
|
||||
from collections.abc import Mapping
|
||||
from typing import Any, Literal
|
||||
|
||||
from core.abstract.character import CharacterProperty
|
||||
from core.basic.skill import Skill
|
||||
from core.basic.equipment import EquEffect
|
||||
from ..formula import 获取基础属性, 获取唤醒属性
|
||||
from ..roleinfo import CharacterEquipInfo, get_key_by_value, CharacterOathInfo
|
||||
from .jade import Jade
|
||||
|
||||
|
||||
class CharacterBase(CharacterProperty):
|
||||
# region 额外类属性(CharacterProperty 中未声明的)
|
||||
|
||||
BindAwake: int
|
||||
"""绑定觉醒等级"""
|
||||
skills: list['Skill'] = []
|
||||
skills_dict: dict[str, 'Skill'] = {}
|
||||
equVersion: str = '0'
|
||||
"""装备版本"""
|
||||
charEquipInfo: dict[str, 'CharacterEquipInfo']
|
||||
"""装备打造信息"""
|
||||
charOathInfo: list['CharacterOathInfo']
|
||||
"""誓约打造信息"""
|
||||
equ_effect: list['EquEffect'] = []
|
||||
"""装备效果列表"""
|
||||
equ_options: dict[str, int] = {}
|
||||
"""装备选项列表"""
|
||||
EquEffectRatio = 1.0
|
||||
"""装备效果倍率"""
|
||||
max_point = 0
|
||||
"""套装效果点数"""
|
||||
buffer: bool = False
|
||||
|
||||
# region 职业属性
|
||||
实际名称: str = ''
|
||||
名称: str = ''
|
||||
角色: str = ''
|
||||
角色类型: str = ''
|
||||
职业: str = ''
|
||||
武器选项: list[str] = []
|
||||
副武器选项: list[str] = []
|
||||
输出类型选项: list[str] = []
|
||||
防具精通属性: list[str] = []
|
||||
输出类型: str = '物理百分比'
|
||||
# endregion
|
||||
|
||||
# endregion
|
||||
|
||||
# region 跨 Mixin 方法前向声明(供静态类型检查使用,由对应 Mixin 实现)
|
||||
|
||||
def load_skills(self) -> None:
|
||||
"""加载技能(由 CalcEquipMixin 实现)"""
|
||||
|
||||
def calc_carry_skills(self, DSB: bool, BUFF: bool) -> list:
|
||||
"""计算输出技能(由 CalcCarryMixin 实现)"""
|
||||
return []
|
||||
|
||||
def get_carry_info(self) -> list:
|
||||
"""获取输出信息(由 CalcCarryMixin 实现)"""
|
||||
return []
|
||||
|
||||
def calc_buffer_skills(self) -> list:
|
||||
"""计算辅助技能(由 CalcBufferMixin 实现)"""
|
||||
return []
|
||||
|
||||
def get_buffer_info(self) -> list:
|
||||
"""获取辅助信息(由 CalcBufferMixin 实现)"""
|
||||
return []
|
||||
|
||||
# endregion
|
||||
|
||||
def __init__(self, equVersion, moduleName) -> None:
|
||||
self.equVersion = equVersion
|
||||
self.moduleName = moduleName
|
||||
# 工会四维
|
||||
self.STR = 0 + 120
|
||||
self.INT = 0 + 120
|
||||
self.Spirit = 0 + 120
|
||||
self.Vitality = 0 + 120
|
||||
# 唤醒的情况下的基础数据
|
||||
self.AtkP = 0 + 65
|
||||
self.AtkM = 0 + 65
|
||||
self.AtkI = 1116 + 65
|
||||
self.PAtkP = 1.0
|
||||
self.PAtkM = 1.0
|
||||
self.PAtkI = 1.0
|
||||
self.ElementA = {
|
||||
'火': False,
|
||||
'冰': False,
|
||||
'光': False,
|
||||
'暗': False,
|
||||
}
|
||||
self.ElementDB = {
|
||||
'火': 13,
|
||||
'冰': 13,
|
||||
'光': 13,
|
||||
'暗': 13,
|
||||
}
|
||||
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 = 1.0
|
||||
self.equs = {}
|
||||
self.jade_effect = Jade()
|
||||
self.equ_effect = []
|
||||
self.equ_options = {}
|
||||
self.max_point = 0
|
||||
self.skills = []
|
||||
self.skills_dict = {}
|
||||
self.load_skills()
|
||||
|
||||
# region 角色属性设置
|
||||
|
||||
def SetBaseStatus(self) -> None:
|
||||
"""设角色基础属性"""
|
||||
temp = 获取基础属性(self.角色, self.职业)
|
||||
唤醒 = 获取唤醒属性()
|
||||
for index, i in enumerate([get_key_by_value(i) for i in ['力量', '体力', '智力', '精神']]):
|
||||
setattr(self, i, getattr(self, i) + temp[index] + 唤醒)
|
||||
|
||||
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,
|
||||
攻击强化=0,
|
||||
攻击强化P=0,
|
||||
增益量=0,
|
||||
增益量P=0,
|
||||
**kwargs: Mapping[
|
||||
Literal[
|
||||
'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',
|
||||
'EquEffectRatio',
|
||||
'火强',
|
||||
'冰强',
|
||||
'光强',
|
||||
'暗强',
|
||||
'火属性抗性',
|
||||
'冰属性抗性',
|
||||
'光属性抗性',
|
||||
'暗属性抗性',
|
||||
'火属性攻击',
|
||||
'冰属性攻击',
|
||||
'光属性攻击',
|
||||
'暗属性攻击',
|
||||
],
|
||||
Any,
|
||||
],
|
||||
) -> None:
|
||||
"""设置角色属性"""
|
||||
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) + 全属强
|
||||
self.ElementR[elem] += kwargs.get(f'{elem}抗', 0) + kwargs.get('ElementR', {}).get(elem, 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.0)
|
||||
self.Buffer += 增益量 + kwargs.get('Buffer', 0)
|
||||
self.BufferP += 增益量P + kwargs.get('BufferP', 0)
|
||||
self.EquEffectRatio += kwargs.get('EquEffectRatio', 0.0)
|
||||
|
||||
def AddElementDB(self, element: str, value: float, type: int = 0) -> None:
|
||||
"""
|
||||
增加属性强化
|
||||
type: 0 站街 1 进图
|
||||
"""
|
||||
if element not in self.ElementDB:
|
||||
raise ValueError(f'Invalid element: {element}')
|
||||
if type == 0:
|
||||
value = value * (1 + self.jade_effect.ElementIncrease)
|
||||
if type == 1:
|
||||
value = int(value * (1 + self.jade_effect.ElementIncrease))
|
||||
self.ElementDB[element] += value
|
||||
|
||||
def AddSkillLv(self, min: int, max: int, lv: int, type=-1, exceptSkills: list[str] = []) -> None:
|
||||
"""
|
||||
增加技能等级
|
||||
type: -1 全部, 0 被动, 1 主动
|
||||
"""
|
||||
skillType = 'all' if type == -1 else ('active' if type == 1 else 'passive')
|
||||
for skill in self.skills:
|
||||
if min <= skill.learnLv <= max:
|
||||
if (skillType == 'all' or skill.type == skillType) and skill.lv > 0 and skill.name not in exceptSkills:
|
||||
skill.lv += lv
|
||||
|
||||
def SetSkillCD(self, min=1, max=100, cd=0, exclude=[50, 85, 100]) -> None:
|
||||
"""设置技能CD"""
|
||||
for skill in self.skills:
|
||||
if min <= skill.learnLv <= max and (skill.type == 'active' or skill.damage) and skill.learnLv not in exclude:
|
||||
skill.cdReduce *= 1 - cd
|
||||
|
||||
def SetSkillCDRecover(self, min=1, max=100, cd=0, exclude=[50, 85, 100]) -> None:
|
||||
"""设置技能CD恢复"""
|
||||
for skill in self.skills:
|
||||
if min <= skill.learnLv <= max and (skill.type == 'active' or skill.damage) and skill.learnLv not in exclude:
|
||||
skill.cdRecover += cd
|
||||
|
||||
def SetSkillRation(self, min=1, max=100, ratio=1, type=-1) -> None:
|
||||
"""设置技能倍率
|
||||
0 修改技能面板 1 不修改技能面板
|
||||
type: -1 全部, 0 被动, 1 主动
|
||||
"""
|
||||
for skill in self.skills:
|
||||
if min <= skill.learnLv <= max and skill.damage and skill.type == 'active':
|
||||
if type == 0:
|
||||
skill.skillRation *= 1 + ratio
|
||||
else:
|
||||
skill.skillDamage *= 1 + ratio
|
||||
|
||||
# endregion
|
||||
|
||||
# region 技能查询
|
||||
|
||||
def GetSkillByName(self, name) -> 'Skill':
|
||||
"""通过技能名获取技能"""
|
||||
return self.skills_dict.get(name, None)
|
||||
|
||||
def GetSkillByID(self, id: str) -> 'Skill':
|
||||
"""通过技能ID获取技能"""
|
||||
skill = list(filter(lambda x: str(x.id) == id, self.skills))
|
||||
return skill[0] if len(skill) > 0 else None
|
||||
|
||||
def GetSkillByUUID(self, uuid: str) -> 'Skill':
|
||||
"""通过技能UUID获取技能"""
|
||||
skill = list(filter(lambda x: str(x.uuid) == uuid, self.skills))
|
||||
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)]
|
||||
|
||||
def GetWeaponType(self) -> tuple[str, str]:
|
||||
"""获取武器类型"""
|
||||
weapon = self.charEquipInfo['武器'].equInfo
|
||||
if weapon is None:
|
||||
return None, None
|
||||
else:
|
||||
return weapon.itemDetailType, weapon.categorize
|
||||
|
||||
# endregion
|
||||
@@ -0,0 +1,64 @@
|
||||
from core.basic.property import CharacterInfo
|
||||
from ..roleinfo import get_key_by_value
|
||||
from .base import CharacterBase
|
||||
|
||||
|
||||
class CalcBufferMixin(CharacterBase):
|
||||
"""辅助角色 Buff 技能计算相关方法"""
|
||||
|
||||
# region 辅助计算项
|
||||
|
||||
def calc_buffer_skills(self):
|
||||
skillInfos = []
|
||||
# 适用属性
|
||||
main = getattr(self, get_key_by_value(self.适用属性))
|
||||
# 增益量
|
||||
buffer_power = self.Buffer * self.BufferP
|
||||
# buff系数
|
||||
buff_ratio_new = (main / 2993 + 1) * (buffer_power / 4800 + 1) if buffer_power > 0 else 0
|
||||
buff_ratio_old = main / 2993 + 1
|
||||
# 觉醒系数
|
||||
awake_ratio_new = ((main + 7500) / 7500 + 1) * ((buffer_power + 68000) / 8500 + 1) if buffer_power > 0 else 0
|
||||
awake_ratio_old = main / 7500 + 1
|
||||
for i in self.skills:
|
||||
if i.lv > 0 and i.hasUP and i.up is not None and i.up > 0:
|
||||
self.SetStatus(四维=40)
|
||||
if i.buffer and i.lv > 0:
|
||||
info = i.skillInfo()
|
||||
value = info[0]
|
||||
if i.buffType == 'buff' or i.buffType == 'buffSub':
|
||||
value1 = (info[1][0] + info[1][2]) * info[1][1] * buff_ratio_old + info[1][0] * buff_ratio_new
|
||||
value2 = (info[2][0] + info[2][2]) * info[2][1] * buff_ratio_old + info[2][0] * buff_ratio_new
|
||||
elif i.buffType == 'awake' or i.buffType == 'awakeSub':
|
||||
value1 = (info[1][0] + info[1][2]) * info[1][1] * awake_ratio_old + info[1][0] * awake_ratio_new
|
||||
value2 = (info[2][0] + info[2][2]) * info[2][1] * awake_ratio_old + info[2][0] * awake_ratio_new
|
||||
else:
|
||||
value1 = (info[1][0] + info[1][2]) * info[1][1]
|
||||
value2 = (info[2][0] + info[2][2]) * info[2][1]
|
||||
value3 = info[3]
|
||||
value4 = info[4]
|
||||
if i.buffType == 'awake' and self.bindAwake == 50:
|
||||
pass
|
||||
else:
|
||||
skillInfos.append(
|
||||
{
|
||||
'name': i.name,
|
||||
'cd': value4,
|
||||
'icon': i.icon,
|
||||
'lv': i.lv,
|
||||
'buff': [value, value1, value2, value3],
|
||||
'type': i.type,
|
||||
}
|
||||
)
|
||||
return skillInfos
|
||||
|
||||
def get_buffer_info(self):
|
||||
attrs = [get_key_by_value(self.适用属性), 'Buffer', 'BufferP']
|
||||
info = []
|
||||
for attr in attrs:
|
||||
temp = getattr(CharacterInfo, attr)
|
||||
value = getattr(self, attr)
|
||||
info.append({'name': temp.name, 'value': temp.value(value)})
|
||||
return info
|
||||
|
||||
# endregion
|
||||
@@ -0,0 +1,103 @@
|
||||
from ..formula import 获取基础属性
|
||||
from core.basic.property import CharacterInfo
|
||||
from .base import CharacterBase
|
||||
|
||||
|
||||
class CalcCarryMixin(CharacterBase):
|
||||
"""输出角色技能伤害计算相关方法"""
|
||||
|
||||
# region 输出计算项
|
||||
|
||||
def calc_damage_ration(self, DSB: bool, BUFF: bool):
|
||||
"""计算属性系数"""
|
||||
attrs = []
|
||||
if self.输出类型 == '物理百分比':
|
||||
attrs.extend(['STR', 'AtkP', 'PAtkP'])
|
||||
if self.输出类型 == '魔法百分比':
|
||||
attrs.extend(['INT', 'AtkM', 'PAtkM'])
|
||||
if self.输出类型 == '物理固伤':
|
||||
attrs.extend(['STR', 'AtkI', 'PAtkI'])
|
||||
if self.输出类型 == '魔法固伤':
|
||||
attrs.extend(['INT', 'AtkI', 'PAtkI'])
|
||||
# 力智系数
|
||||
value0_1 = getattr(self, attrs[0])
|
||||
value0_2 = 获取基础属性(self.角色, self.职业)[0] if attrs[0] == 'STR' else 获取基础属性(self.角色, self.职业)[1]
|
||||
# 系统奶及奶系增幅
|
||||
value = value0_1 + ((value0_1 - value0_2) * 3.08 + 2886) * (1 if DSB else 0) + (170000 + 300000) * (1 if BUFF else 0)
|
||||
ratio_0: float = value / 250 + 1
|
||||
# 物理/魔法/独立攻击力
|
||||
ratio_1: float = getattr(self, attrs[1]) + 30000 * (1 if BUFF else 0)
|
||||
# 技能 物理/魔法/独立攻击力%
|
||||
ratio_2: float = getattr(self, attrs[2])
|
||||
# 属强系数
|
||||
ratio_3 = max(self.ElementDB.values()) * 0.0045 + 1.05
|
||||
# 暴击系数
|
||||
ratio_4 = 1.5
|
||||
# BUFF系数
|
||||
ratio_5 = self.buff
|
||||
# 技攻系数
|
||||
ratio_6 = self.SkillAttack * (self.jade_effect.SkillAttack + 1)
|
||||
# 攻击强化
|
||||
ratio_7 = 1 + self.Attack / 100 * (self.AttackP + self.jade_effect.AttackP)
|
||||
# 防御系数,暂定145沙袋防御
|
||||
monster_defense = 81417275817
|
||||
ratio_8 = 1 - monster_defense / (monster_defense + 200 * 100)
|
||||
# 杂项
|
||||
ratio_9 = 1.0 * self.ElementIncrease
|
||||
return (ratio_0, ratio_1, ratio_2, ratio_3, ratio_4, ratio_5, ratio_6, ratio_7, ratio_8, ratio_9)
|
||||
|
||||
def calc_carry_skills(self, DSB: bool, BUFF: bool):
|
||||
skillInfos = []
|
||||
for i in self.skills:
|
||||
if i.damage and i.lv > 0:
|
||||
for mode in i.mode:
|
||||
temp = i.skillInfo(mode)
|
||||
if temp[0] > 0:
|
||||
skillInfos.append(
|
||||
{
|
||||
'name': i.name,
|
||||
'icon': i.icon,
|
||||
'lv': i.lv,
|
||||
'data': temp[0],
|
||||
'ratio': temp[1],
|
||||
'cd': temp[2],
|
||||
'mode': mode,
|
||||
'learnLv': i.learnLv,
|
||||
'type': i.type,
|
||||
}
|
||||
)
|
||||
ratios = self.calc_damage_ration(DSB, BUFF)
|
||||
ratio_char_skill = ratios[0] * ratios[1] * ratios[2] * ratios[3] * ratios[4] * ratios[5] * ratios[6] * ratios[7] * ratios[8] * ratios[9] / 1000
|
||||
ratuio_equ_skill = ratios[0] * ratios[1] * ratios[3] * ratios[4] * ratios[6] * ratios[7] * ratios[8] * ratios[9] / 1000
|
||||
for i in skillInfos:
|
||||
i['damage'] = ratio_char_skill * i['data'] * i['ratio'] / 100
|
||||
for i in self.equ_effect:
|
||||
skillInfos.append({'name': i.name, 'icon': i.icon, 'lv': 0, 'data': i.data, 'ratio': 10.0, 'cd': i.cd, 'damage': ratuio_equ_skill * i.data * 10 * self.EquEffectRatio / 100, 'mode': ''})
|
||||
return skillInfos
|
||||
|
||||
def get_carry_info(self):
|
||||
attrs = []
|
||||
if self.输出类型 == '物理百分比':
|
||||
attrs.extend(['STR', 'AtkP'])
|
||||
if self.输出类型 == '魔法百分比':
|
||||
attrs.extend(['INT', 'AtkM'])
|
||||
if self.输出类型 == '物理固伤':
|
||||
attrs.extend(['STR', 'AtkI'])
|
||||
if self.输出类型 == '魔法固伤':
|
||||
attrs.extend(['INT', 'AtkI'])
|
||||
info = []
|
||||
attrs.extend(['Attack', 'AttackP', 'SkillAttack', 'EquEffectRatio', 'ElementDB'])
|
||||
for attr in attrs:
|
||||
temp = getattr(CharacterInfo, attr)
|
||||
if attr.startswith('Atk'):
|
||||
info.append({'name': temp.name, 'value': temp.value(getattr(self, attr) * getattr(self, f'P{attr}'))})
|
||||
else:
|
||||
value = getattr(self, attr)
|
||||
if attr == 'SkillAttack':
|
||||
value *= self.jade_effect.SkillAttack + 1
|
||||
if attr == 'AttackP':
|
||||
value += self.jade_effect.AttackP
|
||||
info.append({'name': temp.name, 'value': temp.value(value)})
|
||||
return info
|
||||
|
||||
# endregion
|
||||
@@ -0,0 +1,314 @@
|
||||
import sys
|
||||
from uuid import uuid1
|
||||
|
||||
from core.basic.equipment import get_equipment
|
||||
from ..formula import 增幅计算, 强化技攻, 武器强化计算, 精通计算, 耳环计算, 左右计算, 锻造计算
|
||||
from ..roleinfo import CharacterEquipInfo, CharacterOathInfo, get_key_by_value
|
||||
from .base import CharacterBase
|
||||
|
||||
|
||||
class CalcEquipMixin(CharacterBase):
|
||||
"""装备计算、角色初始化相关方法"""
|
||||
|
||||
# region 打造信息导入
|
||||
|
||||
def SetDetail(self, info: dict[str, dict]) -> None:
|
||||
"""打造信息导入"""
|
||||
self.charEquipInfo = {}
|
||||
self.charOathInfo = []
|
||||
self.bindAwake = info.get('bindAwake', 50)
|
||||
for key in info['equips']:
|
||||
self.charEquipInfo[key] = CharacterEquipInfo(info['equips'][key], self.equVersion, key)
|
||||
for key in info['oaths']:
|
||||
# 导入誓约打造信息、誓约信息
|
||||
self.charOathInfo.append(CharacterOathInfo(info['oaths'][key], self.equVersion, key))
|
||||
|
||||
def calc_init(self, setInfo: dict[str, dict]):
|
||||
self.equ_options = setInfo.get('options', {})
|
||||
self.setInfo = setInfo
|
||||
self.SetDetail(setInfo)
|
||||
self.SetSkills(setInfo.get('skills', {}))
|
||||
|
||||
def SetSkills(self, skills: dict[str, dict]):
|
||||
"""设置技能等级"""
|
||||
for key in skills:
|
||||
skill = self.GetSkillByID(key)
|
||||
if skill is not None:
|
||||
if skill.hasUP:
|
||||
skill.up = skills[key].get('up', 0)
|
||||
if skill.hasVP:
|
||||
skill.vp = skills[key].get('vp', 0)
|
||||
skill.lv += skills[key].get('lv', 0)
|
||||
|
||||
def load_skills(self) -> None:
|
||||
"""加载技能"""
|
||||
module = sys.modules[self.moduleName]
|
||||
for name in dir(module):
|
||||
memberClass = getattr(module, name)
|
||||
if isinstance(memberClass, type) and memberClass.__name__.startswith('Skill'):
|
||||
skill = memberClass(char=self)
|
||||
self.skills_dict[skill.name] = skill
|
||||
self.skills.append(skill)
|
||||
|
||||
# endregion
|
||||
|
||||
# region 套装 / 装备 / 时装 / 基础属性 / 辟邪玉 / 杂项
|
||||
|
||||
def calc_suits(self):
|
||||
"""套装效果统计"""
|
||||
suitInfo = {}
|
||||
oathSuitInfo = {}
|
||||
equs = get_equipment(self.equVersion)
|
||||
for item in filter(lambda x: x.equInfo is not None, self.charEquipInfo.values()):
|
||||
partEqu = item.equInfo
|
||||
# partFusion = item.fusionInfo
|
||||
if partEqu is not None:
|
||||
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
|
||||
for item in self.charOathInfo:
|
||||
partOath = item.oathInfo
|
||||
if partOath is not None:
|
||||
for suit in partOath.suit:
|
||||
if oathSuitInfo.get(suit, None) is None:
|
||||
oathSuitInfo[suit] = {'point': 0, 'count': 0}
|
||||
if partOath.Point == 0:
|
||||
oathSuitInfo[suit]['count'] += 1
|
||||
else:
|
||||
oathSuitInfo[suit]['point'] += partOath.Point
|
||||
max_point_suit = max((suit for suit in suitInfo if suitInfo[suit]['point'] > 0), key=lambda suit: suitInfo[suit]['point'], default=None)
|
||||
max_point_oath_suit = max((suit for suit in oathSuitInfo if oathSuitInfo[suit]['point'] > 0), key=lambda suit: oathSuitInfo[suit]['point'], default=None)
|
||||
zero_point_suits = [suit for suit in suitInfo if suitInfo[suit]['point'] == 0]
|
||||
# 套装没有到太初的时候,优先把誓约套装的点数加到装备套装上,以达到更高的套装等级
|
||||
if 0 < suitInfo[max_point_suit]['point'] < 2550:
|
||||
suitInfo[max_point_suit]['point'] += min(2550 - suitInfo[max_point_suit]['point'], oathSuitInfo[max_point_oath_suit]['point'])
|
||||
oathSuitInfo[max_point_oath_suit]['point'] -= min(2550 - suitInfo[max_point_suit]['point'], oathSuitInfo[max_point_oath_suit]['point'])
|
||||
pass
|
||||
suits = zero_point_suits + ([max_point_suit] if max_point_suit is not None else [])
|
||||
suitList = []
|
||||
oathSuitList = []
|
||||
res = []
|
||||
for suit in suits:
|
||||
if suitInfo[suit]['point'] == 0:
|
||||
suitList += equs.get_suit_info(suit, 0, suitInfo[suit]['count'])
|
||||
else:
|
||||
suitList += equs.get_suit_info(suit, suitInfo[suit]['point'], 0)
|
||||
if len(suitList) == 0:
|
||||
continue
|
||||
temp = suitList[-1]
|
||||
res.append(
|
||||
{
|
||||
'id': temp.id,
|
||||
'name': temp.name,
|
||||
'rarity': temp.rarity,
|
||||
'point': suitInfo[suit]['point'],
|
||||
'count': suitInfo[suit]['count'],
|
||||
'level': temp.level,
|
||||
'imageUrl': temp.imageUrl,
|
||||
'value': temp.value,
|
||||
}
|
||||
)
|
||||
|
||||
for suit in oathSuitInfo:
|
||||
if oathSuitInfo[suit]['point'] == 0:
|
||||
oathSuitList += equs.get_oath_suit_info(suit, 0, oathSuitInfo[suit]['count'])
|
||||
else:
|
||||
oathSuitList += equs.get_oath_suit_info(suit, oathSuitInfo[suit]['point'], 0)
|
||||
if len(oathSuitList) == 0:
|
||||
continue
|
||||
print(oathSuitList[0].__dict__)
|
||||
suits_effect = [i.id for i in suitList]
|
||||
for i in suits_effect:
|
||||
func = equs.funs.execture(f'suit_{i}')
|
||||
suit = next((x for x in equs.suits if str(x.id) == str(i)), None)
|
||||
if func is not None:
|
||||
func(self)
|
||||
if suit is not None:
|
||||
filtered_dict = {k: v for k, v in suit.__dict__.items() if k[0].isupper()}
|
||||
self.SetStatus(**filtered_dict)
|
||||
self.max_point = max([i['point'] for i in res], default=0)
|
||||
if self.max_point >= 2550:
|
||||
skillAttack = (self.max_point - 2550) // 70 * 0.01
|
||||
buffer = (self.max_point - 2550) // 70 * 100
|
||||
self.SetStatus(SkillAttack=skillAttack, Buffer=buffer)
|
||||
return res
|
||||
|
||||
def calc_equs(self):
|
||||
"""计算装备基础效果、附魔"""
|
||||
effects = get_equipment(self.equVersion).funs
|
||||
# for detail in [(item.equInfo, item.fusionInfo, item.enchant, item.emblem_0, item.emblem_1) for item in filter(lambda x: x.equInfo is not None, self.charEquipInfo.values())]:
|
||||
for detail in [(item.equInfo, item.enchant) for item in filter(lambda x: x.equInfo is not None, self.charEquipInfo.values())]:
|
||||
equ = detail[0]
|
||||
if equ is None or equ.itemType == '副武器':
|
||||
continue
|
||||
enchat = detail[1]
|
||||
fun = effects.execture(f'equ_{equ.id}')
|
||||
if fun is None:
|
||||
continue
|
||||
filtered_dict = {k: v for k, v in equ.__dict__.items() if k[0].isupper()}
|
||||
self.SetStatus(**filtered_dict)
|
||||
fun(self)
|
||||
fun = effects.execture(f'enchant_{enchat}')
|
||||
if fun is not None:
|
||||
fun(self)
|
||||
# emblem_0 = detail[3]
|
||||
# emblem_1 = detail[4]
|
||||
# if str(emblem_0).isdigit():
|
||||
# fun = effects.execture(f'emblem_{emblem_0}')
|
||||
# if fun is not None:
|
||||
# fun(self)
|
||||
# else:
|
||||
# skill = self.GetSkillByName(emblem_0)
|
||||
# if skill is not None:
|
||||
# skill.lv += 1
|
||||
# self.SetStatus(四维=8)
|
||||
# fun = effects.execture(f'emblem_{emblem_1}')
|
||||
# if fun is not None:
|
||||
# fun(self)
|
||||
# if fusion is None:
|
||||
# continue
|
||||
# fun = effects.execture(f'stone_{fusion.id}')
|
||||
# filtered_dict = {k: v for k, v in fusion.__dict__.items() if k[0].isupper()}
|
||||
# self.SetStatus(**filtered_dict)
|
||||
# if fun is not None:
|
||||
# fun(self)
|
||||
|
||||
def calc_oaths(self):
|
||||
pass
|
||||
|
||||
def calc_avatar(self, avatar: dict):
|
||||
"""计算时装效果"""
|
||||
equ = get_equipment(self.equVersion)
|
||||
dress = {key: value for key, value in avatar.items() if key in ['头部', '帽子', '脸部', '胸部', '上衣', '腰带', '下装', '鞋']}
|
||||
equ.funs.calc_dress_effect(dress, self)
|
||||
avatarElse = {key: value for key, value in avatar.items() if key not in ['头部', '帽子', '脸部', '胸部', '上衣', '腰带', '下装', '鞋']}
|
||||
for key in avatarElse:
|
||||
value = avatarElse[key].get('enchant', None)
|
||||
emblem_0 = avatarElse[key].get('emblem_0', None)
|
||||
emblem_1 = avatarElse[key].get('emblem_1', None)
|
||||
if value is not None:
|
||||
fun = equ.funs.execture(f'enchant_{value}')
|
||||
if fun is not None:
|
||||
fun(self)
|
||||
for i in [emblem_0, emblem_1]:
|
||||
if i is None:
|
||||
continue
|
||||
fun = equ.funs.execture(f'emblem_{i}')
|
||||
if fun is not None:
|
||||
fun(self)
|
||||
|
||||
def calc_weapon(self, cur: 'CharacterEquipInfo'):
|
||||
"""武器强化、锻造计算"""
|
||||
value = 锻造计算(115, '史诗', cur.refine)
|
||||
self.SetStatus(AtkI=value)
|
||||
if '传世武器' in 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)
|
||||
|
||||
def calc_basic(self):
|
||||
"""计算基础属性:防具精通、增幅、强化等"""
|
||||
for part in ['上衣', '头肩', '下装', '腰带', '鞋']:
|
||||
cur = self.charEquipInfo[part]
|
||||
if cur.equInfo is None:
|
||||
continue
|
||||
equ = cur.equInfo
|
||||
reinforce = self.charEquipInfo[part].reinforce
|
||||
if equ is None:
|
||||
continue
|
||||
for key in self.防具精通属性:
|
||||
value = 精通计算(115, equ.rarity, reinforce, equ.itemDetailType, self.防具类型, self.buffer, key)
|
||||
key = get_key_by_value(key)
|
||||
setattr(self, key, getattr(self, key) + value)
|
||||
for part in self.charEquipInfo.keys():
|
||||
cur = self.charEquipInfo[part]
|
||||
if cur.equInfo is None:
|
||||
continue
|
||||
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 '武器' in part:
|
||||
self.calc_weapon(cur)
|
||||
if part == '耳环':
|
||||
value = 耳环计算(115, '史诗', cur.reinforce)
|
||||
self.SetStatus(AtkM=value, AtkP=value, AtkI=value)
|
||||
if part in ['辅助装备', '魔法石']:
|
||||
value = 左右计算(115, '史诗', cur.reinforce)
|
||||
self.SetStatus(STR=value, INT=value, Spirit=value, Vitality=value)
|
||||
|
||||
def calc_jade(self, jades):
|
||||
"""计算辟邪玉效果"""
|
||||
funs = get_equipment(self.equVersion).funs
|
||||
for key in jades:
|
||||
jade = jades[key]
|
||||
fun = funs.execture(f'jade_{jade.get("id", 0)}')
|
||||
if fun is not None:
|
||||
fun(self, jade.get('value', 0))
|
||||
|
||||
def calc_sundry(self, sundry: dict):
|
||||
"""计算杂项效果"""
|
||||
funs = get_equipment(self.equVersion).funs
|
||||
funs.execture('sundry_0')(
|
||||
self,
|
||||
sundry.get('medal_rarity', 0),
|
||||
sundry.get('medal_reinforce', 0),
|
||||
[sundry.get('medal_gem_0', 0), sundry.get('medal_gem_1', 0), sundry.get('medal_gem_2', 0), sundry.get('medal_gem_3', 0)],
|
||||
)
|
||||
funs.execture('sundry_6')(self, sundry.get('adventure', 1))
|
||||
funs.execture('sundry_5')(self, sundry.get('fog', 1))
|
||||
funs.execture('sundry_7')(self, sundry.get('marriage_house', 0), sundry.get('marriage_ring', 0))
|
||||
funs.execture('sundry_9')(self, sundry.get('contract', 0))
|
||||
funs.execture('sundry_10')(
|
||||
self,
|
||||
sundry.get('collection_type', 0),
|
||||
sundry.get('collection_num_0', 0),
|
||||
sundry.get('collection_num_1', 0),
|
||||
)
|
||||
funs.execture('sundry_13')(self, sundry.get('costume_card', 0))
|
||||
|
||||
# endregion
|
||||
|
||||
# region 主计算入口
|
||||
|
||||
def calc(self, setInfo: dict[str, dict]):
|
||||
self.calc_init(setInfo)
|
||||
self.SetBaseStatus()
|
||||
self.calc_jade(setInfo.get('jades', []))
|
||||
self.calc_avatar(setInfo.get('avatar', {}))
|
||||
self.calc_basic()
|
||||
self.calc_sundry(setInfo.get('sundry', {}))
|
||||
suit = self.calc_suits()
|
||||
self.calc_equs()
|
||||
self.calc_oaths()
|
||||
skillInfos = []
|
||||
if self.buffer:
|
||||
skillInfos = self.calc_buffer_skills()
|
||||
info = self.get_buffer_info()
|
||||
else:
|
||||
if len(self.输出类型选项) > 1:
|
||||
temp = self.输出类型选项[0]
|
||||
if '固伤' in temp:
|
||||
if self.INT > self.STR:
|
||||
self.输出类型 = '魔法固伤'
|
||||
else:
|
||||
self.输出类型 = '物理固伤'
|
||||
else:
|
||||
if self.INT > self.STR and self.AtkM > self.AtkP:
|
||||
self.输出类型 = '魔法百分比'
|
||||
else:
|
||||
self.输出类型 = '物理百分比'
|
||||
skillInfos = self.calc_carry_skills(setInfo.get('DSB', False), setInfo.get('BUFF', False))
|
||||
info = self.get_carry_info()
|
||||
return {'uuid': uuid1().hex, 'skills': skillInfos, 'info': info, 'suits': suit, 'buffer': self.buffer}
|
||||
|
||||
# endregion
|
||||
@@ -0,0 +1,120 @@
|
||||
from core.basic.equipment import get_equipment
|
||||
from core.basic.property import CharacterInfo
|
||||
from .base import CharacterBase
|
||||
|
||||
|
||||
class CharacterInfoMixin(CharacterBase):
|
||||
"""角色信息查询相关方法(用于前端展示)"""
|
||||
|
||||
def getInfo(self):
|
||||
"""返回到前端信息"""
|
||||
info = {}
|
||||
info['role'] = self.role
|
||||
info['alter'] = self.name
|
||||
info['equVersion'] = self.equVersion
|
||||
info['name'] = self.nameCN
|
||||
info['weapons'] = self.武器选项
|
||||
info['subweapons'] = self.副武器选项
|
||||
info['buffer'] = self.buffer
|
||||
if self.buffer:
|
||||
info['properties'] = self.防具精通属性
|
||||
info['properties'] = self.输出类型选项
|
||||
skillInfo = []
|
||||
skill_clothes = []
|
||||
platinum = []
|
||||
for skill in self.skills:
|
||||
if 15 <= skill.learnLv <= 70 and skill.learnLv not in [48, 50]:
|
||||
platinum.append(skill.name)
|
||||
if skill.learnLv <= 95:
|
||||
skill_clothes.append(skill.name)
|
||||
skillInfo.append(
|
||||
{
|
||||
'id': skill.id,
|
||||
'name': skill.name,
|
||||
'icon': skill.icon,
|
||||
'type': skill.type,
|
||||
'learnLv': skill.learnLv,
|
||||
'masterLv': skill.masterLv,
|
||||
'maxLearnLv': skill.calculate_lv(),
|
||||
'maxLv': skill.maxLv,
|
||||
'position': skill.position,
|
||||
'line': skill.line,
|
||||
'bind': skill.bind,
|
||||
'hasVP': skill.hasVP,
|
||||
'hasUP': skill.hasUP,
|
||||
'upType': skill.upType,
|
||||
'uuid': skill.uuid,
|
||||
'vps': [{'name': i['name'], 'desc': i['desc']} for i in skill.vps],
|
||||
}
|
||||
)
|
||||
info['skills'] = skillInfo
|
||||
equInfos = get_equipment(self.equVersion)
|
||||
equs = []
|
||||
suits = []
|
||||
stones = []
|
||||
for i in equInfos.equs:
|
||||
if i.itemType == '武器' and i.itemDetailType not in self.武器选项:
|
||||
continue
|
||||
equs.append(i.__dict__)
|
||||
for i in equInfos.suits:
|
||||
suits.append(i.__dict__)
|
||||
for i in equInfos.stones:
|
||||
stones.append(i.__dict__)
|
||||
info['equips'] = equs
|
||||
info['suits'] = suits
|
||||
info['stones'] = stones
|
||||
key = '辅助' if self.buffer else '输出'
|
||||
info['enchants'] = list(filter(lambda x: key in x['categorize'], equInfos.enchants))
|
||||
info['emblems'] = [i for i in equInfos.emblems]
|
||||
info['avatar'] = equInfos.funs.get_dress_list(skill_clothes)
|
||||
info['jades'] = equInfos.jades
|
||||
info['options'] = equInfos.funs.options
|
||||
info['sundry'] = equInfos.funs.sundryList
|
||||
for skill in platinum:
|
||||
info['emblems'].append(
|
||||
{
|
||||
'id': skill,
|
||||
'fame': 232,
|
||||
'position': ['辅助装备', '魔法石'],
|
||||
'detail': skill + ' Lv+1' + ' 四维 + 8',
|
||||
'categorize': ['技能'],
|
||||
'rarity': '白金',
|
||||
}
|
||||
)
|
||||
return info
|
||||
|
||||
def getBasicInos(self):
|
||||
res = []
|
||||
attrs = []
|
||||
if self.输出类型.includes('物理'):
|
||||
attrs = ['STR', 'PSTR', 'AtkP', 'PAtkP', 'CriticalPP', 'CriticalP']
|
||||
if self.输出类型.includes('魔法'):
|
||||
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
|
||||
@@ -0,0 +1,12 @@
|
||||
class Jade:
|
||||
ElementIncrease: float
|
||||
"""属性增幅"""
|
||||
AttackP: float
|
||||
"""攻击强化%"""
|
||||
SkillAttack: float
|
||||
"""技能攻击力%"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.ElementIncrease = 0.0
|
||||
self.AttackP = 0.0
|
||||
self.SkillAttack = 0.0
|
||||
@@ -1,3 +1,15 @@
|
||||
# ⚠️ 此文件已被 character/ 包目录取代。
|
||||
# Python 会优先加载 character/__init__.py,此文件不会被 import 执行。
|
||||
#
|
||||
# 模块拆分结构(位于 core/basic/character/):
|
||||
# jade.py — Jade 辟邪玉类
|
||||
# base.py — CharacterBase(属性 / __init__ / 基础状态方法 / 技能操作)
|
||||
# calc_equip.py — CalcEquipMixin(套装/装备/时装/强化/辟邪玉/杂项 + calc 主入口)
|
||||
# calc_carry.py — CalcCarryMixin(输出伤害计算)
|
||||
# calc_buffer.py — CalcBufferMixin(辅助 Buff 技能计算)
|
||||
# info.py — CharacterInfoMixin(前端信息查询)
|
||||
# __init__.py — 组装 Character 类 + createCharacter 工厂函数
|
||||
|
||||
from functools import cache
|
||||
import importlib
|
||||
import sys
|
||||
@@ -89,15 +89,16 @@ class Equipments:
|
||||
self.emblems = []
|
||||
self.suits: list[Suit] = []
|
||||
self.suit_dict: dict[str, Suit] = {}
|
||||
self.oath_suits: list[Suit] = []
|
||||
self.oath_suits: list[OathSuit] = []
|
||||
self.oath_suit_dict: dict[str, OathSuit] = {}
|
||||
self.init_equs()
|
||||
self.init_suits()
|
||||
self.init_enchants()
|
||||
self.init_stones()
|
||||
self.init_emblem()
|
||||
self.init_jades()
|
||||
# self.init_oaths()
|
||||
# self.init_oath_suits()
|
||||
self.init_oaths()
|
||||
self.init_oath_suits()
|
||||
self.engine.dispose()
|
||||
|
||||
def init_equs(self):
|
||||
@@ -235,7 +236,9 @@ class Equipments:
|
||||
buffers = parse_to_number_list(suit['Buffer'], [0])
|
||||
suit['Buffer'] = 0 if i - 1 >= len(buffers) else buffers[i - 1]
|
||||
suit['skills'] = [OathSuitSkill(**{k: v for k, v in skill.__dict__.items() if not k.startswith('_')}) for skill in skills]
|
||||
self.oath_suits.append(suit)
|
||||
oath_suit = OathSuit(**suit)
|
||||
self.oath_suits.append(oath_suit)
|
||||
self.oath_suit_dict.setdefault(str(suit['suitId']), []).append(oath_suit)
|
||||
pass
|
||||
pass
|
||||
|
||||
@@ -263,7 +266,7 @@ class Equipments:
|
||||
result[suit.count] = suit
|
||||
return list(result.values())
|
||||
|
||||
def get_oath_suit_info(self, suitId: str | int, point: int = 0, count: int = 0) -> list[Suit]:
|
||||
def get_oath_suit_info(self, suitId: str | int, point: int = 0, count: int = 0) -> list['OathSuit']:
|
||||
"""根据套装点数返回对应适用的誓约套装属性\n
|
||||
新套装只需要传入suitID和point即可,count默认为0\n
|
||||
老套装需要传入suitID和count即可,point默认为0
|
||||
@@ -271,8 +274,8 @@ class Equipments:
|
||||
if suitId not in self.oath_suit_dict:
|
||||
return []
|
||||
# 先筛选出点数小于等于point和数量小于等于count的套装
|
||||
suits: list[Suit] = [suit for suit in self.oath_suit_dict[str(suitId)] if suit.point <= point and suit.count <= count]
|
||||
result: dict[int, Suit] = {}
|
||||
suits: list[OathSuit] = [suit for suit in self.oath_suit_dict[str(suitId)] if suit.point <= point and suit.count <= count]
|
||||
result: dict[int, OathSuit] = {}
|
||||
# 取每种count套装中点数最高的
|
||||
for suit in suits:
|
||||
if suit.count not in result or suit.point > result[suit.count].point:
|
||||
|
||||
@@ -13,32 +13,32 @@ class CharacterEquipInfo:
|
||||
"""强化类型"""
|
||||
enchant: str
|
||||
"""附魔"""
|
||||
emblem_0: str
|
||||
"""徽章1"""
|
||||
emblem_1: str
|
||||
"""徽章2"""
|
||||
fusion: int | None
|
||||
"""贴膜ID"""
|
||||
# emblem_0: str
|
||||
# """徽章1"""
|
||||
# emblem_1: str
|
||||
# """徽章2"""
|
||||
# fusion: int | None
|
||||
# """贴膜ID"""
|
||||
refine: int | None
|
||||
"""锻造等级"""
|
||||
weaponFusion: int | None
|
||||
"""武器融合详情"""
|
||||
# weaponFusion: int | None
|
||||
# """武器融合详情"""
|
||||
adaptation: int
|
||||
"""调适等级"""
|
||||
equInfo: Union['Equ', None]
|
||||
"""装备信息"""
|
||||
fusionInfo: Union['Equ', None]
|
||||
"""贴膜信息"""
|
||||
# fusionInfo: Union['Equ', None]
|
||||
# """贴膜信息"""
|
||||
precision: float
|
||||
"""秘宝精度"""
|
||||
|
||||
def __init__(self, info={}, equVerison=0, part='') -> None:
|
||||
info['fusion'] = info.get('fusion', None)
|
||||
# info['fusion'] = info.get('fusion', None)
|
||||
info['precision'] = info.get('precision', 0)
|
||||
info['weaponFusion'] = info.get('weaponFusion', None)
|
||||
# info['weaponFusion'] = info.get('weaponFusion', None)
|
||||
self.__dict__.update(info)
|
||||
equ = get_equipment(equVerison).equ_dict.get(self.id, None)
|
||||
fusion = get_equipment(equVerison).stone_dict.get(self.fusion, None)
|
||||
# fusion = get_equipment(equVerison).stone_dict.get(self.fusion, None)
|
||||
if equ is not None and (equ.itemType == part or equ.itemDetailType == part or (equ.itemType == '武器' and part == '副武器')):
|
||||
self.equInfo = equ.adapt(self.adaptation)
|
||||
self.adaptation = min(self.adaptation, self.equInfo.max_adaptation)
|
||||
@@ -46,10 +46,10 @@ class CharacterEquipInfo:
|
||||
self.equInfo.itemType = '副武器'
|
||||
else:
|
||||
self.equInfo = None
|
||||
if fusion is not None and (fusion.itemType == part or fusion.itemDetailType == part):
|
||||
self.fusionInfo = fusion.adapt(self.adaptation)
|
||||
else:
|
||||
self.fusionInfo = None
|
||||
# if fusion is not None and (fusion.itemType == part or fusion.itemDetailType == part):
|
||||
# self.fusionInfo = fusion.adapt(self.adaptation)
|
||||
# else:
|
||||
# self.fusionInfo = None
|
||||
|
||||
|
||||
class CharacterOathInfo:
|
||||
|
||||
Binary file not shown.
+24
-3
@@ -2,8 +2,29 @@ from core.basic.character import createCharacter
|
||||
|
||||
char = createCharacter('GF.gunner_female.spitfire_female')
|
||||
|
||||
char.calc_init({'oaths': {'0': {'id': '2010201', 'adaptation': 3}, '11': {'id': '2050200', 'adaptation': 0}}, 'equips': {}})
|
||||
char.calc_init(
|
||||
{
|
||||
'oaths': {'0': {'id': '2010201', 'adaptation': 3}, '1': {'id': '2010201', 'adaptation': 3}, '2': {'id': '2010201', 'adaptation': 3}, '3': {'id': '2010201', 'adaptation': 3}, '4': {'id': '2010201', 'adaptation': 3}, '11': {'id': '2010200', 'adaptation': 0}},
|
||||
'equips': {
|
||||
'武器': {'id': '88', 'reinforce': 14, 'reinforceType': 1, 'enchant': 512, 'emblem_0': 0, 'emblem_1': 0, 'fusion': 0, 'refine': 8, 'adaptation': 3, 'precision': 100},
|
||||
'称号': {'id': '3017', 'reinforce': 0, 'reinforceType': 0, 'enchant': 1201, 'emblem_0': 0, 'emblem_1': 0, 'fusion': 0, 'refine': 0, 'adaptation': 3, 'precision': 100},
|
||||
'上衣': {'id': '999', 'reinforce': 13, 'reinforceType': 1, 'enchant': 105, 'emblem_0': 1, 'emblem_1': 1, 'fusion': '26', 'refine': 0, 'adaptation': 3, 'precision': 100},
|
||||
'头肩': {'id': '1001', 'reinforce': 14, 'reinforceType': 1, 'enchant': 5, 'emblem_0': 0, 'emblem_1': 0, 'fusion': '28', 'refine': 0, 'adaptation': 3, 'precision': 100},
|
||||
'下装': {'id': '1000', 'reinforce': 14, 'reinforceType': 1, 'enchant': 202, 'emblem_0': 1, 'emblem_1': 1, 'fusion': '27', 'refine': 0, 'adaptation': 3, 'precision': 100},
|
||||
'鞋': {'id': '1003', 'reinforce': 14, 'reinforceType': 1, 'enchant': 309, 'emblem_0': 11, 'emblem_1': 11, 'fusion': '30', 'refine': 0, 'adaptation': 3, 'precision': 100},
|
||||
'腰带': {'id': '1002', 'reinforce': 14, 'reinforceType': 1, 'enchant': 309, 'emblem_0': 4, 'emblem_1': 4, 'fusion': '29', 'refine': 0, 'adaptation': 3, 'precision': 100},
|
||||
'项链': {'id': '477', 'reinforce': 13, 'reinforceType': 1, 'enchant': 609, 'emblem_0': 0, 'emblem_1': 0, 'fusion': '180', 'refine': 0, 'adaptation': 3, 'precision': 100},
|
||||
'手镯': {'id': '483', 'reinforce': 14, 'reinforceType': 1, 'enchant': 609, 'emblem_0': 11, 'emblem_1': 11, 'fusion': '302', 'refine': 0, 'adaptation': 3, 'precision': 100},
|
||||
'戒指': {'id': '489', 'reinforce': 14, 'reinforceType': 1, 'enchant': 609, 'emblem_0': 4, 'emblem_1': 4, 'fusion': '304', 'refine': 0, 'adaptation': 3, 'precision': 100},
|
||||
'辅助装备': {'id': '492', 'reinforce': 14, 'reinforceType': 1, 'enchant': 905, 'emblem_0': '兵器研究', 'emblem_1': 0, 'fusion': '182', 'refine': 3, 'adaptation': 3, 'precision': 100},
|
||||
'魔法石': {'id': '495', 'reinforce': 14, 'reinforceType': 1, 'enchant': 1003, 'emblem_0': '兵器研究', 'emblem_1': 0, 'fusion': '184', 'refine': 3, 'adaptation': 3, 'precision': 100},
|
||||
'耳环': {'id': '498', 'reinforce': 14, 'reinforceType': 1, 'enchant': 1104, 'emblem_0': 0, 'emblem_1': 0, 'fusion': '186', 'refine': 0, 'adaptation': 3, 'precision': 100},
|
||||
'宠物': {'id': '4022', 'reinforce': 0, 'reinforceType': 0, 'enchant': 1304, 'emblem_0': 0, 'emblem_1': 0, 'fusion': 0, 'refine': 0, 'adaptation': 3, 'precision': 100},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
char.calc_suits()
|
||||
|
||||
for oath in char.charOathInfo:
|
||||
print(oath.id, oath.adaptation, oath.oathInfo.position, oath.oathInfo.max_adaptation, oath.oathInfo.Point)
|
||||
# for oath in char.charOathInfo:
|
||||
# print(oath.id, oath.adaptation, oath.oathInfo.position, oath.oathInfo.max_adaptation, oath.oathInfo.Point)
|
||||
|
||||
Reference in New Issue
Block a user