mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-25 08:23:35 +08:00
352 lines
10 KiB
Python
352 lines
10 KiB
Python
# Copyright (c) 2011-2019 Eric Froemling
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
# of this software and associated documentation files (the "Software"), to deal
|
|
# in the Software without restriction, including without limitation the rights
|
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
# copies of the Software, and to permit persons to whom the Software is
|
|
# furnished to do so, subject to the following conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be included in
|
|
# all copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
# SOFTWARE.
|
|
# -----------------------------------------------------------------------------
|
|
"""Snippets of code for use by the internal C++ layer.
|
|
|
|
History: originally I would dynamically compile/eval bits of Python text
|
|
from within C++ code, but the major downside there was that I would
|
|
never catch code breakage until the code was next run. By defining all
|
|
snippets I use here and then capturing references to them all at launch
|
|
I can verify everything I'm looking for exists and pylint can do
|
|
its magic on this file.
|
|
"""
|
|
# (most of these are self-explanatory)
|
|
# pylint: disable=missing-function-docstring
|
|
from __future__ import annotations
|
|
|
|
from typing import TYPE_CHECKING
|
|
|
|
import _ba
|
|
|
|
if TYPE_CHECKING:
|
|
from typing import List, Sequence, Optional
|
|
import ba
|
|
|
|
|
|
def reset_to_main_menu() -> None:
|
|
"""Reset the game to the main menu gracefully."""
|
|
_ba.app.return_to_main_menu_session_gracefully()
|
|
|
|
|
|
def set_config_fullscreen_on() -> None:
|
|
"""The app has set fullscreen on its own and we should note it."""
|
|
_ba.app.config['Fullscreen'] = True
|
|
_ba.app.config.commit()
|
|
|
|
|
|
def set_config_fullscreen_off() -> None:
|
|
"""The app has set fullscreen on its own and we should note it."""
|
|
_ba.app.config['Fullscreen'] = False
|
|
_ba.app.config.commit()
|
|
|
|
|
|
def not_signed_in_screen_message() -> None:
|
|
from ba._lang import Lstr
|
|
_ba.screenmessage(Lstr(resource='notSignedInErrorText'))
|
|
|
|
|
|
def connecting_to_party_message() -> None:
|
|
from ba._lang import Lstr
|
|
_ba.screenmessage(Lstr(resource='internal.connectingToPartyText'),
|
|
color=(1, 1, 1))
|
|
|
|
|
|
def rejecting_invite_already_in_party_message() -> None:
|
|
from ba._lang import Lstr
|
|
_ba.screenmessage(
|
|
Lstr(resource='internal.rejectingInviteAlreadyInPartyText'),
|
|
color=(1, 0.5, 0))
|
|
|
|
|
|
def connection_failed_message() -> None:
|
|
from ba._lang import Lstr
|
|
_ba.screenmessage(Lstr(resource='internal.connectionFailedText'),
|
|
color=(1, 0.5, 0))
|
|
|
|
|
|
def temporarily_unavailable_message() -> None:
|
|
from ba._lang import Lstr
|
|
_ba.playsound(_ba.getsound('error'))
|
|
_ba.screenmessage(
|
|
Lstr(resource='getTicketsWindow.unavailableTemporarilyText'),
|
|
color=(1, 0, 0))
|
|
|
|
|
|
def in_progress_message() -> None:
|
|
from ba._lang import Lstr
|
|
_ba.playsound(_ba.getsound('error'))
|
|
_ba.screenmessage(Lstr(resource='getTicketsWindow.inProgressText'),
|
|
color=(1, 0, 0))
|
|
|
|
|
|
def error_message() -> None:
|
|
from ba._lang import Lstr
|
|
_ba.playsound(_ba.getsound('error'))
|
|
_ba.screenmessage(Lstr(resource='errorText'), color=(1, 0, 0))
|
|
|
|
|
|
def purchase_not_valid_error() -> None:
|
|
from ba._lang import Lstr
|
|
_ba.playsound(_ba.getsound('error'))
|
|
_ba.screenmessage(Lstr(resource='store.purchaseNotValidError',
|
|
subs=[('${EMAIL}', 'support@froemling.net')]),
|
|
color=(1, 0, 0))
|
|
|
|
|
|
def purchase_already_in_progress_error() -> None:
|
|
from ba._lang import Lstr
|
|
_ba.playsound(_ba.getsound('error'))
|
|
_ba.screenmessage(Lstr(resource='store.purchaseAlreadyInProgressText'),
|
|
color=(1, 0, 0))
|
|
|
|
|
|
def gear_vr_controller_warning() -> None:
|
|
from ba._lang import Lstr
|
|
_ba.playsound(_ba.getsound('error'))
|
|
_ba.screenmessage(Lstr(resource='usesExternalControllerText'),
|
|
color=(1, 0, 0))
|
|
|
|
|
|
def orientation_reset_cb_message() -> None:
|
|
from ba._lang import Lstr
|
|
_ba.screenmessage(
|
|
Lstr(resource='internal.vrOrientationResetCardboardText'),
|
|
color=(0, 1, 0))
|
|
|
|
|
|
def orientation_reset_message() -> None:
|
|
from ba._lang import Lstr
|
|
_ba.screenmessage(Lstr(resource='internal.vrOrientationResetText'),
|
|
color=(0, 1, 0))
|
|
|
|
|
|
def handle_app_resume() -> None:
|
|
_ba.app.handle_app_resume()
|
|
|
|
|
|
def launch_main_menu_session() -> None:
|
|
from bastd.mainmenu import MainMenuSession
|
|
_ba.new_host_session(MainMenuSession)
|
|
|
|
|
|
def language_test_toggle() -> None:
|
|
from ba._lang import setlanguage
|
|
setlanguage('Gibberish' if _ba.app.language == 'English' else 'English')
|
|
|
|
|
|
def award_in_control_achievement() -> None:
|
|
from ba._achievement import award_local_achievement
|
|
award_local_achievement('In Control')
|
|
|
|
|
|
def award_dual_wielding_achievement() -> None:
|
|
from ba._achievement import award_local_achievement
|
|
award_local_achievement('Dual Wielding')
|
|
|
|
|
|
def play_gong_sound() -> None:
|
|
_ba.playsound(_ba.getsound('gong'))
|
|
|
|
|
|
def launch_coop_game(name: str) -> None:
|
|
_ba.app.launch_coop_game(name)
|
|
|
|
|
|
def purchases_restored_message() -> None:
|
|
from ba._lang import Lstr
|
|
_ba.screenmessage(Lstr(resource='getTicketsWindow.purchasesRestoredText'),
|
|
color=(0, 1, 0))
|
|
|
|
|
|
def dismiss_wii_remotes_window() -> None:
|
|
call = _ba.app.dismiss_wii_remotes_window_call
|
|
if call is not None:
|
|
# Weird; this seems to trigger pylint only sometimes.
|
|
# pylint: disable=useless-suppression
|
|
# pylint: disable=not-callable
|
|
call()
|
|
|
|
|
|
def unavailable_message() -> None:
|
|
from ba._lang import Lstr
|
|
_ba.screenmessage(Lstr(resource='getTicketsWindow.unavailableText'),
|
|
color=(1, 0, 0))
|
|
|
|
|
|
def submit_analytics_counts(sval: str) -> None:
|
|
_ba.add_transaction({'type': 'ANALYTICS_COUNTS', 'values': sval})
|
|
_ba.run_transactions()
|
|
|
|
|
|
def set_last_ad_network(sval: str) -> None:
|
|
import time
|
|
_ba.app.last_ad_network = sval
|
|
_ba.app.last_ad_network_set_time = time.time()
|
|
|
|
|
|
def no_game_circle_message() -> None:
|
|
from ba._lang import Lstr
|
|
_ba.screenmessage(Lstr(resource='noGameCircleText'), color=(1, 0, 0))
|
|
|
|
|
|
def empty_call() -> None:
|
|
pass
|
|
|
|
|
|
def level_icon_press() -> None:
|
|
print('LEVEL ICON PRESSED')
|
|
|
|
|
|
def trophy_icon_press() -> None:
|
|
print('TROPHY ICON PRESSED')
|
|
|
|
|
|
def coin_icon_press() -> None:
|
|
print('COIN ICON PRESSED')
|
|
|
|
|
|
def ticket_icon_press() -> None:
|
|
from bastd.ui.resourcetypeinfo import ResourceTypeInfoWindow
|
|
ResourceTypeInfoWindow(
|
|
origin_widget=_ba.get_special_widget('tickets_info_button'))
|
|
|
|
|
|
def back_button_press() -> None:
|
|
_ba.back_press()
|
|
|
|
|
|
def friends_button_press() -> None:
|
|
print('FRIEND BUTTON PRESSED!')
|
|
|
|
|
|
def print_trace() -> None:
|
|
import traceback
|
|
print('Python Traceback (most recent call last):')
|
|
traceback.print_stack()
|
|
|
|
|
|
def toggle_fullscreen() -> None:
|
|
cfg = _ba.app.config
|
|
cfg['Fullscreen'] = not cfg.resolve('Fullscreen')
|
|
cfg.apply_and_commit()
|
|
|
|
|
|
def party_icon_activate(origin: Sequence[float]) -> None:
|
|
import weakref
|
|
from bastd.ui.party import PartyWindow
|
|
app = _ba.app
|
|
_ba.playsound(_ba.getsound('swish'))
|
|
|
|
# If it exists, dismiss it; otherwise make a new one.
|
|
if app.party_window is not None and app.party_window() is not None:
|
|
app.party_window().close()
|
|
else:
|
|
app.party_window = weakref.ref(PartyWindow(origin=origin))
|
|
|
|
|
|
def read_config() -> None:
|
|
_ba.app.read_config()
|
|
|
|
|
|
def ui_remote_press() -> None:
|
|
"""Handle a press by a remote device that is only usable for nav."""
|
|
from ba._lang import Lstr
|
|
_ba.screenmessage(Lstr(resource="internal.controllerForMenusOnlyText"),
|
|
color=(1, 0, 0))
|
|
_ba.playsound(_ba.getsound('error'))
|
|
|
|
|
|
def quit_window() -> None:
|
|
from bastd.ui.confirm import QuitWindow
|
|
QuitWindow()
|
|
|
|
|
|
def remove_in_game_ads_message() -> None:
|
|
_ba.app.do_remove_in_game_ads_message()
|
|
|
|
|
|
def telnet_access_request() -> None:
|
|
from bastd.ui.telnet import TelnetAccessRequestWindow
|
|
TelnetAccessRequestWindow()
|
|
|
|
|
|
def app_pause() -> None:
|
|
_ba.app.handle_app_pause()
|
|
|
|
|
|
def do_quit() -> None:
|
|
_ba.quit()
|
|
|
|
|
|
def shutdown() -> None:
|
|
_ba.app.shutdown()
|
|
|
|
|
|
def gc_disable() -> None:
|
|
import gc
|
|
gc.disable()
|
|
|
|
|
|
def device_menu_press(device: ba.InputDevice) -> None:
|
|
from bastd.ui.mainmenu import MainMenuWindow
|
|
in_main_menu = bool(_ba.app.main_menu_window)
|
|
if not in_main_menu:
|
|
_ba.set_ui_input_device(device)
|
|
_ba.playsound(_ba.getsound('swish'))
|
|
_ba.app.main_menu_window = (MainMenuWindow().get_root_widget())
|
|
|
|
|
|
def show_url_window(address: str) -> None:
|
|
from bastd.ui.url import ShowURLWindow
|
|
ShowURLWindow(address)
|
|
|
|
|
|
def party_invite_revoke(invite_id: str) -> None:
|
|
# If there's a confirm window up for joining this particular
|
|
# invite, kill it.
|
|
for winref in _ba.app.invite_confirm_windows:
|
|
win = winref()
|
|
if win is not None and win.ew_party_invite_id == invite_id:
|
|
_ba.containerwidget(edit=win.get_root_widget(),
|
|
transition='out_right')
|
|
|
|
|
|
def filter_chat_message(msg: str, client_id: int) -> Optional[str]:
|
|
"""Intercept/filter chat messages.
|
|
|
|
Called for all chat messages while hosting.
|
|
Messages originating from the host will have clientID -1.
|
|
Should filter and return the string to be displayed, or return None
|
|
to ignore the message.
|
|
"""
|
|
del client_id # Unused by default.
|
|
return msg
|
|
|
|
|
|
def local_chat_message(msg: str) -> None:
|
|
if (_ba.app.party_window is not None
|
|
and _ba.app.party_window() is not None):
|
|
_ba.app.party_window().on_chat_message(msg)
|
|
|
|
|
|
def handle_remote_achievement_list(completed_achievements: List[str]) -> None:
|
|
from ba import _achievement
|
|
_achievement.set_completed_achievements(completed_achievements)
|