bastd.activity.freeforallvictory

Functionality related to the final screen in free-for-all games.

  1# Released under the MIT License. See LICENSE for details.
  2#
  3"""Functionality related to the final screen in free-for-all games."""
  4
  5from __future__ import annotations
  6
  7from typing import TYPE_CHECKING
  8
  9import ba
 10from bastd.activity.multiteamscore import MultiTeamScoreScreenActivity
 11
 12if TYPE_CHECKING:
 13    from typing import Any
 14
 15
 16class FreeForAllVictoryScoreScreenActivity(MultiTeamScoreScreenActivity):
 17    """Score screen shown at after free-for-all rounds."""
 18
 19    def __init__(self, settings: dict):
 20        super().__init__(settings=settings)
 21
 22        # Keep prev activity alive while we fade in.
 23        self.transition_time = 0.5
 24        self._cymbal_sound = ba.getsound('cymbal')
 25
 26    def on_begin(self) -> None:
 27        # pylint: disable=too-many-locals
 28        # pylint: disable=too-many-statements
 29        from bastd.actor.text import Text
 30        from bastd.actor.image import Image
 31        ba.set_analytics_screen('FreeForAll Score Screen')
 32        super().on_begin()
 33
 34        y_base = 100.0
 35        ts_h_offs = -305.0
 36        tdelay = 1.0
 37        scale = 1.2
 38        spacing = 37.0
 39
 40        # We include name and previous score in the sort to reduce the amount
 41        # of random jumping around the list we do in cases of ties.
 42        player_order_prev = list(self.players)
 43        player_order_prev.sort(
 44            reverse=True,
 45            key=lambda p: (
 46                p.team.sessionteam.customdata['previous_score'],
 47                p.getname(full=True),
 48            ))
 49        player_order = list(self.players)
 50        player_order.sort(reverse=True,
 51                          key=lambda p: (
 52                              p.team.sessionteam.customdata['score'],
 53                              p.team.sessionteam.customdata['score'],
 54                              p.getname(full=True),
 55                          ))
 56
 57        v_offs = -74.0 + spacing * len(player_order_prev) * 0.5
 58        delay1 = 1.3 + 0.1
 59        delay2 = 2.9 + 0.1
 60        delay3 = 2.9 + 0.1
 61        order_change = player_order != player_order_prev
 62
 63        if order_change:
 64            delay3 += 1.5
 65
 66        ba.timer(0.3, ba.Call(ba.playsound, self._score_display_sound))
 67        results = self.settings_raw['results']
 68        assert isinstance(results, ba.GameResults)
 69        self.show_player_scores(delay=0.001,
 70                                results=results,
 71                                scale=1.2,
 72                                x_offset=-110.0)
 73
 74        sound_times: set[float] = set()
 75
 76        def _scoretxt(text: str,
 77                      x_offs: float,
 78                      y_offs: float,
 79                      highlight: bool,
 80                      delay: float,
 81                      extrascale: float,
 82                      flash: bool = False) -> Text:
 83            return Text(text,
 84                        position=(ts_h_offs + x_offs * scale,
 85                                  y_base + (y_offs + v_offs + 2.0) * scale),
 86                        scale=scale * extrascale,
 87                        color=((1.0, 0.7, 0.3, 1.0) if highlight else
 88                               (0.7, 0.7, 0.7, 0.7)),
 89                        h_align=Text.HAlign.RIGHT,
 90                        transition=Text.Transition.IN_LEFT,
 91                        transition_delay=tdelay + delay,
 92                        flash=flash).autoretain()
 93
 94        v_offs -= spacing
 95        slide_amt = 0.0
 96        transtime = 0.250
 97        transtime2 = 0.250
 98
 99        session = self.session
100        assert isinstance(session, ba.FreeForAllSession)
101        title = Text(ba.Lstr(resource='firstToSeriesText',
102                             subs=[('${COUNT}',
103                                    str(session.get_ffa_series_length()))]),
104                     scale=1.05 * scale,
105                     position=(ts_h_offs - 0.0 * scale,
106                               y_base + (v_offs + 50.0) * scale),
107                     h_align=Text.HAlign.CENTER,
108                     color=(0.5, 0.5, 0.5, 0.5),
109                     transition=Text.Transition.IN_LEFT,
110                     transition_delay=tdelay).autoretain()
111
112        v_offs -= 25
113        v_offs_start = v_offs
114
115        ba.timer(
116            tdelay + delay3,
117            ba.WeakCall(
118                self._safe_animate, title.position_combine, 'input0', {
119                    0.0: ts_h_offs - 0.0 * scale,
120                    transtime2: ts_h_offs - (0.0 + slide_amt) * scale
121                }))
122
123        for i, player in enumerate(player_order_prev):
124            v_offs_2 = v_offs_start - spacing * (player_order.index(player))
125            ba.timer(tdelay + 0.3,
126                     ba.Call(ba.playsound, self._score_display_sound_small))
127            if order_change:
128                ba.timer(tdelay + delay2 + 0.1,
129                         ba.Call(ba.playsound, self._cymbal_sound))
130            img = Image(player.get_icon(),
131                        position=(ts_h_offs - 72.0 * scale,
132                                  y_base + (v_offs + 15.0) * scale),
133                        scale=(30.0 * scale, 30.0 * scale),
134                        transition=Image.Transition.IN_LEFT,
135                        transition_delay=tdelay).autoretain()
136            ba.timer(
137                tdelay + delay2,
138                ba.WeakCall(
139                    self._safe_animate, img.position_combine, 'input1', {
140                        0: y_base + (v_offs + 15.0) * scale,
141                        transtime: y_base + (v_offs_2 + 15.0) * scale
142                    }))
143            ba.timer(
144                tdelay + delay3,
145                ba.WeakCall(
146                    self._safe_animate, img.position_combine, 'input0', {
147                        0: ts_h_offs - 72.0 * scale,
148                        transtime2: ts_h_offs - (72.0 + slide_amt) * scale
149                    }))
150            txt = Text(ba.Lstr(value=player.getname(full=True)),
151                       maxwidth=130.0,
152                       scale=0.75 * scale,
153                       position=(ts_h_offs - 50.0 * scale,
154                                 y_base + (v_offs + 15.0) * scale),
155                       h_align=Text.HAlign.LEFT,
156                       v_align=Text.VAlign.CENTER,
157                       color=ba.safecolor(player.team.color + (1, )),
158                       transition=Text.Transition.IN_LEFT,
159                       transition_delay=tdelay).autoretain()
160            ba.timer(
161                tdelay + delay2,
162                ba.WeakCall(
163                    self._safe_animate, txt.position_combine, 'input1', {
164                        0: y_base + (v_offs + 15.0) * scale,
165                        transtime: y_base + (v_offs_2 + 15.0) * scale
166                    }))
167            ba.timer(
168                tdelay + delay3,
169                ba.WeakCall(
170                    self._safe_animate, txt.position_combine, 'input0', {
171                        0: ts_h_offs - 50.0 * scale,
172                        transtime2: ts_h_offs - (50.0 + slide_amt) * scale
173                    }))
174
175            txt_num = Text('#' + str(i + 1),
176                           scale=0.55 * scale,
177                           position=(ts_h_offs - 95.0 * scale,
178                                     y_base + (v_offs + 8.0) * scale),
179                           h_align=Text.HAlign.RIGHT,
180                           color=(0.6, 0.6, 0.6, 0.6),
181                           transition=Text.Transition.IN_LEFT,
182                           transition_delay=tdelay).autoretain()
183            ba.timer(
184                tdelay + delay3,
185                ba.WeakCall(
186                    self._safe_animate, txt_num.position_combine, 'input0', {
187                        0: ts_h_offs - 95.0 * scale,
188                        transtime2: ts_h_offs - (95.0 + slide_amt) * scale
189                    }))
190
191            s_txt = _scoretxt(
192                str(player.team.sessionteam.customdata['previous_score']), 80,
193                0, False, 0, 1.0)
194            ba.timer(
195                tdelay + delay2,
196                ba.WeakCall(
197                    self._safe_animate, s_txt.position_combine, 'input1', {
198                        0: y_base + (v_offs + 2.0) * scale,
199                        transtime: y_base + (v_offs_2 + 2.0) * scale
200                    }))
201            ba.timer(
202                tdelay + delay3,
203                ba.WeakCall(
204                    self._safe_animate, s_txt.position_combine, 'input0', {
205                        0: ts_h_offs + 80.0 * scale,
206                        transtime2: ts_h_offs + (80.0 - slide_amt) * scale
207                    }))
208
209            score_change = (
210                player.team.sessionteam.customdata['score'] -
211                player.team.sessionteam.customdata['previous_score'])
212            if score_change > 0:
213                xval = 113
214                yval = 3.0
215                s_txt_2 = _scoretxt('+' + str(score_change),
216                                    xval,
217                                    yval,
218                                    True,
219                                    0,
220                                    0.7,
221                                    flash=True)
222                ba.timer(
223                    tdelay + delay2,
224                    ba.WeakCall(
225                        self._safe_animate, s_txt_2.position_combine, 'input1',
226                        {
227                            0: y_base + (v_offs + yval + 2.0) * scale,
228                            transtime: y_base + (v_offs_2 + yval + 2.0) * scale
229                        }))
230                ba.timer(
231                    tdelay + delay3,
232                    ba.WeakCall(
233                        self._safe_animate, s_txt_2.position_combine, 'input0',
234                        {
235                            0: ts_h_offs + xval * scale,
236                            transtime2: ts_h_offs + (xval - slide_amt) * scale
237                        }))
238
239                def _safesetattr(node: ba.Node | None, attr: str,
240                                 value: Any) -> None:
241                    if node:
242                        setattr(node, attr, value)
243
244                ba.timer(
245                    tdelay + delay1,
246                    ba.Call(_safesetattr, s_txt.node, 'color', (1, 1, 1, 1)))
247                for j in range(score_change):
248                    ba.timer((tdelay + delay1 + 0.15 * j),
249                             ba.Call(
250                                 _safesetattr, s_txt.node, 'text',
251                                 str(player.team.sessionteam.
252                                     customdata['previous_score'] + j + 1)))
253                    tfin = tdelay + delay1 + 0.15 * j
254                    if tfin not in sound_times:
255                        sound_times.add(tfin)
256                        ba.timer(
257                            tfin,
258                            ba.Call(ba.playsound,
259                                    self._score_display_sound_small))
260            v_offs -= spacing
261
262    def _safe_animate(self, node: ba.Node | None, attr: str,
263                      keys: dict[float, float]) -> None:
264        """Run an animation on a node if the node still exists."""
265        if node:
266            ba.animate(node, attr, keys)
class FreeForAllVictoryScoreScreenActivity(ba._activity.Activity[ba._player.EmptyPlayer, ba._team.EmptyTeam]):
 17class FreeForAllVictoryScoreScreenActivity(MultiTeamScoreScreenActivity):
 18    """Score screen shown at after free-for-all rounds."""
 19
 20    def __init__(self, settings: dict):
 21        super().__init__(settings=settings)
 22
 23        # Keep prev activity alive while we fade in.
 24        self.transition_time = 0.5
 25        self._cymbal_sound = ba.getsound('cymbal')
 26
 27    def on_begin(self) -> None:
 28        # pylint: disable=too-many-locals
 29        # pylint: disable=too-many-statements
 30        from bastd.actor.text import Text
 31        from bastd.actor.image import Image
 32        ba.set_analytics_screen('FreeForAll Score Screen')
 33        super().on_begin()
 34
 35        y_base = 100.0
 36        ts_h_offs = -305.0
 37        tdelay = 1.0
 38        scale = 1.2
 39        spacing = 37.0
 40
 41        # We include name and previous score in the sort to reduce the amount
 42        # of random jumping around the list we do in cases of ties.
 43        player_order_prev = list(self.players)
 44        player_order_prev.sort(
 45            reverse=True,
 46            key=lambda p: (
 47                p.team.sessionteam.customdata['previous_score'],
 48                p.getname(full=True),
 49            ))
 50        player_order = list(self.players)
 51        player_order.sort(reverse=True,
 52                          key=lambda p: (
 53                              p.team.sessionteam.customdata['score'],
 54                              p.team.sessionteam.customdata['score'],
 55                              p.getname(full=True),
 56                          ))
 57
 58        v_offs = -74.0 + spacing * len(player_order_prev) * 0.5
 59        delay1 = 1.3 + 0.1
 60        delay2 = 2.9 + 0.1
 61        delay3 = 2.9 + 0.1
 62        order_change = player_order != player_order_prev
 63
 64        if order_change:
 65            delay3 += 1.5
 66
 67        ba.timer(0.3, ba.Call(ba.playsound, self._score_display_sound))
 68        results = self.settings_raw['results']
 69        assert isinstance(results, ba.GameResults)
 70        self.show_player_scores(delay=0.001,
 71                                results=results,
 72                                scale=1.2,
 73                                x_offset=-110.0)
 74
 75        sound_times: set[float] = set()
 76
 77        def _scoretxt(text: str,
 78                      x_offs: float,
 79                      y_offs: float,
 80                      highlight: bool,
 81                      delay: float,
 82                      extrascale: float,
 83                      flash: bool = False) -> Text:
 84            return Text(text,
 85                        position=(ts_h_offs + x_offs * scale,
 86                                  y_base + (y_offs + v_offs + 2.0) * scale),
 87                        scale=scale * extrascale,
 88                        color=((1.0, 0.7, 0.3, 1.0) if highlight else
 89                               (0.7, 0.7, 0.7, 0.7)),
 90                        h_align=Text.HAlign.RIGHT,
 91                        transition=Text.Transition.IN_LEFT,
 92                        transition_delay=tdelay + delay,
 93                        flash=flash).autoretain()
 94
 95        v_offs -= spacing
 96        slide_amt = 0.0
 97        transtime = 0.250
 98        transtime2 = 0.250
 99
100        session = self.session
101        assert isinstance(session, ba.FreeForAllSession)
102        title = Text(ba.Lstr(resource='firstToSeriesText',
103                             subs=[('${COUNT}',
104                                    str(session.get_ffa_series_length()))]),
105                     scale=1.05 * scale,
106                     position=(ts_h_offs - 0.0 * scale,
107                               y_base + (v_offs + 50.0) * scale),
108                     h_align=Text.HAlign.CENTER,
109                     color=(0.5, 0.5, 0.5, 0.5),
110                     transition=Text.Transition.IN_LEFT,
111                     transition_delay=tdelay).autoretain()
112
113        v_offs -= 25
114        v_offs_start = v_offs
115
116        ba.timer(
117            tdelay + delay3,
118            ba.WeakCall(
119                self._safe_animate, title.position_combine, 'input0', {
120                    0.0: ts_h_offs - 0.0 * scale,
121                    transtime2: ts_h_offs - (0.0 + slide_amt) * scale
122                }))
123
124        for i, player in enumerate(player_order_prev):
125            v_offs_2 = v_offs_start - spacing * (player_order.index(player))
126            ba.timer(tdelay + 0.3,
127                     ba.Call(ba.playsound, self._score_display_sound_small))
128            if order_change:
129                ba.timer(tdelay + delay2 + 0.1,
130                         ba.Call(ba.playsound, self._cymbal_sound))
131            img = Image(player.get_icon(),
132                        position=(ts_h_offs - 72.0 * scale,
133                                  y_base + (v_offs + 15.0) * scale),
134                        scale=(30.0 * scale, 30.0 * scale),
135                        transition=Image.Transition.IN_LEFT,
136                        transition_delay=tdelay).autoretain()
137            ba.timer(
138                tdelay + delay2,
139                ba.WeakCall(
140                    self._safe_animate, img.position_combine, 'input1', {
141                        0: y_base + (v_offs + 15.0) * scale,
142                        transtime: y_base + (v_offs_2 + 15.0) * scale
143                    }))
144            ba.timer(
145                tdelay + delay3,
146                ba.WeakCall(
147                    self._safe_animate, img.position_combine, 'input0', {
148                        0: ts_h_offs - 72.0 * scale,
149                        transtime2: ts_h_offs - (72.0 + slide_amt) * scale
150                    }))
151            txt = Text(ba.Lstr(value=player.getname(full=True)),
152                       maxwidth=130.0,
153                       scale=0.75 * scale,
154                       position=(ts_h_offs - 50.0 * scale,
155                                 y_base + (v_offs + 15.0) * scale),
156                       h_align=Text.HAlign.LEFT,
157                       v_align=Text.VAlign.CENTER,
158                       color=ba.safecolor(player.team.color + (1, )),
159                       transition=Text.Transition.IN_LEFT,
160                       transition_delay=tdelay).autoretain()
161            ba.timer(
162                tdelay + delay2,
163                ba.WeakCall(
164                    self._safe_animate, txt.position_combine, 'input1', {
165                        0: y_base + (v_offs + 15.0) * scale,
166                        transtime: y_base + (v_offs_2 + 15.0) * scale
167                    }))
168            ba.timer(
169                tdelay + delay3,
170                ba.WeakCall(
171                    self._safe_animate, txt.position_combine, 'input0', {
172                        0: ts_h_offs - 50.0 * scale,
173                        transtime2: ts_h_offs - (50.0 + slide_amt) * scale
174                    }))
175
176            txt_num = Text('#' + str(i + 1),
177                           scale=0.55 * scale,
178                           position=(ts_h_offs - 95.0 * scale,
179                                     y_base + (v_offs + 8.0) * scale),
180                           h_align=Text.HAlign.RIGHT,
181                           color=(0.6, 0.6, 0.6, 0.6),
182                           transition=Text.Transition.IN_LEFT,
183                           transition_delay=tdelay).autoretain()
184            ba.timer(
185                tdelay + delay3,
186                ba.WeakCall(
187                    self._safe_animate, txt_num.position_combine, 'input0', {
188                        0: ts_h_offs - 95.0 * scale,
189                        transtime2: ts_h_offs - (95.0 + slide_amt) * scale
190                    }))
191
192            s_txt = _scoretxt(
193                str(player.team.sessionteam.customdata['previous_score']), 80,
194                0, False, 0, 1.0)
195            ba.timer(
196                tdelay + delay2,
197                ba.WeakCall(
198                    self._safe_animate, s_txt.position_combine, 'input1', {
199                        0: y_base + (v_offs + 2.0) * scale,
200                        transtime: y_base + (v_offs_2 + 2.0) * scale
201                    }))
202            ba.timer(
203                tdelay + delay3,
204                ba.WeakCall(
205                    self._safe_animate, s_txt.position_combine, 'input0', {
206                        0: ts_h_offs + 80.0 * scale,
207                        transtime2: ts_h_offs + (80.0 - slide_amt) * scale
208                    }))
209
210            score_change = (
211                player.team.sessionteam.customdata['score'] -
212                player.team.sessionteam.customdata['previous_score'])
213            if score_change > 0:
214                xval = 113
215                yval = 3.0
216                s_txt_2 = _scoretxt('+' + str(score_change),
217                                    xval,
218                                    yval,
219                                    True,
220                                    0,
221                                    0.7,
222                                    flash=True)
223                ba.timer(
224                    tdelay + delay2,
225                    ba.WeakCall(
226                        self._safe_animate, s_txt_2.position_combine, 'input1',
227                        {
228                            0: y_base + (v_offs + yval + 2.0) * scale,
229                            transtime: y_base + (v_offs_2 + yval + 2.0) * scale
230                        }))
231                ba.timer(
232                    tdelay + delay3,
233                    ba.WeakCall(
234                        self._safe_animate, s_txt_2.position_combine, 'input0',
235                        {
236                            0: ts_h_offs + xval * scale,
237                            transtime2: ts_h_offs + (xval - slide_amt) * scale
238                        }))
239
240                def _safesetattr(node: ba.Node | None, attr: str,
241                                 value: Any) -> None:
242                    if node:
243                        setattr(node, attr, value)
244
245                ba.timer(
246                    tdelay + delay1,
247                    ba.Call(_safesetattr, s_txt.node, 'color', (1, 1, 1, 1)))
248                for j in range(score_change):
249                    ba.timer((tdelay + delay1 + 0.15 * j),
250                             ba.Call(
251                                 _safesetattr, s_txt.node, 'text',
252                                 str(player.team.sessionteam.
253                                     customdata['previous_score'] + j + 1)))
254                    tfin = tdelay + delay1 + 0.15 * j
255                    if tfin not in sound_times:
256                        sound_times.add(tfin)
257                        ba.timer(
258                            tfin,
259                            ba.Call(ba.playsound,
260                                    self._score_display_sound_small))
261            v_offs -= spacing
262
263    def _safe_animate(self, node: ba.Node | None, attr: str,
264                      keys: dict[float, float]) -> None:
265        """Run an animation on a node if the node still exists."""
266        if node:
267            ba.animate(node, attr, keys)

Score screen shown at after free-for-all rounds.

FreeForAllVictoryScoreScreenActivity(settings: dict)
20    def __init__(self, settings: dict):
21        super().__init__(settings=settings)
22
23        # Keep prev activity alive while we fade in.
24        self.transition_time = 0.5
25        self._cymbal_sound = ba.getsound('cymbal')

Creates an Activity in the current ba.Session.

The activity will not be actually run until ba.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.

def on_begin(self) -> None:
 27    def on_begin(self) -> None:
 28        # pylint: disable=too-many-locals
 29        # pylint: disable=too-many-statements
 30        from bastd.actor.text import Text
 31        from bastd.actor.image import Image
 32        ba.set_analytics_screen('FreeForAll Score Screen')
 33        super().on_begin()
 34
 35        y_base = 100.0
 36        ts_h_offs = -305.0
 37        tdelay = 1.0
 38        scale = 1.2
 39        spacing = 37.0
 40
 41        # We include name and previous score in the sort to reduce the amount
 42        # of random jumping around the list we do in cases of ties.
 43        player_order_prev = list(self.players)
 44        player_order_prev.sort(
 45            reverse=True,
 46            key=lambda p: (
 47                p.team.sessionteam.customdata['previous_score'],
 48                p.getname(full=True),
 49            ))
 50        player_order = list(self.players)
 51        player_order.sort(reverse=True,
 52                          key=lambda p: (
 53                              p.team.sessionteam.customdata['score'],
 54                              p.team.sessionteam.customdata['score'],
 55                              p.getname(full=True),
 56                          ))
 57
 58        v_offs = -74.0 + spacing * len(player_order_prev) * 0.5
 59        delay1 = 1.3 + 0.1
 60        delay2 = 2.9 + 0.1
 61        delay3 = 2.9 + 0.1
 62        order_change = player_order != player_order_prev
 63
 64        if order_change:
 65            delay3 += 1.5
 66
 67        ba.timer(0.3, ba.Call(ba.playsound, self._score_display_sound))
 68        results = self.settings_raw['results']
 69        assert isinstance(results, ba.GameResults)
 70        self.show_player_scores(delay=0.001,
 71                                results=results,
 72                                scale=1.2,
 73                                x_offset=-110.0)
 74
 75        sound_times: set[float] = set()
 76
 77        def _scoretxt(text: str,
 78                      x_offs: float,
 79                      y_offs: float,
 80                      highlight: bool,
 81                      delay: float,
 82                      extrascale: float,
 83                      flash: bool = False) -> Text:
 84            return Text(text,
 85                        position=(ts_h_offs + x_offs * scale,
 86                                  y_base + (y_offs + v_offs + 2.0) * scale),
 87                        scale=scale * extrascale,
 88                        color=((1.0, 0.7, 0.3, 1.0) if highlight else
 89                               (0.7, 0.7, 0.7, 0.7)),
 90                        h_align=Text.HAlign.RIGHT,
 91                        transition=Text.Transition.IN_LEFT,
 92                        transition_delay=tdelay + delay,
 93                        flash=flash).autoretain()
 94
 95        v_offs -= spacing
 96        slide_amt = 0.0
 97        transtime = 0.250
 98        transtime2 = 0.250
 99
100        session = self.session
101        assert isinstance(session, ba.FreeForAllSession)
102        title = Text(ba.Lstr(resource='firstToSeriesText',
103                             subs=[('${COUNT}',
104                                    str(session.get_ffa_series_length()))]),
105                     scale=1.05 * scale,
106                     position=(ts_h_offs - 0.0 * scale,
107                               y_base + (v_offs + 50.0) * scale),
108                     h_align=Text.HAlign.CENTER,
109                     color=(0.5, 0.5, 0.5, 0.5),
110                     transition=Text.Transition.IN_LEFT,
111                     transition_delay=tdelay).autoretain()
112
113        v_offs -= 25
114        v_offs_start = v_offs
115
116        ba.timer(
117            tdelay + delay3,
118            ba.WeakCall(
119                self._safe_animate, title.position_combine, 'input0', {
120                    0.0: ts_h_offs - 0.0 * scale,
121                    transtime2: ts_h_offs - (0.0 + slide_amt) * scale
122                }))
123
124        for i, player in enumerate(player_order_prev):
125            v_offs_2 = v_offs_start - spacing * (player_order.index(player))
126            ba.timer(tdelay + 0.3,
127                     ba.Call(ba.playsound, self._score_display_sound_small))
128            if order_change:
129                ba.timer(tdelay + delay2 + 0.1,
130                         ba.Call(ba.playsound, self._cymbal_sound))
131            img = Image(player.get_icon(),
132                        position=(ts_h_offs - 72.0 * scale,
133                                  y_base + (v_offs + 15.0) * scale),
134                        scale=(30.0 * scale, 30.0 * scale),
135                        transition=Image.Transition.IN_LEFT,
136                        transition_delay=tdelay).autoretain()
137            ba.timer(
138                tdelay + delay2,
139                ba.WeakCall(
140                    self._safe_animate, img.position_combine, 'input1', {
141                        0: y_base + (v_offs + 15.0) * scale,
142                        transtime: y_base + (v_offs_2 + 15.0) * scale
143                    }))
144            ba.timer(
145                tdelay + delay3,
146                ba.WeakCall(
147                    self._safe_animate, img.position_combine, 'input0', {
148                        0: ts_h_offs - 72.0 * scale,
149                        transtime2: ts_h_offs - (72.0 + slide_amt) * scale
150                    }))
151            txt = Text(ba.Lstr(value=player.getname(full=True)),
152                       maxwidth=130.0,
153                       scale=0.75 * scale,
154                       position=(ts_h_offs - 50.0 * scale,
155                                 y_base + (v_offs + 15.0) * scale),
156                       h_align=Text.HAlign.LEFT,
157                       v_align=Text.VAlign.CENTER,
158                       color=ba.safecolor(player.team.color + (1, )),
159                       transition=Text.Transition.IN_LEFT,
160                       transition_delay=tdelay).autoretain()
161            ba.timer(
162                tdelay + delay2,
163                ba.WeakCall(
164                    self._safe_animate, txt.position_combine, 'input1', {
165                        0: y_base + (v_offs + 15.0) * scale,
166                        transtime: y_base + (v_offs_2 + 15.0) * scale
167                    }))
168            ba.timer(
169                tdelay + delay3,
170                ba.WeakCall(
171                    self._safe_animate, txt.position_combine, 'input0', {
172                        0: ts_h_offs - 50.0 * scale,
173                        transtime2: ts_h_offs - (50.0 + slide_amt) * scale
174                    }))
175
176            txt_num = Text('#' + str(i + 1),
177                           scale=0.55 * scale,
178                           position=(ts_h_offs - 95.0 * scale,
179                                     y_base + (v_offs + 8.0) * scale),
180                           h_align=Text.HAlign.RIGHT,
181                           color=(0.6, 0.6, 0.6, 0.6),
182                           transition=Text.Transition.IN_LEFT,
183                           transition_delay=tdelay).autoretain()
184            ba.timer(
185                tdelay + delay3,
186                ba.WeakCall(
187                    self._safe_animate, txt_num.position_combine, 'input0', {
188                        0: ts_h_offs - 95.0 * scale,
189                        transtime2: ts_h_offs - (95.0 + slide_amt) * scale
190                    }))
191
192            s_txt = _scoretxt(
193                str(player.team.sessionteam.customdata['previous_score']), 80,
194                0, False, 0, 1.0)
195            ba.timer(
196                tdelay + delay2,
197                ba.WeakCall(
198                    self._safe_animate, s_txt.position_combine, 'input1', {
199                        0: y_base + (v_offs + 2.0) * scale,
200                        transtime: y_base + (v_offs_2 + 2.0) * scale
201                    }))
202            ba.timer(
203                tdelay + delay3,
204                ba.WeakCall(
205                    self._safe_animate, s_txt.position_combine, 'input0', {
206                        0: ts_h_offs + 80.0 * scale,
207                        transtime2: ts_h_offs + (80.0 - slide_amt) * scale
208                    }))
209
210            score_change = (
211                player.team.sessionteam.customdata['score'] -
212                player.team.sessionteam.customdata['previous_score'])
213            if score_change > 0:
214                xval = 113
215                yval = 3.0
216                s_txt_2 = _scoretxt('+' + str(score_change),
217                                    xval,
218                                    yval,
219                                    True,
220                                    0,
221                                    0.7,
222                                    flash=True)
223                ba.timer(
224                    tdelay + delay2,
225                    ba.WeakCall(
226                        self._safe_animate, s_txt_2.position_combine, 'input1',
227                        {
228                            0: y_base + (v_offs + yval + 2.0) * scale,
229                            transtime: y_base + (v_offs_2 + yval + 2.0) * scale
230                        }))
231                ba.timer(
232                    tdelay + delay3,
233                    ba.WeakCall(
234                        self._safe_animate, s_txt_2.position_combine, 'input0',
235                        {
236                            0: ts_h_offs + xval * scale,
237                            transtime2: ts_h_offs + (xval - slide_amt) * scale
238                        }))
239
240                def _safesetattr(node: ba.Node | None, attr: str,
241                                 value: Any) -> None:
242                    if node:
243                        setattr(node, attr, value)
244
245                ba.timer(
246                    tdelay + delay1,
247                    ba.Call(_safesetattr, s_txt.node, 'color', (1, 1, 1, 1)))
248                for j in range(score_change):
249                    ba.timer((tdelay + delay1 + 0.15 * j),
250                             ba.Call(
251                                 _safesetattr, s_txt.node, 'text',
252                                 str(player.team.sessionteam.
253                                     customdata['previous_score'] + j + 1)))
254                    tfin = tdelay + delay1 + 0.15 * j
255                    if tfin not in sound_times:
256                        sound_times.add(tfin)
257                        ba.timer(
258                            tfin,
259                            ba.Call(ba.playsound,
260                                    self._score_display_sound_small))
261            v_offs -= spacing

Called once the previous ba.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.

Inherited Members
ba._activitytypes.ScoreScreenActivity
transition_time
inherits_tint
inherits_vr_camera_offset
use_fixed_vr_overlay
default_music
on_player_join
on_transition_in
bastd.activity.multiteamscore.MultiTeamScoreScreenActivity
show_player_scores
ba._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
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
ba._dependency.DependencyComponent
dep_is_present
get_dynamic_deps