Source code for bauiv1lib.profile.upgrade

# Released under the MIT License. See LICENSE for details.
#
"""UI for player profile upgrades."""

from __future__ import annotations

import time
import weakref
from typing import TYPE_CHECKING

import bauiv1 as bui

if TYPE_CHECKING:
    from typing import Any

    from bauiv1lib.profile.edit import EditProfileWindow


[docs] class ProfileUpgradeWindow(bui.Window): """Window for player profile upgrades to global.""" def __init__( self, edit_profile_window: EditProfileWindow, transition: str = 'in_right', ): if bui.app.classic is None: raise RuntimeError('This requires classic.') plus = bui.app.plus assert plus is not None self._r = 'editProfileWindow' self._width = 680 self._height = 350 assert bui.app.classic is not None uiscale = bui.app.ui_v1.uiscale self._base_scale = ( 2.05 if uiscale is bui.UIScale.SMALL else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.2 ) self._upgrade_start_time: float | None = None self._name = edit_profile_window.getname() self._edit_profile_window = weakref.ref(edit_profile_window) top_extra = 15 if uiscale is bui.UIScale.SMALL else 15 super().__init__( root_widget=bui.containerwidget( size=(self._width, self._height + top_extra), toolbar_visibility='menu_currency', transition=transition, scale=self._base_scale, stack_offset=( (0, 15) if uiscale is bui.UIScale.SMALL else (0, 0) ), ) ) cancel_button = bui.buttonwidget( parent=self._root_widget, position=(52, 30), size=(155, 60), scale=0.8, autoselect=True, label=bui.Lstr(resource='cancelText'), on_activate_call=self._cancel, ) self._upgrade_button = bui.buttonwidget( parent=self._root_widget, position=(self._width - 190, 30), size=(155, 60), scale=0.8, autoselect=True, label=bui.Lstr(resource='upgradeText'), on_activate_call=self._on_upgrade_press, ) bui.containerwidget( edit=self._root_widget, cancel_button=cancel_button, start_button=self._upgrade_button, selected_child=self._upgrade_button, ) assert bui.app.classic is not None bui.textwidget( parent=self._root_widget, position=(self._width * 0.5, self._height - 38), size=(0, 0), text=bui.Lstr(resource=self._r + '.upgradeToGlobalProfileText'), color=bui.app.ui_v1.title_color, maxwidth=self._width * 0.45, scale=1.0, h_align='center', v_align='center', ) assert bui.app.classic is not None bui.textwidget( parent=self._root_widget, position=(self._width * 0.5, self._height - 100), size=(0, 0), text=bui.Lstr(resource=self._r + '.upgradeProfileInfoText'), color=bui.app.ui_v1.infotextcolor, maxwidth=self._width * 0.8, scale=0.7, h_align='center', v_align='center', ) self._status_text = bui.textwidget( parent=self._root_widget, position=(self._width * 0.5, self._height - 160), size=(0, 0), text=bui.Lstr( resource=self._r + '.checkingAvailabilityText', subs=[('${NAME}', self._name)], ), color=(0.8, 0.4, 0.0), maxwidth=self._width * 0.8, scale=0.65, h_align='center', v_align='center', ) self._price_text = bui.textwidget( parent=self._root_widget, position=(self._width * 0.5, self._height - 230), size=(0, 0), text='', color=(0.2, 1, 0.2), maxwidth=self._width * 0.8, scale=1.5, h_align='center', v_align='center', ) self._tickets_text: bui.Widget | None if not bui.app.ui_v1.use_toolbars: self._tickets_text = bui.textwidget( parent=self._root_widget, position=(self._width * 0.9 - 5, self._height - 30), size=(0, 0), text=bui.charstr(bui.SpecialChar.TICKET) + '123', color=(0.2, 1, 0.2), maxwidth=100, scale=0.5, h_align='right', v_align='center', ) else: self._tickets_text = None bui.app.classic.master_server_v1_get( 'bsGlobalProfileCheck', {'name': self._name, 'b': bui.app.env.engine_build_number}, callback=bui.WeakCall(self._profile_check_result), ) self._cost = plus.get_v1_account_misc_read_val( 'price.global_profile', 500 ) self._status: str | None = 'waiting' self._update_timer = bui.AppTimer( 1.0, bui.WeakCall(self._update), repeat=True ) self._update() def _profile_check_result(self, result: dict[str, Any] | None) -> None: if result is None: bui.textwidget( edit=self._status_text, text=bui.Lstr(resource='internal.unavailableNoConnectionText'), color=(1, 0, 0), ) self._status = 'error' bui.buttonwidget( edit=self._upgrade_button, color=(0.4, 0.4, 0.4), textcolor=(0.5, 0.5, 0.5), ) else: if result['available']: bui.textwidget( edit=self._status_text, text=bui.Lstr( resource=self._r + '.availableText', subs=[('${NAME}', self._name)], ), color=(0, 1, 0), ) bui.textwidget( edit=self._price_text, text=bui.charstr(bui.SpecialChar.TICKET) + str(self._cost), ) self._status = None else: bui.textwidget( edit=self._status_text, text=bui.Lstr( resource=self._r + '.unavailableText', subs=[('${NAME}', self._name)], ), color=(1, 0, 0), ) self._status = 'unavailable' bui.buttonwidget( edit=self._upgrade_button, color=(0.4, 0.4, 0.4), textcolor=(0.5, 0.5, 0.5), ) def _on_upgrade_press(self) -> None: from bauiv1lib import getcurrency if self._status is None: plus = bui.app.plus assert plus is not None # If it appears we don't have enough tickets, offer to buy more. tickets = plus.get_v1_account_ticket_count() if tickets < self._cost: bui.getsound('error').play() getcurrency.show_get_tickets_prompt() return bui.screenmessage( bui.Lstr(resource='purchasingText'), color=(0, 1, 0) ) self._status = 'pre_upgrading' # Now we tell the original editor to save the profile, add an # upgrade transaction, and then sit and wait for everything to # go through. edit_profile_window = self._edit_profile_window() if edit_profile_window is None: print('profile upgrade: original edit window gone') return success = edit_profile_window.save(transition_out=False) if not success: print('profile upgrade: error occurred saving profile') bui.screenmessage( bui.Lstr(resource='errorText'), color=(1, 0, 0) ) bui.getsound('error').play() return plus.add_v1_account_transaction( {'type': 'UPGRADE_PROFILE', 'name': self._name} ) plus.run_v1_account_transactions() self._status = 'upgrading' self._upgrade_start_time = time.time() else: bui.getsound('error').play() def _update(self) -> None: plus = bui.app.plus assert plus is not None try: t_str = str(plus.get_v1_account_ticket_count()) except Exception: t_str = '?' if self._tickets_text is not None: bui.textwidget( edit=self._tickets_text, text=bui.Lstr( resource='getTicketsWindow.youHaveShortText', subs=[ ( '${COUNT}', bui.charstr(bui.SpecialChar.TICKET) + t_str, ) ], ), ) # Once we've kicked off an upgrade attempt and all transactions go # through, we're done. if ( self._status == 'upgrading' and not plus.have_outstanding_v1_account_transactions() ): self._status = 'exiting' bui.containerwidget(edit=self._root_widget, transition='out_right') edit_profile_window = self._edit_profile_window() if edit_profile_window is None: print( 'profile upgrade transition out:' ' original edit window gone' ) return bui.getsound('gunCocking').play() edit_profile_window.reload_window() def _cancel(self) -> None: # If we recently sent out an upgrade request, disallow canceling # for a bit. if ( self._upgrade_start_time is not None and time.time() - self._upgrade_start_time < 10.0 ): bui.getsound('error').play() return bui.containerwidget(edit=self._root_widget, transition='out_right')