GenshinUID/tools/get_action.py

323 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import re
import json
from typing import List
from pathlib import Path
from copy import deepcopy
import httpx
Genshin_version = '3.0.0'
path = (
Path(__file__).parents[1]
/ 'utils'
/ 'enka_api'
/ 'map'
/ f'avatarId2Name_mapping_{Genshin_version}.json'
)
element_path = (
Path(__file__).parents[1]
/ 'utils'
/ 'enka_api'
/ 'map'
/ f'avatarName2Element_mapping_{Genshin_version}.json'
)
with open(path, 'r', encoding='utf-8') as f:
char_id_list = json.load(f)
with open(element_path, 'r', encoding='utf-8') as f:
char_element_list = json.load(f)
char_list = []
char_action = {}
INDEX_MAP = ['', 'A', 'E', 'Q']
attack_type_list = {'普通攻击': 'A', '重击': 'B', '下落攻击': 'C', '战技': 'E', '爆发': 'Q'}
label_type_list = {
'普通攻击': 'A',
'重击': 'B',
'下落攻击': 'C',
'攻击': 'attack',
'充能效率': 'ce',
'生命值': 'hp',
'防御': 'defense',
'暴击率': 'critrate',
'暴击伤害': 'critDmg',
'元素精通': 'em',
}
extra = {
'胡桃': {'A重击伤害': '蒸发', 'Q低血量时技能伤害': '蒸发'},
'香菱': {'E喷火伤害': '蒸发', 'Q旋火轮伤害': '蒸发'},
'达达利亚': {'Q技能伤害·近战': '蒸发', 'Q技能伤害·远程': '蒸发'},
'重云': {'Q技能伤害': '融化'},
'雷电将军': {
'E协同攻击伤害': '超激化',
'Q梦想一刀基础伤害': '满愿力',
'Q一段伤害': '超激化',
'Q重击伤害': '超激化',
},
'甘雨': {'A霜华矢命中伤害': '融化', 'A霜华矢·霜华绽发伤害': '融化'},
'可莉': {'A重击伤害': '蒸发'},
'优菈': {'Q光降之剑基础伤害': '13层'},
'行秋': {'E技能伤害': '蒸发'},
'莫娜': {'A重击伤害': '蒸发', 'Q泡影破裂伤害': '蒸发'},
'迪卢克': {'Q斩击伤害': '蒸发'},
'芭芭拉': {'A重击伤害': '蒸发'},
'七七': {'Q技能伤害': '融化'},
'八重神子': {'Q天狐霆雷伤害': '超激化', 'E杀生樱伤害·叁阶': '超激化', 'E杀生樱伤害·肆阶': '超激化'},
'菲谢尔': {'E奥兹攻击伤害': '超激化'},
'久岐忍': {'Q单次伤害': '超激化'},
'柯莱': {'Q跃动伤害': '蔓激化', 'E技能伤害': '蔓激化'},
'提纳里': {'E技能伤害': '蔓激化', 'Q缠藤箭伤害': '蔓激化', 'Q次级缠藤箭伤害': '蔓激化'},
'刻晴': {'A重击伤害': '超激化', 'Q技能伤害': '超激化', 'Q连斩伤害': '超激化', 'Q最后一击伤害': '超激化'},
'北斗': {'Q闪雷伤害': '超激化'},
}
template = {'A重击伤害': {'name': 'A重击伤害', 'type': '', 'plus': 1, 'value': []}}
def fill_label(label_name: str, index: int) -> str:
label_name = INDEX_MAP[index] + label_name
return label_name
def from_type_to_value(value_type: str, para):
value = ''
if value_type == 'F1P':
value = '%.1f%%' % (para * 100)
elif value_type == 'F2P':
value = '%.2f%%' % (para * 100)
elif value_type == 'F1':
value = '%.1f' % (para)
elif value_type == 'F2':
value = '%.2f' % (para)
elif value_type == 'P':
value = str(round(para * 100)) + '%'
elif value_type == 'I':
value = '%.2f' % para
return value
def find_tag(labels: List, index: int, char: str, parameters: dict) -> dict:
result = {}
for label in labels:
if char != '旅行者':
if char_element_list[char] == 'Anemo':
if 'A扩散伤害' not in result:
result['A扩散伤害'] = {
'name': 'A扩散伤害',
'type': '扩散',
'plus': 0,
'value': [str(i) for i in range(1, 11)],
}
# 拿到形如{param1:F1P}的字典
label_split = label.split('|')[-1]
# 拿到单个标签的名称,形如一段伤害
label_name = label.split('|')[0]
# 寻找label中带*的倍数倍率,比如 攻击力*3
label_plus = 1
if '*' in label_split:
label_plus = label_split.split('*')[-1]
label_plus = int(re.findall(r'[0-9]+', label_plus)[0])
# 如果在label_split内拿到了形如每秒{param2:F2P}生命值上限+{param3:I},获取汉字转换类型
laber_kanji_list = re.findall(r'[\u4e00-\u9fa5]+', label_split)
# 如果label_split中有汉字则获取汉字的类型
laber_kanji_list_str = ''.join(laber_kanji_list).replace('每秒', '')
for type in label_type_list:
if type in laber_kanji_list_str:
label_kanji = type
break
else:
label_kanji = '攻击力'
# 找到标签{param1:F1P}的List
label_attr = re.findall(r'{[a-zA-Z0-9]+:[a-zA-Z0-9]+}', label_split)
# 例如"持续治疗|每秒{param2:F2P}生命值上限+{param3:I}",
# 对单个标签内多个param进行处理处理成形如['{param2:F2P}', '{param3:I}']
value_type = ''
temp_value = []
temp_temp = []
for indexA, k in enumerate(label_attr):
# 去除多多余字符 变成 param2:F2P
k_deal = k.replace('{', '').replace('}', '')
value_type = k_deal.split(':')[-1] # F2P
value_index = k_deal.split(':')[0] # param2
temp = [
from_type_to_value(value_type, parameter)
for parameter in parameters[value_index]
]
if indexA == 0:
temp_value = temp
# 只采用高空坠地的倍率
elif indexA == 1 and '低空/高空坠地' in label:
temp_value = temp
# 阿忍仅计算50%血量以下伤害
elif indexA == 1 and char == '久岐忍':
temp_value = temp
# 埃洛伊特殊值
elif indexA == 2 and char == '埃洛伊':
temp_value = temp
# 烟绯满层丹火印
elif indexA == 4 and char == '烟绯':
temp_value = temp
# 无例外情况倍率全部相加
else:
temp_value = [f'{i}+{j}' for i, j in zip(temp_temp, temp)]
# 读入缓存
temp_temp = temp
# 制作倍率单元素
parameter_list = {
'name': '',
'type': label_kanji,
'plus': label_plus,
'value': temp_value,
}
# 特殊化处理
if '心海' in char:
label_name = label_name.replace('提升', '提高')
label_name = label_name.replace('低空/高空坠地冲击伤害', '高空下落伤害')
label_name = label_name.replace('技能', '')
# 提升指提升百分比 例如 E:dmgBouns+50%
# 提高指提高固定值 例如 Q:addDmg+40%defense
label_keyword_hurt_list = ['一段', '壹阶', '贰阶', '叁阶', '肆阶']
label_keyword_up_list = {
'普通攻击': 'A:addDmg',
'重击': 'B:addDmg',
'攻击': 'attack',
'生命值': 'hp',
'防御': 'defense',
'暴击率': 'critrate',
'充能效率': 'ce',
'元素精通': 'em',
}
if '持续时间' in label_name:
continue
elif '提升' in label_name:
# 云瑾和申鹤
if '伤害值提升' in label_name:
parameter_list['name'] = fill_label(label_name, index)
result[fill_label(label_name, index)] = parameter_list
elif '伤害提升' in label_name:
add_type = ''
# 寻找有没有合适的加成eg
target = 0
for attack_type in attack_type_list:
if attack_type in label_name:
add_type += attack_type_list[attack_type]
target += 1
# 没有就对E进行加成
else:
if target > 0:
if '变格' in label_name:
parameter_list['plus'] = 4
else:
add_type += 'E'
# 格式化加:
if add_type:
add_type = add_type + ':'
add_attr = '{}dmgBonus+'.format(add_type) + '{' + '}'
parameter_list['effect'] = add_attr
parameter_list['name'] = fill_label(label_name, index)
if 'effect' not in result:
result['effect'] = []
result['effect'].append(parameter_list)
else:
continue
elif '提高' in label_name:
# 阻止雷电将军E
if '元素爆发伤害提高' in label_name:
continue
if '攻击速度' in label_name:
continue
for attack_type in label_type_list:
if attack_type in label_name:
add_prop = label_keyword_up_list[attack_type]
break
else:
add_prop = 'E:addDmg'
for attack_type in label_type_list:
if attack_type in label_kanji:
base_prop = label_keyword_up_list[attack_type]
break
else:
base_prop = 'attack'
add_attr = add_prop + '+{' + '}' + base_prop
parameter_list['effect'] = add_attr
parameter_list['name'] = fill_label(label_name, index)
if 'effect' not in result:
result['effect'] = []
result['effect'].append(parameter_list)
elif '伤害' in label_name:
if '' in label_name or '' in label_name:
for label_keyword in label_keyword_hurt_list:
if label_keyword in label_name:
parameter_list['name'] = fill_label(label_name, index)
result[fill_label(label_name, index)] = parameter_list
elif '低空/高空坠地冲击伤害' in label_name and char not in ['']:
continue
elif '下坠期间伤害' in label_name:
continue
else:
parameter_list['name'] = fill_label(label_name, index)
result[fill_label(label_name, index)] = parameter_list
elif '治疗' in label_name:
parameter_list['name'] = fill_label(label_name, index)
result[fill_label(label_name, index)] = parameter_list
elif '护盾' in label_name:
parameter_list['name'] = fill_label(label_name, index)
result[fill_label(label_name, index)] = parameter_list
elif '满蓄力瞄准射击' in label_name:
parameter_list['name'] = fill_label(label_name, index)
result[fill_label(label_name, index)] = parameter_list
elif '愿力加成' in label_name:
parameter_list['name'] = fill_label(label_name, index)
result['extra'] = parameter_list
if char in extra:
for extra_name in extra[char]:
temp_name = extra_name.replace('技能', '')
if fill_label(label_name, index) == temp_name:
new_parameter_list = deepcopy(parameter_list)
new_parameter_list['name'] = (
fill_label(label_name, index)
+ f'({extra[char][extra_name]})'
)
result[
fill_label(label_name, index)
+ f'({extra[char][extra_name]})'
] = new_parameter_list
return result
for char_id in char_id_list:
char_list.append(char_id_list[char_id])
for char in char_list:
talent_data = httpx.get(
f'https://info.minigg.cn/talents?query={char}'
).json()
if 'errcode' in talent_data:
continue
result = {}
for i in range(1, 4):
skill = talent_data['combat{}'.format(str(i))]
labels = skill['attributes']['labels']
parameters = skill['attributes']['parameters']
result = dict(result, **find_tag(labels, i, char, parameters))
char_action[char] = result
with open(
str(
Path(__file__).parents[1]
/ 'genshinuid_enka'
/ 'dmgCalc'
/ 'char_action.json'
),
'w',
encoding='UTF-8',
) as file:
json.dump(char_action, file, ensure_ascii=False)