From fa0036f14cc1e66c223f200edcfedf80b06065a0 Mon Sep 17 00:00:00 2001 From: Roman Trapeznikov Date: Sat, 10 Jul 2021 22:27:48 +0300 Subject: [PATCH] got coop in headless builds working --- assets/src/ba_data/python/ba/_coopsession.py | 34 +++++++++++++++---- .../python/bastd/activity/coopscore.py | 21 +++++------- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/assets/src/ba_data/python/ba/_coopsession.py b/assets/src/ba_data/python/ba/_coopsession.py index 6273f867..d0534e3c 100644 --- a/assets/src/ba_data/python/ba/_coopsession.py +++ b/assets/src/ba_data/python/ba/_coopsession.py @@ -156,8 +156,29 @@ class CoopSession(Session): from ba._general import WeakCall super().on_player_leave(sessionplayer) - # If all our players leave we wanna quit out of the session. - _ba.timer(2.0, WeakCall(self._end_session_if_empty)) + if _ba.app.server is not None: + # If we're in server mode, end game and show results. + activity = self.getactivity() + _ba.timer(2.0, WeakCall(self._end_activity_if_empty)) + else: + # Otherwise, if all our players leave + # we wanna quit out of the session. + _ba.timer(2.0, WeakCall(self._end_session_if_empty)) + + def _end_activity_if_empty(self) -> None: + activity = self.getactivity() + if activity is None: + return # Probably everything is already broken, why do something? + + if activity.players: + return + + with _ba.Context(activity): + from ba._gameactivity import GameActivity + + # FIXME: rewrite this, doesn't cover all cases + assert isinstance(activity, GameActivity) + activity.end_game() def _end_session_if_empty(self) -> None: activity = self.getactivity() @@ -250,10 +271,11 @@ class CoopSession(Session): # If at any point we have no in-game players, quit out of the session # (this can happen if someone leaves in the tutorial for instance). - active_players = [p for p in self.sessionplayers if p.in_game] - if not active_players: - self.end() - return + if isinstance(activity, TutorialActivity): + active_players = [p for p in self.sessionplayers if p.in_game] + if not active_players: + self.end() + return # If we're in a between-round activity or a restart-activity, # hop into a round. diff --git a/assets/src/ba_data/python/bastd/activity/coopscore.py b/assets/src/ba_data/python/bastd/activity/coopscore.py index a0a9d81f..fa4165db 100644 --- a/assets/src/ba_data/python/bastd/activity/coopscore.py +++ b/assets/src/ba_data/python/bastd/activity/coopscore.py @@ -122,7 +122,7 @@ class CoopScoreScreen(ba.Activity[ba.Player, ba.Team]): self._birth_time = ba.time() self._min_view_time = 5.0 self._allow_server_transition = False - self._server_transitioning: Optional[bool] = True + self._server_transitioning: Optional[bool] = None self._playerinfos: List[ba.PlayerInfo] = settings['playerinfos'] assert isinstance(self._playerinfos, list) @@ -494,8 +494,6 @@ class CoopScoreScreen(ba.Activity[ba.Player, ba.Team]): def _player_press(self) -> None: # (Only for headless builds). - print('HERE PLAYER PRESS') - # If this activity is a good 'end point', ask server-mode just once if # it wants to do anything special like switch sessions or kill the app. if (self._allow_server_transition and _ba.app.server is not None @@ -503,16 +501,14 @@ class CoopScoreScreen(ba.Activity[ba.Player, ba.Team]): self._server_transitioning = _ba.app.server.handle_transition() assert isinstance(self._server_transitioning, bool) - print('HERE IF PASSED') - # If server-mode is handling this, don't do anything ourself. if self._server_transitioning is True: return - print('HERE RESTARTING COOP') # Otherwise restart current level. - print('HERE ui_restart() only for testing; replace after that') - self._ui_restart() + self._campaign.set_selected_level(self._level_name) + with ba.Context(self): + self.end({'outcome': 'restart'}) def _safe_assign(self, player: EmptyPlayer) -> None: # (Only for headless builds). @@ -520,16 +516,15 @@ class CoopScoreScreen(ba.Activity[ba.Player, ba.Team]): # Just to be extra careful, don't assign if we're transitioning out. # (though theoretically that should be ok). if not self.is_transitioning_out() and player: - player.assigninput((ba.InputType.JUMP_PRESS, ba.InputType.PUNCH_PRESS, - ba.InputType.BOMB_PRESS, ba.InputType.PICK_UP_PRESS), - self._player_press) + player.assigninput( + (ba.InputType.JUMP_PRESS, ba.InputType.PUNCH_PRESS, + ba.InputType.BOMB_PRESS, ba.InputType.PICK_UP_PRESS), + self._player_press) def on_player_join(self, player: PlayerType) -> None: - print('HERE ON PLAYER JOIN') super().on_player_join(player) if ba.app.server is not None: - print('HERE INPUT ASSIGNED') # Host can't press retry button, so anyone can do it instead. time_till_assign = max( 0, self._birth_time + self._min_view_time - _ba.time())