mirror of
https://github.com/hypervortex/VH-Bombsquad-Modded-Server-Files
synced 2026-08-15 13:04:50 +00:00
288 lines
9.7 KiB
Python
288 lines
9.7 KiB
Python
# 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 ba
|
|
import ba.internal
|
|
|
|
if TYPE_CHECKING:
|
|
from typing import Any
|
|
from bastd.ui.profile.edit import EditProfileWindow
|
|
|
|
|
|
class ProfileUpgradeWindow(ba.Window):
|
|
"""Window for player profile upgrades to global."""
|
|
|
|
def __init__(
|
|
self,
|
|
edit_profile_window: EditProfileWindow,
|
|
transition: str = 'in_right',
|
|
):
|
|
from ba.internal import master_server_get
|
|
|
|
self._r = 'editProfileWindow'
|
|
|
|
self._width = 680
|
|
self._height = 350
|
|
uiscale = ba.app.ui.uiscale
|
|
self._base_scale = (
|
|
2.05
|
|
if uiscale is ba.UIScale.SMALL
|
|
else 1.5
|
|
if uiscale is ba.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 ba.UIScale.SMALL else 15
|
|
super().__init__(
|
|
root_widget=ba.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 ba.UIScale.SMALL else (0, 0),
|
|
)
|
|
)
|
|
cancel_button = ba.buttonwidget(
|
|
parent=self._root_widget,
|
|
position=(52, 30),
|
|
size=(155, 60),
|
|
scale=0.8,
|
|
autoselect=True,
|
|
label=ba.Lstr(resource='cancelText'),
|
|
on_activate_call=self._cancel,
|
|
)
|
|
self._upgrade_button = ba.buttonwidget(
|
|
parent=self._root_widget,
|
|
position=(self._width - 190, 30),
|
|
size=(155, 60),
|
|
scale=0.8,
|
|
autoselect=True,
|
|
label=ba.Lstr(resource='upgradeText'),
|
|
on_activate_call=self._on_upgrade_press,
|
|
)
|
|
ba.containerwidget(
|
|
edit=self._root_widget,
|
|
cancel_button=cancel_button,
|
|
start_button=self._upgrade_button,
|
|
selected_child=self._upgrade_button,
|
|
)
|
|
|
|
ba.textwidget(
|
|
parent=self._root_widget,
|
|
position=(self._width * 0.5, self._height - 38),
|
|
size=(0, 0),
|
|
text=ba.Lstr(resource=self._r + '.upgradeToGlobalProfileText'),
|
|
color=ba.app.ui.title_color,
|
|
maxwidth=self._width * 0.45,
|
|
scale=1.0,
|
|
h_align='center',
|
|
v_align='center',
|
|
)
|
|
|
|
ba.textwidget(
|
|
parent=self._root_widget,
|
|
position=(self._width * 0.5, self._height - 100),
|
|
size=(0, 0),
|
|
text=ba.Lstr(resource=self._r + '.upgradeProfileInfoText'),
|
|
color=ba.app.ui.infotextcolor,
|
|
maxwidth=self._width * 0.8,
|
|
scale=0.7,
|
|
h_align='center',
|
|
v_align='center',
|
|
)
|
|
|
|
self._status_text = ba.textwidget(
|
|
parent=self._root_widget,
|
|
position=(self._width * 0.5, self._height - 160),
|
|
size=(0, 0),
|
|
text=ba.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 = ba.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: ba.Widget | None
|
|
if not ba.app.ui.use_toolbars:
|
|
self._tickets_text = ba.textwidget(
|
|
parent=self._root_widget,
|
|
position=(self._width * 0.9 - 5, self._height - 30),
|
|
size=(0, 0),
|
|
text=ba.charstr(ba.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
|
|
|
|
master_server_get(
|
|
'bsGlobalProfileCheck',
|
|
{'name': self._name, 'b': ba.app.build_number},
|
|
callback=ba.WeakCall(self._profile_check_result),
|
|
)
|
|
self._cost = ba.internal.get_v1_account_misc_read_val(
|
|
'price.global_profile', 500
|
|
)
|
|
self._status: str | None = 'waiting'
|
|
self._update_timer = ba.Timer(
|
|
1.0,
|
|
ba.WeakCall(self._update),
|
|
timetype=ba.TimeType.REAL,
|
|
repeat=True,
|
|
)
|
|
self._update()
|
|
|
|
def _profile_check_result(self, result: dict[str, Any] | None) -> None:
|
|
if result is None:
|
|
ba.textwidget(
|
|
edit=self._status_text,
|
|
text=ba.Lstr(resource='internal.unavailableNoConnectionText'),
|
|
color=(1, 0, 0),
|
|
)
|
|
self._status = 'error'
|
|
ba.buttonwidget(
|
|
edit=self._upgrade_button,
|
|
color=(0.4, 0.4, 0.4),
|
|
textcolor=(0.5, 0.5, 0.5),
|
|
)
|
|
else:
|
|
if result['available']:
|
|
ba.textwidget(
|
|
edit=self._status_text,
|
|
text=ba.Lstr(
|
|
resource=self._r + '.availableText',
|
|
subs=[('${NAME}', self._name)],
|
|
),
|
|
color=(0, 1, 0),
|
|
)
|
|
ba.textwidget(
|
|
edit=self._price_text,
|
|
text=ba.charstr(ba.SpecialChar.TICKET) + str(self._cost),
|
|
)
|
|
self._status = None
|
|
else:
|
|
ba.textwidget(
|
|
edit=self._status_text,
|
|
text=ba.Lstr(
|
|
resource=self._r + '.unavailableText',
|
|
subs=[('${NAME}', self._name)],
|
|
),
|
|
color=(1, 0, 0),
|
|
)
|
|
self._status = 'unavailable'
|
|
ba.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 bastd.ui import getcurrency
|
|
|
|
if self._status is None:
|
|
# If it appears we don't have enough tickets, offer to buy more.
|
|
tickets = ba.internal.get_v1_account_ticket_count()
|
|
if tickets < self._cost:
|
|
ba.playsound(ba.getsound('error'))
|
|
getcurrency.show_get_tickets_prompt()
|
|
return
|
|
ba.screenmessage(
|
|
ba.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')
|
|
ba.screenmessage(ba.Lstr(resource='errorText'), color=(1, 0, 0))
|
|
ba.playsound(ba.getsound('error'))
|
|
return
|
|
ba.internal.add_transaction(
|
|
{'type': 'UPGRADE_PROFILE', 'name': self._name}
|
|
)
|
|
ba.internal.run_transactions()
|
|
self._status = 'upgrading'
|
|
self._upgrade_start_time = time.time()
|
|
else:
|
|
ba.playsound(ba.getsound('error'))
|
|
|
|
def _update(self) -> None:
|
|
try:
|
|
t_str = str(ba.internal.get_v1_account_ticket_count())
|
|
except Exception:
|
|
t_str = '?'
|
|
if self._tickets_text is not None:
|
|
ba.textwidget(
|
|
edit=self._tickets_text,
|
|
text=ba.Lstr(
|
|
resource='getTicketsWindow.youHaveShortText',
|
|
subs=[
|
|
('${COUNT}', ba.charstr(ba.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 ba.internal.have_outstanding_transactions()
|
|
):
|
|
self._status = 'exiting'
|
|
ba.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
|
|
ba.playsound(ba.getsound('gunCocking'))
|
|
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
|
|
):
|
|
ba.playsound(ba.getsound('error'))
|
|
return
|
|
ba.containerwidget(edit=self._root_widget, transition='out_right')
|