bascenev1lib.activity.multiteamscore

Functionality related to teams mode score screen.

  1# Released under the MIT License. See LICENSE for details.
  2#
  3"""Functionality related to teams mode score screen."""
  4from __future__ import annotations
  5
  6from typing import override
  7
  8import bascenev1 as bs
  9
 10from bascenev1lib.actor.text import Text
 11from bascenev1lib.actor.image import Image
 12
 13
 14class MultiTeamScoreScreenActivity(bs.ScoreScreenActivity):
 15    """Base class for score screens."""
 16
 17    def __init__(self, settings: dict):
 18        super().__init__(settings=settings)
 19        self._score_display_sound = bs.getsound('scoreHit01')
 20        self._score_display_sound_small = bs.getsound('scoreHit02')
 21
 22        self._show_up_next: bool = True
 23
 24    @override
 25    def on_begin(self) -> None:
 26        super().on_begin()
 27        session = self.session
 28        if self._show_up_next and isinstance(session, bs.MultiTeamSession):
 29            txt = bs.Lstr(
 30                value='${A}   ${B}',
 31                subs=[
 32                    (
 33                        '${A}',
 34                        bs.Lstr(
 35                            resource='upNextText',
 36                            subs=[
 37                                ('${COUNT}', str(session.get_game_number() + 1))
 38                            ],
 39                        ),
 40                    ),
 41                    ('${B}', session.get_next_game_description()),
 42                ],
 43            )
 44            Text(
 45                txt,
 46                maxwidth=900,
 47                h_attach=Text.HAttach.CENTER,
 48                v_attach=Text.VAttach.BOTTOM,
 49                h_align=Text.HAlign.CENTER,
 50                v_align=Text.VAlign.CENTER,
 51                position=(0, 53),
 52                flash=False,
 53                color=(0.3, 0.3, 0.35, 1.0),
 54                transition=Text.Transition.FADE_IN,
 55                transition_delay=2.0,
 56            ).autoretain()
 57
 58    def show_player_scores(
 59        self,
 60        delay: float = 2.5,
 61        results: bs.GameResults | None = None,
 62        scale: float = 1.0,
 63        x_offset: float = 0.0,
 64        y_offset: float = 0.0,
 65    ) -> None:
 66        """Show scores for individual players."""
 67        # pylint: disable=too-many-locals
 68        # pylint: disable=too-many-statements
 69
 70        ts_v_offset = 150.0 + y_offset
 71        ts_h_offs = 80.0 + x_offset
 72        tdelay = delay
 73        spacing = 40
 74
 75        is_free_for_all = isinstance(self.session, bs.FreeForAllSession)
 76
 77        def _get_prec_score(p_rec: bs.PlayerRecord) -> int | None:
 78            if is_free_for_all and results is not None:
 79                assert isinstance(results, bs.GameResults)
 80                assert p_rec.team.activityteam is not None
 81                val = results.get_sessionteam_score(p_rec.team)
 82                return val
 83            return p_rec.accumscore
 84
 85        def _get_prec_score_str(p_rec: bs.PlayerRecord) -> str | bs.Lstr:
 86            if is_free_for_all and results is not None:
 87                assert isinstance(results, bs.GameResults)
 88                assert p_rec.team.activityteam is not None
 89                val = results.get_sessionteam_score_str(p_rec.team)
 90                assert val is not None
 91                return val
 92            return str(p_rec.accumscore)
 93
 94        # stats.get_records() can return players that are no longer in
 95        # the game.. if we're using results we have to filter those out
 96        # (since they're not in results and that's where we pull their
 97        # scores from)
 98        if results is not None:
 99            assert isinstance(results, bs.GameResults)
100            player_records = []
101            valid_players = list(self.stats.get_records().items())
102
103            # noinspection PyUnresolvedReferences
104            def _get_player_score_set_entry(
105                player: bs.SessionPlayer,
106            ) -> bs.PlayerRecord | None:
107                for p_rec in valid_players:
108                    if p_rec[1].player is player:
109                        return p_rec[1]
110                return None
111
112            # Results is already sorted; just convert it into a list of
113            # score-set-entries.
114            for winnergroup in results.winnergroups:
115                for team in winnergroup.teams:
116                    if len(team.players) == 1:
117                        player_entry = _get_player_score_set_entry(
118                            team.players[0]
119                        )
120                        if player_entry is not None:
121                            player_records.append(player_entry)
122        else:
123            player_records = []
124            player_records_scores = [
125                (_get_prec_score(p), name, p)
126                for name, p in list(self.stats.get_records().items())
127            ]
128            player_records_scores.sort(reverse=True)
129            player_records = [p[2] for p in player_records_scores]
130
131        voffs = -140.0 + spacing * len(player_records) * 0.5
132
133        def _txt(
134            xoffs: float,
135            yoffs: float,
136            text: bs.Lstr,
137            h_align: Text.HAlign = Text.HAlign.RIGHT,
138            extrascale: float = 1.0,
139            maxwidth: float | None = 120.0,
140        ) -> None:
141            Text(
142                text,
143                color=(0.5, 0.5, 0.6, 0.5),
144                position=(
145                    ts_h_offs + xoffs * scale,
146                    ts_v_offset + (voffs + yoffs + 4.0) * scale,
147                ),
148                h_align=h_align,
149                v_align=Text.VAlign.CENTER,
150                scale=0.8 * scale * extrascale,
151                maxwidth=maxwidth,
152                transition=Text.Transition.IN_LEFT,
153                transition_delay=tdelay,
154            ).autoretain()
155
156        session = self.session
157        assert isinstance(session, bs.MultiTeamSession)
158        tval = bs.Lstr(
159            resource='gameLeadersText',
160            subs=[('${COUNT}', str(session.get_game_number()))],
161        )
162        _txt(
163            180,
164            43,
165            tval,
166            h_align=Text.HAlign.CENTER,
167            extrascale=1.4,
168            maxwidth=None,
169        )
170        _txt(-15, 4, bs.Lstr(resource='playerText'), h_align=Text.HAlign.LEFT)
171        _txt(180, 4, bs.Lstr(resource='killsText'))
172        _txt(280, 4, bs.Lstr(resource='deathsText'), maxwidth=100)
173
174        score_label = 'Score' if results is None else results.score_label
175        translated = bs.Lstr(translate=('scoreNames', score_label))
176
177        _txt(390, 0, translated)
178
179        topkillcount = 0
180        topkilledcount = 99999
181        top_score = (
182            0 if not player_records else _get_prec_score(player_records[0])
183        )
184
185        for prec in player_records:
186            topkillcount = max(topkillcount, prec.accum_kill_count)
187            topkilledcount = min(topkilledcount, prec.accum_killed_count)
188
189        def _scoretxt(
190            text: str | bs.Lstr,
191            x_offs: float,
192            highlight: bool,
193            delay2: float,
194            maxwidth: float = 70.0,
195        ) -> None:
196            Text(
197                text,
198                position=(
199                    ts_h_offs + x_offs * scale,
200                    ts_v_offset + (voffs + 15) * scale,
201                ),
202                scale=scale,
203                color=(
204                    (1.0, 0.9, 0.5, 1.0) if highlight else (0.5, 0.5, 0.6, 0.5)
205                ),
206                h_align=Text.HAlign.RIGHT,
207                v_align=Text.VAlign.CENTER,
208                maxwidth=maxwidth,
209                transition=Text.Transition.IN_LEFT,
210                transition_delay=tdelay + delay2,
211            ).autoretain()
212
213        for playerrec in player_records:
214            tdelay += 0.05
215            voffs -= spacing
216            Image(
217                playerrec.get_icon(),
218                position=(
219                    ts_h_offs - 12 * scale,
220                    ts_v_offset + (voffs + 15.0) * scale,
221                ),
222                scale=(30.0 * scale, 30.0 * scale),
223                transition=Image.Transition.IN_LEFT,
224                transition_delay=tdelay,
225            ).autoretain()
226            Text(
227                bs.Lstr(value=playerrec.getname(full=True)),
228                maxwidth=160,
229                scale=0.75 * scale,
230                position=(
231                    ts_h_offs + 10.0 * scale,
232                    ts_v_offset + (voffs + 15) * scale,
233                ),
234                h_align=Text.HAlign.LEFT,
235                v_align=Text.VAlign.CENTER,
236                color=bs.safecolor(playerrec.team.color + (1,)),
237                transition=Text.Transition.IN_LEFT,
238                transition_delay=tdelay,
239            ).autoretain()
240            _scoretxt(
241                str(playerrec.accum_kill_count),
242                180,
243                playerrec.accum_kill_count == topkillcount,
244                0.1,
245            )
246            _scoretxt(
247                str(playerrec.accum_killed_count),
248                280,
249                playerrec.accum_killed_count == topkilledcount,
250                0.1,
251            )
252            _scoretxt(
253                _get_prec_score_str(playerrec),
254                390,
255                _get_prec_score(playerrec) == top_score,
256                0.2,
257            )
class MultiTeamScoreScreenActivity(bascenev1._activity.Activity[bascenev1._player.EmptyPlayer, bascenev1._team.EmptyTeam]):
 15class MultiTeamScoreScreenActivity(bs.ScoreScreenActivity):
 16    """Base class for score screens."""
 17
 18    def __init__(self, settings: dict):
 19        super().__init__(settings=settings)
 20        self._score_display_sound = bs.getsound('scoreHit01')
 21        self._score_display_sound_small = bs.getsound('scoreHit02')
 22
 23        self._show_up_next: bool = True
 24
 25    @override
 26    def on_begin(self) -> None:
 27        super().on_begin()
 28        session = self.session
 29        if self._show_up_next and isinstance(session, bs.MultiTeamSession):
 30            txt = bs.Lstr(
 31                value='${A}   ${B}',
 32                subs=[
 33                    (
 34                        '${A}',
 35                        bs.Lstr(
 36                            resource='upNextText',
 37                            subs=[
 38                                ('${COUNT}', str(session.get_game_number() + 1))
 39                            ],
 40                        ),
 41                    ),
 42                    ('${B}', session.get_next_game_description()),
 43                ],
 44            )
 45            Text(
 46                txt,
 47                maxwidth=900,
 48                h_attach=Text.HAttach.CENTER,
 49                v_attach=Text.VAttach.BOTTOM,
 50                h_align=Text.HAlign.CENTER,
 51                v_align=Text.VAlign.CENTER,
 52                position=(0, 53),
 53                flash=False,
 54                color=(0.3, 0.3, 0.35, 1.0),
 55                transition=Text.Transition.FADE_IN,
 56                transition_delay=2.0,
 57            ).autoretain()
 58
 59    def show_player_scores(
 60        self,
 61        delay: float = 2.5,
 62        results: bs.GameResults | None = None,
 63        scale: float = 1.0,
 64        x_offset: float = 0.0,
 65        y_offset: float = 0.0,
 66    ) -> None:
 67        """Show scores for individual players."""
 68        # pylint: disable=too-many-locals
 69        # pylint: disable=too-many-statements
 70
 71        ts_v_offset = 150.0 + y_offset
 72        ts_h_offs = 80.0 + x_offset
 73        tdelay = delay
 74        spacing = 40
 75
 76        is_free_for_all = isinstance(self.session, bs.FreeForAllSession)
 77
 78        def _get_prec_score(p_rec: bs.PlayerRecord) -> int | None:
 79            if is_free_for_all and results is not None:
 80                assert isinstance(results, bs.GameResults)
 81                assert p_rec.team.activityteam is not None
 82                val = results.get_sessionteam_score(p_rec.team)
 83                return val
 84            return p_rec.accumscore
 85
 86        def _get_prec_score_str(p_rec: bs.PlayerRecord) -> str | bs.Lstr:
 87            if is_free_for_all and results is not None:
 88                assert isinstance(results, bs.GameResults)
 89                assert p_rec.team.activityteam is not None
 90                val = results.get_sessionteam_score_str(p_rec.team)
 91                assert val is not None
 92                return val
 93            return str(p_rec.accumscore)
 94
 95        # stats.get_records() can return players that are no longer in
 96        # the game.. if we're using results we have to filter those out
 97        # (since they're not in results and that's where we pull their
 98        # scores from)
 99        if results is not None:
100            assert isinstance(results, bs.GameResults)
101            player_records = []
102            valid_players = list(self.stats.get_records().items())
103
104            # noinspection PyUnresolvedReferences
105            def _get_player_score_set_entry(
106                player: bs.SessionPlayer,
107            ) -> bs.PlayerRecord | None:
108                for p_rec in valid_players:
109                    if p_rec[1].player is player:
110                        return p_rec[1]
111                return None
112
113            # Results is already sorted; just convert it into a list of
114            # score-set-entries.
115            for winnergroup in results.winnergroups:
116                for team in winnergroup.teams:
117                    if len(team.players) == 1:
118                        player_entry = _get_player_score_set_entry(
119                            team.players[0]
120                        )
121                        if player_entry is not None:
122                            player_records.append(player_entry)
123        else:
124            player_records = []
125            player_records_scores = [
126                (_get_prec_score(p), name, p)
127                for name, p in list(self.stats.get_records().items())
128            ]
129            player_records_scores.sort(reverse=True)
130            player_records = [p[2] for p in player_records_scores]
131
132        voffs = -140.0 + spacing * len(player_records) * 0.5
133
134        def _txt(
135            xoffs: float,
136            yoffs: float,
137            text: bs.Lstr,
138            h_align: Text.HAlign = Text.HAlign.RIGHT,
139            extrascale: float = 1.0,
140            maxwidth: float | None = 120.0,
141        ) -> None:
142            Text(
143                text,
144                color=(0.5, 0.5, 0.6, 0.5),
145                position=(
146                    ts_h_offs + xoffs * scale,
147                    ts_v_offset + (voffs + yoffs + 4.0) * scale,
148                ),
149                h_align=h_align,
150                v_align=Text.VAlign.CENTER,
151                scale=0.8 * scale * extrascale,
152                maxwidth=maxwidth,
153                transition=Text.Transition.IN_LEFT,
154                transition_delay=tdelay,
155            ).autoretain()
156
157        session = self.session
158        assert isinstance(session, bs.MultiTeamSession)
159        tval = bs.Lstr(
160            resource='gameLeadersText',
161            subs=[('${COUNT}', str(session.get_game_number()))],
162        )
163        _txt(
164            180,
165            43,
166            tval,
167            h_align=Text.HAlign.CENTER,
168            extrascale=1.4,
169            maxwidth=None,
170        )
171        _txt(-15, 4, bs.Lstr(resource='playerText'), h_align=Text.HAlign.LEFT)
172        _txt(180, 4, bs.Lstr(resource='killsText'))
173        _txt(280, 4, bs.Lstr(resource='deathsText'), maxwidth=100)
174
175        score_label = 'Score' if results is None else results.score_label
176        translated = bs.Lstr(translate=('scoreNames', score_label))
177
178        _txt(390, 0, translated)
179
180        topkillcount = 0
181        topkilledcount = 99999
182        top_score = (
183            0 if not player_records else _get_prec_score(player_records[0])
184        )
185
186        for prec in player_records:
187            topkillcount = max(topkillcount, prec.accum_kill_count)
188            topkilledcount = min(topkilledcount, prec.accum_killed_count)
189
190        def _scoretxt(
191            text: str | bs.Lstr,
192            x_offs: float,
193            highlight: bool,
194            delay2: float,
195            maxwidth: float = 70.0,
196        ) -> None:
197            Text(
198                text,
199                position=(
200                    ts_h_offs + x_offs * scale,
201                    ts_v_offset + (voffs + 15) * scale,
202                ),
203                scale=scale,
204                color=(
205                    (1.0, 0.9, 0.5, 1.0) if highlight else (0.5, 0.5, 0.6, 0.5)
206                ),
207                h_align=Text.HAlign.RIGHT,
208                v_align=Text.VAlign.CENTER,
209                maxwidth=maxwidth,
210                transition=Text.Transition.IN_LEFT,
211                transition_delay=tdelay + delay2,
212            ).autoretain()
213
214        for playerrec in player_records:
215            tdelay += 0.05
216            voffs -= spacing
217            Image(
218                playerrec.get_icon(),
219                position=(
220                    ts_h_offs - 12 * scale,
221                    ts_v_offset + (voffs + 15.0) * scale,
222                ),
223                scale=(30.0 * scale, 30.0 * scale),
224                transition=Image.Transition.IN_LEFT,
225                transition_delay=tdelay,
226            ).autoretain()
227            Text(
228                bs.Lstr(value=playerrec.getname(full=True)),
229                maxwidth=160,
230                scale=0.75 * scale,
231                position=(
232                    ts_h_offs + 10.0 * scale,
233                    ts_v_offset + (voffs + 15) * scale,
234                ),
235                h_align=Text.HAlign.LEFT,
236                v_align=Text.VAlign.CENTER,
237                color=bs.safecolor(playerrec.team.color + (1,)),
238                transition=Text.Transition.IN_LEFT,
239                transition_delay=tdelay,
240            ).autoretain()
241            _scoretxt(
242                str(playerrec.accum_kill_count),
243                180,
244                playerrec.accum_kill_count == topkillcount,
245                0.1,
246            )
247            _scoretxt(
248                str(playerrec.accum_killed_count),
249                280,
250                playerrec.accum_killed_count == topkilledcount,
251                0.1,
252            )
253            _scoretxt(
254                _get_prec_score_str(playerrec),
255                390,
256                _get_prec_score(playerrec) == top_score,
257                0.2,
258            )

Base class for score screens.

MultiTeamScoreScreenActivity(settings: dict)
18    def __init__(self, settings: dict):
19        super().__init__(settings=settings)
20        self._score_display_sound = bs.getsound('scoreHit01')
21        self._score_display_sound_small = bs.getsound('scoreHit02')
22
23        self._show_up_next: bool = True

Creates an Activity in the current bascenev1.Session.

The activity will not be actually run until bascenev1.Session.setactivity is called. 'settings' should be a dict of key/value pairs specific to the activity.

Activities should preload as much of their media/etc as possible in their constructor, but none of it should actually be used until they are transitioned in.

@override
def on_begin(self) -> None:
25    @override
26    def on_begin(self) -> None:
27        super().on_begin()
28        session = self.session
29        if self._show_up_next and isinstance(session, bs.MultiTeamSession):
30            txt = bs.Lstr(
31                value='${A}   ${B}',
32                subs=[
33                    (
34                        '${A}',
35                        bs.Lstr(
36                            resource='upNextText',
37                            subs=[
38                                ('${COUNT}', str(session.get_game_number() + 1))
39                            ],
40                        ),
41                    ),
42                    ('${B}', session.get_next_game_description()),
43                ],
44            )
45            Text(
46                txt,
47                maxwidth=900,
48                h_attach=Text.HAttach.CENTER,
49                v_attach=Text.VAttach.BOTTOM,
50                h_align=Text.HAlign.CENTER,
51                v_align=Text.VAlign.CENTER,
52                position=(0, 53),
53                flash=False,
54                color=(0.3, 0.3, 0.35, 1.0),
55                transition=Text.Transition.FADE_IN,
56                transition_delay=2.0,
57            ).autoretain()

Called once the previous Activity has finished transitioning out.

At this point the activity's initial players and teams are filled in and it should begin its actual game logic.

def show_player_scores( self, delay: float = 2.5, results: bascenev1._gameresults.GameResults | None = None, scale: float = 1.0, x_offset: float = 0.0, y_offset: float = 0.0) -> None:
 59    def show_player_scores(
 60        self,
 61        delay: float = 2.5,
 62        results: bs.GameResults | None = None,
 63        scale: float = 1.0,
 64        x_offset: float = 0.0,
 65        y_offset: float = 0.0,
 66    ) -> None:
 67        """Show scores for individual players."""
 68        # pylint: disable=too-many-locals
 69        # pylint: disable=too-many-statements
 70
 71        ts_v_offset = 150.0 + y_offset
 72        ts_h_offs = 80.0 + x_offset
 73        tdelay = delay
 74        spacing = 40
 75
 76        is_free_for_all = isinstance(self.session, bs.FreeForAllSession)
 77
 78        def _get_prec_score(p_rec: bs.PlayerRecord) -> int | None:
 79            if is_free_for_all and results is not None:
 80                assert isinstance(results, bs.GameResults)
 81                assert p_rec.team.activityteam is not None
 82                val = results.get_sessionteam_score(p_rec.team)
 83                return val
 84            return p_rec.accumscore
 85
 86        def _get_prec_score_str(p_rec: bs.PlayerRecord) -> str | bs.Lstr:
 87            if is_free_for_all and results is not None:
 88                assert isinstance(results, bs.GameResults)
 89                assert p_rec.team.activityteam is not None
 90                val = results.get_sessionteam_score_str(p_rec.team)
 91                assert val is not None
 92                return val
 93            return str(p_rec.accumscore)
 94
 95        # stats.get_records() can return players that are no longer in
 96        # the game.. if we're using results we have to filter those out
 97        # (since they're not in results and that's where we pull their
 98        # scores from)
 99        if results is not None:
100            assert isinstance(results, bs.GameResults)
101            player_records = []
102            valid_players = list(self.stats.get_records().items())
103
104            # noinspection PyUnresolvedReferences
105            def _get_player_score_set_entry(
106                player: bs.SessionPlayer,
107            ) -> bs.PlayerRecord | None:
108                for p_rec in valid_players:
109                    if p_rec[1].player is player:
110                        return p_rec[1]
111                return None
112
113            # Results is already sorted; just convert it into a list of
114            # score-set-entries.
115            for winnergroup in results.winnergroups:
116                for team in winnergroup.teams:
117                    if len(team.players) == 1:
118                        player_entry = _get_player_score_set_entry(
119                            team.players[0]
120                        )
121                        if player_entry is not None:
122                            player_records.append(player_entry)
123        else:
124            player_records = []
125            player_records_scores = [
126                (_get_prec_score(p), name, p)
127                for name, p in list(self.stats.get_records().items())
128            ]
129            player_records_scores.sort(reverse=True)
130            player_records = [p[2] for p in player_records_scores]
131
132        voffs = -140.0 + spacing * len(player_records) * 0.5
133
134        def _txt(
135            xoffs: float,
136            yoffs: float,
137            text: bs.Lstr,
138            h_align: Text.HAlign = Text.HAlign.RIGHT,
139            extrascale: float = 1.0,
140            maxwidth: float | None = 120.0,
141        ) -> None:
142            Text(
143                text,
144                color=(0.5, 0.5, 0.6, 0.5),
145                position=(
146                    ts_h_offs + xoffs * scale,
147                    ts_v_offset + (voffs + yoffs + 4.0) * scale,
148                ),
149                h_align=h_align,
150                v_align=Text.VAlign.CENTER,
151                scale=0.8 * scale * extrascale,
152                maxwidth=maxwidth,
153                transition=Text.Transition.IN_LEFT,
154                transition_delay=tdelay,
155            ).autoretain()
156
157        session = self.session
158        assert isinstance(session, bs.MultiTeamSession)
159        tval = bs.Lstr(
160            resource='gameLeadersText',
161            subs=[('${COUNT}', str(session.get_game_number()))],
162        )
163        _txt(
164            180,
165            43,
166            tval,
167            h_align=Text.HAlign.CENTER,
168            extrascale=1.4,
169            maxwidth=None,
170        )
171        _txt(-15, 4, bs.Lstr(resource='playerText'), h_align=Text.HAlign.LEFT)
172        _txt(180, 4, bs.Lstr(resource='killsText'))
173        _txt(280, 4, bs.Lstr(resource='deathsText'), maxwidth=100)
174
175        score_label = 'Score' if results is None else results.score_label
176        translated = bs.Lstr(translate=('scoreNames', score_label))
177
178        _txt(390, 0, translated)
179
180        topkillcount = 0
181        topkilledcount = 99999
182        top_score = (
183            0 if not player_records else _get_prec_score(player_records[0])
184        )
185
186        for prec in player_records:
187            topkillcount = max(topkillcount, prec.accum_kill_count)
188            topkilledcount = min(topkilledcount, prec.accum_killed_count)
189
190        def _scoretxt(
191            text: str | bs.Lstr,
192            x_offs: float,
193            highlight: bool,
194            delay2: float,
195            maxwidth: float = 70.0,
196        ) -> None:
197            Text(
198                text,
199                position=(
200                    ts_h_offs + x_offs * scale,
201                    ts_v_offset + (voffs + 15) * scale,
202                ),
203                scale=scale,
204                color=(
205                    (1.0, 0.9, 0.5, 1.0) if highlight else (0.5, 0.5, 0.6, 0.5)
206                ),
207                h_align=Text.HAlign.RIGHT,
208                v_align=Text.VAlign.CENTER,
209                maxwidth=maxwidth,
210                transition=Text.Transition.IN_LEFT,
211                transition_delay=tdelay + delay2,
212            ).autoretain()
213
214        for playerrec in player_records:
215            tdelay += 0.05
216            voffs -= spacing
217            Image(
218                playerrec.get_icon(),
219                position=(
220                    ts_h_offs - 12 * scale,
221                    ts_v_offset + (voffs + 15.0) * scale,
222                ),
223                scale=(30.0 * scale, 30.0 * scale),
224                transition=Image.Transition.IN_LEFT,
225                transition_delay=tdelay,
226            ).autoretain()
227            Text(
228                bs.Lstr(value=playerrec.getname(full=True)),
229                maxwidth=160,
230                scale=0.75 * scale,
231                position=(
232                    ts_h_offs + 10.0 * scale,
233                    ts_v_offset + (voffs + 15) * scale,
234                ),
235                h_align=Text.HAlign.LEFT,
236                v_align=Text.VAlign.CENTER,
237                color=bs.safecolor(playerrec.team.color + (1,)),
238                transition=Text.Transition.IN_LEFT,
239                transition_delay=tdelay,
240            ).autoretain()
241            _scoretxt(
242                str(playerrec.accum_kill_count),
243                180,
244                playerrec.accum_kill_count == topkillcount,
245                0.1,
246            )
247            _scoretxt(
248                str(playerrec.accum_killed_count),
249                280,
250                playerrec.accum_killed_count == topkilledcount,
251                0.1,
252            )
253            _scoretxt(
254                _get_prec_score_str(playerrec),
255                390,
256                _get_prec_score(playerrec) == top_score,
257                0.2,
258            )

Show scores for individual players.

Inherited Members
bascenev1._activitytypes.ScoreScreenActivity
transition_time
inherits_tint
inherits_vr_camera_offset
use_fixed_vr_overlay
default_music
on_player_join
on_transition_in
bascenev1._activity.Activity
settings_raw
teams
players
announce_player_deaths
is_joining_activity
allow_pausing
allow_kick_idle_players
slow_motion
inherits_slow_motion
inherits_music
inherits_vr_overlay_center
allow_mid_activity_joins
can_show_ad_on_death
paused_text
preloads
lobby
context
globalsnode
stats
on_expire
customdata
expired
playertype
teamtype
retain_actor
add_actor_weak_ref
session
on_player_leave
on_team_join
on_team_leave
on_transition_out
handlemessage
has_transitioned_in
has_begun
has_ended
is_transitioning_out
transition_out
end
create_player
create_team
bascenev1._dependency.DependencyComponent
dep_is_present
get_dynamic_deps