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.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 model.other import ItemCount
from utils.model import BaseModel from utils.model import BaseModel
@ -13,6 +13,7 @@ __all__ = (
"Story", "Story",
"Seuyu", "Seuyu",
"AvatarAttribute", "AvatarAttribute",
"AddProp",
) )
@ -98,11 +99,22 @@ class AvatarInfo(BaseModel):
"""故事""" """故事"""
class AddProp(BaseModel):
"""属性加成"""
type: PropType
"""属性类型"""
value: float
"""属性值"""
class AvatarPromote(BaseModel): class AvatarPromote(BaseModel):
promote_level: int = 0 promote_level: int = 0
"""突破等级""" """突破等级"""
max_level: int max_level: int
"""解锁的等级上限""" """解锁的等级上限"""
add_props: list[AddProp] = []
"""属性加成"""
coin: int = 0 coin: int = 0
"""摩拉""" """摩拉"""
@ -134,28 +146,10 @@ class AvatarAttribute(BaseModel):
"""防御力""" """防御力"""
Critical: float Critical: float
"""暴击率""" """暴击率"""
CriticalDamage: float CriticalHurt: float
"""暴击伤害""" """暴击伤害"""
ChargeEfficiency: 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): 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): class Talent(BaseModel):
name: str 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): class CombatTalent(Talent):
"""战斗天赋""" """战斗天赋"""
cooldown: float = 0 cooldown: float = 0
"""冷却时间""" """冷却时间"""
param_descriptions: list[str] = []
"""参数描述"""
attributes: list[TalentAttribute] attributes: list[TalentAttribute]
"""数值参数列表""" """数值参数"""
class NormalAttack(CombatTalent): class NormalAttack(CombatTalent):

View File

@ -3,8 +3,10 @@ from typing import TypeVar
import ujson as json import ujson as json
from aiofiles import open as async_open from aiofiles import open as async_open
from humps import pascalize
from model.avatar import ( from model.avatar import (
AddProp,
AlternateSprint, AlternateSprint,
Avatar, Avatar,
AvatarAttribute, AvatarAttribute,
@ -28,7 +30,7 @@ from model.avatar import (
TalentAttribute, TalentAttribute,
UtilityPassive, UtilityPassive,
) )
from model.enums import Association, AvatarQuality, Element, WeaponType from model.enums import Association, AvatarQuality, Element, PropType, 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.funcs import remove_rich_tag
@ -117,9 +119,21 @@ elements_map = {
): Element.Geo, ): Element.Geo,
(471154292, 821712868, 1128382182, 3053155130, 4168416172): Element.Null, (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( proud_skill_datas = sorted(
filter( filter(
lambda x: x["proudSkillGroupId"] == proud_skill_group_id, 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"], key=lambda x: x["level"],
) )
result: list[TalentAttribute] = [] result: list[TalentAttribute] = []
param_descriptions: list[str] = []
for proud_skill_data in proud_skill_datas: for proud_skill_data in proud_skill_datas:
param_descriptions = list( param_descriptions = list(
filter( filter(
@ -147,8 +162,7 @@ def get_skill_attributes(proud_skill_group_id: int) -> list[TalentAttribute]:
result.append( result.append(
TalentAttribute( TalentAttribute(
level=proud_skill_data["level"], level=proud_skill_data["level"],
param_descriptions=param_descriptions, params=proud_skill_data["paramList"][:param_num],
param_list=proud_skill_data["paramList"][:param_num],
break_level=proud_skill_data.get("breakLevel", 0), break_level=proud_skill_data.get("breakLevel", 0),
coin=proud_skill_data.get("coinCost", 0), coin=proud_skill_data.get("coinCost", 0),
cost_items=list( 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: 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 = ( cooldown = (
skill_data.get("cdTime", 0) if "cooldown" in skill_cls.__fields__ else None 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( return skill_cls(
**{ **{
i[0]: i[1] i[0]: i[1]
for i in zip( 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 if i is not None
} }
@ -209,9 +232,9 @@ def parse_passive_talent(
description=_description or "", description=_description or "",
icon=skill_data["icon"], icon=skill_data["icon"],
promote_level=_promote_level, promote_level=_promote_level,
param_descriptions=param_descriptions,
attribute=TalentAttribute( attribute=TalentAttribute(
param_descriptions=param_descriptions, params=_param_list,
param_list=_param_list,
break_level=skill_data.get("breakLevel", 0), break_level=skill_data.get("breakLevel", 0),
), ),
) )
@ -331,7 +354,7 @@ async def parse_avatar_data(lang: Lang):
Attack=data["attackBase"], Attack=data["attackBase"],
Defense=data["defenseBase"], Defense=data["defenseBase"],
Critical=data["critical"], Critical=data["critical"],
CriticalDamage=data["criticalHurt"], CriticalHurt=data["criticalHurt"],
ChargeEfficiency=data["chargeEfficiency"], 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"])) skill_ids = list(filter(lambda x: x != 0, skill_depot_data["skills"]))
# 普通攻击 # 普通攻击
normal_attack = parse_skill(skill_ids[0], NormalAttack) 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 = ( 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
) )
# 元素爆发 if id not in [10000005, 10000007]:
burst_skill = ( # 元素战技
parse_skill(skill_depot_data["energySkill"], ElementalBurst) elemental_skill = parse_skill(skill_ids[1], ElementalSkill)
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 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 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 skill_depot_data["inherentProudSkillOpens"][2], UtilityPassive
) )
if id not in [10000005, 10000007] else:
else None elemental_skill = (
) burst_skill
# 杂项固有天赋 ) = first_passive = fourth_passive = utility_passive = None
# 杂项固有天赋
if skill_depot_data["inherentProudSkillOpens"][3]: if skill_depot_data["inherentProudSkillOpens"][3]:
miscellaneous_passive = parse_passive_talent( miscellaneous_passive = parse_passive_talent(
skill_depot_data["inherentProudSkillOpens"][3], MiscellaneousPassive skill_depot_data["inherentProudSkillOpens"][3], MiscellaneousPassive
@ -415,10 +423,33 @@ async def parse_avatar_data(lang: Lang):
items.append( items.append(
ItemCount(item_id=item_data["id"], count=item_data["count"]) 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( promotes.append(
AvatarPromote( AvatarPromote(
promote_level=promote_data.get("promoteLevel", 0), promote_level=promote_data.get("promoteLevel", 0),
max_level=promote_data["unlockMaxLevel"], max_level=promote_data["unlockMaxLevel"],
add_props=add_props,
coin=promote_data.get("scoinCost", 0), coin=promote_data.get("scoinCost", 0),
cost_items=items, cost_items=items,
) )
@ -457,10 +488,11 @@ async def parse_avatar_data(lang: Lang):
constellations=constellations, constellations=constellations,
) )
avatar_list.append(avatar) avatar_list.append(avatar)
async with async_open(out_path / "avatar.json", encoding="utf-8", mode="w") as file: async with async_open(out_path / "avatar.json", encoding="utf-8", mode="w") as file:
await file.write( await file.write(
json.dumps( json.dumps(
[i.dict() for i in avatar_list], [i.dict(exclude_none=True) for i in avatar_list],
ensure_ascii=False, ensure_ascii=False,
encode_html_chars=False, encode_html_chars=False,
indent=4, 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: async with async_open(out_path / "item.json", encoding="utf-8", mode="w") as file:
await file.write( await file.write(
json.dumps( json.dumps(
[i.dict() for i in item_list], [i.dict(exclude_none=True) for i in item_list],
ensure_ascii=False, ensure_ascii=False,
encode_html_chars=False, encode_html_chars=False,
indent=4, indent=4,

View File

@ -5,10 +5,10 @@ except ImportError:
__all__ = ("remove_rich_tag",) __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: def remove_rich_tag(string: str | None) -> str:
"""去除富文本标签""" """去除富文本标签"""
if string is not None: if string is not None:
return re.sub( return re.sub(reich_pattern, "", string)
r"(<(?P<tag_name>[a-z]+?)=(?P<value>.+?)>.+?</(?P=tag_name)>)", "", string
)