# Released under the MIT License. See LICENSE for details.
#
"""UI functionality related to UI items."""
from __future__ import annotations
from typing import TYPE_CHECKING
import bascenev1 as bs
import bauiv1 as bui
if TYPE_CHECKING:
from typing import Any
[docs]
def instantiate_store_item_display(
item_name: str,
item: dict[str, Any],
parent_widget: bui.Widget,
b_pos: tuple[float, float],
b_width: float,
b_height: float,
*,
boffs_h: float = 0.0,
boffs_h2: float = 0.0,
boffs_v2: float = 0,
delay: float = 0.0,
button: bool = True,
) -> None:
"""(internal)"""
# pylint: disable=too-many-positional-arguments
# pylint: disable=too-many-statements
# pylint: disable=too-many-branches
# pylint: disable=too-many-locals
assert bui.app.classic is not None
store = bui.app.classic.store
plus = bui.app.plus
assert plus is not None
del boffs_h # unused arg
del boffs_h2 # unused arg
del boffs_v2 # unused arg
item_info = store.get_store_item(item_name)
title_v = 0.24
price_v = 0.145
base_text_scale = 1.0
item['name'] = title = store.get_store_item_name_translated(item_name)
btn: bui.Widget | None
# Hack; showbuffer stuff isn't working well when we're showing merch.
showbuffer = 10 if item_name in {'merch', 'pro', 'pro_sale'} else 76.0
if button:
item['button'] = btn = bui.buttonwidget(
parent=parent_widget,
position=b_pos,
transition_delay=delay,
show_buffer_top=showbuffer,
enable_sound=False,
button_type='square',
size=(b_width, b_height),
autoselect=True,
label='',
)
bui.widget(edit=btn, show_buffer_bottom=showbuffer)
else:
btn = None
b_offs_x = -0.015 * b_width
check_pos = 0.76
icon_tex = None
tint_tex = None
tint_color = None
tint2_color = None
tex_name: str | None = None
desc: str | None = None
modes: bui.Lstr | None = None
if item_name.startswith('characters.'):
assert bui.app.classic is not None
character = bui.app.classic.spaz_appearances[item_info['character']]
tint_color = (
item_info['color']
if 'color' in item_info
else (
character.default_color
if character.default_color is not None
else (1, 1, 1)
)
)
tint2_color = (
item_info['highlight']
if 'highlight' in item_info
else (
character.default_highlight
if character.default_highlight is not None
else (1, 1, 1)
)
)
icon_tex = character.icon_texture
tint_tex = character.icon_mask_texture
title_v = 0.255
price_v = 0.145
elif item_name == 'merch':
base_text_scale = 0.6
title_v = 0.85
price_v = 0.15
elif item_name in ['upgrades.pro', 'pro']:
base_text_scale = 0.6
title_v = 0.85
price_v = 0.15
elif item_name.startswith('maps.'):
map_type = item_info['map_type']
tex_name = map_type.get_preview_texture_name()
title_v = 0.312
price_v = 0.17
elif item_name.startswith('games.'):
gametype = item_info['gametype']
modes_l = []
if gametype.supports_session_type(bs.CoopSession):
modes_l.append(bui.Lstr(resource='playModes.coopText'))
if gametype.supports_session_type(bs.DualTeamSession):
modes_l.append(bui.Lstr(resource='playModes.teamsText'))
if gametype.supports_session_type(bs.FreeForAllSession):
modes_l.append(bui.Lstr(resource='playModes.freeForAllText'))
if len(modes_l) == 3:
modes = bui.Lstr(
value='${A}, ${B}, ${C}',
subs=[
('${A}', modes_l[0]),
('${B}', modes_l[1]),
('${C}', modes_l[2]),
],
)
elif len(modes_l) == 2:
modes = bui.Lstr(
value='${A}, ${B}',
subs=[('${A}', modes_l[0]), ('${B}', modes_l[1])],
)
elif len(modes_l) == 1:
modes = modes_l[0]
else:
raise RuntimeError()
desc = gametype.get_description_display_string(bs.CoopSession)
tex_name = item_info['previewTex']
base_text_scale = 0.8
title_v = 0.48
price_v = 0.17
elif item_name.startswith('icons.'):
base_text_scale = 1.5
price_v = 0.2
check_pos = 0.6
if item_name.startswith('characters.'):
frame_size = b_width * 0.7
im_dim = frame_size * (100.0 / 113.0)
im_pos = (
b_pos[0] + b_width * 0.5 - im_dim * 0.5 + b_offs_x,
b_pos[1] + b_height * 0.57 - im_dim * 0.5,
)
mask_texture = bui.gettexture('characterIconMask')
assert icon_tex is not None
assert tint_tex is not None
bui.imagewidget(
parent=parent_widget,
position=im_pos,
size=(im_dim, im_dim),
color=(1, 1, 1),
transition_delay=delay,
mask_texture=mask_texture,
draw_controller=btn,
texture=bui.gettexture(icon_tex),
tint_texture=bui.gettexture(tint_tex),
tint_color=tint_color,
tint2_color=tint2_color,
)
if item_name == 'merch':
frame_size = b_width * 0.65
im_dim = frame_size * (100.0 / 113.0)
im_pos = (
b_pos[0] + b_width * 0.5 - im_dim * 0.5 + b_offs_x,
b_pos[1] + b_height * 0.47 - im_dim * 0.5,
)
bui.imagewidget(
parent=parent_widget,
position=im_pos,
size=(im_dim, im_dim),
transition_delay=delay,
draw_controller=btn,
opacity=1.0,
texture=bui.gettexture('merch'),
)
if item_name in ['pro', 'upgrades.pro']:
frame_size = b_width * 0.5
im_dim = frame_size * (100.0 / 113.0)
im_pos = (
b_pos[0] + b_width * 0.5 - im_dim * 0.5 + b_offs_x,
b_pos[1] + b_height * 0.5 - im_dim * 0.5,
)
bui.imagewidget(
parent=parent_widget,
position=im_pos,
size=(im_dim, im_dim),
transition_delay=delay,
draw_controller=btn,
color=(0.3, 0.0, 0.3),
opacity=0.3,
texture=bui.gettexture('logo'),
)
txt = bui.Lstr(resource='store.bombSquadProNewDescriptionText')
item['descriptionText'] = bui.textwidget(
parent=parent_widget,
text=txt,
position=(b_pos[0] + b_width * 0.5, b_pos[1] + b_height * 0.69),
transition_delay=delay,
scale=b_width * (1.0 / 230.0) * base_text_scale * 0.75,
maxwidth=b_width * 0.75,
max_height=b_height * 0.2,
size=(0, 0),
h_align='center',
v_align='center',
draw_controller=btn,
color=(0.3, 1, 0.3),
)
extra_backings = item['extra_backings'] = []
extra_images = item['extra_images'] = []
extra_texts = item['extra_texts'] = []
extra_texts_2 = item['extra_texts_2'] = []
backing_color = (0.5, 0.8, 0.3) if button else (0.6, 0.5, 0.65)
b_square_texture = bui.gettexture('buttonSquare')
char_mask_texture = bui.gettexture('characterIconMask')
pos = (0.17, 0.43)
tile_size = (b_width * 0.16 * 1.2, b_width * 0.2 * 1.2)
tile_pos = (b_pos[0] + b_width * pos[0], b_pos[1] + b_height * pos[1])
extra_backings.append(
bui.imagewidget(
parent=parent_widget,
position=(
tile_pos[0] - tile_size[0] * 0.5,
tile_pos[1] - tile_size[1] * 0.5,
),
size=tile_size,
transition_delay=delay,
draw_controller=btn,
color=backing_color,
texture=b_square_texture,
)
)
im_size = tile_size[0] * 0.8
extra_images.append(
bui.imagewidget(
parent=parent_widget,
position=(
tile_pos[0] - im_size * 0.5,
tile_pos[1] - im_size * 0.4,
),
size=(im_size, im_size),
transition_delay=delay,
draw_controller=btn,
color=(1, 1, 1),
texture=bui.gettexture('ticketsMore'),
)
)
bonus_tickets = str(
plus.get_v1_account_misc_read_val('proBonusTickets', 100)
)
extra_texts.append(
bui.textwidget(
parent=parent_widget,
draw_controller=btn,
position=(
tile_pos[0] - tile_size[0] * 0.03,
tile_pos[1] - tile_size[1] * 0.25,
),
size=(0, 0),
color=(0.6, 1, 0.6),
transition_delay=delay,
h_align='center',
v_align='center',
maxwidth=tile_size[0] * 0.7,
scale=0.55,
text=bui.Lstr(
resource='getTicketsWindow.ticketsText',
subs=[('${COUNT}', bonus_tickets)],
),
flatness=1.0,
shadow=0.0,
)
)
for charname, pos in [
('Kronk', (0.32, 0.45)),
('Zoe', (0.425, 0.4)),
('Jack Morgan', (0.555, 0.45)),
('Mel', (0.645, 0.4)),
]:
tile_size = (b_width * 0.16 * 0.9, b_width * 0.2 * 0.9)
tile_pos = (
b_pos[0] + b_width * pos[0],
b_pos[1] + b_height * pos[1],
)
assert bui.app.classic is not None
character = bui.app.classic.spaz_appearances[charname]
extra_backings.append(
bui.imagewidget(
parent=parent_widget,
position=(
tile_pos[0] - tile_size[0] * 0.5,
tile_pos[1] - tile_size[1] * 0.5,
),
size=tile_size,
transition_delay=delay,
draw_controller=btn,
color=backing_color,
texture=b_square_texture,
)
)
im_size = tile_size[0] * 0.7
extra_images.append(
bui.imagewidget(
parent=parent_widget,
position=(
tile_pos[0] - im_size * 0.53,
tile_pos[1] - im_size * 0.35,
),
size=(im_size, im_size),
transition_delay=delay,
draw_controller=btn,
color=(1, 1, 1),
texture=bui.gettexture(character.icon_texture),
tint_texture=bui.gettexture(character.icon_mask_texture),
tint_color=character.default_color,
tint2_color=character.default_highlight,
mask_texture=char_mask_texture,
)
)
extra_texts.append(
bui.textwidget(
parent=parent_widget,
draw_controller=btn,
position=(
tile_pos[0] - im_size * 0.03,
tile_pos[1] - im_size * 0.51,
),
size=(0, 0),
color=(0.6, 1, 0.6),
transition_delay=delay,
h_align='center',
v_align='center',
maxwidth=tile_size[0] * 0.7,
scale=0.55,
text=bui.Lstr(translate=('characterNames', charname)),
flatness=1.0,
shadow=0.0,
)
)
# If we have a 'total-worth' item-id for this id, show that price so
# the user knows how much this is worth.
total_worth_item = plus.get_v1_account_misc_read_val('twrths', {}).get(
item_name
)
total_worth_price: str | None
if total_worth_item is not None:
price = plus.get_price(total_worth_item)
total_worth_price = (
store.get_clean_price(price) if price is not None else '??'
)
else:
total_worth_price = None
if total_worth_price is not None:
total_worth_text = bui.Lstr(
resource='store.totalWorthText',
subs=[('${TOTAL_WORTH}', total_worth_price)],
)
extra_texts_2.append(
bui.textwidget(
parent=parent_widget,
text=total_worth_text,
position=(
b_pos[0] + b_width * 0.5 + b_offs_x,
b_pos[1] + b_height * 0.25,
),
transition_delay=delay,
scale=b_width * (1.0 / 230.0) * base_text_scale * 0.45,
maxwidth=b_width * 0.5,
size=(0, 0),
h_align='center',
v_align='center',
shadow=1.0,
flatness=1.0,
draw_controller=btn,
color=(0.3, 1, 1),
)
)
mesh_opaque = bui.getmesh('level_select_button_opaque')
mesh_transparent = bui.getmesh('level_select_button_transparent')
mask_tex = bui.gettexture('mapPreviewMask')
for levelname, preview_tex_name, pos in [
('Infinite Onslaught', 'doomShroomPreview', (0.80, 0.48)),
('Infinite Runaround', 'towerDPreview', (0.80, 0.32)),
]:
tile_size = (b_width * 0.2, b_width * 0.13)
tile_pos = (
b_pos[0] + b_width * pos[0],
b_pos[1] + b_height * pos[1],
)
im_size = tile_size[0] * 0.8
extra_backings.append(
bui.imagewidget(
parent=parent_widget,
position=(
tile_pos[0] - tile_size[0] * 0.5,
tile_pos[1] - tile_size[1] * 0.5,
),
size=tile_size,
transition_delay=delay,
draw_controller=btn,
color=backing_color,
texture=b_square_texture,
)
)
# Hack - gotta draw two transparent versions to avoid z issues.
for mod in mesh_opaque, mesh_transparent:
extra_images.append(
bui.imagewidget(
parent=parent_widget,
position=(
tile_pos[0] - im_size * 0.52,
tile_pos[1] - im_size * 0.2,
),
size=(im_size, im_size * 0.5),
transition_delay=delay,
mesh_transparent=mod,
mask_texture=mask_tex,
draw_controller=btn,
texture=bui.gettexture(preview_tex_name),
)
)
extra_texts.append(
bui.textwidget(
parent=parent_widget,
draw_controller=btn,
position=(
tile_pos[0] - im_size * 0.03,
tile_pos[1] - im_size * 0.2,
),
size=(0, 0),
color=(0.6, 1, 0.6),
transition_delay=delay,
h_align='center',
v_align='center',
maxwidth=tile_size[0] * 0.7,
scale=0.55,
text=bui.Lstr(translate=('coopLevelNames', levelname)),
flatness=1.0,
shadow=0.0,
)
)
if item_name.startswith('icons.'):
item['icon_text'] = bui.textwidget(
parent=parent_widget,
text=item_info['icon'],
position=(b_pos[0] + b_width * 0.5, b_pos[1] + b_height * 0.5),
transition_delay=delay,
scale=b_width * (1.0 / 230.0) * base_text_scale * 2.0,
maxwidth=b_width * 0.9,
max_height=b_height * 0.9,
size=(0, 0),
h_align='center',
v_align='center',
draw_controller=btn,
)
if item_name.startswith('maps.'):
frame_size = b_width * 0.9
im_dim = frame_size * (100.0 / 113.0)
im_pos = (
b_pos[0] + b_width * 0.5 - im_dim * 0.5 + b_offs_x,
b_pos[1] + b_height * 0.62 - im_dim * 0.25,
)
mesh_opaque = bui.getmesh('level_select_button_opaque')
mesh_transparent = bui.getmesh('level_select_button_transparent')
mask_tex = bui.gettexture('mapPreviewMask')
assert tex_name is not None
bui.imagewidget(
parent=parent_widget,
position=im_pos,
size=(im_dim, im_dim * 0.5),
transition_delay=delay,
mesh_opaque=mesh_opaque,
mesh_transparent=mesh_transparent,
mask_texture=mask_tex,
draw_controller=btn,
texture=bui.gettexture(tex_name),
)
if item_name.startswith('games.'):
frame_size = b_width * 0.8
im_dim = frame_size * (100.0 / 113.0)
im_pos = (
b_pos[0] + b_width * 0.5 - im_dim * 0.5 + b_offs_x,
b_pos[1] + b_height * 0.72 - im_dim * 0.25,
)
mesh_opaque = bui.getmesh('level_select_button_opaque')
mesh_transparent = bui.getmesh('level_select_button_transparent')
mask_tex = bui.gettexture('mapPreviewMask')
assert tex_name is not None
bui.imagewidget(
parent=parent_widget,
position=im_pos,
size=(im_dim, im_dim * 0.5),
transition_delay=delay,
mesh_opaque=mesh_opaque,
mesh_transparent=mesh_transparent,
mask_texture=mask_tex,
draw_controller=btn,
texture=bui.gettexture(tex_name),
)
item['descriptionText'] = bui.textwidget(
parent=parent_widget,
text=desc,
position=(b_pos[0] + b_width * 0.5, b_pos[1] + b_height * 0.36),
transition_delay=delay,
scale=b_width * (1.0 / 230.0) * base_text_scale * 0.78,
maxwidth=b_width * 0.8,
max_height=b_height * 0.14,
size=(0, 0),
h_align='center',
v_align='center',
draw_controller=btn,
flatness=1.0,
shadow=0.0,
color=(0.6, 1, 0.6),
)
item['gameModesText'] = bui.textwidget(
parent=parent_widget,
text=modes,
position=(b_pos[0] + b_width * 0.5, b_pos[1] + b_height * 0.26),
transition_delay=delay,
scale=b_width * (1.0 / 230.0) * base_text_scale * 0.65,
maxwidth=b_width * 0.8,
size=(0, 0),
h_align='center',
v_align='center',
draw_controller=btn,
shadow=0,
flatness=1.0,
color=(0.6, 0.8, 0.6),
)
if not item_name.startswith('icons.'):
item['title_text'] = bui.textwidget(
parent=parent_widget,
text=title,
position=(
b_pos[0] + b_width * 0.5 + b_offs_x,
b_pos[1] + b_height * title_v,
),
transition_delay=delay,
scale=b_width * (1.0 / 230.0) * base_text_scale,
maxwidth=b_width * 0.8,
size=(0, 0),
h_align='center',
v_align='center',
draw_controller=btn,
color=(0.7, 0.9, 0.7, 1.0),
)
item['purchase_check'] = bui.imagewidget(
parent=parent_widget,
position=(b_pos[0] + b_width * check_pos, b_pos[1] + b_height * 0.05),
transition_delay=delay,
mesh_transparent=bui.getmesh('checkTransparent'),
opacity=0.0,
size=(60, 60),
color=(0.6, 0.5, 0.8),
draw_controller=btn,
texture=bui.gettexture('uiAtlas'),
)
item['price_widget'] = bui.textwidget(
parent=parent_widget,
text='',
position=(
b_pos[0] + b_width * 0.5 + b_offs_x,
b_pos[1] + b_height * price_v,
),
transition_delay=delay,
scale=b_width * (1.0 / 300.0) * base_text_scale,
maxwidth=b_width * 0.9,
size=(0, 0),
h_align='center',
v_align='center',
draw_controller=btn,
color=(0.2, 1, 0.2, 1.0),
)
item['price_widget_left'] = bui.textwidget(
parent=parent_widget,
text='',
position=(
b_pos[0] + b_width * 0.33 + b_offs_x,
b_pos[1] + b_height * price_v,
),
transition_delay=delay,
scale=b_width * (1.0 / 300.0) * base_text_scale,
maxwidth=b_width * 0.3,
size=(0, 0),
h_align='center',
v_align='center',
draw_controller=btn,
color=(0.2, 1, 0.2, 0.5),
)
item['price_widget_right'] = bui.textwidget(
parent=parent_widget,
text='',
position=(
b_pos[0] + b_width * 0.66 + b_offs_x,
b_pos[1] + b_height * price_v,
),
transition_delay=delay,
scale=1.1 * b_width * (1.0 / 300.0) * base_text_scale,
maxwidth=b_width * 0.3,
size=(0, 0),
h_align='center',
v_align='center',
draw_controller=btn,
color=(0.2, 1, 0.2, 1.0),
)
item['price_slash_widget'] = bui.imagewidget(
parent=parent_widget,
position=(
b_pos[0] + b_width * 0.33 + b_offs_x - 36,
b_pos[1] + b_height * price_v - 35,
),
transition_delay=delay,
texture=bui.gettexture('slash'),
opacity=0.0,
size=(70, 70),
draw_controller=btn,
color=(1, 0, 0),
)
badge_rad = 44
badge_center = (
b_pos[0] + b_width * 0.1 + b_offs_x,
b_pos[1] + b_height * 0.87,
)
item['sale_bg_widget'] = bui.imagewidget(
parent=parent_widget,
position=(badge_center[0] - badge_rad, badge_center[1] - badge_rad),
opacity=0.0,
transition_delay=delay,
texture=bui.gettexture('circleZigZag'),
draw_controller=btn,
size=(badge_rad * 2, badge_rad * 2),
color=(0.5, 0, 1),
)
item['sale_title_widget'] = bui.textwidget(
parent=parent_widget,
position=(badge_center[0], badge_center[1] + 12),
transition_delay=delay,
scale=1.0,
maxwidth=badge_rad * 1.6,
size=(0, 0),
h_align='center',
v_align='center',
draw_controller=btn,
shadow=0.0,
flatness=1.0,
color=(0, 1, 0),
)
item['sale_time_widget'] = bui.textwidget(
parent=parent_widget,
position=(badge_center[0], badge_center[1] - 12),
transition_delay=delay,
scale=0.7,
maxwidth=badge_rad * 1.6,
size=(0, 0),
h_align='center',
v_align='center',
draw_controller=btn,
shadow=0.0,
flatness=1.0,
color=(0.0, 1, 0.0, 1),
)