mirror of
https://github.com/Shu-Ying/main_plugin_farm.git
synced 2026-11-04 03:30:16 +08:00
100 lines
4.2 KiB
Python
100 lines
4.2 KiB
Python
"""文字指令使用的木质种子价目板;全部价格来自离线目录。"""
|
|
|
|
import logging
|
|
import shlex
|
|
|
|
from PIL import Image
|
|
|
|
from .canvas import Canvas, font
|
|
from .models import RenderOptions
|
|
|
|
logger = logging.getLogger(__name__)
|
|
PAGE_SIZE = 6
|
|
|
|
|
|
def shop_page(catalogue, page):
|
|
plants = sorted((p for p in catalogue if p.buyable),
|
|
key=lambda p: p.plant_id)
|
|
pages = max(1, (len(plants) + PAGE_SIZE - 1) // PAGE_SIZE)
|
|
if type(page) is not int or not 1 <= page <= pages:
|
|
raise ValueError('Invalid shop page')
|
|
start = (page - 1) * PAGE_SIZE
|
|
return tuple(plants[start:start + PAGE_SIZE]), pages
|
|
|
|
|
|
def duration(seconds):
|
|
hours, remainder = divmod(seconds, 3600)
|
|
minutes, seconds = divmod(remainder, 60)
|
|
return ''.join(f'{value}{unit}' for value, unit in (
|
|
(hours, '小时'), (minutes, '分'), (seconds, '秒'),
|
|
) if value) or '0秒'
|
|
|
|
|
|
def render_shop(renderer, plants, account, page, pages, image_format='AUTO'):
|
|
options = RenderOptions(format=image_format, quality=80)
|
|
codec = options.codec()
|
|
canvas = Canvas(renderer.assets.image('webgl/shop-board.png', (1024, 1536)))
|
|
|
|
def text(value, xy, size=28, color='#5b3015', width=850):
|
|
value = canvas.fit_text(value, renderer.font_path, size, width)
|
|
box = font(renderer.font_path, size).getbbox(value)
|
|
canvas.text((xy[0], xy[1]-box[1]), value,
|
|
renderer.font_path, size, color)
|
|
|
|
def centered(value, y, size, color='#5b3015'):
|
|
x = round((1024 - canvas.measure_text(
|
|
value, renderer.font_path, size,
|
|
)) / 2)
|
|
text(value, (x, y), size, color)
|
|
|
|
centered('种 子 商 店', 58, 54, '#fff5d3')
|
|
centered('种子价目板 · 发送文字指令购买', 178, 25, '#7a6439')
|
|
balances = ('未开通农场 · 可浏览种子,购买前请发送:开通农场'
|
|
if account is None else
|
|
f'Lv.{account.level} 农场币 {account.point:,} '
|
|
f'点券 {account.vip_point:,}')
|
|
text(balances, (142, 248), 29, width=745)
|
|
for index, plant in enumerate(plants):
|
|
y = 326 + index * 156
|
|
icon = f'plant/{plant.name}/icon.png'
|
|
if icon in renderer.assets.metadata['images']:
|
|
image = renderer.assets.image(icon)
|
|
image.thumbnail((104, 110), Image.Resampling.LANCZOS)
|
|
canvas.paste(image, (175-image.width//2, y+67-image.height//2))
|
|
else:
|
|
text('暂无图', (133, y+55), 23, '#8b8057', width=92)
|
|
logger.info('farm shop packaged icon unavailable id=%s',
|
|
plant.plant_id)
|
|
text(plant.name, (268, y+13), 34, width=490)
|
|
text(f'#{plant.plant_id}', (774, y+17), 26, '#69783e', width=132)
|
|
currency = '点券' if plant.is_vip else '农场币'
|
|
text(f'{plant.cost:,} {currency} / 粒', (268, y+62), 32,
|
|
'#b66522', width=480)
|
|
locked = account is not None and account.level < plant.level
|
|
text(f'{"需" if locked else "等级"} Lv.{plant.level}',
|
|
(774, y+69), 23, '#ac542d' if locked else '#66733d', width=132)
|
|
text(f'首熟 {duration(plant.growth_seconds)} · {plant.crop}季'
|
|
f' · 每季{plant.harvest}个', (268, y+108), 23, width=635)
|
|
if not plants:
|
|
text('暂无出售中的种子', (340, 690), 34)
|
|
example = plants[0] if plants else None
|
|
if example:
|
|
text(f'按编号:购买种子 #{example.plant_id} 5', (142, 1291), 27)
|
|
name = example.name
|
|
if any(c.isspace() for c in name) or any(c in name for c in '\"\''):
|
|
name = shlex.quote(name)
|
|
text(f'按名称:购买种子 {name} 5', (142, 1341), 27, width=750)
|
|
else:
|
|
text('购买种子 #编号 数量 或 购买种子 种子名 数量',
|
|
(142, 1316), 25, width=750)
|
|
navigation = f'第 {page} / {pages} 页'
|
|
if page < pages:
|
|
navigation += f' 下一页:种子商店 {page+1}'
|
|
elif page > 1:
|
|
navigation += f' 上一页:种子商店 {page-1}'
|
|
text(navigation, (263, 1420), 23, width=510)
|
|
content = canvas.encode(codec, options.quality, options.method)
|
|
logger.info('farm shop render width=%s height=%s bytes=%s codec=%s',
|
|
*canvas.image.size, len(content), codec)
|
|
return content
|