diff --git a/.efrocachemap b/.efrocachemap
index 2a75284a..d84f2ebd 100644
--- a/.efrocachemap
+++ b/.efrocachemap
@@ -3936,20 +3936,20 @@
"build/prefab/full/linux_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/b0/14/defa61c54179e1810f8308cac55c",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/89/2d/9c41cd7bba801f79906a397f9b23",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/78/bb/4656448316b4b5ff7bc348ede9f2",
- "build/prefab/full/mac_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/c0/e0/54ff7942beddb65315194b79da09",
+ "build/prefab/full/mac_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/81/29/9ec99c71737474a1605181bef5c6",
"build/prefab/full/mac_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/5b/52/1771901e2344bad49238986c80b2",
- "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2d/d7/e1ffb234f71e715587456fc7cfd8",
+ "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/24/59/abed30ff7c1966552a0dbfe56810",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/99/88/2ee8c18b63f64425516050c8a304",
- "build/prefab/full/windows_x86/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/ac/a2/75427a8ecc1f19d402b58f9014e6",
- "build/prefab/full/windows_x86/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/d7/d4/4640f90f0ae2d2b98b8fbf099c2f",
- "build/prefab/full/windows_x86_server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/95/94/a110e7c8d338d5a6cefe2e975e8b",
- "build/prefab/full/windows_x86_server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/51/26/638d82bbf9acbfaffd8cfe780671",
+ "build/prefab/full/windows_x86/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/6c/6e/90e03410471ddd69aa2eafa7b3d6",
+ "build/prefab/full/windows_x86/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/1c/da/64018791c880f5ed095d6842c080",
+ "build/prefab/full/windows_x86_server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/44/c4/59ab73c66476bbbacf123db2f3f1",
+ "build/prefab/full/windows_x86_server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/e2/3f/5661800cf25e241eba4f0233192b",
"build/prefab/lib/linux_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/66/c9/3b04209f599dea8b8ca4be7d3404",
"build/prefab/lib/linux_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/0d/3b/b7b46c3131cff8a40dfaa001af38",
"build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/57/40/0c1d88af3ce14e0f8870ab9ac7ad",
"build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/8a/72/02b4eddf662001f05f98288d4ad4",
- "build/prefab/lib/mac_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ac/e6/0e2476b60bfa7d3af4e9a2a6db1f",
- "build/prefab/lib/mac_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f3/81/218f5899da12bcaf1128175e7ef0",
- "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/84/14/923a2f78920255adffe574b613d6",
- "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4e/f0/8e6fdd837a08e6daae5bd9e743dc"
+ "build/prefab/lib/mac_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e1/a1/4d2b0ad4013a93cf040451c17f55",
+ "build/prefab/lib/mac_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3e/b3/3782cbf1a2d3910015eadd6299f0",
+ "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d5/cb/04953a61dd28871b139d5f7af8d1",
+ "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e6/52/2d87920dd7ebc63105afc784e7cd"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8fdf2c8a..689009c4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@
- Ditto with AdsSubsystem and ba.app.ads
- Revamped tab-button functionality into a cleaner type-safe class (bastd.ui.tabs.TabRow)
- Split Gather-Window tabs out into individual classes for future improvements (bastd.ui.gather.*)
+- Added the ability to disable ticket-purchasing UIs for builds (ba.app.allow_ticket_purchases)
### 1.5.26 (20217)
- Simplified licensing header on python scripts.
diff --git a/assets/src/ba_data/python/ba/_app.py b/assets/src/ba_data/python/ba/_app.py
index b07c37b1..502282ab 100644
--- a/assets/src/ba_data/python/ba/_app.py
+++ b/assets/src/ba_data/python/ba/_app.py
@@ -195,6 +195,7 @@ class App:
assert isinstance(self.headless_mode, bool)
self.iircade_mode: bool = self._env['iircade_mode']
assert isinstance(self.headless_mode, bool)
+ self.allow_ticket_purchases: bool = not self.iircade_mode
# Misc.
self.tips: List[str] = []
diff --git a/assets/src/ba_data/python/bastd/ui/getcurrency.py b/assets/src/ba_data/python/bastd/ui/getcurrency.py
index 691fdfe1..db19be22 100644
--- a/assets/src/ba_data/python/bastd/ui/getcurrency.py
+++ b/assets/src/ba_data/python/bastd/ui/getcurrency.py
@@ -588,12 +588,24 @@ class GetCurrencyWindow(ba.Window):
def show_get_tickets_prompt() -> None:
- """Show a prompt to get more currency."""
- from bastd.ui import confirm
- confirm.ConfirmWindow(
- ba.Lstr(translate=('serverResponses',
- 'You don\'t have enough tickets for this!')),
- lambda: GetCurrencyWindow(modal=True),
- ok_text=ba.Lstr(resource='getTicketsWindow.titleText'),
- width=460,
- height=130)
+ """Show a 'not enough tickets' prompt with an option to purchase more.
+
+ Note that the purchase option may not always be available
+ depending on the build of the game.
+ """
+ from bastd.ui.confirm import ConfirmWindow
+ if ba.app.allow_ticket_purchases:
+ ConfirmWindow(
+ ba.Lstr(translate=('serverResponses',
+ 'You don\'t have enough tickets for this!')),
+ lambda: GetCurrencyWindow(modal=True),
+ ok_text=ba.Lstr(resource='getTicketsWindow.titleText'),
+ width=460,
+ height=130)
+ else:
+ ConfirmWindow(
+ ba.Lstr(translate=('serverResponses',
+ 'You don\'t have enough tickets for this!')),
+ cancel_button=False,
+ width=460,
+ height=130)
diff --git a/assets/src/ba_data/python/bastd/ui/settings/allsettings.py b/assets/src/ba_data/python/bastd/ui/settings/allsettings.py
index 32c3e3e8..cd987740 100644
--- a/assets/src/ba_data/python/bastd/ui/settings/allsettings.py
+++ b/assets/src/ba_data/python/bastd/ui/settings/allsettings.py
@@ -209,6 +209,15 @@ class AllSettingsWindow(ba.Window):
# pylint: disable=cyclic-import
from bastd.ui.settings.controls import ControlsSettingsWindow
self._save_state()
+
+ # Disallow this on iircade.
+ if ba.app.iircade_mode:
+ ba.playsound(ba.getsound('error'))
+ ba.screenmessage(
+ ba.Lstr(resource='getTicketsWindow.unavailableText'),
+ color=(1, 0, 0))
+ return
+
ba.containerwidget(edit=self._root_widget, transition='out_left')
ba.app.ui.set_main_menu_window(
ControlsSettingsWindow(
@@ -218,6 +227,15 @@ class AllSettingsWindow(ba.Window):
# pylint: disable=cyclic-import
from bastd.ui.settings.graphics import GraphicsSettingsWindow
self._save_state()
+
+ # Disallow this on iircade.
+ if ba.app.iircade_mode:
+ ba.playsound(ba.getsound('error'))
+ ba.screenmessage(
+ ba.Lstr(resource='getTicketsWindow.unavailableText'),
+ color=(1, 0, 0))
+ return
+
ba.containerwidget(edit=self._root_widget, transition='out_left')
ba.app.ui.set_main_menu_window(
GraphicsSettingsWindow(
diff --git a/assets/src/ba_data/python/bastd/ui/store/browser.py b/assets/src/ba_data/python/bastd/ui/store/browser.py
index 85a697fa..12be6a00 100644
--- a/assets/src/ba_data/python/bastd/ui/store/browser.py
+++ b/assets/src/ba_data/python/bastd/ui/store/browser.py
@@ -97,17 +97,27 @@ class StoreBrowserWindow(ba.Window):
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'))
+ self._ticket_count_text: Optional[ba.Widget] = None
+ self._get_tickets_button: Optional[ba.Widget] = None
+
+ if ba.app.allow_ticket_purchases:
+ 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'))
+ else:
+ self._ticket_count_text = ba.textwidget(parent=self._root_widget,
+ size=(210, 64),
+ color=(0.2, 1.0, 0.2),
+ h_align='center',
+ v_align='center')
# Move this dynamically to keep it out of the way of the party icon.
self._update_get_tickets_button_pos()
@@ -116,8 +126,9 @@ class StoreBrowserWindow(ba.Window):
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)
+ if self._get_tickets_button:
+ 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),
@@ -244,7 +255,7 @@ class StoreBrowserWindow(ba.Window):
repeat=True)
self._update_tabs()
- if self._get_tickets_button is not None:
+ if self._get_tickets_button:
last_tab_button = self._tab_row.tabs[tabs_def[-1][0]].button
ba.widget(edit=self._get_tickets_button,
down_widget=last_tab_button)
@@ -261,12 +272,14 @@ class StoreBrowserWindow(ba.Window):
def _update_get_tickets_button_pos(self) -> None:
uiscale = ba.app.ui.uiscale
- if self._get_tickets_button:
- pos = (self._width - 252 -
- (self._x_inset + (47 if uiscale is ba.UIScale.SMALL
+ pos = (self._width - 252 - (self._x_inset +
+ (47 if uiscale is ba.UIScale.SMALL
and _ba.is_party_icon_visible() else 0)),
- self._height - 70)
+ self._height - 70)
+ if self._get_tickets_button:
ba.buttonwidget(edit=self._get_tickets_button, position=pos)
+ if self._ticket_count_text:
+ ba.textwidget(edit=self._ticket_count_text, position=pos)
def _restore_purchases(self) -> None:
from bastd.ui import account
@@ -316,7 +329,10 @@ class StoreBrowserWindow(ba.Window):
_ba.get_account_ticket_count())
else:
sval = ba.Lstr(resource='getTicketsWindow.titleText')
- ba.buttonwidget(edit=self._get_tickets_button, label=sval)
+ if self._get_tickets_button:
+ ba.buttonwidget(edit=self._get_tickets_button, label=sval)
+ if self._ticket_count_text:
+ ba.textwidget(edit=self._ticket_count_text, text=sval)
def _set_tab(self, tab_id: TabID) -> None:
if self._current_tab is tab_id:
@@ -1014,7 +1030,7 @@ class StoreBrowserWindow(ba.Window):
current_tab = self.TabID.CHARACTERS
if self._show_tab is not None:
current_tab = self._show_tab
- if sel_name == 'GetTickets':
+ if sel_name == 'GetTickets' and self._get_tickets_button:
sel = self._get_tickets_button
elif sel_name == 'Back':
sel = self._back_button
diff --git a/assets/src/ba_data/python/bastd/ui/tournamententry.py b/assets/src/ba_data/python/bastd/ui/tournamententry.py
index 87772b07..2299ec21 100644
--- a/assets/src/ba_data/python/bastd/ui/tournamententry.py
+++ b/assets/src/ba_data/python/bastd/ui/tournamententry.py
@@ -215,20 +215,27 @@ class TournamentEntryWindow(popup.PopupWindow):
else:
self._pay_with_ad_btn = None
- self._get_tickets_button: Optional[ba.Widget]
+ self._get_tickets_button: Optional[ba.Widget] = None
+ self._ticket_count_text: Optional[ba.Widget] = None
if not ba.app.ui.use_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
+ if ba.app.allow_ticket_purchases:
+ 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._ticket_count_text = ba.textwidget(
+ parent=self.root_widget,
+ position=(self._width - 190 + 110, 15),
+ color=(0.2, 1, 0.2),
+ h_align='center',
+ v_align='center')
self._seconds_remaining = None
@@ -416,9 +423,12 @@ class TournamentEntryWindow(popup.PopupWindow):
t_str = str(_ba.get_account_ticket_count())
except Exception:
t_str = '?'
- if self._get_tickets_button is not None:
+ if self._get_tickets_button:
ba.buttonwidget(edit=self._get_tickets_button,
label=ba.charstr(ba.SpecialChar.TICKET) + t_str)
+ if self._ticket_count_text:
+ ba.textwidget(edit=self._ticket_count_text,
+ text=ba.charstr(ba.SpecialChar.TICKET) + t_str)
def _launch(self) -> None:
if self._launched:
diff --git a/ballisticacore-cmake/.idea/dictionaries/ericf.xml b/ballisticacore-cmake/.idea/dictionaries/ericf.xml
index f47ef954..62684921 100644
--- a/ballisticacore-cmake/.idea/dictionaries/ericf.xml
+++ b/ballisticacore-cmake/.idea/dictionaries/ericf.xml
@@ -13,8 +13,8 @@
This page documents the Python classes and functions in the 'ba' module, which are the ones most relevant to modding in Ballistica. If you come across something you feel should be included here or could be better explained, please let me know. Happy modding!