diff --git a/genshin/models/starrail/chronicle/characters.py b/genshin/models/starrail/chronicle/characters.py index f6d3bde3..d40f42da 100644 --- a/genshin/models/starrail/chronicle/characters.py +++ b/genshin/models/starrail/chronicle/characters.py @@ -1,14 +1,30 @@ """Starrail chronicle character.""" -from typing import List, Optional +import typing +from typing import Any, Mapping, Optional, Sequence + +if typing.TYPE_CHECKING: + import pydantic.v1 as pydantic +else: + try: + import pydantic.v1 as pydantic + except ImportError: + import pydantic from genshin.models.model import APIModel from .. import character __all__ = [ + "CharacterProperty", + "ModifyRelicProperty", + "PropertyInfo", "Rank", + "RecommendProperty", "Relic", + "RelicProperty", + "Skill", + "SkillStage", "StarRailDetailCharacter", "StarRailDetailCharacters", "StarRailEquipment", @@ -24,6 +40,29 @@ class StarRailEquipment(APIModel): name: str desc: str icon: str + rarity: int + wiki: str + + +class PropertyInfo(APIModel): + """Relic property info.""" + + property_type: int + name: str + icon: str + property_name_relic: str + property_name_filter: str + + +class RelicProperty(APIModel): + """Relic property.""" + + property_type: int + value: str + times: int + preferred: bool + recommended: bool + info: PropertyInfo class Relic(APIModel): @@ -36,6 +75,9 @@ class Relic(APIModel): desc: str icon: str rarity: int + wiki: str + main_property: RelicProperty + properties: Sequence[RelicProperty] class Rank(APIModel): @@ -49,17 +91,118 @@ class Rank(APIModel): is_unlocked: bool +class CharacterProperty(APIModel): + """Base character property.""" + + property_type: int + base: str + add: str + final: str + preferred: bool + recommended: bool + info: PropertyInfo + + +class SkillStage(APIModel): + """Character skill stage.""" + + name: str + desc: str + level: int + remake: str + item_url: str + is_activated: bool + is_rank_work: bool + + +class Skill(APIModel): + """Character skill.""" + + point_id: str + point_type: int + item_url: str + level: int + is_activated: bool + is_rank_work: bool + pre_point: str + anchor: str + remake: str + skill_stages: Sequence[SkillStage] + + +class RecommendProperty(APIModel): + """Character recommended and preferred properties.""" + + recommend_relic_properties: Sequence[int] + custom_relic_properties: Sequence[int] + is_custom_property_valid: bool + + class StarRailDetailCharacter(character.StarRailPartialCharacter): """StarRail character with equipment and relics.""" image: str equip: Optional[StarRailEquipment] - relics: List[Relic] - ornaments: List[Relic] - ranks: List[Rank] + relics: Sequence[Relic] + ornaments: Sequence[Relic] + ranks: Sequence[Rank] + properties: Sequence[CharacterProperty] + base_type: int + figure_path: str + + +class ModifyRelicProperty(APIModel): + """Modify relic property.""" + + property_type: int + modify_property_type: int class StarRailDetailCharacters(APIModel): """StarRail characters.""" - avatar_list: List[StarRailDetailCharacter] + avatar_list: Sequence[StarRailDetailCharacter] + equip_wiki: Mapping[str, str] + relic_wiki: Mapping[str, str] + property_info: Mapping[str, PropertyInfo] + recommend_property: Mapping[str, RecommendProperty] + relic_properties: Sequence[ModifyRelicProperty] + + @pydantic.root_validator(pre=True) + def __fill_additional_fields(cls, values: Mapping[str, Any]) -> Mapping[str, Any]: + """Fill additional fields for convenience.""" + characters = values.get("avatar_list", []) + props_info = values.get("property_info", {}) + rec_props = values.get("recommend_property", {}) + equip_wiki = values.get("equip_wiki", {}) + relic_wiki = values.get("relic_wiki", {}) + + for char in characters: + char_id = str(char["id"]) + char_rec_props = rec_props[char_id]["recommend_relic_properties"] + char_custom_props = rec_props[char_id]["custom_relic_properties"] + + for relic in char["relics"] + char["ornaments"]: + prop_type = relic["main_property"]["property_type"] + relic["main_property"]["info"] = props_info[str(prop_type)] + relic["main_property"]["recommended"] = prop_type in char_rec_props + relic["main_property"]["preferred"] = prop_type in char_custom_props + + for prop in relic["properties"]: + prop_type = prop["property_type"] + prop["recommended"] = prop_type in char_rec_props + prop["preferred"] = prop_type in char_custom_props + prop["info"] = props_info[str(prop_type)] + + relic["wiki"] = relic_wiki.get(str(relic["id"]), "") + + for prop in char["properties"]: + prop_type = prop["property_type"] + prop["recommended"] = prop_type in char_rec_props + prop["preferred"] = prop_type in char_custom_props + prop["info"] = props_info[str(prop_type)] + + if char["equip"]: + char["equip"]["wiki"] = equip_wiki.get(str(char["equip"]["id"]), "") + + return values