2019-10-11 13:35:21 -07:00

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)