mirror of
https://github.com/PaiGramTeam/genshin-wiki.git
synced 2024-11-21 22:58:02 +00:00
🚧 build skill parser
This commit is contained in:
parent
f958a2d749
commit
8259775837
@ -1,10 +1,10 @@
|
|||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from model.enums import Association, AvatarQuality, Element, WeaponType
|
from model.enums import Association, AvatarQuality, Element, WeaponType
|
||||||
|
from model.other import ItemCount
|
||||||
from utils.model import BaseModel
|
from utils.model import BaseModel
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from model.item import Item
|
|
||||||
from model.avatar._talente import AvatarTalents
|
from model.avatar._talente import AvatarTalents
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
@ -16,7 +16,7 @@ __all__ = (
|
|||||||
"AvatarStories",
|
"AvatarStories",
|
||||||
"Story",
|
"Story",
|
||||||
"Seuyu",
|
"Seuyu",
|
||||||
"ItemCount",
|
"AvatarAttribute",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -102,16 +102,7 @@ class AvatarInfo(BaseModel):
|
|||||||
"""故事"""
|
"""故事"""
|
||||||
|
|
||||||
|
|
||||||
class ItemCount(BaseModel):
|
|
||||||
item: "Item"
|
|
||||||
"""物品"""
|
|
||||||
count: int
|
|
||||||
"""数量"""
|
|
||||||
|
|
||||||
|
|
||||||
class AvatarPromote(BaseModel):
|
class AvatarPromote(BaseModel):
|
||||||
required_level: int = 0
|
|
||||||
"""突破所需等级"""
|
|
||||||
promote_level: int = 0
|
promote_level: int = 0
|
||||||
"""突破等级"""
|
"""突破等级"""
|
||||||
max_level: int
|
max_level: int
|
||||||
@ -119,7 +110,7 @@ class AvatarPromote(BaseModel):
|
|||||||
|
|
||||||
coin: int = 0
|
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):
|
class Avatar(BaseModel):
|
||||||
"""角色"""
|
"""角色"""
|
||||||
|
|
||||||
@ -149,9 +175,11 @@ class Avatar(BaseModel):
|
|||||||
"""武器类型"""
|
"""武器类型"""
|
||||||
information: AvatarInfo
|
information: AvatarInfo
|
||||||
"""角色信息"""
|
"""角色信息"""
|
||||||
promote: AvatarPromote
|
attributes: AvatarAttribute
|
||||||
"""角色突破数据"""
|
"""角色基础属性"""
|
||||||
talents: "AvatarTalents"
|
talents: "AvatarTalents"
|
||||||
"""角色天赋信息"""
|
"""角色天赋信息"""
|
||||||
|
promotes: list[AvatarPromote]
|
||||||
|
"""角色突破数据"""
|
||||||
constellations: list[AvatarConstellation]
|
constellations: list[AvatarConstellation]
|
||||||
"""角色命座信息"""
|
"""角色命座信息"""
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
from utils.model import BaseModel
|
|
||||||
from typing import ClassVar
|
from typing import ClassVar
|
||||||
|
|
||||||
|
from model.other import ItemCount
|
||||||
|
from utils.model import BaseModel
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
"Talent",
|
"Talent",
|
||||||
"CombatTalent",
|
"CombatTalent",
|
||||||
@ -15,9 +17,26 @@ __all__ = (
|
|||||||
"UtilityPassive",
|
"UtilityPassive",
|
||||||
"MiscellaneousPassive",
|
"MiscellaneousPassive",
|
||||||
"AvatarTalents",
|
"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):
|
class Talent(BaseModel):
|
||||||
name: str
|
name: str
|
||||||
"""天赋名称"""
|
"""天赋名称"""
|
||||||
@ -28,7 +47,7 @@ class Talent(BaseModel):
|
|||||||
level: int = 0
|
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 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.enums import Association, AvatarQuality, Element, WeaponType
|
||||||
|
from model.other import ItemCount
|
||||||
from utils.const import PROJECT_ROOT
|
from utils.const import PROJECT_ROOT
|
||||||
from utils.manager import ResourceManager
|
from utils.manager import ResourceManager
|
||||||
from utils.typedefs import Lang
|
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")
|
OUT_DIR = PROJECT_ROOT.joinpath("out")
|
||||||
|
|
||||||
elements = {
|
elements = {
|
||||||
@ -29,6 +52,11 @@ async def parse_avatar_data(lang: Lang):
|
|||||||
avatar_json_data = manager.fetch("AvatarExcelConfigData")
|
avatar_json_data = manager.fetch("AvatarExcelConfigData")
|
||||||
fetter_info_json_data = manager.fetch("FetterInfoExcelConfigData")
|
fetter_info_json_data = manager.fetch("FetterInfoExcelConfigData")
|
||||||
story_json_data = manager.fetch("FetterStoryExcelConfigData")
|
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 = []
|
avatar_list = []
|
||||||
for data in avatar_json_data:
|
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())
|
filter(lambda x: x in data["weaponType"], WeaponType.__members__.values())
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 角色信息
|
||||||
title = manager.get_text(info_data["avatarTitleTextMapHash"])
|
title = manager.get_text(info_data["avatarTitleTextMapHash"])
|
||||||
birth = AvatarBirth(
|
birth = AvatarBirth(
|
||||||
month=info_data["infoBirthMonth"], day=info_data["infoBirthDay"]
|
month=info_data["infoBirthMonth"], day=info_data["infoBirthDay"]
|
||||||
@ -113,4 +142,119 @@ async def parse_avatar_data(lang: Lang):
|
|||||||
stories=stories,
|
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()
|
breakpoint()
|
||||||
|
Loading…
Reference in New Issue
Block a user