vh-bombsquad-modded-server-.../dist/ba_data/python/bastd/ui/coop/gamebutton.py
2024-02-26 00:17:10 +05:30

303 lines
9.5 KiB
Python

# Released under the MIT License. See LICENSE for details.
#
"""Defines button for co-op games."""
from __future__ import annotations
import random
from typing import TYPE_CHECKING
import ba
if TYPE_CHECKING:
from bastd.ui.coop.browser import CoopBrowserWindow
class GameButton:
"""Button for entering co-op games."""
def __init__(
self,
window: CoopBrowserWindow,
parent: ba.Widget,
game: str,
x: float,
y: float,
select: bool,
row: str,
):
# pylint: disable=too-many-statements
# pylint: disable=too-many-locals
from ba.internal import getcampaign
self._game = game
sclx = 195.0
scly = 195.0
campaignname, levelname = game.split(':')
# Hack: The Last Stand doesn't actually exist in the easy
# tourney. We just want it for display purposes. Map it to
# the hard-mode version.
if game == 'Easy:The Last Stand':
campaignname = 'Default'
rating: float | None
campaign = getcampaign(campaignname)
rating = campaign.getlevel(levelname).rating
if game == 'Easy:The Last Stand':
rating = None
if rating is None or rating == 0.0:
stars = 0
elif rating >= 9.5:
stars = 3
elif rating >= 7.5:
stars = 2
else:
stars = 1
self._button = btn = ba.buttonwidget(
parent=parent,
position=(x + 23, y + 4),
size=(sclx, scly),
label='',
on_activate_call=ba.Call(window.run_game, game),
button_type='square',
autoselect=True,
on_select_call=ba.Call(window.sel_change, row, game),
)
ba.widget(
edit=btn,
show_buffer_bottom=50,
show_buffer_top=50,
show_buffer_left=400,
show_buffer_right=200,
)
if select:
ba.containerwidget(
edit=parent, selected_child=btn, visible_child=btn
)
image_width = sclx * 0.85 * 0.75
self._preview_widget = ba.imagewidget(
parent=parent,
draw_controller=btn,
position=(x + 21 + sclx * 0.5 - image_width * 0.5, y + scly - 104),
size=(image_width, image_width * 0.5),
model_transparent=window.lsbt,
model_opaque=window.lsbo,
texture=campaign.getlevel(levelname).get_preview_texture(),
mask_texture=ba.gettexture('mapPreviewMask'),
)
translated = campaign.getlevel(levelname).displayname
self._achievements = ba.app.ach.achievements_for_coop_level(game)
self._name_widget = ba.textwidget(
parent=parent,
draw_controller=btn,
position=(x + 20 + sclx * 0.5, y + scly - 27),
size=(0, 0),
h_align='center',
text=translated,
v_align='center',
maxwidth=sclx * 0.76,
scale=0.85,
)
xscl = x + (67 if self._achievements else 50)
yscl = y + scly - (137 if self._achievements else 157)
starscale = 35.0 if self._achievements else 45.0
self._star_widgets: list[ba.Widget] = []
for _i in range(stars):
imw = ba.imagewidget(
parent=parent,
draw_controller=btn,
position=(xscl, yscl),
size=(starscale, starscale),
texture=window.star_tex,
)
self._star_widgets.append(imw)
xscl += starscale
for _i in range(3 - stars):
ba.imagewidget(
parent=parent,
draw_controller=btn,
position=(xscl, yscl),
size=(starscale, starscale),
color=(0, 0, 0),
texture=window.star_tex,
opacity=0.3,
)
xscl += starscale
xach = x + 69
yach = y + scly - 168
a_scale = 30.0
self._achievement_widgets: list[tuple[ba.Widget, ba.Widget]] = []
for ach in self._achievements:
a_complete = ach.complete
imw = ba.imagewidget(
parent=parent,
draw_controller=btn,
position=(xach, yach),
size=(a_scale, a_scale),
color=tuple(ach.get_icon_color(a_complete)[:3])
if a_complete
else (1.2, 1.2, 1.2),
texture=ach.get_icon_texture(a_complete),
)
imw2 = ba.imagewidget(
parent=parent,
draw_controller=btn,
position=(xach, yach),
size=(a_scale, a_scale),
color=(2, 1.4, 0.4),
texture=window.a_outline_tex,
model_transparent=window.a_outline_model,
)
self._achievement_widgets.append((imw, imw2))
# if a_complete:
xach += a_scale * 1.2
# if not unlocked:
self._lock_widget = ba.imagewidget(
parent=parent,
draw_controller=btn,
position=(x - 8 + sclx * 0.5, y + scly * 0.5 - 20),
size=(60, 60),
opacity=0.0,
texture=ba.gettexture('lock'),
)
# give a quasi-random update increment to spread the load..
self._update_timer = ba.Timer(
0.001 * (900 + random.randrange(200)),
ba.WeakCall(self._update),
repeat=True,
timetype=ba.TimeType.REAL,
)
self._update()
def get_button(self) -> ba.Widget:
"""Return the underlying button ba.Widget."""
return self._button
def _update(self) -> None:
# pylint: disable=too-many-boolean-expressions
from ba.internal import getcampaign
# In case we stick around after our UI...
if not self._button:
return
game = self._game
campaignname, levelname = game.split(':')
# Hack - The Last Stand doesn't actually exist in the
# easy tourney; we just want it for display purposes. Map it to
# the hard-mode version.
if game == 'Easy:The Last Stand':
campaignname = 'Default'
campaign = getcampaign(campaignname)
# If this campaign is sequential, make sure we've unlocked
# everything up to here.
unlocked = True
if campaign.sequential:
for level in campaign.levels:
if level.name == levelname:
break
if not level.complete:
unlocked = False
break
# We never actually allow playing last-stand on easy mode.
if game == 'Easy:The Last Stand':
unlocked = False
# Hard-code games we haven't unlocked.
if (
(
game
in (
'Challenges:Infinite Runaround',
'Challenges:Infinite Onslaught',
)
and not ba.app.accounts_v1.have_pro()
)
or (
game in ('Challenges:Meteor Shower',)
and not ba.internal.get_purchased('games.meteor_shower')
)
or (
game
in (
'Challenges:Target Practice',
'Challenges:Target Practice B',
)
and not ba.internal.get_purchased('games.target_practice')
)
or (
game in ('Challenges:Ninja Fight',)
and not ba.internal.get_purchased('games.ninja_fight')
)
or (
game in ('Challenges:Pro Ninja Fight',)
and not ba.internal.get_purchased('games.ninja_fight')
)
or (
game
in (
'Challenges:Easter Egg Hunt',
'Challenges:Pro Easter Egg Hunt',
)
and not ba.internal.get_purchased('games.easter_egg_hunt')
)
):
unlocked = False
# Let's tint levels a slightly different color when easy mode
# is selected.
unlocked_color = (
(0.85, 0.95, 0.5) if game.startswith('Easy:') else (0.5, 0.7, 0.2)
)
ba.buttonwidget(
edit=self._button,
color=unlocked_color if unlocked else (0.5, 0.5, 0.5),
)
ba.imagewidget(edit=self._lock_widget, opacity=0.0 if unlocked else 1.0)
ba.imagewidget(
edit=self._preview_widget, opacity=1.0 if unlocked else 0.3
)
ba.textwidget(
edit=self._name_widget,
color=(0.8, 1.0, 0.8, 1.0) if unlocked else (0.7, 0.7, 0.7, 0.7),
)
for widget in self._star_widgets:
ba.imagewidget(
edit=widget,
opacity=1.0 if unlocked else 0.3,
color=(2.2, 1.2, 0.3) if unlocked else (1, 1, 1),
)
for i, ach in enumerate(self._achievements):
a_complete = ach.complete
ba.imagewidget(
edit=self._achievement_widgets[i][0],
opacity=1.0 if (a_complete and unlocked) else 0.3,
)
ba.imagewidget(
edit=self._achievement_widgets[i][1],
opacity=(
1.0
if (a_complete and unlocked)
else 0.2
if a_complete
else 0.0
),
)