优化:圣遗物评分将变为有效词条计数

This commit is contained in:
KimgiaiiWuyi 2022-06-22 01:04:04 +08:00
parent 70438d55f0
commit d4667a7446
6 changed files with 461 additions and 21 deletions

View File

@ -1,5 +1,5 @@
import math import math
import json import json,asyncio
from io import BytesIO from io import BytesIO
from pathlib import Path from pathlib import Path
from base64 import b64encode from base64 import b64encode
@ -20,9 +20,16 @@ ETC_PATH = R_PATH / 'etc'
COLOR_MAP = {'Anemo' : (3, 90, 77), 'Cryo': (5, 85, 151), 'Dendro': (4, 87, 3), COLOR_MAP = {'Anemo' : (3, 90, 77), 'Cryo': (5, 85, 151), 'Dendro': (4, 87, 3),
'Electro': (47, 1, 85), 'Geo': (85, 34, 1), 'Hydro': (4, 6, 114), 'Pyro': (88, 4, 4)} 'Electro': (47, 1, 85), 'Geo': (85, 34, 1), 'Hydro': (4, 6, 114), 'Pyro': (88, 4, 4)}
SCORE_VALUE_MAP = {'暴击率': 2, '暴击伤害': 1, '元素精通': 0.25, '元素充能效率': 0.65, '百分比血量': 0.86, SCORE_MAP = {'暴击率': 2, '暴击伤害': 1, '元素精通': 0.25, '元素充能效率': 0.65, '百分比血量': 0.86,
'百分比攻击力': 1, '百分比防御力': 0.7, '血量': 0.014, '攻击力': 0.12, '防御力': 0.18} '百分比攻击力': 1, '百分比防御力': 0.7, '血量': 0.014, '攻击力': 0.12, '防御力': 0.18}
VALUE_MAP = {'攻击力': 4.975, '血量': 4.975, '防御力': 6.2, '元素精通': 19.75,
'元素充能效率': 5.5, '暴击率': 3.3, '暴击伤害': 6.6}
# 引入ValueMap
with open(ETC_PATH / 'ValueAttrMap.json', 'r', encoding='UTF-8') as f:
ATTR_MAP = json.load(f)
# 引入dmgMap # 引入dmgMap
with open(ETC_PATH / 'dmgMap.json', 'r', encoding='UTF-8') as f: with open(ETC_PATH / 'dmgMap.json', 'r', encoding='UTF-8') as f:
dmgMap = json.load(f) dmgMap = json.load(f)
@ -31,6 +38,10 @@ with open(ETC_PATH / 'dmgMap.json', 'r', encoding='UTF-8') as f:
with open(ETC_PATH / 'avatarOffsetMap.json', 'r', encoding='UTF-8') as f: with open(ETC_PATH / 'avatarOffsetMap.json', 'r', encoding='UTF-8') as f:
avatarOffsetMap = json.load(f) avatarOffsetMap = json.load(f)
# 引入offset2
with open(ETC_PATH / 'avatarCardOffsetMap.json', 'r', encoding='UTF-8') as f:
avatarCardOffsetMap = json.load(f)
def genshin_font_origin(size: int) -> ImageFont: def genshin_font_origin(size: int) -> ImageFont:
return ImageFont.truetype(str(TEXT_PATH / 'yuanshen_origin.ttf'), size=size) return ImageFont.truetype(str(TEXT_PATH / 'yuanshen_origin.ttf'), size=size)
@ -64,9 +75,46 @@ def strLenth(r: str, size: int, limit: int = 540) -> str:
async def get_artifacts_score(subName: str, subValue: int) -> int: async def get_artifacts_score(subName: str, subValue: int) -> int:
score = subValue * SCORE_VALUE_MAP[subName] score = subValue * SCORE_MAP[subName]
return score return score
async def get_artifacts_value(subName: str, subValue: int, baseAtk: int,
baseHp: int, baseDef: int, charName: str) -> int:
if charName not in ATTR_MAP:
ATTR_MAP[charName] = ['攻击力', '暴击率', '暴击伤害']
if subName in ATTR_MAP[charName] and subName in ['血量', '防御力', '攻击力']:
if subName == '血量':
base = (subValue / baseHp) * 100
elif subName == '防御力':
base = (subValue / baseDef) * 100
elif subName == '攻击力':
base = (subValue / baseAtk) * 100
value = float('{:.2f}'.format(base / VALUE_MAP[subName]))
elif subName in ['百分比血量', '百分比防御力', '百分比攻击力']:
subName = subName.replace('百分比', '')
if subName in ATTR_MAP[charName]:
value = float('{:.2f}'.format(subValue / VALUE_MAP[subName]))
else:
return 0
else:
if subName in ATTR_MAP[charName]:
value = float('{:.2f}'.format(subValue / VALUE_MAP[subName]))
else:
value = 0
if charName == '胡桃' and subName == '攻击力':
value = value * 0.4
return value
async def get_all_artifacts_value(raw_data: dict, baseHp: int, baseAtk: int, baseDef: int, char_name: str) -> int:
artifactsValue = 0
for aritifact in raw_data:
for i in aritifact['reliquarySubstats']:
subName = i['statName']
subValue = i['statValue']
value_temp = await get_artifacts_value(subName, subValue, baseAtk, baseHp, baseDef, char_name)
artifactsValue += value_temp
return artifactsValue
async def get_first_main(mainName: str) -> str: async def get_first_main(mainName: str) -> str:
if '伤害加成' in mainName: if '伤害加成' in mainName:
@ -428,6 +476,23 @@ async def draw_char_card(raw_data: dict, charUrl: str = None) -> bytes:
weapon_text.text((25, 335), weaponEffect, (255, 255, 255), genshin_font_origin(25)) weapon_text.text((25, 335), weaponEffect, (255, 255, 255), genshin_font_origin(25))
img.paste(weapon_img, (387, 590), weapon_img) img.paste(weapon_img, (387, 590), weapon_img)
fight_prop = raw_data['avatarFightProp']
hp = fight_prop['hp']
baseHp = fight_prop['baseHp']
attack = fight_prop['atk']
baseAtk = fight_prop['baseAtk']
defense = fight_prop['def']
baseDef = fight_prop['baseDef']
em = fight_prop['elementalMastery']
critrate = fight_prop['critRate']
critdmg = fight_prop['critDmg']
ce = fight_prop['energyRecharge']
dmgBonus = fight_prop['dmgBonus'] if fight_prop['physicalDmgBonus'] <= fight_prop['dmgBonus'] else fight_prop['physicalDmgBonus']
hp_green = fight_prop['addHp']
attack_green = fight_prop['addAtk']
defense_green = fight_prop['addDef']
# 圣遗物部分 # 圣遗物部分
artifactsAllScore = 0 artifactsAllScore = 0
for aritifact in raw_data['equipList']: for aritifact in raw_data['equipList']:
@ -473,14 +538,26 @@ async def draw_char_card(raw_data: dict, charUrl: str = None) -> bytes:
subValueStr = str(subValue) subValueStr = str(subValue)
else: else:
subValueStr = str(subValue) + '%' subValueStr = str(subValue) + '%'
artifactsScore += await get_artifacts_score(subName, subValue) #artifactsScore += await get_artifacts_score(subName, subValue)
value_temp = await get_artifacts_value(subName, subValue, baseAtk, baseHp, baseDef, char_name)
artifactsScore += value_temp
subNameStr = subName.replace('百分比', '').replace('元素', '') subNameStr = subName.replace('百分比', '').replace('元素', '')
artifacts_text.text((20, 256 + index * 33), '·{}'.format(subNameStr), (255, 255, 255), if value_temp == 0:
artifacts_color = (160, 160, 160)
elif value_temp >= 4.5:
artifacts_color = (247, 50, 50)
else:
artifacts_color = (255, 255, 100)
artifacts_text.text((20, 256 + index * 33), '·{}'.format(subNameStr), artifacts_color,
genshin_font_origin(25), anchor='lm') genshin_font_origin(25), anchor='lm')
artifacts_text.text((268, 256 + index * 33), '{}'.format(subValueStr), (255, 255, 255), artifacts_text.text((268, 256 + index * 33), '{}'.format(subValueStr), artifacts_color,
genshin_font_origin(25), anchor='rm') genshin_font_origin(25), anchor='rm')
if artifactsScore >= 6:
artifactsScore_color = (247, 26, 26)
else:
artifactsScore_color = (255, 255, 255)
artifactsAllScore += artifactsScore artifactsAllScore += artifactsScore
artifacts_text.text((268, 190), f'{math.ceil(artifactsScore)}', (255, 255, 255), genshin_font_origin(23), artifacts_text.text((268, 190), '{:.2f}'.format(artifactsScore) + '', artifactsScore_color, genshin_font_origin(23),
anchor='rm') anchor='rm')
if artifactsPos == '生之花': if artifactsPos == '生之花':
@ -510,20 +587,6 @@ async def draw_char_card(raw_data: dict, charUrl: str = None) -> bytes:
# img_text.text((110, 973), q_skill_name, (255, 255, 255), genshin_font_origin(26), anchor='lm') # img_text.text((110, 973), q_skill_name, (255, 255, 255), genshin_font_origin(26), anchor='lm')
img_text.text((103, 1016), f'{str(q_skill_level)}', (255, 255, 255), genshin_font_origin(30), anchor='mm') img_text.text((103, 1016), f'{str(q_skill_level)}', (255, 255, 255), genshin_font_origin(30), anchor='mm')
fight_prop = raw_data['avatarFightProp']
hp = fight_prop['hp']
attack = fight_prop['atk']
defense = fight_prop['def']
em = fight_prop['elementalMastery']
critrate = fight_prop['critRate']
critdmg = fight_prop['critDmg']
ce = fight_prop['energyRecharge']
dmgBonus = fight_prop['dmgBonus'] if fight_prop['physicalDmgBonus'] <= fight_prop['dmgBonus'] else fight_prop['physicalDmgBonus']
hp_green = fight_prop['addHp']
attack_green = fight_prop['addAtk']
defense_green = fight_prop['addDef']
# 属性 # 属性
img_text.text((785, 174), str(round(hp)), (255, 255, 255), genshin_font_origin(28), anchor='rm') img_text.text((785, 174), str(round(hp)), (255, 255, 255), genshin_font_origin(28), anchor='rm')
img_text.text((785, 227), str(round(attack)), (255, 255, 255), genshin_font_origin(28), anchor='rm') img_text.text((785, 227), str(round(attack)), (255, 255, 255), genshin_font_origin(28), anchor='rm')
@ -559,3 +622,115 @@ async def draw_char_card(raw_data: dict, charUrl: str = None) -> bytes:
imgmes = 'base64://' + b64encode(result_buffer.getvalue()).decode() imgmes = 'base64://' + b64encode(result_buffer.getvalue()).decode()
res = imgmes res = imgmes
return res return res
async def draw_single_card(img: Image, char: dict, index: int, color: Tuple[int, int, int],
x_limit: int, char_card_mask: Image, char_card_1: Image, img_card: Image):
size_36 = genshin_font_origin(36)
size_46 = genshin_font_origin(46)
img_base = Image.open(TEXT_PATH / '{}.png'.format(char['avatarElement']))
if char['char_name'] in avatarCardOffsetMap:
offset_x, offset_y = avatarCardOffsetMap[char['char_name']][0], avatarCardOffsetMap[char['char_name']][1]
else:
offset_x, offset_y = 200, 0
char_img = Image.open(GACHA_PATH / 'UI_Gacha_AvatarImg_{}.png'.format(char['avatarEnName']))
img_base.paste(char_img, (-439 + offset_x, 130 + offset_y), char_img)
img_card.paste(img_base, (-25, -260), char_card_mask)
img_card = Image.alpha_composite(img_card, char_card_1)
#img_card.paste(img_card, (0, 0), img_card)
char_card_text = ImageDraw.Draw(img_card)
char_card_text.text((448, 59.2), f'{str(round(char["critrate"] * 100, 2))}%', color, size_36, anchor='lm')
char_card_text.text((448, 122.2), f'{str(round(char["critdmg"] * 100, 2))}%', color, size_36, anchor='lm')
char_card_text.text((410.9, 252.6), str(char['a_skill_level']), color, size_36, anchor='mm')
char_card_text.text((485, 252.6), str(char['e_skill_level']), color, size_36, anchor='mm')
char_card_text.text((558, 252.6), str(char['q_skill_level']), color, size_36, anchor='mm')
if float(char['percent']) >= 100:
percent_color = (204, 57, 78)
else:
percent_color = color
if char['value'] >= 28.5:
value_color = (204, 57, 78)
else:
value_color = color
char_card_text.text((742, 253.1), str(char['percent']) + '%', percent_color, size_46, anchor='mm')
char_card_text.text((742, 113.1), str(char['value']) + '', value_color, size_46, anchor='mm')
char_card_text.text((21.2, 70.5), f'{str(char["talent_num"])}', color, size_36, anchor='lm')
char_card_text.text((21.2, 129.8), f'{str(char["weapon_affix"])}', color, size_36, anchor='lm')
img.paste(img_card, ((index % x_limit) * 900, (index // x_limit) * 300), img_card)
async def draw_cahrcard_list(uid: str,limit :int = 24) -> str:
uid_fold = PLAYER_PATH / str(uid)
char_file_list = uid_fold.glob('*')
char_list = []
for i in char_file_list:
file_name = i.name
if '\u4e00' <= file_name[0] <= '\u9fff':
char_list.append(file_name.split('.')[0])
if not char_list:
return '你还没有已缓存的角色!\n请先使用【强制刷新】进行刷新!'
char_done_list = []
for char_name in char_list:
temp = {}
with open(uid_fold / f'{char_name}.json', 'r', encoding='UTF-8') as f:
raw_data = json.load(f)
fight_prop = raw_data['avatarFightProp']
skillList = raw_data['avatarSkill']
temp['char_name'] = char_name
temp['avatarEnName'] = raw_data['avatarEnName']
temp['avatarElement'] = raw_data['avatarElement']
temp['percent'] = await get_char_percent(raw_data)
temp['critrate'] = fight_prop['critRate']
temp['critdmg'] = fight_prop['critDmg']
baseHp = fight_prop['baseHp']
baseAtk = fight_prop['baseAtk']
baseDef = fight_prop['baseDef']
temp['value'] = await get_all_artifacts_value(raw_data['equipList'], baseHp, baseAtk, baseDef, char_name)
temp['value'] = float('{:.2f}'.format(temp['value']))
temp['avatarElement'] = raw_data['avatarElement']
temp['a_skill_level'] = skillList[0]['skillLevel']
temp['e_skill_level'] = skillList[1]['skillLevel']
temp['q_skill_level'] = skillList[-1]['skillLevel']
temp['talent_num'] = len(raw_data['talentList'])
temp['weapon_affix'] = raw_data['weaponInfo']['weaponAffix']
char_done_list.append(temp)
# 排序
char_done_list.sort(key=lambda x: (-float(x['percent'])))
char_done_list = char_done_list[:limit]
char_card_1 = Image.open(TEXT_PATH / 'charcard_1.png')
char_card_mask = Image.open(TEXT_PATH / 'charcard_mask.png')
x_limit = 2
color = (255, 255, 255)
x_tile = (len(char_done_list) + x_limit - 1) // x_limit
y_tile = math.ceil(len(char_done_list) / x_tile)
x_tile, y_tile = x_tile if x_tile <= y_tile else y_tile, y_tile if y_tile >= x_tile else x_tile
img = Image.new('RGBA', (900 * x_tile, 300 * y_tile), (0, 0, 0))
img_card = Image.new('RGBA', (900, 300))
tasks = []
for index, char in enumerate(char_done_list):
tasks.append(draw_single_card(img, char, index, color, x_limit, char_card_mask, char_card_1, img_card))
await asyncio.wait(tasks)
img = img.convert('RGB')
result_buffer = BytesIO()
img.save(result_buffer, format='JPEG', subsampling=0, quality=90)
imgmes = 'base64://' + b64encode(result_buffer.getvalue()).decode()
res = imgmes
return res

View File

@ -0,0 +1,264 @@
{
"神里绫人": [
"血量",
"攻击力",
"暴击率",
"暴击伤害",
"元素精通"
],
"八重神子": [
"攻击力",
"暴击率",
"暴击伤害",
"元素精通",
""
],
"申鹤": [
"攻击力",
"元素充能效率"
],
"云堇": [
"防御力",
"元素充能效率"
],
"荒泷一斗": [
"防御力",
"暴击率",
"暴击伤害"
],
"五郎": [
"防御力",
"元素充能效率"
],
"班尼特": [
"血量",
"攻击力",
"暴击率",
"暴击伤害",
"元素 充能效率"
],
"枫原万叶": [
"元素精通",
"暴击率",
"暴击伤害",
"元素充能效率"
],
"雷电将军": [
"攻击力",
"暴击率",
"暴击伤害",
"元素充能效率"
],
"行秋": [
"攻击力",
"暴击率",
"暴击伤害",
"元素充能效率"
],
"钟离": [
"血量",
"攻击力",
"暴击率",
"暴击伤害",
"元素充能效率"
],
"神里绫华": [
"攻击力",
"暴击率",
"暴击伤害"
],
"香菱": [
"攻击力",
"暴击率",
"暴击伤害",
"元素充能效率",
"元素精通"
],
"胡桃": [
"血量",
"暴击率",
"暴击伤害",
"元素精通"
],
"甘雨": [
"攻击力",
"暴击率",
"暴击伤害",
"元素精通"
],
"温迪": [
"元素精通",
"暴击率",
"暴击伤害",
"元素充能效率"
],
"珊瑚宫心海": [
"血量",
"元素充能效率"
],
"莫娜": [
"元素精通",
"暴击率",
"暴击伤害",
"元素充能效率"
],
"阿贝多": [
"防御力",
"暴击率",
"暴击伤害"
],
"迪奥娜": [
"血量",
"元素充能效率"
],
"优菈": [
"攻击力",
"暴击率",
"暴击伤害"
],
"达达利亚": [
"攻击力",
"暴击率",
"暴击伤害",
"元素精通"
],
"魈": [
"攻击力",
"暴击率",
"暴击伤害"
],
"宵宫": [
"攻击力",
"暴击率",
"暴击伤害",
"元素精通"
],
"九条裟罗": [
"攻击力",
"暴击率",
"暴击伤害",
"元素充能效率"
],
"琴": [
"攻击力",
"暴击率",
"暴击伤害",
"元素充能效率"
],
"菲谢尔": [
"攻击力",
"暴击率",
"暴击伤害"
],
"罗莎莉亚": [
"攻击力",
"暴击率",
"暴击伤害"
],
"可莉": [
"攻击力",
"暴击率",
"暴击伤害"
],
"凝光": [
"攻击力",
"暴击率",
"暴击伤害"
],
"北斗": [
"攻击力",
"暴击率",
"暴击伤害"
],
"刻晴": [
"攻击力",
"暴击率",
"暴击伤害"
],
"托马": [
"血量",
"元素充能效率"
],
"迪卢克": [
"攻击力",
"暴击率",
"暴击伤害",
"元素精通"
],
"芭芭拉": [
"血量",
"元素充能效率"
],
"诺艾尔": [
"防御力",
"暴击率",
"暴击伤害"
],
"旅行者": [
"攻击力",
"暴击率",
"暴击伤害"
],
"重云": [
"攻击力",
"暴击率",
"暴击伤害"
],
"七七": [
"攻击力",
"暴击率",
"暴击伤害",
"元素充能效率"
],
"凯亚": [
"攻击力",
"暴击率",
"暴击伤害"
],
"烟绯": [
"攻击力",
"暴击率",
"暴击伤害",
"元素精通"
],
"早柚": [
"元素精通",
"元素充能效率"
],
"安柏": [
"攻击力",
"暴击率",
"暴击伤害",
"元素精通"
],
"丽莎": [
"攻击力",
"暴击率",
"暴击伤害"
],
"埃洛伊": [
"攻击力",
"暴击率",
"暴击伤害"
],
"辛焱": [
"攻击力",
"暴击率",
"暴击伤害"
],
"砂糖": [
"元素精通",
"元素充能效率"
],
"雷泽": [
"攻击力",
"暴击率",
"暴击伤害"
],
"夜兰": [
"血量",
"暴击率",
"暴击伤害",
"元素充能效率"
]
}

View File

@ -0,0 +1 @@
{"凯特": [200, 0], "神里绫华": [0, 0], "琴": [100, 0], "旅行者": [200, 0], "丽莎": [200, -100], "芭芭拉": [200, 0], "凯亚": [150, -150], "迪卢克": [300, 0], "雷泽": [400, 0], "安柏": [0, 200], "温迪": [100, 0], "香菱": [-100, -250], "北斗": [200, 0], "行秋": [250, -100], "魈": [200, 200], "凝光": [500, 0], "可莉": [0, 0], "钟离": [100, 0], "菲谢尔": [300, 0], "班尼特": [150, 150], "达达利亚": [0, 0], "诺艾尔": [300, -80], "七七": [200, 100], "重云": [200, 0], "甘雨": [100, 0], "阿贝多": [200, 0], "迪奥娜": [-300, 0], "莫娜": [200, 0], "刻晴": [400, 250], "砂糖": [50, 0], "辛焱": [250, 0], "罗莎莉亚": [200, 0], "胡桃": [560, 0], "枫原万叶": [150, -200], "烟绯": [-400, 0], "宵宫": [250, 0], "托马": [200, 0], "优菈": [-200, 0], "雷电将军": [100, 0], "早柚": [500, 0], "珊瑚宫心海": [200, 0], "五郎": [60, 0], "九条裟罗": [100, 0], "荒泷一斗": [100, 0], "八重神子": [300, 0], "夜兰": [80, 0], "埃洛伊": [60, 0], "申鹤": [360, 0], "云堇": [100, 0], "久岐忍": [200, 0], "神里绫人": [50, 0], "队伍测试4号": [200, 0], "场景测试": [200, 0], "裸模1号": [200, 0], "裸男": [200, 0], "联机测试": [200, 0], "成男体型测试": [200, 0], "成女体型测试": [200, 0], "少女体型测试": [200, 0], "阿葵丽雅": [200, 0], "瑶瑶": [200, 0], "少女体型测试-二号机": [200, 0], "白盒少女": [200, 0], "大剑少女": [200, 0], "后武器测试A": [200, 0], "后武器测试B": [200, 0], "后武器测试C": [200, 0], "后武器测试D": [200, 0], "长枪成女": [200, 0], "单手剑成女测试": [200, 0], "Rx白盒": [200, 0], "少男体型测试": [200, 0], "女主新普攻": [200, 0], "男主新普攻": [200, 0], "重云(测试)": [200, 0], "测试角色": [200, 0], "七七(测试)": [200, 0], "迪奥娜(测试)": [200, 0]}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB