mirror of
https://github.com/PaiGramTeam/genshin-wiki.git
synced 2024-11-21 22:58:02 +00:00
✨ add AddProp
attr for AvatarPromote
This commit is contained in:
parent
ea67d86f4b
commit
fa5c315d67
@ -1,5 +1,5 @@
|
||||
from model.avatar._talente import AvatarTalents
|
||||
from model.enums import Association, AvatarQuality, Element, WeaponType
|
||||
from model.enums import Association, AvatarQuality, Element, PropType, WeaponType
|
||||
from model.other import ItemCount
|
||||
from utils.model import BaseModel
|
||||
|
||||
@ -13,6 +13,7 @@ __all__ = (
|
||||
"Story",
|
||||
"Seuyu",
|
||||
"AvatarAttribute",
|
||||
"AddProp",
|
||||
)
|
||||
|
||||
|
||||
@ -98,11 +99,22 @@ class AvatarInfo(BaseModel):
|
||||
"""故事"""
|
||||
|
||||
|
||||
class AddProp(BaseModel):
|
||||
"""属性加成"""
|
||||
|
||||
type: PropType
|
||||
"""属性类型"""
|
||||
value: float
|
||||
"""属性值"""
|
||||
|
||||
|
||||
class AvatarPromote(BaseModel):
|
||||
promote_level: int = 0
|
||||
"""突破等级"""
|
||||
max_level: int
|
||||
"""解锁的等级上限"""
|
||||
add_props: list[AddProp] = []
|
||||
"""属性加成"""
|
||||
|
||||
coin: int = 0
|
||||
"""摩拉"""
|
||||
@ -134,28 +146,10 @@ class AvatarAttribute(BaseModel):
|
||||
"""防御力"""
|
||||
Critical: float
|
||||
"""暴击率"""
|
||||
CriticalDamage: float
|
||||
CriticalHurt: float
|
||||
"""暴击伤害"""
|
||||
ChargeEfficiency: float
|
||||
"""元素充能效率"""
|
||||
ElementalMastery: float = 0
|
||||
"""元素精通"""
|
||||
PhysicalAddHurt: float = 0
|
||||
"""物理伤害加成"""
|
||||
PyroAddHurt: float = 0
|
||||
"""火元素伤害加成"""
|
||||
HydroAddHurt: float = 0
|
||||
"""水元素伤害加成"""
|
||||
AnemoAddHurt: float = 0
|
||||
"""风元素伤害加成"""
|
||||
ElectroAddHurt: float = 0
|
||||
"""雷元素伤害加成"""
|
||||
DendroAddHurt: float = 0
|
||||
"""草元素伤害加成"""
|
||||
CryoAddHurt: float = 0
|
||||
"""冰元素伤害加成"""
|
||||
GeoAddHurt: float = 0
|
||||
"""岩元素伤害加成"""
|
||||
|
||||
|
||||
class Avatar(BaseModel):
|
||||
|
@ -21,22 +21,6 @@ __all__ = (
|
||||
)
|
||||
|
||||
|
||||
class TalentAttribute(BaseModel):
|
||||
level: int = 1
|
||||
"""等级"""
|
||||
param_descriptions: list[str] = []
|
||||
"""参数描述"""
|
||||
param_list: list[float] = []
|
||||
"""参数列表"""
|
||||
|
||||
break_level: int = 0
|
||||
"""所需突破等级"""
|
||||
coin: int = 0
|
||||
"""摩拉"""
|
||||
cost_items: list[ItemCount] = []
|
||||
"""消耗物品"""
|
||||
|
||||
|
||||
class Talent(BaseModel):
|
||||
name: str
|
||||
"""天赋名称"""
|
||||
@ -48,14 +32,29 @@ class Talent(BaseModel):
|
||||
"""解锁等级"""
|
||||
|
||||
|
||||
class TalentAttribute(BaseModel):
|
||||
level: int = 1
|
||||
"""等级"""
|
||||
params: list[float] = []
|
||||
"""参数数值"""
|
||||
|
||||
break_level: int = 0
|
||||
"""所需突破等级"""
|
||||
coin: int = 0
|
||||
"""摩拉"""
|
||||
cost_items: list[ItemCount] = []
|
||||
"""消耗物品"""
|
||||
|
||||
|
||||
class CombatTalent(Talent):
|
||||
"""战斗天赋"""
|
||||
|
||||
cooldown: float = 0
|
||||
"""冷却时间"""
|
||||
|
||||
param_descriptions: list[str] = []
|
||||
"""参数描述"""
|
||||
attributes: list[TalentAttribute]
|
||||
"""数值参数列表"""
|
||||
"""数值参数"""
|
||||
|
||||
|
||||
class NormalAttack(CombatTalent):
|
||||
|
@ -3,8 +3,10 @@ from typing import TypeVar
|
||||
|
||||
import ujson as json
|
||||
from aiofiles import open as async_open
|
||||
from humps import pascalize
|
||||
|
||||
from model.avatar import (
|
||||
AddProp,
|
||||
AlternateSprint,
|
||||
Avatar,
|
||||
AvatarAttribute,
|
||||
@ -28,7 +30,7 @@ from model.avatar import (
|
||||
TalentAttribute,
|
||||
UtilityPassive,
|
||||
)
|
||||
from model.enums import Association, AvatarQuality, Element, WeaponType
|
||||
from model.enums import Association, AvatarQuality, Element, PropType, WeaponType
|
||||
from model.other import ItemCount
|
||||
from utils.const import PROJECT_ROOT
|
||||
from utils.funcs import remove_rich_tag
|
||||
@ -117,9 +119,21 @@ elements_map = {
|
||||
): Element.Geo,
|
||||
(471154292, 821712868, 1128382182, 3053155130, 4168416172): Element.Null,
|
||||
}
|
||||
prop_type_map = {
|
||||
"Hp": PropType.HP,
|
||||
"RockAddHurt": PropType.Geo,
|
||||
"ElecAddHurt": PropType.Electro,
|
||||
"FireAddHurt": PropType.Pyro,
|
||||
"WaterAddHurt": PropType.Hydro,
|
||||
"IceAddHurt": PropType.Cryo,
|
||||
"WindAddHurt": PropType.Anemo,
|
||||
"GrassAddHurt": PropType.Dendro,
|
||||
}
|
||||
|
||||
|
||||
def get_skill_attributes(proud_skill_group_id: int) -> list[TalentAttribute]:
|
||||
def get_skill_attributes(
|
||||
proud_skill_group_id: int,
|
||||
) -> tuple[list[TalentAttribute], list[str]]:
|
||||
proud_skill_datas = sorted(
|
||||
filter(
|
||||
lambda x: x["proudSkillGroupId"] == proud_skill_group_id,
|
||||
@ -128,6 +142,7 @@ def get_skill_attributes(proud_skill_group_id: int) -> list[TalentAttribute]:
|
||||
key=lambda x: x["level"],
|
||||
)
|
||||
result: list[TalentAttribute] = []
|
||||
param_descriptions: list[str] = []
|
||||
for proud_skill_data in proud_skill_datas:
|
||||
param_descriptions = list(
|
||||
filter(
|
||||
@ -147,8 +162,7 @@ def get_skill_attributes(proud_skill_group_id: int) -> list[TalentAttribute]:
|
||||
result.append(
|
||||
TalentAttribute(
|
||||
level=proud_skill_data["level"],
|
||||
param_descriptions=param_descriptions,
|
||||
param_list=proud_skill_data["paramList"][:param_num],
|
||||
params=proud_skill_data["paramList"][:param_num],
|
||||
break_level=proud_skill_data.get("breakLevel", 0),
|
||||
coin=proud_skill_data.get("coinCost", 0),
|
||||
cost_items=list(
|
||||
@ -159,7 +173,7 @@ def get_skill_attributes(proud_skill_group_id: int) -> list[TalentAttribute]:
|
||||
),
|
||||
)
|
||||
)
|
||||
return result
|
||||
return result, param_descriptions
|
||||
|
||||
|
||||
def parse_skill(skill_id: int, skill_cls: type[CombatTalent]) -> CombatTalent:
|
||||
@ -170,13 +184,22 @@ def parse_skill(skill_id: int, skill_cls: type[CombatTalent]) -> CombatTalent:
|
||||
cooldown = (
|
||||
skill_data.get("cdTime", 0) if "cooldown" in skill_cls.__fields__ else None
|
||||
)
|
||||
attributes = get_skill_attributes(skill_data["proudSkillGroupId"])
|
||||
attributes, param_descriptions = 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],
|
||||
[
|
||||
"name",
|
||||
"description",
|
||||
"icon",
|
||||
"cooldown",
|
||||
"attributes",
|
||||
"param_descriptions",
|
||||
],
|
||||
[_name, _description, icon, cooldown, attributes, param_descriptions],
|
||||
)
|
||||
if i is not None
|
||||
}
|
||||
@ -209,9 +232,9 @@ def parse_passive_talent(
|
||||
description=_description or "",
|
||||
icon=skill_data["icon"],
|
||||
promote_level=_promote_level,
|
||||
param_descriptions=param_descriptions,
|
||||
attribute=TalentAttribute(
|
||||
param_descriptions=param_descriptions,
|
||||
param_list=_param_list,
|
||||
params=_param_list,
|
||||
break_level=skill_data.get("breakLevel", 0),
|
||||
),
|
||||
)
|
||||
@ -331,7 +354,7 @@ async def parse_avatar_data(lang: Lang):
|
||||
Attack=data["attackBase"],
|
||||
Defense=data["defenseBase"],
|
||||
Critical=data["critical"],
|
||||
CriticalDamage=data["criticalHurt"],
|
||||
CriticalHurt=data["criticalHurt"],
|
||||
ChargeEfficiency=data["chargeEfficiency"],
|
||||
)
|
||||
|
||||
@ -342,47 +365,32 @@ async def parse_avatar_data(lang: Lang):
|
||||
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 id not in [10000005, 10000007]
|
||||
else None
|
||||
)
|
||||
# 冲刺技能
|
||||
alternate_sprint = (
|
||||
parse_skill(skill_ids[2], AlternateSprint) if len(skill_ids) == 3 else None
|
||||
)
|
||||
# 元素爆发
|
||||
burst_skill = (
|
||||
parse_skill(skill_depot_data["energySkill"], ElementalBurst)
|
||||
if id not in [10000005, 10000007]
|
||||
else None
|
||||
)
|
||||
# 第一次突破被动天赋
|
||||
first_passive = (
|
||||
parse_passive_talent(
|
||||
if id not in [10000005, 10000007]:
|
||||
# 元素战技
|
||||
elemental_skill = parse_skill(skill_ids[1], ElementalSkill)
|
||||
# 元素爆发
|
||||
burst_skill = parse_skill(skill_depot_data["energySkill"], ElementalBurst)
|
||||
# 第一次突破被动天赋
|
||||
first_passive = parse_passive_talent(
|
||||
skill_depot_data["inherentProudSkillOpens"][0], FirstAscensionPassive
|
||||
)
|
||||
if id not in [10000005, 10000007]
|
||||
else None
|
||||
)
|
||||
# 第四次突破被动天赋
|
||||
fourth_passive = (
|
||||
parse_passive_talent(
|
||||
# 第四次突破被动天赋
|
||||
fourth_passive = parse_passive_talent(
|
||||
skill_depot_data["inherentProudSkillOpens"][1], FourthAscensionPassive
|
||||
)
|
||||
if id not in [10000005, 10000007]
|
||||
else None
|
||||
)
|
||||
# 实用固有天赋
|
||||
utility_passive = (
|
||||
parse_passive_talent(
|
||||
# 实用固有天赋
|
||||
utility_passive = parse_passive_talent(
|
||||
skill_depot_data["inherentProudSkillOpens"][2], UtilityPassive
|
||||
)
|
||||
if id not in [10000005, 10000007]
|
||||
else None
|
||||
)
|
||||
# 杂项固有天赋
|
||||
else:
|
||||
elemental_skill = (
|
||||
burst_skill
|
||||
) = first_passive = fourth_passive = utility_passive = None
|
||||
# 杂项固有天赋
|
||||
if skill_depot_data["inherentProudSkillOpens"][3]:
|
||||
miscellaneous_passive = parse_passive_talent(
|
||||
skill_depot_data["inherentProudSkillOpens"][3], MiscellaneousPassive
|
||||
@ -415,10 +423,33 @@ async def parse_avatar_data(lang: Lang):
|
||||
items.append(
|
||||
ItemCount(item_id=item_data["id"], count=item_data["count"])
|
||||
)
|
||||
add_props = []
|
||||
for add_prop_data in promote_data["addProps"]:
|
||||
_string = pascalize(
|
||||
add_prop_data["propType"]
|
||||
.removeprefix("FIGHT_PROP_")
|
||||
.removeprefix("BASE_")
|
||||
.lower()
|
||||
).replace("Hp", "HP")
|
||||
prop_type_string = {
|
||||
**prop_type_map,
|
||||
**PropType.__members__,
|
||||
**{v: v for k, v in PropType.__members__.items()},
|
||||
}[_string]
|
||||
prop_type = PropType(prop_type_string)
|
||||
add_props.append(
|
||||
AddProp(
|
||||
type=prop_type,
|
||||
value=add_prop_data.get(
|
||||
"value", attributes.dict().get(prop_type, 0)
|
||||
),
|
||||
)
|
||||
)
|
||||
promotes.append(
|
||||
AvatarPromote(
|
||||
promote_level=promote_data.get("promoteLevel", 0),
|
||||
max_level=promote_data["unlockMaxLevel"],
|
||||
add_props=add_props,
|
||||
coin=promote_data.get("scoinCost", 0),
|
||||
cost_items=items,
|
||||
)
|
||||
@ -457,10 +488,11 @@ async def parse_avatar_data(lang: Lang):
|
||||
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],
|
||||
[i.dict(exclude_none=True) for i in avatar_list],
|
||||
ensure_ascii=False,
|
||||
encode_html_chars=False,
|
||||
indent=4,
|
||||
|
@ -77,7 +77,7 @@ async def parse_item_data(
|
||||
async with async_open(out_path / "item.json", encoding="utf-8", mode="w") as file:
|
||||
await file.write(
|
||||
json.dumps(
|
||||
[i.dict() for i in item_list],
|
||||
[i.dict(exclude_none=True) for i in item_list],
|
||||
ensure_ascii=False,
|
||||
encode_html_chars=False,
|
||||
indent=4,
|
||||
|
@ -5,10 +5,10 @@ except ImportError:
|
||||
|
||||
__all__ = ("remove_rich_tag",)
|
||||
|
||||
reich_pattern = r"(<(?P<tag_name>[a-z]+?)=(?P<value>.+?)>.+?</(?P=tag_name)>)"
|
||||
|
||||
|
||||
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
|
||||
)
|
||||
return re.sub(reich_pattern, "", string)
|
||||
|
Loading…
Reference in New Issue
Block a user