2023-05-02 03:10:53 +00:00
|
|
|
from itertools import chain
|
2023-05-02 10:20:27 +00:00
|
|
|
from typing import TypeVar
|
2023-04-29 14:59:16 +00:00
|
|
|
|
2023-05-02 10:20:27 +00:00
|
|
|
from model.avatar import (
|
|
|
|
AlternateSprint,
|
|
|
|
AvatarAttribute,
|
|
|
|
AvatarBirth,
|
|
|
|
AvatarInfo,
|
|
|
|
AvatarPromote,
|
|
|
|
AvatarStories,
|
|
|
|
ElementalBurst,
|
|
|
|
ElementalSkill,
|
|
|
|
NormalAttack,
|
|
|
|
Seuyu,
|
|
|
|
Story,
|
|
|
|
Talent,
|
|
|
|
TalentAttribute,
|
|
|
|
)
|
2023-05-02 03:10:53 +00:00
|
|
|
from model.enums import Association, AvatarQuality, Element, WeaponType
|
2023-05-02 10:20:27 +00:00
|
|
|
from model.other import ItemCount
|
2023-05-02 03:10:53 +00:00
|
|
|
from utils.const import PROJECT_ROOT
|
2023-04-29 14:59:16 +00:00
|
|
|
from utils.manager import ResourceManager
|
2023-05-02 03:10:53 +00:00
|
|
|
from utils.typedefs import Lang
|
|
|
|
|
2023-05-02 10:20:27 +00:00
|
|
|
try:
|
|
|
|
import regex as re
|
|
|
|
except ImportError:
|
|
|
|
import re
|
|
|
|
|
|
|
|
T = TypeVar("T", bound=Talent)
|
|
|
|
|
2023-05-02 03:10:53 +00:00
|
|
|
OUT_DIR = PROJECT_ROOT.joinpath("out")
|
|
|
|
|
|
|
|
elements = {
|
|
|
|
3057990932: Element.Cryo,
|
|
|
|
467004516: Element.Anemo,
|
|
|
|
821712868: Element.Null,
|
|
|
|
2480172868: Element.Electro,
|
|
|
|
4022324356: Element.Hydro,
|
|
|
|
627825788: Element.Pyro,
|
|
|
|
2596397668: Element.Dendro,
|
|
|
|
967031460: Element.Geo,
|
|
|
|
}
|
2023-04-29 14:59:16 +00:00
|
|
|
|
|
|
|
|
2023-05-02 03:10:53 +00:00
|
|
|
# noinspection PyShadowingBuiltins,SpellCheckingInspection
|
2023-04-29 14:59:16 +00:00
|
|
|
async def parse_avatar_data(lang: Lang):
|
2023-05-02 03:10:53 +00:00
|
|
|
out_path = OUT_DIR.joinpath(f"{lang}")
|
|
|
|
out_path.mkdir(exist_ok=True, parents=True)
|
|
|
|
|
|
|
|
manager = ResourceManager(lang=lang)
|
|
|
|
avatar_json_data = manager.fetch("AvatarExcelConfigData")
|
|
|
|
fetter_info_json_data = manager.fetch("FetterInfoExcelConfigData")
|
|
|
|
story_json_data = manager.fetch("FetterStoryExcelConfigData")
|
2023-05-02 10:20:27 +00:00
|
|
|
promote_json_data = manager.fetch("AvatarPromoteExcelConfigData")
|
|
|
|
|
|
|
|
skill_depot_json_data = manager.fetch("AvatarSkillDepotExcelConfigData")
|
|
|
|
skill_json_data = manager.fetch("AvatarSkillExcelConfigData")
|
|
|
|
proud_skill_json_data = manager.fetch("ProudSkillExcelConfigData")
|
2023-05-02 03:10:53 +00:00
|
|
|
|
|
|
|
avatar_list = []
|
|
|
|
for data in avatar_json_data:
|
|
|
|
id = data["id"]
|
|
|
|
if (
|
|
|
|
info_data := next(
|
|
|
|
chain(
|
|
|
|
filter(lambda x: x["avatarId"] == id, fetter_info_json_data),
|
|
|
|
[
|
|
|
|
None,
|
|
|
|
],
|
|
|
|
)
|
|
|
|
)
|
|
|
|
) is None:
|
|
|
|
continue
|
|
|
|
name = manager.get_text(data["nameTextMapHash"])
|
|
|
|
element = elements[info_data["avatarVisionBeforTextMapHash"]]
|
|
|
|
quality = AvatarQuality(data["qualityType"].removeprefix("QUALITY_"))
|
|
|
|
weapon_type = next(
|
|
|
|
filter(lambda x: x in data["weaponType"], WeaponType.__members__.values())
|
|
|
|
)
|
|
|
|
|
2023-05-02 10:20:27 +00:00
|
|
|
# 角色信息
|
2023-05-02 03:10:53 +00:00
|
|
|
title = manager.get_text(info_data["avatarTitleTextMapHash"])
|
|
|
|
birth = AvatarBirth(
|
|
|
|
month=info_data["infoBirthMonth"], day=info_data["infoBirthDay"]
|
|
|
|
)
|
|
|
|
occupation = manager.get_text(info_data["avatarNativeTextMapHash"])
|
|
|
|
vision = manager.get_text(info_data["avatarVisionBeforTextMapHash"])
|
|
|
|
constellation = manager.get_text(
|
|
|
|
info_data["avatarConstellationBeforTextMapHash"]
|
|
|
|
)
|
|
|
|
description = manager.get_text(info_data["avatarDetailTextMapHash"])
|
|
|
|
association = Association(
|
|
|
|
info_data["avatarAssocType"].removeprefix("ASSOC_TYPE_")
|
|
|
|
)
|
|
|
|
seuyu = Seuyu(
|
|
|
|
cn=manager.get_text(info_data["cvChineseTextMapHash"]),
|
|
|
|
jp=manager.get_text(info_data["cvJapaneseTextMapHash"]),
|
|
|
|
en=manager.get_text(info_data["cvEnglishTextMapHash"]),
|
|
|
|
kr=manager.get_text(info_data["cvKoreanTextMapHash"]),
|
|
|
|
)
|
|
|
|
story_data = sorted(
|
|
|
|
filter(lambda x: x["avatarId"] == id, story_json_data),
|
|
|
|
key=lambda x: x["fetterId"],
|
|
|
|
)
|
|
|
|
stories = AvatarStories(
|
|
|
|
**{
|
|
|
|
i[0]: i[1]
|
|
|
|
for i in zip(
|
|
|
|
AvatarStories.__fields__.keys(),
|
|
|
|
map(
|
|
|
|
lambda x: Story(
|
|
|
|
title=manager.get_text(x["storyTitleTextMapHash"]),
|
|
|
|
content=manager.get_text(x["storyContextTextMapHash"]),
|
|
|
|
tips=list(
|
|
|
|
filter(
|
|
|
|
lambda y: y is not None,
|
|
|
|
map(
|
|
|
|
lambda z: manager.get_text(z),
|
|
|
|
x["tips"],
|
|
|
|
),
|
|
|
|
)
|
|
|
|
),
|
|
|
|
),
|
|
|
|
sorted(
|
|
|
|
filter(lambda x: x["avatarId"] == id, story_data),
|
|
|
|
key=lambda x: x["fetterId"],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
)
|
|
|
|
information = AvatarInfo(
|
|
|
|
title=title,
|
|
|
|
birth=birth,
|
|
|
|
occupation=occupation,
|
|
|
|
vision=vision,
|
|
|
|
constellation=constellation,
|
|
|
|
description=description,
|
|
|
|
association=association,
|
|
|
|
seuyu=seuyu,
|
|
|
|
stories=stories,
|
|
|
|
)
|
|
|
|
|
2023-05-02 10:20:27 +00:00
|
|
|
# 角色基础属性
|
|
|
|
attribute = AvatarAttribute(
|
|
|
|
HP=data["hpBase"],
|
|
|
|
Attack=data["attackBase"],
|
|
|
|
Defense=data["defenseBase"],
|
|
|
|
Critical=data["critical"],
|
|
|
|
CriticalDamage=data["criticalHurt"],
|
|
|
|
ChargeEfficiency=data["chargeEfficiency"],
|
|
|
|
)
|
|
|
|
|
|
|
|
def get_skill_attributes(proud_skill_group_id: int) -> list[TalentAttribute]:
|
|
|
|
proud_skill_datas = sorted(
|
|
|
|
filter(
|
|
|
|
lambda x: x["proudSkillGroupId"] == proud_skill_group_id,
|
|
|
|
proud_skill_json_data,
|
|
|
|
),
|
|
|
|
key=lambda x: x["level"],
|
|
|
|
)
|
|
|
|
result: list[TalentAttribute] = []
|
|
|
|
for proud_skill_data in proud_skill_datas:
|
|
|
|
param_descriptions = list(
|
|
|
|
filter(
|
|
|
|
lambda x: x is not None,
|
|
|
|
map(
|
|
|
|
lambda x: manager.get_text(x),
|
|
|
|
proud_skill_data["paramDescList"],
|
|
|
|
),
|
|
|
|
)
|
|
|
|
)
|
|
|
|
param_num = len(param_descriptions)
|
|
|
|
for param_description in param_descriptions:
|
|
|
|
param_num = max(
|
|
|
|
param_num,
|
|
|
|
*map(int, re.findall(r"param(\d*)\:", param_description)),
|
|
|
|
)
|
|
|
|
result.append(
|
|
|
|
TalentAttribute(
|
|
|
|
level=proud_skill_data["level"],
|
|
|
|
param_descriptions=param_descriptions,
|
|
|
|
param_list=proud_skill_data["paramList"][:param_num],
|
|
|
|
break_level=proud_skill_data.get("breakLevel", 0),
|
|
|
|
coin=proud_skill_data.get("coinCost", 0),
|
|
|
|
cost_items=list(
|
|
|
|
map(
|
|
|
|
lambda x: ItemCount(
|
|
|
|
item_id=x["id"],
|
|
|
|
count=x["count"],
|
|
|
|
),
|
|
|
|
filter(lambda x: x, proud_skill_data["costItems"]),
|
|
|
|
)
|
|
|
|
),
|
|
|
|
)
|
|
|
|
)
|
|
|
|
return result
|
|
|
|
|
|
|
|
def parse_skill(skill_id: int, skill_cls: type[T]) -> T:
|
|
|
|
skill_data = next(filter(lambda x: x["id"] == skill_id, skill_json_data))
|
|
|
|
_name = manager.get_text(skill_data["nameTextMapHash"])
|
|
|
|
_description = manager.get_text(skill_data["descTextMapHash"])
|
|
|
|
icon = skill_data["skillIcon"]
|
|
|
|
cooldown = (
|
|
|
|
skill_data.get("cdTime", 0)
|
|
|
|
if "cooldown" in skill_cls.__fields__.keys()
|
|
|
|
else None
|
|
|
|
)
|
|
|
|
attributes = get_skill_attributes(skill_data["proudSkillGroupId"])
|
|
|
|
return skill_cls(
|
|
|
|
**{
|
|
|
|
i[0]: i[1]
|
|
|
|
for i in zip(
|
|
|
|
["name", "description", "icon", "cooldown", "attributes"],
|
|
|
|
[_name, _description, icon, cooldown, attributes],
|
|
|
|
)
|
|
|
|
if i is not None
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
# 天赋
|
|
|
|
skill_depot_data = next(
|
|
|
|
filter(lambda x: x["id"] == data["skillDepotId"], skill_depot_json_data)
|
|
|
|
)
|
|
|
|
skill_ids = list(filter(lambda x: x != 0, skill_depot_data["skills"]))
|
|
|
|
# 普通攻击
|
|
|
|
normal_attack = parse_skill(skill_ids[0], NormalAttack)
|
|
|
|
# 元素战技
|
|
|
|
elemental_skill = parse_skill(skill_ids[1], ElementalSkill)
|
|
|
|
# 冲刺技能
|
|
|
|
if len(skill_ids) == 3:
|
|
|
|
alternate_sprint = parse_skill(skill_ids[2], AlternateSprint)
|
|
|
|
# 元素爆发
|
|
|
|
burst_skill = parse_skill(skill_depot_data["energySkill"], ElementalBurst)
|
|
|
|
breakpoint()
|
|
|
|
|
|
|
|
# 角色突破数据
|
|
|
|
promote_id = data["avatarPromoteId"]
|
|
|
|
promote_datas = sorted(
|
|
|
|
filter(lambda x: x["avatarPromoteId"] == promote_id, promote_json_data),
|
|
|
|
key=lambda x: x.get("promoteLevel", 0),
|
|
|
|
)
|
|
|
|
promotes = []
|
|
|
|
for promote_data in promote_datas:
|
|
|
|
items = []
|
|
|
|
for item_data in promote_data["costItems"]:
|
|
|
|
if item_data:
|
|
|
|
items.append(
|
|
|
|
ItemCount(item_id=item_data["id"], count=item_data["count"])
|
|
|
|
)
|
|
|
|
promotes.append(
|
|
|
|
AvatarPromote(
|
|
|
|
promote_level=promote_data.get("promoteLevel", 0),
|
|
|
|
max_level=promote_data["unlockMaxLevel"],
|
|
|
|
coin=promote_data.get("scoinCost", 0),
|
|
|
|
cost_items=items,
|
|
|
|
)
|
|
|
|
)
|
2023-05-02 03:10:53 +00:00
|
|
|
breakpoint()
|