Merge pull request #650 from 3alTemp/tournament_entry

Practice in Tournaments! + Multi-entry bug fix
This commit is contained in:
Eric Froemling 2024-03-14 20:58:42 -07:00 committed by GitHub
commit 623b49375b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 122 additions and 57 deletions

View File

@ -61,6 +61,10 @@ class CoopSession(Session):
max_players = classic.coop_session_args['max_players']
else:
max_players = app.config.get('Coop Game Max Players', 4)
if 'submit_score' in classic.coop_session_args:
submit_score = classic.coop_session_args['submit_score']
else:
submit_score = True
# print('FIXME: COOP SESSION WOULD CALC DEPS.')
depsets: Sequence[bascenev1.DependencySet] = []
@ -71,6 +75,7 @@ class CoopSession(Session):
team_colors=TEAM_COLORS,
min_players=min_players,
max_players=max_players,
submit_score=submit_score,
)
# Tournament-ID if we correspond to a co-op tournament (otherwise None)
@ -346,7 +351,10 @@ class CoopSession(Session):
self.setactivity(next_game)
if not (env.demo or env.arcade):
if self.tournament_id is not None:
if (
self.tournament_id is not None
and classic.coop_session_args['submit_score']
):
self._custom_menu_ui = [
{
'label': babase.Lstr(resource='restartText'),

View File

@ -100,6 +100,7 @@ class Session:
team_colors: Sequence[Sequence[float]] | None = None,
min_players: int = 1,
max_players: int = 8,
submit_score: bool = True,
):
"""Instantiate a session.
@ -175,6 +176,7 @@ class Session:
if _max_players_override is None
else _max_players_override
)
self.submit_score = submit_score
self.customdata = {}
self._in_set_activity = False

View File

@ -125,6 +125,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
self._tournament_time_remaining: float | None = None
self._tournament_time_remaining_text: Text | None = None
self._tournament_time_remaining_text_timer: bs.BaseTimer | None = None
self._submit_score = self.session.submit_score
# Stuff for activity skip by pressing button
self._birth_time = bs.time()
@ -789,7 +790,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
transition_delay=2.0,
)
if self._score is not None:
if self._score is not None and self._submit_score:
bs.timer(0.4, bs.WeakCall(self._play_drumroll))
# Add us to high scores, filter, and store.
@ -1396,7 +1397,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
assert self._show_info is not None
available = self._show_info['results'] is not None
if available:
if available and self._submit_score:
error = (
self._show_info['results']['error']
if 'error' in self._show_info['results']
@ -1529,7 +1530,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
maxwidth=400,
transition_delay=1.0,
).autoretain()
else:
elif self._submit_score:
ZoomText(
(
('#' + str(player_rank))
@ -1752,9 +1753,10 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
transition_delay=0,
).autoretain()
bs.timer(0.35, self._score_display_sound.play)
if not error:
bs.timer(0.35, self.cymbal_sound.play)
if self._submit_score:
bs.timer(0.35, self._score_display_sound.play)
if not error:
bs.timer(0.35, self.cymbal_sound.play)
def _show_fail(self) -> None:
ZoomText(

View File

@ -14,7 +14,6 @@ import bauiv1 as bui
if TYPE_CHECKING:
from typing import Any, Callable
import bascenev1 as bs
@ -32,6 +31,7 @@ class TournamentEntryWindow(PopupWindow):
on_close_call: Callable[[], Any] | None = None,
):
# Needs some tidying.
# pylint: disable=too-many-locals
# pylint: disable=too-many-branches
# pylint: disable=too-many-statements
@ -80,11 +80,21 @@ class TournamentEntryWindow(PopupWindow):
self._tournament_activity = tournament_activity
self._width = 340
self._height = 225
self._width: float = 340.0
self._height: float = 225.0
bg_color = (0.5, 0.4, 0.6)
# Show the practice button as long as we're not
# restarting while on a paid tournament run.
self._do_practice = (
self._tournament_activity is None and
bui.app.config.get('tournament_practice_enabled', False)
)
off_p = 0 if not self._do_practice else 48
self._height += off_p * 0.933
# Creates our root_widget.
super().__init__(
position=position,
@ -107,7 +117,7 @@ class TournamentEntryWindow(PopupWindow):
self._cancel_button = bui.buttonwidget(
parent=self.root_widget,
position=(20, self._height - 34),
position=(40, self._height - 34),
size=(60, 60),
scale=0.5,
label='',
@ -132,15 +142,15 @@ class TournamentEntryWindow(PopupWindow):
btn = self._pay_with_tickets_button = bui.buttonwidget(
parent=self.root_widget,
position=(30 + x_offs, 60),
position=(30 + x_offs, 60 + off_p),
autoselect=True,
button_type='square',
size=(120, 120),
label='',
on_activate_call=self._on_pay_with_tickets_press,
)
self._ticket_img_pos = (50 + x_offs, 94)
self._ticket_img_pos_free = (50 + x_offs, 80)
self._ticket_img_pos = (50 + x_offs, 94 + off_p)
self._ticket_img_pos_free = (50 + x_offs, 80 + off_p)
self._ticket_img = bui.imagewidget(
parent=self.root_widget,
draw_controller=btn,
@ -148,8 +158,8 @@ class TournamentEntryWindow(PopupWindow):
position=self._ticket_img_pos,
texture=bui.gettexture('tickets'),
)
self._ticket_cost_text_position = (87 + x_offs, 88)
self._ticket_cost_text_position_free = (87 + x_offs, 120)
self._ticket_cost_text_position = (87 + x_offs, 88 + off_p)
self._ticket_cost_text_position_free = (87 + x_offs, 120 + off_p)
self._ticket_cost_text = bui.textwidget(
parent=self.root_widget,
draw_controller=btn,
@ -165,7 +175,7 @@ class TournamentEntryWindow(PopupWindow):
self._free_plays_remaining_text = bui.textwidget(
parent=self.root_widget,
draw_controller=btn,
position=(87 + x_offs, 78),
position=(87 + x_offs, 78 + off_p),
size=(0, 0),
h_align='center',
v_align='center',
@ -178,7 +188,7 @@ class TournamentEntryWindow(PopupWindow):
if self._do_ad_btn:
btn = self._pay_with_ad_btn = bui.buttonwidget(
parent=self.root_widget,
position=(190, 60),
position=(190, 60 + off_p),
autoselect=True,
button_type='square',
size=(120, 120),
@ -189,12 +199,12 @@ class TournamentEntryWindow(PopupWindow):
parent=self.root_widget,
draw_controller=btn,
size=(80, 80),
position=(210, 94),
position=(210, 94 + off_p),
texture=bui.gettexture('tv'),
)
self._ad_text_position = (251, 88)
self._ad_text_position_remaining = (251, 92)
self._ad_text_position = (251, 88 + off_p)
self._ad_text_position_remaining = (251, 92 + off_p)
have_ad_tries_remaining = (
self._tournament_info['adTriesRemaining'] is not None
)
@ -224,7 +234,7 @@ class TournamentEntryWindow(PopupWindow):
self._ad_plays_remaining_text = bui.textwidget(
parent=self.root_widget,
draw_controller=btn,
position=(251, 78),
position=(251, 78 + off_p),
size=(0, 0),
h_align='center',
v_align='center',
@ -236,7 +246,7 @@ class TournamentEntryWindow(PopupWindow):
bui.textwidget(
parent=self.root_widget,
position=(self._width * 0.5, 120),
position=(self._width * 0.5, 120 + off_p),
size=(0, 0),
h_align='center',
v_align='center',
@ -250,13 +260,26 @@ class TournamentEntryWindow(PopupWindow):
else:
self._pay_with_ad_btn = None
btn_size = (150, 45)
btn_pos = (self._width / 2 - btn_size[0] / 2, self._width / 2 - 110)
self._practice_button = None
if self._do_practice:
self._practice_button = bui.buttonwidget(
parent=self.root_widget,
position=btn_pos,
autoselect=True,
size=btn_size,
label=bui.Lstr(resource='practiceText'),
on_activate_call=self._on_practice_press,
)
self._get_tickets_button: bui.Widget | None = None
self._ticket_count_text: bui.Widget | None = None
if not bui.app.ui_v1.use_toolbars:
if bui.app.classic.allow_ticket_purchases:
self._get_tickets_button = bui.buttonwidget(
parent=self.root_widget,
position=(self._width - 190 + 125, self._height - 34),
position=(self._width - 190 + 105, self._height - 34),
autoselect=True,
scale=0.5,
size=(120, 60),
@ -372,6 +395,8 @@ class TournamentEntryWindow(PopupWindow):
sel = self.root_widget.get_selected_child()
if sel == self._pay_with_ad_btn:
sel_name = 'Ad'
elif sel == self._practice_button:
sel_name = 'Practice'
else:
sel_name = 'Tickets'
cfg = bui.app.config
@ -382,6 +407,8 @@ class TournamentEntryWindow(PopupWindow):
sel_name = bui.app.config.get('Tournament Pay Selection', 'Tickets')
if sel_name == 'Ad' and self._pay_with_ad_btn is not None:
sel = self._pay_with_ad_btn
elif sel_name == 'Practice' and self._practice_button is not None:
sel = self._practice_button
else:
sel = self._pay_with_tickets_button
bui.containerwidget(edit=self.root_widget, selected_child=sel)
@ -537,29 +564,37 @@ class TournamentEntryWindow(PopupWindow):
text=bui.charstr(bui.SpecialChar.TICKET) + t_str,
)
def _launch(self) -> None:
def _launch(self, practice: bool = False) -> None:
assert bui.app.classic is not None
if self._launched:
return
self._launched = True
launched = False
# If they gave us an existing activity, just restart it.
if self._tournament_activity is not None:
# If they gave us an existing, non-consistent
# practice activity, just restart it.
if (
self._tournament_activity is not None
and not practice == self._tournament_activity.session.submit_score
):
try:
bui.apptimer(0.1, bui.getsound('cashRegister').play)
if not practice:
bui.apptimer(0.1, bui.getsound('cashRegister').play)
bui.screenmessage(
bui.Lstr(
translate=(
'serverResponses',
'Entering tournament...',
)
),
color=(0, 1, 0),
)
bui.apptimer(0 if practice else 0.3, self._transition_out)
launched = True
with self._tournament_activity.context:
self._tournament_activity.end(
{'outcome': 'restart'}, force=True
)
bui.apptimer(0.3, self._transition_out)
launched = True
bui.screenmessage(
bui.Lstr(
translate=('serverResponses', 'Entering tournament...')
),
color=(0, 1, 0),
)
# We can hit exceptions here if _tournament_activity ends before
# our restart attempt happens.
@ -572,29 +607,28 @@ class TournamentEntryWindow(PopupWindow):
# If we had no existing activity (or were unable to restart it)
# launch a new session.
if not launched:
bui.apptimer(0.1, bui.getsound('cashRegister').play)
if not practice:
bui.apptimer(0.1, bui.getsound('cashRegister').play)
bui.screenmessage(
bui.Lstr(
translate=('serverResponses', 'Entering tournament...')
),
color=(0, 1, 0),
)
bui.apptimer(
1.0,
lambda: (
bui.app.classic.launch_coop_game(
self._tournament_info['game'],
args={
'min_players': self._tournament_info['minPlayers'],
'max_players': self._tournament_info['maxPlayers'],
'tournament_id': self._tournament_id,
},
)
if bui.app.classic is not None
else None
),
)
bui.apptimer(0.7, self._transition_out)
bui.screenmessage(
bui.Lstr(
translate=('serverResponses', 'Entering tournament...')
),
color=(0, 1, 0),
0 if practice else 1.0,
lambda: bui.app.classic.launch_coop_game(
self._tournament_info['game'],
args={
'min_players': self._tournament_info['minPlayers'],
'max_players': self._tournament_info['maxPlayers'],
'tournament_id': self._tournament_id,
'submit_score': not practice,
},
) if bui.app.classic is not None
else None
)
bui.apptimer(0 if practice else 1.25, self._transition_out)
def _on_pay_with_tickets_press(self) -> None:
from bauiv1lib import getcurrency
@ -691,6 +725,25 @@ class TournamentEntryWindow(PopupWindow):
on_completion_call=bui.WeakCall(self._on_ad_complete),
)
def _on_practice_press(self) -> None:
plus = bui.app.plus
assert plus is not None
# If we're already entering, ignore.
if self._entering:
return
# Deny if it looks like the tourney has ended.
if self._seconds_remaining == 0:
bui.screenmessage(
bui.Lstr(resource='tournamentEndedText'), color=(1, 0, 0)
)
bui.getsound('error').play()
return
self._entering = True
self._launch(practice=True)
def _on_ad_complete(self, actually_showed: bool) -> None:
plus = bui.app.plus
assert plus is not None