From 6f2bd47a4c3e036c812591c85139cc50814f4812 Mon Sep 17 00:00:00 2001 From: TrialTemp Date: Tue, 9 Jan 2024 12:19:42 -0600 Subject: [PATCH] Practice in Tournaments! --- .../ba_data/python/bascenev1/_coopsession.py | 12 +- .../ba_data/python/bascenev1/_session.py | 2 + .../python/bascenev1lib/activity/coopscore.py | 14 +- .../python/bauiv1lib/tournamententry.py | 131 +++++++++++++----- 4 files changed, 115 insertions(+), 44 deletions(-) diff --git a/src/assets/ba_data/python/bascenev1/_coopsession.py b/src/assets/ba_data/python/bascenev1/_coopsession.py index 72a67919..268b8ae8 100644 --- a/src/assets/ba_data/python/bascenev1/_coopsession.py +++ b/src/assets/ba_data/python/bascenev1/_coopsession.py @@ -60,7 +60,11 @@ 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] = [] @@ -70,6 +74,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) @@ -341,7 +346,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 + activity.session._submit_score + ): self._custom_menu_ui = [ { 'label': babase.Lstr(resource='restartText'), diff --git a/src/assets/ba_data/python/bascenev1/_session.py b/src/assets/ba_data/python/bascenev1/_session.py index 9ee55313..a76167b5 100644 --- a/src/assets/ba_data/python/bascenev1/_session.py +++ b/src/assets/ba_data/python/bascenev1/_session.py @@ -91,6 +91,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. @@ -162,6 +163,7 @@ class Session: self.sessionplayers = [] self.min_players = min_players self.max_players = max_players + self._submit_score = submit_score self.customdata = {} self._in_set_activity = False diff --git a/src/assets/ba_data/python/bascenev1lib/activity/coopscore.py b/src/assets/ba_data/python/bascenev1lib/activity/coopscore.py index 8b335a19..2bcf5514 100644 --- a/src/assets/ba_data/python/bascenev1lib/activity/coopscore.py +++ b/src/assets/ba_data/python/bascenev1lib/activity/coopscore.py @@ -124,6 +124,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() @@ -776,7 +777,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. @@ -1371,7 +1372,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'] @@ -1504,7 +1505,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)) @@ -1722,9 +1723,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( diff --git a/src/assets/ba_data/python/bauiv1lib/tournamententry.py b/src/assets/ba_data/python/bauiv1lib/tournamententry.py index d00c37dd..bea86616 100644 --- a/src/assets/ba_data/python/bauiv1lib/tournamententry.py +++ b/src/assets/ba_data/python/bauiv1lib/tournamententry.py @@ -85,6 +85,17 @@ class TournamentEntryWindow(PopupWindow): 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. + from bascenev1lib.activity.coopscore import CoopScoreScreen + self._do_practice = ( + self._tournament_activity is None or + isinstance(self._tournament_activity, CoopScoreScreen) + ) + + 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 +118,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 +143,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 +159,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 +176,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 +189,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 +200,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 ) @@ -222,7 +233,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', @@ -234,7 +245,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', @@ -248,13 +259,28 @@ 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 + ) + 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), @@ -370,6 +396,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 @@ -380,6 +408,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) @@ -523,29 +553,37 @@ class TournamentEntryWindow(PopupWindow): text=bui.charstr(bui.SpecialChar.TICKET) + t_str, ) - def _launch(self) -> None: + def _launch(self, practice = 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. @@ -558,27 +596,29 @@ 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, + 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.7, self._transition_out) - bui.screenmessage( - bui.Lstr( - translate=('serverResponses', 'Entering tournament...') - ), - color=(0, 1, 0), - ) + bui.apptimer(0 if practice else 0.7, self._transition_out) def _on_pay_with_tickets_press(self) -> None: from bauiv1lib import getcurrency @@ -674,6 +714,25 @@ class TournamentEntryWindow(PopupWindow): 'tournament_entry', 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 @@ -751,4 +810,4 @@ class TournamentEntryWindow(PopupWindow): def on_popup_cancel(self) -> None: bui.getsound('swish').play() - self._on_cancel() + self._on_cancel() \ No newline at end of file