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

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 json
import json,asyncio
from io import BytesIO
from pathlib import Path
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),
'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}
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
with open(ETC_PATH / 'dmgMap.json', 'r', encoding='UTF-8') as 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:
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:
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:
score = subValue * SCORE_VALUE_MAP[subName]
score = subValue * SCORE_MAP[subName]
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:
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))
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
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)
else:
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('元素', '')
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')
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')
if artifactsScore >= 6:
artifactsScore_color = (247, 26, 26)
else:
artifactsScore_color = (255, 255, 255)
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')
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((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, 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()
res = imgmes
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