mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-19 21:37:57 +08:00
more work on tokens
This commit is contained in:
parent
9acbc2c94f
commit
ee007b15db
88
.efrocachemap
generated
88
.efrocachemap
generated
@ -4062,50 +4062,50 @@
|
||||
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
|
||||
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
|
||||
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
|
||||
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "de1a31ddd37764c6a31c6c619a0069fe",
|
||||
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "1a4894c9eb324e6d2a442f72e5651c2c",
|
||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "1999d90958ff312203a290aaff97a24f",
|
||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "9a33cde90e447754e0b669f1e08948b2",
|
||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "c52c4b14e87cada2d2de8060caf64ec3",
|
||||
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "4894e58ac2fa3cbff0c0542e33afd94e",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "eee4b5407e69075d925fad94de12c0b8",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "5d041c76ab815765179308a01b6a0028",
|
||||
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "8ae3a85f68553255fa47a86e35cd41b0",
|
||||
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "cd9dac595579b8e19f15eade2cf8155f",
|
||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "1ab4f141dd2541ae40e886b5d448d86f",
|
||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "fb869f599357cb079851542411b2a852",
|
||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "d06777b1f953c4f102d3ddb5b9d79337",
|
||||
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "ac0582306bab0108da45dc53e0c544a7",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "f847c697c1d541bbd1207355065fa988",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "6edc275e5c427a04df8b02b115d2d832",
|
||||
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "473ef626512034b43a8fa54ad66af1ce",
|
||||
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "45f6a37d5e21b45542260f86b7c4784b",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "4d9922c7ba8e15e2059fcef7f87d195a",
|
||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "fd57a5b64d0fc65bd04bbfdd4b63965d",
|
||||
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "fbfd42ab5d27e3ff921fa9cda02b2b45",
|
||||
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "abb5870a4b01cda2c9a958149f759325",
|
||||
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "fbfd42ab5d27e3ff921fa9cda02b2b45",
|
||||
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "abb5870a4b01cda2c9a958149f759325",
|
||||
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "1b51a49163d412cdd0b1441e3459e6c4",
|
||||
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "4a39d8397fb76df3bafa366d8085d1cd",
|
||||
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "1b51a49163d412cdd0b1441e3459e6c4",
|
||||
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "4a39d8397fb76df3bafa366d8085d1cd",
|
||||
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "c4ed230b63e7109de342e045733963e5",
|
||||
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "adb7ef762cb92b4c3bbe74a36e8ac6df",
|
||||
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "c4ed230b63e7109de342e045733963e5",
|
||||
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "adb7ef762cb92b4c3bbe74a36e8ac6df",
|
||||
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "0863bb24d2a42598dd20e7b55beb1c02",
|
||||
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "1805fd5900917411f0e8032bf3c4734c",
|
||||
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "3277c2f61c315e2ca7ed6776ba2363e2",
|
||||
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "1805fd5900917411f0e8032bf3c4734c",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "b639992e280ee3a73b764a3e3e58baec",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "5ebaf4315d286080e5789939edfe43ce",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "be8f76ded92473fbab8b28018097456c",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "dcab88e3c14c6f4c4a03dd8617328eaf",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "bab18c50134744a7206ea1ded2d90ab2",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "c6788ba7cd99fc29a0b6ca8351f412b4",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "e61726c963e53ee7746ffbd7ed35c919",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "841fbbd6b87ac5d50ccdda647d8ff909",
|
||||
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "9698e65459797b5a87072643f548f4ab",
|
||||
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "e02eb31d2e4065e0436fc96232248fc5",
|
||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "c79f227c4164afcd09ea70f8828c2f22",
|
||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "6d4f68f726a373fdc179230a72a92324",
|
||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "c285dfc219ba755f5abfbbe09b9aa9b8",
|
||||
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "dd0b580b172574f14ef51789acfcc8f2",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "69619ebd570b57f59ab3648aa6d3590a",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "916f649191e81cc23e35818016e220df",
|
||||
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "c2c725f438afe35aaade8b007d812e46",
|
||||
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "6da83421d80c824fe9fe6f13b5f7991e",
|
||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "f621b7c2e34f55dc8af7ca41bc4dc4ed",
|
||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "2aa7d4c4008d6be2fc172a2375d47fed",
|
||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "c51e187921cff4b389a345a0f87f364b",
|
||||
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "5a74d47d994cbdf24da77462ef66ab55",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "f25707a21481e3c45e7dbefc46b544f0",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "9ace2a7c76cc66b8f9eab4d689a6ea49",
|
||||
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "6e40b5fb42a16bfeeebf71aabeab1007",
|
||||
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "8505048dfc05e7c02328bfbc359e23b3",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "a73f6abea43df032adb422ad5be2f486",
|
||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "cba67113f21cca2a51772ca92fc3f113",
|
||||
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "61badc0ac176ef98abeba3ffa7a0c6d6",
|
||||
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "79862c15f8121428281bb328b3d19e08",
|
||||
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "61badc0ac176ef98abeba3ffa7a0c6d6",
|
||||
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "79862c15f8121428281bb328b3d19e08",
|
||||
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "b47a86a58800dadefce197ee923c07c7",
|
||||
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "7d5c7f92343fa4c0690995a0335afed8",
|
||||
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "b47a86a58800dadefce197ee923c07c7",
|
||||
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "7d5c7f92343fa4c0690995a0335afed8",
|
||||
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "bb72cb9f98d48a5f572733db4095c449",
|
||||
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "cc8aea2f632599441196a35fd1dc927a",
|
||||
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "bb72cb9f98d48a5f572733db4095c449",
|
||||
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "cc8aea2f632599441196a35fd1dc927a",
|
||||
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "60b7e716cd73097cd29654a1787dcc5d",
|
||||
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "c1c40ab7f37c200b366dc6d4dbceb2a6",
|
||||
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "f4cf12b15ecca349357f6fa68541b8e5",
|
||||
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "c1c40ab7f37c200b366dc6d4dbceb2a6",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "3d9473e959782490836d1e76f20dc5ad",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "2887132d17a9909f02e6a12110e747a1",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "7fc343bf0a59b0b77496c5a32e53ae4a",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "2d32ced3489090b4331f690ed6e43c22",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "0380d3daa1497385764b2bb190430567",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "a4c2a736cc9f100a1115defa962448a7",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "bfb0fcd3fc53dcfed5022c9880df6033",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "a648e37862105c638c05c2e833470764",
|
||||
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
|
||||
"src/assets/ba_data/python/babase/_mgen/enums.py": "cb299985623bbcc86015cb103a424ae6",
|
||||
"src/ballistica/base/mgen/pyembed/binding_base.inc": "efa61468cf098f77cc6a234461d8b86d",
|
||||
|
||||
@ -1,4 +1,8 @@
|
||||
### 1.7.36 (build 21919, api 8, 2024-07-21)
|
||||
### 1.7.36 (build 21928, api 8, 2024-07-22)
|
||||
- Wired up Tokens, BombSquad's new purchasable currency. The first thing these
|
||||
can be used for is storage packs on ballistica.net, but this will expand to
|
||||
other places in the game soon. For a full explanation on why these were added,
|
||||
see https://ballistica.net/whataretokens
|
||||
- Wired up initial support for using asset-packages for bundled assets.
|
||||
- bacloud workspace commands are now a bit smarter; you can now do things like
|
||||
`bacloud workspace put .` or even just `bacloud workspace put` and it will
|
||||
|
||||
@ -52,7 +52,7 @@ if TYPE_CHECKING:
|
||||
|
||||
# Build number and version of the ballistica binary we expect to be
|
||||
# using.
|
||||
TARGET_BALLISTICA_BUILD = 21919
|
||||
TARGET_BALLISTICA_BUILD = 21928
|
||||
TARGET_BALLISTICA_VERSION = '1.7.36'
|
||||
|
||||
|
||||
|
||||
@ -4,16 +4,15 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import time
|
||||
from enum import Enum
|
||||
from functools import partial
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING, assert_never
|
||||
|
||||
import bacommon.cloud
|
||||
|
||||
import bauiv1 as bui
|
||||
from bauiv1lib.connectivity import wait_for_connectivity
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Callable
|
||||
@ -58,8 +57,13 @@ class _TxtDef:
|
||||
class GetTokensWindow(bui.Window):
|
||||
"""Window for purchasing/acquiring classic tickets."""
|
||||
|
||||
def __del__(self) -> None:
|
||||
print('~GetTokensWindow()')
|
||||
class State(Enum):
|
||||
"""What are we doing?"""
|
||||
|
||||
LOADING = 'loading'
|
||||
NOT_SIGNED_IN = 'not_signed_in'
|
||||
HAVE_GOLD_PASS = 'have_gold_pass'
|
||||
SHOWING_STORE = 'showing_store'
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@ -291,6 +295,12 @@ class GetTokensWindow(bui.Window):
|
||||
self._restore_previous_call = restore_previous_call
|
||||
self._textcolor = (0.92, 0.92, 2.0)
|
||||
|
||||
self._query_in_flight = False
|
||||
self._last_query_time = -1.0
|
||||
self._last_query_response: bacommon.cloud.StoreQueryResponse | None = (
|
||||
None
|
||||
)
|
||||
|
||||
# If they provided an origin-widget, scale up from that.
|
||||
scale_origin: tuple[float, float] | None
|
||||
if origin_widget is not None:
|
||||
@ -350,7 +360,7 @@ class GetTokensWindow(bui.Window):
|
||||
|
||||
bui.containerwidget(edit=self._root_widget, cancel_button=btn)
|
||||
|
||||
bui.textwidget(
|
||||
self._title_text = bui.textwidget(
|
||||
parent=self._root_widget,
|
||||
position=(self._width * 0.5, self._height - 47),
|
||||
size=(0, 0),
|
||||
@ -366,6 +376,7 @@ class GetTokensWindow(bui.Window):
|
||||
|
||||
self._status_text = bui.textwidget(
|
||||
parent=self._root_widget,
|
||||
size=(0, 0),
|
||||
position=(self._width * 0.5, self._height * 0.5),
|
||||
h_align='center',
|
||||
v_align='center',
|
||||
@ -374,40 +385,117 @@ class GetTokensWindow(bui.Window):
|
||||
text='Loading...',
|
||||
)
|
||||
|
||||
self._core_widgets = [
|
||||
self._back_button,
|
||||
self._title_text,
|
||||
self._status_text,
|
||||
]
|
||||
|
||||
self._token_count_widget: bui.Widget | None = None
|
||||
self._smooth_update_timer: bui.AppTimer | None = None
|
||||
self._smooth_token_count: float | None = None
|
||||
self._token_count: int = 0
|
||||
self._smooth_increase_speed = 1.0
|
||||
self._ticking_sound: bui.Sound | None = None
|
||||
|
||||
# Get all textures used by our buttons preloading so hopefully
|
||||
# they'll be in place by the time we show them.
|
||||
for bdef in self._buttondefs:
|
||||
for bimg in bdef.imgdefs:
|
||||
bui.gettexture(bimg.tex)
|
||||
|
||||
# Wait for a master-server connection if need be. Otherwise we
|
||||
# could error if called at the wrong time even with an internet
|
||||
# connection, which is unintuitive.
|
||||
wait_for_connectivity(
|
||||
on_connected=bui.WeakCall(self._on_have_connectivity),
|
||||
on_cancel=bui.WeakCall(self._back),
|
||||
self._state = self.State.LOADING
|
||||
|
||||
self._update_timer = bui.AppTimer(
|
||||
0.789, bui.WeakCall(self._update), repeat=True
|
||||
)
|
||||
self._update()
|
||||
|
||||
def _on_have_connectivity(self) -> None:
|
||||
plus = bui.app.plus
|
||||
assert plus is not None
|
||||
def __del__(self) -> None:
|
||||
if self._ticking_sound is not None:
|
||||
self._ticking_sound.stop()
|
||||
self._ticking_sound = None
|
||||
|
||||
# Sanity check; we need to be signed in. (we should not be
|
||||
# allowed to get here if we aren't, but it could happen for
|
||||
# fluke-ish reasons.)
|
||||
if plus.accounts.primary is None:
|
||||
bui.screenmessage(
|
||||
bui.Lstr(resource='notSignedInErrorText'), color=(1, 0, 0)
|
||||
)
|
||||
bui.getsound('error').play()
|
||||
self._back()
|
||||
def _update(self) -> None:
|
||||
# No-op if our underlying widget is dead or on its way out.
|
||||
if not self._root_widget or self._root_widget.transitioning_out:
|
||||
return
|
||||
|
||||
with plus.accounts.primary:
|
||||
plus.cloud.send_message_cb(
|
||||
bacommon.cloud.StoreQueryMessage(),
|
||||
on_response=bui.WeakCall(self._on_store_query_response),
|
||||
plus = bui.app.plus
|
||||
|
||||
if plus is None or plus.accounts.primary is None:
|
||||
self._update_state(self.State.NOT_SIGNED_IN)
|
||||
return
|
||||
|
||||
# Poll for relevant changes to the store or our account.
|
||||
now = time.monotonic()
|
||||
if not self._query_in_flight and now - self._last_query_time > 2.0:
|
||||
self._last_query_time = now
|
||||
self._query_in_flight = True
|
||||
with plus.accounts.primary:
|
||||
plus.cloud.send_message_cb(
|
||||
bacommon.cloud.StoreQueryMessage(),
|
||||
on_response=bui.WeakCall(self._on_store_query_response),
|
||||
)
|
||||
|
||||
# Can't do much until we get a store state.
|
||||
if self._last_query_response is None:
|
||||
return
|
||||
|
||||
# If we've got a gold-pass, just show that. No need to offer any
|
||||
# other purchases.
|
||||
if self._last_query_response.gold_pass:
|
||||
self._update_state(self.State.HAVE_GOLD_PASS)
|
||||
return
|
||||
|
||||
# Ok we seem to be signed in and have store stuff we can show.
|
||||
# Do that.
|
||||
self._update_state(self.State.SHOWING_STORE)
|
||||
|
||||
def _update_state(self, state: State) -> None:
|
||||
|
||||
# We don't do much when state is unchanged.
|
||||
if state is self._state:
|
||||
# Update a few things in store mode though, such as token
|
||||
# count.
|
||||
if state is self.State.SHOWING_STORE:
|
||||
self._update_store_state()
|
||||
return
|
||||
|
||||
# Ok, state is changing. Start by resetting to a blank slate.
|
||||
self._token_count_widget = None
|
||||
for widget in self._root_widget.get_children():
|
||||
if widget not in self._core_widgets:
|
||||
widget.delete()
|
||||
|
||||
# Build up new state.
|
||||
if state is self.State.NOT_SIGNED_IN:
|
||||
bui.textwidget(
|
||||
edit=self._status_text,
|
||||
color=(1, 0, 0),
|
||||
text=bui.Lstr(resource='notSignedInErrorText'),
|
||||
)
|
||||
elif state is self.State.LOADING:
|
||||
raise RuntimeError('Should never return to loading state.')
|
||||
elif state is self.State.HAVE_GOLD_PASS:
|
||||
bui.textwidget(
|
||||
edit=self._status_text,
|
||||
color=(0, 1, 0),
|
||||
text=(
|
||||
'You have a Gold Pass.\n'
|
||||
'All token purchases are free.\n'
|
||||
'Enjoy!'
|
||||
),
|
||||
)
|
||||
elif state is self.State.SHOWING_STORE:
|
||||
assert self._last_query_response is not None
|
||||
bui.textwidget(edit=self._status_text, text='')
|
||||
self._build_store_for_response(self._last_query_response)
|
||||
else:
|
||||
# Make sure we handle all cases.
|
||||
assert_never(state)
|
||||
|
||||
self._state = state
|
||||
|
||||
def _on_load_error(self) -> None:
|
||||
bui.textwidget(
|
||||
@ -418,20 +506,19 @@ class GetTokensWindow(bui.Window):
|
||||
|
||||
def _on_store_query_response(
|
||||
self, response: bacommon.cloud.StoreQueryResponse | Exception
|
||||
) -> None:
|
||||
self._query_in_flight = False
|
||||
if isinstance(response, bacommon.cloud.StoreQueryResponse):
|
||||
self._last_query_response = response
|
||||
# Hurry along any effects of this response.
|
||||
self._update()
|
||||
|
||||
def _build_store_for_response(
|
||||
self, response: bacommon.cloud.StoreQueryResponse
|
||||
) -> None:
|
||||
# pylint: disable=too-many-locals
|
||||
|
||||
plus = bui.app.plus
|
||||
|
||||
# If our message failed, just error and back out.
|
||||
if isinstance(response, Exception):
|
||||
logging.info('Store query failed.', exc_info=response)
|
||||
|
||||
bui.screenmessage(bui.Lstr(resource='errorText'), color=(1, 0, 0))
|
||||
bui.getsound('error').play()
|
||||
self._back()
|
||||
return
|
||||
|
||||
bui.textwidget(edit=self._status_text, text='')
|
||||
|
||||
xinset = 40
|
||||
@ -559,7 +646,7 @@ class GetTokensWindow(bui.Window):
|
||||
v_align='center',
|
||||
text='BombSquad\'s shiny new currency.',
|
||||
)
|
||||
_tnumtxt = bui.textwidget(
|
||||
self._token_count_widget = bui.textwidget(
|
||||
parent=self._root_widget,
|
||||
position=(self._width - self._x_inset - 120.0, self._height - 48),
|
||||
color=(2.0, 0.7, 0.0),
|
||||
@ -568,8 +655,12 @@ class GetTokensWindow(bui.Window):
|
||||
size=(0, 0),
|
||||
h_align='left',
|
||||
v_align='center',
|
||||
text=str(response.tokens),
|
||||
text='',
|
||||
)
|
||||
self._token_count = response.tokens
|
||||
self._smooth_token_count = float(self._token_count)
|
||||
self._smooth_update() # will set the text widget.
|
||||
|
||||
_tlabeltxt = bui.textwidget(
|
||||
parent=self._root_widget,
|
||||
position=(self._width - self._x_inset - 123.0, self._height - 48),
|
||||
@ -592,15 +683,83 @@ class GetTokensWindow(bui.Window):
|
||||
# Looks like purchases will never work here.
|
||||
errmsg = (
|
||||
'Sorry, purchases are not available on this build.\n'
|
||||
'As a fallback, sign in to this account on another'
|
||||
' platform and make purchases from there.'
|
||||
'Try signing into your account on another platform'
|
||||
' and making purchases from there.'
|
||||
)
|
||||
|
||||
bui.screenmessage(errmsg, color=(1, 0.5, 0))
|
||||
bui.getsound('error').play()
|
||||
return
|
||||
|
||||
print(f'WOULD PURCHASE {itemid}')
|
||||
assert plus is not None
|
||||
plus.purchase(itemid)
|
||||
|
||||
def _update_store_state(self) -> None:
|
||||
"""Called to make minor updates to an already shown store."""
|
||||
assert self._token_count_widget is not None
|
||||
assert self._last_query_response is not None
|
||||
|
||||
self._token_count = self._last_query_response.tokens
|
||||
|
||||
# Kick off new smooth update if need be.
|
||||
assert self._smooth_token_count is not None
|
||||
if (
|
||||
self._token_count != int(self._smooth_token_count)
|
||||
and self._smooth_update_timer is None
|
||||
):
|
||||
self._smooth_update_timer = bui.AppTimer(
|
||||
0.05, bui.WeakCall(self._smooth_update), repeat=True
|
||||
)
|
||||
diff = abs(float(self._token_count) - self._smooth_token_count)
|
||||
self._smooth_increase_speed = (
|
||||
diff / 100.0
|
||||
if diff >= 5000
|
||||
else (
|
||||
diff / 50.0
|
||||
if diff >= 1500
|
||||
else diff / 30.0 if diff >= 500 else diff / 15.0
|
||||
)
|
||||
)
|
||||
|
||||
def _smooth_update(self) -> None:
|
||||
|
||||
# Stop if the count widget disappears.
|
||||
if not self._token_count_widget:
|
||||
self._smooth_update_timer = None
|
||||
return
|
||||
|
||||
finished = False
|
||||
|
||||
# If we're going down, do it immediately.
|
||||
assert self._smooth_token_count is not None
|
||||
if int(self._smooth_token_count) >= self._token_count:
|
||||
self._smooth_token_count = float(self._token_count)
|
||||
finished = True
|
||||
else:
|
||||
# We're going up; start a sound if need be.
|
||||
self._smooth_token_count = min(
|
||||
self._smooth_token_count + 1.0 * self._smooth_increase_speed,
|
||||
self._token_count,
|
||||
)
|
||||
if int(self._smooth_token_count) >= self._token_count:
|
||||
finished = True
|
||||
self._smooth_token_count = float(self._token_count)
|
||||
elif self._ticking_sound is None:
|
||||
self._ticking_sound = bui.getsound('scoreIncrease')
|
||||
self._ticking_sound.play()
|
||||
|
||||
bui.textwidget(
|
||||
edit=self._token_count_widget,
|
||||
text=str(int(self._smooth_token_count)),
|
||||
)
|
||||
|
||||
# If we've reached the target, kill the timer/sound/etc.
|
||||
if finished:
|
||||
self._smooth_update_timer = None
|
||||
if self._ticking_sound is not None:
|
||||
self._ticking_sound.stop()
|
||||
self._ticking_sound = None
|
||||
bui.getsound('cashRegister2').play()
|
||||
|
||||
def _back(self) -> None:
|
||||
|
||||
|
||||
@ -41,12 +41,12 @@ void BasePlatformApple::RestorePurchases() {
|
||||
}
|
||||
|
||||
void BasePlatformApple::PurchaseAck(const std::string& purchase,
|
||||
const std::string& order_id) {
|
||||
const std::string& order_id, bool valid) {
|
||||
#if BA_USE_STORE_KIT
|
||||
BallisticaKit::StoreKitContext::purchaseAck(purchase, order_id);
|
||||
// AppleUtils::PurchaseAck(purchase, order_id);
|
||||
#else
|
||||
BasePlatform::PurchaseAck(purchase, order_id);
|
||||
BasePlatform::PurchaseAck(purchase, order_id, valid);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -13,8 +13,8 @@ class BasePlatformApple : public BasePlatform {
|
||||
BasePlatformApple();
|
||||
void DoPurchase(const std::string& item) override;
|
||||
void RestorePurchases() override;
|
||||
void PurchaseAck(const std::string& purchase,
|
||||
const std::string& order_id) override;
|
||||
void PurchaseAck(const std::string& purchase, const std::string& order_id,
|
||||
bool valid) override;
|
||||
void DoOpenURL(const std::string& url) override;
|
||||
auto OverlayWebBrowserIsSupported() -> bool override;
|
||||
void DoOverlayWebBrowserOpenURL(const std::string& url) override;
|
||||
|
||||
@ -106,7 +106,7 @@ void BasePlatform::RestorePurchases() {
|
||||
}
|
||||
|
||||
void BasePlatform::PurchaseAck(const std::string& purchase,
|
||||
const std::string& order_id) {
|
||||
const std::string& order_id, bool valid) {
|
||||
Log(LogLevel::kError, "PurchaseAck() unimplemented");
|
||||
}
|
||||
|
||||
|
||||
@ -52,9 +52,9 @@ class BasePlatform {
|
||||
/// Restore purchases (currently only relevant on Apple platforms).
|
||||
virtual void RestorePurchases();
|
||||
|
||||
/// Purchase was ack'ed by the master-server (so can consume).
|
||||
/// Purchase was ack'ed by the master-server (so can consume or cancel).
|
||||
virtual void PurchaseAck(const std::string& purchase,
|
||||
const std::string& order_id);
|
||||
const std::string& order_id, bool valid);
|
||||
|
||||
#pragma mark ENVIRONMENT -------------------------------------------------------
|
||||
|
||||
|
||||
@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int {
|
||||
namespace ballistica {
|
||||
|
||||
// These are set automatically via script; don't modify them here.
|
||||
const int kEngineBuildNumber = 21919;
|
||||
const int kEngineBuildNumber = 21928;
|
||||
const char* kEngineVersion = "1.7.36";
|
||||
const int kEngineApiVersion = 8;
|
||||
|
||||
|
||||
@ -284,5 +284,7 @@ class StoreQueryResponse(Response):
|
||||
result: Annotated[Result, IOAttrs('r')]
|
||||
|
||||
tokens: Annotated[int, IOAttrs('t')]
|
||||
gold_pass: Annotated[bool, IOAttrs('g')]
|
||||
|
||||
available_purchases: Annotated[list[Purchase], IOAttrs('p')]
|
||||
token_info_url: Annotated[str, IOAttrs('tiu')]
|
||||
|
||||
@ -98,7 +98,10 @@ def run_standard_syncs(
|
||||
|
||||
# Actual syncs require localconfig entries.
|
||||
if link_entry not in localconfig:
|
||||
print(f'No link entry for {src_project}; skipping sync entry.')
|
||||
print(
|
||||
f'No link entry for {src_project}'
|
||||
f' in project {projectroot}; skipping sync entry.'
|
||||
)
|
||||
continue
|
||||
src = Path(localconfig[link_entry], src_subpath)
|
||||
if verbose:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user