mirror of
https://github.com/PaiGramTeam/genshin-wiki.git
synced 2024-11-24 09:15:16 +00:00
🐛 fix some bugs
This commit is contained in:
parent
7cb30c4b04
commit
ea67d86f4b
@ -1,12 +1,8 @@
|
|||||||
from typing import TYPE_CHECKING
|
from model.avatar._talente import AvatarTalents
|
||||||
|
|
||||||
from model.enums import Association, AvatarQuality, Element, WeaponType
|
from model.enums import Association, AvatarQuality, Element, WeaponType
|
||||||
from model.other import ItemCount
|
from model.other import ItemCount
|
||||||
from utils.model import BaseModel
|
from utils.model import BaseModel
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from model.avatar._talente import AvatarTalents
|
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
"Avatar",
|
"Avatar",
|
||||||
"AvatarBirth",
|
"AvatarBirth",
|
||||||
@ -74,17 +70,17 @@ class AvatarStories(BaseModel):
|
|||||||
story_5: Story
|
story_5: Story
|
||||||
"""角色故事5"""
|
"""角色故事5"""
|
||||||
|
|
||||||
miscellaneous: Story
|
miscellaneous: Story | None = None
|
||||||
"""角色杂谈"""
|
"""角色杂谈"""
|
||||||
|
|
||||||
vision: Story
|
vision: Story | None = None
|
||||||
"""神之眼"""
|
"""神之眼"""
|
||||||
|
|
||||||
|
|
||||||
class AvatarInfo(BaseModel):
|
class AvatarInfo(BaseModel):
|
||||||
title: str
|
title: str | None
|
||||||
"""称号"""
|
"""称号"""
|
||||||
birth: AvatarBirth
|
birth: AvatarBirth | None
|
||||||
"""生日"""
|
"""生日"""
|
||||||
occupation: str
|
occupation: str
|
||||||
"""所属"""
|
"""所属"""
|
||||||
@ -123,6 +119,8 @@ class AvatarConstellation(BaseModel):
|
|||||||
"""命座描述"""
|
"""命座描述"""
|
||||||
icon: str
|
icon: str
|
||||||
"""命座图标"""
|
"""命座图标"""
|
||||||
|
param_list: list[float]
|
||||||
|
"""命座数据参数列表"""
|
||||||
|
|
||||||
|
|
||||||
class AvatarAttribute(BaseModel):
|
class AvatarAttribute(BaseModel):
|
||||||
@ -177,7 +175,7 @@ class Avatar(BaseModel):
|
|||||||
"""角色信息"""
|
"""角色信息"""
|
||||||
attributes: AvatarAttribute
|
attributes: AvatarAttribute
|
||||||
"""角色基础属性"""
|
"""角色基础属性"""
|
||||||
talents: "AvatarTalents"
|
talents: AvatarTalents
|
||||||
"""角色天赋信息"""
|
"""角色天赋信息"""
|
||||||
promotes: list[AvatarPromote]
|
promotes: list[AvatarPromote]
|
||||||
"""角色突破数据"""
|
"""角色突破数据"""
|
||||||
|
@ -112,16 +112,16 @@ class AvatarTalents(BaseModel):
|
|||||||
|
|
||||||
normal_attack: NormalAttack
|
normal_attack: NormalAttack
|
||||||
"""普通攻击"""
|
"""普通攻击"""
|
||||||
elemental_skill: ElementalSkill
|
elemental_skill: ElementalSkill | None
|
||||||
"""元素战技"""
|
"""元素战技"""
|
||||||
elemental_burst: ElementalBurst
|
elemental_burst: ElementalBurst | None
|
||||||
"""元素爆发"""
|
"""元素爆发"""
|
||||||
alternate_sprint: AlternateSprint | None = None
|
alternate_sprint: AlternateSprint | None = None
|
||||||
"""冲刺技能"""
|
"""冲刺技能"""
|
||||||
|
|
||||||
first_ascension_passive: FirstAscensionPassive
|
first_ascension_passive: FirstAscensionPassive | None
|
||||||
"""第一次突破固有天赋"""
|
"""第一次突破固有天赋"""
|
||||||
fourth_ascension_passive: FourthAscensionPassive
|
fourth_ascension_passive: FourthAscensionPassive | None
|
||||||
"""第四次突破固有天赋"""
|
"""第四次突破固有天赋"""
|
||||||
utility_passive: UtilityPassive | None = None
|
utility_passive: UtilityPassive | None = None
|
||||||
"""实用固有天赋"""
|
"""实用固有天赋"""
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
from itertools import chain
|
from itertools import chain
|
||||||
from typing import TypeVar
|
from typing import TypeVar
|
||||||
|
|
||||||
|
import ujson as json
|
||||||
|
from aiofiles import open as async_open
|
||||||
|
|
||||||
from model.avatar import (
|
from model.avatar import (
|
||||||
AlternateSprint,
|
AlternateSprint,
|
||||||
|
Avatar,
|
||||||
AvatarAttribute,
|
AvatarAttribute,
|
||||||
AvatarBirth,
|
AvatarBirth,
|
||||||
|
AvatarConstellation,
|
||||||
AvatarInfo,
|
AvatarInfo,
|
||||||
AvatarPromote,
|
AvatarPromote,
|
||||||
AvatarStories,
|
AvatarStories,
|
||||||
@ -26,6 +31,7 @@ from model.avatar import (
|
|||||||
from model.enums import Association, AvatarQuality, Element, WeaponType
|
from model.enums import Association, AvatarQuality, Element, WeaponType
|
||||||
from model.other import ItemCount
|
from model.other import ItemCount
|
||||||
from utils.const import PROJECT_ROOT
|
from utils.const import PROJECT_ROOT
|
||||||
|
from utils.funcs import remove_rich_tag
|
||||||
from utils.manager import ResourceManager
|
from utils.manager import ResourceManager
|
||||||
from utils.typedefs import Lang
|
from utils.typedefs import Lang
|
||||||
|
|
||||||
@ -38,20 +44,184 @@ TalentType = TypeVar("TalentType", bound=Talent)
|
|||||||
|
|
||||||
OUT_DIR = PROJECT_ROOT.joinpath("out")
|
OUT_DIR = PROJECT_ROOT.joinpath("out")
|
||||||
|
|
||||||
elements = {
|
elements_map = {
|
||||||
3057990932: Element.Cryo,
|
(
|
||||||
467004516: Element.Anemo,
|
230082676,
|
||||||
821712868: Element.Null,
|
313529204,
|
||||||
2480172868: Element.Electro,
|
627825788,
|
||||||
4022324356: Element.Hydro,
|
1247335084,
|
||||||
627825788: Element.Pyro,
|
1646245548,
|
||||||
2596397668: Element.Dendro,
|
1740638908,
|
||||||
967031460: Element.Geo,
|
3105283268,
|
||||||
|
3112476852,
|
||||||
|
3177381772,
|
||||||
|
3847511308,
|
||||||
|
): Element.Pyro,
|
||||||
|
(
|
||||||
|
321258364,
|
||||||
|
483165900,
|
||||||
|
756679372,
|
||||||
|
1688473500,
|
||||||
|
2480954540,
|
||||||
|
3228108484,
|
||||||
|
3400532572,
|
||||||
|
3646588372,
|
||||||
|
4022324356,
|
||||||
|
): Element.Hydro,
|
||||||
|
(
|
||||||
|
126875444,
|
||||||
|
467004516,
|
||||||
|
550531300,
|
||||||
|
898621369,
|
||||||
|
1778251796,
|
||||||
|
2075460644,
|
||||||
|
2477900860,
|
||||||
|
2648184060,
|
||||||
|
): Element.Anemo,
|
||||||
|
(
|
||||||
|
122554396,
|
||||||
|
608089036,
|
||||||
|
689445588,
|
||||||
|
1072755468,
|
||||||
|
1821644548,
|
||||||
|
1843086100,
|
||||||
|
2085306033,
|
||||||
|
2143937940,
|
||||||
|
2480172868,
|
||||||
|
2689029804,
|
||||||
|
3352621156,
|
||||||
|
4219874220,
|
||||||
|
): Element.Electro,
|
||||||
|
(2161032364, 4017448612): Element.Dendro,
|
||||||
|
(
|
||||||
|
98482612,
|
||||||
|
766902996,
|
||||||
|
862088588,
|
||||||
|
1480674860,
|
||||||
|
1695600284,
|
||||||
|
2778487532,
|
||||||
|
2809830820,
|
||||||
|
3057990932,
|
||||||
|
4127670180,
|
||||||
|
4220569804,
|
||||||
|
): Element.Cryo,
|
||||||
|
(
|
||||||
|
825986772,
|
||||||
|
967031460,
|
||||||
|
1016213980,
|
||||||
|
1662907292,
|
||||||
|
2507042785,
|
||||||
|
3219124204,
|
||||||
|
3617274620,
|
||||||
|
3929787020,
|
||||||
|
): Element.Geo,
|
||||||
|
(471154292, 821712868, 1128382182, 3053155130, 4168416172): Element.Null,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# noinspection PyShadowingBuiltins,SpellCheckingInspection
|
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[CombatTalent]) -> CombatTalent:
|
||||||
|
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__ 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
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_passive_talent(
|
||||||
|
talent_data: dict, talent_cls: type[PassiveTalent]
|
||||||
|
) -> PassiveTalent:
|
||||||
|
group_id = talent_data["proudSkillGroupId"]
|
||||||
|
_promote_level = talent_data.get("needAvatarPromoteLevel", 0)
|
||||||
|
skill_data = next(
|
||||||
|
filter(lambda x: x["proudSkillGroupId"] == group_id, proud_skill_json_data)
|
||||||
|
)
|
||||||
|
param_descriptions = list(
|
||||||
|
filter(
|
||||||
|
lambda x: x is not None,
|
||||||
|
map(
|
||||||
|
lambda x: manager.get_text(x),
|
||||||
|
skill_data["paramDescList"],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
_description = manager.get_text(skill_data["descTextMapHash"])
|
||||||
|
_param_list = skill_data["paramList"][
|
||||||
|
: len(re.findall(r"(\d+(?:\.)?\d+)", remove_rich_tag(_description) or ""))
|
||||||
|
]
|
||||||
|
return talent_cls(
|
||||||
|
name=manager.get_text(skill_data["nameTextMapHash"]) or "",
|
||||||
|
description=_description or "",
|
||||||
|
icon=skill_data["icon"],
|
||||||
|
promote_level=_promote_level,
|
||||||
|
attribute=TalentAttribute(
|
||||||
|
param_descriptions=param_descriptions,
|
||||||
|
param_list=_param_list,
|
||||||
|
break_level=skill_data.get("breakLevel", 0),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyShadowingBuiltins,SpellCheckingInspection,PyGlobalUndefined
|
||||||
async def parse_avatar_data(lang: Lang):
|
async def parse_avatar_data(lang: Lang):
|
||||||
|
global out_path, manager
|
||||||
|
global avatar_json_data, fetter_info_json_data, story_json_data, promote_json_data
|
||||||
|
global skill_depot_json_data, skill_json_data, proud_skill_json_data, talent_json_data
|
||||||
out_path = OUT_DIR.joinpath(f"{lang}")
|
out_path = OUT_DIR.joinpath(f"{lang}")
|
||||||
out_path.mkdir(exist_ok=True, parents=True)
|
out_path.mkdir(exist_ok=True, parents=True)
|
||||||
|
|
||||||
@ -64,6 +234,7 @@ async def parse_avatar_data(lang: Lang):
|
|||||||
skill_depot_json_data = manager.fetch("AvatarSkillDepotExcelConfigData")
|
skill_depot_json_data = manager.fetch("AvatarSkillDepotExcelConfigData")
|
||||||
skill_json_data = manager.fetch("AvatarSkillExcelConfigData")
|
skill_json_data = manager.fetch("AvatarSkillExcelConfigData")
|
||||||
proud_skill_json_data = manager.fetch("ProudSkillExcelConfigData")
|
proud_skill_json_data = manager.fetch("ProudSkillExcelConfigData")
|
||||||
|
talent_json_data = manager.fetch("AvatarTalentExcelConfigData")
|
||||||
|
|
||||||
avatar_list = []
|
avatar_list = []
|
||||||
for data in avatar_json_data:
|
for data in avatar_json_data:
|
||||||
@ -71,25 +242,36 @@ async def parse_avatar_data(lang: Lang):
|
|||||||
if (
|
if (
|
||||||
info_data := next(
|
info_data := next(
|
||||||
chain(
|
chain(
|
||||||
filter(lambda x: x["avatarId"] == id, fetter_info_json_data),
|
filter(lambda x: x["avatarId"] == id, fetter_info_json_data), [None]
|
||||||
[
|
|
||||||
None,
|
|
||||||
],
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
) is None:
|
) is None:
|
||||||
continue
|
continue
|
||||||
name = manager.get_text(data["nameTextMapHash"])
|
name = manager.get_text(data["nameTextMapHash"])
|
||||||
element = elements[info_data["avatarVisionBeforTextMapHash"]]
|
element = next(
|
||||||
quality = AvatarQuality(data["qualityType"].removeprefix("QUALITY_"))
|
filter(
|
||||||
|
lambda x: info_data["avatarVisionBeforTextMapHash"] in x[0],
|
||||||
|
elements_map.items(),
|
||||||
|
)
|
||||||
|
)[1]
|
||||||
|
quality = AvatarQuality(
|
||||||
|
data["qualityType"].removeprefix("QUALITY_").replace("ORANGE_SP", "SPECIAL")
|
||||||
|
)
|
||||||
weapon_type = next(
|
weapon_type = next(
|
||||||
filter(lambda x: x in data["weaponType"], WeaponType.__members__.values())
|
filter(
|
||||||
|
lambda x: x in data["weaponType"].replace("POLE", "POLEARM"),
|
||||||
|
WeaponType.__members__.values(),
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
# 角色信息
|
# 角色信息
|
||||||
title = manager.get_text(info_data["avatarTitleTextMapHash"])
|
title = manager.get_text(info_data["avatarTitleTextMapHash"])
|
||||||
birth = AvatarBirth(
|
birth = (
|
||||||
month=info_data["infoBirthMonth"], day=info_data["infoBirthDay"]
|
AvatarBirth(
|
||||||
|
month=info_data["infoBirthMonth"], day=info_data["infoBirthDay"]
|
||||||
|
)
|
||||||
|
if id not in [10000005, 10000007]
|
||||||
|
else None
|
||||||
)
|
)
|
||||||
occupation = manager.get_text(info_data["avatarNativeTextMapHash"])
|
occupation = manager.get_text(info_data["avatarNativeTextMapHash"])
|
||||||
vision = manager.get_text(info_data["avatarVisionBeforTextMapHash"])
|
vision = manager.get_text(info_data["avatarVisionBeforTextMapHash"])
|
||||||
@ -106,36 +288,30 @@ async def parse_avatar_data(lang: Lang):
|
|||||||
en=manager.get_text(info_data["cvEnglishTextMapHash"]),
|
en=manager.get_text(info_data["cvEnglishTextMapHash"]),
|
||||||
kr=manager.get_text(info_data["cvKoreanTextMapHash"]),
|
kr=manager.get_text(info_data["cvKoreanTextMapHash"]),
|
||||||
)
|
)
|
||||||
story_data = sorted(
|
story_datas = sorted(
|
||||||
filter(lambda x: x["avatarId"] == id, story_json_data),
|
filter(lambda x: x["avatarId"] == id, story_json_data),
|
||||||
key=lambda x: x["fetterId"],
|
key=lambda x: x["fetterId"],
|
||||||
)
|
)
|
||||||
stories = AvatarStories(
|
stories = []
|
||||||
**{
|
for story_data in sorted(
|
||||||
i[0]: i[1]
|
filter(lambda x: x["avatarId"] == id, story_datas),
|
||||||
for i in zip(
|
key=lambda x: x["fetterId"],
|
||||||
AvatarStories.__fields__.keys(),
|
):
|
||||||
map(
|
tips = list(
|
||||||
lambda x: Story(
|
filter(
|
||||||
title=manager.get_text(x["storyTitleTextMapHash"]),
|
lambda x: x is not None,
|
||||||
content=manager.get_text(x["storyContextTextMapHash"]),
|
map(lambda x: manager.get_text(x), story_data["tips"]),
|
||||||
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"],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
}
|
)
|
||||||
|
story = Story(
|
||||||
|
title=manager.get_text(story_data["storyTitleTextMapHash"]),
|
||||||
|
content=manager.get_text(story_data["storyContextTextMapHash"]),
|
||||||
|
tips=tips,
|
||||||
|
)
|
||||||
|
stories.append(story)
|
||||||
|
|
||||||
|
avatar_stories = AvatarStories(
|
||||||
|
**{i[0]: i[1] for i in zip(AvatarStories.__fields__, stories)}
|
||||||
)
|
)
|
||||||
information = AvatarInfo(
|
information = AvatarInfo(
|
||||||
title=title,
|
title=title,
|
||||||
@ -146,11 +322,11 @@ async def parse_avatar_data(lang: Lang):
|
|||||||
description=description,
|
description=description,
|
||||||
association=association,
|
association=association,
|
||||||
seuyu=seuyu,
|
seuyu=seuyu,
|
||||||
stories=stories,
|
stories=avatar_stories,
|
||||||
)
|
)
|
||||||
|
|
||||||
# 角色基础属性
|
# 角色基础属性
|
||||||
attribute = AvatarAttribute(
|
attributes = AvatarAttribute(
|
||||||
HP=data["hpBase"],
|
HP=data["hpBase"],
|
||||||
Attack=data["attackBase"],
|
Attack=data["attackBase"],
|
||||||
Defense=data["defenseBase"],
|
Defense=data["defenseBase"],
|
||||||
@ -159,117 +335,6 @@ async def parse_avatar_data(lang: Lang):
|
|||||||
ChargeEfficiency=data["chargeEfficiency"],
|
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[CombatTalent]) -> CombatTalent:
|
|
||||||
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
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
def parse_passive_talent(
|
|
||||||
talent_data: dict, talent_cls: type[PassiveTalent]
|
|
||||||
) -> PassiveTalent:
|
|
||||||
group_id = talent_data["proudSkillGroupId"]
|
|
||||||
_promote_level = talent_data.get("needAvatarPromoteLevel", 0)
|
|
||||||
skill_data = next(
|
|
||||||
filter(
|
|
||||||
lambda x: x["proudSkillGroupId"] == group_id, proud_skill_json_data
|
|
||||||
)
|
|
||||||
)
|
|
||||||
param_descriptions = list(
|
|
||||||
filter(
|
|
||||||
lambda x: x is not None,
|
|
||||||
map(
|
|
||||||
lambda x: manager.get_text(x),
|
|
||||||
skill_data["paramDescList"],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
_description = manager.get_text(skill_data["descTextMapHash"])
|
|
||||||
_param_list = skill_data["paramList"][
|
|
||||||
: len(
|
|
||||||
re.findall(
|
|
||||||
r"(\d+)|(?:(\d+)%)|(?:(\d+\.\d+))",
|
|
||||||
re.sub(
|
|
||||||
r"(<(?P<tag_name>[a-z]+?)=(?P<value>.+?)>.+</(?P=tag_name)>)",
|
|
||||||
"",
|
|
||||||
_description,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
]
|
|
||||||
return talent_cls(
|
|
||||||
name=manager.get_text(skill_data["nameTextMapHash"]),
|
|
||||||
description=_description,
|
|
||||||
icon=skill_data["icon"],
|
|
||||||
promote_level=_promote_level,
|
|
||||||
attribute=TalentAttribute(
|
|
||||||
param_descriptions=param_descriptions,
|
|
||||||
param_list=_param_list,
|
|
||||||
break_level=skill_data.get("breakLevel", 0),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
# 天赋
|
# 天赋
|
||||||
skill_depot_data = next(
|
skill_depot_data = next(
|
||||||
filter(lambda x: x["id"] == data["skillDepotId"], skill_depot_json_data)
|
filter(lambda x: x["id"] == data["skillDepotId"], skill_depot_json_data)
|
||||||
@ -278,36 +343,47 @@ async def parse_avatar_data(lang: Lang):
|
|||||||
# 普通攻击
|
# 普通攻击
|
||||||
normal_attack = parse_skill(skill_ids[0], NormalAttack)
|
normal_attack = parse_skill(skill_ids[0], NormalAttack)
|
||||||
# 元素战技
|
# 元素战技
|
||||||
elemental_skill = parse_skill(skill_ids[1], ElementalSkill)
|
elemental_skill = (
|
||||||
|
parse_skill(skill_ids[1], ElementalSkill)
|
||||||
|
if id not in [10000005, 10000007]
|
||||||
|
else None
|
||||||
|
)
|
||||||
# 冲刺技能
|
# 冲刺技能
|
||||||
alternate_sprint = (
|
alternate_sprint = (
|
||||||
parse_skill(skill_ids[2], AlternateSprint) if len(skill_ids) == 3 else None
|
parse_skill(skill_ids[2], AlternateSprint) if len(skill_ids) == 3 else None
|
||||||
)
|
)
|
||||||
# 元素爆发
|
# 元素爆发
|
||||||
burst_skill = parse_skill(skill_depot_data["energySkill"], ElementalBurst)
|
burst_skill = (
|
||||||
|
parse_skill(skill_depot_data["energySkill"], ElementalBurst)
|
||||||
|
if id not in [10000005, 10000007]
|
||||||
|
else None
|
||||||
|
)
|
||||||
# 第一次突破被动天赋
|
# 第一次突破被动天赋
|
||||||
first_passive = parse_passive_talent(
|
first_passive = (
|
||||||
skill_depot_data["inherentProudSkillOpens"][0], FirstAscensionPassive
|
parse_passive_talent(
|
||||||
|
skill_depot_data["inherentProudSkillOpens"][0], FirstAscensionPassive
|
||||||
|
)
|
||||||
|
if id not in [10000005, 10000007]
|
||||||
|
else None
|
||||||
)
|
)
|
||||||
# 第四次突破被动天赋
|
# 第四次突破被动天赋
|
||||||
fourth_passive = parse_passive_talent(
|
fourth_passive = (
|
||||||
skill_depot_data["inherentProudSkillOpens"][1], FourthAscensionPassive
|
parse_passive_talent(
|
||||||
|
skill_depot_data["inherentProudSkillOpens"][1], FourthAscensionPassive
|
||||||
|
)
|
||||||
|
if id not in [10000005, 10000007]
|
||||||
|
else None
|
||||||
)
|
)
|
||||||
# 实用固有天赋
|
# 实用固有天赋
|
||||||
utility_passive = parse_passive_talent(
|
utility_passive = (
|
||||||
skill_depot_data["inherentProudSkillOpens"][2], UtilityPassive
|
parse_passive_talent(
|
||||||
|
skill_depot_data["inherentProudSkillOpens"][2], UtilityPassive
|
||||||
|
)
|
||||||
|
if id not in [10000005, 10000007]
|
||||||
|
else None
|
||||||
)
|
)
|
||||||
# 杂项固有天赋
|
# 杂项固有天赋
|
||||||
if (
|
if skill_depot_data["inherentProudSkillOpens"][3]:
|
||||||
len(
|
|
||||||
list(
|
|
||||||
filter(
|
|
||||||
lambda x: x != 0, skill_depot_data["inherentProudSkillOpens"]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
== 4
|
|
||||||
):
|
|
||||||
miscellaneous_passive = parse_passive_talent(
|
miscellaneous_passive = parse_passive_talent(
|
||||||
skill_depot_data["inherentProudSkillOpens"][3], MiscellaneousPassive
|
skill_depot_data["inherentProudSkillOpens"][3], MiscellaneousPassive
|
||||||
)
|
)
|
||||||
@ -335,7 +411,7 @@ async def parse_avatar_data(lang: Lang):
|
|||||||
for promote_data in promote_datas:
|
for promote_data in promote_datas:
|
||||||
items = []
|
items = []
|
||||||
for item_data in promote_data["costItems"]:
|
for item_data in promote_data["costItems"]:
|
||||||
if item_data:
|
if item_data and id not in [10000005, 10000007]:
|
||||||
items.append(
|
items.append(
|
||||||
ItemCount(item_id=item_data["id"], count=item_data["count"])
|
ItemCount(item_id=item_data["id"], count=item_data["count"])
|
||||||
)
|
)
|
||||||
@ -347,4 +423,47 @@ async def parse_avatar_data(lang: Lang):
|
|||||||
cost_items=items,
|
cost_items=items,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
breakpoint()
|
|
||||||
|
# 角色命座信息
|
||||||
|
constellations: list[AvatarConstellation] = []
|
||||||
|
for constellation_id in filter(lambda x: x != 0, skill_depot_data["talents"]):
|
||||||
|
constellation_data = next(
|
||||||
|
filter(lambda x: x["talentId"] == constellation_id, talent_json_data)
|
||||||
|
)
|
||||||
|
constellation_description = manager.get_text(
|
||||||
|
constellation_data["descTextMapHash"]
|
||||||
|
)
|
||||||
|
# noinspection PyTypeChecker
|
||||||
|
constellations.append(
|
||||||
|
AvatarConstellation(
|
||||||
|
name=manager.get_text(constellation_data["nameTextMapHash"]),
|
||||||
|
description=constellation_description,
|
||||||
|
icon=constellation_data["icon"],
|
||||||
|
param_list=list(
|
||||||
|
filter(lambda x: x != 0.0, constellation_data["paramList"])
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
avatar = Avatar(
|
||||||
|
id=id,
|
||||||
|
name=name,
|
||||||
|
element=element,
|
||||||
|
quality=quality,
|
||||||
|
weapon_type=weapon_type,
|
||||||
|
information=information,
|
||||||
|
attributes=attributes,
|
||||||
|
talents=avatar_talents,
|
||||||
|
promotes=promotes,
|
||||||
|
constellations=constellations,
|
||||||
|
)
|
||||||
|
avatar_list.append(avatar)
|
||||||
|
async with async_open(out_path / "avatar.json", encoding="utf-8", mode="w") as file:
|
||||||
|
await file.write(
|
||||||
|
json.dumps(
|
||||||
|
[i.dict() for i in avatar_list],
|
||||||
|
ensure_ascii=False,
|
||||||
|
encode_html_chars=False,
|
||||||
|
indent=4,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
return out_path, avatar_list
|
||||||
|
14
utils/funcs.py
Normal file
14
utils/funcs.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
try:
|
||||||
|
import regex as re
|
||||||
|
except ImportError:
|
||||||
|
import re
|
||||||
|
|
||||||
|
__all__ = ("remove_rich_tag",)
|
||||||
|
|
||||||
|
|
||||||
|
def remove_rich_tag(string: str | None) -> str:
|
||||||
|
"""去除富文本标签"""
|
||||||
|
if string is not None:
|
||||||
|
return re.sub(
|
||||||
|
r"(<(?P<tag_name>[a-z]+?)=(?P<value>.+?)>.+?</(?P=tag_name)>)", "", string
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user