add AddProp attr for AvatarPromote

This commit is contained in:
Karako 2023-05-02 23:17:55 +08:00
parent ea67d86f4b
commit fa5c315d67
No known key found for this signature in database
GPG Key ID: 5920831B0095D4A0
5 changed files with 110 additions and 85 deletions

View File

@ -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):

View File

@ -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):

View File

@ -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,
attribute=TalentAttribute(
param_descriptions=param_descriptions,
param_list=_param_list,
attribute=TalentAttribute(
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,46 +365,31 @@ 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
)
if id not in [10000005, 10000007]:
# 元素战技
elemental_skill = parse_skill(skill_ids[1], ElementalSkill)
# 元素爆发
burst_skill = (
parse_skill(skill_depot_data["energySkill"], ElementalBurst)
if id not in [10000005, 10000007]
else None
)
burst_skill = parse_skill(skill_depot_data["energySkill"], ElementalBurst)
# 第一次突破被动天赋
first_passive = (
parse_passive_talent(
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(
@ -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,

View File

@ -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,

View File

@ -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)