From be4de98e7c1fe888c8c0c7859e55d707d747c860 Mon Sep 17 00:00:00 2001 From: Roman Trapeznikov Date: Thu, 9 Apr 2020 16:04:06 +0300 Subject: [PATCH 01/18] fix scores sorting in scorescreen activity --- assets/src/ba_data/python/bastd/activity/coopscorescreen.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/src/ba_data/python/bastd/activity/coopscorescreen.py b/assets/src/ba_data/python/bastd/activity/coopscorescreen.py index d97ad1e7..d29ba4cd 100644 --- a/assets/src/ba_data/python/bastd/activity/coopscorescreen.py +++ b/assets/src/ba_data/python/bastd/activity/coopscorescreen.py @@ -676,7 +676,8 @@ class CoopScoreScreen(ba.Activity): our_score = None try: - our_high_scores.sort(reverse=self._score_order == 'increasing') + our_high_scores.sort(reverse=self._score_order == 'increasing', + key=lambda x: x[0]) except Exception: ba.print_exception('Error sorting scores') print('our_high_scores:', our_high_scores) From bb39357a70aaca1d77a81fc66eba5e4199ff4542 Mon Sep 17 00:00:00 2001 From: Roman Trapeznikov Date: Thu, 9 Apr 2020 16:07:07 +0300 Subject: [PATCH 02/18] fix friends results sorting --- assets/src/ba_data/python/bastd/activity/coopscorescreen.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/src/ba_data/python/bastd/activity/coopscorescreen.py b/assets/src/ba_data/python/bastd/activity/coopscorescreen.py index d29ba4cd..f139d251 100644 --- a/assets/src/ba_data/python/bastd/activity/coopscorescreen.py +++ b/assets/src/ba_data/python/bastd/activity/coopscorescreen.py @@ -928,7 +928,8 @@ class CoopScoreScreen(ba.Activity): results.remove(score) break results.append(our_score_entry) - results.sort(reverse=self._score_order == 'increasing') + results.sort(reverse=self._score_order == 'increasing', + key=lambda x: x[0]) # If we're not submitting our own score, we still want to change the # name of our own score to 'Me'. From fe606ced907541be1b93e9674a9874e632b66b9c Mon Sep 17 00:00:00 2001 From: indev Date: Thu, 9 Apr 2020 19:36:35 +0300 Subject: [PATCH 03/18] Fix elimination --- assets/src/ba_data/python/bastd/game/elimination.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/src/ba_data/python/bastd/game/elimination.py b/assets/src/ba_data/python/bastd/game/elimination.py index f17a116c..89700e30 100644 --- a/assets/src/ba_data/python/bastd/game/elimination.py +++ b/assets/src/ba_data/python/bastd/game/elimination.py @@ -59,7 +59,7 @@ class Icon(ba.Actor): icon = player.get_icon() self.node = ba.newnode('image', - owner=self, + delegate=self, attrs={ 'texture': icon['texture'], 'tint_texture': icon['tint_texture'], From b13df592748c26b9f0431191069873a941b135b3 Mon Sep 17 00:00:00 2001 From: Roman Trapeznikov Date: Fri, 10 Apr 2020 12:37:45 +0300 Subject: [PATCH 04/18] specify a sorting key for sorting nested lists in ba module sorting with objects that Python cannot compare --- assets/src/ba_data/python/ba/_gameresults.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/src/ba_data/python/ba/_gameresults.py b/assets/src/ba_data/python/ba/_gameresults.py index 47146043..76513f16 100644 --- a/assets/src/ba_data/python/ba/_gameresults.py +++ b/assets/src/ba_data/python/ba/_gameresults.py @@ -189,7 +189,7 @@ class TeamGameResults: sval.append(team) results: List[Tuple[Optional[int], List[ba.Team]]] = list(winners.items()) - results.sort(reverse=not self._lower_is_better) + results.sort(reverse=not self._lower_is_better, key=lambda x: x[0]) # Also group the 'None' scores. none_teams: List[ba.Team] = [] From 93c407cccc25cb1ec9cddc4b5fa1717019969674 Mon Sep 17 00:00:00 2001 From: Roman Trapeznikov Date: Fri, 10 Apr 2020 12:48:21 +0300 Subject: [PATCH 05/18] specify sorting key for sorting nested lists in elimination game --- assets/src/ba_data/python/bastd/game/elimination.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/src/ba_data/python/bastd/game/elimination.py b/assets/src/ba_data/python/bastd/game/elimination.py index f17a116c..6843a453 100644 --- a/assets/src/ba_data/python/bastd/game/elimination.py +++ b/assets/src/ba_data/python/bastd/game/elimination.py @@ -400,7 +400,8 @@ class EliminationGame(ba.TeamGameActivity): self.map.get_start_position(team.get_id())) points.append( ((start_pos - player_pos).length(), start_pos)) - points.sort() + # Hmm.. we need to sorting vectors too? + points.sort(key=lambda x: x[0]) return points[-1][1] return None From 56d5b5f17565cf47c818e658a99ae66ed9d8fbbc Mon Sep 17 00:00:00 2001 From: Roman Trapeznikov Date: Fri, 10 Apr 2020 12:52:10 +0300 Subject: [PATCH 06/18] specify sorting key for sorting nested lists in race game --- assets/src/ba_data/python/bastd/game/race.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/assets/src/ba_data/python/bastd/game/race.py b/assets/src/ba_data/python/bastd/game/race.py index 5640e9b7..2190231a 100644 --- a/assets/src/ba_data/python/bastd/game/race.py +++ b/assets/src/ba_data/python/bastd/game/race.py @@ -550,9 +550,7 @@ class RaceGame(ba.TeamGameActivity): p_list = [[player.gamedata['distance'], player] for player in self.players] - p_list.sort(reverse=True) - # FIXME - need another way to sort p_list. - # It tries to compare ba.Player objects. + p_list.sort(reverse=True, key=lambda x: x[0]) for i, plr in enumerate(p_list): try: plr[1].gamedata['rank'] = i From 78e70e002c32251e61491405f2825f73d3603083 Mon Sep 17 00:00:00 2001 From: Roman Trapeznikov Date: Fri, 10 Apr 2020 13:02:08 +0300 Subject: [PATCH 07/18] specify sorting key for sorting nested lists in multiteamjoinscreen --- .../src/ba_data/python/bastd/activity/multiteamendscreen.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/src/ba_data/python/bastd/activity/multiteamendscreen.py b/assets/src/ba_data/python/bastd/activity/multiteamendscreen.py index 4abff20b..f3f399c9 100644 --- a/assets/src/ba_data/python/bastd/activity/multiteamendscreen.py +++ b/assets/src/ba_data/python/bastd/activity/multiteamendscreen.py @@ -80,11 +80,11 @@ class TeamSeriesVictoryScoreScreenActivity(TeamsScoreScreenActivity): player_entries.append( (prec.player.team.sessiondata['score'], prec.get_name(full=True), prec)) - player_entries.sort(reverse=True) + player_entries.sort(reverse=True, key=lambda x: x[0]) else: for _pkey, prec in self.stats.get_records().items(): player_entries.append((prec.score, prec.name_full, prec)) - player_entries.sort(reverse=True) + player_entries.sort(reverse=True, key=lambda x: x[0]) ts_height = 300.0 ts_h_offs = -390.0 From ea9910820299d5f15b720b699989da9755effe21 Mon Sep 17 00:00:00 2001 From: Roman Trapeznikov Date: Fri, 10 Apr 2020 13:58:28 +0300 Subject: [PATCH 08/18] add sorting key for some sorted functions for sorting nested lists --- assets/src/ba_data/python/bastd/ui/gather.py | 3 +-- assets/src/ba_data/python/efro/util.py | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/src/ba_data/python/bastd/ui/gather.py b/assets/src/ba_data/python/bastd/ui/gather.py index fc63e4f4..7611aee2 100644 --- a/assets/src/ba_data/python/bastd/ui/gather.py +++ b/assets/src/ba_data/python/bastd/ui/gather.py @@ -1451,8 +1451,7 @@ class GatherWindow(ba.Window): key=lambda p: ( p['queue'] is None, # Show non-queued last. p['ping'] if p['ping'] is not None else 999999, - p['index'], - p)) + p['index'])) existing_selection = self._public_party_list_selection first = True diff --git a/assets/src/ba_data/python/efro/util.py b/assets/src/ba_data/python/efro/util.py index 8f607758..aa777d4d 100644 --- a/assets/src/ba_data/python/efro/util.py +++ b/assets/src/ba_data/python/efro/util.py @@ -303,4 +303,6 @@ def make_hash(obj: Any) -> int: for k, v in new_obj.items(): new_obj[k] = make_hash(v) + # NOTE: there is sorted works correctly because it compares only + # unique first values (i.e. dict keys) return hash(tuple(frozenset(sorted(new_obj.items())))) From 193cabf3c4bc1d6a1776ff1a36769e520eb412bb Mon Sep 17 00:00:00 2001 From: indev Date: Sat, 11 Apr 2020 11:15:46 +0300 Subject: [PATCH 09/18] Fix some spawn-points (Top -> top, Bottom -> bottom) --- assets/src/ba_data/python/bastd/game/onslaught.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/src/ba_data/python/bastd/game/onslaught.py b/assets/src/ba_data/python/bastd/game/onslaught.py index d2379e7c..dca402c2 100644 --- a/assets/src/ba_data/python/bastd/game/onslaught.py +++ b/assets/src/ba_data/python/bastd/game/onslaught.py @@ -430,11 +430,11 @@ class OnslaughtGame(ba.CoopGameActivity): {'entries': [ {'type': spazbot.ChargerBotProShielded, 'point': 'bottom_right'}, - {'type': spazbot.ChargerBotProShielded, 'point': 'Bottom'} + {'type': spazbot.ChargerBotProShielded, 'point': 'bottom'} if player_count > 2 else None, {'type': spazbot.ChargerBotProShielded, 'point': 'bottom_left'}, - {'type': spazbot.ChargerBotProShielded, 'point': 'Top'} + {'type': spazbot.ChargerBotProShielded, 'point': 'top'} if hard else None, {'type': spazbot.BomberBotProStatic, 'point': 'turret_top_middle'}, From 3029979a592151648cd1c6366b48b222c123ab01 Mon Sep 17 00:00:00 2001 From: indev Date: Sat, 11 Apr 2020 12:08:58 +0300 Subject: [PATCH 10/18] Hockey puck is visible now --- assets/src/ba_data/python/bastd/game/hockey.py | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/src/ba_data/python/bastd/game/hockey.py b/assets/src/ba_data/python/bastd/game/hockey.py index 7fae6d79..95705d6d 100644 --- a/assets/src/ba_data/python/bastd/game/hockey.py +++ b/assets/src/ba_data/python/bastd/game/hockey.py @@ -69,6 +69,7 @@ class Puck(ba.Actor): 'position': self._spawn_pos, 'materials': pmats }) + ba.animate(self.node, "model_scale", {0: 0, 0.2: 1.3, 0.26: 1}) def handlemessage(self, msg: Any) -> Any: if isinstance(msg, ba.DieMessage): From 3b50b6ee9dd271133ce685cbb0f5815613b488a7 Mon Sep 17 00:00:00 2001 From: indev Date: Sat, 11 Apr 2020 12:11:21 +0300 Subject: [PATCH 11/18] Fixed one minor exception --- assets/src/ba_data/python/bastd/game/capturetheflag.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/src/ba_data/python/bastd/game/capturetheflag.py b/assets/src/ba_data/python/bastd/game/capturetheflag.py index c32526f9..c23a5dd3 100644 --- a/assets/src/ba_data/python/bastd/game/capturetheflag.py +++ b/assets/src/ba_data/python/bastd/game/capturetheflag.py @@ -290,6 +290,8 @@ class CaptureTheFlagGame(ba.TeamGameActivity): if (not team.gamedata['home_flag_at_base'] and flag.held_count == 0): time_out_counting_down = True + if flag.time_out_respawn_time is None: + flag.reset_return_times() flag.time_out_respawn_time -= 1 if flag.time_out_respawn_time <= 0: flag.handlemessage(ba.DieMessage()) From 17273e90d85a7dc12a8597ea57f0fb4aff783875 Mon Sep 17 00:00:00 2001 From: indev Date: Sat, 11 Apr 2020 12:23:25 +0300 Subject: [PATCH 12/18] Mypy tests passed --- assets/src/ba_data/python/bastd/game/capturetheflag.py | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/src/ba_data/python/bastd/game/capturetheflag.py b/assets/src/ba_data/python/bastd/game/capturetheflag.py index c23a5dd3..c123eaa7 100644 --- a/assets/src/ba_data/python/bastd/game/capturetheflag.py +++ b/assets/src/ba_data/python/bastd/game/capturetheflag.py @@ -292,6 +292,7 @@ class CaptureTheFlagGame(ba.TeamGameActivity): time_out_counting_down = True if flag.time_out_respawn_time is None: flag.reset_return_times() + assert flag.time_out_respawn_time is not None flag.time_out_respawn_time -= 1 if flag.time_out_respawn_time <= 0: flag.handlemessage(ba.DieMessage()) From f6802dfed0f15510942620cff6ca4b6282e9ffb9 Mon Sep 17 00:00:00 2001 From: Roman Trapeznikov Date: Sat, 11 Apr 2020 15:02:46 +0300 Subject: [PATCH 13/18] fix ffa session --- assets/src/ba_data/python/ba/_session.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/assets/src/ba_data/python/ba/_session.py b/assets/src/ba_data/python/ba/_session.py index 52671049..10d43c76 100644 --- a/assets/src/ba_data/python/ba/_session.py +++ b/assets/src/ba_data/python/ba/_session.py @@ -146,11 +146,6 @@ class Session: # print('Would set host-session asset-reqs to:', # required_asset_packages) - if team_names is None: - team_names = ['Good Guys'] - if team_colors is None: - team_colors = [(0.6, 0.2, 1.0)] - # First thing, wire up our internal engine data. self._sessiondata = _ba.register_session(self) From 337045c9f84d10027f108f76f6091f1f983f38a5 Mon Sep 17 00:00:00 2001 From: Roman Trapeznikov Date: Sat, 11 Apr 2020 15:35:45 +0300 Subject: [PATCH 14/18] type-checking --- assets/src/ba_data/python/ba/_session.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/src/ba_data/python/ba/_session.py b/assets/src/ba_data/python/ba/_session.py index 10d43c76..c5f774ca 100644 --- a/assets/src/ba_data/python/ba/_session.py +++ b/assets/src/ba_data/python/ba/_session.py @@ -192,6 +192,8 @@ class Session: self.max_players = max_players if self._use_teams: + assert team_names is not None + assert team_colors is not None for i, color in enumerate(team_colors): team = Team(team_id=self._next_team_id, name=GameActivity.get_team_display_string( From 8f9a7c4ac61e410d085159d4fff366c12b679772 Mon Sep 17 00:00:00 2001 From: Roman Trapeznikov Date: Sat, 11 Apr 2020 15:54:58 +0300 Subject: [PATCH 15/18] enable pylint: too-many-branches --- assets/src/ba_data/python/ba/_session.py | 1 - 1 file changed, 1 deletion(-) diff --git a/assets/src/ba_data/python/ba/_session.py b/assets/src/ba_data/python/ba/_session.py index c5f774ca..b1b56d4a 100644 --- a/assets/src/ba_data/python/ba/_session.py +++ b/assets/src/ba_data/python/ba/_session.py @@ -97,7 +97,6 @@ class Session: instances; one for each ba.Activity the session may potentially run. """ # pylint: disable=too-many-statements - # pylint: disable=too-many-branches # pylint: disable=too-many-locals # pylint: disable=cyclic-import from ba._lobby import Lobby From c654830c5049ffc2b691d724bafc928d10ab5b82 Mon Sep 17 00:00:00 2001 From: Eric Froemling Date: Sat, 11 Apr 2020 13:47:37 -0700 Subject: [PATCH 16/18] tidying --- assets/src/ba_data/python/ba/_teambasesession.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/assets/src/ba_data/python/ba/_teambasesession.py b/assets/src/ba_data/python/ba/_teambasesession.py index ffd93f36..2bd8bbe6 100644 --- a/assets/src/ba_data/python/ba/_teambasesession.py +++ b/assets/src/ba_data/python/ba/_teambasesession.py @@ -53,7 +53,7 @@ class TeamBaseSession(Session): def __init__(self) -> None: """Set up playlists and launches a ba.Activity to accept joiners.""" # pylint: disable=cyclic-import - from ba import _playlist as bsplaylist + from ba import _playlist from bastd.activity import multiteamjoinscreen app = _ba.app cfg = app.config @@ -67,6 +67,7 @@ class TeamBaseSession(Session): # print('FIXME: TEAM BASE SESSION WOULD CALC DEPS.') depsets: Sequence[ba.DependencySet] = [] + super().__init__(depsets, team_names=team_names, team_colors=team_colors, @@ -105,17 +106,17 @@ class TeamBaseSession(Session): playlist = copy.deepcopy(playlists[self._playlist_name]) else: if self._use_teams: - playlist = bsplaylist.get_default_teams_playlist() + playlist = _playlist.get_default_teams_playlist() else: - playlist = bsplaylist.get_default_free_for_all_playlist() + playlist = _playlist.get_default_free_for_all_playlist() # Resolve types and whatnot to get our final playlist. - playlist_resolved = bsplaylist.filter_playlist(playlist, - sessiontype=type(self), - add_resolved_type=True) + playlist_resolved = _playlist.filter_playlist(playlist, + sessiontype=type(self), + add_resolved_type=True) if not playlist_resolved: - raise Exception("playlist contains no valid games") + raise RuntimeError("Playlist contains no valid games.") self._playlist = ShuffleList(playlist_resolved, shuffle=self._playlist_randomize) From f0e6e2be778c6c488655f03acc2b8c17f1d1c613 Mon Sep 17 00:00:00 2001 From: Eric Froemling Date: Sat, 11 Apr 2020 21:54:27 -0700 Subject: [PATCH 17/18] Simple tidying --- assets/src/ba_data/python/ba/_app.py | 9 +- assets/src/ba_data/python/ba/_coopsession.py | 1 + assets/src/ba_data/python/ba/_gameactivity.py | 5 +- assets/src/ba_data/python/ba/_playlist.py | 124 +++++++----------- assets/src/ba_data/python/ba/_session.py | 76 +++++------ .../src/ba_data/python/ba/_teambasesession.py | 20 +-- 6 files changed, 103 insertions(+), 132 deletions(-) diff --git a/assets/src/ba_data/python/ba/_app.py b/assets/src/ba_data/python/ba/_app.py index bb625c88..5e652b50 100644 --- a/assets/src/ba_data/python/ba/_app.py +++ b/assets/src/ba_data/python/ba/_app.py @@ -771,7 +771,10 @@ class App: return False # Ok, we're good to go. - self.coop_session_args = {'campaign': campaignname, 'level': levelname} + self.coop_session_args = { + 'campaign': campaignname, + 'level': levelname, + } for arg_name, arg_val in list(args.items()): self.coop_session_args[arg_name] = arg_val @@ -782,8 +785,8 @@ class App: except Exception: from ba import _error _error.print_exception() - from bastd import mainmenu - _ba.new_host_session(mainmenu.MainMenuSession) + from bastd.mainmenu import MainMenuSession + _ba.new_host_session(MainMenuSession) _ba.fade_screen(False, endcall=_fade_end) return True diff --git a/assets/src/ba_data/python/ba/_coopsession.py b/assets/src/ba_data/python/ba/_coopsession.py index c0f212c3..7e3967c2 100644 --- a/assets/src/ba_data/python/ba/_coopsession.py +++ b/assets/src/ba_data/python/ba/_coopsession.py @@ -353,6 +353,7 @@ class CoopSession(Session): if results.get_score_type() in ('seconds', 'milliseconds', 'time'): score_type = 'time' + # Results contains milliseconds; ScoreScreen wants # hundredths; need to fix :-/ if score is not None: diff --git a/assets/src/ba_data/python/ba/_gameactivity.py b/assets/src/ba_data/python/ba/_gameactivity.py index c64af244..f5a7f7f6 100644 --- a/assets/src/ba_data/python/ba/_gameactivity.py +++ b/assets/src/ba_data/python/ba/_gameactivity.py @@ -289,10 +289,10 @@ class GameActivity(Activity): @classmethod def supports_session_type(cls, sessiontype: Type[ba.Session]) -> bool: """Return whether this game supports the provided Session type.""" - from ba import _teambasesession + from ba._teambasesession import TeamBaseSession # By default, games support any versus mode - return issubclass(sessiontype, _teambasesession.TeamBaseSession) + return issubclass(sessiontype, TeamBaseSession) def __init__(self, settings: Dict[str, Any]): """Instantiate the Activity.""" @@ -546,6 +546,7 @@ class GameActivity(Activity): self.end_game() + # FIXME: this logic should live in the session classes. def _game_begin_analytics(self) -> None: """Update analytics events for the start of the game.""" # pylint: disable=too-many-branches diff --git a/assets/src/ba_data/python/ba/_playlist.py b/assets/src/ba_data/python/ba/_playlist.py index 9e473999..5caf6dec 100644 --- a/assets/src/ba_data/python/ba/_playlist.py +++ b/assets/src/ba_data/python/ba/_playlist.py @@ -60,26 +60,29 @@ def filter_playlist(playlist: PlaylistType, unowned_game_types = set() for entry in copy.deepcopy(playlist): - # 'map' used to be called 'level' here + # 'map' used to be called 'level' here. if 'level' in entry: entry['map'] = entry['level'] del entry['level'] - # we now stuff map into settings instead of it being its own thing + + # We now stuff map into settings instead of it being its own thing. if 'map' in entry: entry['settings']['map'] = entry['map'] del entry['map'] - # update old map names to new ones + + # Update old map names to new ones. entry['settings']['map'] = _map.get_filtered_map_name( entry['settings']['map']) if remove_unowned and entry['settings']['map'] in unowned_maps: continue - # ok, for each game in our list, try to import the module and grab + + # Ok, for each game in our list, try to import the module and grab # the actual game class. add successful ones to our initial list - # to present to the user + # to present to the user. if not isinstance(entry['type'], str): raise Exception("invalid entry format") try: - # do some type filters for backwards compat. + # Do some type filters for backwards compat. if entry['type'] in ('Assault.AssaultGame', 'Happy_Thoughts.HappyThoughtsGame', 'bsAssault.AssaultGame', @@ -147,7 +150,7 @@ def filter_playlist(playlist: PlaylistType, if mark_unowned and gameclass in unowned_game_types: entry['is_unowned_game'] = True - # make sure all settings the game defines are present + # Make sure all settings the game defines are present. neededsettings = gameclass.get_settings(sessiontype) for setting_name, setting in neededsettings: if (setting_name not in entry['settings'] @@ -164,6 +167,7 @@ def filter_playlist(playlist: PlaylistType, def get_default_free_for_all_playlist() -> PlaylistType: """Return a default playlist for free-for-all mode.""" + # NOTE: these are currently using old type/map names, # but filtering translates them properly to the new ones. # (is kinda a handy way to ensure filtering is working). @@ -177,8 +181,7 @@ def get_default_free_for_all_playlist() -> PlaylistType: 'map': 'Doom Shroom' }, 'type': 'bs_death_match.DeathMatchGame' - }, - { + }, { 'settings': { 'Chosen One Gets Gloves': True, 'Chosen One Gets Shield': False, @@ -189,8 +192,7 @@ def get_default_free_for_all_playlist() -> PlaylistType: 'map': 'Monkey Face' }, 'type': 'bs_chosen_one.ChosenOneGame' - }, - { + }, { 'settings': { 'Hold Time': 30, 'Respawn Times': 1.0, @@ -198,15 +200,13 @@ def get_default_free_for_all_playlist() -> PlaylistType: 'map': 'Zigzag' }, 'type': 'bs_king_of_the_hill.KingOfTheHillGame' - }, - { + }, { 'settings': { 'Epic Mode': False, 'map': 'Rampage' }, 'type': 'bs_meteor_shower.MeteorShowerGame' - }, - { + }, { 'settings': { 'Epic Mode': 1, 'Lives Per Player': 1, @@ -215,8 +215,7 @@ def get_default_free_for_all_playlist() -> PlaylistType: 'map': 'Tip Top' }, 'type': 'bs_elimination.EliminationGame' - }, - { + }, { 'settings': { 'Hold Time': 30, 'Respawn Times': 1.0, @@ -224,8 +223,7 @@ def get_default_free_for_all_playlist() -> PlaylistType: 'map': 'The Pad' }, 'type': 'bs_keep_away.KeepAwayGame' - }, - { + }, { 'settings': { 'Epic Mode': True, 'Kills to Win Per Player': 10, @@ -234,8 +232,7 @@ def get_default_free_for_all_playlist() -> PlaylistType: 'map': 'Rampage' }, 'type': 'bs_death_match.DeathMatchGame' - }, - { + }, { 'settings': { 'Bomb Spawning': 1000, 'Epic Mode': False, @@ -246,8 +243,7 @@ def get_default_free_for_all_playlist() -> PlaylistType: 'map': 'Big G' }, 'type': 'bs_race.RaceGame' - }, - { + }, { 'settings': { 'Hold Time': 30, 'Respawn Times': 1.0, @@ -255,8 +251,7 @@ def get_default_free_for_all_playlist() -> PlaylistType: 'map': 'Happy Thoughts' }, 'type': 'bs_king_of_the_hill.KingOfTheHillGame' - }, - { + }, { 'settings': { 'Enable Impact Bombs': 1, 'Enable Triple Bombs': False, @@ -264,8 +259,7 @@ def get_default_free_for_all_playlist() -> PlaylistType: 'map': 'Doom Shroom' }, 'type': 'bs_target_practice.TargetPracticeGame' - }, - { + }, { 'settings': { 'Epic Mode': False, 'Lives Per Player': 5, @@ -274,8 +268,7 @@ def get_default_free_for_all_playlist() -> PlaylistType: 'map': 'Step Right Up' }, 'type': 'bs_elimination.EliminationGame' - }, - { + }, { 'settings': { 'Epic Mode': False, 'Kills to Win Per Player': 10, @@ -284,8 +277,7 @@ def get_default_free_for_all_playlist() -> PlaylistType: 'map': 'Crag Castle' }, 'type': 'bs_death_match.DeathMatchGame' - }, - { + }, { 'map': 'Lake Frigid', 'settings': { 'Bomb Spawning': 0, @@ -296,7 +288,7 @@ def get_default_free_for_all_playlist() -> PlaylistType: 'map': 'Lake Frigid' }, 'type': 'bs_race.RaceGame' - }] # yapf: disable + }] def get_default_teams_playlist() -> PlaylistType: @@ -317,8 +309,7 @@ def get_default_teams_playlist() -> PlaylistType: 'map': 'Bridgit' }, 'type': 'bs_capture_the_flag.CTFGame' - }, - { + }, { 'settings': { 'Epic Mode': False, 'Respawn Times': 1.0, @@ -327,8 +318,7 @@ def get_default_teams_playlist() -> PlaylistType: 'map': 'Step Right Up' }, 'type': 'bs_assault.AssaultGame' - }, - { + }, { 'settings': { 'Balance Total Lives': False, 'Epic Mode': False, @@ -339,8 +329,7 @@ def get_default_teams_playlist() -> PlaylistType: 'map': 'Rampage' }, 'type': 'bs_elimination.EliminationGame' - }, - { + }, { 'settings': { 'Epic Mode': False, 'Kills to Win Per Player': 5, @@ -349,8 +338,7 @@ def get_default_teams_playlist() -> PlaylistType: 'map': 'Roundabout' }, 'type': 'bs_death_match.DeathMatchGame' - }, - { + }, { 'settings': { 'Respawn Times': 1.0, 'Score to Win': 1, @@ -358,8 +346,7 @@ def get_default_teams_playlist() -> PlaylistType: 'map': 'Hockey Stadium' }, 'type': 'bs_hockey.HockeyGame' - }, - { + }, { 'settings': { 'Hold Time': 30, 'Respawn Times': 1.0, @@ -367,8 +354,7 @@ def get_default_teams_playlist() -> PlaylistType: 'map': 'Monkey Face' }, 'type': 'bs_keep_away.KeepAwayGame' - }, - { + }, { 'settings': { 'Balance Total Lives': False, 'Epic Mode': True, @@ -379,8 +365,7 @@ def get_default_teams_playlist() -> PlaylistType: 'map': 'Tip Top' }, 'type': 'bs_elimination.EliminationGame' - }, - { + }, { 'settings': { 'Epic Mode': False, 'Respawn Times': 1.0, @@ -389,8 +374,7 @@ def get_default_teams_playlist() -> PlaylistType: 'map': 'Crag Castle' }, 'type': 'bs_assault.AssaultGame' - }, - { + }, { 'settings': { 'Epic Mode': False, 'Kills to Win Per Player': 5, @@ -399,15 +383,13 @@ def get_default_teams_playlist() -> PlaylistType: 'map': 'Doom Shroom' }, 'type': 'bs_death_match.DeathMatchGame' - }, - { + }, { 'settings': { 'Epic Mode': False, 'map': 'Rampage' }, 'type': 'bs_meteor_shower.MeteorShowerGame' - }, - { + }, { 'settings': { 'Epic Mode': False, 'Flag Idle Return Time': 30, @@ -418,8 +400,7 @@ def get_default_teams_playlist() -> PlaylistType: 'map': 'Roundabout' }, 'type': 'bs_capture_the_flag.CTFGame' - }, - { + }, { 'settings': { 'Respawn Times': 1.0, 'Score to Win': 21, @@ -427,8 +408,7 @@ def get_default_teams_playlist() -> PlaylistType: 'map': 'Football Stadium' }, 'type': 'bs_football.FootballTeamGame' - }, - { + }, { 'settings': { 'Epic Mode': True, 'Respawn Times': 0.25, @@ -437,8 +417,7 @@ def get_default_teams_playlist() -> PlaylistType: 'map': 'Bridgit' }, 'type': 'bs_assault.AssaultGame' - }, - { + }, { 'map': 'Doom Shroom', 'settings': { 'Enable Impact Bombs': 1, @@ -447,8 +426,7 @@ def get_default_teams_playlist() -> PlaylistType: 'map': 'Doom Shroom' }, 'type': 'bs_target_practice.TargetPracticeGame' - }, - { + }, { 'settings': { 'Hold Time': 30, 'Respawn Times': 1.0, @@ -456,8 +434,7 @@ def get_default_teams_playlist() -> PlaylistType: 'map': 'Tip Top' }, 'type': 'bs_king_of_the_hill.KingOfTheHillGame' - }, - { + }, { 'settings': { 'Epic Mode': False, 'Respawn Times': 1.0, @@ -466,8 +443,7 @@ def get_default_teams_playlist() -> PlaylistType: 'map': 'Zigzag' }, 'type': 'bs_assault.AssaultGame' - }, - { + }, { 'settings': { 'Epic Mode': False, 'Flag Idle Return Time': 30, @@ -478,8 +454,7 @@ def get_default_teams_playlist() -> PlaylistType: 'map': 'Happy Thoughts' }, 'type': 'bs_capture_the_flag.CTFGame' - }, - { + }, { 'settings': { 'Bomb Spawning': 1000, 'Epic Mode': True, @@ -489,8 +464,7 @@ def get_default_teams_playlist() -> PlaylistType: 'map': 'Big G' }, 'type': 'bs_race.RaceGame' - }, - { + }, { 'settings': { 'Epic Mode': False, 'Kills to Win Per Player': 5, @@ -499,8 +473,7 @@ def get_default_teams_playlist() -> PlaylistType: 'map': 'Monkey Face' }, 'type': 'bs_death_match.DeathMatchGame' - }, - { + }, { 'settings': { 'Hold Time': 30, 'Respawn Times': 1.0, @@ -508,8 +481,7 @@ def get_default_teams_playlist() -> PlaylistType: 'map': 'Lake Frigid' }, 'type': 'bs_keep_away.KeepAwayGame' - }, - { + }, { 'settings': { 'Epic Mode': False, 'Flag Idle Return Time': 30, @@ -520,8 +492,7 @@ def get_default_teams_playlist() -> PlaylistType: 'map': 'Tip Top' }, 'type': 'bs_capture_the_flag.CTFGame' - }, - { + }, { 'settings': { 'Balance Total Lives': False, 'Epic Mode': False, @@ -532,8 +503,7 @@ def get_default_teams_playlist() -> PlaylistType: 'map': 'Crag Castle' }, 'type': 'bs_elimination.EliminationGame' - }, - { + }, { 'settings': { 'Epic Mode': True, 'Respawn Times': 0.25, @@ -541,4 +511,4 @@ def get_default_teams_playlist() -> PlaylistType: 'map': 'Zigzag' }, 'type': 'bs_conquest.ConquestGame' - }] # yapf: disable + }] diff --git a/assets/src/ba_data/python/ba/_session.py b/assets/src/ba_data/python/ba/_session.py index b1b56d4a..14bf3ef1 100644 --- a/assets/src/ba_data/python/ba/_session.py +++ b/assets/src/ba_data/python/ba/_session.py @@ -75,14 +75,6 @@ class Session: """ - # Annotate our attrs at class level so they're available for introspection. - teams: List[ba.Team] - campaign: Optional[ba.Campaign] - lobby: ba.Lobby - min_players: int - max_players: int - players: List[ba.Player] - def __init__(self, depsets: Sequence[ba.DependencySet], team_names: Sequence[str] = None, @@ -107,26 +99,23 @@ class Session: from ba._error import DependencyError from ba._dependency import Dependency, AssetPackage - # print(' WOULD LOOK AT DEP SETS', depsets) - - # first off, resolve all dep-sets we were passed. - # if things are missing, we'll try to gather them into - # a single missing-deps exception if possible - # to give the caller a clean path to download missing - # stuff and try again. + # First off, resolve all dependency-sets we were passed. + # If things are missing, we'll try to gather them into a single + # missing-deps exception if possible to give the caller a clean + # path to download missing stuff and try again. missing_asset_packages: Set[str] = set() for depset in depsets: try: depset.resolve() except DependencyError as exc: - # we gather/report missing assets only; barf on anything else + # Gather/report missing assets only; barf on anything else. if all(issubclass(d.cls, AssetPackage) for d in exc.deps): for dep in exc.deps: assert isinstance(dep.config, str) missing_asset_packages.add(dep.config) else: missing_info = [(d.cls, d.config) for d in exc.deps] - raise Exception( + raise RuntimeError( f'Missing non-asset dependencies: {missing_info}') # Throw a combined exception if we found anything missing. @@ -153,11 +142,11 @@ class Session: # FIXME: This stuff shouldn't be here. self.sharedobjs: Dict[str, Any] = {} - # TeamGameActivity uses this to display a help overlay on - # the first activity only. + # TeamGameActivity uses this to display a help overlay on the first + # activity only. self.have_shown_controls_help_overlay = False - self.campaign = None + self.campaign: Optional[ba.Campaign] = None # FIXME: Should be able to kill this I think. self.campaign_state: Dict[str, str] = {} @@ -167,8 +156,8 @@ class Session: self._in_set_activity = False self._allow_mid_activity_joins = allow_mid_activity_joins - self.teams = [] - self.players = [] + self.teams: List[ba.Team] = [] + self.players: List[ba.Player] = [] self._next_team_id = 0 self._activity_retained: Optional[ba.Activity] = None self.launch_end_session_activity_time: Optional[float] = None @@ -180,9 +169,8 @@ class Session: self._activity_weak: ReferenceType[ba.Activity] self._activity_weak = weakref.ref(_EmptyObj()) # type: ignore - if self._activity_weak() is not None: - raise Exception("error creating empty weak ref") + raise Exception("Error creating empty activity weak ref.") self._next_activity: Optional[ba.Activity] = None self.wants_to_end = False @@ -190,6 +178,7 @@ class Session: self.min_players = min_players self.max_players = max_players + # Create Teams. if self._use_teams: assert team_names is not None assert team_colors is not None @@ -206,10 +195,10 @@ class Session: self.on_team_join(team) except Exception: from ba import _error - _error.print_exception('exception in on_team_join for', - self) + _error.print_exception( + f'Error in on_team_join for {self}.') - self.lobby = Lobby() + self.lobby: ba.Lobby = Lobby() self.stats = Stats() # Instantiate our session globals node @@ -238,8 +227,8 @@ class Session: if len(self.players) >= self.max_players: - # Print a rejection message *only* to the client trying to join - # (prevents spamming everyone else in the game). + # Print a rejection message *only* to the client trying to + # join (prevents spamming everyone else in the game). _ba.playsound(_ba.getsound('error')) _ba.screenmessage( Lstr(resource='playerLimitReachedText', @@ -287,7 +276,7 @@ class Session: _error.print_exception( 'Error in Lobby.remove_chooser()') - # *if* he was actually in the game, announce his departure + # *If* they were actually in the game, announce their departure. if team is not None: _ba.screenmessage( Lstr(resource='playerLeftText', @@ -298,7 +287,7 @@ class Session: # team lists every activity) if team is not None and player in team.players: - # Testing.. can remove this eventually. + # Testing; can remove this eventually. if isinstance(self, FreeForAllSession): if len(team.players) != 1: _error.print_error("expected 1 player in FFA team") @@ -324,7 +313,7 @@ class Session: player.set_activity(None) player.set_node(None) - # reset the player - this will remove its actor-ref and clear + # Reset the player; this will remove its actor-ref and clear # its calls/etc try: with _ba.Context(activity): @@ -373,6 +362,7 @@ class Session: except Exception: _error.print_exception( 'exception in on_team_leave for session', self) + # Clear the team's session-data (so dying stuff will # have proper context). try: @@ -450,20 +440,22 @@ class Session: """ from ba._general import Call from ba._enums import TimeType - # only pay attention if this is coming from our current activity.. + + # Only pay attention if this is coming from our current activity. if activity is not self._activity_retained: return - # if this activity hasn't begun yet, just set it up to end immediately - # once it does + # If this activity hasn't begun yet, just set it up to end immediately + # once it does. if not activity.has_begun(): activity.set_immediate_end(results, delay, force) - # the activity has already begun; get ready to end it.. + # The activity has already begun; get ready to end it. else: if (not activity.has_ended()) or force: activity.set_has_ended(True) - # set a timer to set in motion this activity's demise + + # Set a timer to set in motion this activity's demise. self._activity_end_timer = _ba.Timer( delay, Call(self._complete_end_activity, activity, results), @@ -479,8 +471,8 @@ class Session: return None if isinstance(msg, PlayerProfilesChangedMessage): - # if we have a current activity with a lobby, ask it to - # reload profiles + # If we have a current activity with a lobby, ask it to reload + # profiles. with _ba.Context(self): self.lobby.reload_profiles() return None @@ -507,7 +499,7 @@ class Session: "Session.set_activity() cannot be called recursively.") if activity.session is not _ba.getsession(): - raise Exception("provided activity's session is not current") + raise Exception("Provided Activity's Session is not current.") # Quietly ignore this if the whole session is going down. if self._ending: @@ -570,7 +562,7 @@ class Session: prev_activity._transitioning_out = True # pylint: enable=protected-access - # activity will be None until the next one begins. + # Activity will be None until the next one begins. with _ba.Context(prev_activity): prev_activity.on_transition_out() @@ -609,6 +601,7 @@ class Session: _ba.timer(activity.transition_time, prev_activity._destroy, timetype=TimeType.REAL) + # Just run immediately. else: # noinspection PyProtectedMember @@ -716,6 +709,7 @@ class Session: _ba.playsound(_ba.getsound('error')) else: return + # Otherwise just add players on the fly. else: self._add_chosen_player(chooser) diff --git a/assets/src/ba_data/python/ba/_teambasesession.py b/assets/src/ba_data/python/ba/_teambasesession.py index 2bd8bbe6..c01b995c 100644 --- a/assets/src/ba_data/python/ba/_teambasesession.py +++ b/assets/src/ba_data/python/ba/_teambasesession.py @@ -101,6 +101,7 @@ class TeamBaseSession(Session): if (self._playlist_name != '__default__' and self._playlist_name in playlists): + # Make sure to copy this, as we muck with it in place once we've # got it and we don't want that to affect our config. playlist = copy.deepcopy(playlists[self._playlist_name]) @@ -177,22 +178,21 @@ class TeamBaseSession(Session): TeamSeriesVictoryScoreScreenActivity) from ba import _activitytypes - # If we have a tutorial to show, - # that's the first thing we do no matter what. + # If we have a tutorial to show, that's the first thing we do no + # matter what. if self._tutorial_activity_instance is not None: self.set_activity(self._tutorial_activity_instance) self._tutorial_activity_instance = None - # If we're leaving the tutorial activity, - # pop a transition activity to transition - # us into a round gracefully (otherwise we'd - # snap from one terrain to another instantly). + # If we're leaving the tutorial activity, pop a transition activity + # to transition us into a round gracefully (otherwise we'd snap from + # one terrain to another instantly). elif isinstance(activity, TutorialActivity): self.set_activity( _ba.new_activity(_activitytypes.TransitionActivity)) - # If we're in a between-round activity or a restart-activity, - # hop into a round. + # If we're in a between-round activity or a restart-activity, hop + # into a round. elif isinstance( activity, (_activitytypes.JoiningActivity, _activitytypes.TransitionActivity, @@ -204,6 +204,7 @@ class TeamBaseSession(Session): self._game_number = 0 for team in self.teams: team.sessiondata['score'] = 0 + # Otherwise just set accum (per-game) scores. else: self.stats.reset_accum() @@ -217,7 +218,7 @@ class TeamBaseSession(Session): # Instantiate the next now so they have plenty of time to load. self._instantiate_next_game() - # (re)register all players and wire stats to our next activity + # (Re)register all players and wire stats to our next activity. for player in self.players: # ..but only ones who have been placed on a team # (ie: no longer sitting in the lobby). @@ -322,6 +323,7 @@ class ShuffleList: continue if test_obj['type'] == self.last_gotten['type']: continue + # Sufficiently different; lets go with it. break From d353e3f83452a0e67d195e05c8ee8d6e2f92b935 Mon Sep 17 00:00:00 2001 From: Eric Froemling Date: Sat, 11 Apr 2020 22:14:25 -0700 Subject: [PATCH 18/18] moving some type annotations back to class level to fix docs generation --- assets/src/ba_data/python/ba/_session.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/assets/src/ba_data/python/ba/_session.py b/assets/src/ba_data/python/ba/_session.py index 14bf3ef1..0b620ccf 100644 --- a/assets/src/ba_data/python/ba/_session.py +++ b/assets/src/ba_data/python/ba/_session.py @@ -75,6 +75,15 @@ class Session: """ + # Note: even though these are instance vars, we annotate them at the + # class level so that docs generation can access their types. + campaign: Optional[ba.Campaign] + lobby: ba.Lobby + max_players: int + min_players: int + players: List[ba.Player] + teams: List[ba.Team] + def __init__(self, depsets: Sequence[ba.DependencySet], team_names: Sequence[str] = None, @@ -146,7 +155,7 @@ class Session: # activity only. self.have_shown_controls_help_overlay = False - self.campaign: Optional[ba.Campaign] = None + self.campaign = None # FIXME: Should be able to kill this I think. self.campaign_state: Dict[str, str] = {} @@ -156,8 +165,8 @@ class Session: self._in_set_activity = False self._allow_mid_activity_joins = allow_mid_activity_joins - self.teams: List[ba.Team] = [] - self.players: List[ba.Player] = [] + self.teams = [] + self.players = [] self._next_team_id = 0 self._activity_retained: Optional[ba.Activity] = None self.launch_end_session_activity_time: Optional[float] = None @@ -198,7 +207,7 @@ class Session: _error.print_exception( f'Error in on_team_join for {self}.') - self.lobby: ba.Lobby = Lobby() + self.lobby = Lobby() self.stats = Stats() # Instantiate our session globals node