LittlePaimon/Paimon_Gacha/gacha_res.py

250 lines
9.5 KiB
Python
Raw Normal View History

2022-04-30 14:13:39 +08:00
import json
import os
import datetime
import numpy
import random
from PIL import Image, PngImagePlugin, ImageDraw, ImageFont
from .gacha_info import init_user_info, user_info, save_user_info
from ..utils.util import pil2b64
RES_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'res', 'gacha_res')
font_path = os.path.join(RES_PATH, 'zh-cn.ttf')
count_font = ImageFont.truetype(font_path, 35)
time_font = ImageFont.truetype(font_path, 20)
with open(os.path.join(RES_PATH, 'type.json'), 'r', encoding="utf-8") as fp:
type_json = json.load(fp)
cache_img = {}
cache_item = {}
def random_int():
return numpy.random.randint(low=0, high=10000, size=None, dtype='l')
# 抽卡概率来自https://www.bilibili.com/read/cv10468091
# 角色抽卡概率
def character_probability(rank, count):
ret = 0
count += 1
if rank == 5 and count <= 73:
ret = 60
elif rank == 5 and count >= 74:
ret = 60 + 600 * (count - 73)
elif rank == 4 and count <= 8:
ret = 510
elif rank == 4 and count >= 9:
ret = 510 + 5100 * (count - 8)
return ret
# 武器抽卡概率
def weapon_probability(rank, count):
ret = 0
count += 1
if rank == 5 and count <= 62:
ret = 70
elif rank == 5 and count <= 73:
ret = 70 + 700 * (count - 62)
elif rank == 5 and count >= 74:
ret = 7770 + 350 * (count - 73)
elif rank == 4 and count <= 7:
ret = 600
elif rank == 4 and count == 8:
ret = 6600
elif rank == 4 and count >= 9:
ret = 6600 + 3000 * (count - 8)
return ret
def get_pool_type(gacha_type):
if gacha_type == 301 or gacha_type == 400:
return 'role'
if gacha_type == 200:
return 'permanent'
return 'weapon'
def get_rank(uid, pool_str):
value = random_int()
if pool_str == 'weapon':
index_5 = weapon_probability(5, user_info[uid]["gacha_list"][("gacha_5_%s" % pool_str)])
index_4 = weapon_probability(4, user_info[uid]["gacha_list"][("gacha_4_%s" % pool_str)]) + index_5
else:
index_5 = character_probability(5, user_info[uid]["gacha_list"][("gacha_5_%s" % pool_str)])
index_4 = character_probability(4, user_info[uid]["gacha_list"][("gacha_4_%s" % pool_str)]) + index_5
if value <= index_5:
return 5
elif value <= index_4:
return 4
else:
return 3
def is_Up(uid, rank, pool_str):
if pool_str == 'permanent':
return False
elif pool_str == 'weapon':
return random_int() <= 7500 or user_info[uid]["gacha_list"]["is_up_%s_weapon" % rank]
else:
return random_int() <= 5000 or user_info[uid]["gacha_list"]["is_up_%s_role" % rank]
def once(uid, gacha_data):
role = {}
init_user_info(uid)
pool_str = get_pool_type(gacha_data['gacha_type'])
# 判定星级
rank = get_rank(uid, pool_str)
# 是否为up
if rank != 3:
is_up = is_Up(uid, rank, pool_str)
user_info[uid]["gacha_list"]["wish_total"] += 1
if rank == 3:
role = random.choice(gacha_data['r3_prob_list'])
user_info[uid]["gacha_list"][("gacha_4_%s" % pool_str)] += 1
user_info[uid]["gacha_list"][("gacha_5_%s" % pool_str)] += 1
role['count'] = 1
else:
if rank == 5 and pool_str == 'weapon' and user_info[uid]["gacha_list"]["dg_time"] == 2 and "pool_type" not in gacha_data:
role['item_name'] = user_info[uid]["gacha_list"]["dg_name"]
role['item_type'] = '武器'
role['rank'] = rank
elif is_up:
role = random.choice(gacha_data['r%s_up_items' % rank])
user_info[uid]["gacha_list"]["wish_%s_up" % rank] += 1
role['rank'] = rank
else:
role = random.choice(gacha_data['r%s_prob_list' % rank])
while True:
role = random.choice(gacha_data['r%s_prob_list' % rank])
if role['is_up'] == 0:
break
if rank == 4:
user_info[uid]["gacha_list"][("gacha_5_%s" % pool_str)] += 1
elif rank == 5:
user_info[uid]["gacha_list"][("gacha_4_%s" % pool_str)] += 1
if pool_str == 'weapon' and "pool_type" not in gacha_data:
if user_info[uid]["gacha_list"]["dg_name"] == '':
role['dg_time'] = -1
elif role['item_name'] != user_info[uid]["gacha_list"]["dg_name"]:
user_info[uid]["gacha_list"]["dg_time"] += 1
role['dg_time'] = user_info[uid]["gacha_list"]["dg_time"]
else:
user_info[uid]["gacha_list"]["dg_name"] = ''
user_info[uid]["gacha_list"]["dg_time"] = 0
role['dg_time'] = 3
user_info[uid]["gacha_list"]["wish_%s" % rank] += 1
if gacha_data['gacha_type'] != 200:
user_info[uid]["gacha_list"][("is_up_%s_%s" % (rank, pool_str))] = not is_up
if role['item_type'] == '角色':
itemname = 'role'
else:
itemname = 'weapon'
if role['item_name'] not in user_info[uid]["role_list"]:
user_info[uid]["%s_list" % itemname][role['item_name']] = {}
user_info[uid]["%s_list" % itemname][role['item_name']]['数量'] = 1
user_info[uid]["%s_list" % itemname][role['item_name']]['出货'] = []
if rank == 5:
user_info[uid]["%s_list" % itemname][role['item_name']]['星级'] = '★★★★★'
user_info[uid]["%s_list" % itemname][role['item_name']]['出货'].append(
(user_info[uid]['gacha_list']['gacha_%s_%s' % (rank, pool_str)] + 1))
else:
user_info[uid]["%s_list" % itemname][role['item_name']]['星级'] = '★★★★'
else:
user_info[uid]["%s_list" % itemname][role['item_name']]['数量'] += 1
if rank == 5:
user_info[uid]["%s_list" % itemname][role['item_name']]['出货'].append(
(user_info[uid]['gacha_list']['gacha_%s_%s' % (rank, pool_str)] + 1))
role['count'] = user_info[uid]["gacha_list"]["gacha_%s_%s" % (rank, pool_str)] + 1
user_info[uid]["gacha_list"]["gacha_%s_%s" % (rank, pool_str)] = 0
save_user_info()
return role
async def create_item(rank, item_type, name, element, count, dg_time):
bg = Image.open(os.path.join(RES_PATH, f'{rank}_background.png')).resize((143, 845))
item_img = Image.open(os.path.join(RES_PATH, item_type, f'{name}.png'))
rank_img = Image.open(os.path.join(RES_PATH, f'{rank}_star.png')).resize((119, 30))
if item_type == '角色':
item_img = item_img.resize((item_img.size[0] + 12, item_img.size[1] + 45))
item_img.alpha_composite(rank_img, (4, 510))
item_type_icon = Image.open(os.path.join(RES_PATH, '元素', f'{element}.png')).resize((80, 80))
item_img.alpha_composite(item_type_icon, (25, 420))
bg.alpha_composite(item_img, (3, 125))
else:
bg.alpha_composite(item_img, (3, 240))
bg.alpha_composite(rank_img, (9, 635))
item_type_icon = type_json.get(name)
if item_type_icon:
item_type_icon = Image.open(os.path.join(RES_PATH, '类型', f'{item_type_icon}.png')).resize((100, 100))
bg.alpha_composite(item_type_icon, (18, 530))
if rank == 5 and count != -1:
draw = ImageDraw.Draw(bg)
if len(str(count)) == 2:
draw.text((19, 750), ('[' + str(count) + '抽]'), font=count_font, fill='white')
else:
draw.text((26, 750), ('[' + str(count) + '抽]'), font=count_font, fill='white')
if dg_time != -1:
if dg_time == 3:
draw.text((3, 785), ('定轨结束'), font=count_font, fill='white')
else:
draw.text((7, 785), ('定轨' + str(dg_time) + '/2'), font=count_font, fill='white')
return bg
async def ten(uid, gacha_data, sd) -> PngImagePlugin.PngImageFile:
gacha_list = []
for i in range(0, 10):
if gacha_data['gacha_type'] == 'all_star':
role = random.choice(gacha_data['list'])
role['count'] = -1
role['rank'] = 5
else:
role = once(uid, gacha_data).copy()
gacha_list.append(role)
gacha_list.sort(key=lambda x: x["rank"], reverse=True)
img: PngImagePlugin.PngImageFile
img = Image.open(os.path.join(RES_PATH, 'background.png'))
i = 0
for wish in gacha_list:
i += 1
rank = wish['rank']
item_type = wish['item_type']
name = wish['item_name']
element = wish.get('item_attr') or type_json[name]
count = wish['count']
try:
dg_time = wish['dg_time']
except:
dg_time = -1
i_img = await create_item(rank, item_type, name, element, count, dg_time)
img.alpha_composite(i_img, (105 + (i_img.size[0] * i), 123))
img.thumbnail((1024, 768))
img2 = Image.new("RGB", img.size, (255, 255, 255))
img2.paste(img, mask=img.split()[3])
return img2
async def more_ten(uid, gacha_data, num, sd):
time_str = datetime.datetime.strftime(datetime.datetime.now(), '%m-%d %H:%M')
if num == 1:
img = await ten(uid, gacha_data, sd)
else:
img = Image.new("RGB", (1024, 575 * num), (255, 255, 255))
for i in range(0, num):
item_img = await ten(uid, gacha_data, sd)
img.paste(item_img, (0, 575 * i))
draw = ImageDraw.Draw(img)
draw.text((27, 575 * num - 30), ('@%s %s Created By LittlePaimon' % (str(sd.nickname), time_str)), font=time_font,
2022-04-30 14:13:39 +08:00
fill="#8E8E8E")
return pil2b64(img, 75)