Source code for bascenev1lib.activity.multiteamscore

# Released under the MIT License. See LICENSE for details.
#
"""Functionality related to teams mode score screen."""
from __future__ import annotations

from typing import override

import bascenev1 as bs

from bascenev1lib.actor.text import Text
from bascenev1lib.actor.image import Image


[docs] class MultiTeamScoreScreenActivity(bs.ScoreScreenActivity): """Base class for score screens.""" def __init__(self, settings: dict): super().__init__(settings=settings) self._score_display_sound = bs.getsound('scoreHit01') self._score_display_sound_small = bs.getsound('scoreHit02') self._show_up_next: bool = True
[docs] @override def on_begin(self) -> None: super().on_begin() session = self.session if self._show_up_next and isinstance(session, bs.MultiTeamSession): txt = bs.Lstr( value='${A} ${B}', subs=[ ( '${A}', bs.Lstr( resource='upNextText', subs=[ ('${COUNT}', str(session.get_game_number() + 1)) ], ), ), ('${B}', session.get_next_game_description()), ], ) Text( txt, maxwidth=900, h_attach=Text.HAttach.CENTER, v_attach=Text.VAttach.BOTTOM, h_align=Text.HAlign.CENTER, v_align=Text.VAlign.CENTER, position=(0, 53), flash=False, color=(0.3, 0.3, 0.35, 1.0), transition=Text.Transition.FADE_IN, transition_delay=2.0, ).autoretain()
[docs] def show_player_scores( self, *, delay: float = 2.5, results: bs.GameResults | None = None, scale: float = 1.0, x_offset: float = 0.0, y_offset: float = 0.0, ) -> None: """Show scores for individual players.""" # pylint: disable=too-many-locals # pylint: disable=too-many-statements ts_v_offset = 150.0 + y_offset ts_h_offs = 80.0 + x_offset tdelay = delay spacing = 40 is_free_for_all = isinstance(self.session, bs.FreeForAllSession) def _get_prec_score(p_rec: bs.PlayerRecord) -> int | None: if is_free_for_all and results is not None: assert isinstance(results, bs.GameResults) assert p_rec.team.activityteam is not None val = results.get_sessionteam_score(p_rec.team) return val return p_rec.accumscore def _get_prec_score_str(p_rec: bs.PlayerRecord) -> str | bs.Lstr: if is_free_for_all and results is not None: assert isinstance(results, bs.GameResults) assert p_rec.team.activityteam is not None val = results.get_sessionteam_score_str(p_rec.team) assert val is not None return val return str(p_rec.accumscore) # stats.get_records() can return players that are no longer in # the game.. if we're using results we have to filter those out # (since they're not in results and that's where we pull their # scores from) if results is not None: assert isinstance(results, bs.GameResults) player_records = [] valid_players = list(self.stats.get_records().items()) # noinspection PyUnresolvedReferences def _get_player_score_set_entry( player: bs.SessionPlayer, ) -> bs.PlayerRecord | None: for p_rec in valid_players: if p_rec[1].player is player: return p_rec[1] return None # Results is already sorted; just convert it into a list of # score-set-entries. for winnergroup in results.winnergroups: for team in winnergroup.teams: if len(team.players) == 1: player_entry = _get_player_score_set_entry( team.players[0] ) if player_entry is not None: player_records.append(player_entry) else: player_records = [] player_records_scores = [ (_get_prec_score(p), name, p) for name, p in list(self.stats.get_records().items()) ] player_records_scores.sort(reverse=True) player_records = [p[2] for p in player_records_scores] voffs = -140.0 + spacing * len(player_records) * 0.5 def _txt( xoffs: float, yoffs: float, text: bs.Lstr, *, h_align: Text.HAlign = Text.HAlign.RIGHT, extrascale: float = 1.0, maxwidth: float | None = 120.0, ) -> None: Text( text, color=(0.5, 0.5, 0.6, 0.5), position=( ts_h_offs + xoffs * scale, ts_v_offset + (voffs + yoffs + 4.0) * scale, ), h_align=h_align, v_align=Text.VAlign.CENTER, scale=0.8 * scale * extrascale, maxwidth=maxwidth, transition=Text.Transition.IN_LEFT, transition_delay=tdelay, ).autoretain() session = self.session assert isinstance(session, bs.MultiTeamSession) tval = bs.Lstr( resource='gameLeadersText', subs=[('${COUNT}', str(session.get_game_number()))], ) _txt( 180, 43, tval, h_align=Text.HAlign.CENTER, extrascale=1.4, maxwidth=None, ) _txt(-15, 4, bs.Lstr(resource='playerText'), h_align=Text.HAlign.LEFT) _txt(180, 4, bs.Lstr(resource='killsText')) _txt(280, 4, bs.Lstr(resource='deathsText'), maxwidth=100) score_label = 'Score' if results is None else results.score_label translated = bs.Lstr(translate=('scoreNames', score_label)) _txt(390, 0, translated) topkillcount = 0 topkilledcount = 99999 top_score = ( 0 if not player_records else _get_prec_score(player_records[0]) ) for prec in player_records: topkillcount = max(topkillcount, prec.accum_kill_count) topkilledcount = min(topkilledcount, prec.accum_killed_count) def _scoretxt( text: str | bs.Lstr, x_offs: float, highlight: bool, delay2: float, maxwidth: float = 70.0, ) -> None: Text( text, position=( ts_h_offs + x_offs * scale, ts_v_offset + (voffs + 15) * scale, ), scale=scale, color=( (1.0, 0.9, 0.5, 1.0) if highlight else (0.5, 0.5, 0.6, 0.5) ), h_align=Text.HAlign.RIGHT, v_align=Text.VAlign.CENTER, maxwidth=maxwidth, transition=Text.Transition.IN_LEFT, transition_delay=tdelay + delay2, ).autoretain() for playerrec in player_records: tdelay += 0.05 voffs -= spacing Image( playerrec.get_icon(), position=( ts_h_offs - 12 * scale, ts_v_offset + (voffs + 15.0) * scale, ), scale=(30.0 * scale, 30.0 * scale), transition=Image.Transition.IN_LEFT, transition_delay=tdelay, ).autoretain() Text( bs.Lstr(value=playerrec.getname(full=True)), maxwidth=160, scale=0.75 * scale, position=( ts_h_offs + 10.0 * scale, ts_v_offset + (voffs + 15) * scale, ), h_align=Text.HAlign.LEFT, v_align=Text.VAlign.CENTER, color=bs.safecolor(playerrec.team.color + (1,)), transition=Text.Transition.IN_LEFT, transition_delay=tdelay, ).autoretain() _scoretxt( str(playerrec.accum_kill_count), 180, playerrec.accum_kill_count == topkillcount, 0.1, ) _scoretxt( str(playerrec.accum_killed_count), 280, playerrec.accum_killed_count == topkilledcount, 0.1, ) _scoretxt( _get_prec_score_str(playerrec), 390, _get_prec_score(playerrec) == top_score, 0.2, )