def on_begin(self) -> None:
        from ba.deprecated import get_resource
        ba.set_analytics_screen('Teams Score Screen')
        super().on_begin()

        height = 130
        active_team_count = len(self.teams)
        vval = (height * active_team_count) / 2 - height / 2
        i = 0
        shift_time = 2.5

        # Usually we say 'Best of 7', but if the language prefers we can say
        # 'First to 4'.
        session = self.session
        assert isinstance(session, ba.TeamBaseSession)
        if get_resource('bestOfUseFirstToInstead'):
            best_txt = ba.Lstr(resource='firstToSeriesText',
                               subs=[('${COUNT}',
                                      str(session.get_series_length() / 2 + 1))
                                     ])
        else:
            best_txt = ba.Lstr(resource='bestOfSeriesText',
                               subs=[('${COUNT}',
                                      str(session.get_series_length()))])

        ZoomText(best_txt,
                 position=(0, 175),
                 shiftposition=(-250, 175),
                 shiftdelay=2.5,
                 flash=False,
                 trail=False,
                 h_align='center',
                 scale=0.25,
                 color=(0.5, 0.5, 0.5, 1.0),
                 jitter=3.0).autoretain()
        for team in self.teams:
            ba.timer(
                i * 0.15 + 0.15,
                ba.WeakCall(self._show_team_name, vval - i * height, team,
                            i * 0.2, shift_time - (i * 0.150 + 0.150)))
            ba.timer(i * 0.150 + 0.5,
                     ba.Call(ba.playsound, self._score_display_sound_small))
            scored = (team is self.settings['winner'])
            delay = 0.2
            if scored:
                delay = 1.2
                ba.timer(
                    i * 0.150 + 0.2,
                    ba.WeakCall(self._show_team_old_score, vval - i * height,
                                team, shift_time - (i * 0.15 + 0.2)))
                ba.timer(i * 0.15 + 1.5,
                         ba.Call(ba.playsound, self._score_display_sound))

            ba.timer(
                i * 0.150 + delay,
                ba.WeakCall(self._show_team_score, vval - i * height, team,
                            scored, i * 0.2 + 0.1,
                            shift_time - (i * 0.15 + delay)))
            i += 1
        self.show_player_scores()
Esempio n. 2
0
    def _email(self) -> None:
        import urllib.parse

        # If somehow we got signed out.
        if _ba.get_account_state() != 'signed_in':
            ba.screenmessage(ba.Lstr(resource='notSignedInText'),
                             color=(1, 0, 0))
            ba.playsound(ba.getsound('error'))
            return

        ba.set_analytics_screen('Email Friend Code')
        subject = (ba.Lstr(resource='gatherWindow.friendHasSentPromoCodeText').
                   evaluate().replace(
                       '${NAME}', _ba.get_account_name()).replace(
                           '${APP_NAME}',
                           ba.Lstr(resource='titleText').evaluate()).replace(
                               '${COUNT}', str(self._data['tickets'])))
        body = (ba.Lstr(resource='gatherWindow.youHaveBeenSentAPromoCodeText').
                evaluate().replace('${APP_NAME}',
                                   ba.Lstr(resource='titleText').evaluate()) +
                '\n\n' + str(self._data['code']) + '\n\n')
        body += (
            (ba.Lstr(resource='gatherWindow.friendPromoCodeRedeemShortText').
             evaluate().replace('${COUNT}', str(self._data['tickets']))) +
            '\n\n' +
            ba.Lstr(resource='gatherWindow.friendPromoCodeInstructionsText').
            evaluate().replace('${APP_NAME}',
                               ba.Lstr(resource='titleText').evaluate()) +
            '\n' + ba.Lstr(resource='gatherWindow.friendPromoCodeExpireText').
            evaluate().replace('${EXPIRE_HOURS}', str(
                self._data['expireHours'])) + '\n' +
            ba.Lstr(resource='enjoyText').evaluate())
        ba.open_url('mailto:?subject=' + urllib.parse.quote(subject) +
                    '&body=' + urllib.parse.quote(body))
Esempio n. 3
0
    def __init__(self, transition: Optional[str] = 'in_right'):
        # pylint: disable=cyclic-import
        import threading
        from bastd.mainmenu import MainMenuSession
        self._in_game = not isinstance(_ba.get_foreground_host_session(),
                                       MainMenuSession)

        # Preload some modules we use in a background thread so we won't
        # have a visual hitch when the user taps them.
        threading.Thread(target=self._preload_modules).start()

        if not self._in_game:
            ba.set_analytics_screen('Main Menu')
            self._show_remote_app_info_on_first_launch()

        # Make a vanilla container; we'll modify it to our needs in refresh.
        super().__init__(root_widget=ba.containerwidget(
            transition=transition,
            toolbar_visibility='menu_minimal_no_back' if self.
            _in_game else 'menu_minimal_no_back'))

        # Grab this stuff in case it changes.
        self._is_demo = ba.app.demo_mode
        self._is_arcade = ba.app.arcade_mode
        self._is_iircade = ba.app.iircade_mode

        self._tdelay = 0.0
        self._t_delay_inc = 0.02
        self._t_delay_play = 1.7
        self._p_index = 0
        self._use_autoselect = True
        self._button_width = 200.0
        self._button_height = 45.0
        self._width = 100.0
        self._height = 100.0
        self._demo_menu_button: Optional[ba.Widget] = None
        self._gather_button: Optional[ba.Widget] = None
        self._start_button: Optional[ba.Widget] = None
        self._watch_button: Optional[ba.Widget] = None
        self._gc_button: Optional[ba.Widget] = None
        self._how_to_play_button: Optional[ba.Widget] = None
        self._credits_button: Optional[ba.Widget] = None
        self._settings_button: Optional[ba.Widget] = None

        self._store_char_tex = self._get_store_char_tex()

        self._refresh()
        self._restore_state()

        # Keep an eye on a few things and refresh if they change.
        self._account_state = _ba.get_account_state()
        self._account_state_num = _ba.get_account_state_num()
        self._account_type = (_ba.get_account_type()
                              if self._account_state == 'signed_in' else None)
        self._refresh_timer = ba.Timer(1.0,
                                       ba.WeakCall(self._check_refresh),
                                       repeat=True,
                                       timetype=ba.TimeType.REAL)
Esempio n. 4
0
 def _google_invites(self) -> None:
     ba.set_analytics_screen('App Invite UI')
     _ba.show_app_invite(
         ba.Lstr(resource='gatherWindow.appInviteTitleText',
                 subs=[('${APP_NAME}', ba.Lstr(resource='titleText'))
                       ]).evaluate(),
         ba.Lstr(resource='gatherWindow.appInviteMessageText',
                 subs=[('${COUNT}', str(self._data['tickets'])),
                       ('${NAME}', _ba.get_account_name().split()[0]),
                       ('${APP_NAME}', ba.Lstr(resource='titleText'))
                       ]).evaluate(), self._data['code'])
Esempio n. 5
0
 def on_begin(self) -> None:
     ba.set_analytics_screen('Draw Score Screen')
     super().on_begin()
     ZoomText(ba.Lstr(resource='drawText'),
              position=(0, 0),
              maxwidth=400,
              shiftposition=(-220, 0),
              shiftdelay=2.0,
              flash=False,
              trail=False,
              jitter=1.0).autoretain()
     ba.timer(0.35, ba.Call(ba.playsound, self._score_display_sound))
     self.show_player_scores(results=self.settings_raw.get('results', None))
Esempio n. 6
0
    def __init__(self, transition: Optional[str] = 'in_right'):
        # pylint: disable=cyclic-import
        from bastd import mainmenu
        self._in_game = not isinstance(_ba.get_foreground_host_session(),
                                       mainmenu.MainMenuSession)
        if not self._in_game:
            ba.set_analytics_screen('Main Menu')

            self._show_remote_app_info_on_first_launch()

        # Make a vanilla container; we'll modify it to our needs in refresh.
        super().__init__(root_widget=ba.containerwidget(
            transition=transition,
            toolbar_visibility='menu_minimal_no_back' if self.
            _in_game else 'menu_minimal_no_back'))

        self._is_kiosk = ba.app.kiosk_mode
        self._tdelay = 0.0
        self._t_delay_inc = 0.02
        self._t_delay_play = 1.7
        self._p_index = 0
        self._use_autoselect = True
        self._button_width = 200.0
        self._button_height = 45.0
        self._width = 100.0
        self._height = 100.0
        self._demo_menu_button: Optional[ba.Widget] = None
        self._gather_button: Optional[ba.Widget] = None
        self._start_button: Optional[ba.Widget] = None
        self._watch_button: Optional[ba.Widget] = None
        self._gc_button: Optional[ba.Widget] = None
        self._how_to_play_button: Optional[ba.Widget] = None
        self._credits_button: Optional[ba.Widget] = None

        self._store_char_tex = self._get_store_char_tex()

        self._refresh()
        self._restore_state()

        # Keep an eye on a few things and refresh if they change.
        self._account_state = _ba.get_account_state()
        self._account_state_num = _ba.get_account_state_num()
        self._account_type = (_ba.get_account_type()
                              if self._account_state == 'signed_in' else None)
        self._refresh_timer = ba.Timer(1.0,
                                       ba.WeakCall(self._check_refresh),
                                       repeat=True,
                                       timetype=ba.TimeType.REAL)
Esempio n. 7
0
    def _google_invites(self) -> None:
        if self._data is None:
            ba.screenmessage(ba.Lstr(
                resource='getTicketsWindow.unavailableTemporarilyText'),
                             color=(1, 0, 0))
            ba.playsound(ba.getsound('error'))
            return

        if _ba.get_account_state() == 'signed_in':
            ba.set_analytics_screen('App Invite UI')
            _ba.show_app_invite(
                ba.Lstr(resource='gatherWindow.appInviteTitleText',
                        subs=[('${APP_NAME}', ba.Lstr(resource='titleText'))
                              ]).evaluate(),
                ba.Lstr(resource='gatherWindow.appInviteMessageText',
                        subs=[('${COUNT}', str(self._data['tickets'])),
                              ('${NAME}', _ba.get_account_name().split()[0]),
                              ('${APP_NAME}', ba.Lstr(resource='titleText'))
                              ]).evaluate(), self._data['code'])
        else:
            ba.playsound(ba.getsound('error'))
Esempio n. 8
0
    def __init__(self,
                 transition: str = 'in_right',
                 origin_widget: ba.Widget = None):
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-locals
        import threading

        # Preload some modules we use in a background thread so we won't
        # have a visual hitch when the user taps them.
        threading.Thread(target=self._preload_modules).start()

        ba.set_analytics_screen('Settings Window')
        scale_origin: Optional[Tuple[float, float]]
        if origin_widget is not None:
            self._transition_out = 'out_scale'
            scale_origin = origin_widget.get_screen_space_center()
            transition = 'in_scale'
        else:
            self._transition_out = 'out_right'
            scale_origin = None
        uiscale = ba.app.uiscale
        width = 900 if uiscale is ba.UIScale.SMALL else 580
        x_inset = 75 if uiscale is ba.UIScale.SMALL else 0
        height = 435
        # button_height = 42
        self._r = 'settingsWindow'
        top_extra = 20 if uiscale is ba.UIScale.SMALL else 0

        uiscale = ba.app.uiscale
        super().__init__(root_widget=ba.containerwidget(
            size=(width, height + top_extra),
            transition=transition,
            toolbar_visibility='menu_minimal',
            scale_origin_stack_offset=scale_origin,
            scale=(1.75 if uiscale is ba.UIScale.SMALL else
                   1.35 if uiscale is ba.UIScale.MEDIUM else 1.0),
            stack_offset=(0, -8) if uiscale is ba.UIScale.SMALL else (0, 0)))

        if ba.app.toolbars and uiscale is ba.UIScale.SMALL:
            self._back_button = None
            ba.containerwidget(edit=self._root_widget,
                               on_cancel_call=self._do_back)
        else:
            self._back_button = btn = ba.buttonwidget(
                parent=self._root_widget,
                autoselect=True,
                position=(40 + x_inset, height - 55),
                size=(130, 60),
                scale=0.8,
                text_scale=1.2,
                label=ba.Lstr(resource='backText'),
                button_type='back',
                on_activate_call=self._do_back)
            ba.containerwidget(edit=self._root_widget, cancel_button=btn)

        ba.textwidget(parent=self._root_widget,
                      position=(0, height - 44),
                      size=(width, 25),
                      text=ba.Lstr(resource=self._r + '.titleText'),
                      color=ba.app.title_color,
                      h_align='center',
                      v_align='center',
                      maxwidth=130)

        if self._back_button is not None:
            ba.buttonwidget(edit=self._back_button,
                            button_type='backSmall',
                            size=(60, 60),
                            label=ba.charstr(ba.SpecialChar.BACK))

        v = height - 80
        v -= 145

        basew = 280 if uiscale is ba.UIScale.SMALL else 230
        baseh = 170
        x_offs = x_inset + (105 if uiscale is ba.UIScale.SMALL else
                            72) - basew  # now unused
        x_offs2 = x_offs + basew - 7
        x_offs3 = x_offs + 2 * (basew - 7)
        x_offs4 = x_offs2
        x_offs5 = x_offs3

        def _b_title(x: float, y: float, button: ba.Widget,
                     text: Union[str, ba.Lstr]) -> None:
            ba.textwidget(parent=self._root_widget,
                          text=text,
                          position=(x + basew * 0.47, y + baseh * 0.22),
                          maxwidth=basew * 0.7,
                          size=(0, 0),
                          h_align='center',
                          v_align='center',
                          draw_controller=button,
                          color=(0.7, 0.9, 0.7, 1.0))

        ctb = self._controllers_button = ba.buttonwidget(
            parent=self._root_widget,
            autoselect=True,
            position=(x_offs2, v),
            size=(basew, baseh),
            button_type='square',
            label='',
            on_activate_call=self._do_controllers)
        if ba.app.toolbars and self._back_button is None:
            bbtn = _ba.get_special_widget('back_button')
            ba.widget(edit=ctb, left_widget=bbtn)
        _b_title(x_offs2, v, ctb,
                 ba.Lstr(resource=self._r + '.controllersText'))
        imgw = imgh = 130
        ba.imagewidget(parent=self._root_widget,
                       position=(x_offs2 + basew * 0.49 - imgw * 0.5, v + 35),
                       size=(imgw, imgh),
                       texture=ba.gettexture('controllerIcon'),
                       draw_controller=ctb)

        gfxb = self._graphics_button = ba.buttonwidget(
            parent=self._root_widget,
            autoselect=True,
            position=(x_offs3, v),
            size=(basew, baseh),
            button_type='square',
            label='',
            on_activate_call=self._do_graphics)
        if ba.app.toolbars:
            pbtn = _ba.get_special_widget('party_button')
            ba.widget(edit=gfxb, up_widget=pbtn, right_widget=pbtn)
        _b_title(x_offs3, v, gfxb, ba.Lstr(resource=self._r + '.graphicsText'))
        imgw = imgh = 110
        ba.imagewidget(parent=self._root_widget,
                       position=(x_offs3 + basew * 0.49 - imgw * 0.5, v + 42),
                       size=(imgw, imgh),
                       texture=ba.gettexture('graphicsIcon'),
                       draw_controller=gfxb)

        v -= (baseh - 5)

        abtn = self._audio_button = ba.buttonwidget(
            parent=self._root_widget,
            autoselect=True,
            position=(x_offs4, v),
            size=(basew, baseh),
            button_type='square',
            label='',
            on_activate_call=self._do_audio)
        _b_title(x_offs4, v, abtn, ba.Lstr(resource=self._r + '.audioText'))
        imgw = imgh = 120
        ba.imagewidget(parent=self._root_widget,
                       position=(x_offs4 + basew * 0.49 - imgw * 0.5 + 5,
                                 v + 35),
                       size=(imgw, imgh),
                       color=(1, 1, 0),
                       texture=ba.gettexture('audioIcon'),
                       draw_controller=abtn)

        avb = self._advanced_button = ba.buttonwidget(
            parent=self._root_widget,
            autoselect=True,
            position=(x_offs5, v),
            size=(basew, baseh),
            button_type='square',
            label='',
            on_activate_call=self._do_advanced)
        _b_title(x_offs5, v, avb, ba.Lstr(resource=self._r + '.advancedText'))
        imgw = imgh = 120
        ba.imagewidget(parent=self._root_widget,
                       position=(x_offs5 + basew * 0.49 - imgw * 0.5 + 5,
                                 v + 35),
                       size=(imgw, imgh),
                       color=(0.8, 0.95, 1),
                       texture=ba.gettexture('advancedIcon'),
                       draw_controller=avb)
Esempio n. 9
0
    def __init__(self,
                 main_menu: bool = False,
                 origin_widget: ba.Widget = None):
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-locals
        from ba.internal import get_remote_app_name
        from ba.deprecated import get_resource
        ba.set_analytics_screen('Help Window')

        # If they provided an origin-widget, scale up from that.
        scale_origin: Optional[Tuple[float, float]]
        if origin_widget is not None:
            self._transition_out = 'out_scale'
            scale_origin = origin_widget.get_screen_space_center()
            transition = 'in_scale'
        else:
            self._transition_out = 'out_right'
            scale_origin = None
            transition = 'in_right'

        self._r = 'helpWindow'

        self._main_menu = main_menu
        width = 950 if ba.app.small_ui else 750
        x_offs = 100 if ba.app.small_ui else 0
        height = 460 if ba.app.small_ui else 530 if ba.app.med_ui else 600

        super().__init__(root_widget=ba.containerwidget(
            size=(width, height),
            transition=transition,
            toolbar_visibility='menu_minimal',
            scale_origin_stack_offset=scale_origin,
            scale=(
                1.77 if ba.app.small_ui else 1.25 if ba.app.med_ui else 1.0),
            stack_offset=(0, -30) if ba.app.small_ui else (
                0, 15) if ba.app.med_ui else (0, 0)))

        ba.textwidget(parent=self._root_widget,
                      position=(0, height - (50 if ba.app.small_ui else 45)),
                      size=(width, 25),
                      text=ba.Lstr(resource=self._r + '.titleText',
                                   subs=[('${APP_NAME}',
                                          ba.Lstr(resource='titleText'))]),
                      color=ba.app.title_color,
                      h_align='center',
                      v_align='top')

        self._scrollwidget = ba.scrollwidget(
            parent=self._root_widget,
            position=(44 + x_offs, 55 if ba.app.small_ui else 55),
            simple_culling_v=100.0,
            size=(width - (88 + 2 * x_offs),
                  height - 120 + (5 if ba.app.small_ui else 0)),
            capture_arrows=True)

        if ba.app.toolbars:
            ba.widget(edit=self._scrollwidget,
                      right_widget=_ba.get_special_widget('party_button'))
        ba.containerwidget(edit=self._root_widget,
                           selected_child=self._scrollwidget)

        # ugly: create this last so it gets first dibs at touch events (since
        # we have it close to the scroll widget)
        if ba.app.small_ui and ba.app.toolbars:
            ba.containerwidget(edit=self._root_widget,
                               on_cancel_call=self._close)
            ba.widget(edit=self._scrollwidget,
                      left_widget=_ba.get_special_widget('back_button'))
        else:
            btn = ba.buttonwidget(
                parent=self._root_widget,
                position=(x_offs + (40 + 0 if ba.app.small_ui else 70),
                          height - (59 if ba.app.small_ui else 50)),
                size=(140, 60),
                scale=0.7 if ba.app.small_ui else 0.8,
                label=ba.Lstr(
                    resource='backText') if self._main_menu else 'Close',
                button_type='back' if self._main_menu else None,
                extra_touch_border_scale=2.0,
                autoselect=True,
                on_activate_call=self._close)
            ba.containerwidget(edit=self._root_widget, cancel_button=btn)

            if self._main_menu:
                ba.buttonwidget(edit=btn,
                                button_type='backSmall',
                                size=(60, 55),
                                label=ba.charstr(ba.SpecialChar.BACK))

        # interface_type = ba.app.interface_type

        self._sub_width = 660
        self._sub_height = 1590 + get_resource(
            self._r + '.someDaysExtraSpace') + get_resource(
                self._r + '.orPunchingSomethingExtraSpace')

        self._subcontainer = ba.containerwidget(parent=self._scrollwidget,
                                                size=(self._sub_width,
                                                      self._sub_height),
                                                background=False,
                                                claims_left_right=False,
                                                claims_tab=False)

        spacing = 1.0
        h = self._sub_width * 0.5
        v = self._sub_height - 55
        logo_tex = ba.gettexture('logo')
        icon_buffer = 1.1
        header = (0.7, 1.0, 0.7, 1.0)
        header2 = (0.8, 0.8, 1.0, 1.0)
        paragraph = (0.8, 0.8, 1.0, 1.0)

        txt = ba.Lstr(resource=self._r + '.welcomeText',
                      subs=[('${APP_NAME}', ba.Lstr(resource='titleText'))
                            ]).evaluate()
        txt_scale = 1.4
        txt_maxwidth = 480
        ba.textwidget(parent=self._subcontainer,
                      position=(h, v),
                      size=(0, 0),
                      scale=txt_scale,
                      flatness=0.5,
                      res_scale=1.5,
                      text=txt,
                      h_align='center',
                      color=header,
                      v_align='center',
                      maxwidth=txt_maxwidth)
        txt_width = min(
            txt_maxwidth,
            _ba.get_string_width(txt, suppress_warning=True) * txt_scale)

        icon_size = 70
        hval2 = h - (txt_width * 0.5 + icon_size * 0.5 * icon_buffer)
        ba.imagewidget(parent=self._subcontainer,
                       size=(icon_size, icon_size),
                       position=(hval2 - 0.5 * icon_size,
                                 v - 0.45 * icon_size),
                       texture=logo_tex)

        force_test = False
        app = ba.app
        if (app.platform == 'android'
                and app.subplatform == 'alibaba') or force_test:
            v -= 120.0
            txtv = (
                '\xe8\xbf\x99\xe6\x98\xaf\xe4\xb8\x80\xe4\xb8\xaa\xe5\x8f\xaf'
                '\xe4\xbb\xa5\xe5\x92\x8c\xe5\xae\xb6\xe4\xba\xba\xe6\x9c\x8b'
                '\xe5\x8f\x8b\xe4\xb8\x80\xe8\xb5\xb7\xe7\x8e\xa9\xe7\x9a\x84'
                '\xe6\xb8\xb8\xe6\x88\x8f,\xe5\x90\x8c\xe6\x97\xb6\xe6\x94\xaf'
                '\xe6\x8c\x81\xe8\x81\x94 \xe2\x80\xa8\xe7\xbd\x91\xe5\xaf\xb9'
                '\xe6\x88\x98\xe3\x80\x82\n'
                '\xe5\xa6\x82\xe6\xb2\xa1\xe6\x9c\x89\xe6\xb8\xb8\xe6\x88\x8f'
                '\xe6\x89\x8b\xe6\x9f\x84,\xe5\x8f\xaf\xe4\xbb\xa5\xe4\xbd\xbf'
                '\xe7\x94\xa8\xe7\xa7\xbb\xe5\x8a\xa8\xe8\xae\xbe\xe5\xa4\x87'
                '\xe6\x89\xab\xe7\xa0\x81\xe4\xb8\x8b\xe8\xbd\xbd\xe2\x80\x9c'
                '\xe9\x98\xbf\xe9\x87\x8c\xc2'
                '\xa0TV\xc2\xa0\xe5\x8a\xa9\xe6\x89'
                '\x8b\xe2\x80\x9d\xe7\x94\xa8 \xe6\x9d\xa5\xe4\xbb\xa3\xe6\x9b'
                '\xbf\xe5\xa4\x96\xe8\xae\xbe\xe3\x80\x82\n'
                '\xe6\x9c\x80\xe5\xa4\x9a\xe6\x94\xaf\xe6\x8c\x81\xe6\x8e\xa5'
                '\xe5\x85\xa5\xc2\xa08\xc2\xa0\xe4\xb8\xaa\xe5\xa4\x96\xe8'
                '\xae\xbe')
            ba.textwidget(parent=self._subcontainer,
                          size=(0, 0),
                          h_align='center',
                          v_align='center',
                          maxwidth=self._sub_width * 0.9,
                          position=(self._sub_width * 0.5, v - 180),
                          text=txtv)
            ba.imagewidget(parent=self._subcontainer,
                           position=(self._sub_width - 320, v - 120),
                           size=(200, 200),
                           texture=ba.gettexture('aliControllerQR'))
            ba.imagewidget(parent=self._subcontainer,
                           position=(90, v - 130),
                           size=(210, 210),
                           texture=ba.gettexture('multiplayerExamples'))
            v -= 120.0

        else:
            v -= spacing * 50.0
            txt = ba.Lstr(resource=self._r + '.someDaysText').evaluate()
            ba.textwidget(parent=self._subcontainer,
                          position=(h, v),
                          size=(0, 0),
                          scale=1.2,
                          maxwidth=self._sub_width * 0.9,
                          text=txt,
                          h_align='center',
                          color=paragraph,
                          v_align='center',
                          flatness=1.0)
            v -= (spacing * 25.0 +
                  get_resource(self._r + '.someDaysExtraSpace'))
            txt_scale = 0.66
            txt = ba.Lstr(resource=self._r +
                          '.orPunchingSomethingText').evaluate()
            ba.textwidget(parent=self._subcontainer,
                          position=(h, v),
                          size=(0, 0),
                          scale=txt_scale,
                          maxwidth=self._sub_width * 0.9,
                          text=txt,
                          h_align='center',
                          color=paragraph,
                          v_align='center',
                          flatness=1.0)
            v -= (spacing * 27.0 +
                  get_resource(self._r + '.orPunchingSomethingExtraSpace'))
            txt_scale = 1.0
            txt = ba.Lstr(resource=self._r + '.canHelpText',
                          subs=[('${APP_NAME}', ba.Lstr(resource='titleText'))
                                ]).evaluate()
            ba.textwidget(parent=self._subcontainer,
                          position=(h, v),
                          size=(0, 0),
                          scale=txt_scale,
                          flatness=1.0,
                          text=txt,
                          h_align='center',
                          color=paragraph,
                          v_align='center')

            v -= spacing * 70.0
            txt_scale = 1.0
            txt = ba.Lstr(resource=self._r + '.toGetTheMostText').evaluate()
            ba.textwidget(parent=self._subcontainer,
                          position=(h, v),
                          size=(0, 0),
                          scale=txt_scale,
                          maxwidth=self._sub_width * 0.9,
                          text=txt,
                          h_align='center',
                          color=header,
                          v_align='center',
                          flatness=1.0)

            v -= spacing * 40.0
            txt_scale = 0.74
            txt = ba.Lstr(resource=self._r + '.friendsText').evaluate()
            hval2 = h - 220
            ba.textwidget(parent=self._subcontainer,
                          position=(hval2, v),
                          size=(0, 0),
                          scale=txt_scale,
                          maxwidth=100,
                          text=txt,
                          h_align='right',
                          color=header,
                          v_align='center',
                          flatness=1.0)

            txt = ba.Lstr(resource=self._r + '.friendsGoodText',
                          subs=[('${APP_NAME}', ba.Lstr(resource='titleText'))
                                ]).evaluate()
            txt_scale = 0.7
            ba.textwidget(parent=self._subcontainer,
                          position=(hval2 + 10, v + 8),
                          size=(0, 0),
                          scale=txt_scale,
                          maxwidth=500,
                          text=txt,
                          h_align='left',
                          color=paragraph,
                          flatness=1.0)

            app = ba.app

            v -= spacing * 45.0
            txt = (ba.Lstr(resource=self._r + '.devicesText').evaluate()
                   if app.vr_mode else ba.Lstr(resource=self._r +
                                               '.controllersText').evaluate())
            txt_scale = 0.74
            hval2 = h - 220
            ba.textwidget(parent=self._subcontainer,
                          position=(hval2, v),
                          size=(0, 0),
                          scale=txt_scale,
                          maxwidth=100,
                          text=txt,
                          h_align='right',
                          color=header,
                          v_align='center',
                          flatness=1.0)

            txt_scale = 0.7
            if not app.vr_mode:
                txt = ba.Lstr(resource=self._r + '.controllersInfoText',
                              subs=[('${APP_NAME}',
                                     ba.Lstr(resource='titleText')),
                                    ('${REMOTE_APP_NAME}',
                                     get_remote_app_name())]).evaluate()
            else:
                txt = ba.Lstr(resource=self._r + '.devicesInfoText',
                              subs=[('${APP_NAME}',
                                     ba.Lstr(resource='titleText'))
                                    ]).evaluate()

            ba.textwidget(parent=self._subcontainer,
                          position=(hval2 + 10, v + 8),
                          size=(0, 0),
                          scale=txt_scale,
                          maxwidth=500,
                          max_height=105,
                          text=txt,
                          h_align='left',
                          color=paragraph,
                          flatness=1.0)

        v -= spacing * 150.0

        txt = ba.Lstr(resource=self._r + '.controlsText').evaluate()
        txt_scale = 1.4
        txt_maxwidth = 480
        ba.textwidget(parent=self._subcontainer,
                      position=(h, v),
                      size=(0, 0),
                      scale=txt_scale,
                      flatness=0.5,
                      text=txt,
                      h_align='center',
                      color=header,
                      v_align='center',
                      res_scale=1.5,
                      maxwidth=txt_maxwidth)
        txt_width = min(
            txt_maxwidth,
            _ba.get_string_width(txt, suppress_warning=True) * txt_scale)
        icon_size = 70

        hval2 = h - (txt_width * 0.5 + icon_size * 0.5 * icon_buffer)
        ba.imagewidget(parent=self._subcontainer,
                       size=(icon_size, icon_size),
                       position=(hval2 - 0.5 * icon_size,
                                 v - 0.45 * icon_size),
                       texture=logo_tex)

        v -= spacing * 45.0

        txt_scale = 0.7
        txt = ba.Lstr(resource=self._r + '.controlsSubtitleText',
                      subs=[('${APP_NAME}', ba.Lstr(resource='titleText'))
                            ]).evaluate()
        ba.textwidget(parent=self._subcontainer,
                      position=(h, v),
                      size=(0, 0),
                      scale=txt_scale,
                      maxwidth=self._sub_width * 0.9,
                      flatness=1.0,
                      text=txt,
                      h_align='center',
                      color=paragraph,
                      v_align='center')
        v -= spacing * 160.0

        sep = 70
        icon_size = 100
        # icon_size_2 = 30
        hval2 = h - sep
        vval2 = v
        ba.imagewidget(parent=self._subcontainer,
                       size=(icon_size, icon_size),
                       position=(hval2 - 0.5 * icon_size,
                                 vval2 - 0.5 * icon_size),
                       texture=ba.gettexture('buttonPunch'),
                       color=(1, 0.7, 0.3))

        txt_scale = get_resource(self._r + '.punchInfoTextScale')
        txt = ba.Lstr(resource=self._r + '.punchInfoText').evaluate()
        ba.textwidget(parent=self._subcontainer,
                      position=(h - sep - 185 + 70, v + 120),
                      size=(0, 0),
                      scale=txt_scale,
                      flatness=1.0,
                      text=txt,
                      h_align='center',
                      color=(1, 0.7, 0.3, 1.0),
                      v_align='top')

        hval2 = h + sep
        vval2 = v
        ba.imagewidget(parent=self._subcontainer,
                       size=(icon_size, icon_size),
                       position=(hval2 - 0.5 * icon_size,
                                 vval2 - 0.5 * icon_size),
                       texture=ba.gettexture('buttonBomb'),
                       color=(1, 0.3, 0.3))

        txt = ba.Lstr(resource=self._r + '.bombInfoText').evaluate()
        txt_scale = get_resource(self._r + '.bombInfoTextScale')
        ba.textwidget(parent=self._subcontainer,
                      position=(h + sep + 50 + 60, v - 35),
                      size=(0, 0),
                      scale=txt_scale,
                      flatness=1.0,
                      maxwidth=270,
                      text=txt,
                      h_align='center',
                      color=(1, 0.3, 0.3, 1.0),
                      v_align='top')

        hval2 = h
        vval2 = v + sep
        ba.imagewidget(parent=self._subcontainer,
                       size=(icon_size, icon_size),
                       position=(hval2 - 0.5 * icon_size,
                                 vval2 - 0.5 * icon_size),
                       texture=ba.gettexture('buttonPickUp'),
                       color=(0.5, 0.5, 1))

        txtl = ba.Lstr(resource=self._r + '.pickUpInfoText')
        txt_scale = get_resource(self._r + '.pickUpInfoTextScale')
        ba.textwidget(parent=self._subcontainer,
                      position=(h + 60 + 120, v + sep + 50),
                      size=(0, 0),
                      scale=txt_scale,
                      flatness=1.0,
                      text=txtl,
                      h_align='center',
                      color=(0.5, 0.5, 1, 1.0),
                      v_align='top')

        hval2 = h
        vval2 = v - sep
        ba.imagewidget(parent=self._subcontainer,
                       size=(icon_size, icon_size),
                       position=(hval2 - 0.5 * icon_size,
                                 vval2 - 0.5 * icon_size),
                       texture=ba.gettexture('buttonJump'),
                       color=(0.4, 1, 0.4))

        txt = ba.Lstr(resource=self._r + '.jumpInfoText').evaluate()
        txt_scale = get_resource(self._r + '.jumpInfoTextScale')
        ba.textwidget(parent=self._subcontainer,
                      position=(h - 250 + 75, v - sep - 15 + 30),
                      size=(0, 0),
                      scale=txt_scale,
                      flatness=1.0,
                      text=txt,
                      h_align='center',
                      color=(0.4, 1, 0.4, 1.0),
                      v_align='top')

        txt = ba.Lstr(resource=self._r + '.runInfoText').evaluate()
        txt_scale = get_resource(self._r + '.runInfoTextScale')
        ba.textwidget(parent=self._subcontainer,
                      position=(h, v - sep - 100),
                      size=(0, 0),
                      scale=txt_scale,
                      maxwidth=self._sub_width * 0.93,
                      flatness=1.0,
                      text=txt,
                      h_align='center',
                      color=(0.7, 0.7, 1.0, 1.0),
                      v_align='center')

        v -= spacing * 280.0

        txt = ba.Lstr(resource=self._r + '.powerupsText').evaluate()
        txt_scale = 1.4
        txt_maxwidth = 480
        ba.textwidget(parent=self._subcontainer,
                      position=(h, v),
                      size=(0, 0),
                      scale=txt_scale,
                      flatness=0.5,
                      text=txt,
                      h_align='center',
                      color=header,
                      v_align='center',
                      maxwidth=txt_maxwidth)
        txt_width = min(
            txt_maxwidth,
            _ba.get_string_width(txt, suppress_warning=True) * txt_scale)
        icon_size = 70
        hval2 = h - (txt_width * 0.5 + icon_size * 0.5 * icon_buffer)
        ba.imagewidget(parent=self._subcontainer,
                       size=(icon_size, icon_size),
                       position=(hval2 - 0.5 * icon_size,
                                 v - 0.45 * icon_size),
                       texture=logo_tex)

        v -= spacing * 50.0
        txt_scale = get_resource(self._r + '.powerupsSubtitleTextScale')
        txt = ba.Lstr(resource=self._r + '.powerupsSubtitleText').evaluate()
        ba.textwidget(parent=self._subcontainer,
                      position=(h, v),
                      size=(0, 0),
                      scale=txt_scale,
                      maxwidth=self._sub_width * 0.9,
                      text=txt,
                      h_align='center',
                      color=paragraph,
                      v_align='center',
                      flatness=1.0)

        v -= spacing * 1.0

        mm1 = -270
        mm2 = -215
        mm3 = 0
        icon_size = 50
        shadow_size = 80
        shadow_offs_x = 3
        shadow_offs_y = -4
        t_big = 1.1
        t_small = 0.65

        shadow_tex = ba.gettexture('shadowSharp')

        for tex in [
                'powerupPunch', 'powerupShield', 'powerupBomb',
                'powerupHealth', 'powerupIceBombs', 'powerupImpactBombs',
                'powerupStickyBombs', 'powerupLandMines', 'powerupCurse'
        ]:
            name = ba.Lstr(resource=self._r + '.' + tex + 'NameText')
            desc = ba.Lstr(resource=self._r + '.' + tex + 'DescriptionText')

            v -= spacing * 60.0

            ba.imagewidget(
                parent=self._subcontainer,
                size=(shadow_size, shadow_size),
                position=(h + mm1 + shadow_offs_x - 0.5 * shadow_size,
                          v + shadow_offs_y - 0.5 * shadow_size),
                texture=shadow_tex,
                color=(0, 0, 0),
                opacity=0.5)
            ba.imagewidget(parent=self._subcontainer,
                           size=(icon_size, icon_size),
                           position=(h + mm1 - 0.5 * icon_size,
                                     v - 0.5 * icon_size),
                           texture=ba.gettexture(tex))

            txt_scale = t_big
            txtl = name
            ba.textwidget(parent=self._subcontainer,
                          position=(h + mm2, v + 3),
                          size=(0, 0),
                          scale=txt_scale,
                          maxwidth=200,
                          flatness=1.0,
                          text=txtl,
                          h_align='left',
                          color=header2,
                          v_align='center')
            txt_scale = t_small
            txtl = desc
            ba.textwidget(parent=self._subcontainer,
                          position=(h + mm3, v),
                          size=(0, 0),
                          scale=txt_scale,
                          maxwidth=300,
                          flatness=1.0,
                          text=txtl,
                          h_align='left',
                          color=paragraph,
                          v_align='center',
                          res_scale=0.5)
Esempio n. 10
0
File: menu.py Progetto: BombDash/bap
    def __init__(self,
                 transition: Optional[str] = 'in_right',
                 origin_widget: ba.Widget = None):
        # pylint: disable=too-many-locals
        # pylint: disable=too-many-statements
        ba.set_analytics_screen('Bapman Window')
        scale_origin: Optional[Tuple[float, float]]
        if origin_widget is not None:
            self._transition_out = 'out_scale'
            scale_origin = origin_widget.get_screen_space_center()
            transition = 'in_scale'
        else:
            self._transition_out = 'out_right'
            scale_origin = None
        width = 900 if ba.app.small_ui else 580
        x_inset = 75 if ba.app.small_ui else 0
        height = 435
        # button_height = 42
        self._r = 'bapmanWindow'
        top_extra = 20 if ba.app.small_ui else 0

        super().__init__(root_widget=ba.containerwidget(
            size=(width, height + top_extra),
            transition=transition,
            toolbar_visibility='menu_minimal',
            scale_origin_stack_offset=scale_origin,
            scale=(
                1.75 if ba.app.small_ui else 1.35 if ba.app.med_ui else 1.0),
            stack_offset=(0, -8) if ba.app.small_ui else (0, 0)))

        if ba.app.toolbars and ba.app.small_ui:
            self._back_button = None
            ba.containerwidget(edit=self._root_widget,
                               on_cancel_call=self._do_back)
        else:
            self._back_button = btn = ba.buttonwidget(
                parent=self._root_widget,
                autoselect=True,
                position=(40 + x_inset, height - 55),
                size=(130, 60),
                scale=0.8,
                text_scale=1.2,
                label=ba.Lstr(resource='backText'),
                button_type='back',
                on_activate_call=self._do_back)
            ba.containerwidget(edit=self._root_widget, cancel_button=btn)

        ba.textwidget(
            parent=self._root_widget,
            position=(0, height - 44),
            size=(width, 25),
            # text=ba.Lstr(resource=self._r + '.titleText'),  # FIXME
            text='Bapman',
            color=ba.app.title_color,
            h_align='center',
            v_align='center',
            maxwidth=130)

        if self._back_button is not None:
            ba.buttonwidget(edit=self._back_button,
                            button_type='backSmall',
                            size=(60, 60),
                            label=ba.charstr(ba.SpecialChar.BACK))

        v = height - 80
        v -= 145

        basew = 280 if ba.app.small_ui else 230
        baseh = 170
        x_offs = x_inset + (105
                            if ba.app.small_ui else 72) - basew  # now unused
        x_offs2 = x_offs + basew - 7
        x_offs3 = x_offs + 2 * (basew - 7)
        x_offs4 = x_offs2
        x_offs5 = x_offs3

        def _b_title(x: float, y: float, button: ba.Widget,
                     text: Union[str, ba.Lstr]) -> None:
            ba.textwidget(parent=self._root_widget,
                          text=text,
                          position=(x + basew * 0.47, y + baseh * 0.22),
                          maxwidth=basew * 0.7,
                          size=(0, 0),
                          h_align='center',
                          v_align='center',
                          draw_controller=button,
                          color=(0.7, 0.9, 0.7, 1.0))

        ctb = self._browse_installed_button = ba.buttonwidget(
            parent=self._root_widget,
            autoselect=True,
            position=(x_offs2, v),
            size=(basew, baseh),
            button_type='square',
            label='',
            on_activate_call=self._do_browse_installed)
        if ba.app.toolbars and self._back_button is None:
            bbtn = _ba.get_special_widget('back_button')
            ba.widget(edit=ctb, left_widget=bbtn)
        _b_title(
            x_offs2,
            v,
            ctb,
            # ba.Lstr(resource=self._r + '.browseInstalledText')  # FIXME
            "Installed")
        imgw = imgh = 130
        ba.imagewidget(parent=self._root_widget,
                       position=(x_offs2 + basew * 0.49 - imgw * 0.5, v + 35),
                       size=(imgw, imgh),
                       color=(0.4, 0.5, 1.0),
                       texture=ba.gettexture('folder'),
                       draw_controller=ctb)

        gfxb = self._search_button = ba.buttonwidget(
            parent=self._root_widget,
            autoselect=True,
            position=(x_offs3, v),
            size=(basew, baseh),
            button_type='square',
            label='',
            on_activate_call=self._do_search)
        if ba.app.toolbars:
            pbtn = _ba.get_special_widget('party_button')
            ba.widget(edit=gfxb, up_widget=pbtn, right_widget=pbtn)
        _b_title(
            x_offs3,
            v,
            gfxb,
            # ba.Lstr(resource=self._r + '.searchText')  # FIXME
            'Search new packages')
        imgw = imgh = 110
        ba.imagewidget(parent=self._root_widget,
                       position=(x_offs3 + basew * 0.49 - imgw * 0.5, v + 42),
                       size=(imgw, imgh),
                       texture=ba.gettexture('downButton'),
                       draw_controller=gfxb)

        v -= (baseh - 5)

        abtn = self._install_local_button = ba.buttonwidget(
            parent=self._root_widget,
            autoselect=True,
            position=(x_offs4, v),
            size=(basew, baseh),
            button_type='square',
            label='',
            on_activate_call=self._do_install_local)
        _b_title(
            x_offs4,
            v,
            abtn,
            # ba.Lstr(resource=self._r + '.installLocalText')  # FIXME
            'Install local package')
        imgw = imgh = 120
        ba.imagewidget(parent=self._root_widget,
                       position=(x_offs4 + basew * 0.49 - imgw * 0.5 + 5,
                                 v + 35),
                       size=(imgw, imgh),
                       color=(1, 1, 1),
                       texture=ba.gettexture('file'),
                       draw_controller=abtn)

        avb = self._browse_repos_button = ba.buttonwidget(
            parent=self._root_widget,
            autoselect=True,
            position=(x_offs5, v),
            size=(basew, baseh),
            button_type='square',
            label='',
            on_activate_call=self._do_browse_repos)
        _b_title(
            x_offs5,
            v,
            avb,
            # ba.Lstr(resource=self._r + '.browseReposText')  # FIXME
            'Repositories')
        imgw = imgh = 120
        ba.imagewidget(parent=self._root_widget,
                       position=(x_offs5 + basew * 0.49 - imgw * 0.5 + 5,
                                 v + 35),
                       size=(imgw, imgh),
                       color=(0.8, 0.95, 1),
                       texture=ba.gettexture('advancedIcon'),
                       draw_controller=avb)
Esempio n. 11
0
    def __init__(self,
                 transition: str = 'in_right',
                 modal: bool = False,
                 origin_widget: ba.Widget = None):
        from ba.internal import get_cached_league_rank_data
        from ba.deprecated import get_resource
        ba.set_analytics_screen('League Rank Window')

        self._league_rank_data: Optional[Dict[str, Any]] = None
        self._modal = modal

        # If they provided an origin-widget, scale up from that.
        scale_origin: Optional[Tuple[float, float]]
        if origin_widget is not None:
            self._transition_out = 'out_scale'
            scale_origin = origin_widget.get_screen_space_center()
            transition = 'in_scale'
        else:
            self._transition_out = 'out_right'
            scale_origin = None

        self._width = 1320 if ba.app.small_ui else 1120
        x_inset = 100 if ba.app.small_ui else 0
        self._height = (657
                        if ba.app.small_ui else 710 if ba.app.med_ui else 800)
        self._r = 'coopSelectWindow'
        self._rdict = get_resource(self._r)
        top_extra = 20 if ba.app.small_ui else 0

        self._league_url_arg = ''

        self._is_current_season = False
        self._can_do_more_button = True

        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height + top_extra),
            stack_offset=(0, -15) if ba.app.small_ui else (
                0, 10) if ba.app.med_ui else (0, 0),
            transition=transition,
            scale_origin_stack_offset=scale_origin,
            scale=(
                1.2 if ba.app.small_ui else 0.93 if ba.app.med_ui else 0.8)))

        self._back_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(75 + x_inset,
                      self._height - 87 - (4 if ba.app.small_ui else 0)),
            size=(120, 60),
            scale=1.2,
            autoselect=True,
            label=ba.Lstr(resource='doneText' if self._modal else 'backText'),
            button_type=None if self._modal else 'back',
            on_activate_call=self._back)

        self._title_text = ba.textwidget(
            parent=self._root_widget,
            position=(self._width * 0.5, self._height - 56),
            size=(0, 0),
            text=ba.Lstr(
                resource='league.leagueRankText',
                fallback_resource='coopSelectWindow.powerRankingText'),
            h_align="center",
            color=ba.app.title_color,
            scale=1.4,
            maxwidth=600,
            v_align="center")

        ba.buttonwidget(edit=btn,
                        button_type='backSmall',
                        position=(75 + x_inset, self._height - 87 -
                                  (2 if ba.app.small_ui else 0)),
                        size=(60, 55),
                        label=ba.charstr(ba.SpecialChar.BACK))

        self._scroll_width = self._width - (130 + 2 * x_inset)
        self._scroll_height = self._height - 160
        self._scrollwidget = ba.scrollwidget(parent=self._root_widget,
                                             highlight=False,
                                             position=(65 + x_inset, 70),
                                             size=(self._scroll_width,
                                                   self._scroll_height),
                                             center_small_content=True)
        ba.widget(edit=self._scrollwidget, autoselect=True)
        ba.containerwidget(edit=self._scrollwidget, claims_left_right=True)
        ba.containerwidget(edit=self._root_widget,
                           cancel_button=self._back_button,
                           selected_child=self._back_button)

        self._last_power_ranking_query_time: Optional[float] = None
        self._doing_power_ranking_query = False

        self._subcontainer: Optional[ba.Widget] = None
        self._subcontainerwidth = 800
        self._subcontainerheight = 483
        self._power_ranking_score_widgets: List[ba.Widget] = []

        self._season_popup_menu: Optional[popup_ui.PopupMenu] = None
        self._requested_season: Optional[str] = None
        self._season: Optional[str] = None

        # take note of our account state; we'll refresh later if this changes
        self._account_state = _ba.get_account_state()

        self._refresh()
        self._restore_state()

        # if we've got cached power-ranking data already, display it
        info = get_cached_league_rank_data()
        if info is not None:
            self._update_for_league_rank_data(info)

        self._update_timer = ba.Timer(1.0,
                                      ba.WeakCall(self._update),
                                      timetype=ba.TimeType.REAL,
                                      repeat=True)
        self._update(show=(info is None))
Esempio n. 12
0
    def __init__(self,
                 transition: Optional[str] = 'in_right',
                 origin_widget: ba.Widget = None):
        # pylint: disable=too-many-locals
        # pylint: disable=too-many-statements
        from bastd.ui.tabs import TabRow
        ba.set_analytics_screen('Watch Window')
        scale_origin: Optional[Tuple[float, float]]
        if origin_widget is not None:
            self._transition_out = 'out_scale'
            scale_origin = origin_widget.get_screen_space_center()
            transition = 'in_scale'
        else:
            self._transition_out = 'out_right'
            scale_origin = None
        ba.app.ui.set_main_menu_location('Watch')
        self._tab_data: Dict[str, Any] = {}
        self._my_replays_scroll_width: Optional[float] = None
        self._my_replays_watch_replay_button: Optional[ba.Widget] = None
        self._scrollwidget: Optional[ba.Widget] = None
        self._columnwidget: Optional[ba.Widget] = None
        self._my_replay_selected: Optional[str] = None
        self._my_replays_rename_window: Optional[ba.Widget] = None
        self._my_replay_rename_text: Optional[ba.Widget] = None
        self._r = 'watchWindow'
        uiscale = ba.app.ui.uiscale
        self._width = 1240 if uiscale is ba.UIScale.SMALL else 1040
        x_inset = 100 if uiscale is ba.UIScale.SMALL else 0
        self._height = (578 if uiscale is ba.UIScale.SMALL else
                        670 if uiscale is ba.UIScale.MEDIUM else 800)
        self._current_tab: Optional[WatchWindow.TabID] = None
        extra_top = 20 if uiscale is ba.UIScale.SMALL else 0

        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height + extra_top),
            transition=transition,
            toolbar_visibility='menu_minimal',
            scale_origin_stack_offset=scale_origin,
            scale=(1.3 if uiscale is ba.UIScale.SMALL else
                   0.97 if uiscale is ba.UIScale.MEDIUM else 0.8),
            stack_offset=(0, -10) if uiscale is ba.UIScale.SMALL else (
                0, 15) if uiscale is ba.UIScale.MEDIUM else (0, 0)))

        if uiscale is ba.UIScale.SMALL and ba.app.ui.use_toolbars:
            ba.containerwidget(edit=self._root_widget,
                               on_cancel_call=self._back)
            self._back_button = None
        else:
            self._back_button = btn = ba.buttonwidget(
                parent=self._root_widget,
                autoselect=True,
                position=(70 + x_inset, self._height - 74),
                size=(140, 60),
                scale=1.1,
                label=ba.Lstr(resource='backText'),
                button_type='back',
                on_activate_call=self._back)
            ba.containerwidget(edit=self._root_widget, cancel_button=btn)
            ba.buttonwidget(edit=btn,
                            button_type='backSmall',
                            size=(60, 60),
                            label=ba.charstr(ba.SpecialChar.BACK))

        ba.textwidget(parent=self._root_widget,
                      position=(self._width * 0.5, self._height - 38),
                      size=(0, 0),
                      color=ba.app.ui.title_color,
                      scale=1.5,
                      h_align='center',
                      v_align='center',
                      text=ba.Lstr(resource=self._r + '.titleText'),
                      maxwidth=400)

        tabdefs = [
            (self.TabID.MY_REPLAYS,
             ba.Lstr(resource=self._r + '.myReplaysText')),
            # (self.TabID.TEST_TAB, ba.Lstr(value='Testing')),
        ]

        scroll_buffer_h = 130 + 2 * x_inset
        tab_buffer_h = 750 + 2 * x_inset

        self._tab_row = TabRow(self._root_widget,
                               tabdefs,
                               pos=(tab_buffer_h * 0.5, self._height - 130),
                               size=(self._width - tab_buffer_h, 50),
                               on_select_call=self._set_tab)

        if ba.app.ui.use_toolbars:
            first_tab = self._tab_row.tabs[tabdefs[0][0]]
            last_tab = self._tab_row.tabs[tabdefs[-1][0]]
            ba.widget(edit=last_tab.button,
                      right_widget=_ba.get_special_widget('party_button'))
            if uiscale is ba.UIScale.SMALL:
                bbtn = _ba.get_special_widget('back_button')
                ba.widget(edit=first_tab.button,
                          up_widget=bbtn,
                          left_widget=bbtn)

        self._scroll_width = self._width - scroll_buffer_h
        self._scroll_height = self._height - 180

        # Not actually using a scroll widget anymore; just an image.
        scroll_left = (self._width - self._scroll_width) * 0.5
        scroll_bottom = self._height - self._scroll_height - 79 - 48
        buffer_h = 10
        buffer_v = 4
        ba.imagewidget(parent=self._root_widget,
                       position=(scroll_left - buffer_h,
                                 scroll_bottom - buffer_v),
                       size=(self._scroll_width + 2 * buffer_h,
                             self._scroll_height + 2 * buffer_v),
                       texture=ba.gettexture('scrollWidget'),
                       model_transparent=ba.getmodel('softEdgeOutside'))
        self._tab_container: Optional[ba.Widget] = None

        self._restore_state()
Esempio n. 13
0
    def __init__(self, origin_widget: ba.Widget = None):
        # pylint: disable=too-many-locals
        # pylint: disable=too-many-statements
        import json
        ba.set_analytics_screen('Credits Window')

        # if they provided an origin-widget, scale up from that
        scale_origin: Optional[Tuple[float, float]]
        if origin_widget is not None:
            self._transition_out = 'out_scale'
            scale_origin = origin_widget.get_screen_space_center()
            transition = 'in_scale'
        else:
            self._transition_out = 'out_right'
            scale_origin = None
            transition = 'in_right'

        uiscale = ba.app.uiscale
        width = 870 if uiscale is ba.UIScale.SMALL else 670
        x_inset = 100 if uiscale is ba.UIScale.SMALL else 0
        height = 398 if uiscale is ba.UIScale.SMALL else 500

        self._r = 'creditsWindow'
        super().__init__(root_widget=ba.containerwidget(
            size=(width, height),
            transition=transition,
            toolbar_visibility='menu_minimal',
            scale_origin_stack_offset=scale_origin,
            scale=(2.0 if uiscale is ba.UIScale.SMALL else
                   1.3 if uiscale is ba.UIScale.MEDIUM else 1.0),
            stack_offset=(0, -8) if uiscale is ba.UIScale.SMALL else (0, 0)))

        if ba.app.ui.use_toolbars and uiscale is ba.UIScale.SMALL:
            ba.containerwidget(edit=self._root_widget,
                               on_cancel_call=self._back)
        else:
            btn = ba.buttonwidget(
                parent=self._root_widget,
                position=(40 + x_inset, height -
                          (68 if uiscale is ba.UIScale.SMALL else 62)),
                size=(140, 60),
                scale=0.8,
                label=ba.Lstr(resource='backText'),
                button_type='back',
                on_activate_call=self._back,
                autoselect=True)
            ba.containerwidget(edit=self._root_widget, cancel_button=btn)

            ba.buttonwidget(
                edit=btn,
                button_type='backSmall',
                position=(40 + x_inset, height -
                          (68 if uiscale is ba.UIScale.SMALL else 62) + 5),
                size=(60, 48),
                label=ba.charstr(ba.SpecialChar.BACK))

        ba.textwidget(parent=self._root_widget,
                      position=(0, height -
                                (59 if uiscale is ba.UIScale.SMALL else 54)),
                      size=(width, 30),
                      text=ba.Lstr(resource=self._r + '.titleText',
                                   subs=[('${APP_NAME}',
                                          ba.Lstr(resource='titleText'))]),
                      h_align='center',
                      color=ba.app.ui.title_color,
                      maxwidth=330,
                      v_align='center')

        scroll = ba.scrollwidget(parent=self._root_widget,
                                 position=(40 + x_inset, 35),
                                 size=(width - (80 + 2 * x_inset),
                                       height - 100),
                                 capture_arrows=True)

        if ba.app.ui.use_toolbars:
            ba.widget(edit=scroll,
                      right_widget=_ba.get_special_widget('party_button'))
            if uiscale is ba.UIScale.SMALL:
                ba.widget(edit=scroll,
                          left_widget=_ba.get_special_widget('back_button'))

        def _format_names(names2: Sequence[str], inset: float) -> str:
            sval = ''
            # measure a series since there's overlaps and stuff..
            space_width = _ba.get_string_width(' ' * 10,
                                               suppress_warning=True) / 10.0
            spacing = 330.0
            col1 = inset
            col2 = col1 + spacing
            col3 = col2 + spacing
            line_width = 0.0
            nline = ''
            for name in names2:
                # move to the next column (or row) and print
                if line_width > col3:
                    sval += nline + '\n'
                    nline = ''
                    line_width = 0

                if line_width > col2:
                    target = col3
                elif line_width > col1:
                    target = col2
                else:
                    target = col1
                spacingstr = ' ' * int((target - line_width) / space_width)
                nline += spacingstr
                nline += name
                line_width = _ba.get_string_width(nline, suppress_warning=True)
            if nline != '':
                sval += nline + '\n'
            return sval

        sound_and_music = ba.Lstr(resource=self._r +
                                  '.songCreditText').evaluate()
        sound_and_music = sound_and_music.replace(
            '${TITLE}', "'William Tell (Trumpet Entry)'")
        sound_and_music = sound_and_music.replace(
            '${PERFORMER}', 'The Apollo Symphony Orchestra')
        sound_and_music = sound_and_music.replace(
            '${PERFORMER}', 'The Apollo Symphony Orchestra')
        sound_and_music = sound_and_music.replace('${COMPOSER}',
                                                  'Gioacchino Rossini')
        sound_and_music = sound_and_music.replace('${ARRANGER}', 'Chris Worth')
        sound_and_music = sound_and_music.replace('${PUBLISHER}', 'BMI')
        sound_and_music = sound_and_music.replace('${SOURCE}',
                                                  'www.AudioSparx.com')
        spc = '     '
        sound_and_music = spc + sound_and_music.replace('\n', '\n' + spc)
        names = [
            'HubOfTheUniverseProd', 'Jovica', 'LG', 'Leady', 'Percy Duke',
            'PhreaKsAccount', 'Pogotron', 'Rock Savage', 'anamorphosis',
            'benboncan', 'cdrk', 'chipfork', 'guitarguy1985', 'jascha',
            'joedeshon', 'loofa', 'm_O_m', 'mich3d', 'sandyrb', 'shakaharu',
            'sirplus', 'stickman', 'thanvannispen', 'virotic', 'zimbot'
        ]
        names.sort(key=lambda x: x.lower())
        freesound_names = _format_names(names, 90)

        try:
            with open('ba_data/data/langdata.json') as infile:
                translation_contributors = (json.loads(
                    infile.read())['translation_contributors'])
        except Exception:
            ba.print_exception('Error reading translation contributors.')
            translation_contributors = []

        translation_names = _format_names(translation_contributors, 60)

        # Need to bake this out and chop it up since we're passing our
        # 65535 vertex limit for meshes..
        # We can remove that limit once we drop support for GL ES2.. :-/
        # (or add mesh splitting under the hood)
        credits_text = (
            '  ' + ba.Lstr(resource=self._r +
                           '.codingGraphicsAudioText').evaluate().replace(
                               '${NAME}', 'Eric Froemling') + '\n'
            '\n'
            '  ' + ba.Lstr(resource=self._r +
                           '.additionalAudioArtIdeasText').evaluate().replace(
                               '${NAME}', 'Raphael Suter') + '\n'
            '\n'
            '  ' +
            ba.Lstr(resource=self._r + '.soundAndMusicText').evaluate() + '\n'
            '\n' + sound_and_music + '\n'
            '\n'
            '     ' + ba.Lstr(resource=self._r +
                              '.publicDomainMusicViaText').evaluate().replace(
                                  '${NAME}', 'Musopen.com') + '\n'
            '        ' +
            ba.Lstr(resource=self._r +
                    '.thanksEspeciallyToText').evaluate().replace(
                        '${NAME}', 'the US Army, Navy, and Marine Bands') +
            '\n'
            '\n'
            '     ' + ba.Lstr(resource=self._r +
                              '.additionalMusicFromText').evaluate().replace(
                                  '${NAME}', 'The YouTube Audio Library') +
            '\n'
            '\n'
            '     ' +
            ba.Lstr(resource=self._r + '.soundsText').evaluate().replace(
                '${SOURCE}', 'Freesound.org') + '\n'
            '\n' + freesound_names + '\n'
            '\n'
            '  ' + ba.Lstr(resource=self._r +
                           '.languageTranslationsText').evaluate() + '\n'
            '\n' + '\n'.join(translation_names.splitlines()[:146]) +
            '\n'.join(translation_names.splitlines()[146:]) + '\n'
            '\n'
            '  Shout Out to Awesome Mods / Modders:\n\n'
            '     BombDash ModPack\n'
            '     TheMikirog & SoK - BombSquad Joyride Modpack\n'
            '     Mrmaxmeier - BombSquad-Community-Mod-Manager\n'
            '\n'
            '  Holiday theme vector art designed by Freepik\n'
            '\n'
            '  ' +
            ba.Lstr(resource=self._r + '.specialThanksText').evaluate() + '\n'
            '\n'
            '     Todd, Laura, and Robert Froemling\n'
            '     ' +
            ba.Lstr(resource=self._r + '.allMyFamilyText').evaluate().replace(
                '\n', '\n     ') + '\n'
            '     ' + ba.Lstr(resource=self._r +
                              '.whoeverInventedCoffeeText').evaluate() + '\n'
            '\n'
            '  ' + ba.Lstr(resource=self._r + '.legalText').evaluate() + '\n'
            '\n'
            '     ' + ba.Lstr(resource=self._r +
                              '.softwareBasedOnText').evaluate().replace(
                                  '${NAME}', 'the Khronos Group') + '\n'
            '\n'
            '                                       '
            '                      www.froemling.net\n')

        txt = credits_text
        lines = txt.splitlines()
        line_height = 20

        scale = 0.55
        self._sub_width = width - 80
        self._sub_height = line_height * len(lines) + 40

        container = self._subcontainer = ba.containerwidget(
            parent=scroll,
            size=(self._sub_width, self._sub_height),
            background=False,
            claims_left_right=False,
            claims_tab=False)

        voffs = 0
        for line in lines:
            ba.textwidget(parent=container,
                          padding=4,
                          color=(0.7, 0.9, 0.7, 1.0),
                          scale=scale,
                          flatness=1.0,
                          size=(0, 0),
                          position=(0, self._sub_height - 20 + voffs),
                          h_align='left',
                          v_align='top',
                          text=ba.Lstr(value=line))
            voffs -= line_height
Esempio n. 14
0
    def __init__(self,
                 transition: Optional[str] = 'in_right',
                 origin_widget: ba.Widget = None):
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-locals
        # pylint: disable=cyclic-import
        from bastd.ui.gather.abouttab import AboutGatherTab
        from bastd.ui.gather.manualtab import ManualGatherTab
        from bastd.ui.gather.privatetab import PrivateGatherTab
        from bastd.ui.gather.publictab import PublicGatherTab
        from bastd.ui.gather.nearbytab import NearbyGatherTab

        ba.set_analytics_screen('Gather Window')
        scale_origin: Optional[tuple[float, float]]
        if origin_widget is not None:
            self._transition_out = 'out_scale'
            scale_origin = origin_widget.get_screen_space_center()
            transition = 'in_scale'
        else:
            self._transition_out = 'out_right'
            scale_origin = None
        ba.app.ui.set_main_menu_location('Gather')
        _ba.set_party_icon_always_visible(True)
        uiscale = ba.app.ui.uiscale
        self._width = 1240 if uiscale is ba.UIScale.SMALL else 1040
        x_offs = 100 if uiscale is ba.UIScale.SMALL else 0
        self._height = (582 if uiscale is ba.UIScale.SMALL else
                        680 if uiscale is ba.UIScale.MEDIUM else 800)
        self._current_tab: Optional[GatherWindow.TabID] = None
        extra_top = 20 if uiscale is ba.UIScale.SMALL else 0
        self._r = 'gatherWindow'

        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height + extra_top),
            transition=transition,
            toolbar_visibility='menu_minimal',
            scale_origin_stack_offset=scale_origin,
            scale=(1.3 if uiscale is ba.UIScale.SMALL else
                   0.97 if uiscale is ba.UIScale.MEDIUM else 0.8),
            stack_offset=(0, -11) if uiscale is ba.UIScale.SMALL else (
                0, 0) if uiscale is ba.UIScale.MEDIUM else (0, 0)))

        if uiscale is ba.UIScale.SMALL and ba.app.ui.use_toolbars:
            ba.containerwidget(edit=self._root_widget,
                               on_cancel_call=self._back)
            self._back_button = None
        else:
            self._back_button = btn = ba.buttonwidget(
                parent=self._root_widget,
                position=(70 + x_offs, self._height - 74),
                size=(140, 60),
                scale=1.1,
                autoselect=True,
                label=ba.Lstr(resource='backText'),
                button_type='back',
                on_activate_call=self._back)
            ba.containerwidget(edit=self._root_widget, cancel_button=btn)
            ba.buttonwidget(edit=btn,
                            button_type='backSmall',
                            position=(70 + x_offs, self._height - 78),
                            size=(60, 60),
                            label=ba.charstr(ba.SpecialChar.BACK))

        condensed = uiscale is not ba.UIScale.LARGE
        t_offs_y = (0 if not condensed else
                    25 if uiscale is ba.UIScale.MEDIUM else 17)
        ba.textwidget(parent=self._root_widget,
                      position=(self._width * 0.5,
                                self._height - 42 + t_offs_y),
                      size=(0, 0),
                      color=ba.app.ui.title_color,
                      scale=(1.5 if not condensed else
                             1.0 if uiscale is ba.UIScale.MEDIUM else 0.6),
                      h_align='center',
                      v_align='center',
                      text=ba.Lstr(resource=self._r + '.titleText'),
                      maxwidth=550)

        scroll_buffer_h = 130 + 2 * x_offs
        tab_buffer_h = ((320 if condensed else 250) + 2 * x_offs)

        # Build up the set of tabs we want.
        tabdefs: list[tuple[GatherWindow.TabID, ba.Lstr]] = [
            (self.TabID.ABOUT, ba.Lstr(resource=self._r + '.aboutText'))
        ]
        if _ba.get_account_misc_read_val('enablePublicParties', True):
            tabdefs.append((self.TabID.INTERNET,
                            ba.Lstr(resource=self._r + '.publicText')))
        tabdefs.append(
            (self.TabID.PRIVATE, ba.Lstr(resource=self._r + '.privateText')))
        tabdefs.append(
            (self.TabID.NEARBY, ba.Lstr(resource=self._r + '.nearbyText')))
        tabdefs.append(
            (self.TabID.MANUAL, ba.Lstr(resource=self._r + '.manualText')))

        # On small UI, push our tabs up closer to the top of the screen to
        # save a bit of space.
        tabs_top_extra = 42 if condensed else 0
        self._tab_row = TabRow(self._root_widget,
                               tabdefs,
                               pos=(tab_buffer_h * 0.5,
                                    self._height - 130 + tabs_top_extra),
                               size=(self._width - tab_buffer_h, 50),
                               on_select_call=ba.WeakCall(self._set_tab))

        # Now instantiate handlers for these tabs.
        tabtypes: dict[GatherWindow.TabID, type[GatherTab]] = {
            self.TabID.ABOUT: AboutGatherTab,
            self.TabID.MANUAL: ManualGatherTab,
            self.TabID.PRIVATE: PrivateGatherTab,
            self.TabID.INTERNET: PublicGatherTab,
            self.TabID.NEARBY: NearbyGatherTab
        }
        self._tabs: dict[GatherWindow.TabID, GatherTab] = {}
        for tab_id in self._tab_row.tabs:
            tabtype = tabtypes.get(tab_id)
            if tabtype is not None:
                self._tabs[tab_id] = tabtype(self)

        if ba.app.ui.use_toolbars:
            ba.widget(edit=self._tab_row.tabs[tabdefs[-1][0]].button,
                      right_widget=_ba.get_special_widget('party_button'))
            if uiscale is ba.UIScale.SMALL:
                ba.widget(edit=self._tab_row.tabs[tabdefs[0][0]].button,
                          left_widget=_ba.get_special_widget('back_button'))

        self._scroll_width = self._width - scroll_buffer_h
        self._scroll_height = self._height - 180.0 + tabs_top_extra

        self._scroll_left = (self._width - self._scroll_width) * 0.5
        self._scroll_bottom = (self._height - self._scroll_height - 79 - 48 +
                               tabs_top_extra)
        buffer_h = 10
        buffer_v = 4

        # Not actually using a scroll widget anymore; just an image.
        ba.imagewidget(parent=self._root_widget,
                       position=(self._scroll_left - buffer_h,
                                 self._scroll_bottom - buffer_v),
                       size=(self._scroll_width + 2 * buffer_h,
                             self._scroll_height + 2 * buffer_v),
                       texture=ba.gettexture('scrollWidget'),
                       model_transparent=ba.getmodel('softEdgeOutside'))
        self._tab_container: Optional[ba.Widget] = None

        self._restore_state()
Esempio n. 15
0
    def on_begin(self) -> None:
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-locals
        # pylint: disable=too-many-statements
        from bastd.actor.text import Text
        from bastd.actor.image import Image
        from ba.deprecated import get_resource
        ba.set_analytics_screen('FreeForAll Series Victory Screen' if self.
                                _is_ffa else 'Teams Series Victory Screen')
        if ba.app.uiscale is ba.UIScale.LARGE:
            sval = ba.Lstr(resource='pressAnyKeyButtonPlayAgainText')
        else:
            sval = ba.Lstr(resource='pressAnyButtonPlayAgainText')
        self._show_up_next = False
        self._custom_continue_message = sval
        super().on_begin()
        winning_sessionteam = self.settings_raw['winner']

        # Pause a moment before playing victory music.
        ba.timer(0.6, ba.WeakCall(self._play_victory_music))
        ba.timer(4.4,
                 ba.WeakCall(self._show_winner, self.settings_raw['winner']))
        ba.timer(4.6, ba.Call(ba.playsound, self._score_display_sound))

        # Score / Name / Player-record.
        player_entries: List[Tuple[int, str, ba.PlayerRecord]] = []

        # Note: for ffa, exclude players who haven't entered the game yet.
        if self._is_ffa:
            for _pkey, prec in self.stats.get_records().items():
                if prec.player.in_game:
                    player_entries.append(
                        (prec.player.sessionteam.customdata['score'],
                         prec.getname(full=True), prec))
            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, key=lambda x: x[0])

        ts_height = 300.0
        ts_h_offs = -390.0
        tval = 6.4
        t_incr = 0.12

        always_use_first_to = get_resource('bestOfUseFirstToInstead')

        session = self.session
        if self._is_ffa:
            assert isinstance(session, ba.FreeForAllSession)
            txt = ba.Lstr(
                value='${A}:',
                subs=[('${A}',
                       ba.Lstr(resource='firstToFinalText',
                               subs=[('${COUNT}',
                                      str(session.get_ffa_series_length()))]))
                      ])
        else:
            assert isinstance(session, ba.MultiTeamSession)

            # Some languages may prefer to always show 'first to X' instead of
            # 'best of X'.
            # FIXME: This will affect all clients connected to us even if
            #  they're not using this language. Should try to come up
            #  with a wording that works everywhere.
            if always_use_first_to:
                txt = ba.Lstr(
                    value='${A}:',
                    subs=[
                        ('${A}',
                         ba.Lstr(resource='firstToFinalText',
                                 subs=[
                                     ('${COUNT}',
                                      str(session.get_series_length() / 2 + 1))
                                 ]))
                    ])
            else:
                txt = ba.Lstr(
                    value='${A}:',
                    subs=[('${A}',
                           ba.Lstr(resource='bestOfFinalText',
                                   subs=[('${COUNT}',
                                          str(session.get_series_length()))]))
                          ])

        Text(txt,
             v_align=Text.VAlign.CENTER,
             maxwidth=300,
             color=(0.5, 0.5, 0.5, 1.0),
             position=(0, 220),
             scale=1.2,
             transition=Text.Transition.IN_TOP_SLOW,
             h_align=Text.HAlign.CENTER,
             transition_delay=t_incr * 4).autoretain()

        win_score = (session.get_series_length() - 1) // 2 + 1
        lose_score = 0
        for team in self.teams:
            if team.sessionteam.customdata['score'] != win_score:
                lose_score = team.sessionteam.customdata['score']

        if not self._is_ffa:
            Text(ba.Lstr(resource='gamesToText',
                         subs=[('${WINCOUNT}', str(win_score)),
                               ('${LOSECOUNT}', str(lose_score))]),
                 color=(0.5, 0.5, 0.5, 1.0),
                 maxwidth=160,
                 v_align=Text.VAlign.CENTER,
                 position=(0, -215),
                 scale=1.8,
                 transition=Text.Transition.IN_LEFT,
                 h_align=Text.HAlign.CENTER,
                 transition_delay=4.8 + t_incr * 4).autoretain()

        if self._is_ffa:
            v_extra = 120
        else:
            v_extra = 0

        mvp: Optional[ba.PlayerRecord] = None
        mvp_name: Optional[str] = None

        # Show game MVP.
        if not self._is_ffa:
            mvp, mvp_name = None, None
            for entry in player_entries:
                if entry[2].team == winning_sessionteam:
                    mvp = entry[2]
                    mvp_name = entry[1]
                    break
            if mvp is not None:
                Text(ba.Lstr(resource='mostValuablePlayerText'),
                     color=(0.5, 0.5, 0.5, 1.0),
                     v_align=Text.VAlign.CENTER,
                     maxwidth=300,
                     position=(180, ts_height / 2 + 15),
                     transition=Text.Transition.IN_LEFT,
                     h_align=Text.HAlign.LEFT,
                     transition_delay=tval).autoretain()
                tval += 4 * t_incr

                Image(mvp.get_icon(),
                      position=(230, ts_height / 2 - 55 + 14 - 5),
                      scale=(70, 70),
                      transition=Image.Transition.IN_LEFT,
                      transition_delay=tval).autoretain()
                assert mvp_name is not None
                Text(ba.Lstr(value=mvp_name),
                     position=(280, ts_height / 2 - 55 + 15 - 5),
                     h_align=Text.HAlign.LEFT,
                     v_align=Text.VAlign.CENTER,
                     maxwidth=170,
                     scale=1.3,
                     color=ba.safecolor(mvp.team.color + (1, )),
                     transition=Text.Transition.IN_LEFT,
                     transition_delay=tval).autoretain()
                tval += 4 * t_incr

        # Most violent.
        most_kills = 0
        for entry in player_entries:
            if entry[2].kill_count >= most_kills:
                mvp = entry[2]
                mvp_name = entry[1]
                most_kills = entry[2].kill_count
        if mvp is not None:
            Text(ba.Lstr(resource='mostViolentPlayerText'),
                 color=(0.5, 0.5, 0.5, 1.0),
                 v_align=Text.VAlign.CENTER,
                 maxwidth=300,
                 position=(180, ts_height / 2 - 150 + v_extra + 15),
                 transition=Text.Transition.IN_LEFT,
                 h_align=Text.HAlign.LEFT,
                 transition_delay=tval).autoretain()
            Text(ba.Lstr(value='(${A})',
                         subs=[('${A}',
                                ba.Lstr(resource='killsTallyText',
                                        subs=[('${COUNT}', str(most_kills))]))
                               ]),
                 position=(260, ts_height / 2 - 150 - 15 + v_extra),
                 color=(0.3, 0.3, 0.3, 1.0),
                 scale=0.6,
                 h_align=Text.HAlign.LEFT,
                 transition=Text.Transition.IN_LEFT,
                 transition_delay=tval).autoretain()
            tval += 4 * t_incr

            Image(mvp.get_icon(),
                  position=(233, ts_height / 2 - 150 - 30 - 46 + 25 + v_extra),
                  scale=(50, 50),
                  transition=Image.Transition.IN_LEFT,
                  transition_delay=tval).autoretain()
            assert mvp_name is not None
            Text(ba.Lstr(value=mvp_name),
                 position=(270, ts_height / 2 - 150 - 30 - 36 + v_extra + 15),
                 h_align=Text.HAlign.LEFT,
                 v_align=Text.VAlign.CENTER,
                 maxwidth=180,
                 color=ba.safecolor(mvp.team.color + (1, )),
                 transition=Text.Transition.IN_LEFT,
                 transition_delay=tval).autoretain()
            tval += 4 * t_incr

        # Most killed.
        most_killed = 0
        mkp, mkp_name = None, None
        for entry in player_entries:
            if entry[2].killed_count >= most_killed:
                mkp = entry[2]
                mkp_name = entry[1]
                most_killed = entry[2].killed_count
        if mkp is not None:
            Text(ba.Lstr(resource='mostViolatedPlayerText'),
                 color=(0.5, 0.5, 0.5, 1.0),
                 v_align=Text.VAlign.CENTER,
                 maxwidth=300,
                 position=(180, ts_height / 2 - 300 + v_extra + 15),
                 transition=Text.Transition.IN_LEFT,
                 h_align=Text.HAlign.LEFT,
                 transition_delay=tval).autoretain()
            Text(ba.Lstr(value='(${A})',
                         subs=[('${A}',
                                ba.Lstr(resource='deathsTallyText',
                                        subs=[('${COUNT}', str(most_killed))]))
                               ]),
                 position=(260, ts_height / 2 - 300 - 15 + v_extra),
                 h_align=Text.HAlign.LEFT,
                 scale=0.6,
                 color=(0.3, 0.3, 0.3, 1.0),
                 transition=Text.Transition.IN_LEFT,
                 transition_delay=tval).autoretain()
            tval += 4 * t_incr
            Image(mkp.get_icon(),
                  position=(233, ts_height / 2 - 300 - 30 - 46 + 25 + v_extra),
                  scale=(50, 50),
                  transition=Image.Transition.IN_LEFT,
                  transition_delay=tval).autoretain()
            assert mkp_name is not None
            Text(ba.Lstr(value=mkp_name),
                 position=(270, ts_height / 2 - 300 - 30 - 36 + v_extra + 15),
                 h_align=Text.HAlign.LEFT,
                 v_align=Text.VAlign.CENTER,
                 color=ba.safecolor(mkp.team.color + (1, )),
                 maxwidth=180,
                 transition=Text.Transition.IN_LEFT,
                 transition_delay=tval).autoretain()
            tval += 4 * t_incr

        # Now show individual scores.
        tdelay = tval
        Text(ba.Lstr(resource='finalScoresText'),
             color=(0.5, 0.5, 0.5, 1.0),
             position=(ts_h_offs, ts_height / 2),
             transition=Text.Transition.IN_RIGHT,
             transition_delay=tdelay).autoretain()
        tdelay += 4 * t_incr

        v_offs = 0.0
        tdelay += len(player_entries) * 8 * t_incr
        for _score, name, prec in player_entries:
            tdelay -= 4 * t_incr
            v_offs -= 40
            Text(str(prec.team.customdata['score'])
                 if self._is_ffa else str(prec.score),
                 color=(0.5, 0.5, 0.5, 1.0),
                 position=(ts_h_offs + 230, ts_height / 2 + v_offs),
                 h_align=Text.HAlign.RIGHT,
                 transition=Text.Transition.IN_RIGHT,
                 transition_delay=tdelay).autoretain()
            tdelay -= 4 * t_incr

            Image(prec.get_icon(),
                  position=(ts_h_offs - 72, ts_height / 2 + v_offs + 15),
                  scale=(30, 30),
                  transition=Image.Transition.IN_LEFT,
                  transition_delay=tdelay).autoretain()
            Text(ba.Lstr(value=name),
                 position=(ts_h_offs - 50, ts_height / 2 + v_offs + 15),
                 h_align=Text.HAlign.LEFT,
                 v_align=Text.VAlign.CENTER,
                 maxwidth=180,
                 color=ba.safecolor(prec.team.color + (1, )),
                 transition=Text.Transition.IN_RIGHT,
                 transition_delay=tdelay).autoretain()

        ba.timer(15.0, ba.WeakCall(self._show_tips))
Esempio n. 16
0
    def __init__(self, data: Dict[str, Any]):
        from ba.internal import is_browser_likely_available
        ba.set_analytics_screen('Friend Promo Code')
        self._width = 650
        self._height = 400
        uiscale = ba.app.uiscale
        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height),
            color=(0.45, 0.63, 0.15),
            transition='in_scale',
            scale=(1.7 if uiscale is ba.UIScale.SMALL else
                   1.35 if uiscale is ba.UIScale.MEDIUM else 1.0)))
        self._data = copy.deepcopy(data)
        ba.playsound(ba.getsound('cashRegister'))
        ba.playsound(ba.getsound('swish'))

        self._cancel_button = ba.buttonwidget(parent=self._root_widget,
                                              scale=0.7,
                                              position=(50, self._height - 50),
                                              size=(60, 60),
                                              label='',
                                              on_activate_call=self.close,
                                              autoselect=True,
                                              color=(0.45, 0.63, 0.15),
                                              icon=ba.gettexture('crossOut'),
                                              iconscale=1.2)
        ba.containerwidget(edit=self._root_widget,
                           cancel_button=self._cancel_button)

        ba.textwidget(
            parent=self._root_widget,
            position=(self._width * 0.5, self._height * 0.8),
            size=(0, 0),
            color=ba.app.ui.infotextcolor,
            scale=1.0,
            flatness=1.0,
            h_align='center',
            v_align='center',
            text=ba.Lstr(resource='gatherWindow.shareThisCodeWithFriendsText'),
            maxwidth=self._width * 0.85)

        ba.textwidget(parent=self._root_widget,
                      position=(self._width * 0.5, self._height * 0.645),
                      size=(0, 0),
                      color=(1.0, 3.0, 1.0),
                      scale=2.0,
                      h_align='center',
                      v_align='center',
                      text=data['code'],
                      maxwidth=self._width * 0.85)

        award_str: Optional[Union[str, ba.Lstr]]
        if self._data['awardTickets'] != 0:
            award_str = ba.Lstr(
                resource='gatherWindow.friendPromoCodeAwardText',
                subs=[('${COUNT}', str(self._data['awardTickets']))])
        else:
            award_str = ''
        ba.textwidget(
            parent=self._root_widget,
            position=(self._width * 0.5, self._height * 0.37),
            size=(0, 0),
            color=ba.app.ui.infotextcolor,
            scale=1.0,
            flatness=1.0,
            h_align='center',
            v_align='center',
            text=ba.Lstr(
                value='${A}\n${B}\n${C}\n${D}',
                subs=[
                    ('${A}',
                     ba.Lstr(
                         resource='gatherWindow.friendPromoCodeRedeemLongText',
                         subs=[('${COUNT}', str(self._data['tickets'])),
                               ('${MAX_USES}',
                                str(self._data['usesRemaining']))])),
                    ('${B}',
                     ba.Lstr(resource=(
                         'gatherWindow.friendPromoCodeWhereToEnterText'))),
                    ('${C}', award_str),
                    ('${D}',
                     ba.Lstr(resource='gatherWindow.friendPromoCodeExpireText',
                             subs=[('${EXPIRE_HOURS}',
                                    str(self._data['expireHours']))]))
                ]),
            maxwidth=self._width * 0.9,
            max_height=self._height * 0.35)

        if is_browser_likely_available():
            xoffs = 0
            ba.buttonwidget(parent=self._root_widget,
                            size=(200, 40),
                            position=(self._width * 0.5 - 100 + xoffs, 39),
                            autoselect=True,
                            label=ba.Lstr(resource='gatherWindow.emailItText'),
                            on_activate_call=ba.WeakCall(self._email))
Esempio n. 17
0
    def __init__(self,
                 transition: str = 'in_right',
                 from_modal_store: bool = False,
                 modal: bool = False,
                 origin_widget: ba.Widget = None,
                 store_back_location: str = None):
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-locals

        ba.set_analytics_screen('Get Tickets Window')

        self._transitioning_out = False
        self._store_back_location = store_back_location  # ew.

        self._ad_button_greyed = False
        self._smooth_update_timer: Optional[ba.Timer] = None
        self._ad_button = None
        self._ad_label = None
        self._ad_image = None
        self._ad_time_text = None

        # If they provided an origin-widget, scale up from that.
        scale_origin: Optional[Tuple[float, float]]
        if origin_widget is not None:
            self._transition_out = 'out_scale'
            scale_origin = origin_widget.get_screen_space_center()
            transition = 'in_scale'
        else:
            self._transition_out = 'out_right'
            scale_origin = None

        uiscale = ba.app.uiscale
        self._width = 1000.0 if uiscale is ba.UIScale.SMALL else 800.0
        x_inset = 100.0 if uiscale is ba.UIScale.SMALL else 0.0
        self._height = 480.0

        self._modal = modal
        self._from_modal_store = from_modal_store
        self._r = 'getTicketsWindow'

        top_extra = 20 if uiscale is ba.UIScale.SMALL else 0

        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height + top_extra),
            transition=transition,
            scale_origin_stack_offset=scale_origin,
            color=(0.4, 0.37, 0.55),
            scale=(1.63 if uiscale is ba.UIScale.SMALL else
                   1.2 if uiscale is ba.UIScale.MEDIUM else 1.0),
            stack_offset=(0, -3) if uiscale is ba.UIScale.SMALL else (0, 0)))

        btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(55 + x_inset, self._height - 79),
            size=(140, 60),
            scale=1.0,
            autoselect=True,
            label=ba.Lstr(resource='doneText' if modal else 'backText'),
            button_type='regular' if modal else 'back',
            on_activate_call=self._back)

        ba.containerwidget(edit=self._root_widget, cancel_button=btn)

        ba.textwidget(parent=self._root_widget,
                      position=(self._width * 0.5, self._height - 55),
                      size=(0, 0),
                      color=ba.app.title_color,
                      scale=1.2,
                      h_align='center',
                      v_align='center',
                      text=ba.Lstr(resource=self._r + '.titleText'),
                      maxwidth=290)

        if not modal:
            ba.buttonwidget(edit=btn,
                            button_type='backSmall',
                            size=(60, 60),
                            label=ba.charstr(ba.SpecialChar.BACK))

        b_size = (220.0, 180.0)
        v = self._height - b_size[1] - 80
        spacing = 1

        self._ad_button = None

        def _add_button(item: str,
                        position: Tuple[float, float],
                        size: Tuple[float, float],
                        label: ba.Lstr,
                        price: str = None,
                        tex_name: str = None,
                        tex_opacity: float = 1.0,
                        tex_scale: float = 1.0,
                        enabled: bool = True,
                        text_scale: float = 1.0) -> ba.Widget:
            btn2 = ba.buttonwidget(
                parent=self._root_widget,
                position=position,
                button_type='square',
                size=size,
                label='',
                autoselect=True,
                color=None if enabled else (0.5, 0.5, 0.5),
                on_activate_call=(ba.Call(self._purchase, item)
                                  if enabled else self._disabled_press))
            txt = ba.textwidget(parent=self._root_widget,
                                text=label,
                                position=(position[0] + size[0] * 0.5,
                                          position[1] + size[1] * 0.3),
                                scale=text_scale,
                                maxwidth=size[0] * 0.75,
                                size=(0, 0),
                                h_align='center',
                                v_align='center',
                                draw_controller=btn2,
                                color=(0.7, 0.9, 0.7, 1.0 if enabled else 0.2))
            if price is not None and enabled:
                ba.textwidget(parent=self._root_widget,
                              text=price,
                              position=(position[0] + size[0] * 0.5,
                                        position[1] + size[1] * 0.17),
                              scale=0.7,
                              maxwidth=size[0] * 0.75,
                              size=(0, 0),
                              h_align='center',
                              v_align='center',
                              draw_controller=btn2,
                              color=(0.4, 0.9, 0.4, 1.0))
            i = None
            if tex_name is not None:
                tex_size = 90.0 * tex_scale
                i = ba.imagewidget(
                    parent=self._root_widget,
                    texture=ba.gettexture(tex_name),
                    position=(position[0] + size[0] * 0.5 - tex_size * 0.5,
                              position[1] + size[1] * 0.66 - tex_size * 0.5),
                    size=(tex_size, tex_size),
                    draw_controller=btn2,
                    opacity=tex_opacity * (1.0 if enabled else 0.25))
            if item == 'ad':
                self._ad_button = btn2
                self._ad_label = txt
                assert i is not None
                self._ad_image = i
                self._ad_time_text = ba.textwidget(
                    parent=self._root_widget,
                    text='1m 10s',
                    position=(position[0] + size[0] * 0.5,
                              position[1] + size[1] * 0.5),
                    scale=text_scale * 1.2,
                    maxwidth=size[0] * 0.85,
                    size=(0, 0),
                    h_align='center',
                    v_align='center',
                    draw_controller=btn2,
                    color=(0.4, 0.9, 0.4, 1.0))
            return btn2

        rsrc = self._r + '.ticketsText'

        c2txt = ba.Lstr(
            resource=rsrc,
            subs=[('${COUNT}',
                   str(_ba.get_account_misc_read_val('tickets2Amount', 500)))])
        c3txt = ba.Lstr(
            resource=rsrc,
            subs=[('${COUNT}',
                   str(_ba.get_account_misc_read_val('tickets3Amount',
                                                     1500)))])
        c4txt = ba.Lstr(
            resource=rsrc,
            subs=[('${COUNT}',
                   str(_ba.get_account_misc_read_val('tickets4Amount',
                                                     5000)))])
        c5txt = ba.Lstr(
            resource=rsrc,
            subs=[('${COUNT}',
                   str(_ba.get_account_misc_read_val('tickets5Amount',
                                                     15000)))])

        h = 110.0

        # enable buttons if we have prices..
        tickets2_price = _ba.get_price('tickets2')
        tickets3_price = _ba.get_price('tickets3')
        tickets4_price = _ba.get_price('tickets4')
        tickets5_price = _ba.get_price('tickets5')

        # TEMP
        # tickets1_price = '$0.99'
        # tickets2_price = '$4.99'
        # tickets3_price = '$9.99'
        # tickets4_price = '$19.99'
        # tickets5_price = '$49.99'

        _add_button('tickets2',
                    enabled=(tickets2_price is not None),
                    position=(self._width * 0.5 - spacing * 1.5 -
                              b_size[0] * 2.0 + h, v),
                    size=b_size,
                    label=c2txt,
                    price=tickets2_price,
                    tex_name='ticketsMore')  # 0.99-ish
        _add_button('tickets3',
                    enabled=(tickets3_price is not None),
                    position=(self._width * 0.5 - spacing * 0.5 -
                              b_size[0] * 1.0 + h, v),
                    size=b_size,
                    label=c3txt,
                    price=tickets3_price,
                    tex_name='ticketRoll')  # 4.99-ish
        v -= b_size[1] - 5
        _add_button('tickets4',
                    enabled=(tickets4_price is not None),
                    position=(self._width * 0.5 - spacing * 1.5 -
                              b_size[0] * 2.0 + h, v),
                    size=b_size,
                    label=c4txt,
                    price=tickets4_price,
                    tex_name='ticketRollBig',
                    tex_scale=1.2)  # 9.99-ish
        _add_button('tickets5',
                    enabled=(tickets5_price is not None),
                    position=(self._width * 0.5 - spacing * 0.5 -
                              b_size[0] * 1.0 + h, v),
                    size=b_size,
                    label=c5txt,
                    price=tickets5_price,
                    tex_name='ticketRolls',
                    tex_scale=1.2)  # 19.99-ish

        self._enable_ad_button = _ba.has_video_ads()
        h = self._width * 0.5 + 110.0
        v = self._height - b_size[1] - 115.0

        if self._enable_ad_button:
            h_offs = 35
            b_size_3 = (150, 120)
            cdb = _add_button(
                'ad',
                position=(h + h_offs, v),
                size=b_size_3,
                label=ba.Lstr(resource=self._r + '.ticketsFromASponsorText',
                              subs=[('${COUNT}',
                                     str(
                                         _ba.get_account_misc_read_val(
                                             'sponsorTickets', 5)))]),
                tex_name='ticketsMore',
                enabled=self._enable_ad_button,
                tex_opacity=0.6,
                tex_scale=0.7,
                text_scale=0.7)
            ba.buttonwidget(edit=cdb,
                            color=(0.65, 0.5,
                                   0.7) if self._enable_ad_button else
                            (0.5, 0.5, 0.5))

            self._ad_free_text = ba.textwidget(
                parent=self._root_widget,
                text=ba.Lstr(resource=self._r + '.freeText'),
                position=(h + h_offs + b_size_3[0] * 0.5,
                          v + b_size_3[1] * 0.5 + 25),
                size=(0, 0),
                color=(1, 1, 0, 1.0) if self._enable_ad_button else
                (1, 1, 1, 0.2),
                draw_controller=cdb,
                rotate=15,
                shadow=1.0,
                maxwidth=150,
                h_align='center',
                v_align='center',
                scale=1.0)
            v -= 125
        else:
            v -= 20

        if True:  # pylint: disable=using-constant-test
            h_offs = 35
            b_size_3 = (150, 120)
            cdb = _add_button(
                'app_invite',
                position=(h + h_offs, v),
                size=b_size_3,
                label=ba.Lstr(
                    resource='gatherWindow.earnTicketsForRecommendingText',
                    subs=[
                        ('${COUNT}',
                         str(_ba.get_account_misc_read_val(
                             'sponsorTickets', 5)))
                    ]),
                tex_name='ticketsMore',
                enabled=True,
                tex_opacity=0.6,
                tex_scale=0.7,
                text_scale=0.7)
            ba.buttonwidget(edit=cdb, color=(0.65, 0.5, 0.7))

            ba.textwidget(parent=self._root_widget,
                          text=ba.Lstr(resource=self._r + '.freeText'),
                          position=(h + h_offs + b_size_3[0] * 0.5,
                                    v + b_size_3[1] * 0.5 + 25),
                          size=(0, 0),
                          color=(1, 1, 0, 1.0),
                          draw_controller=cdb,
                          rotate=15,
                          shadow=1.0,
                          maxwidth=150,
                          h_align='center',
                          v_align='center',
                          scale=1.0)
            tc_y_offs = 0

        h = self._width - (185 + x_inset)
        v = self._height - 95 + tc_y_offs

        txt1 = (ba.Lstr(
            resource=self._r +
            '.youHaveText').evaluate().split('${COUNT}')[0].strip())
        txt2 = (ba.Lstr(
            resource=self._r +
            '.youHaveText').evaluate().split('${COUNT}')[-1].strip())

        ba.textwidget(parent=self._root_widget,
                      text=txt1,
                      position=(h, v),
                      size=(0, 0),
                      color=(0.5, 0.5, 0.6),
                      maxwidth=200,
                      h_align='center',
                      v_align='center',
                      scale=0.8)
        v -= 30
        self._ticket_count_text = ba.textwidget(parent=self._root_widget,
                                                position=(h, v),
                                                size=(0, 0),
                                                color=(0.2, 1.0, 0.2),
                                                maxwidth=200,
                                                h_align='center',
                                                v_align='center',
                                                scale=1.6)
        v -= 30
        ba.textwidget(parent=self._root_widget,
                      text=txt2,
                      position=(h, v),
                      size=(0, 0),
                      color=(0.5, 0.5, 0.6),
                      maxwidth=200,
                      h_align='center',
                      v_align='center',
                      scale=0.8)

        # update count now and once per second going forward..
        self._ticking_node: Optional[ba.Node] = None
        self._smooth_ticket_count: Optional[float] = None
        self._ticket_count = 0
        self._update()
        self._update_timer = ba.Timer(1.0,
                                      ba.WeakCall(self._update),
                                      timetype=ba.TimeType.REAL,
                                      repeat=True)
        self._smooth_increase_speed = 1.0
Esempio n. 18
0
    def __init__(self,
                 sessiontype: Type[ba.Session],
                 transition: Optional[str] = 'in_right',
                 origin_widget: ba.Widget = None):
        # pylint: disable=too-many-statements
        # pylint: disable=cyclic-import
        from bastd.ui.playlist import PlaylistTypeVars

        # If they provided an origin-widget, scale up from that.
        scale_origin: Optional[Tuple[float, float]]
        if origin_widget is not None:
            self._transition_out = 'out_scale'
            scale_origin = origin_widget.get_screen_space_center()
            transition = 'in_scale'
        else:
            self._transition_out = 'out_right'
            scale_origin = None

        # Store state for when we exit the next game.
        if issubclass(sessiontype, ba.DualTeamSession):
            ba.app.main_window = 'Team Game Select'
            ba.set_analytics_screen('Teams Window')
        elif issubclass(sessiontype, ba.FreeForAllSession):
            ba.app.main_window = 'Free-for-All Game Select'
            ba.set_analytics_screen('FreeForAll Window')
        else:
            raise TypeError(f'Invalid sessiontype: {sessiontype}.')
        self._pvars = PlaylistTypeVars(sessiontype)

        self._sessiontype = sessiontype

        self._customize_button: Optional[ba.Widget] = None
        self._sub_width: Optional[float] = None
        self._sub_height: Optional[float] = None

        # On new installations, go ahead and create a few playlists
        # besides the hard-coded default one:
        if not _ba.get_account_misc_val('madeStandardPlaylists', False):
            _ba.add_transaction({
                'type':
                'ADD_PLAYLIST',
                'playlistType':
                'Free-for-All',
                'playlistName':
                ba.Lstr(
                    resource='singleGamePlaylistNameText').evaluate().replace(
                        '${GAME}',
                        ba.Lstr(translate=('gameNames',
                                           'Death Match')).evaluate()),
                'playlist': [
                    {
                        'type': 'bs_death_match.DeathMatchGame',
                        'settings': {
                            'Epic Mode': False,
                            'Kills to Win Per Player': 10,
                            'Respawn Times': 1.0,
                            'Time Limit': 300,
                            'map': 'Doom Shroom'
                        }
                    },
                    {
                        'type': 'bs_death_match.DeathMatchGame',
                        'settings': {
                            'Epic Mode': False,
                            'Kills to Win Per Player': 10,
                            'Respawn Times': 1.0,
                            'Time Limit': 300,
                            'map': 'Crag Castle'
                        }
                    },
                ]
            })
            _ba.add_transaction({
                'type':
                'ADD_PLAYLIST',
                'playlistType':
                'Team Tournament',
                'playlistName':
                ba.Lstr(
                    resource='singleGamePlaylistNameText').evaluate().replace(
                        '${GAME}',
                        ba.Lstr(translate=('gameNames',
                                           'Capture the Flag')).evaluate()),
                'playlist': [
                    {
                        'type': 'bs_capture_the_flag.CTFGame',
                        'settings': {
                            'map': 'Bridgit',
                            'Score to Win': 3,
                            'Flag Idle Return Time': 30,
                            'Flag Touch Return Time': 0,
                            'Respawn Times': 1.0,
                            'Time Limit': 600,
                            'Epic Mode': False
                        }
                    },
                    {
                        'type': 'bs_capture_the_flag.CTFGame',
                        'settings': {
                            'map': 'Roundabout',
                            'Score to Win': 2,
                            'Flag Idle Return Time': 30,
                            'Flag Touch Return Time': 0,
                            'Respawn Times': 1.0,
                            'Time Limit': 600,
                            'Epic Mode': False
                        }
                    },
                    {
                        'type': 'bs_capture_the_flag.CTFGame',
                        'settings': {
                            'map': 'Tip Top',
                            'Score to Win': 2,
                            'Flag Idle Return Time': 30,
                            'Flag Touch Return Time': 3,
                            'Respawn Times': 1.0,
                            'Time Limit': 300,
                            'Epic Mode': False
                        }
                    },
                ]
            })
            _ba.add_transaction({
                'type':
                'ADD_PLAYLIST',
                'playlistType':
                'Team Tournament',
                'playlistName':
                ba.Lstr(translate=('playlistNames', 'Just Sports')).evaluate(),
                'playlist': [
                    {
                        'type': 'bs_hockey.HockeyGame',
                        'settings': {
                            'Time Limit': 0,
                            'map': 'Hockey Stadium',
                            'Score to Win': 1,
                            'Respawn Times': 1.0
                        }
                    },
                    {
                        'type': 'bs_football.FootballTeamGame',
                        'settings': {
                            'Time Limit': 0,
                            'map': 'Football Stadium',
                            'Score to Win': 21,
                            'Respawn Times': 1.0
                        }
                    },
                ]
            })
            _ba.add_transaction({
                'type':
                'ADD_PLAYLIST',
                'playlistType':
                'Free-for-All',
                'playlistName':
                ba.Lstr(translate=('playlistNames', 'Just Epic')).evaluate(),
                'playlist': [{
                    'type': 'bs_elimination.EliminationGame',
                    'settings': {
                        'Time Limit': 120,
                        'map': 'Tip Top',
                        'Respawn Times': 1.0,
                        'Lives Per Player': 1,
                        'Epic Mode': 1
                    }
                }]
            })
            _ba.add_transaction({
                'type': 'SET_MISC_VAL',
                'name': 'madeStandardPlaylists',
                'value': True
            })
            _ba.run_transactions()

        # Get the current selection (if any).
        self._selected_playlist = ba.app.config.get(self._pvars.config_name +
                                                    ' Playlist Selection')

        uiscale = ba.app.uiscale
        self._width = 900 if uiscale is ba.UIScale.SMALL else 800
        x_inset = 50 if uiscale is ba.UIScale.SMALL else 0
        self._height = (480 if uiscale is ba.UIScale.SMALL else
                        510 if uiscale is ba.UIScale.MEDIUM else 580)

        top_extra = 20 if uiscale is ba.UIScale.SMALL else 0

        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height + top_extra),
            transition=transition,
            toolbar_visibility='menu_full',
            scale_origin_stack_offset=scale_origin,
            scale=(1.69 if uiscale is ba.UIScale.SMALL else
                   1.05 if uiscale is ba.UIScale.MEDIUM else 0.9),
            stack_offset=(0, -26) if uiscale is ba.UIScale.SMALL else (0, 0)))

        self._back_button: Optional[ba.Widget] = ba.buttonwidget(
            parent=self._root_widget,
            position=(59 + x_inset, self._height - 70),
            size=(120, 60),
            scale=1.0,
            on_activate_call=self._on_back_press,
            autoselect=True,
            label=ba.Lstr(resource='backText'),
            button_type='back')
        ba.containerwidget(edit=self._root_widget,
                           cancel_button=self._back_button)
        txt = self._title_text = ba.textwidget(
            parent=self._root_widget,
            position=(self._width * 0.5, self._height - 41),
            size=(0, 0),
            text=self._pvars.window_title_name,
            scale=1.3,
            res_scale=1.5,
            color=ba.app.heading_color,
            h_align='center',
            v_align='center')
        if uiscale is ba.UIScale.SMALL and ba.app.toolbars:
            ba.textwidget(edit=txt, text='')

        ba.buttonwidget(edit=self._back_button,
                        button_type='backSmall',
                        size=(60, 54),
                        position=(59 + x_inset, self._height - 67),
                        label=ba.charstr(ba.SpecialChar.BACK))

        if uiscale is ba.UIScale.SMALL and ba.app.toolbars:
            self._back_button.delete()
            self._back_button = None
            ba.containerwidget(edit=self._root_widget,
                               on_cancel_call=self._on_back_press)
            scroll_offs = 33
        else:
            scroll_offs = 0
        self._scroll_width = self._width - (100 + 2 * x_inset)
        self._scroll_height = self._height - (
            146 if uiscale is ba.UIScale.SMALL and ba.app.toolbars else 136)
        self._scrollwidget = ba.scrollwidget(
            parent=self._root_widget,
            highlight=False,
            size=(self._scroll_width, self._scroll_height),
            position=((self._width - self._scroll_width) * 0.5,
                      65 + scroll_offs))
        ba.containerwidget(edit=self._scrollwidget, claims_left_right=True)
        self._subcontainer: Optional[ba.Widget] = None
        self._config_name_full = self._pvars.config_name + ' Playlists'
        self._last_config = None

        # Update now and once per second.
        # (this should do our initial refresh)
        self._update()
        self._update_timer = ba.Timer(1.0,
                                      ba.WeakCall(self._update),
                                      timetype=ba.TimeType.REAL,
                                      repeat=True)
Esempio n. 19
0
    def __init__(self,
                 transition: str = 'in_right',
                 modal: bool = False,
                 origin_widget: ba.Widget = None,
                 close_once_signed_in: bool = False):
        # pylint: disable=too-many-statements

        self._sign_in_game_circle_button: Optional[ba.Widget] = None
        self._sign_in_v2_button: Optional[ba.Widget] = None
        self._sign_in_device_button: Optional[ba.Widget] = None

        self._close_once_signed_in = close_once_signed_in
        ba.set_analytics_screen('Account Window')

        # If they provided an origin-widget, scale up from that.
        scale_origin: Optional[tuple[float, float]]
        if origin_widget is not None:
            self._transition_out = 'out_scale'
            scale_origin = origin_widget.get_screen_space_center()
            transition = 'in_scale'
        else:
            self._transition_out = 'out_right'
            scale_origin = None

        self._r = 'accountSettingsWindow'
        self._modal = modal
        self._needs_refresh = False
        self._signed_in = (_ba.get_v1_account_state() == 'signed_in')
        self._account_state_num = _ba.get_v1_account_state_num()
        self._show_linked = (self._signed_in
                             and _ba.get_v1_account_misc_read_val(
                                 'allowAccountLinking2', False))
        self._check_sign_in_timer = ba.Timer(1.0,
                                             ba.WeakCall(self._update),
                                             timetype=ba.TimeType.REAL,
                                             repeat=True)

        # Currently we can only reset achievements on game-center.
        account_type: Optional[str]
        if self._signed_in:
            account_type = _ba.get_v1_account_type()
        else:
            account_type = None
        self._can_reset_achievements = (account_type == 'Game Center')

        app = ba.app
        uiscale = app.ui.uiscale

        self._width = 760 if uiscale is ba.UIScale.SMALL else 660
        x_offs = 50 if uiscale is ba.UIScale.SMALL else 0
        self._height = (390 if uiscale is ba.UIScale.SMALL else
                        430 if uiscale is ba.UIScale.MEDIUM else 490)

        self._sign_in_button = None
        self._sign_in_text = None

        self._scroll_width = self._width - (100 + x_offs * 2)
        self._scroll_height = self._height - 120
        self._sub_width = self._scroll_width - 20

        # Determine which sign-in/sign-out buttons we should show.
        self._show_sign_in_buttons: list[str] = []

        if app.platform == 'android' and app.subplatform == 'google':
            self._show_sign_in_buttons.append('Google Play')

        elif app.platform == 'android' and app.subplatform == 'amazon':
            self._show_sign_in_buttons.append('Game Circle')

        # Local accounts are generally always available with a few key
        # exceptions.
        self._show_sign_in_buttons.append('Local')

        # Ditto with shiny new V2 ones.
        if bool(True):
            self._show_sign_in_buttons.append('V2')

        top_extra = 15 if uiscale is ba.UIScale.SMALL else 0
        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height + top_extra),
            transition=transition,
            toolbar_visibility='menu_minimal',
            scale_origin_stack_offset=scale_origin,
            scale=(2.09 if uiscale is ba.UIScale.SMALL else
                   1.4 if uiscale is ba.UIScale.MEDIUM else 1.0),
            stack_offset=(0, -19) if uiscale is ba.UIScale.SMALL else (0, 0)))
        if uiscale is ba.UIScale.SMALL and ba.app.ui.use_toolbars:
            self._back_button = None
            ba.containerwidget(edit=self._root_widget,
                               on_cancel_call=self._back)
        else:
            self._back_button = btn = ba.buttonwidget(
                parent=self._root_widget,
                position=(51 + x_offs, self._height - 62),
                size=(120, 60),
                scale=0.8,
                text_scale=1.2,
                autoselect=True,
                label=ba.Lstr(
                    resource='doneText' if self._modal else 'backText'),
                button_type='regular' if self._modal else 'back',
                on_activate_call=self._back)
            ba.containerwidget(edit=self._root_widget, cancel_button=btn)
            if not self._modal:
                ba.buttonwidget(edit=btn,
                                button_type='backSmall',
                                size=(60, 56),
                                label=ba.charstr(ba.SpecialChar.BACK))

        ba.textwidget(parent=self._root_widget,
                      position=(self._width * 0.5, self._height - 41),
                      size=(0, 0),
                      text=ba.Lstr(resource=self._r + '.titleText'),
                      color=ba.app.ui.title_color,
                      maxwidth=self._width - 340,
                      h_align='center',
                      v_align='center')

        self._scrollwidget = ba.scrollwidget(
            parent=self._root_widget,
            highlight=False,
            position=((self._width - self._scroll_width) * 0.5,
                      self._height - 65 - self._scroll_height),
            size=(self._scroll_width, self._scroll_height),
            claims_left_right=True,
            claims_tab=True,
            selection_loops_to_parent=True)
        self._subcontainer: Optional[ba.Widget] = None
        self._refresh()
        self._restore_state()
Esempio n. 20
0
    def __init__(self) -> None:
        ba.set_analytics_screen('AppInviteWindow')
        self._data: Optional[Dict[str, Any]] = None
        self._width = 650
        self._height = 400

        uiscale = ba.app.uiscale
        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height),
            transition='in_scale',
            scale=(1.8 if uiscale is ba.UIScale.SMALL else
                   1.35 if uiscale is ba.UIScale.MEDIUM else 1.0)))

        self._cancel_button = ba.buttonwidget(parent=self._root_widget,
                                              scale=0.8,
                                              position=(60, self._height - 50),
                                              size=(50, 50),
                                              label='',
                                              on_activate_call=self.close,
                                              autoselect=True,
                                              color=(0.4, 0.4, 0.6),
                                              icon=ba.gettexture('crossOut'),
                                              iconscale=1.2)

        ba.containerwidget(edit=self._root_widget,
                           cancel_button=self._cancel_button)

        ba.textwidget(
            parent=self._root_widget,
            size=(0, 0),
            position=(self._width * 0.5, self._height * 0.5 + 110),
            autoselect=True,
            scale=0.8,
            maxwidth=self._width * 0.9,
            h_align='center',
            v_align='center',
            color=(0.3, 0.8, 0.3),
            flatness=1.0,
            text=ba.Lstr(
                resource='gatherWindow.earnTicketsForRecommendingAmountText',
                fallback_resource=(
                    'gatherWindow.earnTicketsForRecommendingText'),
                subs=[
                    ('${COUNT}',
                     str(_ba.get_account_misc_read_val('friendTryTickets',
                                                       300))),
                    ('${YOU_COUNT}',
                     str(
                         _ba.get_account_misc_read_val('friendTryAwardTickets',
                                                       100)))
                ]))

        or_text = ba.Lstr(resource='orText',
                          subs=[('${A}', ''),
                                ('${B}', '')]).evaluate().strip()
        ba.buttonwidget(
            parent=self._root_widget,
            size=(250, 150),
            position=(self._width * 0.5 - 125, self._height * 0.5 - 80),
            autoselect=True,
            button_type='square',
            label=ba.Lstr(resource='gatherWindow.inviteFriendsText'),
            on_activate_call=ba.WeakCall(self._google_invites))

        ba.textwidget(parent=self._root_widget,
                      size=(0, 0),
                      position=(self._width * 0.5, self._height * 0.5 - 94),
                      autoselect=True,
                      scale=0.9,
                      h_align='center',
                      v_align='center',
                      color=(0.5, 0.5, 0.5),
                      flatness=1.0,
                      text=or_text)

        ba.buttonwidget(
            parent=self._root_widget,
            size=(180, 50),
            position=(self._width * 0.5 - 90, self._height * 0.5 - 170),
            autoselect=True,
            color=(0.5, 0.5, 0.6),
            textcolor=(0.7, 0.7, 0.8),
            text_scale=0.8,
            label=ba.Lstr(resource='gatherWindow.appInviteSendACodeText'),
            on_activate_call=ba.WeakCall(self._send_code))

        # kick off a transaction to get our code
        _ba.add_transaction(
            {
                'type': 'FRIEND_PROMO_CODE_REQUEST',
                'ali': False,
                'expire_time': time.time() + 20
            },
            callback=ba.WeakCall(self._on_code_result))
        _ba.run_transactions()
Esempio n. 21
0
    def __init__(self,
                 tournament_id: str,
                 tournament_activity: ba.Activity = None,
                 position: Tuple[float, float] = (0.0, 0.0),
                 delegate: Any = None,
                 scale: float = None,
                 offset: Tuple[float, float] = (0.0, 0.0),
                 on_close_call: Callable[[], Any] = None):
        # Needs some tidying.
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-locals
        # pylint: disable=too-many-statements

        ba.set_analytics_screen('Tournament Entry Window')

        self._tournament_id = tournament_id
        self._tournament_info = (ba.app.tournament_info[self._tournament_id])

        # Set a few vars depending on the tourney fee.
        self._fee = self._tournament_info['fee']
        self._allow_ads = self._tournament_info['allowAds']
        if self._fee == 4:
            self._purchase_name = 'tournament_entry_4'
            self._purchase_price_name = 'price.tournament_entry_4'
        elif self._fee == 3:
            self._purchase_name = 'tournament_entry_3'
            self._purchase_price_name = 'price.tournament_entry_3'
        elif self._fee == 2:
            self._purchase_name = 'tournament_entry_2'
            self._purchase_price_name = 'price.tournament_entry_2'
        elif self._fee == 1:
            self._purchase_name = 'tournament_entry_1'
            self._purchase_price_name = 'price.tournament_entry_1'
        else:
            if self._fee != 0:
                raise ValueError('invalid fee: ' + str(self._fee))
            self._purchase_name = 'tournament_entry_0'
            self._purchase_price_name = 'price.tournament_entry_0'

        self._purchase_price: Optional[int] = None

        self._on_close_call = on_close_call
        if scale is None:
            uiscale = ba.app.uiscale
            scale = (2.3 if uiscale is ba.UIScale.SMALL else
                     1.65 if uiscale is ba.UIScale.MEDIUM else 1.23)
        self._delegate = delegate
        self._transitioning_out = False

        self._tournament_activity = tournament_activity

        self._width = 340
        self._height = 220

        bg_color = (0.5, 0.4, 0.6)

        # Creates our root_widget.
        popup.PopupWindow.__init__(self,
                                   position=position,
                                   size=(self._width, self._height),
                                   scale=scale,
                                   bg_color=bg_color,
                                   offset=offset,
                                   toolbar_visibility='menu_currency')

        self._last_ad_press_time = -9999.0
        self._last_ticket_press_time = -9999.0
        self._entering = False
        self._launched = False

        # Show the ad button only if we support ads *and* it has a level 1 fee.
        self._do_ad_btn = (_ba.has_video_ads() and self._allow_ads)

        x_offs = 0 if self._do_ad_btn else 85

        self._cancel_button = ba.buttonwidget(parent=self.root_widget,
                                              position=(20, self._height - 30),
                                              size=(50, 50),
                                              scale=0.5,
                                              label='',
                                              color=bg_color,
                                              on_activate_call=self._on_cancel,
                                              autoselect=True,
                                              icon=ba.gettexture('crossOut'),
                                              iconscale=1.2)

        self._title_text = ba.textwidget(
            parent=self.root_widget,
            position=(self._width * 0.5, self._height - 20),
            size=(0, 0),
            h_align='center',
            v_align='center',
            scale=0.6,
            text=ba.Lstr(resource='tournamentEntryText'),
            maxwidth=200,
            color=(1, 1, 1, 0.4))

        btn = self._pay_with_tickets_button = ba.buttonwidget(
            parent=self.root_widget,
            position=(30 + x_offs, 60),
            autoselect=True,
            button_type='square',
            size=(120, 120),
            label='',
            on_activate_call=self._on_pay_with_tickets_press)
        self._ticket_img_pos = (50 + x_offs, 94)
        self._ticket_img_pos_free = (50 + x_offs, 80)
        self._ticket_img = ba.imagewidget(parent=self.root_widget,
                                          draw_controller=btn,
                                          size=(80, 80),
                                          position=self._ticket_img_pos,
                                          texture=ba.gettexture('tickets'))
        self._ticket_cost_text_position = (87 + x_offs, 88)
        self._ticket_cost_text_position_free = (87 + x_offs, 120)
        self._ticket_cost_text = ba.textwidget(
            parent=self.root_widget,
            draw_controller=btn,
            position=self._ticket_cost_text_position,
            size=(0, 0),
            h_align='center',
            v_align='center',
            scale=0.6,
            text='',
            maxwidth=95,
            color=(0, 1, 0))
        self._free_plays_remaining_text = ba.textwidget(
            parent=self.root_widget,
            draw_controller=btn,
            position=(87 + x_offs, 78),
            size=(0, 0),
            h_align='center',
            v_align='center',
            scale=0.33,
            text='',
            maxwidth=95,
            color=(0, 0.8, 0))
        self._pay_with_ad_btn: Optional[ba.Widget]
        if self._do_ad_btn:
            btn = self._pay_with_ad_btn = ba.buttonwidget(
                parent=self.root_widget,
                position=(190, 60),
                autoselect=True,
                button_type='square',
                size=(120, 120),
                label='',
                on_activate_call=self._on_pay_with_ad_press)
            self._pay_with_ad_img = ba.imagewidget(parent=self.root_widget,
                                                   draw_controller=btn,
                                                   size=(80, 80),
                                                   position=(210, 94),
                                                   texture=ba.gettexture('tv'))

            self._ad_text_position = (251, 88)
            self._ad_text_position_remaining = (251, 92)
            have_ad_tries_remaining = (
                self._tournament_info['adTriesRemaining'] is not None)
            self._ad_text = ba.textwidget(
                parent=self.root_widget,
                draw_controller=btn,
                position=self._ad_text_position_remaining
                if have_ad_tries_remaining else self._ad_text_position,
                size=(0, 0),
                h_align='center',
                v_align='center',
                scale=0.6,
                text=ba.Lstr(resource='watchAVideoText',
                             fallback_resource='watchAnAdText'),
                maxwidth=95,
                color=(0, 1, 0))
            ad_plays_remaining_text = (
                '' if not have_ad_tries_remaining else '' +
                str(self._tournament_info['adTriesRemaining']))
            self._ad_plays_remaining_text = ba.textwidget(
                parent=self.root_widget,
                draw_controller=btn,
                position=(251, 78),
                size=(0, 0),
                h_align='center',
                v_align='center',
                scale=0.33,
                text=ad_plays_remaining_text,
                maxwidth=95,
                color=(0, 0.8, 0))

            ba.textwidget(parent=self.root_widget,
                          position=(self._width * 0.5, 120),
                          size=(0, 0),
                          h_align='center',
                          v_align='center',
                          scale=0.6,
                          text=ba.Lstr(resource='orText',
                                       subs=[('${A}', ''), ('${B}', '')]),
                          maxwidth=35,
                          color=(1, 1, 1, 0.5))
        else:
            self._pay_with_ad_btn = None

        self._get_tickets_button: Optional[ba.Widget]
        if not ba.app.toolbars:
            self._get_tickets_button = ba.buttonwidget(
                parent=self.root_widget,
                position=(self._width - 190 + 110, 15),
                autoselect=True,
                scale=0.6,
                size=(120, 60),
                textcolor=(0.2, 1, 0.2),
                label=ba.charstr(ba.SpecialChar.TICKET),
                color=(0.6, 0.4, 0.7),
                on_activate_call=self._on_get_tickets_press)
        else:
            self._get_tickets_button = None

        self._seconds_remaining = None

        ba.containerwidget(edit=self.root_widget,
                           cancel_button=self._cancel_button)

        # Let's also ask the server for info about this tournament
        # (time remaining, etc) so we can show the user time remaining,
        # disallow entry if time has run out, etc.
        xoffs = 104 if ba.app.toolbars else 0
        self._time_remaining_text = ba.textwidget(parent=self.root_widget,
                                                  position=(70 + xoffs, 23),
                                                  size=(0, 0),
                                                  h_align='center',
                                                  v_align='center',
                                                  text='-',
                                                  scale=0.65,
                                                  maxwidth=100,
                                                  flatness=1.0,
                                                  color=(0.7, 0.7, 0.7))
        self._time_remaining_label_text = ba.textwidget(
            parent=self.root_widget,
            position=(70 + xoffs, 40),
            size=(0, 0),
            h_align='center',
            v_align='center',
            text=ba.Lstr(resource='coopSelectWindow.timeRemainingText'),
            scale=0.45,
            flatness=1.0,
            maxwidth=100,
            color=(0.7, 0.7, 0.7))

        self._last_query_time: Optional[float] = None

        # If there seems to be a relatively-recent valid cached info for this
        # tournament, use it. Otherwise we'll kick off a query ourselves.
        if (self._tournament_id in ba.app.tournament_info
                and ba.app.tournament_info[self._tournament_id]['valid'] and
            (ba.time(ba.TimeType.REAL, ba.TimeFormat.MILLISECONDS) -
             ba.app.tournament_info[self._tournament_id]['timeReceived'] <
             1000 * 60 * 5)):
            try:
                info = ba.app.tournament_info[self._tournament_id]
                self._seconds_remaining = max(
                    0, info['timeRemaining'] - int(
                        (ba.time(ba.TimeType.REAL, ba.TimeFormat.MILLISECONDS)
                         - info['timeReceived']) / 1000))
                self._have_valid_data = True
                self._last_query_time = ba.time(ba.TimeType.REAL)
            except Exception:
                ba.print_exception('error using valid tourney data')
                self._have_valid_data = False
        else:
            self._have_valid_data = False

        self._fg_state = ba.app.fg_state
        self._running_query = False
        self._update_timer = ba.Timer(1.0,
                                      ba.WeakCall(self._update),
                                      repeat=True,
                                      timetype=ba.TimeType.REAL)
        self._update()
        self._restore_state()
Esempio n. 22
0
    def on_begin(self) -> None:
        # pylint: disable=too-many-locals
        # pylint: disable=too-many-statements
        from bastd.actor.text import Text
        from bastd.actor.image import Image
        ba.set_analytics_screen('FreeForAll Score Screen')
        super().on_begin()

        y_base = 100.0
        ts_h_offs = -305.0
        tdelay = 1.0
        scale = 1.2
        spacing = 37.0

        # We include name and previous score in the sort to reduce the amount
        # of random jumping around the list we do in cases of ties.
        player_order_prev = list(self.players)
        player_order_prev.sort(
            reverse=True,
            key=lambda p: (
                p.team.sessionteam.customdata['previous_score'],
                p.getname(full=True),
            ))
        player_order = list(self.players)
        player_order.sort(reverse=True,
                          key=lambda p: (
                              p.team.sessionteam.customdata['score'],
                              p.team.sessionteam.customdata['score'],
                              p.getname(full=True),
                          ))

        v_offs = -74.0 + spacing * len(player_order_prev) * 0.5
        delay1 = 1.3 + 0.1
        delay2 = 2.9 + 0.1
        delay3 = 2.9 + 0.1
        order_change = player_order != player_order_prev

        if order_change:
            delay3 += 1.5

        ba.timer(0.3, ba.Call(ba.playsound, self._score_display_sound))
        results = self.settings_raw['results']
        assert isinstance(results, ba.GameResults)
        self.show_player_scores(delay=0.001,
                                results=results,
                                scale=1.2,
                                x_offset=-110.0)

        sound_times: Set[float] = set()

        def _scoretxt(text: str,
                      x_offs: float,
                      y_offs: float,
                      highlight: bool,
                      delay: float,
                      extrascale: float,
                      flash: bool = False) -> Text:
            return Text(text,
                        position=(ts_h_offs + x_offs * scale,
                                  y_base + (y_offs + v_offs + 2.0) * scale),
                        scale=scale * extrascale,
                        color=((1.0, 0.7, 0.3, 1.0) if highlight else
                               (0.7, 0.7, 0.7, 0.7)),
                        h_align=Text.HAlign.RIGHT,
                        transition=Text.Transition.IN_LEFT,
                        transition_delay=tdelay + delay,
                        flash=flash).autoretain()

        v_offs -= spacing
        slide_amt = 0.0
        transtime = 0.250
        transtime2 = 0.250

        session = self.session
        assert isinstance(session, ba.FreeForAllSession)
        title = Text(ba.Lstr(resource='firstToSeriesText',
                             subs=[('${COUNT}',
                                    str(session.get_ffa_series_length()))]),
                     scale=1.05 * scale,
                     position=(ts_h_offs - 0.0 * scale,
                               y_base + (v_offs + 50.0) * scale),
                     h_align=Text.HAlign.CENTER,
                     color=(0.5, 0.5, 0.5, 0.5),
                     transition=Text.Transition.IN_LEFT,
                     transition_delay=tdelay).autoretain()

        v_offs -= 25
        v_offs_start = v_offs

        ba.timer(
            tdelay + delay3,
            ba.WeakCall(
                self._safe_animate, title.position_combine, 'input0', {
                    0.0: ts_h_offs - 0.0 * scale,
                    transtime2: ts_h_offs - (0.0 + slide_amt) * scale
                }))

        for i, player in enumerate(player_order_prev):
            v_offs_2 = v_offs_start - spacing * (player_order.index(player))
            ba.timer(tdelay + 0.3,
                     ba.Call(ba.playsound, self._score_display_sound_small))
            if order_change:
                ba.timer(tdelay + delay2 + 0.1,
                         ba.Call(ba.playsound, self._cymbal_sound))
            img = Image(player.get_icon(),
                        position=(ts_h_offs - 72.0 * scale,
                                  y_base + (v_offs + 15.0) * scale),
                        scale=(30.0 * scale, 30.0 * scale),
                        transition=Image.Transition.IN_LEFT,
                        transition_delay=tdelay).autoretain()
            ba.timer(
                tdelay + delay2,
                ba.WeakCall(
                    self._safe_animate, img.position_combine, 'input1', {
                        0: y_base + (v_offs + 15.0) * scale,
                        transtime: y_base + (v_offs_2 + 15.0) * scale
                    }))
            ba.timer(
                tdelay + delay3,
                ba.WeakCall(
                    self._safe_animate, img.position_combine, 'input0', {
                        0: ts_h_offs - 72.0 * scale,
                        transtime2: ts_h_offs - (72.0 + slide_amt) * scale
                    }))
            txt = Text(ba.Lstr(value=player.getname(full=True)),
                       maxwidth=130.0,
                       scale=0.75 * scale,
                       position=(ts_h_offs - 50.0 * scale,
                                 y_base + (v_offs + 15.0) * scale),
                       h_align=Text.HAlign.LEFT,
                       v_align=Text.VAlign.CENTER,
                       color=ba.safecolor(player.team.color + (1, )),
                       transition=Text.Transition.IN_LEFT,
                       transition_delay=tdelay).autoretain()
            ba.timer(
                tdelay + delay2,
                ba.WeakCall(
                    self._safe_animate, txt.position_combine, 'input1', {
                        0: y_base + (v_offs + 15.0) * scale,
                        transtime: y_base + (v_offs_2 + 15.0) * scale
                    }))
            ba.timer(
                tdelay + delay3,
                ba.WeakCall(
                    self._safe_animate, txt.position_combine, 'input0', {
                        0: ts_h_offs - 50.0 * scale,
                        transtime2: ts_h_offs - (50.0 + slide_amt) * scale
                    }))

            txt_num = Text('#' + str(i + 1),
                           scale=0.55 * scale,
                           position=(ts_h_offs - 95.0 * scale,
                                     y_base + (v_offs + 8.0) * scale),
                           h_align=Text.HAlign.RIGHT,
                           color=(0.6, 0.6, 0.6, 0.6),
                           transition=Text.Transition.IN_LEFT,
                           transition_delay=tdelay).autoretain()
            ba.timer(
                tdelay + delay3,
                ba.WeakCall(
                    self._safe_animate, txt_num.position_combine, 'input0', {
                        0: ts_h_offs - 95.0 * scale,
                        transtime2: ts_h_offs - (95.0 + slide_amt) * scale
                    }))

            s_txt = _scoretxt(
                str(player.team.sessionteam.customdata['previous_score']), 80,
                0, False, 0, 1.0)
            ba.timer(
                tdelay + delay2,
                ba.WeakCall(
                    self._safe_animate, s_txt.position_combine, 'input1', {
                        0: y_base + (v_offs + 2.0) * scale,
                        transtime: y_base + (v_offs_2 + 2.0) * scale
                    }))
            ba.timer(
                tdelay + delay3,
                ba.WeakCall(
                    self._safe_animate, s_txt.position_combine, 'input0', {
                        0: ts_h_offs + 80.0 * scale,
                        transtime2: ts_h_offs + (80.0 - slide_amt) * scale
                    }))

            score_change = (
                player.team.sessionteam.customdata['score'] -
                player.team.sessionteam.customdata['previous_score'])
            if score_change > 0:
                xval = 113
                yval = 3.0
                s_txt_2 = _scoretxt('+' + str(score_change),
                                    xval,
                                    yval,
                                    True,
                                    0,
                                    0.7,
                                    flash=True)
                ba.timer(
                    tdelay + delay2,
                    ba.WeakCall(
                        self._safe_animate, s_txt_2.position_combine, 'input1',
                        {
                            0: y_base + (v_offs + yval + 2.0) * scale,
                            transtime: y_base + (v_offs_2 + yval + 2.0) * scale
                        }))
                ba.timer(
                    tdelay + delay3,
                    ba.WeakCall(
                        self._safe_animate, s_txt_2.position_combine, 'input0',
                        {
                            0: ts_h_offs + xval * scale,
                            transtime2: ts_h_offs + (xval - slide_amt) * scale
                        }))

                def _safesetattr(node: Optional[ba.Node], attr: str,
                                 value: Any) -> None:
                    if node:
                        setattr(node, attr, value)

                ba.timer(
                    tdelay + delay1,
                    ba.Call(_safesetattr, s_txt.node, 'color', (1, 1, 1, 1)))
                for j in range(score_change):
                    ba.timer((tdelay + delay1 + 0.15 * j),
                             ba.Call(
                                 _safesetattr, s_txt.node, 'text',
                                 str(player.team.sessionteam.
                                     customdata['previous_score'] + j + 1)))
                    tfin = tdelay + delay1 + 0.15 * j
                    if tfin not in sound_times:
                        sound_times.add(tfin)
                        ba.timer(
                            tfin,
                            ba.Call(ba.playsound,
                                    self._score_display_sound_small))
            v_offs -= spacing
Esempio n. 23
0
    def __init__(self,
                 transition: str = 'in_right',
                 modal: bool = False,
                 show_tab: str = None,
                 on_close_call: Callable[[], Any] = None,
                 back_location: str = None,
                 origin_widget: ba.Widget = None):
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-locals
        from bastd.ui import tabs
        from ba import SpecialChar

        app = ba.app
        uiscale = app.uiscale

        ba.set_analytics_screen('Store Window')

        scale_origin: Optional[Tuple[float, float]]

        # If they provided an origin-widget, scale up from that.
        if origin_widget is not None:
            self._transition_out = 'out_scale'
            scale_origin = origin_widget.get_screen_space_center()
            transition = 'in_scale'
        else:
            self._transition_out = 'out_right'
            scale_origin = None

        self.button_infos: Optional[Dict[str, Dict[str, Any]]] = None
        self.update_buttons_timer: Optional[ba.Timer] = None
        self._status_textwidget_update_timer = None

        self._back_location = back_location
        self._on_close_call = on_close_call
        self._show_tab = show_tab
        self._modal = modal
        self._width = 1240 if uiscale is ba.UIScale.SMALL else 1040
        self._x_inset = x_inset = 100 if uiscale is ba.UIScale.SMALL else 0
        self._height = (578 if uiscale is ba.UIScale.SMALL else
                        645 if uiscale is ba.UIScale.MEDIUM else 800)
        self._current_tab: Optional[str] = None
        extra_top = 30 if uiscale is ba.UIScale.SMALL else 0

        self._request: Any = None
        self._r = 'store'
        self._last_buy_time: Optional[float] = None

        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height + extra_top),
            transition=transition,
            toolbar_visibility='menu_full',
            scale=(1.3 if uiscale is ba.UIScale.SMALL else
                   0.9 if uiscale is ba.UIScale.MEDIUM else 0.8),
            scale_origin_stack_offset=scale_origin,
            stack_offset=((0, -5) if uiscale is ba.UIScale.SMALL else (
                0, 0) if uiscale is ba.UIScale.MEDIUM else (0, 0))))

        self._back_button = btn = ba.buttonwidget(
            parent=self._root_widget,
            position=(70 + x_inset, self._height - 74),
            size=(140, 60),
            scale=1.1,
            autoselect=True,
            label=ba.Lstr(resource='doneText' if self._modal else 'backText'),
            button_type=None if self._modal else 'back',
            on_activate_call=self._back)
        ba.containerwidget(edit=self._root_widget, cancel_button=btn)

        self._get_tickets_button = ba.buttonwidget(
            parent=self._root_widget,
            size=(210, 65),
            on_activate_call=self._on_get_more_tickets_press,
            autoselect=True,
            scale=0.9,
            text_scale=1.4,
            left_widget=self._back_button,
            color=(0.7, 0.5, 0.85),
            textcolor=(0.2, 1.0, 0.2),
            label=ba.Lstr(resource='getTicketsWindow.titleText'))

        # Move this dynamically to keep it out of the way of the party icon.
        self._update_get_tickets_button_pos()
        self._get_ticket_pos_update_timer = ba.Timer(
            1.0,
            ba.WeakCall(self._update_get_tickets_button_pos),
            repeat=True,
            timetype=ba.TimeType.REAL)
        ba.widget(edit=self._back_button,
                  right_widget=self._get_tickets_button)
        self._ticket_text_update_timer = ba.Timer(
            1.0,
            ba.WeakCall(self._update_tickets_text),
            timetype=ba.TimeType.REAL,
            repeat=True)
        self._update_tickets_text()

        app = ba.app
        if app.platform in ['mac', 'ios'] and app.subplatform == 'appstore':
            ba.buttonwidget(
                parent=self._root_widget,
                position=(self._width * 0.5 - 70, 16),
                size=(230, 50),
                scale=0.65,
                on_activate_call=ba.WeakCall(self._restore_purchases),
                color=(0.35, 0.3, 0.4),
                selectable=False,
                textcolor=(0.55, 0.5, 0.6),
                label=ba.Lstr(
                    resource='getTicketsWindow.restorePurchasesText'))

        ba.textwidget(parent=self._root_widget,
                      position=(self._width * 0.5, self._height - 44),
                      size=(0, 0),
                      color=app.title_color,
                      scale=1.5,
                      h_align='center',
                      v_align='center',
                      text=ba.Lstr(resource='storeText'),
                      maxwidth=420)

        if not self._modal:
            ba.buttonwidget(edit=self._back_button,
                            button_type='backSmall',
                            size=(60, 60),
                            label=ba.charstr(SpecialChar.BACK))

        scroll_buffer_h = 130 + 2 * x_inset
        tab_buffer_h = 250 + 2 * x_inset

        tabs_def = [
            ('extras', ba.Lstr(resource=self._r + '.extrasText')),
            ('maps', ba.Lstr(resource=self._r + '.mapsText')),
            ('minigames', ba.Lstr(resource=self._r + '.miniGamesText')),
            ('characters', ba.Lstr(resource=self._r + '.charactersText')),
            ('icons', ba.Lstr(resource=self._r + '.iconsText')),
        ]

        tab_results = tabs.create_tab_buttons(self._root_widget,
                                              tabs_def,
                                              pos=(tab_buffer_h * 0.5,
                                                   self._height - 130),
                                              size=(self._width - tab_buffer_h,
                                                    50),
                                              on_select_call=self._set_tab,
                                              return_extra_info=True)

        self._purchasable_count_widgets: Dict[str, Dict[str, Any]] = {}

        # Create our purchasable-items tags and have them update over time.
        for i, tab in enumerate(tabs_def):
            pos = tab_results['positions'][i]
            size = tab_results['sizes'][i]
            button = tab_results['buttons_indexed'][i]
            rad = 10
            center = (pos[0] + 0.1 * size[0], pos[1] + 0.9 * size[1])
            img = ba.imagewidget(parent=self._root_widget,
                                 position=(center[0] - rad * 1.04,
                                           center[1] - rad * 1.15),
                                 size=(rad * 2.2, rad * 2.2),
                                 texture=ba.gettexture('circleShadow'),
                                 color=(1, 0, 0))
            txt = ba.textwidget(parent=self._root_widget,
                                position=center,
                                size=(0, 0),
                                h_align='center',
                                v_align='center',
                                maxwidth=1.4 * rad,
                                scale=0.6,
                                shadow=1.0,
                                flatness=1.0)
            rad = 20
            sale_img = ba.imagewidget(parent=self._root_widget,
                                      position=(center[0] - rad,
                                                center[1] - rad),
                                      size=(rad * 2, rad * 2),
                                      draw_controller=button,
                                      texture=ba.gettexture('circleZigZag'),
                                      color=(0.5, 0, 1.0))
            sale_title_text = ba.textwidget(parent=self._root_widget,
                                            position=(center[0],
                                                      center[1] + 0.24 * rad),
                                            size=(0, 0),
                                            h_align='center',
                                            v_align='center',
                                            draw_controller=button,
                                            maxwidth=1.4 * rad,
                                            scale=0.6,
                                            shadow=0.0,
                                            flatness=1.0,
                                            color=(0, 1, 0))
            sale_time_text = ba.textwidget(parent=self._root_widget,
                                           position=(center[0],
                                                     center[1] - 0.29 * rad),
                                           size=(0, 0),
                                           h_align='center',
                                           v_align='center',
                                           draw_controller=button,
                                           maxwidth=1.4 * rad,
                                           scale=0.4,
                                           shadow=0.0,
                                           flatness=1.0,
                                           color=(0, 1, 0))
            self._purchasable_count_widgets[tab[0]] = {
                'img': img,
                'text': txt,
                'sale_img': sale_img,
                'sale_title_text': sale_title_text,
                'sale_time_text': sale_time_text
            }
        self._tab_update_timer = ba.Timer(1.0,
                                          ba.WeakCall(self._update_tabs),
                                          timetype=ba.TimeType.REAL,
                                          repeat=True)
        self._update_tabs()

        self._tab_buttons = tab_results['buttons']

        if self._get_tickets_button is not None:
            last_tab_button = self._tab_buttons[tabs_def[-1][0]]
            ba.widget(edit=self._get_tickets_button,
                      down_widget=last_tab_button)
            ba.widget(edit=last_tab_button,
                      up_widget=self._get_tickets_button,
                      right_widget=self._get_tickets_button)

        self._scroll_width = self._width - scroll_buffer_h
        self._scroll_height = self._height - 180

        self._scrollwidget: Optional[ba.Widget] = None
        self._status_textwidget: Optional[ba.Widget] = None
        self._restore_state()
Esempio n. 24
0
    def __init__(self,
                 sessiontype: type[ba.Session],
                 transition: Optional[str] = 'in_right',
                 origin_widget: ba.Widget = None):
        # pylint: disable=too-many-statements
        # pylint: disable=cyclic-import
        from bastd.ui.playlist import PlaylistTypeVars

        # If they provided an origin-widget, scale up from that.
        scale_origin: Optional[tuple[float, float]]
        if origin_widget is not None:
            self._transition_out = 'out_scale'
            scale_origin = origin_widget.get_screen_space_center()
            transition = 'in_scale'
        else:
            self._transition_out = 'out_right'
            scale_origin = None

        # Store state for when we exit the next game.
        if issubclass(sessiontype, ba.DualTeamSession):
            ba.app.ui.set_main_menu_location('Team Game Select')
            ba.set_analytics_screen('Teams Window')
        elif issubclass(sessiontype, ba.FreeForAllSession):
            ba.app.ui.set_main_menu_location('Free-for-All Game Select')
            ba.set_analytics_screen('FreeForAll Window')
        else:
            raise TypeError(f'Invalid sessiontype: {sessiontype}.')
        self._pvars = PlaylistTypeVars(sessiontype)

        self._sessiontype = sessiontype

        self._customize_button: Optional[ba.Widget] = None
        self._sub_width: Optional[float] = None
        self._sub_height: Optional[float] = None

        self._ensure_standard_playlists_exist()

        # Get the current selection (if any).
        self._selected_playlist = ba.app.config.get(self._pvars.config_name +
                                                    ' Playlist Selection')

        uiscale = ba.app.ui.uiscale
        self._width = 900 if uiscale is ba.UIScale.SMALL else 800
        x_inset = 50 if uiscale is ba.UIScale.SMALL else 0
        self._height = (480 if uiscale is ba.UIScale.SMALL else
                        510 if uiscale is ba.UIScale.MEDIUM else 580)

        top_extra = 20 if uiscale is ba.UIScale.SMALL else 0

        super().__init__(root_widget=ba.containerwidget(
            size=(self._width, self._height + top_extra),
            transition=transition,
            toolbar_visibility='menu_full',
            scale_origin_stack_offset=scale_origin,
            scale=(1.69 if uiscale is ba.UIScale.SMALL else
                   1.05 if uiscale is ba.UIScale.MEDIUM else 0.9),
            stack_offset=(0, -26) if uiscale is ba.UIScale.SMALL else (0, 0)))

        self._back_button: Optional[ba.Widget] = ba.buttonwidget(
            parent=self._root_widget,
            position=(59 + x_inset, self._height - 70),
            size=(120, 60),
            scale=1.0,
            on_activate_call=self._on_back_press,
            autoselect=True,
            label=ba.Lstr(resource='backText'),
            button_type='back')
        ba.containerwidget(edit=self._root_widget,
                           cancel_button=self._back_button)
        txt = self._title_text = ba.textwidget(
            parent=self._root_widget,
            position=(self._width * 0.5, self._height - 41),
            size=(0, 0),
            text=self._pvars.window_title_name,
            scale=1.3,
            res_scale=1.5,
            color=ba.app.ui.heading_color,
            h_align='center',
            v_align='center')
        if uiscale is ba.UIScale.SMALL and ba.app.ui.use_toolbars:
            ba.textwidget(edit=txt, text='')

        ba.buttonwidget(edit=self._back_button,
                        button_type='backSmall',
                        size=(60, 54),
                        position=(59 + x_inset, self._height - 67),
                        label=ba.charstr(ba.SpecialChar.BACK))

        if uiscale is ba.UIScale.SMALL and ba.app.ui.use_toolbars:
            self._back_button.delete()
            self._back_button = None
            ba.containerwidget(edit=self._root_widget,
                               on_cancel_call=self._on_back_press)
            scroll_offs = 33
        else:
            scroll_offs = 0
        self._scroll_width = self._width - (100 + 2 * x_inset)
        self._scroll_height = (self._height -
                               (146 if uiscale is ba.UIScale.SMALL
                                and ba.app.ui.use_toolbars else 136))
        self._scrollwidget = ba.scrollwidget(
            parent=self._root_widget,
            highlight=False,
            size=(self._scroll_width, self._scroll_height),
            position=((self._width - self._scroll_width) * 0.5,
                      65 + scroll_offs))
        ba.containerwidget(edit=self._scrollwidget, claims_left_right=True)
        self._subcontainer: Optional[ba.Widget] = None
        self._config_name_full = self._pvars.config_name + ' Playlists'
        self._last_config = None

        # Update now and once per second.
        # (this should do our initial refresh)
        self._update()
        self._update_timer = ba.Timer(1.0,
                                      ba.WeakCall(self._update),
                                      timetype=ba.TimeType.REAL,
                                      repeat=True)