This commit was merged in pull request #1.
This commit is contained in:
2026-06-02 20:56:07 +08:00
parent f824177aa5
commit bb3ad71d21
38 changed files with 1304 additions and 532 deletions
+19 -13
View File
@@ -1,5 +1,4 @@
from collections.abc import Mapping
import sys
from typing import Any, Literal
from core.abstract.character import CharacterProperty
@@ -15,8 +14,11 @@ class CharacterBase(CharacterProperty):
BindAwake: int
"""绑定觉醒等级"""
skills: list['Skill'] = []
skills_dict: dict[str, 'Skill'] = {}
skills: list['Skill']
skills_dict: dict[str, 'Skill']
skills_id_dict: dict[str, 'Skill']
skills_uuid_dict: dict[str, 'Skill']
skill_names_cache: dict[tuple[str, bool | str], list[str]]
equVersion: str = '0'
"""装备版本"""
charEquipInfo: dict[str, 'CharacterEquipInfo']
@@ -33,9 +35,9 @@ class CharacterBase(CharacterProperty):
"""誓约套装信息"""
oathSkillInfo: list['OathSuitSkill']
"""誓约技能信息"""
equ_effect: list['EquEffect'] = []
equ_effect: list['EquEffect']
"""装备效果列表"""
equ_options: dict[str, int] = {}
equ_options: dict[str, int]
"""装备选项列表"""
EquEffectRatio = 1.0
"""装备效果倍率"""
@@ -148,6 +150,9 @@ class CharacterBase(CharacterProperty):
self.max_point = 0
self.skills = []
self.skills_dict = {}
self.skills_id_dict = {}
self.skills_uuid_dict = {}
self.skill_names_cache = {}
self.load_skills()
# region 角色属性设置
@@ -285,7 +290,7 @@ class CharacterBase(CharacterProperty):
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:
def AddSkillLv(self, min: int, max: int, lv: int, type=-1, exceptSkills: tuple[str, ...] = ()) -> None:
"""
增加技能等级
type: -1 全部, 0 被动, 1 主动
@@ -296,13 +301,13 @@ class CharacterBase(CharacterProperty):
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:
def SetSkillCD(self, min=1, max=100, cd=0, exclude: tuple[int, ...] = (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:
def SetSkillCDRecover(self, min=1, max=100, cd=0, exclude: tuple[int, ...] = (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:
@@ -330,17 +335,18 @@ class CharacterBase(CharacterProperty):
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
return self.skills_id_dict.get(str(id), 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
return self.skills_uuid_dict.get(str(uuid), 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)]
key = (type, damage)
if key not in self.skill_names_cache:
self.skill_names_cache[key] = [skill.name for skill in self.skills if (type == 'all' or skill.type == type) and (damage == 'all' or skill.damage == damage)]
return self.skill_names_cache[key]
def GetWeaponType(self) -> tuple[str, str]:
"""获取武器类型"""
+55 -42
View File
@@ -1,4 +1,5 @@
import sys
from functools import cache
from uuid import uuid1
from core.basic.equipment import OathSuit, Suit, get_equipment
@@ -7,6 +8,16 @@ from ..roleinfo import CharacterEmblemInfo, CharacterEquipInfo, CharacterOathInf
from .base import CharacterBase
@cache
def get_skill_classes(module_name: str) -> tuple[type, ...]:
module = sys.modules[module_name]
return tuple(
memberClass
for name in dir(module)
if isinstance((memberClass := getattr(module, name)), type) and memberClass.__name__.startswith('Skill')
)
class CalcEquipMixin(CharacterBase):
"""装备计算、角色初始化相关方法"""
@@ -22,11 +33,12 @@ class CalcEquipMixin(CharacterBase):
info['emblems'] = {}
if info.get('oaths', None) is None:
info['oaths'] = {}
equs = get_equipment(self.equVersion)
for key in info['equips']:
self.charEquipInfo[key] = CharacterEquipInfo(info['equips'][key], self.equVersion, key)
self.charEquipInfo[key] = CharacterEquipInfo(info['equips'][key], self.equVersion, key, equs)
for key in info['oaths']:
# 导入誓约打造信息、誓约信息
self.charOathInfo.append(CharacterOathInfo(info['oaths'][key], self.equVersion, key))
self.charOathInfo.append(CharacterOathInfo(info['oaths'][key], self.equVersion, key, equs))
try:
# 异常处理 彩色等级自动取最小值
minEmblemLv = min([info['emblems'][key]['lv'] for key in ['红色', '蓝色', '绿色', '黄色']], default=1)
@@ -36,7 +48,7 @@ class CalcEquipMixin(CharacterBase):
info['emblems'][key]['part'] = key
self.charEmblemInfo.append(CharacterEmblemInfo(info['emblems'][key]))
pass
except Exception as e:
except Exception:
pass
self.charOathSkillId = info.get('oathSkill', 1)
@@ -59,13 +71,12 @@ class CalcEquipMixin(CharacterBase):
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)
for memberClass in get_skill_classes(self.moduleName):
skill = memberClass(char=self)
self.skills_dict[skill.name] = skill
self.skills_id_dict[str(skill.id)] = skill
self.skills_uuid_dict[str(skill.uuid)] = skill
self.skills.append(skill)
# endregion
@@ -77,27 +88,27 @@ class CalcEquipMixin(CharacterBase):
oathSuitInfo = {}
correction = 0
equs = get_equipment(self.equVersion)
for item in filter(lambda x: x.equInfo is not None, self.charEquipInfo.values()):
for item in self.charEquipInfo.values():
partEqu = item.equInfo
if partEqu is None:
continue
# 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 suit in partEqu.suit:
suit_item = suitInfo.setdefault(suit, {'point': 0, 'count': 0})
if partEqu.Point == 0:
suit_item['count'] += 1
else:
suit_item['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
if partOath is None:
continue
for suit in partOath.suit:
oath_suit_item = oathSuitInfo.setdefault(suit, {'point': 0, 'count': 0})
if partOath.Point == 0:
oath_suit_item['count'] += 1
else:
oath_suit_item['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]
@@ -140,17 +151,19 @@ class CalcEquipMixin(CharacterBase):
oathSuitList += equs.get_oath_suit_info(suit, oathSuitInfo[suit]['point'], 0)
if len(oathSuitList) == 0:
continue
oath_suit_by_suit_id = {item.suitId: item for item in oathSuitList}
for suit in suitList:
i = suit.id
func = equs.funs.execture(f'suit_{i}')
suit = next((x for x in equs.suits if str(x.id) == str(i)), None)
suit = equs.suit_id_dict.get(str(i), None)
if suit is None:
continue
# 誓约和套装进行匹配
# 如果存在誓约和套装是同一个套装
# 则直接不执行原套装效果,执行誓约套装增强的效果
oathEffect = next((x for x in oathSuitList if x.suitId == suit.suitId), None)
if suit is not None:
filtered_dict = {k: v for k, v in suit.__dict__.items() if k[0].isupper()}
self.SetStatus(**filtered_dict)
oathEffect = oath_suit_by_suit_id.get(suit.suitId, None)
filtered_dict = {k: v for k, v in suit.__dict__.items() if k[0].isupper()}
self.SetStatus(**filtered_dict)
if func is not None and oathEffect is None:
# print(f'套装 {suit.name} 生效')
func(self)
@@ -160,15 +173,15 @@ class CalcEquipMixin(CharacterBase):
self.max_point = 0 if res['suit'] is None else res.get('suit', {}).get('point', 0)
try:
self.oath_max_point = oathSuitInfo.get(max_point_oath_suit, {}).get('point', 0)
except:
except Exception:
self.oath_max_point = 0
self.oathSuitInfo = []
self.oathSkillInfo = []
# 当套装点数达到太初时,誓约技能生效
if self.max_point >= 2550:
oathSuit = next((x for x in oathSuitList if x.suitId == max_point_oath_suit), None)
oathSuit = oath_suit_by_suit_id.get(max_point_oath_suit, None)
if oathSuit is not None:
skills = list(filter(lambda x: x.suitId == oathSuit.suitId, oathSuit.skills))
skills = [x for x in oathSuit.skills if x.suitId == oathSuit.suitId]
skill = next((x for x in oathSuit.skills if str(x.skillId) == str(self.charOathSkillId)), None)
# 誓约套装效果生效
filtered_dict = {k: v for k, v in oathSuit.__dict__.items() if k[0].isupper()}
@@ -214,11 +227,11 @@ class CalcEquipMixin(CharacterBase):
"""计算装备基础效果、附魔"""
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]
for item in self.charEquipInfo.values():
equ = item.equInfo
if equ is None or equ.itemType == '副武器':
continue
enchat = detail[1]
enchat = item.enchant
fun = effects.execture(f'equ_{equ.id}')
if fun is None:
continue
@@ -316,20 +329,20 @@ class CalcEquipMixin(CharacterBase):
def calc_basic(self):
"""计算基础属性:防具精通、增幅、强化等"""
char_equip_info = self.charEquipInfo
for part in ['上衣', '头肩', '下装', '腰带', '鞋']:
cur = self.charEquipInfo[part]
cur = char_equip_info[part]
if cur.equInfo is None:
continue
equ = cur.equInfo
reinforce = self.charEquipInfo[part].reinforce
reinforce = cur.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]
for part, cur in char_equip_info.items():
if cur.equInfo is None:
continue
if cur.reinforceType == 1: