mirror of
https://github.com/PaiGramTeam/genshin-wiki.git
synced 2024-11-21 14:48:17 +00:00
🚧 build skill parser
This commit is contained in:
parent
f958a2d749
commit
8259775837
@ -1,10 +1,10 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from model.enums import Association, AvatarQuality, Element, WeaponType
|
||||
from model.other import ItemCount
|
||||
from utils.model import BaseModel
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from model.item import Item
|
||||
from model.avatar._talente import AvatarTalents
|
||||
|
||||
__all__ = (
|
||||
@ -16,7 +16,7 @@ __all__ = (
|
||||
"AvatarStories",
|
||||
"Story",
|
||||
"Seuyu",
|
||||
"ItemCount",
|
||||
"AvatarAttribute",
|
||||
)
|
||||
|
||||
|
||||
@ -102,16 +102,7 @@ class AvatarInfo(BaseModel):
|
||||
"""故事"""
|
||||
|
||||
|
||||
class ItemCount(BaseModel):
|
||||
item: "Item"
|
||||
"""物品"""
|
||||
count: int
|
||||
"""数量"""
|
||||
|
||||
|
||||
class AvatarPromote(BaseModel):
|
||||
required_level: int = 0
|
||||
"""突破所需等级"""
|
||||
promote_level: int = 0
|
||||
"""突破等级"""
|
||||
max_level: int
|
||||
@ -119,7 +110,7 @@ class AvatarPromote(BaseModel):
|
||||
|
||||
coin: int = 0
|
||||
"""摩拉"""
|
||||
items: list[ItemCount] = []
|
||||
cost_items: list[ItemCount] = []
|
||||
"""突破所需材料"""
|
||||
|
||||
|
||||
@ -134,6 +125,41 @@ class AvatarConstellation(BaseModel):
|
||||
"""命座图标"""
|
||||
|
||||
|
||||
class AvatarAttribute(BaseModel):
|
||||
"""角色属性"""
|
||||
|
||||
HP: float
|
||||
"""生命值"""
|
||||
Attack: float
|
||||
"""攻击力"""
|
||||
Defense: float
|
||||
"""防御力"""
|
||||
Critical: float
|
||||
"""暴击率"""
|
||||
CriticalDamage: 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):
|
||||
"""角色"""
|
||||
|
||||
@ -149,9 +175,11 @@ class Avatar(BaseModel):
|
||||
"""武器类型"""
|
||||
information: AvatarInfo
|
||||
"""角色信息"""
|
||||
promote: AvatarPromote
|
||||
"""角色突破数据"""
|
||||
attributes: AvatarAttribute
|
||||
"""角色基础属性"""
|
||||
talents: "AvatarTalents"
|
||||
"""角色天赋信息"""
|
||||
promotes: list[AvatarPromote]
|
||||
"""角色突破数据"""
|
||||
constellations: list[AvatarConstellation]
|
||||
"""角色命座信息"""
|
||||
|
@ -1,6 +1,8 @@
|
||||
from utils.model import BaseModel
|
||||
from typing import ClassVar
|
||||
|
||||
from model.other import ItemCount
|
||||
from utils.model import BaseModel
|
||||
|
||||
__all__ = (
|
||||
"Talent",
|
||||
"CombatTalent",
|
||||
@ -15,9 +17,26 @@ __all__ = (
|
||||
"UtilityPassive",
|
||||
"MiscellaneousPassive",
|
||||
"AvatarTalents",
|
||||
"TalentAttribute",
|
||||
)
|
||||
|
||||
|
||||
class TalentAttribute(BaseModel):
|
||||
level: int
|
||||
"""等级"""
|
||||
param_descriptions: list[str]
|
||||
"""参数描述"""
|
||||
param_list: list[float]
|
||||
"""参数列表"""
|
||||
|
||||
break_level: int = 0
|
||||
"""所需突破等级"""
|
||||
coin: int = 0
|
||||
"""摩拉"""
|
||||
cost_items: list[ItemCount] = []
|
||||
"""消耗物品"""
|
||||
|
||||
|
||||
class Talent(BaseModel):
|
||||
name: str
|
||||
"""天赋名称"""
|
||||
@ -28,7 +47,7 @@ class Talent(BaseModel):
|
||||
level: int = 0
|
||||
"""解锁等级"""
|
||||
|
||||
params: list[float] = []
|
||||
attributes: list[TalentAttribute]
|
||||
"""数值参数列表"""
|
||||
|
||||
|
||||
|
8
model/other.py
Normal file
8
model/other.py
Normal file
@ -0,0 +1,8 @@
|
||||
from utils.model import BaseModel
|
||||
|
||||
|
||||
class ItemCount(BaseModel):
|
||||
item_id: int
|
||||
"""物品ID"""
|
||||
count: int
|
||||
"""数量"""
|
@ -1,11 +1,34 @@
|
||||
from itertools import chain
|
||||
from typing import TypeVar
|
||||
|
||||
from model.avatar import AvatarBirth, AvatarInfo, AvatarStories, Seuyu, Story
|
||||
from model.avatar import (
|
||||
AlternateSprint,
|
||||
AvatarAttribute,
|
||||
AvatarBirth,
|
||||
AvatarInfo,
|
||||
AvatarPromote,
|
||||
AvatarStories,
|
||||
ElementalBurst,
|
||||
ElementalSkill,
|
||||
NormalAttack,
|
||||
Seuyu,
|
||||
Story,
|
||||
Talent,
|
||||
TalentAttribute,
|
||||
)
|
||||
from model.enums import Association, AvatarQuality, Element, WeaponType
|
||||
from model.other import ItemCount
|
||||
from utils.const import PROJECT_ROOT
|
||||
from utils.manager import ResourceManager
|
||||
from utils.typedefs import Lang
|
||||
|
||||
try:
|
||||
import regex as re
|
||||
except ImportError:
|
||||
import re
|
||||
|
||||
T = TypeVar("T", bound=Talent)
|
||||
|
||||
OUT_DIR = PROJECT_ROOT.joinpath("out")
|
||||
|
||||
elements = {
|
||||
@ -29,6 +52,11 @@ async def parse_avatar_data(lang: Lang):
|
||||
avatar_json_data = manager.fetch("AvatarExcelConfigData")
|
||||
fetter_info_json_data = manager.fetch("FetterInfoExcelConfigData")
|
||||
story_json_data = manager.fetch("FetterStoryExcelConfigData")
|
||||
promote_json_data = manager.fetch("AvatarPromoteExcelConfigData")
|
||||
|
||||
skill_depot_json_data = manager.fetch("AvatarSkillDepotExcelConfigData")
|
||||
skill_json_data = manager.fetch("AvatarSkillExcelConfigData")
|
||||
proud_skill_json_data = manager.fetch("ProudSkillExcelConfigData")
|
||||
|
||||
avatar_list = []
|
||||
for data in avatar_json_data:
|
||||
@ -51,6 +79,7 @@ async def parse_avatar_data(lang: Lang):
|
||||
filter(lambda x: x in data["weaponType"], WeaponType.__members__.values())
|
||||
)
|
||||
|
||||
# 角色信息
|
||||
title = manager.get_text(info_data["avatarTitleTextMapHash"])
|
||||
birth = AvatarBirth(
|
||||
month=info_data["infoBirthMonth"], day=info_data["infoBirthDay"]
|
||||
@ -113,4 +142,119 @@ async def parse_avatar_data(lang: Lang):
|
||||
stories=stories,
|
||||
)
|
||||
|
||||
# 角色基础属性
|
||||
attribute = AvatarAttribute(
|
||||
HP=data["hpBase"],
|
||||
Attack=data["attackBase"],
|
||||
Defense=data["defenseBase"],
|
||||
Critical=data["critical"],
|
||||
CriticalDamage=data["criticalHurt"],
|
||||
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[T]) -> T:
|
||||
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
|
||||
}
|
||||
)
|
||||
|
||||
# 天赋
|
||||
skill_depot_data = next(
|
||||
filter(lambda x: x["id"] == data["skillDepotId"], skill_depot_json_data)
|
||||
)
|
||||
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 len(skill_ids) == 3:
|
||||
alternate_sprint = parse_skill(skill_ids[2], AlternateSprint)
|
||||
# 元素爆发
|
||||
burst_skill = parse_skill(skill_depot_data["energySkill"], ElementalBurst)
|
||||
breakpoint()
|
||||
|
||||
# 角色突破数据
|
||||
promote_id = data["avatarPromoteId"]
|
||||
promote_datas = sorted(
|
||||
filter(lambda x: x["avatarPromoteId"] == promote_id, promote_json_data),
|
||||
key=lambda x: x.get("promoteLevel", 0),
|
||||
)
|
||||
promotes = []
|
||||
for promote_data in promote_datas:
|
||||
items = []
|
||||
for item_data in promote_data["costItems"]:
|
||||
if item_data:
|
||||
items.append(
|
||||
ItemCount(item_id=item_data["id"], count=item_data["count"])
|
||||
)
|
||||
promotes.append(
|
||||
AvatarPromote(
|
||||
promote_level=promote_data.get("promoteLevel", 0),
|
||||
max_level=promote_data["unlockMaxLevel"],
|
||||
coin=promote_data.get("scoinCost", 0),
|
||||
cost_items=items,
|
||||
)
|
||||
)
|
||||
breakpoint()
|
||||
|
Loading…
Reference in New Issue
Block a user