init
This commit is contained in:
@@ -0,0 +1,579 @@
|
||||
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
|
||||
# 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]
|
||||
"""属性攻击"""
|
||||
|
||||
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"]
|
||||
"""装备打造信息"""
|
||||
|
||||
# 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.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
|
||||
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,
|
||||
火属性攻击=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',
|
||||
}
|
||||
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.AtkP += 物攻 + kwargs.get('AtkP', 0)
|
||||
self.AtkM += 魔攻 + kwargs.get('AtkM', 0)
|
||||
self.AtkI += 独立 + kwargs.get('AtkI', 0)
|
||||
self.PAtkP *= kwargs.get('PAtkP', 0)
|
||||
self.PAtkM *= kwargs.get('PAtkM', 0)
|
||||
self.PAtkI *= kwargs.get('PAtkI', 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, max, lv, 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=99, cd=0) -> None:
|
||||
"""
|
||||
设置技能CD
|
||||
type: -1 全部, 0 被动, 1 主动
|
||||
"""
|
||||
for skill in self.skills:
|
||||
if min <= skill.requiredLv <= max and skill.damage:
|
||||
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
|
||||
|
||||
@cache
|
||||
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)
|
||||
|
||||
# def calc(self):
|
||||
# """计算角色属性"""
|
||||
# func = []
|
||||
# for i in self.charEquipInfo:
|
||||
# # 计算装备
|
||||
# temp = self.equs.get_func_by_id(self.charEquipInfo[i].id)
|
||||
# func.append(temp)
|
||||
# temp(self)
|
||||
# pass
|
||||
|
||||
def getInfo(self):
|
||||
"""返回到前端信息"""
|
||||
info = {}
|
||||
info['alter'] = self.实际名称
|
||||
info['equVersion'] = self.equVersion
|
||||
info['name'] = self.名称
|
||||
info['weaopns'] = self.武器选项
|
||||
skillInfo = []
|
||||
for skill in self.skills:
|
||||
skillInfo.append(
|
||||
{
|
||||
'name': skill.name,
|
||||
'icon': skill.icon,
|
||||
'type': skill.type,
|
||||
# 'SPCost': skill.SPCost,
|
||||
"learnLv": skill.learnLv,
|
||||
"masterLv": skill.masterLv,
|
||||
"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,
|
||||
'positon':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 = []
|
||||
# 装备过滤
|
||||
# for i in self.equs.info:
|
||||
# if (i.typeSon1Id == '武器' and i.typeSon2Id not in self.武器选项) or (i.name.startswith('精 · ') and self.异界 not in i.name):
|
||||
# pass
|
||||
# else:
|
||||
# equs.append(
|
||||
# {
|
||||
# 'id': i.id,
|
||||
# 'name': i.name,
|
||||
# 'icon': i.icon,
|
||||
# 'typeSon1Id': i.typeSon1Id,
|
||||
# 'typeSon2Id': i.typeSon2Id,
|
||||
# 'typeSon3Id': i.typeSon3Id,
|
||||
# 'rarity': i.rarity,
|
||||
# 'lv': i.lv,
|
||||
# 'suit': i.suit,
|
||||
# }
|
||||
# )
|
||||
# 附魔、徽章
|
||||
# for i in self.equs.prop:
|
||||
# if i.typeSon1Id == '附魔':
|
||||
# enchats.append(
|
||||
# {
|
||||
# 'id': i.id,
|
||||
# 'name': i.name,
|
||||
# 'icon': i.icon,
|
||||
# 'typeSon1Id': i.typeSon1Id,
|
||||
# 'typeSon2Id': i.typeSon2Id,
|
||||
# 'typeSon3Id': i.typeSon3Id,
|
||||
# 'rarity': i.rarity,
|
||||
# 'lv': i.lv,
|
||||
# 'desc': i.desc,
|
||||
# }
|
||||
# )
|
||||
# if i.typeSon1Id == '徽章':
|
||||
# emblems.append(
|
||||
# {
|
||||
# 'id': i.id,
|
||||
# 'name': i.name,
|
||||
# 'icon': i.icon,
|
||||
# 'typeSon1Id': i.typeSon1Id,
|
||||
# 'typeSon2Id': i.typeSon2Id,
|
||||
# 'typeSon3Id': i.typeSon3Id,
|
||||
# 'rarity': i.rarity,
|
||||
# 'lv': i.lv,
|
||||
# 'desc': i.desc,
|
||||
# }
|
||||
# )
|
||||
# info['enchats'] = enchats
|
||||
# info['emblems'] = emblems
|
||||
# info['seal'] = [i.__dict__ for i in self.equs.seal]
|
||||
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(self, setInfo: dict[str, dict]):
|
||||
funcs = []
|
||||
suits = []
|
||||
self.calc_init(setInfo)
|
||||
# self.SetDetail(setInfo)
|
||||
# 角色基础属性
|
||||
self.SetBaseStatus()
|
||||
return
|
||||
# 技能影响角色的属性,如属强、抗性等
|
||||
for skill in self.skills:
|
||||
skill.effect(self)
|
||||
for i in self.charEquipInfo:
|
||||
# region 装备效果
|
||||
fun = self.equs.get_func_by_id(f'equ_{self.charEquipInfo[i].id}')
|
||||
equ = self.equs.get_equ_by_id(self.charEquipInfo[i].id)
|
||||
if equ is None:
|
||||
continue
|
||||
self.SetStatus(**equ.__dict__)
|
||||
funcs.append(fun + (equ,))
|
||||
# 护甲精通计算
|
||||
if equ.typeSon2Id == self.防具类型:
|
||||
self.SetStatus(**精通计算(equ.lv, equ.rarity, equ.typeSon1Id, equ.typeSon2Id, self.输出类型, self.buffer))
|
||||
# 套装效果
|
||||
suits += (equ.suit or '').split(',')
|
||||
# endregion
|
||||
# region 附魔效果
|
||||
fun = self.equs.get_func_by_id(f'prop_{self.charEquipInfo[i].enchant}')
|
||||
funcs.append(fun + (equ,))
|
||||
# endregion
|
||||
# region 徽章效果
|
||||
for emblem in self.charEquipInfo[i].emblems:
|
||||
fun = self.equs.get_func_by_id(f'prop_{emblem}')
|
||||
funcs.append(fun + (equ,))
|
||||
# endregion
|
||||
# region 魔法封印效果
|
||||
for seal in self.charEquipInfo[i].seals:
|
||||
fun = self.equs.get_func_by_id(f'seal_{seal}')
|
||||
funcs.append(fun + (equ,))
|
||||
# endregion
|
||||
# region 套装效果
|
||||
matchSuit = []
|
||||
for i in list(set(filter(lambda x: x != '' and x is not None, suits))):
|
||||
# 获取当前的套装的数量
|
||||
nums = len(list(filter(lambda x: x == i, suits)))
|
||||
# 获取当前的套装信息
|
||||
suisInfos = list(filter(lambda x: x.suitID == i, self.equs.suit))
|
||||
if len(suisInfos) > 0:
|
||||
matchSuit += [i.id for i in list(filter(lambda x: x.needNum <= nums, suisInfos))]
|
||||
# 兼容于判断
|
||||
if suisInfos[0].compatibility is not None and suisInfos[0].compatibility != '':
|
||||
for compatibility in suisInfos[0].compatibility.split(','):
|
||||
# 兼容于的装备数量
|
||||
numsComp = len(list(filter(lambda x: x == compatibility, suits)))
|
||||
# 大于兼容于小于兼容于加上当前套装数量
|
||||
if numsComp > 0:
|
||||
matchSuit += [
|
||||
i.id
|
||||
for i in list(
|
||||
filter(
|
||||
lambda x: x.suitID == compatibility and numsComp < x.needNum <= nums + numsComp,
|
||||
self.equs.suit,
|
||||
)
|
||||
)
|
||||
]
|
||||
for i in matchSuit:
|
||||
fun = self.equs.get_func_by_id(f'suit_{i}')
|
||||
funcs.append(fun + (None,))
|
||||
# endregion
|
||||
funcs.sort(key=lambda x: x[2])
|
||||
for func in funcs:
|
||||
# 站街
|
||||
func[1](self, func[3], 0)
|
||||
# 进图
|
||||
func[1](self, func[3], 1)
|
||||
return {
|
||||
'basicInfo': self.getBasicInos(),
|
||||
'skillInfo': [],
|
||||
}
|
||||
|
||||
# endregion
|
||||
|
||||
|
||||
def createCharacter(alter: str, equVersion: str = '0'):
|
||||
character: Character = None
|
||||
module_name = 'core.characters.' + alter
|
||||
try:
|
||||
character = importlib.import_module(module_name).classChange(equVersion)
|
||||
except Exception as ex:
|
||||
print(ex)
|
||||
print('create character ' + module_name + ' error.')
|
||||
pass
|
||||
return character
|
||||
@@ -0,0 +1,125 @@
|
||||
from database.models import Session, EquData, SuitData
|
||||
from database.connect import get_db_engine as get_engine
|
||||
from functools import cache
|
||||
|
||||
|
||||
def parse_to_number_list(info: str, default: list[float] = [0]) -> list[float]:
|
||||
return default if not info else [float(i) for i in info.split(',')]
|
||||
|
||||
|
||||
class Equ:
|
||||
id: str
|
||||
name: str
|
||||
rarity: str
|
||||
itemType: str
|
||||
itemDetailType: str
|
||||
Point: list[float] | float
|
||||
categorize: str
|
||||
imageUrl: str
|
||||
detail: str
|
||||
bufferDetail: str
|
||||
STR: list[float] | float
|
||||
INT: list[float] | float
|
||||
Vitality: list[float] | float
|
||||
Spirit: list[float] | float
|
||||
AtkP: list[float] | float
|
||||
AtkM: list[float] | float
|
||||
AtkI: list[float] | float
|
||||
SkillAttack: list[float] | float
|
||||
Attack: list[float] | float
|
||||
Buffer: list[float] | float
|
||||
max_adaptation: int
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.__dict__.update(kwargs)
|
||||
|
||||
def adapt(self, adaptation: int = 0):
|
||||
"""调适
|
||||
|
||||
Args:
|
||||
adaptation (int): 调适等级
|
||||
"""
|
||||
temp = self.__dict__.copy()
|
||||
keys = [key for key in EquData.__dict__.keys() if key[0].isupper()]
|
||||
for attr in keys:
|
||||
value = getattr(self, attr)
|
||||
temp[attr] = value[min(adaptation, len(value) - 1)] if isinstance(value, list) else value
|
||||
return Equ(**temp)
|
||||
|
||||
|
||||
class Suit:
|
||||
id: int
|
||||
suitId: int
|
||||
suitName: str
|
||||
rarity: str
|
||||
name: str
|
||||
point: int
|
||||
level: int
|
||||
count: int
|
||||
SkillAttack: float
|
||||
Attack: float
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.__dict__.update(kwargs)
|
||||
|
||||
|
||||
class Equipments:
|
||||
def __init__(self, version='0'):
|
||||
self.version = version
|
||||
self.engine = get_engine(version)
|
||||
self.equs: list[Equ] = []
|
||||
self.equ_dict: dict[str, Equ] = {}
|
||||
self.suits: list[Suit] = []
|
||||
self.suit_dict: dict[str, Suit] = {}
|
||||
self.init_equs()
|
||||
self.init_suits()
|
||||
self.engine.dispose()
|
||||
|
||||
def init_equs(self):
|
||||
"""从数据库中获取所有装备信息"""
|
||||
with Session(self.engine) as session:
|
||||
db_list = session.query(EquData).all()
|
||||
keys = [key for key in EquData.__dict__.keys() if key[0].isupper()] + ['suit']
|
||||
for item in db_list:
|
||||
max_adaptation = 0
|
||||
item.id = str(item.id)
|
||||
for attr in keys:
|
||||
value = parse_to_number_list(getattr(item, attr))
|
||||
max_adaptation = max(max_adaptation, len(value) - 1)
|
||||
setattr(item, attr, value)
|
||||
equ_dict = {k: v for k, v in item.__dict__.items() if not k.startswith('_')}
|
||||
equ_dict['max_adaptation'] = max_adaptation
|
||||
equ = Equ(**equ_dict)
|
||||
self.equs.append(equ)
|
||||
self.equ_dict[equ.id] = equ
|
||||
|
||||
def init_suits(self):
|
||||
"""从数据库中获取所有套装信息"""
|
||||
with Session(self.engine) as session:
|
||||
db_list = session.query(SuitData).all()
|
||||
for item in db_list:
|
||||
suit = Suit(**{k: v for k, v in item.__dict__.items() if not k.startswith('_')})
|
||||
self.suits.append(suit)
|
||||
self.suit_dict.setdefault(str(suit.suitId), []).append(suit)
|
||||
pass
|
||||
|
||||
def get_suit_info(self, suitId: str | int, point: int = 0, count: int = 0) -> list[Suit]:
|
||||
"""根据套装点数返回对应适用的套装属性\n
|
||||
新套装只需要传入suitID和point即可,count默认为0\n
|
||||
老套装需要传入suitID和count即可,point默认为0
|
||||
"""
|
||||
# 先筛选出点数小于等于point和数量小于等于count的套装
|
||||
suits: list[Suit] = [suit for suit in self.suit_dict[str(suitId)] if suit.point <= point and suit.count <= count]
|
||||
result: dict[int, Suit] = {}
|
||||
# 取每种count套装中点数最高的
|
||||
for suit in suits:
|
||||
if suit.count not in result or suit.point > result[suit.count].point:
|
||||
result[suit.count] = suit
|
||||
return list(result.values())
|
||||
|
||||
|
||||
|
||||
@cache
|
||||
def get_equipment(version: str = '0') -> Equipments:
|
||||
# print('加载装备信息')
|
||||
return Equipments(version)
|
||||
@@ -0,0 +1,602 @@
|
||||
# 看看就行, 计算细节通用的数据
|
||||
|
||||
# region
|
||||
def 强化技攻(强化等级, 强化类型, 部位):
|
||||
增幅技攻 = [0] * 11 + [0.2, 0.4, 0.7, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4]
|
||||
强化技攻 = [0] * 13 + [0.4, 0.7, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2]
|
||||
if 强化类型 == '强化':
|
||||
if 部位 not in ['武器', '耳环']:
|
||||
return 0
|
||||
else:
|
||||
return 强化技攻[强化等级]
|
||||
return 增幅技攻[强化等级]
|
||||
|
||||
|
||||
# endregion
|
||||
|
||||
# region 增幅
|
||||
|
||||
|
||||
增幅系数 = (0, 1, 2, 3, 4, 6, 8, 10, 22, 28, 35, 42, 50, 67, 108, 150, 192, 267, 342, 417, 500, 583, 667, 750, 833, 917, 1000, 1083, 1167, 1250, 1333, 1417)
|
||||
增幅成长系数 = {'稀有': 1, '神器': 1.3, '勇者': 1.1, '传说': 1.4, '史诗': 1.5, '神话': 1.6}
|
||||
增幅品级加分 = {'稀有': 45, '神器': 45, '勇者': 45, '传说': 46, '史诗': 46, '神话': 46}
|
||||
# 增幅品级底数 = {'稀有': 5, '神器': 6, '勇者': 5, '传说': 6, '史诗': 7, '神话': 8}
|
||||
# 增幅品级底数_HF = {'稀有': 10, '神器': 11, '勇者': 10, '传说': 11, '史诗': 12, '神话': 13}
|
||||
增幅品级底数 = {'稀有': 10, '神器': 11, '勇者': 10, '传说': 11, '史诗': 12, '神话': 13}
|
||||
|
||||
|
||||
def 增幅计算(装备等级, 品质, 强化等级, 版本='GF'):
|
||||
if 版本 == 'GF':
|
||||
if 品质 == '智慧产物':
|
||||
return 0
|
||||
return int((装备等级 + 增幅品级加分[品质]) * 增幅成长系数[品质] * 增幅系数[强化等级] / 100 - 0.00000001) + 增幅品级底数[品质] + (0 if 强化等级 < 12 else 5)
|
||||
|
||||
|
||||
# endregion
|
||||
|
||||
# region 特殊装备&勋章
|
||||
|
||||
耳环强化系数 = (
|
||||
0,
|
||||
83,
|
||||
124,
|
||||
166,
|
||||
207,
|
||||
248,
|
||||
314,
|
||||
370,
|
||||
426,
|
||||
482,
|
||||
621,
|
||||
970,
|
||||
1455,
|
||||
1941,
|
||||
2911,
|
||||
4043,
|
||||
5175,
|
||||
7116,
|
||||
9056,
|
||||
10997,
|
||||
13099,
|
||||
15363,
|
||||
17627,
|
||||
19891,
|
||||
22155,
|
||||
24420,
|
||||
26684,
|
||||
28948,
|
||||
31212,
|
||||
33476,
|
||||
35740,
|
||||
38004,
|
||||
)
|
||||
左右强化系数 = (
|
||||
0,
|
||||
60,
|
||||
90,
|
||||
120,
|
||||
150,
|
||||
180,
|
||||
210,
|
||||
247,
|
||||
285,
|
||||
322,
|
||||
360,
|
||||
675,
|
||||
1013,
|
||||
1350,
|
||||
2025,
|
||||
2812,
|
||||
3600,
|
||||
4950,
|
||||
6300,
|
||||
7650,
|
||||
9112,
|
||||
10688,
|
||||
12262,
|
||||
13838,
|
||||
15412,
|
||||
16988,
|
||||
18562,
|
||||
20138,
|
||||
21712,
|
||||
23288,
|
||||
24862,
|
||||
26438,
|
||||
)
|
||||
勋章强化系数 = (0, 100, 120, 144, 173, 208, 250, 300, 320, 360, 400, 610, 1220, 2440, 2684, 2952, 3838, 4989, 6486, 8432, 10962)
|
||||
特殊成长系数 = {'普通': 0.4, '高级': 0.7, '稀有': 1, '神器': 1.25, '传说': 1.35, '史诗': 1.45, '神话': 1.55}
|
||||
特殊品级加分 = {'普通': 24, '高级': 30, '稀有': 26, '神器': 28, '传说': 29, '史诗': 30, '神话': 31}
|
||||
|
||||
|
||||
def 耳环计算(装备等级, 品质, 强化等级):
|
||||
if 品质 == '智慧产物':
|
||||
return 0
|
||||
return int((装备等级 + 特殊品级加分[品质]) / 2400 * 特殊成长系数[品质] * 耳环强化系数[强化等级])
|
||||
|
||||
|
||||
def 左右计算(装备等级, 品质, 强化等级):
|
||||
if 品质 == '智慧产物':
|
||||
return 0
|
||||
return int((装备等级 + 特殊品级加分[品质]) / 2400 * 特殊成长系数[品质] * 左右强化系数[强化等级])
|
||||
|
||||
|
||||
def 勋章计算(装备等级, 品质, 强化等级):
|
||||
return int((装备等级 + 特殊品级加分[品质]) / 2400 * 特殊成长系数[品质] * 勋章强化系数[强化等级])
|
||||
|
||||
|
||||
# endregion
|
||||
|
||||
# region 武器
|
||||
|
||||
武器强化系数 = (0, 2, 2.6, 3.6, 4.7, 5.8, 6.9, 8.2, 11, 14.6, 18.7, 26.9, 36.7, 43, 49.2, 55.4, 61.7, 68, 74.3, 80.6, 86.9, 93.2, 99.5, 105.8, 112.1, 118.3, 124.6, 130.9, 137.1, 143.4, 149.7, 156.0)
|
||||
武器锻造系数 = (0, 2, 3, 4, 6, 8, 13, 18, 25, 32, 41)
|
||||
武器成长系数 = {'普通': 0.4, '高级': 0.7, '稀有': 1, '神器': 1.25, '勇者': 1.1, '传说': 1.35, '史诗': 1.45, '神话': 1.55}
|
||||
武器品级加分 = {'普通': 8, '高级': 8, '稀有': 10, '神器': 12, '勇者': 11, '传说': 13, '史诗': 14, '神话': 15}
|
||||
武器类型系数 = {
|
||||
'短剑': (1.095, 1.115),
|
||||
'太刀': (1.095, 1.105),
|
||||
'钝器': (1.11, 1.095),
|
||||
'巨剑': (1.12, 1.09),
|
||||
'光剑': (1.093, 1.09),
|
||||
'手套': (1.095, 1.115),
|
||||
'臂铠': (1.12, 1.09),
|
||||
'爪': (1.1, 1.1),
|
||||
'拳套': (1.105, 1.095),
|
||||
'东方棍': (1.095, 1.1),
|
||||
'左轮枪': (1.087, 1.077),
|
||||
'自动手枪': (1.064, 1.094),
|
||||
'步枪': (1.1, 1.085),
|
||||
'手炮': (1.106, 1.064),
|
||||
'手弩': (1.075, 1.085),
|
||||
'矛': (1.12, 1.085),
|
||||
'棍棒': (1.108, 1.09),
|
||||
'魔杖': (1.09, 1.11),
|
||||
'法杖': (1.095, 1.12),
|
||||
'扫把': (1.1, 1.11),
|
||||
'十字架': (1.1, 1.095),
|
||||
'念珠': (1.09, 1.115),
|
||||
'图腾': (1.105, 1.09),
|
||||
'镰刀': (1.105, 1.105),
|
||||
'战斧': (1.12, 1.085),
|
||||
'匕首': (1.09, 1.089),
|
||||
'双剑': (1.102, 1.08),
|
||||
'手杖': (1.081, 1.115),
|
||||
'苦无': (1.09, 1.11),
|
||||
'长枪': (1.105, 1.09),
|
||||
'战戟': (1.12, 1.085),
|
||||
'光枪': (1.095, 1.115),
|
||||
'暗矛': (1.095, 1.105),
|
||||
'长刀': (1.108, 1.09),
|
||||
'小太刀': (1.1, 1.1),
|
||||
'重剑': (1.12, 1.09),
|
||||
'源力剑': (1.095, 1.115),
|
||||
# todo
|
||||
'神弦弓': (1.1, 1.095),
|
||||
'玄机弓': (1.108, 1.09),
|
||||
'强攻弩': (1.12, 1.09),
|
||||
'妖影弓': (1.095, 1.1),
|
||||
}
|
||||
|
||||
|
||||
def 武器强化计算(装备等级, 品质, 强化等级, 武器类型, 类型):
|
||||
武器系数 = 武器类型系数[武器类型][0 if 类型 == '物理' else 1]
|
||||
return int((装备等级 + 武器品级加分[品质]) / 8 * 武器成长系数[品质] * 武器强化系数[强化等级] * 武器系数)
|
||||
|
||||
|
||||
def 锻造计算(装备等级, 品质, 锻造等级):
|
||||
return round((装备等级 + 武器品级加分[品质]) / 8 * 武器成长系数[品质] * 武器锻造系数[锻造等级])
|
||||
|
||||
|
||||
def 锻造四维(装备等级, 品质, 锻造等级):
|
||||
return round((装备等级 + 武器品级加分[品质]) / 80 * 武器成长系数[品质] * 武器锻造系数[锻造等级])
|
||||
|
||||
|
||||
武器冷却惩罚系数 = {
|
||||
'短剑': (1, 1, 1),
|
||||
'太刀': (0.95, 0.95, 1),
|
||||
'钝器': (1, 1, 1),
|
||||
'巨剑': (1.05, 1, 1),
|
||||
'光剑': (0.9, 1, 1),
|
||||
'手套': (0.9, 1, 1),
|
||||
'臂铠': (1.05, 1, 1),
|
||||
'爪': (1, 1, 1),
|
||||
'拳套': (0.9, 1, 1),
|
||||
'东方棍': (1, 1, 1),
|
||||
'左轮枪': (0.95, 1, 1),
|
||||
'自动手枪': (0.9, 1, 1),
|
||||
'步枪': (1, 1, 1),
|
||||
'手炮': (1.05, 1, 1),
|
||||
'手弩': (0.9, 1, 1),
|
||||
'矛': (1, 0.95, 1),
|
||||
'棍棒': (0.95, 1, 1),
|
||||
'魔杖': (0.95, 1, 1),
|
||||
'法杖': (1, 1.05, 1),
|
||||
'扫把': (1, 1, 1),
|
||||
'十字架': (1, 0.95, 1),
|
||||
'念珠': (0.95, 1, 1),
|
||||
'图腾': (1, 0.95, 1),
|
||||
'镰刀': (0.95, 1, 1),
|
||||
'战斧': (1.05, 0.9, 1),
|
||||
'匕首': (0.9, 0.95, 1),
|
||||
'双剑': (1.05, 0.9, 1),
|
||||
'手杖': (1, 1.05, 1),
|
||||
'苦无': (1, 1, 1),
|
||||
'长枪': (1, 1, 1),
|
||||
'战戟': (1.1, 0.9, 1),
|
||||
'光枪': (1, 1, 1),
|
||||
'暗矛': (0.95, 0.95, 1),
|
||||
'长刀': (1, 1, 1),
|
||||
'小太刀': (0.95, 1, 1),
|
||||
'重剑': (1.05, 1, 1),
|
||||
'源力剑': (1, 1, 1),
|
||||
# todo
|
||||
'神弦弓': (1, 1, 1),
|
||||
'玄机弓': (1, 1, 1),
|
||||
'强攻弩': (1.05, 1, 1),
|
||||
'妖影弓': (0.95, 0.95, 1),
|
||||
}
|
||||
|
||||
MP系数 = {
|
||||
'短剑': (1, 1.15, 1),
|
||||
'太刀': (0.95, 1.05, 1),
|
||||
'钝器': (1.1, 0.95, 1),
|
||||
'巨剑': (1.2, 0.9, 1),
|
||||
'光剑': (0.9, 1, 1),
|
||||
'手套': (0.95, 1.15, 1),
|
||||
'臂铠': (1.2, 0.9, 1),
|
||||
'爪': (1, 1, 1),
|
||||
'拳套': (1.05, 0.95, 1),
|
||||
'东方棍': (0.95, 1, 1),
|
||||
'左轮枪': (1, 0.9, 1),
|
||||
'自动手枪': (0.7, 1.1, 1),
|
||||
'步枪': (1.1, 0.95, 1),
|
||||
'手炮': (1.25, 0.75, 1),
|
||||
'手弩': (0.9, 1, 1),
|
||||
'矛': (1.1, 0.95, 1),
|
||||
'棍棒': (1, 1, 1),
|
||||
'魔杖': (0.95, 1, 1),
|
||||
'法杖': (1, 1.1, 1),
|
||||
'扫把': (1, 1, 1),
|
||||
'十字架': (1, 0.95, 1),
|
||||
'念珠': (0.9, 1.15, 1),
|
||||
'图腾': (1.05, 0.9, 1),
|
||||
'镰刀': (0.95, 1, 1),
|
||||
'战斧': (1.2, 0.85, 1),
|
||||
'匕首': (1, 0.9, 1),
|
||||
'双剑': (1.2, 0.8, 1),
|
||||
'手杖': (0.95, 1.15, 1),
|
||||
'苦无': (1, 1.1, 1),
|
||||
'长枪': (1.1, 1, 1),
|
||||
'战戟': (1.2, 0.9, 1),
|
||||
'光枪': (1, 1.15, 1),
|
||||
'暗矛': (0.95, 1.05, 1),
|
||||
'长刀': (1.1, 1, 1),
|
||||
'小太刀': (1, 1, 1),
|
||||
'重剑': (1.2, 0.9, 1),
|
||||
'源力剑': (1, 1.15, 1),
|
||||
# todo
|
||||
'神弦弓': (1, 1, 1),
|
||||
'玄机弓': (1.1, 1, 1),
|
||||
'强攻弩': (1.2, 0.9, 1),
|
||||
'妖影弓': (0.95, 1, 1),
|
||||
}
|
||||
|
||||
|
||||
def 武器冷却惩罚(武器类型, 输出类型):
|
||||
类型系数 = 0 if 输出类型 == '物理百分比' else (1 if 输出类型 == '魔法百分比' else 2)
|
||||
return 武器冷却惩罚系数[武器类型][类型系数]
|
||||
# else:
|
||||
# return 武器冷却惩罚系数_HF[武器类型][类型系数]
|
||||
|
||||
|
||||
def 武器MP系数(武器类型, 输出类型, 版本='GF') -> float:
|
||||
类型系数 = 0 if 输出类型 == '物理百分比' else (1 if 输出类型 == '魔法百分比' else 2)
|
||||
if 版本 == 'GF':
|
||||
return MP系数[武器类型][类型系数]
|
||||
|
||||
|
||||
# endregion
|
||||
|
||||
# region 防具
|
||||
|
||||
# 部位系数 = {'上衣': 0.30, '头肩': 0.20, '下装': 0.25, '腰带': 0.10, '鞋': 0.15}
|
||||
# 品级加分 = {'稀有': 5, '神器': 8, '勇者': 11, '传说': 14, '史诗': 17, '智慧产物': 17, '神话': 18}
|
||||
|
||||
|
||||
# def 精通计算(装备等级, 品质, 强化等级, 部位):
|
||||
# return round((20 + 2.5 * (装备等级 + 品级加分[品质] + int(强化等级 / 3))) * 部位系数[部位], 2)
|
||||
|
||||
# def 辅助精通计算(装备等级, 品质, 强化等级, 部位):
|
||||
# return round((4 + (装备等级 + 品级加分[品质] + int(强化等级 / 3))) * 部位系数[部位], 2)
|
||||
|
||||
甲类系数 = {'皮甲': 2.9, '板甲': 2.9, '重甲': 3.1, '轻甲': 3.2, '布甲': 3.2}
|
||||
部位系数 = {'上衣': 0.30, '头肩': 0.20, '下装': 0.25, '腰带': 0.10, '鞋': 0.15}
|
||||
品级加分 = {'稀有': 5, '神器': 8, '勇者': 11, '传说': 14, '史诗': 17, '智慧产物': 17, '神话': 18}
|
||||
|
||||
|
||||
def 精通计算(装备等级, 品质, 强化等级, 部位, 甲类):
|
||||
return round((20 + 甲类系数[甲类] * (装备等级 + 品级加分[品质] + int(强化等级 / 3))) * 部位系数[部位], 2)
|
||||
|
||||
|
||||
def 辅助精通计算(装备等级, 品质, 强化等级, 部位, 属性):
|
||||
if 属性 == '智力':
|
||||
return round((8 + 2.4 * (装备等级 + 品级加分[品质] + int(强化等级 / 3))) * 部位系数[部位], 2)
|
||||
if 属性 == '体力':
|
||||
return round((4 + 1.6 * (装备等级 + 品级加分[品质] + int(强化等级 / 3))) * 部位系数[部位], 2)
|
||||
if 属性 == '精神':
|
||||
return round((8 + 0.8 * (装备等级 + 品级加分[品质] + int(强化等级 / 3))) * 部位系数[部位], 2)
|
||||
|
||||
|
||||
# endregion
|
||||
|
||||
# region 角色基础属性
|
||||
|
||||
当前等级 = 110
|
||||
|
||||
# 力量 体力 智力 精神
|
||||
角色基础系数 = {
|
||||
'魔枪士': (4.6, 4.6, 4.4, 4.4, 7, 7, 5, 5),
|
||||
'格斗家(女)': (5, 5, 4, 4, 7.5, 7.5, 4.5, 4.5),
|
||||
'格斗家(男)': (5, 5, 4, 4, 7.5, 7.5, 4.5, 4.5),
|
||||
'枪剑士': (4.6, 4.6, 4.4, 4.4, 7, 7, 5, 5),
|
||||
'神枪手(女)': (4.5, 4.5, 4.5, 4.5, 6.5, 6.5, 5.5, 5.5),
|
||||
'神枪手(男)': (4.5, 4.5, 4.5, 4.5, 6.5, 6.5, 5.5, 5.5),
|
||||
'守护者': (4.8, 4.8, 4.2, 4.2, 7, 7, 5, 5),
|
||||
'魔法师(女)': (4, 4, 5, 5, 4.5, 4.5, 7.5, 7.5),
|
||||
'魔法师(男)': (3.5, 4, 5.5, 5, 4, 4.5, 8, 7.5),
|
||||
'暗夜使者': (5, 4, 5, 4, 7.5, 5.5, 6.5, 4.5),
|
||||
'缔造者': (4, 4, 5, 5, 4.5, 4.5, 7.5, 7.5),
|
||||
'黑暗武士': (4.8, 4.8, 4.2, 4.2, 7.5, 7.5, 4.5, 4.5),
|
||||
'鬼剑士(男)': (4.8, 4.8, 4.2, 4.2, 7.5, 7.5, 4.5, 4.5),
|
||||
'鬼剑士(女)': (4.6, 4.6, 4.4, 4.4, 7, 7, 5, 5),
|
||||
'圣职者(男)': (4.7, 4.8, 4, 4.5, 6.5, 6.5, 4.5, 6.5),
|
||||
'圣职者(女)': (4.7, 4.8, 4, 4.5, 6.5, 6.5, 4.5, 6.5),
|
||||
# todo
|
||||
'弓箭手': (4.6, 4.6, 4.4, 4.4, 7, 7, 5, 5),
|
||||
}
|
||||
|
||||
# 力量 体力 智力 精神
|
||||
职业基础数据 = {
|
||||
'征战者-魔枪士': (5.5, 5.5, 3.5, 3.5),
|
||||
'决战者-魔枪士': (5, 5, 4, 4),
|
||||
'狩猎者-魔枪士': (3, 4.5, 6, 4.5),
|
||||
'暗枪士-魔枪士': (3.5, 3.5, 5.5, 5.5),
|
||||
'气功师-格斗家(女)': (3.5, 3.5, 5.5, 5.5),
|
||||
'散打-格斗家(女)': (5.5, 5.5, 3.5, 3.5),
|
||||
'街霸-格斗家(女)': (5, 4, 5, 4),
|
||||
'柔道家-格斗家(女)': (5, 6, 3.5, 3.5),
|
||||
'气功师-格斗家(男)': (3.5, 3.5, 5.5, 5.5),
|
||||
'散打-格斗家(男)': (5.5, 5.5, 3.5, 3.5),
|
||||
'街霸-格斗家(男)': (5, 4, 5, 4),
|
||||
'柔道家-格斗家(男)': (5, 6, 3.5, 3.5),
|
||||
'暗刃-枪剑士': (5.5, 5.5, 3.5, 3.5),
|
||||
'特工-枪剑士': (5, 5, 4, 4),
|
||||
'战线佣兵-枪剑士': (5.2, 5, 3.5, 4.3),
|
||||
'源能专家-枪剑士': (3.5, 3.5, 5.5, 5.5),
|
||||
'漫游枪手-神枪手(女)': (5.5, 5.5, 3.5, 3.5),
|
||||
'枪炮师-神枪手(女)': (5.5, 5.5, 3.5, 3.5),
|
||||
'机械师-神枪手(女)': (3.5, 3.5, 5.5, 5.5),
|
||||
'弹药专家-神枪手(女)': (4.7, 4.3, 4.7, 4.3),
|
||||
'漫游枪手-神枪手(男)': (5.5, 5.5, 3.5, 3.5),
|
||||
'枪炮师-神枪手(男)': (5.5, 5.5, 3.5, 3.5),
|
||||
'机械师-神枪手(男)': (3.5, 3.5, 5.5, 5.5),
|
||||
'弹药专家-神枪手(男)': (4.7, 4.3, 4.7, 4.3),
|
||||
'合金战士-神枪手(男)': (5.5, 5.5, 3.5, 3.5),
|
||||
'精灵骑士-守护者': (5, 5, 4, 4),
|
||||
'混沌魔灵-守护者': (3.5, 3.5, 5.5, 5.5),
|
||||
'帕拉丁-守护者': (5, 5.5, 2, 5.5),
|
||||
'龙骑士-守护者': (5, 5, 4, 4),
|
||||
'元素师-魔法师(女)': (3.5, 3.5, 5.5, 5.5),
|
||||
'召唤师-魔法师(女)': (3.8, 3.7, 5.3, 5.2),
|
||||
'战斗法师-魔法师(女)': (5, 4, 5, 4),
|
||||
'魔道学者-魔法师(女)': (4.5, 4, 5.2, 4.3),
|
||||
'小魔女-魔法师(女)': (4.7, 4.8, 5.5, 4.5),
|
||||
'元素爆破师-魔法师(男)': (3.5, 3.5, 5.5, 5.5),
|
||||
'冰结师-魔法师(男)': (3.5, 3.7, 5.5, 5.2),
|
||||
'血法师-魔法师(男)': (5.5, 5.5, 3.5, 3.5),
|
||||
'逐风者-魔法师(男)': (5.5, 5.2, 3.5, 3.8),
|
||||
'次元行者-魔法师(男)': (3.5, 3.5, 5.5, 5.5),
|
||||
'刺客-暗夜使者': (5.3, 4.5, 4.2, 4),
|
||||
'死灵术士-暗夜使者': (4.7, 3.5, 5.3, 4.5),
|
||||
'忍者-暗夜使者': (4.5, 3.5, 5.5, 4.5),
|
||||
'影舞者-暗夜使者': (5.5, 4.5, 4, 4),
|
||||
'缔造者-魔法师(女)': (4, 4, 5, 5),
|
||||
'黑暗武士-鬼剑士(男)': (4.8, 4.8, 4.2, 4.2),
|
||||
'剑魂-鬼剑士(男)': (5, 5, 4, 4),
|
||||
'鬼泣-鬼剑士(男)': (3.5, 3.5, 5.5, 5.5),
|
||||
'狂战士-鬼剑士(男)': (5.5, 5.5, 3.5, 3.5),
|
||||
'阿修罗-鬼剑士(男)': (3, 4.5, 6, 4.5),
|
||||
'剑影-鬼剑士(男)': (5, 5, 4, 4),
|
||||
'刃影-鬼剑士(女)': (5, 5, 4, 4),
|
||||
'驭剑士-鬼剑士(女)': (5, 5, 4, 4),
|
||||
'暗殿骑士-鬼剑士(女)': (3.5, 3.5, 5.5, 5.5),
|
||||
'契魔者-鬼剑士(女)': (5.5, 5.5, 3.5, 3.5),
|
||||
'流浪武士-鬼剑士(女)': (5.5, 5.5, 3.5, 3.5),
|
||||
'圣骑士-圣职者(男)': (3.5, 5.5, 3.5, 5.5),
|
||||
'蓝拳圣使-圣职者(男)': (5.2, 5, 3.9, 3.9),
|
||||
'驱魔师-圣职者(男)': (5, 4, 5, 4),
|
||||
'复仇者-圣职者(男)': (3.5, 3.5, 5.5, 5.5),
|
||||
'圣骑士-圣职者(女)': (3.5, 5.5, 5.5, 3.5),
|
||||
'异端审判者-圣职者(女)': (5.2, 5, 3.5, 4.3),
|
||||
'巫女-圣职者(女)': (3.5, 3.5, 5.5, 5.5),
|
||||
'诱魔者-圣职者(女)': (3.5, 3.5, 5.5, 5.5),
|
||||
# todo
|
||||
'缪斯-弓箭手': (3.5, 5.5, 3.5, 5.5),
|
||||
'旅人-弓箭手': (5.5, 5.5, 3.5, 3.5),
|
||||
'猎人-弓箭手': (5.5, 5.5, 3.5, 3.5),
|
||||
'妖护使-弓箭手': (5.5, 5.5, 3.5, 3.5),
|
||||
}
|
||||
|
||||
# 火抗 冰抗 光抗 暗抗
|
||||
|
||||
职业属性抗性数据 = {
|
||||
'征战者-魔枪士': (23, 23, 23, 23),
|
||||
'决战者-魔枪士': (23, 23, 23, 23),
|
||||
'狩猎者-魔枪士': (23, 23, 23, 23),
|
||||
'暗枪士-魔枪士': (23, 23, 23, 23),
|
||||
'气功师-格斗家(女)': (23, 23, 93, -7),
|
||||
'散打-格斗家(女)': (23, 23, 43, 3),
|
||||
'街霸-格斗家(女)': (23, 23, 43, 3),
|
||||
'柔道家-格斗家(女)': (23, 23, 43, 3),
|
||||
'气功师-格斗家(男)': (23, 23, 63, -7),
|
||||
'散打-格斗家(男)': (23, 23, 43, 3),
|
||||
'街霸-格斗家(男)': (23, 23, 43, 3),
|
||||
'柔道家-格斗家(男)': (23, 23, 43, 3),
|
||||
'暗刃-枪剑士': (23, 23, 23, 23),
|
||||
'特工-枪剑士': (23, 23, 23, 23),
|
||||
'战线佣兵-枪剑士': (23, 23, 23, 23),
|
||||
'源能专家-枪剑士': (23, 23, 23, 23),
|
||||
'漫游枪手-神枪手(女)': (23, 23, 23, 23),
|
||||
'枪炮师-神枪手(女)': (23, 23, 23, 23),
|
||||
'机械师-神枪手(女)': (23, 23, 23, 23),
|
||||
'弹药专家-神枪手(女)': (23, 23, 23, 23),
|
||||
'漫游枪手-神枪手(男)': (23, 23, 23, 23),
|
||||
'枪炮师-神枪手(男)': (23, 23, 23, 23),
|
||||
'机械师-神枪手(男)': (23, 23, 23, 23),
|
||||
'弹药专家-神枪手(男)': (23, 23, 23, 23),
|
||||
'合金战士-神枪手(男)': (23, 23, 23, 23),
|
||||
'精灵骑士-守护者': (28, 28, 28, 28),
|
||||
'混沌魔灵-守护者': (28, 28, 28, 28),
|
||||
'帕拉丁-守护者': (28, 28, 28, 28),
|
||||
'龙骑士-守护者': (28, 28, 28, 28),
|
||||
'元素师-魔法师(女)': (23, 23, 23, 23),
|
||||
'召唤师-魔法师(女)': (23, 23, 23, 23),
|
||||
'战斗法师-魔法师(女)': (23, 23, 23, 23),
|
||||
'魔道学者-魔法师(女)': (23, 23, 23, 23),
|
||||
'小魔女-魔法师(女)': (23, 23, 23, 23),
|
||||
'元素爆破师-魔法师(男)': (23, 23, 23, 23),
|
||||
'冰结师-魔法师(男)': (23, 23, 23, 23),
|
||||
'血法师-魔法师(男)': (23, 23, 23, 23),
|
||||
'逐风者-魔法师(男)': (23, 23, 23, 23),
|
||||
'次元行者-魔法师(男)': (23, 23, 23, 23),
|
||||
'刺客-暗夜使者': (23, 23, 23, 23),
|
||||
'死灵术士-暗夜使者': (23, 23, 3, 43),
|
||||
'忍者-暗夜使者': (31, 23, 23, 23),
|
||||
'影舞者-暗夜使者': (23, 23, 23, 23),
|
||||
'缔造者-魔法师(女)': (23, 23, 23, 23),
|
||||
'黑暗武士-鬼剑士(男)': (23, 23, 3, 43),
|
||||
'剑魂-鬼剑士(男)': (23, 23, 3, 43),
|
||||
'鬼泣-鬼剑士(男)': (23, 23, -7, 63),
|
||||
'狂战士-鬼剑士(男)': (23, 23, 3, 43),
|
||||
'阿修罗-鬼剑士(男)': (23, 23, 3, 43),
|
||||
'剑影-鬼剑士(男)': (23, 23, 3, 43),
|
||||
'刃影-鬼剑士(女)': (23, 23, 3, 43),
|
||||
'驭剑士-鬼剑士(女)': (23, 23, 3, 43),
|
||||
'暗殿骑士-鬼剑士(女)': (23, 23, 3, 43),
|
||||
'契魔者-鬼剑士(女)': (23, 23, 3, 43),
|
||||
'流浪武士-鬼剑士(女)': (23, 23, 3, 43),
|
||||
'圣骑士-圣职者(男)': (23, 23, 23, 23),
|
||||
'蓝拳圣使-圣职者(男)': (23, 23, 23, 23),
|
||||
'驱魔师-圣职者(男)': (23, 23, 23, 23),
|
||||
'复仇者-圣职者(男)': (23, 23, 23, 23),
|
||||
'圣骑士-圣职者(女)': (23, 23, 43, 23),
|
||||
'异端审判者-圣职者(女)': (23, 23, 23, 23),
|
||||
'巫女-圣职者(女)': (23, 23, 23, 23),
|
||||
'诱魔者-圣职者(女)': (23, 23, 23, 23),
|
||||
# todo
|
||||
'缪斯-弓箭手': (23, 23, 23, 23),
|
||||
'旅人-弓箭手': (23, 23, 23, 23),
|
||||
'猎人-弓箭手': (23, 23, 23, 23),
|
||||
'妖护使-弓箭手': (23, 23, 23, 23),
|
||||
}
|
||||
|
||||
# 出血 中毒 灼伤 感电 冰冻 减速 眩晕 诅咒 失明 石化 睡眠 混乱 束缚
|
||||
职业异常抗性数据 = {
|
||||
'征战者-魔枪士': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'决战者-魔枪士': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'狩猎者-魔枪士': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'暗枪士-魔枪士': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'气功师-格斗家(女)': (0, 0, 0, 0, 0, 0, 0, 0, 0.05, 0, 0, 0, 0),
|
||||
'散打-格斗家(女)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'街霸-格斗家(女)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'柔道家-格斗家(女)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'气功师-格斗家(男)': (0, 0, 0, 0, 0, 0, 0, 0, 0.05, 0, 0, 0, 0),
|
||||
'散打-格斗家(男)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'街霸-格斗家(男)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'柔道家-格斗家(男)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'暗刃-枪剑士': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'特工-枪剑士': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'战线佣兵-枪剑士': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'源能专家-枪剑士': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'漫游枪手-神枪手(女)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'枪炮师-神枪手(女)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'机械师-神枪手(女)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'弹药专家-神枪手(女)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'漫游枪手-神枪手(男)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'枪炮师-神枪手(男)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'机械师-神枪手(男)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'弹药专家-神枪手(男)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'合金战士-神枪手(男)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'精灵骑士-守护者': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'混沌魔灵-守护者': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'帕拉丁-守护者': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'龙骑士-守护者': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'元素师-魔法师(女)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'召唤师-魔法师(女)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'战斗法师-魔法师(女)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'魔道学者-魔法师(女)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'小魔女-魔法师(女)': (0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0),
|
||||
'元素爆破师-魔法师(男)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'冰结师-魔法师(男)': (0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'血法师-魔法师(男)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'逐风者-魔法师(男)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'次元行者-魔法师(男)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'刺客-暗夜使者': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'死灵术士-暗夜使者': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'忍者-暗夜使者': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'影舞者-暗夜使者': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'缔造者-魔法师(女)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'黑暗武士-鬼剑士(男)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'剑魂-鬼剑士(男)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'鬼泣-鬼剑士(男)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'狂战士-鬼剑士(男)': (0, 0, 0, 0, 0, 0, 0.95, 0, 0, 0, 0.95, 0, 0),
|
||||
'阿修罗-鬼剑士(男)': (0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0),
|
||||
'剑影-鬼剑士(男)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'刃影-鬼剑士(女)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'驭剑士-鬼剑士(女)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'暗殿骑士-鬼剑士(女)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'契魔者-鬼剑士(女)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'流浪武士-鬼剑士(女)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'圣骑士-圣职者(男)': (0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0, 0.05),
|
||||
'蓝拳圣使-圣职者(男)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'驱魔师-圣职者(男)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'复仇者-圣职者(男)': (0, 0, 0, 0, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3),
|
||||
'圣骑士-圣职者(女)': (0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05),
|
||||
'异端审判者-圣职者(女)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'巫女-圣职者(女)': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'诱魔者-圣职者(女)': (0, 0, 0, 0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5),
|
||||
# todo
|
||||
'缪斯-弓箭手': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'旅人-弓箭手': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'猎人-弓箭手': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
'妖护使-弓箭手': (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
}
|
||||
|
||||
|
||||
def 获取基础属性(角色, 职业):
|
||||
角色数据 = 角色基础系数[角色]
|
||||
职业数据 = 职业基础数据[职业 + '-' + 角色]
|
||||
|
||||
唤醒 = 335 if 当前等级 >= 75 else (145 if 当前等级 >= 15 else 0)
|
||||
|
||||
力量 = int(角色数据[4] + 角色数据[0] * min(14, 当前等级 - 1) + 职业数据[0] * max(当前等级 - 15, 0) + 唤醒 + 93 + 当前等级)
|
||||
体力 = int(角色数据[5] + 角色数据[1] * min(14, 当前等级 - 1) + 职业数据[1] * max(当前等级 - 15, 0) + 唤醒 + 93 + 当前等级)
|
||||
智力 = int(角色数据[6] + 角色数据[2] * min(14, 当前等级 - 1) + 职业数据[2] * max(当前等级 - 15, 0) + 唤醒 + 93 + 当前等级)
|
||||
精神 = int(角色数据[7] + 角色数据[3] * min(14, 当前等级 - 1) + 职业数据[3] * max(当前等级 - 15, 0) + 唤醒 + 93 + 当前等级)
|
||||
return (力量, 智力, 体力, 精神)
|
||||
|
||||
|
||||
def 获取属性抗性基础(角色, 职业):
|
||||
return 职业属性抗性数据[职业 + '-' + 角色]
|
||||
|
||||
|
||||
def 获取异常抗性基础(角色, 职业):
|
||||
return 职业异常抗性数据[职业 + '-' + 角色]
|
||||
|
||||
|
||||
刀魂之卡赞 = (0, 31, 40, 48, 58, 67, 79, 90, 103, 116, 131, 145, 161, 178, 194, 212, 230, 250, 270, 292, 313)
|
||||
|
||||
部位列表 = ('上衣', '头肩', '下装', '腰带', '鞋', '手镯', '项链', '戒指', '耳环', '辅助装备', '魔法石', '武器')
|
||||
|
||||
# endregion
|
||||
@@ -0,0 +1,77 @@
|
||||
import enum
|
||||
|
||||
|
||||
class CharacterInfo(enum.Enum):
|
||||
def __init__(self, name, icon, func) -> None:
|
||||
self._name = name
|
||||
self._icon = icon
|
||||
self._func = func
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
return self._icon
|
||||
|
||||
def value(self, value):
|
||||
return self._func(value)
|
||||
|
||||
STR = '力量', '/ui/UI_ProfileIcon_002.png', lambda x: round(x, 0)
|
||||
"""力量"""
|
||||
|
||||
INT = '智力', '/ui/UI_ProfileIcon_003.png', lambda x: round(x, 0)
|
||||
"""智力"""
|
||||
|
||||
AtkP = '物理攻击力', '/ui/UI_ProfileIcon_006.png', lambda x: round(x, 0)
|
||||
"""物理攻击力"""
|
||||
|
||||
AtkM = '魔法攻击力', '/ui/UI_ProfileIcon_007.png', lambda x: round(x, 0)
|
||||
"""魔法攻击力"""
|
||||
|
||||
AtkI = '独立攻击力', '/ui/UI_ProfileIcon_008.png', lambda x: round(x, 0)
|
||||
"""独立攻击力"""
|
||||
|
||||
ElementA: dict[str, float]
|
||||
# """属性攻击"""
|
||||
|
||||
ElementDB0 = '火属性强化', '/ui/UI_ProfileIcon_022.png', lambda x: round(x, 0)
|
||||
|
||||
ElementR0 = '火属性抗性', '/ui/UI_ProfileIcon_023.png', lambda x: round(x, 0)
|
||||
|
||||
ElementDB1 = '冰属性强化', '/ui/UI_ProfileIcon_024.png', lambda x: round(x, 0)
|
||||
|
||||
ElementR1 = '冰属性抗性', '/ui/UI_ProfileIcon_025.png', lambda x: round(x, 0)
|
||||
|
||||
ElementDB2 = '光属性强化', '/ui/UI_ProfileIcon_026.png', lambda x: round(x, 0)
|
||||
|
||||
ElementR2 = '光属性抗性', '/ui/UI_ProfileIcon_027.png', lambda x: round(x, 0)
|
||||
|
||||
ElementDB3 = '暗属性强化', '/ui/UI_ProfileIcon_028.png', lambda x: round(x, 0)
|
||||
|
||||
ElementR3 = '暗属性抗性', '/ui/UI_ProfileIcon_029.png', lambda x: round(x, 0)
|
||||
|
||||
CriticalP = '物理暴击', '/ui/UI_ProfileIcon_011.png', lambda x: f'{format(x * 100, ".2f")}%'
|
||||
"""物理暴击"""
|
||||
|
||||
CriticalM = '魔法暴击', '/ui/UI_ProfileIcon_010.png', lambda x: f'{format(x * 100, ".2f")}%'
|
||||
"""魔法暴击"""
|
||||
|
||||
EquipmentSkillAttack = '技能攻击力增加', '/ui/UI_ProfileIcon_047.png', lambda x: f'{format(x * 100 - 100, ".2f")}%'
|
||||
"""技能攻击力"""
|
||||
|
||||
SpeedA = '攻击速度', '/ui/UI_ProfileIcon_012.png', lambda x: f'{format(x * 100, ".2f")}%'
|
||||
"""攻击速度"""
|
||||
|
||||
SpeedM = '移动速度', '/ui/UI_ProfileIcon_014.png', lambda x: f'{format(x * 100, ".2f")}%'
|
||||
"""移动速度"""
|
||||
|
||||
SpeedR = '施放速度', '/ui/UI_ProfileIcon_013.png', lambda x: f'{format(x * 100, ".2f")}%'
|
||||
"""施放速度"""
|
||||
|
||||
# HitP : float
|
||||
# """命中率"""
|
||||
|
||||
# Hit : float
|
||||
# """命中"""
|
||||
@@ -0,0 +1,96 @@
|
||||
from enum import Enum
|
||||
from typing import Union
|
||||
|
||||
from core.basic.equipment import Equ, get_equipment
|
||||
|
||||
|
||||
class CharacterEquipInfo:
|
||||
id: str
|
||||
"""装备ID"""
|
||||
reinforce: int
|
||||
"""强化等级"""
|
||||
reinforceType: int
|
||||
"""强化类型"""
|
||||
enchant: str
|
||||
"""附魔"""
|
||||
emblems: list[str]
|
||||
"""徽章"""
|
||||
fusion: int | None
|
||||
"""贴膜ID"""
|
||||
refine: int | None
|
||||
"""锻造等级"""
|
||||
fusionDetail: dict | None
|
||||
"""贴膜详情"""
|
||||
adaptation: int
|
||||
"""调适等级"""
|
||||
equInfo: Union['Equ', None]
|
||||
"""装备信息"""
|
||||
fusionInfo: Union['Equ', None]
|
||||
"""贴膜信息"""
|
||||
|
||||
def __init__(self, info={}, equVerison=0, part='') -> None:
|
||||
self.__dict__.update(info)
|
||||
equ = get_equipment(equVerison).equ_dict.get(self.id, None)
|
||||
if equ is not None and (equ.itemType == part or equ.itemDetailType == part):
|
||||
self.equInfo = equ.adapt(self.adaptation)
|
||||
else:
|
||||
self.equInfo = None
|
||||
|
||||
|
||||
class CharacterWeaponInfo(CharacterEquipInfo):
|
||||
refine: int
|
||||
"""锻造等级"""
|
||||
upgradeDetail: dict
|
||||
"""贴膜详情"""
|
||||
|
||||
def __init__(self, info={}) -> None:
|
||||
self.__dict__.update(info)
|
||||
|
||||
|
||||
class Part(Enum):
|
||||
weaopn = '武器'
|
||||
title = '称号'
|
||||
coat = '上衣'
|
||||
neck = '护肩'
|
||||
pants = '下装'
|
||||
shoes = '鞋子'
|
||||
belt = '腰带'
|
||||
bracelet = '手镯'
|
||||
ring = '戒指'
|
||||
necklace = '项链'
|
||||
support = '辅助装备'
|
||||
magic_stone = '魔法石'
|
||||
earring = '耳环'
|
||||
|
||||
|
||||
class CharacterAttributes(Enum):
|
||||
STR = '力量'
|
||||
INT = '智力'
|
||||
Spirit = '精神'
|
||||
Vitality = '体力'
|
||||
AtkP = '物理攻击力'
|
||||
AtkM = '魔法攻击力'
|
||||
AtkI = '独立攻击力'
|
||||
ElementA = '属性攻击'
|
||||
ElementDB = '属性强化数值'
|
||||
ElementR = '属性抗性数值'
|
||||
CriticalM = '魔法暴击'
|
||||
CriticalP = '物理暴击'
|
||||
SkillAttack = '技能攻击力'
|
||||
SpeedA = '攻击速度'
|
||||
SpeedM = '移动速度'
|
||||
SpeedR = '施放速度'
|
||||
Hit = '命中率'
|
||||
Abnormal = '敌人异常状态'
|
||||
MonsterInfo = '怪物信息'
|
||||
Buffer = '增益量'
|
||||
BufferP = '增益量%'
|
||||
Attack = '攻击强化'
|
||||
AttackP = '攻击强化%'
|
||||
|
||||
|
||||
mapping = {value: key for key, value in CharacterAttributes.__members__.items()}
|
||||
|
||||
|
||||
def get_key_by_value(value: str) -> str:
|
||||
return mapping[value]
|
||||
@@ -0,0 +1,178 @@
|
||||
from copy import deepcopy
|
||||
import re
|
||||
from typing import Literal, TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.basic.character import Character
|
||||
|
||||
characterLv = 120 + 5
|
||||
|
||||
|
||||
class Skill:
|
||||
name: str = ''
|
||||
"""技能名称"""
|
||||
_lv: int = 0
|
||||
id: int = 0
|
||||
"""技能ID"""
|
||||
icon: str = '$char/$name'
|
||||
"""技能图标,默认当前职业下该技能名称对应的图标,支持以下模板字符串
|
||||
$common 通用图标路径
|
||||
$char 当前职业图标路径
|
||||
$name 技能名称
|
||||
$id 技能ID
|
||||
"""
|
||||
type: Literal['active', 'passive'] = 'active'
|
||||
"""技能类型 active主动 passive被动"""
|
||||
learnLv: int = 0
|
||||
"""学习等级"""
|
||||
masterLv: int = 0
|
||||
"""精通等级"""
|
||||
maxLv: int = 0
|
||||
"""最大等级"""
|
||||
position: int = 0
|
||||
"""技能树位置"""
|
||||
rangeLv: int = 1
|
||||
"""学习间隔"""
|
||||
cube: int = 0
|
||||
"""无色消耗"""
|
||||
skillRation: int = 1
|
||||
"""技能面板倍率 [改变技能面板]"""
|
||||
skillDamage: int = 1
|
||||
"""技能技攻 [不改变技能面板]"""
|
||||
char: 'Character' = None
|
||||
"""技能所属角色"""
|
||||
damage: bool = False
|
||||
"""是否是伤害技能"""
|
||||
cd: float = 0
|
||||
"""技能冷却时间"""
|
||||
cdReduce: float = 1
|
||||
"""技能冷却缩减"""
|
||||
cdRecover: float = 1
|
||||
"""技能冷却恢复"""
|
||||
associate: list = []
|
||||
"""关联技能
|
||||
type: 关联类型 *乘算 +加算 $角色属性 默认'*skillRation'
|
||||
e.g.
|
||||
*skillRation 乘算技能面板倍率
|
||||
*cdReduce 乘算技能冷却缩减
|
||||
$*PATK 乘算角色物理攻击
|
||||
~直接走type对应的函数名称 传参为old,new,data,skills
|
||||
skills: 关联技能 默认 '*'
|
||||
"""
|
||||
|
||||
def __init__(self, char):
|
||||
self.char = char
|
||||
self.id = self._extract_id()
|
||||
self.icon = self._generate_icon()
|
||||
# self.lv = self._calculate_lv()
|
||||
pass
|
||||
|
||||
def _extract_id(self):
|
||||
className = self.__class__.__name__
|
||||
return int(re.search(r'\d+', className).group()) if re.search(r'\d+', className) else 0
|
||||
|
||||
def _generate_icon(self):
|
||||
icon = self.icon or '$char/$name'
|
||||
icon = icon.replace('$char', f'/characters/{self.char.name}/skill')
|
||||
icon = icon.replace('$common', '/characters/common')
|
||||
icon = icon.replace('$name', f'{self.name}')
|
||||
icon = icon.replace('$id', f'{self.id}')
|
||||
return icon
|
||||
|
||||
def _calculate_lv(self):
|
||||
return min(int((characterLv - self.learnLv) / self.rangeLv + 1), self.masterLv) if self._lv == 0 else self._lv
|
||||
|
||||
@property
|
||||
def lv(self):
|
||||
"""技能等级"""
|
||||
return self._lv
|
||||
|
||||
@lv.setter
|
||||
def lv(self, value):
|
||||
value = min(self.maxLv, value)
|
||||
if self._lv != value:
|
||||
self.effect(self._lv, value)
|
||||
self._lv = value
|
||||
|
||||
def effect(self, old: int, new: int):
|
||||
for assoc in self.associate:
|
||||
type = assoc.get('type', '*skillRation')
|
||||
skills = assoc.get('skills', 'all')
|
||||
data = assoc.get('data', [0] * self.maxLv)
|
||||
if type[0] not in ['*', '+', '$']:
|
||||
if self.precondition():
|
||||
getattr(self, type)(old, new, data, skills)
|
||||
continue
|
||||
if self.precondition():
|
||||
self._apply_association(type, old, new, data, skills)
|
||||
|
||||
def precondition(self):
|
||||
"""effect的前置条件"""
|
||||
return True
|
||||
|
||||
def _apply_association(self, type, old, new, data, skills):
|
||||
if type.startswith('$*'):
|
||||
value = (1 + data[new] / 100) / (1 + data[old] / 100)
|
||||
eval(f'self.char.SetStatus({type[2:]}={value})')
|
||||
elif type.startswith('$+'):
|
||||
value = data[new] / 100 - data[old] / 100
|
||||
eval(f'self.char.SetStatus({type[2:]}={value})')
|
||||
else:
|
||||
if skills == '*':
|
||||
skills = self.char.GetSkillNames('all', True)
|
||||
for name in skills:
|
||||
skill = self.char.GetSkillByName(name)
|
||||
if skill is not None:
|
||||
self._update_skill_attribute(skill,type, old, new, data)
|
||||
|
||||
def _update_skill_attribute(self,skill, type, old, new, data):
|
||||
if type.startswith('*'):
|
||||
setattr(skill, type[1:], getattr(skill, type[1:]) * (1 + data[new] / 100) / (1 + data[old] / 100))
|
||||
elif type.startswith('+'):
|
||||
setattr(skill, type[1:], getattr(skill, type[1:]) + data[new] / 100 - data[old] / 100)
|
||||
|
||||
|
||||
|
||||
class ActiveSkill(Skill):
|
||||
type: str = 'active'
|
||||
"""技能类型 active主动 passive被动"""
|
||||
damage: bool = True
|
||||
"""是否是伤害技能"""
|
||||
|
||||
def __init__(self, char):
|
||||
super().__init__(char)
|
||||
|
||||
def skillInfo(self, mode: str | None = None):
|
||||
basic = self
|
||||
if mode is not None:
|
||||
basic = deepcopy(self)
|
||||
basic.setMode(mode)
|
||||
else:
|
||||
basic = self
|
||||
date = basic.getSkillDate(self.lv)
|
||||
cd = basic.getSkillCD()
|
||||
return date * self.skillRation , self.skillDamage ,cd
|
||||
|
||||
def setMode(self, mode: str):
|
||||
pass
|
||||
|
||||
def getSkillDate(self,lv:int=0):
|
||||
res = 0
|
||||
for i in range(0,10):
|
||||
data = getattr(self, f'data{i}', [])
|
||||
if len(data) == 0:
|
||||
break
|
||||
if lv < len(data):
|
||||
hit = getattr(self, f'hit{i}', 1)
|
||||
power = getattr(self, f'power{i}', 1)
|
||||
res += hit * power * data[lv]
|
||||
return res
|
||||
|
||||
def getSkillCD(self):
|
||||
return self.cd * self.cdReduce / self.cdRecover
|
||||
|
||||
class PassiveSkill(Skill):
|
||||
type: str = 'passive'
|
||||
"""技能类型 active主动 passive被动"""
|
||||
damage: bool = False
|
||||
"""是否是伤害技能"""
|
||||
@@ -0,0 +1,154 @@
|
||||
# 944b9aab492c15a8474f96947ceeb9e4
|
||||
from core.basic.skill import PassiveSkill, ActiveSkill, characterLv
|
||||
from core.basic.character import Character
|
||||
|
||||
|
||||
class Skill0(ActiveSkill):
|
||||
# 기본기 숙련
|
||||
# https://api.neople.co.kr/df/skills/944b9aab492c15a8474f96947ceeb9e4/5a56514f35cf0270ae8d6c65f8fefd78?apikey=fdvit1Kj64EAJm0qfB3JEAD8FLExLDD0
|
||||
name = '基础精通'
|
||||
icon = '$common/$name'
|
||||
learnLv = 1
|
||||
masterLv = characterLv
|
||||
maxLv = 200
|
||||
position = 0
|
||||
rangeLv = 1
|
||||
damage = False
|
||||
type = 'passive'
|
||||
|
||||
|
||||
data0 = [0, 150, 158.7, 167.3, 176, 184.5, 193.2, 201.8, 210.5, 219.2, 227.7, 236.4, 245, 253.7, 262.2, 270.9, 284.3, 297.6, 311, 324.3, 337.7, 350.9, 364.2, 377.6, 390.9, 404.3, 417.6, 431, 444.3, 457.7, 471, 484.2, 497.6, 510.9, 524.3, 537.6, 551, 564.3, 577.7, 591, 604.4, 617.7, 630.9, 644.3, 657.6, 671, 684.3, 697.7, 711, 724.4, 737.7, 751.1, 764.3, 777.6, 791, 804.3, 817.7, 831, 844.4, 857.7, 871.1, 884.4, 897.8, 911, 924.3, 937.7, 951, 964.4, 977.7, 991.1, 1004.4, 1017.8, 1031.1, 1044.5, 1057.7, 1071, 1084.4, 1097.7, 1111.1, 1124.4, 1137.8, 1151.1, 1164.5, 1177.8, 1191, 1204.4, 1217.7, 1231.1, 1244.4, 1257.8, 1271.1, 1284.5, 1297.8, 1311.2, 1324.5, 1337.7, 1351.1, 1364.4, 1377.8, 1391.1, 1404.5, 1417.8, 1431.2, 1444.5, 1457.9, 1471.2, 1484.6, 1497.9, 1511.3, 1524.6, 1538, 1551.3, 1564.7, 1578, 1591.4, 1604.7, 1618.1, 1631.4, 1644.8, 1658.1, 1671.5, 1684.8, 1698.2, 1711.5, 1724.9, 1738.2, 1751.6, 1764.9, 1778.3, 1791.6, 1805, 1818.3, 1831.7, 1845, 1858.4, 1871.7, 1885.1, 1898.4, 1911.8, 1925.1, 1938.5, 1951.8, 1965.2, 1978.5, 1991.9, 2005.2, 2018.6, 2031.9, 2045.3, 2058.6, 2072, 2085.3, 2098.7, 2112, 2125.4, 2138.7, 2152.1, 2165.4, 2178.8, 2192.1, 2205.5, 2218.8, 2232.2, 2245.5, 2258.9, 2272.2, 2285.6, 2298.9, 2312.3, 2325.6, 2339, 2352.3, 2365.7, 2379, 2392.4, 2405.7, 2419.1, 2432.4, 2445.8, 2459.1, 2472.5, 2485.8, 2499.2, 2512.5, 2525.9, 2539.2, 2552.6, 2565.9, 2579.3, 2592.6, 2606, 2619.3, 2632.7, 2646, 2659.4, 2672.7, 2686.1, 2699.4, 2712.8, 2726.1, 2739.5]# noqa: E501
|
||||
|
||||
# G-14手雷 G-14 파열류탄
|
||||
# https://api.neople.co.kr/df/skills/944b9aab492c15a8474f96947ceeb9e4/de3fea2d65c597f4d55c70a02b97fc79?apikey=fdvit1Kj64EAJm0qfB3JEAD8FLExLDD0
|
||||
class Skill1(ActiveSkill):
|
||||
name = "G-14手雷"
|
||||
learnLv = 15
|
||||
masterLv = 60
|
||||
maxLv = 70
|
||||
position = 5
|
||||
rangeLv = 2
|
||||
cd = 2
|
||||
mp = [20, 160]
|
||||
|
||||
data0 = [0, 751, 830, 904, 981, 1057, 1132, 1210, 1287, 1362, 1438, 1516, 1591, 1668, 1746, 1819, 1897, 1972, 2049, 2127, 2202, 2278, 2355, 2429, 2508, 2584, 2659, 2735, 2814, 2888, 2965, 3041, 3116, 3194, 3271, 3346, 3422, 3500, 3575, 3652, 3732, 3806, 3883, 3961, 4034, 4112, 4189, 4264, 4342, 4418, 4493, 4570, 4648, 4723, 4799, 4876, 4950, 5029, 5105, 5180, 5256, 5335, 5409, 5486, 5562, 5637, 5715, 5792, 5867, 5943, 6021]# noqa: E501
|
||||
|
||||
class Skill2(PassiveSkill):
|
||||
# 니트로 모터
|
||||
# https://api.neople.co.kr/df/skills/944b9aab492c15a8474f96947ceeb9e4/4224f9b0b8c7c903e9a1e0f9d9f6d04d?apikey=fdvit1Kj64EAJm0qfB3JEAD8FLExLDD0
|
||||
name = '单兵推进器'
|
||||
learnLv = 15
|
||||
masterLv = 10
|
||||
maxLv = 20
|
||||
position = 8
|
||||
rangeLv = 1
|
||||
|
||||
data0 = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40]
|
||||
data1 = [0, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
|
||||
|
||||
associate = [
|
||||
{'data': data0, 'skills': ['交叉射击', '聚合弹', '凝固汽油弹', '超真空弹:切利']},
|
||||
{'data': data1, 'skills': ['爆裂弹']}
|
||||
]
|
||||
|
||||
|
||||
class Skill3(PassiveSkill):
|
||||
# 병기 숙련
|
||||
# https://api.neople.co.kr/df/skills/944b9aab492c15a8474f96947ceeb9e4/bae12a6dc7d22a5cf149673e88ddda28?apikey=fdvit1Kj64EAJm0qfB3JEAD8FLExLDD0
|
||||
name = '兵器研究'
|
||||
learnLv = 20
|
||||
masterLv = 10
|
||||
maxLv = 20
|
||||
position = 0
|
||||
rangeLv = 3
|
||||
|
||||
data0 = [0, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48] # noqa: E501
|
||||
associate = [{'data': data0, 'type': '$*PAtkI'}]
|
||||
|
||||
# def precondition(self):
|
||||
# weapon = self.char.charEquipInfo['武器'].equInfo
|
||||
# if weapon is not None and (weapon.itemDetailType == '手弩' or weapon.itemDetailType == '步枪' or weapon.categorize == '传世武器'):
|
||||
# return True
|
||||
# return False
|
||||
|
||||
class Skill4(PassiveSkill):
|
||||
# 강화탄
|
||||
# https://api.neople.co.kr/df/skills/944b9aab492c15a8474f96947ceeb9e4/3829c15bf5f520c13998a3479ba0ce7b?apikey=fdvit1Kj64EAJm0qfB3JEAD8FLExLDD0
|
||||
name = '弹药改良'
|
||||
learnLv = 20
|
||||
masterLv = 10 # todo
|
||||
maxLv = 20
|
||||
position = 1 # todo
|
||||
rangeLv = 3
|
||||
|
||||
data0 = [0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10] # noqa: E501
|
||||
data1 = [0, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33] # noqa: E501
|
||||
|
||||
|
||||
class Skill5(PassiveSkill):
|
||||
# 유탄 마스터리
|
||||
# https://api.neople.co.kr/df/skills/944b9aab492c15a8474f96947ceeb9e4/0113c8b1306ca76d208f83f2d093dd62?apikey=fdvit1Kj64EAJm0qfB3JEAD8FLExLDD0
|
||||
name = '手雷精通'
|
||||
learnLv = 20
|
||||
masterLv = 10
|
||||
maxLv = 20
|
||||
position = 7
|
||||
rangeLv = 3
|
||||
|
||||
data0 = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200] # noqa: E501
|
||||
|
||||
associate = [{'type': '*skillRation', 'data': data0, 'skills': ['G-14手雷']}]
|
||||
|
||||
class Skill6(ActiveSkill):
|
||||
# M18 클레이모어
|
||||
# https://api.neople.co.kr/df/skills/944b9aab492c15a8474f96947ceeb9e4/2ff50c35efcf0f287c4c418c8454da48?apikey=fdvit1Kj64EAJm0qfB3JEAD8FLExLDD0
|
||||
name = "M18阔剑地雷"
|
||||
learnLv = 20
|
||||
masterLv = 60 #todo
|
||||
maxLv = 70
|
||||
position = 8 #todo
|
||||
rangeLv = 2
|
||||
cd = 6
|
||||
mp = [70, 588]
|
||||
|
||||
data0 = [0, 2094, 2307, 2519, 2732, 2944, 3157, 3368, 3580, 3793, 4009, 4221, 4434, 4646, 4859, 5071, 5284, 5496, 5709, 5921, 6132, 6344, 6557, 6769, 6982, 7198, 7410, 7623, 7835, 8048, 8260, 8473, 8685, 8896, 9109, 9321, 9534, 9746, 9959, 10171, 10384, 10600, 10812, 11025, 11237, 11450, 11660, 11873, 12085, 12298, 12510, 12723, 12935, 13148, 13360, 13573, 13789, 14001, 14212, 14425, 14637, 14850, 15062, 15275, 15487, 15700, 15912, 16125, 16337, 16550, 16762]# noqa: E501
|
||||
|
||||
class classChange(Character):
|
||||
def __init__(self, equVersion=''):
|
||||
|
||||
super().__init__(equVersion)
|
||||
self.name = 'spitfire_female'
|
||||
self.nameShow = '重霄·弹药专家'
|
||||
self.role = 'gunner_female'
|
||||
|
||||
# 用来筛CP武器的
|
||||
# self.转职 = '弹药专家(女)'
|
||||
self.武器选项 = ['手弩', '步枪']
|
||||
self.输出类型选项 = ['魔法固伤', '物理固伤']
|
||||
self.防具精通属性 = ['智力', '力量']
|
||||
self.类型 = '魔法固伤'
|
||||
self.武器类型 = '手弩'
|
||||
self.防具类型 = '皮甲'
|
||||
self.buff = 1.84
|
||||
|
||||
self.load_skills()
|
||||
|
||||
def load_skills(self):
|
||||
"""加载技能"""
|
||||
skills = []
|
||||
skills_dict = {}
|
||||
i = 0
|
||||
while i >= 0:
|
||||
try:
|
||||
tem = eval('Skill' + str(i) + '(char=self)')
|
||||
skills_dict[tem.name] = tem
|
||||
skills.append(tem)
|
||||
i += 1
|
||||
except Exception as e:
|
||||
print(e)
|
||||
i = -1
|
||||
self.skills = skills
|
||||
self.skills_dict = skills_dict
|
||||
|
||||
def set_skill_info(self, info, rune_except=[], clothes_pants=[]):
|
||||
super().set_skill_info(info, rune_except=['爆裂弹'], clothes_pants=['远古记忆'])
|
||||
@@ -0,0 +1,35 @@
|
||||
#41f1cdc2ff58bb5fdc287be0db2a8df3
|
||||
from core.basic.skill import PassiveSkill, ActiveSkill, characterLv
|
||||
from core.basic.character import Character
|
||||
|
||||
# 基础精通 기본기 숙련
|
||||
# https://api.neople.co.kr/df/skills/41f1cdc2ff58bb5fdc287be0db2a8df3/5a56514f35cf0270ae8d6c65f8fefd78?apikey=fdvit1Kj64EAJm0qfB3JEAD8FLExLDD0
|
||||
class Skill0(ActiveSkill):
|
||||
name = '基础精通'
|
||||
icon = '$common$name'
|
||||
learnLv = 1
|
||||
masterLv = characterLv
|
||||
maxLv = 200
|
||||
position = 0
|
||||
rangeLv = 1
|
||||
damage = False
|
||||
type = 'passive'
|
||||
|
||||
data0 = [0, 150, 158.7, 167.3, 176, 184.5, 193.2, 201.8, 210.5, 219.2, 227.7, 236.4, 245, 253.7, 262.2, 270.9, 284.3, 297.6, 311, 324.3, 337.7, 350.9, 364.2, 377.6, 390.9, 404.3, 417.6, 431, 444.3, 457.7, 471, 484.2, 497.6, 510.9, 524.3, 537.6, 551, 564.3, 577.7, 591, 604.4, 617.7, 630.9, 644.3, 657.6, 671, 684.3, 697.7, 711, 724.4, 737.7, 751.1, 764.3, 777.6, 791, 804.3, 817.7, 831, 844.4, 857.7, 871.1, 884.4, 897.8, 911, 924.3, 937.7, 951, 964.4, 977.7, 991.1, 1004.4, 1017.8, 1031.1, 1044.5, 1057.7, 1071, 1084.4, 1097.7, 1111.1, 1124.4, 1137.8, 1151.1, 1164.5, 1177.8, 1191, 1204.4, 1217.7, 1231.1, 1244.4, 1257.8, 1271.1, 1284.5, 1297.8, 1311.2, 1324.5, 1337.7, 1351.1, 1364.4, 1377.8, 1391.1, 1404.5, 1417.8, 1431.2, 1444.5, 1457.9, 1471.2, 1484.6, 1497.9, 1511.3, 1524.6, 1538, 1551.3, 1564.7, 1578, 1591.4, 1604.7, 1618.1, 1631.4, 1644.8, 1658.1, 1671.5, 1684.8, 1698.2, 1711.5, 1724.9, 1738.2, 1751.6, 1764.9, 1778.3, 1791.6, 1805, 1818.3, 1831.7, 1845, 1858.4, 1871.7, 1885.1, 1898.4, 1911.8, 1925.1, 1938.5, 1951.8, 1965.2, 1978.5, 1991.9, 2005.2, 2018.6, 2031.9, 2045.3, 2058.6, 2072, 2085.3, 2098.7, 2112, 2125.4, 2138.7, 2152.1, 2165.4, 2178.8, 2192.1, 2205.5, 2218.8, 2232.2, 2245.5, 2258.9, 2272.2, 2285.6, 2298.9, 2312.3, 2325.6, 2339, 2352.3, 2365.7, 2379, 2392.4, 2405.7, 2419.1, 2432.4, 2445.8, 2459.1, 2472.5, 2485.8, 2499.2, 2512.5, 2525.9, 2539.2, 2552.6, 2565.9, 2579.3, 2592.6, 2606, 2619.3, 2632.7, 2646, 2659.4, 2672.7, 2686.1, 2699.4, 2712.8, 2726.1, 2739.5]# noqa: E501
|
||||
|
||||
# 空中连斩 공중 연속 베기
|
||||
# https://api.neople.co.kr/df/skills/41f1cdc2ff58bb5fdc287be0db2a8df3/78bd107acd474518b606be1e4fd38239?apikey=fdvit1Kj64EAJm0qfB3JEAD8FLExLDD0
|
||||
class Skill2(ActiveSkill):
|
||||
name = "空中连斩"
|
||||
learnLv = 5
|
||||
masterLv = 1
|
||||
maxLv = 11
|
||||
position = 0 #todo
|
||||
rangeLv = 1
|
||||
mp = [5, 7]
|
||||
|
||||
data0 = [0, 195, 209, 221, 234, 247, 260, 275, 286, 299, 312, 326]# noqa: E501
|
||||
data1 = [0, 144, 154, 163, 173, 182, 192, 202, 211, 221, 230, 240]# noqa: E501
|
||||
|
||||
def effect(self, old , new):
|
||||
pass
|
||||
@@ -0,0 +1,38 @@
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
|
||||
host_window = r'C:\Windows\System32\drivers\etc\hosts'
|
||||
host_mac = r'/etc/hosts'
|
||||
|
||||
|
||||
HOST_LIVE = ['#dcalc', '127.0.0.1:17173 www.dcalc.com']
|
||||
|
||||
|
||||
def search_host(hostvalue):
|
||||
if platform.system().lower() != 'windows':
|
||||
host_path = host_mac
|
||||
else:
|
||||
host_path = host_window
|
||||
hostfile = open(host_path, 'r', errors='ignore')
|
||||
each_line = hostfile.readlines()
|
||||
hostfile.close()
|
||||
findresult = re.findall(hostvalue, ''.join(each_line))
|
||||
return findresult
|
||||
|
||||
|
||||
def write_host(hostvalue):
|
||||
if platform.system().lower() != 'windows':
|
||||
output = open(host_mac, 'a')
|
||||
else:
|
||||
output = open(host_window, 'a')
|
||||
|
||||
for insid in hostvalue:
|
||||
output.write(insid)
|
||||
output.write('\n')
|
||||
output.close()
|
||||
|
||||
|
||||
def host_init():
|
||||
if not search_host(HOST_LIVE[0]):
|
||||
write_host(HOST_LIVE)
|
||||
@@ -0,0 +1,30 @@
|
||||
# 用于实现排行的最小堆
|
||||
from heapq import heapify, heappush, heappushpop
|
||||
|
||||
|
||||
class MinHeap:
|
||||
def __init__(self, top_n, h=[]):
|
||||
self.h = h[:]
|
||||
self.length = top_n
|
||||
heapify(self.h)
|
||||
|
||||
def add(self, element):
|
||||
if len(self.h) < self.length:
|
||||
heappush(self.h, element)
|
||||
else:
|
||||
heappushpop(self.h, element)
|
||||
|
||||
def getTop(self):
|
||||
return sorted(self.h, reverse=True)
|
||||
|
||||
def merge(self, other):
|
||||
"""
|
||||
合并另一个堆
|
||||
@type other MinHeap
|
||||
"""
|
||||
for elem in other.h:
|
||||
self.add(elem)
|
||||
|
||||
def reset(self):
|
||||
self.h = []
|
||||
heapify(self.h)
|
||||
@@ -0,0 +1,182 @@
|
||||
from copy import copy
|
||||
from dataclasses import Field
|
||||
import re
|
||||
from typing import dict
|
||||
from typing_extensions import Self
|
||||
|
||||
|
||||
class Store:
|
||||
def __init__(self, initState: dict[str, Field] = {}):
|
||||
self.__states: dict[str, Field] = initState.copy()
|
||||
self.last_state = None
|
||||
pass
|
||||
|
||||
# 设置值
|
||||
def set(self, key: str, value: any):
|
||||
field = self.__get_field__(key)
|
||||
field.setValue(value)
|
||||
return self
|
||||
|
||||
# 获取值
|
||||
def get(self, key: str, defaultValue: any = None):
|
||||
field = self.__get_field__(key)
|
||||
_value = field.getValue()
|
||||
if _value is None:
|
||||
_value = defaultValue
|
||||
return _value
|
||||
|
||||
def __getitem__(self, __key: str):
|
||||
return self.get(__key)
|
||||
|
||||
# 获取一个克隆值
|
||||
def clone(self, key: str, defaultValue: any = None):
|
||||
value = self.get(key, defaultValue)
|
||||
return copy(value)
|
||||
|
||||
# 主动通知变化
|
||||
def emit(self, key: str, value: any = None):
|
||||
field = self.__get_field__(key)
|
||||
field.emit(value)
|
||||
return self
|
||||
|
||||
# 找到首个不为空的值
|
||||
def first(self, *names):
|
||||
value = None
|
||||
for name in names:
|
||||
value = self.get(name)
|
||||
if value is not None:
|
||||
break
|
||||
return value
|
||||
|
||||
# 计算属性
|
||||
def compute(self, key: str, getter, setter=None):
|
||||
field = self.__get_field__(key)
|
||||
field.apply(setter)
|
||||
field.getter = getter
|
||||
return self
|
||||
|
||||
# 获取值并设置值
|
||||
def use(self, key: str, handle):
|
||||
if callable(handle):
|
||||
value = handle(self.get(key))
|
||||
self.set(key, value)
|
||||
return self
|
||||
|
||||
# 批量修改整个集合
|
||||
def convert(self, key: str, handle):
|
||||
return self.use(key, lambda value: list(map(handle, value)))
|
||||
|
||||
# 绑定对象的属性
|
||||
def bind(self, obj: object, name: str, key=None, defaultValue: any = None):
|
||||
def getter():
|
||||
return getattr(obj, name)
|
||||
|
||||
def setter(value):
|
||||
setattr(obj, name, value)
|
||||
|
||||
# 如果属性不存在 则初始化
|
||||
if hasattr(obj, name) is False or defaultValue is not None:
|
||||
setattr(obj, name, defaultValue)
|
||||
|
||||
return self.compute(key, getter, setter)
|
||||
|
||||
# 根据指定的条件删除
|
||||
def delete(self, pattern=None):
|
||||
def match(_):
|
||||
return True
|
||||
|
||||
if pattern is not None:
|
||||
if callable(pattern):
|
||||
match = pattern
|
||||
elif isinstance(pattern, str):
|
||||
|
||||
def match(s):
|
||||
return re.match(pattern, s)
|
||||
|
||||
keys = list(filter(match, self.__states.keys()))
|
||||
for key in keys:
|
||||
self.__states.pop(key)
|
||||
return self
|
||||
|
||||
# 根据指定的条件导出
|
||||
def exports(self, match=lambda _: True):
|
||||
result = {}
|
||||
for key in self.__states.keys():
|
||||
if match(key):
|
||||
result[key] = self.get(key)
|
||||
return result
|
||||
|
||||
# 导入
|
||||
def imports(self, pairs: dict = {}, prefix=''):
|
||||
for key in pairs.keys():
|
||||
self.set(prefix + str(key), pairs[key])
|
||||
return self
|
||||
|
||||
def copy(self) -> Self:
|
||||
return Store(self.__states)
|
||||
|
||||
# 只读属性
|
||||
|
||||
def const(self, key: str, value: any):
|
||||
return self.compute(key, lambda: value)
|
||||
|
||||
# 监听值的变化
|
||||
def watch(self, key: str, valueChanged):
|
||||
return self.compute(key, None, valueChanged)
|
||||
|
||||
def linstener(self, key: str):
|
||||
def change(value):
|
||||
self.set(key, value)
|
||||
pass
|
||||
|
||||
return change
|
||||
|
||||
def __get_field__(self, key: str):
|
||||
field = None
|
||||
if re.search(r'\{\w+\}', key):
|
||||
key = key.format_map(self)
|
||||
if self.__states.__contains__(key):
|
||||
field = self.__states[key]
|
||||
else:
|
||||
field = Store.Field()
|
||||
self.__states[key] = field
|
||||
self.last_state = (key, field)
|
||||
return field
|
||||
|
||||
class Field:
|
||||
def __init__(self, value=None):
|
||||
self.__value = None
|
||||
self.getter = None
|
||||
self.valueChangeds = []
|
||||
self.locked = False
|
||||
self.setValue(value)
|
||||
pass
|
||||
|
||||
def setValue(self, value):
|
||||
if self.locked:
|
||||
return
|
||||
self.locked = True
|
||||
self.__value = value
|
||||
self.emit(value)
|
||||
self.locked = False
|
||||
return self
|
||||
|
||||
def getValue(self):
|
||||
if callable(self.getter):
|
||||
self.__value = self.getter()
|
||||
return self.__value
|
||||
|
||||
def emit(self, value=None):
|
||||
if value is None:
|
||||
value = self.getValue()
|
||||
for valueChanged in self.valueChangeds:
|
||||
if callable(valueChanged):
|
||||
valueChanged(value)
|
||||
return
|
||||
|
||||
def apply(self, valueChanged):
|
||||
if callable(valueChanged):
|
||||
self.valueChangeds.append(valueChanged)
|
||||
|
||||
|
||||
store = Store()
|
||||
@@ -0,0 +1,58 @@
|
||||
from numbers import Number
|
||||
|
||||
|
||||
def is_number(num_str):
|
||||
"""
|
||||
判断数据是否为一个数字
|
||||
|
||||
:param num_str: 字符串对象
|
||||
:return:
|
||||
"""
|
||||
"""
|
||||
判断数据是否为一个数字
|
||||
|
||||
:param num_str: 字符串对象
|
||||
:return: 布尔值 True 是一个数字 False 不是一个数字 None 本就是数值类型
|
||||
"""
|
||||
# 防止非字段类型类型输入报错
|
||||
if isinstance(num_str, Number):
|
||||
return None
|
||||
elif not isinstance(num_str, str):
|
||||
return False
|
||||
|
||||
if num_str.isdigit():
|
||||
return True
|
||||
# 对Float类型的数字进行判断
|
||||
if num_str.count('.') == 1:
|
||||
num_str_list = num_str.split('.')
|
||||
left = num_str_list[0]
|
||||
right = num_str_list[1]
|
||||
if left.startswith('-') and left.count('-') == 1 and right.isdigit():
|
||||
_left = left.split('-')[1]
|
||||
if _left.isdigit():
|
||||
return True
|
||||
elif left.isdigit() and right.isdigit():
|
||||
return True
|
||||
# 负数判断
|
||||
elif num_str.startswith('-'):
|
||||
_left = num_str.split('-')[1]
|
||||
if _left.isdigit():
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def str_to_num(value, default=0, num_type=float):
|
||||
"""
|
||||
将字符串类型转化为数据类型
|
||||
|
||||
:param value: 需要转化的值,不一定需要是字符串类型
|
||||
:param default: 设置转换失败返回数值,默认原值
|
||||
:param num_type: 设置转换成的数据类型
|
||||
:return:
|
||||
"""
|
||||
num_flag = is_number(value)
|
||||
if num_flag:
|
||||
return num_type(value)
|
||||
elif num_flag is None:
|
||||
return num_type(value)
|
||||
return value if default is None else default
|
||||
Reference in New Issue
Block a user