🚨修复更多的错误
@ -12,6 +12,7 @@ from gsuid_core.utils.image.convert import convert_img
|
|||||||
from gsuid_core.utils.image.image_tools import draw_text_by_line
|
from gsuid_core.utils.image.image_tools import draw_text_by_line
|
||||||
|
|
||||||
from .mono.Character import Character
|
from .mono.Character import Character
|
||||||
|
from ..utils.fonts.first_world import fw_font_120
|
||||||
from ..utils.map.SR_MAP_PATH import RelicId2Rarity
|
from ..utils.map.SR_MAP_PATH import RelicId2Rarity
|
||||||
from ..utils.excel.read_excel import light_cone_ranks
|
from ..utils.excel.read_excel import light_cone_ranks
|
||||||
from ..utils.map.name_covert import name_to_avatar_id, alias_to_char_name
|
from ..utils.map.name_covert import name_to_avatar_id, alias_to_char_name
|
||||||
@ -292,7 +293,6 @@ async def draw_char_info_img(raw_mes: str, sr_uid: str, url: Optional[str]):
|
|||||||
char_info.paste(attr_bg, (517, 265), attr_bg)
|
char_info.paste(attr_bg, (517, 265), attr_bg)
|
||||||
|
|
||||||
# 命座
|
# 命座
|
||||||
lock_img = Image.open(TEXT_PATH / 'icon_lock.png').resize((50, 50))
|
|
||||||
for rank in range(0, 6):
|
for rank in range(0, 6):
|
||||||
rank_bg = Image.open(TEXT_PATH / 'mz_bg.png')
|
rank_bg = Image.open(TEXT_PATH / 'mz_bg.png')
|
||||||
if rank < char.char_rank:
|
if rank < char.char_rank:
|
||||||
@ -302,18 +302,23 @@ async def draw_char_info_img(raw_mes: str, sr_uid: str, url: Optional[str]):
|
|||||||
rank_bg.paste(rank_img, (19, 19), rank_img)
|
rank_bg.paste(rank_img, (19, 19), rank_img)
|
||||||
char_info.paste(rank_bg, (20 + rank * 80, 630), rank_bg)
|
char_info.paste(rank_bg, (20 + rank * 80, 630), rank_bg)
|
||||||
else:
|
else:
|
||||||
rank_img = Image.open(
|
rank_img = (
|
||||||
SKILL_PATH / f'{char.char_id}{RANK_MAP[rank + 1]}'
|
Image.open(SKILL_PATH / f'{char.char_id}{RANK_MAP[rank + 1]}')
|
||||||
).resize((50, 50))
|
.resize((50, 50))
|
||||||
|
.convert("RGBA")
|
||||||
|
)
|
||||||
|
alpha = rank_img.getchannel('A')
|
||||||
|
alpha = alpha.point(lambda i: i // 2)
|
||||||
|
rank_img.putalpha(alpha)
|
||||||
rank_bg.paste(rank_img, (19, 19), rank_img)
|
rank_bg.paste(rank_img, (19, 19), rank_img)
|
||||||
rank_bg.paste(lock_img, (19, 19), lock_img)
|
# rank_bg.paste(lock_img, (19, 19), lock_img)
|
||||||
char_info.paste(rank_bg, (20 + rank * 80, 630), rank_bg)
|
char_info.paste(rank_bg, (20 + rank * 80, 630), rank_bg)
|
||||||
|
|
||||||
# 技能
|
# 技能
|
||||||
skill_bg = Image.open(TEXT_PATH / 'skill_bg.png')
|
skill_bg = Image.open(TEXT_PATH / 'skill_bg.png')
|
||||||
i = 0
|
i = 0
|
||||||
for skill in char.char_skill:
|
for skill in char.char_skill:
|
||||||
skill_attr_img = Image.open(TEXT_PATH / 'skill_attr4.png')
|
skill_attr_img = Image.open(TEXT_PATH / f'skill_attr{i + 1}.png')
|
||||||
skill_panel_img = Image.open(TEXT_PATH / 'skill_panel.png')
|
skill_panel_img = Image.open(TEXT_PATH / 'skill_panel.png')
|
||||||
skill_img = Image.open(
|
skill_img = Image.open(
|
||||||
SKILL_PATH / f'{char.char_id}_'
|
SKILL_PATH / f'{char.char_id}_'
|
||||||
@ -348,157 +353,182 @@ async def draw_char_info_img(raw_mes: str, sr_uid: str, url: Optional[str]):
|
|||||||
char_info.paste(skill_bg, (0, 710), skill_bg)
|
char_info.paste(skill_bg, (0, 710), skill_bg)
|
||||||
|
|
||||||
# 武器
|
# 武器
|
||||||
weapon_bg = Image.open(TEXT_PATH / 'weapon_bg.png')
|
if char.equipment != {}:
|
||||||
weapon_id = char.equipment['equipmentID']
|
weapon_bg = Image.open(TEXT_PATH / 'weapon_bg.png')
|
||||||
weapon_img = Image.open(WEAPON_PATH / f'{weapon_id}.png').resize(
|
weapon_id = char.equipment['equipmentID']
|
||||||
(240, 240)
|
weapon_img = Image.open(WEAPON_PATH / f'{weapon_id}.png').resize(
|
||||||
)
|
(240, 240)
|
||||||
weapon_bg.paste(weapon_img, (-10, 50), weapon_img)
|
)
|
||||||
weapon_bg_draw = ImageDraw.Draw(weapon_bg)
|
weapon_bg.paste(weapon_img, (-10, 50), weapon_img)
|
||||||
weapon_bg_draw.text(
|
weapon_bg_draw = ImageDraw.Draw(weapon_bg)
|
||||||
(370, 47),
|
weapon_bg_draw.text(
|
||||||
f'{char.equipment["equipmentName"]}',
|
(370, 47),
|
||||||
white_color,
|
f'{char.equipment["equipmentName"]}',
|
||||||
sr_font_34,
|
white_color,
|
||||||
'mm',
|
sr_font_34,
|
||||||
)
|
'mm',
|
||||||
weapon_bg_draw.text(
|
)
|
||||||
(536, 47),
|
weapon_bg_draw.text(
|
||||||
f'{NUM_MAP[char.equipment["equipmentRank"]]} 阶',
|
(536, 47),
|
||||||
white_color,
|
f'{NUM_MAP[char.equipment["equipmentRank"]]} 阶',
|
||||||
sr_font_28,
|
white_color,
|
||||||
'mm',
|
sr_font_28,
|
||||||
)
|
'mm',
|
||||||
rarity_img = Image.open(
|
)
|
||||||
TEXT_PATH / f'LightCore_Rarity{char.equipment["equipmentRarity"]}.png'
|
|
||||||
).resize((306, 72))
|
|
||||||
weapon_bg.paste(rarity_img, (160, 55), rarity_img)
|
|
||||||
weapon_bg_draw.text(
|
|
||||||
(430, 90),
|
|
||||||
f'Lv.{char.equipment["equipmentLevel"]}',
|
|
||||||
white_color,
|
|
||||||
sr_font_28,
|
|
||||||
'mm',
|
|
||||||
)
|
|
||||||
|
|
||||||
# 武器技能
|
|
||||||
desc = light_cone_ranks[str(char.equipment['equipmentID'])]['desc']
|
|
||||||
desc_params = light_cone_ranks[str(char.equipment['equipmentID'])][
|
|
||||||
'params'
|
|
||||||
][char.equipment['equipmentRank'] - 1]
|
|
||||||
for i in range(0, len(desc_params)):
|
|
||||||
temp = math.floor(desc_params[i] * 1000) / 10
|
|
||||||
desc = desc.replace(f'#{i + 1}[i]%', f'{str(temp)}%')
|
|
||||||
for i in range(0, len(desc_params)):
|
|
||||||
desc = desc.replace(f'#{i + 1}[i]', str(desc_params[i]))
|
|
||||||
draw_text_by_line(weapon_bg, (220, 115), desc, sr_font_24, '#F9F9F9', 372)
|
|
||||||
char_info.paste(weapon_bg, (22, 870), weapon_bg)
|
|
||||||
|
|
||||||
# 遗器
|
|
||||||
weapon_rank_bg = Image.open(TEXT_PATH / 'rank_bg.png')
|
|
||||||
char_info.paste(weapon_rank_bg, (690, 880), weapon_rank_bg)
|
|
||||||
|
|
||||||
for relic in char.char_relic:
|
|
||||||
relic_img = Image.open(TEXT_PATH / 'yq_bg3.png')
|
|
||||||
if str(relic["SetId"])[0] == '3':
|
|
||||||
relic_piece_img = Image.open(
|
|
||||||
RELIC_PATH / f'{relic["SetId"]}_{relic["Type"] - 5}.png'
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
relic_piece_img = Image.open(
|
|
||||||
RELIC_PATH / f'{relic["SetId"]}_{relic["Type"] - 1}.png'
|
|
||||||
)
|
|
||||||
relic_piece_new_img = relic_piece_img.resize(
|
|
||||||
(105, 105), Image.Resampling.LANCZOS
|
|
||||||
).convert("RGBA")
|
|
||||||
relic_img.paste(relic_piece_new_img, (200, 90), relic_piece_new_img)
|
|
||||||
rarity_img = Image.open(
|
rarity_img = Image.open(
|
||||||
TEXT_PATH
|
TEXT_PATH
|
||||||
/ f'LightCore_Rarity{RelicId2Rarity[str(relic["relicId"])]}.png'
|
/ f'LightCore_Rarity{char.equipment["equipmentRarity"]}.png'
|
||||||
).resize((200, 48))
|
).resize((306, 72))
|
||||||
relic_img.paste(rarity_img, (-10, 80), rarity_img)
|
weapon_bg.paste(rarity_img, (160, 55), rarity_img)
|
||||||
relic_img_draw = ImageDraw.Draw(relic_img)
|
weapon_bg_draw.text(
|
||||||
if len(relic['relicName']) <= 5:
|
(430, 90),
|
||||||
main_name = relic['relicName']
|
f'Lv.{char.equipment["equipmentLevel"]}',
|
||||||
else:
|
white_color,
|
||||||
main_name = relic['relicName'][:2] + relic['relicName'][4:]
|
|
||||||
relic_img_draw.text(
|
|
||||||
(30, 70),
|
|
||||||
main_name,
|
|
||||||
(255, 255, 255),
|
|
||||||
sr_font_34,
|
|
||||||
anchor='lm',
|
|
||||||
)
|
|
||||||
|
|
||||||
# 主属性
|
|
||||||
main_value = mp.mpf(relic['MainAffix']['Value'])
|
|
||||||
main_name: str = relic['MainAffix']['Name']
|
|
||||||
main_level: int = relic['Level']
|
|
||||||
|
|
||||||
if main_name in ['攻击力', '生命值', '防御力', '速度']:
|
|
||||||
mainValueStr = nstr(main_value, 3)
|
|
||||||
else:
|
|
||||||
mainValueStr = str(math.floor(main_value * 1000) / 10) + '%'
|
|
||||||
|
|
||||||
mainNameNew = (
|
|
||||||
main_name.replace('百分比', '')
|
|
||||||
.replace('伤害加成', '伤加成')
|
|
||||||
.replace('属性伤害', '伤害')
|
|
||||||
)
|
|
||||||
|
|
||||||
relic_img_draw.text(
|
|
||||||
(35, 150),
|
|
||||||
mainNameNew,
|
|
||||||
(255, 255, 255),
|
|
||||||
sr_font_28,
|
sr_font_28,
|
||||||
anchor='lm',
|
'mm',
|
||||||
)
|
|
||||||
relic_img_draw.text(
|
|
||||||
(35, 195),
|
|
||||||
'+{}'.format(mainValueStr),
|
|
||||||
(255, 255, 255),
|
|
||||||
sr_font_28,
|
|
||||||
anchor='lm',
|
|
||||||
)
|
|
||||||
relic_img_draw.text(
|
|
||||||
(180, 105),
|
|
||||||
'+{}'.format(str(main_level)),
|
|
||||||
(255, 255, 255),
|
|
||||||
sr_font_23,
|
|
||||||
anchor='mm',
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# relicScore = 0
|
# 武器技能
|
||||||
for index, i in enumerate(relic['SubAffixList']):
|
desc = light_cone_ranks[str(char.equipment['equipmentID'])]['desc']
|
||||||
subName: str = i['Name']
|
desc_params = light_cone_ranks[str(char.equipment['equipmentID'])][
|
||||||
subValue = mp.mpf(i['Value'])
|
'params'
|
||||||
if subName in ['攻击力', '生命值', '防御力', '速度']:
|
][char.equipment['equipmentRank'] - 1]
|
||||||
subValueStr = nstr(subValue, 3)
|
for i in range(0, len(desc_params)):
|
||||||
|
temp = math.floor(desc_params[i] * 1000) / 10
|
||||||
|
desc = desc.replace(f'#{i + 1}[i]%', f'{str(temp)}%')
|
||||||
|
for i in range(0, len(desc_params)):
|
||||||
|
desc = desc.replace(f'#{i + 1}[i]', str(desc_params[i]))
|
||||||
|
draw_text_by_line(
|
||||||
|
weapon_bg, (220, 115), desc, sr_font_24, '#F9F9F9', 372
|
||||||
|
)
|
||||||
|
char_info.paste(weapon_bg, (22, 870), weapon_bg)
|
||||||
|
else:
|
||||||
|
char_img_draw.text(
|
||||||
|
(525, 1005),
|
||||||
|
'No light cone!',
|
||||||
|
white_color,
|
||||||
|
fw_font_120,
|
||||||
|
'mm',
|
||||||
|
)
|
||||||
|
|
||||||
|
# 遗器
|
||||||
|
if char.char_relic:
|
||||||
|
weapon_rank_bg = Image.open(TEXT_PATH / 'rank_bg.png')
|
||||||
|
char_info.paste(weapon_rank_bg, (690, 880), weapon_rank_bg)
|
||||||
|
|
||||||
|
for relic in char.char_relic:
|
||||||
|
relic_img = Image.open(TEXT_PATH / 'yq_bg3.png')
|
||||||
|
if str(relic["SetId"])[0] == '3':
|
||||||
|
relic_piece_img = Image.open(
|
||||||
|
RELIC_PATH / f'{relic["SetId"]}_{relic["Type"] - 5}.png'
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
subValueStr = nstr(subValue * 100, 3) + '%'
|
relic_piece_img = Image.open(
|
||||||
subNameStr = subName.replace('百分比', '').replace('元素', '')
|
RELIC_PATH / f'{relic["SetId"]}_{relic["Type"] - 1}.png'
|
||||||
# 副词条文字颜色
|
)
|
||||||
relic_color = (255, 255, 255)
|
relic_piece_new_img = relic_piece_img.resize(
|
||||||
|
(105, 105), Image.Resampling.LANCZOS
|
||||||
|
).convert("RGBA")
|
||||||
|
relic_img.paste(
|
||||||
|
relic_piece_new_img, (200, 90), relic_piece_new_img
|
||||||
|
)
|
||||||
|
rarity_img = Image.open(
|
||||||
|
TEXT_PATH / f'LightCore_Rarity'
|
||||||
|
f'{RelicId2Rarity[str(relic["relicId"])]}.png'
|
||||||
|
).resize((200, 48))
|
||||||
|
relic_img.paste(rarity_img, (-10, 80), rarity_img)
|
||||||
|
relic_img_draw = ImageDraw.Draw(relic_img)
|
||||||
|
if len(relic['relicName']) <= 5:
|
||||||
|
main_name = relic['relicName']
|
||||||
|
else:
|
||||||
|
main_name = relic['relicName'][:2] + relic['relicName'][4:]
|
||||||
|
relic_img_draw.text(
|
||||||
|
(30, 70),
|
||||||
|
main_name,
|
||||||
|
(255, 255, 255),
|
||||||
|
sr_font_34,
|
||||||
|
anchor='lm',
|
||||||
|
)
|
||||||
|
|
||||||
|
# 主属性
|
||||||
|
main_value = mp.mpf(relic['MainAffix']['Value'])
|
||||||
|
main_name: str = relic['MainAffix']['Name']
|
||||||
|
main_level: int = relic['Level']
|
||||||
|
|
||||||
|
if main_name in ['攻击力', '生命值', '防御力', '速度']:
|
||||||
|
mainValueStr = nstr(main_value, 3)
|
||||||
|
else:
|
||||||
|
mainValueStr = str(math.floor(main_value * 1000) / 10) + '%'
|
||||||
|
|
||||||
|
mainNameNew = (
|
||||||
|
main_name.replace('百分比', '')
|
||||||
|
.replace('伤害加成', '伤加成')
|
||||||
|
.replace('属性伤害', '伤害')
|
||||||
|
)
|
||||||
|
|
||||||
relic_img_draw.text(
|
relic_img_draw.text(
|
||||||
(47, 237 + index * 47),
|
(35, 150),
|
||||||
'{}'.format(subNameStr),
|
mainNameNew,
|
||||||
relic_color,
|
(255, 255, 255),
|
||||||
sr_font_26,
|
sr_font_28,
|
||||||
anchor='lm',
|
anchor='lm',
|
||||||
)
|
)
|
||||||
relic_img_draw.text(
|
relic_img_draw.text(
|
||||||
(290, 237 + index * 47),
|
(35, 195),
|
||||||
'{}'.format(subValueStr),
|
'+{}'.format(mainValueStr),
|
||||||
relic_color,
|
(255, 255, 255),
|
||||||
sr_font_26,
|
sr_font_28,
|
||||||
anchor='rm',
|
anchor='lm',
|
||||||
|
)
|
||||||
|
relic_img_draw.text(
|
||||||
|
(180, 105),
|
||||||
|
'+{}'.format(str(main_level)),
|
||||||
|
(255, 255, 255),
|
||||||
|
sr_font_23,
|
||||||
|
anchor='mm',
|
||||||
)
|
)
|
||||||
|
|
||||||
char_info.paste(relic_img, RELIC_POS[str(relic["Type"])], relic_img)
|
# relicScore = 0
|
||||||
|
for index, i in enumerate(relic['SubAffixList']):
|
||||||
|
subName: str = i['Name']
|
||||||
|
subValue = mp.mpf(i['Value'])
|
||||||
|
if subName in ['攻击力', '生命值', '防御力', '速度']:
|
||||||
|
subValueStr = nstr(subValue, 3)
|
||||||
|
else:
|
||||||
|
subValueStr = nstr(subValue * 100, 3) + '%'
|
||||||
|
subNameStr = subName.replace('百分比', '').replace('元素', '')
|
||||||
|
# 副词条文字颜色
|
||||||
|
relic_color = (255, 255, 255)
|
||||||
|
|
||||||
|
relic_img_draw.text(
|
||||||
|
(47, 237 + index * 47),
|
||||||
|
'{}'.format(subNameStr),
|
||||||
|
relic_color,
|
||||||
|
sr_font_26,
|
||||||
|
anchor='lm',
|
||||||
|
)
|
||||||
|
relic_img_draw.text(
|
||||||
|
(290, 237 + index * 47),
|
||||||
|
'{}'.format(subValueStr),
|
||||||
|
relic_color,
|
||||||
|
sr_font_26,
|
||||||
|
anchor='rm',
|
||||||
|
)
|
||||||
|
|
||||||
|
char_info.paste(
|
||||||
|
relic_img, RELIC_POS[str(relic["Type"])], relic_img
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
char_img_draw.text(
|
||||||
|
(525, 1565),
|
||||||
|
'No relic!',
|
||||||
|
white_color,
|
||||||
|
fw_font_120,
|
||||||
|
'mm',
|
||||||
|
)
|
||||||
|
|
||||||
# 发送图片
|
# 发送图片
|
||||||
# char_info.show()
|
char_info.show()
|
||||||
res = await convert_img(char_info)
|
res = await convert_img(char_info)
|
||||||
logger.info('[sr面板]绘图已完成,等待发送!')
|
logger.info('[sr面板]绘图已完成,等待发送!')
|
||||||
return res
|
return res
|
||||||
|
@ -37,35 +37,38 @@ class Character:
|
|||||||
self.seq_str: str = '无匹配'
|
self.seq_str: str = '无匹配'
|
||||||
|
|
||||||
async def get_equipment_info(self):
|
async def get_equipment_info(self):
|
||||||
base_attr = self.base_attributes
|
if self.equipment == {}:
|
||||||
equip = self.equipment
|
return
|
||||||
ability_property = EquipmentID2AbilityProperty[
|
else:
|
||||||
str(equip['equipmentID'])
|
base_attr = self.base_attributes
|
||||||
]
|
equip = self.equipment
|
||||||
equip_rank = equip['equipmentRank']
|
ability_property = EquipmentID2AbilityProperty[
|
||||||
|
str(equip['equipmentID'])
|
||||||
|
]
|
||||||
|
equip_rank = equip['equipmentRank']
|
||||||
|
|
||||||
equip_ability_property = ability_property[str(equip_rank)]
|
equip_ability_property = ability_property[str(equip_rank)]
|
||||||
|
|
||||||
equip_add_base_attr = equip['baseAttributes']
|
equip_add_base_attr = equip['baseAttributes']
|
||||||
hp = mp.mpf(base_attr['hp']) + mp.mpf(equip_add_base_attr['hp'])
|
hp = mp.mpf(base_attr['hp']) + mp.mpf(equip_add_base_attr['hp'])
|
||||||
attack = mp.mpf(base_attr['attack']) + mp.mpf(
|
attack = mp.mpf(base_attr['attack']) + mp.mpf(
|
||||||
equip_add_base_attr['attack']
|
equip_add_base_attr['attack']
|
||||||
)
|
)
|
||||||
defence = mp.mpf(base_attr['defence']) + mp.mpf(
|
defence = mp.mpf(base_attr['defence']) + mp.mpf(
|
||||||
equip_add_base_attr['defence']
|
equip_add_base_attr['defence']
|
||||||
)
|
)
|
||||||
base_attr['hp'] = str(hp)
|
base_attr['hp'] = str(hp)
|
||||||
base_attr['attack'] = str(attack)
|
base_attr['attack'] = str(attack)
|
||||||
base_attr['defence'] = str(defence)
|
base_attr['defence'] = str(defence)
|
||||||
self.base_attributes = base_attr
|
self.base_attributes = base_attr
|
||||||
|
|
||||||
for equip_ability in equip_ability_property:
|
for equip_ability in equip_ability_property:
|
||||||
property_type = equip_ability['PropertyType']
|
property_type = equip_ability['PropertyType']
|
||||||
value = equip_ability['Value']['Value']
|
value = equip_ability['Value']['Value']
|
||||||
if property_type in self.add_attr:
|
if property_type in self.add_attr:
|
||||||
self.add_attr[property_type] += value
|
self.add_attr[property_type] += value
|
||||||
else:
|
else:
|
||||||
self.add_attr[property_type] = value
|
self.add_attr[property_type] = value
|
||||||
|
|
||||||
async def get_char_attribute_bonus(self):
|
async def get_char_attribute_bonus(self):
|
||||||
attribute_bonus = self.attribute_bonus
|
attribute_bonus = self.attribute_bonus
|
||||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 907 B |
BIN
StarRailUID/starrailuid_charinfo/texture2D/skill_attr5.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
StarRailUID/utils/fonts/FirstWorld.ttf
Normal file
13
StarRailUID/utils/fonts/first_world.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from PIL import ImageFont
|
||||||
|
|
||||||
|
FONT_ORIGIN_PATH = Path(__file__).parent / 'FirstWorld.ttf'
|
||||||
|
|
||||||
|
|
||||||
|
def first_word_origin(size: int) -> ImageFont.FreeTypeFont:
|
||||||
|
return ImageFont.truetype(str(FONT_ORIGIN_PATH), size=size)
|
||||||
|
|
||||||
|
|
||||||
|
fw_font_12 = first_word_origin(12)
|
||||||
|
fw_font_120 = first_word_origin(34)
|