def __init__(self) -> None: from ba._team import SessionTeam from ba._coopsession import CoopSession session = _ba.getsession() self._use_team_colors = session.use_team_colors if session.use_teams: self._teams = [weakref.ref(team) for team in session.teams] else: self._dummy_teams = SessionTeam() self._teams = [weakref.ref(self._dummy_teams)] v_offset = (-150 if isinstance(session, CoopSession) else -50) self.choosers: List[Chooser] = [] self.base_v_offset = v_offset self.update_positions() self._next_add_team = 0 self.character_names_local_unlocked: List[str] = [] self._vpos = 0 # Grab available profiles. self.reload_profiles() self._join_info_text = None
def __init__(self, depsets: Sequence[ba.DependencySet], team_names: Sequence[str] = None, team_colors: Sequence[Sequence[float]] = None, min_players: int = 1, max_players: int = 8): """Instantiate a session. depsets should be a sequence of successfully resolved ba.DependencySet instances; one for each ba.Activity the session may potentially run. """ # pylint: disable=too-many-statements # pylint: disable=too-many-locals # pylint: disable=cyclic-import from ba._lobby import Lobby from ba._stats import Stats from ba._gameactivity import GameActivity from ba._activity import Activity from ba._team import SessionTeam from ba._error import DependencyError from ba._dependency import Dependency, AssetPackage from efro.util import empty_weakref # 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: # 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 RuntimeError( f'Missing non-asset dependencies: {missing_info}' ) from exc # Throw a combined exception if we found anything missing. if missing_asset_packages: raise DependencyError([ Dependency(AssetPackage, set_id) for set_id in missing_asset_packages ]) # Ok; looks like our dependencies check out. # Now give the engine a list of asset-set-ids to pass along to clients. required_asset_packages: Set[str] = set() for depset in depsets: required_asset_packages.update(depset.get_asset_package_ids()) # print('Would set host-session asset-reqs to:', # required_asset_packages) # Init our C++ layer data. self._sessiondata = _ba.register_session(self) # Should remove this if possible. self.tournament_id: Optional[str] = None self.sessionteams = [] self.sessionplayers = [] self.min_players = min_players self.max_players = max_players self.customdata = {} self._in_set_activity = False self._next_team_id = 0 self._activity_retained: Optional[ba.Activity] = None self._launch_end_session_activity_time: Optional[float] = None self._activity_end_timer: Optional[ba.Timer] = None self._activity_weak = empty_weakref(Activity) self._next_activity: Optional[ba.Activity] = None self._wants_to_end = False self._ending = False self._activity_should_end_immediately = False self._activity_should_end_immediately_results: ( Optional[ba.GameResults]) = None self._activity_should_end_immediately_delay = 0.0 # Create static teams if we're using them. if self.use_teams: assert team_names is not None assert team_colors is not None for i, color in enumerate(team_colors): team = SessionTeam(team_id=self._next_team_id, name=GameActivity.get_team_display_string( team_names[i]), color=color) self.sessionteams.append(team) self._next_team_id += 1 try: with _ba.Context(self): self.on_team_join(team) except Exception: print_exception(f'Error in on_team_join for {self}.') self.lobby = Lobby() self.stats = Stats() # Instantiate our session globals node which will apply its settings. self._sessionglobalsnode = _ba.newnode('sessionglobals')
def _add_chosen_player(self, chooser: ba.Chooser) -> ba.SessionPlayer: from ba._team import SessionTeam sessionplayer = chooser.getplayer() assert sessionplayer in self.sessionplayers, ( 'SessionPlayer not found in session ' 'player-list after chooser selection.') activity = self._activity_weak() assert activity is not None # Reset the player's input here, as it is probably # referencing the chooser which could inadvertently keep it alive. sessionplayer.resetinput() # We can pass it to the current activity if it has already begun # (otherwise it'll get passed once begin is called). pass_to_activity = (activity.has_begun() and not activity.is_joining_activity) # However, if we're not allowing mid-game joins, don't actually pass; # just announce the arrival and say they'll partake next round. if pass_to_activity: if not self.allow_mid_activity_joins: pass_to_activity = False with _ba.Context(self): _ba.screenmessage( Lstr(resource='playerDelayedJoinText', subs=[('${PLAYER}', sessionplayer.getname(full=True))]), color=(0, 1, 0), ) # If we're a non-team session, each player gets their own team. # (keeps mini-game coding simpler if we can always deal with teams). if self.use_teams: sessionteam = chooser.sessionteam else: our_team_id = self._next_team_id self._next_team_id += 1 sessionteam = SessionTeam( team_id=our_team_id, color=chooser.get_color(), name=chooser.getplayer().getname(full=True, icon=False), ) # Add player's team to the Session. self.sessionteams.append(sessionteam) with _ba.Context(self): try: self.on_team_join(sessionteam) except Exception: print_exception(f'Error in on_team_join for {self}.') # Add player's team to the Activity. if pass_to_activity: activity.add_team(sessionteam) assert sessionplayer not in sessionteam.players sessionteam.players.append(sessionplayer) sessionplayer.setdata(team=sessionteam, character=chooser.get_character_name(), color=chooser.get_color(), highlight=chooser.get_highlight()) self.stats.register_sessionplayer(sessionplayer) if pass_to_activity: activity.add_player(sessionplayer) return sessionplayer