This commit is contained in:
Eric 2023-06-10 21:36:56 -07:00
parent 77dc36f8d0
commit f966ee330d
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
19 changed files with 347 additions and 391 deletions

View File

@ -12,6 +12,7 @@ from efro.util import set_canonical_module_names
import _babase import _babase
from _babase import ( from _babase import (
have_chars,
android_get_external_files_dir, android_get_external_files_dir,
is_os_playing_music, is_os_playing_music,
getsimplesound, getsimplesound,
@ -275,6 +276,7 @@ __all__ = [
'getsimplesound', 'getsimplesound',
'is_os_playing_music', 'is_os_playing_music',
'android_get_external_files_dir', 'android_get_external_files_dir',
'have_chars',
] ]
# We want stuff to show up as babase.Foo instead of babase._sub.Foo. # We want stuff to show up as babase.Foo instead of babase._sub.Foo.

View File

@ -8,8 +8,7 @@ import copy
import time import time
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import _babase import babase
import bauiv1 as bui
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any from typing import Any
@ -40,15 +39,15 @@ class AccountV1Subsystem:
# Auto-sign-in to a local account in a moment if we're set to. # Auto-sign-in to a local account in a moment if we're set to.
def do_auto_sign_in() -> None: def do_auto_sign_in() -> None:
if _babase.app.plus is None: if babase.app.plus is None:
return return
if ( if (
_babase.app.headless_mode babase.app.headless_mode
or _babase.app.config.get('Auto Account State') == 'Local' or babase.app.config.get('Auto Account State') == 'Local'
): ):
_babase.app.plus.sign_in_v1('Local') babase.app.plus.sign_in_v1('Local')
_babase.pushcall(do_auto_sign_in) babase.pushcall(do_auto_sign_in)
def on_app_pause(self) -> None: def on_app_pause(self) -> None:
"""Should be called when app is pausing.""" """Should be called when app is pausing."""
@ -66,16 +65,14 @@ class AccountV1Subsystem:
(internal) (internal)
""" """
from babase._language import Lstr babase.screenmessage(
babase.Lstr(
_babase.screenmessage(
Lstr(
resource='getTicketsWindow.receivedTicketsText', resource='getTicketsWindow.receivedTicketsText',
subs=[('${COUNT}', str(count))], subs=[('${COUNT}', str(count))],
), ),
color=(0, 1, 0), color=(0, 1, 0),
) )
_babase.getsimplesound('cashRegister').play() babase.getsimplesound('cashRegister').play()
def cache_league_rank_data(self, data: Any) -> None: def cache_league_rank_data(self, data: Any) -> None:
"""(internal)""" """(internal)"""
@ -98,8 +95,8 @@ class AccountV1Subsystem:
total_ach_value = data['at'] total_ach_value = data['at']
else: else:
total_ach_value = 0 total_ach_value = 0
assert _babase.app.classic is not None assert babase.app.classic is not None
for ach in _babase.app.classic.ach.achievements: for ach in babase.app.classic.ach.achievements:
if ach.complete: if ach.complete:
total_ach_value += ach.power_ranking_value total_ach_value += ach.power_ranking_value
@ -129,13 +126,13 @@ class AccountV1Subsystem:
raise ValueError('invalid subset value: ' + str(subset)) raise ValueError('invalid subset value: ' + str(subset))
if data['p']: if data['p']:
if _babase.app.plus is None: if babase.app.plus is None:
pro_mult = 1.0 pro_mult = 1.0
else: else:
pro_mult = ( pro_mult = (
1.0 1.0
+ float( + float(
_babase.app.plus.get_v1_account_misc_read_val( babase.app.plus.get_v1_account_misc_read_val(
'proPowerRankingBoost', 0.0 'proPowerRankingBoost', 0.0
) )
) )
@ -161,21 +158,21 @@ class AccountV1Subsystem:
# Also store the time we received this, so we can adjust # Also store the time we received this, so we can adjust
# time-remaining values/etc. # time-remaining values/etc.
cache_entry['timeReceived'] = _babase.apptime() cache_entry['timeReceived'] = babase.apptime()
cache_entry['valid'] = True cache_entry['valid'] = True
def get_purchased_icons(self) -> list[str]: def get_purchased_icons(self) -> list[str]:
"""(internal)""" """(internal)"""
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
plus = _babase.app.plus plus = babase.app.plus
if plus is None: if plus is None:
return [] return []
if plus.get_v1_account_state() != 'signed_in': if plus.get_v1_account_state() != 'signed_in':
return [] return []
icons = [] icons = []
store_items: dict[str, Any] = ( store_items: dict[str, Any] = (
_babase.app.classic.store.get_store_items() babase.app.classic.store.get_store_items()
if _babase.app.classic is not None if babase.app.classic is not None
else {} else {}
) )
for item_name, item in list(store_items.items()): for item_name, item in list(store_items.items()):
@ -190,7 +187,7 @@ class AccountV1Subsystem:
(internal) (internal)
""" """
plus = _babase.app.plus plus = babase.app.plus
if plus is None: if plus is None:
return return
# This only applies when we're signed in. # This only applies when we're signed in.
@ -199,12 +196,12 @@ class AccountV1Subsystem:
# If the short version of our account name currently cant be # If the short version of our account name currently cant be
# displayed by the game, cancel. # displayed by the game, cancel.
if not _babase.have_chars( if not babase.have_chars(
plus.get_v1_account_display_string(full=False) plus.get_v1_account_display_string(full=False)
): ):
return return
config = _babase.app.config config = babase.app.config
if ( if (
'Player Profiles' not in config 'Player Profiles' not in config
or '__account__' not in config['Player Profiles'] or '__account__' not in config['Player Profiles']
@ -226,7 +223,7 @@ class AccountV1Subsystem:
def have_pro(self) -> bool: def have_pro(self) -> bool:
"""Return whether pro is currently unlocked.""" """Return whether pro is currently unlocked."""
plus = _babase.app.plus plus = babase.app.plus
if plus is None: if plus is None:
return False return False
@ -236,7 +233,7 @@ class AccountV1Subsystem:
plus.get_purchased('upgrades.pro') plus.get_purchased('upgrades.pro')
or plus.get_purchased('static.pro') or plus.get_purchased('static.pro')
or plus.get_purchased('static.pro_sale') or plus.get_purchased('static.pro_sale')
or 'ballistica' + 'kit' == _babase.appname() or 'ballistica' + 'kit' == babase.appname()
) )
def have_pro_options(self) -> bool: def have_pro_options(self) -> bool:
@ -246,7 +243,7 @@ class AccountV1Subsystem:
before Pro was a requirement for these options. before Pro was a requirement for these options.
""" """
plus = _babase.app.plus plus = babase.app.plus
if plus is None: if plus is None:
return False return False
@ -256,33 +253,29 @@ class AccountV1Subsystem:
# or are using ballistica-core builds. # or are using ballistica-core builds.
return self.have_pro() or bool( return self.have_pro() or bool(
plus.get_v1_account_misc_read_val_2('proOptionsUnlocked', False) plus.get_v1_account_misc_read_val_2('proOptionsUnlocked', False)
or _babase.app.config.get('lc14292', 0) > 1 or babase.app.config.get('lc14292', 0) > 1
) )
def show_post_purchase_message(self) -> None: def show_post_purchase_message(self) -> None:
"""(internal)""" """(internal)"""
from babase._language import Lstr cur_time = babase.apptime()
cur_time = _babase.apptime()
if ( if (
self.last_post_purchase_message_time is None self.last_post_purchase_message_time is None
or cur_time - self.last_post_purchase_message_time > 3.0 or cur_time - self.last_post_purchase_message_time > 3.0
): ):
self.last_post_purchase_message_time = cur_time self.last_post_purchase_message_time = cur_time
_babase.screenmessage( babase.screenmessage(
Lstr( babase.Lstr(
resource='updatingAccountText', resource='updatingAccountText',
fallback_resource='purchasingText', fallback_resource='purchasingText',
), ),
color=(0, 1, 0), color=(0, 1, 0),
) )
_babase.getsimplesound('click01').play() babase.getsimplesound('click01').play()
def on_account_state_changed(self) -> None: def on_account_state_changed(self) -> None:
"""(internal)""" """(internal)"""
from babase._language import Lstr plus = babase.app.plus
plus = _babase.app.plus
if plus is None: if plus is None:
return return
# Run any pending promo codes we had queued up while not signed in. # Run any pending promo codes we had queued up while not signed in.
@ -291,8 +284,9 @@ class AccountV1Subsystem:
and self.pending_promo_codes and self.pending_promo_codes
): ):
for code in self.pending_promo_codes: for code in self.pending_promo_codes:
_babase.screenmessage( babase.screenmessage(
Lstr(resource='submittingPromoCodeText'), color=(0, 1, 0) babase.Lstr(resource='submittingPromoCodeText'),
color=(0, 1, 0),
) )
plus.add_v1_account_transaction( plus.add_v1_account_transaction(
{ {
@ -306,12 +300,12 @@ class AccountV1Subsystem:
def add_pending_promo_code(self, code: str) -> None: def add_pending_promo_code(self, code: str) -> None:
"""(internal)""" """(internal)"""
from babase._language import Lstr plus = babase.app.plus
plus = _babase.app.plus
if plus is None: if plus is None:
_babase.screenmessage(Lstr(resource='errorText'), color=(1, 0, 0)) babase.screenmessage(
_babase.getsimplesound('error').play() babase.Lstr(resource='errorText'), color=(1, 0, 0)
)
babase.getsimplesound('error').play()
return return
# If we're not signed in, queue up the code to run the next time we # If we're not signed in, queue up the code to run the next time we
@ -325,16 +319,17 @@ class AccountV1Subsystem:
# If we're still not signed in and have pending codes, # If we're still not signed in and have pending codes,
# inform the user that they need to sign in to use them. # inform the user that they need to sign in to use them.
if self.pending_promo_codes: if self.pending_promo_codes:
_babase.screenmessage( babase.screenmessage(
Lstr(resource='signInForPromoCodeText'), color=(1, 0, 0) babase.Lstr(resource='signInForPromoCodeText'),
color=(1, 0, 0),
) )
_babase.getsimplesound('error').play() babase.getsimplesound('error').play()
self.pending_promo_codes.append(code) self.pending_promo_codes.append(code)
bui.apptimer(6.0, check_pending_codes) babase.apptimer(6.0, check_pending_codes)
return return
_babase.screenmessage( babase.screenmessage(
Lstr(resource='submittingPromoCodeText'), color=(0, 1, 0) babase.Lstr(resource='submittingPromoCodeText'), color=(0, 1, 0)
) )
plus.add_v1_account_transaction( plus.add_v1_account_transaction(
{'type': 'PROMO_CODE', 'expire_time': time.time() + 5, 'code': code} {'type': 'PROMO_CODE', 'expire_time': time.time() + 5, 'code': code}

View File

@ -6,17 +6,13 @@ from __future__ import annotations
import logging import logging
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import _babase import babase
from babase._error import print_exception import bascenev1
import _bascenev1 import bauiv1
import _bauiv1
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any, Sequence from typing import Any, Sequence
import babase
import bascenev1
import bauiv1
import baclassic import baclassic
# This could use some cleanup. # This could use some cleanup.
@ -82,7 +78,7 @@ class AchievementSubsystem:
self.achievements_to_display: ( self.achievements_to_display: (
list[tuple[baclassic.Achievement, bool]] list[tuple[baclassic.Achievement, bool]]
) = [] ) = []
self.achievement_display_timer: _bascenev1.BaseTimer | None = None self.achievement_display_timer: bascenev1.BaseTimer | None = None
self.last_achievement_display_time: float = 0.0 self.last_achievement_display_time: float = 0.0
self.achievement_completion_banner_slots: set[int] = set() self.achievement_completion_banner_slots: set[int] = set()
self._init_achievements() self._init_achievements()
@ -516,7 +512,7 @@ class AchievementSubsystem:
def award_local_achievement(self, achname: str) -> None: def award_local_achievement(self, achname: str) -> None:
"""For non-game-based achievements such as controller-connection.""" """For non-game-based achievements such as controller-connection."""
plus = _babase.app.plus plus = babase.app.plus
if plus is None: if plus is None:
logging.warning('achievements require plus feature-set') logging.warning('achievements require plus feature-set')
return return
@ -535,7 +531,7 @@ class AchievementSubsystem:
self.display_achievement_banner(achname) self.display_achievement_banner(achname)
except Exception: except Exception:
print_exception() logging.exception('Error in award_local_achievement.')
def display_achievement_banner(self, achname: str) -> None: def display_achievement_banner(self, achname: str) -> None:
"""Display a completion banner for an achievement. """Display a completion banner for an achievement.
@ -549,12 +545,12 @@ class AchievementSubsystem:
# purely local context somehow instead of trying to inject these # purely local context somehow instead of trying to inject these
# into whatever activity happens to be active # into whatever activity happens to be active
# (since that won't work while in client mode). # (since that won't work while in client mode).
activity = _bascenev1.get_foreground_host_activity() activity = bascenev1.get_foreground_host_activity()
if activity is not None: if activity is not None:
with activity.context: with activity.context:
self.get_achievement(achname).announce_completion() self.get_achievement(achname).announce_completion()
except Exception: except Exception:
print_exception('error showing server ach') logging.exception('Error in display_achievement_banner.')
def set_completed_achievements(self, achs: Sequence[str]) -> None: def set_completed_achievements(self, achs: Sequence[str]) -> None:
"""Set the current state of completed achievements. """Set the current state of completed achievements.
@ -568,7 +564,7 @@ class AchievementSubsystem:
# us which achievements we currently have. We always defer to them, # us which achievements we currently have. We always defer to them,
# even if that means we have to un-set an achievement we think we have. # even if that means we have to un-set an achievement we think we have.
cfg = _babase.app.config cfg = babase.app.config
cfg['Achievements'] = {} cfg['Achievements'] = {}
for a_name in achs: for a_name in achs:
self.get_achievement(a_name).set_complete(True) self.get_achievement(a_name).set_complete(True)
@ -608,8 +604,8 @@ class AchievementSubsystem:
self.achievements[4].announce_completion() self.achievements[4].announce_completion()
self.achievements[5].announce_completion() self.achievements[5].announce_completion()
_bascenev1.basetimer(3.0, testcall1) bascenev1.basetimer(3.0, testcall1)
_bascenev1.basetimer(7.0, testcall2) bascenev1.basetimer(7.0, testcall2)
def _get_ach_mult(include_pro_bonus: bool = False) -> int: def _get_ach_mult(include_pro_bonus: bool = False) -> int:
@ -617,8 +613,8 @@ def _get_ach_mult(include_pro_bonus: bool = False) -> int:
(just for display; changing this here won't affect actual rewards) (just for display; changing this here won't affect actual rewards)
""" """
plus = _babase.app.plus plus = babase.app.plus
classic = _babase.app.classic classic = babase.app.classic
if plus is None or classic is None: if plus is None or classic is None:
return 5 return 5
val: int = plus.get_v1_account_misc_read_val('achAwardMult', 5) val: int = plus.get_v1_account_misc_read_val('achAwardMult', 5)
@ -631,7 +627,7 @@ def _get_ach_mult(include_pro_bonus: bool = False) -> int:
def _display_next_achievement() -> None: def _display_next_achievement() -> None:
# Pull the first achievement off the list and display it, or kill the # Pull the first achievement off the list and display it, or kill the
# display-timer if the list is empty. # display-timer if the list is empty.
app = _babase.app app = babase.app
assert app.classic is not None assert app.classic is not None
ach_ss = app.classic.ach ach_ss = app.classic.ach
if app.classic.ach.achievements_to_display: if app.classic.ach.achievements_to_display:
@ -639,7 +635,7 @@ def _display_next_achievement() -> None:
ach, sound = ach_ss.achievements_to_display.pop(0) ach, sound = ach_ss.achievements_to_display.pop(0)
ach.show_completion_banner(sound) ach.show_completion_banner(sound)
except Exception: except Exception:
print_exception('error showing next achievement') logging.exception('Error in _display_next_achievement.')
ach_ss.achievements_to_display = [] ach_ss.achievements_to_display = []
ach_ss.achievement_display_timer = None ach_ss.achievement_display_timer = None
else: else:
@ -681,13 +677,13 @@ class Achievement:
def get_icon_ui_texture(self, complete: bool) -> bauiv1.Texture: def get_icon_ui_texture(self, complete: bool) -> bauiv1.Texture:
"""Return the icon texture to display for this achievement""" """Return the icon texture to display for this achievement"""
return _bauiv1.gettexture( return bauiv1.gettexture(
self._icon_name if complete else 'achievementEmpty' self._icon_name if complete else 'achievementEmpty'
) )
def get_icon_texture(self, complete: bool) -> bascenev1.Texture: def get_icon_texture(self, complete: bool) -> bascenev1.Texture:
"""Return the icon texture to display for this achievement""" """Return the icon texture to display for this achievement"""
return _bascenev1.gettexture( return bascenev1.gettexture(
self._icon_name if complete else 'achievementEmpty' self._icon_name if complete else 'achievementEmpty'
) )
@ -712,7 +708,7 @@ class Achievement:
def announce_completion(self, sound: bool = True) -> None: def announce_completion(self, sound: bool = True) -> None:
"""Kick off an announcement for this achievement's completion.""" """Kick off an announcement for this achievement's completion."""
app = _babase.app app = babase.app
plus = app.plus plus = app.plus
classic = app.classic classic = app.classic
if plus is None or classic is None: if plus is None or classic is None:
@ -739,9 +735,9 @@ class Achievement:
# clear itself if an activity died and took it down with it. # clear itself if an activity died and took it down with it.
if ( if (
ach_ss.achievement_display_timer is None ach_ss.achievement_display_timer is None
or _babase.apptime() - ach_ss.last_achievement_display_time > 2.0 or babase.apptime() - ach_ss.last_achievement_display_time > 2.0
) and _bascenev1.getactivity(doraise=False) is not None: ) and bascenev1.getactivity(doraise=False) is not None:
ach_ss.achievement_display_timer = _bascenev1.BaseTimer( ach_ss.achievement_display_timer = bascenev1.BaseTimer(
1.0, _display_next_achievement, repeat=True 1.0, _display_next_achievement, repeat=True
) )
@ -761,13 +757,11 @@ class Achievement:
@property @property
def display_name(self) -> babase.Lstr: def display_name(self) -> babase.Lstr:
"""Return a babase.Lstr for this Achievement's name.""" """Return a babase.Lstr for this Achievement's name."""
from babase._language import Lstr
name: babase.Lstr | str name: babase.Lstr | str
try: try:
if self._level_name != '': if self._level_name != '':
campaignname, campaign_level = self._level_name.split(':') campaignname, campaign_level = self._level_name.split(':')
classic = _babase.app.classic classic = babase.app.classic
assert classic is not None assert classic is not None
name = ( name = (
classic.getcampaign(campaignname) classic.getcampaign(campaignname)
@ -778,8 +772,8 @@ class Achievement:
name = '' name = ''
except Exception: except Exception:
name = '' name = ''
print_exception() logging.exception('Error calcing achievement display-name.')
return Lstr( return babase.Lstr(
resource='achievements.' + self._name + '.name', resource='achievements.' + self._name + '.name',
subs=[('${LEVEL}', name)], subs=[('${LEVEL}', name)],
) )
@ -787,42 +781,40 @@ class Achievement:
@property @property
def description(self) -> babase.Lstr: def description(self) -> babase.Lstr:
"""Get a babase.Lstr for the Achievement's brief description.""" """Get a babase.Lstr for the Achievement's brief description."""
from babase._language import Lstr
if ( if (
'description' 'description'
in _babase.app.lang.get_resource('achievements')[self._name] in babase.app.lang.get_resource('achievements')[self._name]
): ):
return Lstr(resource='achievements.' + self._name + '.description') return babase.Lstr(
return Lstr(resource='achievements.' + self._name + '.descriptionFull') resource='achievements.' + self._name + '.description'
)
return babase.Lstr(
resource='achievements.' + self._name + '.descriptionFull'
)
@property @property
def description_complete(self) -> babase.Lstr: def description_complete(self) -> babase.Lstr:
"""Get a babase.Lstr for the Achievement's description when complete.""" """Get a babase.Lstr for the Achievement's description when complete."""
from babase._language import Lstr
if ( if (
'descriptionComplete' 'descriptionComplete'
in _babase.app.lang.get_resource('achievements')[self._name] in babase.app.lang.get_resource('achievements')[self._name]
): ):
return Lstr( return babase.Lstr(
resource='achievements.' + self._name + '.descriptionComplete' resource='achievements.' + self._name + '.descriptionComplete'
) )
return Lstr( return babase.Lstr(
resource='achievements.' + self._name + '.descriptionFullComplete' resource='achievements.' + self._name + '.descriptionFullComplete'
) )
@property @property
def description_full(self) -> babase.Lstr: def description_full(self) -> babase.Lstr:
"""Get a babase.Lstr for the Achievement's full description.""" """Get a babase.Lstr for the Achievement's full description."""
from babase._language import Lstr return babase.Lstr(
return Lstr(
resource='achievements.' + self._name + '.descriptionFull', resource='achievements.' + self._name + '.descriptionFull',
subs=[ subs=[
( (
'${LEVEL}', '${LEVEL}',
Lstr( babase.Lstr(
translate=( translate=(
'coopLevelNames', 'coopLevelNames',
ACH_LEVEL_NAMES.get(self._name, '?'), ACH_LEVEL_NAMES.get(self._name, '?'),
@ -835,14 +827,12 @@ class Achievement:
@property @property
def description_full_complete(self) -> babase.Lstr: def description_full_complete(self) -> babase.Lstr:
"""Get a babase.Lstr for the Achievement's full desc. when completed.""" """Get a babase.Lstr for the Achievement's full desc. when completed."""
from babase._language import Lstr return babase.Lstr(
return Lstr(
resource='achievements.' + self._name + '.descriptionFullComplete', resource='achievements.' + self._name + '.descriptionFullComplete',
subs=[ subs=[
( (
'${LEVEL}', '${LEVEL}',
Lstr( babase.Lstr(
translate=( translate=(
'coopLevelNames', 'coopLevelNames',
ACH_LEVEL_NAMES.get(self._name, '?'), ACH_LEVEL_NAMES.get(self._name, '?'),
@ -854,7 +844,7 @@ class Achievement:
def get_award_ticket_value(self, include_pro_bonus: bool = False) -> int: def get_award_ticket_value(self, include_pro_bonus: bool = False) -> int:
"""Get the ticket award value for this achievement.""" """Get the ticket award value for this achievement."""
plus = _babase.app.plus plus = babase.app.plus
if plus is None: if plus is None:
return 0 return 0
val: int = plus.get_v1_account_misc_read_val( val: int = plus.get_v1_account_misc_read_val(
@ -866,7 +856,7 @@ class Achievement:
@property @property
def power_ranking_value(self) -> int: def power_ranking_value(self) -> int:
"""Get the power-ranking award value for this achievement.""" """Get the power-ranking award value for this achievement."""
plus = _babase.app.plus plus = babase.app.plus
if plus is None: if plus is None:
return 0 return 0
val: int = plus.get_v1_account_misc_read_val( val: int = plus.get_v1_account_misc_read_val(
@ -889,9 +879,7 @@ class Achievement:
Shows the Achievement icon, name, and description. Shows the Achievement icon, name, and description.
""" """
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from babase._language import Lstr from bascenev1 import CoopSession
from babase._mgen.enums import SpecialChar
from bascenev1._coopsession import CoopSession
from bascenev1lib.actor.image import Image from bascenev1lib.actor.image import Image
from bascenev1lib.actor.text import Text from bascenev1lib.actor.text import Text
@ -923,7 +911,7 @@ class Achievement:
hmo = False hmo = False
else: else:
try: try:
session = _bascenev1.getsession() session = bascenev1.getsession()
if isinstance(session, CoopSession): if isinstance(session, CoopSession):
campaign = session.campaign campaign = session.campaign
assert campaign is not None assert campaign is not None
@ -931,7 +919,7 @@ class Achievement:
else: else:
hmo = False hmo = False
except Exception: except Exception:
print_exception('Error determining campaign.') logging.exception('Error determining campaign.')
hmo = False hmo = False
objs: list[bascenev1.Actor] objs: list[bascenev1.Actor]
@ -1007,7 +995,7 @@ class Achievement:
if hmo: if hmo:
txtactor = Text( txtactor = Text(
Lstr(resource='difficultyHardOnlyText'), babase.Lstr(resource='difficultyHardOnlyText'),
host_only=True, host_only=True,
maxwidth=txt2_max_w * 0.7, maxwidth=txt2_max_w * 0.7,
position=(x + 60, y + 5), position=(x + 60, y + 5),
@ -1031,7 +1019,7 @@ class Achievement:
award_x = -100 award_x = -100
objs.append( objs.append(
Text( Text(
_babase.charstr(SpecialChar.TICKET), babase.charstr(babase.SpecialChar.TICKET),
host_only=True, host_only=True,
position=(x + award_x + 33, y + 7), position=(x + award_x + 33, y + 7),
transition=Text.Transition.FADE_IN, transition=Text.Transition.FADE_IN,
@ -1086,9 +1074,9 @@ class Achievement:
if complete: if complete:
objs.append( objs.append(
Image( Image(
_bascenev1.gettexture('achievementOutline'), bascenev1.gettexture('achievementOutline'),
host_only=True, host_only=True,
mesh_transparent=_bascenev1.getmesh( mesh_transparent=bascenev1.getmesh(
'achievementOutline' 'achievementOutline'
), ),
color=(2, 1.4, 0.4, 1), color=(2, 1.4, 0.4, 1),
@ -1106,7 +1094,7 @@ class Achievement:
award_x = -100 award_x = -100
objs.append( objs.append(
Text( Text(
_babase.charstr(SpecialChar.TICKET), babase.charstr(babase.SpecialChar.TICKET),
host_only=True, host_only=True,
position=(x + award_x + 33, y + 7), position=(x + award_x + 33, y + 7),
transition=Text.Transition.IN_RIGHT, transition=Text.Transition.IN_RIGHT,
@ -1142,7 +1130,7 @@ class Achievement:
# when that's the case. # when that's the case.
if hmo: if hmo:
txtactor = Text( txtactor = Text(
Lstr(resource='difficultyHardOnlyText'), babase.Lstr(resource='difficultyHardOnlyText'),
host_only=True, host_only=True,
maxwidth=300 * 0.7, maxwidth=300 * 0.7,
position=(x + 60, y + 5), position=(x + 60, y + 5),
@ -1211,14 +1199,14 @@ class Achievement:
Return the sub-dict in settings where this achievement's Return the sub-dict in settings where this achievement's
state is stored, creating it if need be. state is stored, creating it if need be.
""" """
val: dict[str, Any] = _babase.app.config.setdefault( val: dict[str, Any] = babase.app.config.setdefault(
'Achievements', {} 'Achievements', {}
).setdefault(self._name, {'Complete': False}) ).setdefault(self._name, {'Complete': False})
assert isinstance(val, dict) assert isinstance(val, dict)
return val return val
def _remove_banner_slot(self) -> None: def _remove_banner_slot(self) -> None:
classic = _babase.app.classic classic = babase.app.classic
assert classic is not None assert classic is not None
assert self._completion_banner_slot is not None assert self._completion_banner_slot is not None
classic.ach.achievement_completion_banner_slots.remove( classic.ach.achievement_completion_banner_slots.remove(
@ -1228,21 +1216,16 @@ class Achievement:
def show_completion_banner(self, sound: bool = True) -> None: def show_completion_banner(self, sound: bool = True) -> None:
"""Create the banner/sound for an acquired achievement announcement.""" """Create the banner/sound for an acquired achievement announcement."""
from babase._general import WeakCall
from babase._language import Lstr
from babase._mgen.enums import SpecialChar
from bascenev1lib.actor.text import Text from bascenev1lib.actor.text import Text
from bascenev1lib.actor.image import Image from bascenev1lib.actor.image import Image
from bascenev1 import _gameutils
from bascenev1._messages import DieMessage
app = _babase.app app = babase.app
assert app.classic is not None assert app.classic is not None
app.classic.ach.last_achievement_display_time = _babase.apptime() app.classic.ach.last_achievement_display_time = babase.apptime()
# Just piggy-back onto any current activity # Just piggy-back onto any current activity
# (should we use the session instead?..) # (should we use the session instead?..)
activity = _bascenev1.getactivity(doraise=False) activity = bascenev1.getactivity(doraise=False)
# If this gets called while this achievement is occupying a slot # If this gets called while this achievement is occupying a slot
# already, ignore it. (probably should never happen in real # already, ignore it. (probably should never happen in real
@ -1255,10 +1238,10 @@ class Achievement:
return return
if sound: if sound:
_bascenev1.getsound('achievement').play(host_only=True) bascenev1.getsound('achievement').play(host_only=True)
else: else:
_bascenev1.timer( bascenev1.timer(
0.5, lambda: _bascenev1.getsound('ding').play(host_only=True) 0.5, lambda: bascenev1.getsound('ding').play(host_only=True)
) )
in_time = 0.300 in_time = 0.300
@ -1276,8 +1259,8 @@ class Achievement:
# Remove us from that slot when we close. # Remove us from that slot when we close.
# Use an app-timer in an empty context so the removal # Use an app-timer in an empty context so the removal
# runs even if our activity/session dies. # runs even if our activity/session dies.
with _babase.ContextRef.empty(): with babase.ContextRef.empty():
_babase.apptimer( babase.apptimer(
in_time + out_time, self._remove_banner_slot in_time + out_time, self._remove_banner_slot
) )
break break
@ -1286,7 +1269,7 @@ class Achievement:
y_offs = 110 * self._completion_banner_slot y_offs = 110 * self._completion_banner_slot
objs: list[bascenev1.Actor] = [] objs: list[bascenev1.Actor] = []
obj = Image( obj = Image(
_bascenev1.gettexture('shadow'), bascenev1.gettexture('shadow'),
position=(-30, 30 + y_offs), position=(-30, 30 + y_offs),
front=True, front=True,
attach=Image.Attach.BOTTOM_CENTER, attach=Image.Attach.BOTTOM_CENTER,
@ -1301,7 +1284,7 @@ class Achievement:
assert obj.node assert obj.node
obj.node.host_only = True obj.node.host_only = True
obj = Image( obj = Image(
_bascenev1.gettexture('light'), bascenev1.gettexture('light'),
position=(-180, 60 + y_offs), position=(-180, 60 + y_offs),
front=True, front=True,
attach=Image.Attach.BOTTOM_CENTER, attach=Image.Attach.BOTTOM_CENTER,
@ -1316,10 +1299,10 @@ class Achievement:
assert obj.node assert obj.node
obj.node.host_only = True obj.node.host_only = True
obj.node.premultiplied = True obj.node.premultiplied = True
combine = _bascenev1.newnode( combine = bascenev1.newnode(
'combine', owner=obj.node, attrs={'size': 2} 'combine', owner=obj.node, attrs={'size': 2}
) )
_gameutils.animate( bascenev1.animate(
combine, combine,
'input0', 'input0',
{ {
@ -1330,7 +1313,7 @@ class Achievement:
in_time + 2.0: 0, in_time + 2.0: 0,
}, },
) )
_gameutils.animate( bascenev1.animate(
combine, combine,
'input1', 'input1',
{ {
@ -1342,7 +1325,7 @@ class Achievement:
}, },
) )
combine.connectattr('output', obj.node, 'scale') combine.connectattr('output', obj.node, 'scale')
_gameutils.animate(obj.node, 'rotate', {0: 0.0, 0.35: 360.0}, loop=True) bascenev1.animate(obj.node, 'rotate', {0: 0.0, 0.35: 360.0}, loop=True)
obj = Image( obj = Image(
self.get_icon_texture(True), self.get_icon_texture(True),
position=(-180, 60 + y_offs), position=(-180, 60 + y_offs),
@ -1360,7 +1343,7 @@ class Achievement:
# Flash. # Flash.
color = self.get_icon_color(True) color = self.get_icon_color(True)
combine = _bascenev1.newnode( combine = bascenev1.newnode(
'combine', owner=obj.node, attrs={'size': 3} 'combine', owner=obj.node, attrs={'size': 3}
) )
keys = { keys = {
@ -1370,7 +1353,7 @@ class Achievement:
in_time + 0.6: 1.5 * color[0], in_time + 0.6: 1.5 * color[0],
in_time + 2.0: 1.0 * color[0], in_time + 2.0: 1.0 * color[0],
} }
_gameutils.animate(combine, 'input0', keys) bascenev1.animate(combine, 'input0', keys)
keys = { keys = {
in_time: 1.0 * color[1], in_time: 1.0 * color[1],
in_time + 0.4: 1.5 * color[1], in_time + 0.4: 1.5 * color[1],
@ -1378,7 +1361,7 @@ class Achievement:
in_time + 0.6: 1.5 * color[1], in_time + 0.6: 1.5 * color[1],
in_time + 2.0: 1.0 * color[1], in_time + 2.0: 1.0 * color[1],
} }
_gameutils.animate(combine, 'input1', keys) bascenev1.animate(combine, 'input1', keys)
keys = { keys = {
in_time: 1.0 * color[2], in_time: 1.0 * color[2],
in_time + 0.4: 1.5 * color[2], in_time + 0.4: 1.5 * color[2],
@ -1386,12 +1369,12 @@ class Achievement:
in_time + 0.6: 1.5 * color[2], in_time + 0.6: 1.5 * color[2],
in_time + 2.0: 1.0 * color[2], in_time + 2.0: 1.0 * color[2],
} }
_gameutils.animate(combine, 'input2', keys) bascenev1.animate(combine, 'input2', keys)
combine.connectattr('output', obj.node, 'color') combine.connectattr('output', obj.node, 'color')
obj = Image( obj = Image(
_bascenev1.gettexture('achievementOutline'), bascenev1.gettexture('achievementOutline'),
mesh_transparent=_bascenev1.getmesh('achievementOutline'), mesh_transparent=bascenev1.getmesh('achievementOutline'),
position=(-180, 60 + y_offs), position=(-180, 60 + y_offs),
front=True, front=True,
attach=Image.Attach.BOTTOM_CENTER, attach=Image.Attach.BOTTOM_CENTER,
@ -1406,7 +1389,7 @@ class Achievement:
# Flash. # Flash.
color = (2, 1.4, 0.4, 1) color = (2, 1.4, 0.4, 1)
combine = _bascenev1.newnode( combine = bascenev1.newnode(
'combine', owner=obj.node, attrs={'size': 3} 'combine', owner=obj.node, attrs={'size': 3}
) )
keys = { keys = {
@ -1416,7 +1399,7 @@ class Achievement:
in_time + 0.6: 1.5 * color[0], in_time + 0.6: 1.5 * color[0],
in_time + 2.0: 1.0 * color[0], in_time + 2.0: 1.0 * color[0],
} }
_gameutils.animate(combine, 'input0', keys) bascenev1.animate(combine, 'input0', keys)
keys = { keys = {
in_time: 1.0 * color[1], in_time: 1.0 * color[1],
in_time + 0.4: 1.5 * color[1], in_time + 0.4: 1.5 * color[1],
@ -1424,7 +1407,7 @@ class Achievement:
in_time + 0.6: 1.5 * color[1], in_time + 0.6: 1.5 * color[1],
in_time + 2.0: 1.0 * color[1], in_time + 2.0: 1.0 * color[1],
} }
_gameutils.animate(combine, 'input1', keys) bascenev1.animate(combine, 'input1', keys)
keys = { keys = {
in_time: 1.0 * color[2], in_time: 1.0 * color[2],
in_time + 0.4: 1.5 * color[2], in_time + 0.4: 1.5 * color[2],
@ -1432,13 +1415,14 @@ class Achievement:
in_time + 0.6: 1.5 * color[2], in_time + 0.6: 1.5 * color[2],
in_time + 2.0: 1.0 * color[2], in_time + 2.0: 1.0 * color[2],
} }
_gameutils.animate(combine, 'input2', keys) bascenev1.animate(combine, 'input2', keys)
combine.connectattr('output', obj.node, 'color') combine.connectattr('output', obj.node, 'color')
objs.append(obj) objs.append(obj)
objt = Text( objt = Text(
Lstr( babase.Lstr(
value='${A}:', subs=[('${A}', Lstr(resource='achievementText'))] value='${A}:',
subs=[('${A}', babase.Lstr(resource='achievementText'))],
), ),
position=(-120, 91 + y_offs), position=(-120, 91 + y_offs),
front=True, front=True,
@ -1474,7 +1458,7 @@ class Achievement:
objt.node.host_only = True objt.node.host_only = True
objt = Text( objt = Text(
_babase.charstr(SpecialChar.TICKET), babase.charstr(babase.SpecialChar.TICKET),
position=(-120 - 170 + 5, 75 + y_offs - 20), position=(-120 - 170 + 5, 75 + y_offs - 20),
front=True, front=True,
v_attach=Text.VAttach.BOTTOM, v_attach=Text.VAttach.BOTTOM,
@ -1554,6 +1538,7 @@ class Achievement:
objt.node.host_only = True objt.node.host_only = True
for actor in objs: for actor in objs:
_bascenev1.timer( bascenev1.timer(
out_time + 1.000, WeakCall(actor.handlemessage, DieMessage()) out_time + 1.000,
babase.WeakCall(actor.handlemessage, bascenev1.DieMessage()),
) )

View File

@ -34,7 +34,6 @@ class AdsSubsystem:
def do_remove_in_game_ads_message(self) -> None: def do_remove_in_game_ads_message(self) -> None:
"""(internal)""" """(internal)"""
from babase._language import Lstr
# Print this message once every 10 minutes at most. # Print this message once every 10 minutes at most.
tval = babase.apptime() tval = babase.apptime()
@ -46,14 +45,19 @@ class AdsSubsystem:
babase.apptimer( babase.apptimer(
1.0, 1.0,
lambda: babase.screenmessage( lambda: babase.screenmessage(
Lstr( babase.Lstr(
resource='removeInGameAdsText', resource='removeInGameAdsText',
subs=[ subs=[
( (
'${PRO}', '${PRO}',
Lstr(resource='store.bombSquadProNameText'), babase.Lstr(
resource='store.bombSquadProNameText'
),
),
(
'${APP_NAME}',
babase.Lstr(resource='titleText'),
), ),
('${APP_NAME}', Lstr(resource='titleText')),
], ],
), ),
color=(1, 1, 0), color=(1, 1, 0),

View File

@ -4,8 +4,9 @@
from __future__ import annotations from __future__ import annotations
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import logging
import _babase import babase
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any from typing import Any
@ -23,15 +24,15 @@ def get_input_device_mapped_value(
# pylint: disable=too-many-return-statements # pylint: disable=too-many-return-statements
# pylint: disable=too-many-branches # pylint: disable=too-many-branches
app = _babase.app app = babase.app
assert app.classic is not None assert app.classic is not None
useragentstring = app.classic.user_agent_string useragentstring = app.classic.user_agent_string
platform = app.classic.platform platform = app.classic.platform
subplatform = app.classic.subplatform subplatform = app.classic.subplatform
appconfig = _babase.app.config appconfig = babase.app.config
# iiRcade: hard-code for a/b/c/x for now... # iiRcade: hard-code for a/b/c/x for now...
if _babase.app.iircade_mode: if babase.app.iircade_mode:
return { return {
'triggerRun2': 19, 'triggerRun2': 19,
'unassignedButtonsRun': False, 'unassignedButtonsRun': False,
@ -97,7 +98,7 @@ def get_input_device_mapped_value(
}.get(name, -1) }.get(name, -1)
# Look for some exact types. # Look for some exact types.
if _babase.is_running_on_fire_tv(): if babase.is_running_on_fire_tv():
if devicename in ['Thunder', 'Amazon Fire Game Controller']: if devicename in ['Thunder', 'Amazon Fire Game Controller']:
return { return {
'triggerRun2': 23, 'triggerRun2': 23,
@ -516,7 +517,7 @@ def get_input_device_mapped_value(
# Reasonable defaults. # Reasonable defaults.
if platform == 'android': if platform == 'android':
if _babase.is_running_on_fire_tv(): if babase.is_running_on_fire_tv():
# Mostly same as default firetv controller. # Mostly same as default firetv controller.
return { return {
'triggerRun2': 23, 'triggerRun2': 23,
@ -575,11 +576,7 @@ def _gen_android_input_hash() -> str:
except PermissionError: except PermissionError:
pass pass
except Exception: except Exception:
from babase import _error logging.exception('Error in _gen_android_input_hash inner loop.')
_error.print_exception(
'error in _gen_android_input_hash inner loop'
)
return md5.hexdigest() return md5.hexdigest()
@ -591,7 +588,7 @@ def get_input_device_map_hash() -> str:
(Different Android versions, for example, may return different (Different Android versions, for example, may return different
key codes for button presses on a given type of controller) key codes for button presses on a given type of controller)
""" """
app = _babase.app app = babase.app
# Currently only using this when classic is present. # Currently only using this when classic is present.
# Need to replace with a modern equivalent. # Need to replace with a modern equivalent.
@ -604,9 +601,7 @@ def get_input_device_map_hash() -> str:
app.classic.input_map_hash = '' app.classic.input_map_hash = ''
return app.classic.input_map_hash return app.classic.input_map_hash
except Exception: except Exception:
from babase import _error logging.exception('Error in get_input_map_hash.')
_error.print_exception('Exception in get_input_map_hash')
return '' return ''
return '' return ''
@ -618,7 +613,7 @@ def get_input_device_config(
The dict will be created if it does not exist. The dict will be created if it does not exist.
""" """
cfg = _babase.app.config cfg = babase.app.config
ccfgs: dict[str, Any] = cfg.setdefault('Controllers', {}) ccfgs: dict[str, Any] = cfg.setdefault('Controllers', {})
ccfgs.setdefault(name, {}) ccfgs.setdefault(name, {})
if default: if default:

View File

@ -25,7 +25,6 @@ import bascenev1
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any from typing import Any
import babase
from bacommon.servermanager import ServerConfig from bacommon.servermanager import ServerConfig

View File

@ -7,14 +7,12 @@ from __future__ import annotations
import logging import logging
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import _babase import babase
import bascenev1
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any from typing import Any
import babase
import bascenev1
class StoreSubsystem: class StoreSubsystem:
"""Wrangles classic store.""" """Wrangles classic store."""
@ -26,29 +24,26 @@ class StoreSubsystem:
def get_store_item_name_translated(self, item_name: str) -> babase.Lstr: def get_store_item_name_translated(self, item_name: str) -> babase.Lstr:
"""Return a babase.Lstr for a store item name.""" """Return a babase.Lstr for a store item name."""
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from babase import _language
from bascenev1 import _map
item_info = self.get_store_item(item_name) item_info = self.get_store_item(item_name)
if item_name.startswith('characters.'): if item_name.startswith('characters.'):
return _language.Lstr( return babase.Lstr(
translate=('characterNames', item_info['character']) translate=('characterNames', item_info['character'])
) )
if item_name in ['merch']: if item_name in ['merch']:
return _language.Lstr(resource='merchText') return babase.Lstr(resource='merchText')
if item_name in ['upgrades.pro', 'pro']: if item_name in ['upgrades.pro', 'pro']:
return _language.Lstr( return babase.Lstr(
resource='store.bombSquadProNameText', resource='store.bombSquadProNameText',
subs=[('${APP_NAME}', _language.Lstr(resource='titleText'))], subs=[('${APP_NAME}', babase.Lstr(resource='titleText'))],
) )
if item_name.startswith('maps.'): if item_name.startswith('maps.'):
map_type: type[_map.Map] = item_info['map_type'] map_type: type[bascenev1.Map] = item_info['map_type']
return _map.get_map_display_string(map_type.name) return bascenev1.get_map_display_string(map_type.name)
if item_name.startswith('games.'): if item_name.startswith('games.'):
gametype: type[bascenev1.GameActivity] = item_info['gametype'] gametype: type[bascenev1.GameActivity] = item_info['gametype']
return gametype.get_display_string() return gametype.get_display_string()
if item_name.startswith('icons.'): if item_name.startswith('icons.'):
return _language.Lstr(resource='editProfileWindow.iconText') return babase.Lstr(resource='editProfileWindow.iconText')
raise ValueError('unrecognized item: ' + item_name) raise ValueError('unrecognized item: ' + item_name)
def get_store_item_display_size( def get_store_item_display_size(
@ -58,14 +53,12 @@ class StoreSubsystem:
if item_name.startswith('characters.'): if item_name.startswith('characters.'):
return 340 * 0.6, 430 * 0.6 return 340 * 0.6, 430 * 0.6
if item_name in ['pro', 'upgrades.pro', 'merch']: if item_name in ['pro', 'upgrades.pro', 'merch']:
from babase._mgen.enums import UIScale assert babase.app.classic is not None
assert _babase.app.classic is not None
return 650 * 0.9, 500 * ( return 650 * 0.9, 500 * (
0.72 0.72
if ( if (
_babase.app.config.get('Merch Link') babase.app.config.get('Merch Link')
and _babase.app.ui_v1.uiscale is UIScale.SMALL and babase.app.ui_v1.uiscale is babase.UIScale.SMALL
) )
else 0.85 else 0.85
) )
@ -81,12 +74,11 @@ class StoreSubsystem:
(internal) (internal)
""" """
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from babase._mgen.enums import SpecialChar
from bascenev1lib import maps from bascenev1lib import maps
assert _babase.app.classic is not None assert babase.app.classic is not None
if _babase.app.classic.store_items is None: if babase.app.classic.store_items is None:
from bascenev1lib.game import ninjafight from bascenev1lib.game import ninjafight
from bascenev1lib.game import meteorshower from bascenev1lib.game import meteorshower
from bascenev1lib.game import targetpractice from bascenev1lib.game import targetpractice
@ -94,7 +86,7 @@ class StoreSubsystem:
# IMPORTANT - need to keep this synced with the master server. # IMPORTANT - need to keep this synced with the master server.
# (doing so manually for now) # (doing so manually for now)
_babase.app.classic.store_items = { babase.app.classic.store_items = {
'characters.kronk': {'character': 'Kronk'}, 'characters.kronk': {'character': 'Kronk'},
'characters.zoe': {'character': 'Zoe'}, 'characters.zoe': {'character': 'Zoe'},
'characters.jackmorgan': {'character': 'Jack Morgan'}, 'characters.jackmorgan': {'character': 'Jack Morgan'},
@ -134,135 +126,157 @@ class StoreSubsystem:
'previewTex': 'towerDPreview', 'previewTex': 'towerDPreview',
}, },
'icons.flag_us': { 'icons.flag_us': {
'icon': _babase.charstr(SpecialChar.FLAG_UNITED_STATES) 'icon': babase.charstr(
babase.SpecialChar.FLAG_UNITED_STATES
)
}, },
'icons.flag_mexico': { 'icons.flag_mexico': {
'icon': _babase.charstr(SpecialChar.FLAG_MEXICO) 'icon': babase.charstr(babase.SpecialChar.FLAG_MEXICO)
}, },
'icons.flag_germany': { 'icons.flag_germany': {
'icon': _babase.charstr(SpecialChar.FLAG_GERMANY) 'icon': babase.charstr(babase.SpecialChar.FLAG_GERMANY)
}, },
'icons.flag_brazil': { 'icons.flag_brazil': {
'icon': _babase.charstr(SpecialChar.FLAG_BRAZIL) 'icon': babase.charstr(babase.SpecialChar.FLAG_BRAZIL)
}, },
'icons.flag_russia': { 'icons.flag_russia': {
'icon': _babase.charstr(SpecialChar.FLAG_RUSSIA) 'icon': babase.charstr(babase.SpecialChar.FLAG_RUSSIA)
}, },
'icons.flag_china': { 'icons.flag_china': {
'icon': _babase.charstr(SpecialChar.FLAG_CHINA) 'icon': babase.charstr(babase.SpecialChar.FLAG_CHINA)
}, },
'icons.flag_uk': { 'icons.flag_uk': {
'icon': _babase.charstr(SpecialChar.FLAG_UNITED_KINGDOM) 'icon': babase.charstr(
babase.SpecialChar.FLAG_UNITED_KINGDOM
)
}, },
'icons.flag_canada': { 'icons.flag_canada': {
'icon': _babase.charstr(SpecialChar.FLAG_CANADA) 'icon': babase.charstr(babase.SpecialChar.FLAG_CANADA)
}, },
'icons.flag_india': { 'icons.flag_india': {
'icon': _babase.charstr(SpecialChar.FLAG_INDIA) 'icon': babase.charstr(babase.SpecialChar.FLAG_INDIA)
}, },
'icons.flag_japan': { 'icons.flag_japan': {
'icon': _babase.charstr(SpecialChar.FLAG_JAPAN) 'icon': babase.charstr(babase.SpecialChar.FLAG_JAPAN)
}, },
'icons.flag_france': { 'icons.flag_france': {
'icon': _babase.charstr(SpecialChar.FLAG_FRANCE) 'icon': babase.charstr(babase.SpecialChar.FLAG_FRANCE)
}, },
'icons.flag_indonesia': { 'icons.flag_indonesia': {
'icon': _babase.charstr(SpecialChar.FLAG_INDONESIA) 'icon': babase.charstr(babase.SpecialChar.FLAG_INDONESIA)
}, },
'icons.flag_italy': { 'icons.flag_italy': {
'icon': _babase.charstr(SpecialChar.FLAG_ITALY) 'icon': babase.charstr(babase.SpecialChar.FLAG_ITALY)
}, },
'icons.flag_south_korea': { 'icons.flag_south_korea': {
'icon': _babase.charstr(SpecialChar.FLAG_SOUTH_KOREA) 'icon': babase.charstr(babase.SpecialChar.FLAG_SOUTH_KOREA)
}, },
'icons.flag_netherlands': { 'icons.flag_netherlands': {
'icon': _babase.charstr(SpecialChar.FLAG_NETHERLANDS) 'icon': babase.charstr(babase.SpecialChar.FLAG_NETHERLANDS)
}, },
'icons.flag_uae': { 'icons.flag_uae': {
'icon': _babase.charstr( 'icon': babase.charstr(
SpecialChar.FLAG_UNITED_ARAB_EMIRATES babase.SpecialChar.FLAG_UNITED_ARAB_EMIRATES
) )
}, },
'icons.flag_qatar': { 'icons.flag_qatar': {
'icon': _babase.charstr(SpecialChar.FLAG_QATAR) 'icon': babase.charstr(babase.SpecialChar.FLAG_QATAR)
}, },
'icons.flag_egypt': { 'icons.flag_egypt': {
'icon': _babase.charstr(SpecialChar.FLAG_EGYPT) 'icon': babase.charstr(babase.SpecialChar.FLAG_EGYPT)
}, },
'icons.flag_kuwait': { 'icons.flag_kuwait': {
'icon': _babase.charstr(SpecialChar.FLAG_KUWAIT) 'icon': babase.charstr(babase.SpecialChar.FLAG_KUWAIT)
}, },
'icons.flag_algeria': { 'icons.flag_algeria': {
'icon': _babase.charstr(SpecialChar.FLAG_ALGERIA) 'icon': babase.charstr(babase.SpecialChar.FLAG_ALGERIA)
}, },
'icons.flag_saudi_arabia': { 'icons.flag_saudi_arabia': {
'icon': _babase.charstr(SpecialChar.FLAG_SAUDI_ARABIA) 'icon': babase.charstr(babase.SpecialChar.FLAG_SAUDI_ARABIA)
}, },
'icons.flag_malaysia': { 'icons.flag_malaysia': {
'icon': _babase.charstr(SpecialChar.FLAG_MALAYSIA) 'icon': babase.charstr(babase.SpecialChar.FLAG_MALAYSIA)
}, },
'icons.flag_czech_republic': { 'icons.flag_czech_republic': {
'icon': _babase.charstr(SpecialChar.FLAG_CZECH_REPUBLIC) 'icon': babase.charstr(
babase.SpecialChar.FLAG_CZECH_REPUBLIC
)
}, },
'icons.flag_australia': { 'icons.flag_australia': {
'icon': _babase.charstr(SpecialChar.FLAG_AUSTRALIA) 'icon': babase.charstr(babase.SpecialChar.FLAG_AUSTRALIA)
}, },
'icons.flag_singapore': { 'icons.flag_singapore': {
'icon': _babase.charstr(SpecialChar.FLAG_SINGAPORE) 'icon': babase.charstr(babase.SpecialChar.FLAG_SINGAPORE)
}, },
'icons.flag_iran': { 'icons.flag_iran': {
'icon': _babase.charstr(SpecialChar.FLAG_IRAN) 'icon': babase.charstr(babase.SpecialChar.FLAG_IRAN)
}, },
'icons.flag_poland': { 'icons.flag_poland': {
'icon': _babase.charstr(SpecialChar.FLAG_POLAND) 'icon': babase.charstr(babase.SpecialChar.FLAG_POLAND)
}, },
'icons.flag_argentina': { 'icons.flag_argentina': {
'icon': _babase.charstr(SpecialChar.FLAG_ARGENTINA) 'icon': babase.charstr(babase.SpecialChar.FLAG_ARGENTINA)
}, },
'icons.flag_philippines': { 'icons.flag_philippines': {
'icon': _babase.charstr(SpecialChar.FLAG_PHILIPPINES) 'icon': babase.charstr(babase.SpecialChar.FLAG_PHILIPPINES)
}, },
'icons.flag_chile': { 'icons.flag_chile': {
'icon': _babase.charstr(SpecialChar.FLAG_CHILE) 'icon': babase.charstr(babase.SpecialChar.FLAG_CHILE)
},
'icons.fedora': {
'icon': babase.charstr(babase.SpecialChar.FEDORA)
},
'icons.hal': {'icon': babase.charstr(babase.SpecialChar.HAL)},
'icons.crown': {
'icon': babase.charstr(babase.SpecialChar.CROWN)
}, },
'icons.fedora': {'icon': _babase.charstr(SpecialChar.FEDORA)},
'icons.hal': {'icon': _babase.charstr(SpecialChar.HAL)},
'icons.crown': {'icon': _babase.charstr(SpecialChar.CROWN)},
'icons.yinyang': { 'icons.yinyang': {
'icon': _babase.charstr(SpecialChar.YIN_YANG) 'icon': babase.charstr(babase.SpecialChar.YIN_YANG)
}, },
'icons.eyeball': { 'icons.eyeball': {
'icon': _babase.charstr(SpecialChar.EYE_BALL) 'icon': babase.charstr(babase.SpecialChar.EYE_BALL)
},
'icons.skull': {
'icon': babase.charstr(babase.SpecialChar.SKULL)
},
'icons.heart': {
'icon': babase.charstr(babase.SpecialChar.HEART)
},
'icons.dragon': {
'icon': babase.charstr(babase.SpecialChar.DRAGON)
},
'icons.helmet': {
'icon': babase.charstr(babase.SpecialChar.HELMET)
}, },
'icons.skull': {'icon': _babase.charstr(SpecialChar.SKULL)},
'icons.heart': {'icon': _babase.charstr(SpecialChar.HEART)},
'icons.dragon': {'icon': _babase.charstr(SpecialChar.DRAGON)},
'icons.helmet': {'icon': _babase.charstr(SpecialChar.HELMET)},
'icons.mushroom': { 'icons.mushroom': {
'icon': _babase.charstr(SpecialChar.MUSHROOM) 'icon': babase.charstr(babase.SpecialChar.MUSHROOM)
}, },
'icons.ninja_star': { 'icons.ninja_star': {
'icon': _babase.charstr(SpecialChar.NINJA_STAR) 'icon': babase.charstr(babase.SpecialChar.NINJA_STAR)
}, },
'icons.viking_helmet': { 'icons.viking_helmet': {
'icon': _babase.charstr(SpecialChar.VIKING_HELMET) 'icon': babase.charstr(babase.SpecialChar.VIKING_HELMET)
},
'icons.moon': {'icon': babase.charstr(babase.SpecialChar.MOON)},
'icons.spider': {
'icon': babase.charstr(babase.SpecialChar.SPIDER)
}, },
'icons.moon': {'icon': _babase.charstr(SpecialChar.MOON)},
'icons.spider': {'icon': _babase.charstr(SpecialChar.SPIDER)},
'icons.fireball': { 'icons.fireball': {
'icon': _babase.charstr(SpecialChar.FIREBALL) 'icon': babase.charstr(babase.SpecialChar.FIREBALL)
},
'icons.mikirog': {
'icon': babase.charstr(babase.SpecialChar.MIKIROG)
}, },
'icons.mikirog': {'icon': _babase.charstr(SpecialChar.MIKIROG)},
} }
return _babase.app.classic.store_items return babase.app.classic.store_items
def get_store_layout(self) -> dict[str, list[dict[str, Any]]]: def get_store_layout(self) -> dict[str, list[dict[str, Any]]]:
"""Return what's available in the store at a given time. """Return what's available in the store at a given time.
Categorized by tab and by section. Categorized by tab and by section.
""" """
plus = _babase.app.plus plus = babase.app.plus
classic = _babase.app.classic classic = babase.app.classic
assert classic is not None assert classic is not None
assert plus is not None assert plus is not None
@ -373,7 +387,7 @@ class StoreSubsystem:
# This will cause merch to show only if the master-server has # This will cause merch to show only if the master-server has
# given us a link (which means merch is available in our region). # given us a link (which means merch is available in our region).
store_layout['extras'] = [{'items': ['pro']}] store_layout['extras'] = [{'items': ['pro']}]
if _babase.app.config.get('Merch Link'): if babase.app.config.get('Merch Link'):
store_layout['extras'][0]['items'].append('merch') store_layout['extras'][0]['items'].append('merch')
return store_layout return store_layout
@ -394,7 +408,7 @@ class StoreSubsystem:
def get_available_purchase_count(self, tab: str | None = None) -> int: def get_available_purchase_count(self, tab: str | None = None) -> int:
"""(internal)""" """(internal)"""
plus = _babase.app.plus plus = babase.app.plus
if plus is None: if plus is None:
return 0 return 0
try: try:
@ -419,7 +433,7 @@ class StoreSubsystem:
def _calc_count_for_tab( def _calc_count_for_tab(
self, tabval: list[dict[str, Any]], our_tickets: int, count: int self, tabval: list[dict[str, Any]], our_tickets: int, count: int
) -> int: ) -> int:
plus = _babase.app.plus plus = babase.app.plus
assert plus assert plus
for section in tabval: for section in tabval:
for item in section['items']: for item in section['items']:
@ -437,14 +451,13 @@ class StoreSubsystem:
"""(internal)""" """(internal)"""
# pylint: disable=too-many-branches # pylint: disable=too-many-branches
# pylint: disable=too-many-nested-blocks # pylint: disable=too-many-nested-blocks
# pylint: disable=too-many-locals plus = babase.app.plus
plus = _babase.app.plus
assert plus is not None assert plus is not None
try: try:
import datetime import datetime
app = _babase.app app = babase.app
assert app.classic is not None assert app.classic is not None
sale_times: list[int | None] = [] sale_times: list[int | None] = []
@ -459,7 +472,7 @@ class StoreSubsystem:
# If we've got a time-remaining in our config, start there. # If we've got a time-remaining in our config, start there.
if 'PSTR' in config: if 'PSTR' in config:
app.classic.pro_sale_start_time = int( app.classic.pro_sale_start_time = int(
_babase.apptime() * 1000 babase.apptime() * 1000
) )
app.classic.pro_sale_start_val = config['PSTR'] app.classic.pro_sale_start_val = config['PSTR']
else: else:
@ -470,7 +483,7 @@ class StoreSubsystem:
) )
if start_duration is not None: if start_duration is not None:
app.classic.pro_sale_start_time = int( app.classic.pro_sale_start_time = int(
_babase.apptime() * 1000 babase.apptime() * 1000
) )
app.classic.pro_sale_start_val = ( app.classic.pro_sale_start_val = (
60000 * start_duration 60000 * start_duration
@ -485,7 +498,7 @@ class StoreSubsystem:
0, 0,
app.classic.pro_sale_start_val app.classic.pro_sale_start_val
- ( - (
int(_babase.apptime() * 1000.0) int(babase.apptime() * 1000.0)
- app.classic.pro_sale_start_time - app.classic.pro_sale_start_time
), ),
) )
@ -519,9 +532,7 @@ class StoreSubsystem:
return min(sale_times_int) if sale_times_int else None return min(sale_times_int) if sale_times_int else None
except Exception: except Exception:
from babase import _error logging.exception('Error calcing sale time.')
_error.print_exception('error calcing sale time')
return None return None
def get_unowned_maps(self) -> list[str]: def get_unowned_maps(self) -> list[str]:
@ -529,9 +540,9 @@ class StoreSubsystem:
Category: **Asset Functions** Category: **Asset Functions**
""" """
plus = _babase.app.plus plus = babase.app.plus
unowned_maps: set[str] = set() unowned_maps: set[str] = set()
if not _babase.app.headless_mode: if not babase.app.headless_mode:
for map_section in self.get_store_layout()['maps']: for map_section in self.get_store_layout()['maps']:
for mapitem in map_section['items']: for mapitem in map_section['items']:
if plus is None or not plus.get_purchased(mapitem): if plus is None or not plus.get_purchased(mapitem):
@ -542,9 +553,9 @@ class StoreSubsystem:
def get_unowned_game_types(self) -> set[type[bascenev1.GameActivity]]: def get_unowned_game_types(self) -> set[type[bascenev1.GameActivity]]:
"""Return present game types not owned by the current account.""" """Return present game types not owned by the current account."""
try: try:
plus = _babase.app.plus plus = babase.app.plus
unowned_games: set[type[bascenev1.GameActivity]] = set() unowned_games: set[type[bascenev1.GameActivity]] = set()
if not _babase.app.headless_mode: if not babase.app.headless_mode:
for section in self.get_store_layout()['minigames']: for section in self.get_store_layout()['minigames']:
for mname in section['items']: for mname in section['items']:
if plus is None or not plus.get_purchased(mname): if plus is None or not plus.get_purchased(mname):
@ -552,7 +563,5 @@ class StoreSubsystem:
unowned_games.add(m_info['gametype']) unowned_games.add(m_info['gametype'])
return unowned_games return unowned_games
except Exception: except Exception:
from babase import _error logging.exception('Error calcing un-owned games.')
_error.print_exception('error calcing un-owned games')
return set() return set()

View File

@ -146,6 +146,7 @@ from bascenev1._profile import (
get_player_profile_icon, get_player_profile_icon,
get_player_profile_colors, get_player_profile_colors,
) )
from bascenev1._map import get_map_display_string
from bascenev1._campaign import init_campaigns from bascenev1._campaign import init_campaigns
from bascenev1._appmode import SceneV1AppMode from bascenev1._appmode import SceneV1AppMode
from bascenev1._session import Session from bascenev1._session import Session
@ -413,6 +414,7 @@ __all__ = [
'set_master_server_source', 'set_master_server_source',
'init_campaigns', 'init_campaigns',
'register_map', 'register_map',
'get_map_display_string',
] ]
# We want stuff here to show up as bascenev1.Foo instead of # We want stuff here to show up as bascenev1.Foo instead of

View File

@ -5,9 +5,9 @@ from __future__ import annotations
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import _babase import babase
import _bascenev1 import _bascenev1
from babase._mgen.enums import InputType, UIScale
from bascenev1._activity import Activity from bascenev1._activity import Activity
# False-positive from pylint due to our class-generics-filter. # False-positive from pylint due to our class-generics-filter.
@ -16,7 +16,6 @@ from bascenev1._team import EmptyTeam # pylint: disable=W0611
from bascenev1._music import MusicType, setmusic from bascenev1._music import MusicType, setmusic
if TYPE_CHECKING: if TYPE_CHECKING:
import babase
import bascenev1 import bascenev1
from bascenev1._lobby import JoinInfo from bascenev1._lobby import JoinInfo
@ -36,22 +35,21 @@ class EndSessionActivity(Activity[EmptyPlayer, EmptyTeam]):
def on_transition_in(self) -> None: def on_transition_in(self) -> None:
super().on_transition_in() super().on_transition_in()
_babase.fade_screen(False) babase.fade_screen(False)
_babase.lock_all_input() babase.lock_all_input()
def on_begin(self) -> None: def on_begin(self) -> None:
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
assert _babase.app.classic is not None assert babase.app.classic is not None
from babase._general import Call
main_menu_session = _babase.app.classic.get_main_menu_session() main_menu_session = babase.app.classic.get_main_menu_session()
super().on_begin() super().on_begin()
_babase.unlock_all_input() babase.unlock_all_input()
assert _babase.app.classic is not None assert babase.app.classic is not None
_babase.app.classic.ads.call_after_ad( babase.app.classic.ads.call_after_ad(
Call(_bascenev1.new_host_session, main_menu_session) babase.Call(_bascenev1.new_host_session, main_menu_session)
) )
@ -90,7 +88,7 @@ class JoinActivity(Activity[EmptyPlayer, EmptyTeam]):
self._tips_text = TipsText() self._tips_text = TipsText()
setmusic(MusicType.CHAR_SELECT) setmusic(MusicType.CHAR_SELECT)
self._join_info = self.session.lobby.create_join_info() self._join_info = self.session.lobby.create_join_info()
_babase.set_analytics_screen('Joining Screen') babase.set_analytics_screen('Joining Screen')
class TransitionActivity(Activity[EmptyPlayer, EmptyTeam]): class TransitionActivity(Activity[EmptyPlayer, EmptyTeam]):
@ -142,7 +140,7 @@ class ScoreScreenActivity(Activity[EmptyPlayer, EmptyTeam]):
def __init__(self, settings: dict): def __init__(self, settings: dict):
super().__init__(settings) super().__init__(settings)
self._birth_time = _babase.apptime() self._birth_time = babase.apptime()
self._min_view_time = 5.0 self._min_view_time = 5.0
self._allow_server_transition = False self._allow_server_transition = False
self._background: bascenev1.Actor | None = None self._background: bascenev1.Actor | None = None
@ -154,16 +152,16 @@ class ScoreScreenActivity(Activity[EmptyPlayer, EmptyTeam]):
self._server_transitioning: bool | None = None self._server_transitioning: bool | None = None
def on_player_join(self, player: EmptyPlayer) -> None: def on_player_join(self, player: EmptyPlayer) -> None:
from babase._general import WeakCall
super().on_player_join(player) super().on_player_join(player)
time_till_assign = max( time_till_assign = max(
0, self._birth_time + self._min_view_time - _babase.apptime() 0, self._birth_time + self._min_view_time - babase.apptime()
) )
# If we're still kicking at the end of our assign-delay, assign this # If we're still kicking at the end of our assign-delay, assign this
# guy's input to trigger us. # guy's input to trigger us.
_bascenev1.timer(time_till_assign, WeakCall(self._safe_assign, player)) _bascenev1.timer(
time_till_assign, babase.WeakCall(self._safe_assign, player)
)
def on_transition_in(self) -> None: def on_transition_in(self) -> None:
from bascenev1lib.actor.tipstext import TipsText from bascenev1lib.actor.tipstext import TipsText
@ -180,20 +178,19 @@ class ScoreScreenActivity(Activity[EmptyPlayer, EmptyTeam]):
def on_begin(self) -> None: def on_begin(self) -> None:
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bascenev1lib.actor.text import Text from bascenev1lib.actor.text import Text
from babase import _language
super().on_begin() super().on_begin()
# Pop up a 'press any button to continue' statement after our # Pop up a 'press any button to continue' statement after our
# min-view-time show a 'press any button to continue..' # min-view-time show a 'press any button to continue..'
# thing after a bit. # thing after a bit.
assert _babase.app.classic is not None assert babase.app.classic is not None
if _babase.app.ui_v1.uiscale is UIScale.LARGE: if babase.app.ui_v1.uiscale is babase.UIScale.LARGE:
# FIXME: Need a better way to determine whether we've probably # FIXME: Need a better way to determine whether we've probably
# got a keyboard. # got a keyboard.
sval = _language.Lstr(resource='pressAnyKeyButtonText') sval = babase.Lstr(resource='pressAnyKeyButtonText')
else: else:
sval = _language.Lstr(resource='pressAnyButtonText') sval = babase.Lstr(resource='pressAnyButtonText')
Text( Text(
self._custom_continue_message self._custom_continue_message
@ -215,12 +212,12 @@ class ScoreScreenActivity(Activity[EmptyPlayer, EmptyTeam]):
# it wants to do anything special like switch sessions or kill the app. # it wants to do anything special like switch sessions or kill the app.
if ( if (
self._allow_server_transition self._allow_server_transition
and _babase.app.classic is not None and babase.app.classic is not None
and _babase.app.classic.server is not None and babase.app.classic.server is not None
and self._server_transitioning is None and self._server_transitioning is None
): ):
self._server_transitioning = ( self._server_transitioning = (
_babase.app.classic.server.handle_transition() babase.app.classic.server.handle_transition()
) )
assert isinstance(self._server_transitioning, bool) assert isinstance(self._server_transitioning, bool)
@ -237,10 +234,10 @@ class ScoreScreenActivity(Activity[EmptyPlayer, EmptyTeam]):
if not self.is_transitioning_out() and player: if not self.is_transitioning_out() and player:
player.assigninput( player.assigninput(
( (
InputType.JUMP_PRESS, babase.InputType.JUMP_PRESS,
InputType.PUNCH_PRESS, babase.InputType.PUNCH_PRESS,
InputType.BOMB_PRESS, babase.InputType.BOMB_PRESS,
InputType.PICK_UP_PRESS, babase.InputType.PICK_UP_PRESS,
), ),
self._player_press, self._player_press,
) )

View File

@ -96,7 +96,6 @@ class CoopGameActivity(GameActivity[PlayerT, TeamT]):
def _show_remaining_achievements(self) -> None: def _show_remaining_achievements(self) -> None:
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from babase._language import Lstr
from bascenev1lib.actor.text import Text from bascenev1lib.actor.text import Text
assert babase.app.classic is not None assert babase.app.classic is not None
@ -112,7 +111,7 @@ class CoopGameActivity(GameActivity[PlayerT, TeamT]):
vrmode = babase.app.vr_mode vrmode = babase.app.vr_mode
if achievements: if achievements:
Text( Text(
Lstr(resource='achievementsRemainingText'), babase.Lstr(resource='achievementsRemainingText'),
host_only=True, host_only=True,
position=(ts_h_offs - 10 + 40, v_offs - 10), position=(ts_h_offs - 10 + 40, v_offs - 10),
transition=Text.Transition.FADE_IN, transition=Text.Transition.FADE_IN,
@ -182,9 +181,7 @@ class CoopGameActivity(GameActivity[PlayerT, TeamT]):
if ach.hard_mode_only and campaign.name == 'Easy': if ach.hard_mode_only and campaign.name == 'Easy':
return return
except Exception: except Exception:
from babase._error import print_exception logging.exception('Error in _award_achievement.')
print_exception()
# If we haven't awarded this one, check to see if we've got it. # If we haven't awarded this one, check to see if we've got it.
# If not, set it through the game service *and* add a transaction # If not, set it through the game service *and* add a transaction

View File

@ -178,11 +178,9 @@ class CoopSession(Session):
return self._custom_menu_ui return self._custom_menu_ui
def on_player_leave(self, sessionplayer: bascenev1.SessionPlayer) -> None: def on_player_leave(self, sessionplayer: bascenev1.SessionPlayer) -> None:
from babase._general import WeakCall
super().on_player_leave(sessionplayer) super().on_player_leave(sessionplayer)
_bascenev1.timer(2.0, WeakCall(self._handle_empty_activity)) _bascenev1.timer(2.0, babase.WeakCall(self._handle_empty_activity))
def _handle_empty_activity(self) -> None: def _handle_empty_activity(self) -> None:
"""Handle cases where all players have left the current activity.""" """Handle cases where all players have left the current activity."""
@ -269,15 +267,14 @@ class CoopSession(Session):
# pylint: disable=too-many-locals # pylint: disable=too-many-locals
# pylint: disable=too-many-statements # pylint: disable=too-many-statements
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from babase._language import Lstr from bascenev1lib.activity.coopscore import CoopScoreScreen
from babase._general import WeakCall from bascenev1lib.tutorial import TutorialActivity
from bascenev1._gameresults import GameResults from bascenev1._gameresults import GameResults
from bascenev1._player import PlayerInfo from bascenev1._player import PlayerInfo
from bascenev1._activitytypes import JoinActivity, TransitionActivity from bascenev1._activitytypes import JoinActivity, TransitionActivity
from bascenev1._coopgame import CoopGameActivity from bascenev1._coopgame import CoopGameActivity
from bascenev1._score import ScoreType from bascenev1._score import ScoreType
from bascenev1lib.activity.coopscore import CoopScoreScreen
from bascenev1lib.tutorial import TutorialActivity
app = babase.app app = babase.app
classic = app.classic classic = app.classic
@ -346,9 +343,9 @@ class CoopSession(Session):
if self.tournament_id is not None: if self.tournament_id is not None:
self._custom_menu_ui = [ self._custom_menu_ui = [
{ {
'label': Lstr(resource='restartText'), 'label': babase.Lstr(resource='restartText'),
'resume_on_call': False, 'resume_on_call': False,
'call': WeakCall( 'call': babase.WeakCall(
self._on_tournament_restart_menu_press self._on_tournament_restart_menu_press
), ),
} }
@ -356,8 +353,8 @@ class CoopSession(Session):
else: else:
self._custom_menu_ui = [ self._custom_menu_ui = [
{ {
'label': Lstr(resource='restartText'), 'label': babase.Lstr(resource='restartText'),
'call': WeakCall(self.restart), 'call': babase.WeakCall(self.restart),
} }
] ]

View File

@ -9,12 +9,13 @@ from dataclasses import dataclass
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from efro.util import asserttype from efro.util import asserttype
import babase
from bascenev1._team import Team, SessionTeam from bascenev1._team import Team, SessionTeam
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Sequence from typing import Sequence
import babase
import bascenev1 import bascenev1
@ -113,8 +114,6 @@ class GameResults:
(properly formatted for the score type.) (properly formatted for the score type.)
""" """
from babase._language import Lstr
from babase._text import timestring
from bascenev1._score import ScoreType from bascenev1._score import ScoreType
if not self._game_set: if not self._game_set:
@ -122,13 +121,13 @@ class GameResults:
for score in list(self._scores.values()): for score in list(self._scores.values()):
if score[0]() is sessionteam: if score[0]() is sessionteam:
if score[1] is None: if score[1] is None:
return Lstr(value='-') return babase.Lstr(value='-')
if self._scoretype is ScoreType.SECONDS: if self._scoretype is ScoreType.SECONDS:
return timestring(score[1], centi=False) return babase.timestring(score[1], centi=False)
if self._scoretype is ScoreType.MILLISECONDS: if self._scoretype is ScoreType.MILLISECONDS:
return timestring(score[1] / 1000.0, centi=True) return babase.timestring(score[1] / 1000.0, centi=True)
return Lstr(value=str(score[1])) return babase.Lstr(value=str(score[1]))
return Lstr(value='-') return babase.Lstr(value='-')
@property @property
def playerinfos(self) -> list[bascenev1.PlayerInfo]: def playerinfos(self) -> list[bascenev1.PlayerInfo]:

View File

@ -6,15 +6,14 @@ from __future__ import annotations
import random import random
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import _babase import babase
import _bascenev1 import _bascenev1
from babase import _math
from bascenev1._actor import Actor from bascenev1._actor import Actor
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Sequence, Any from typing import Sequence, Any
import babase
import bascenev1 import bascenev1
@ -38,9 +37,7 @@ def get_map_display_string(name: str) -> babase.Lstr:
Category: **Asset Functions** Category: **Asset Functions**
""" """
from babase import _language return babase.Lstr(translate=('mapsNames', name))
return _language.Lstr(translate=('mapsNames', name))
def get_map_class(name: str) -> type[Map]: def get_map_class(name: str) -> type[Map]:
@ -48,15 +45,13 @@ def get_map_class(name: str) -> type[Map]:
Category: **Asset Functions** Category: **Asset Functions**
""" """
assert _babase.app.classic is not None assert babase.app.classic is not None
name = get_filtered_map_name(name) name = get_filtered_map_name(name)
try: try:
mapclass: type[Map] = _babase.app.classic.maps[name] mapclass: type[Map] = babase.app.classic.maps[name]
return mapclass return mapclass
except KeyError: except KeyError:
from babase import _error raise babase.NotFoundError(f"Map not found: '{name}'") from None
raise _error.NotFoundError(f"Map not found: '{name}'") from None
class Map(Actor): class Map(Actor):
@ -133,9 +128,7 @@ class Map(Actor):
try: try:
self.preloaddata = _bascenev1.getactivity().preloads[type(self)] self.preloaddata = _bascenev1.getactivity().preloads[type(self)]
except Exception as exc: except Exception as exc:
from babase import _error raise babase.NotFoundError(
raise _error.NotFoundError(
'Preload data not found for ' 'Preload data not found for '
+ str(type(self)) + str(type(self))
+ '; make sure to call the type\'s preload()' + '; make sure to call the type\'s preload()'
@ -262,7 +255,7 @@ class Map(Actor):
return ( return (
None None
if val is None if val is None
else _math.vec3validate(val) else babase.vec3validate(val)
if __debug__ if __debug__
else val else val
) )
@ -336,7 +329,7 @@ class Map(Actor):
farthestpt_dist = -1.0 farthestpt_dist = -1.0
farthestpt = None farthestpt = None
for _i in range(10): for _i in range(10):
testpt = _babase.Vec3(_getpt()) testpt = babase.Vec3(_getpt())
closest_player_dist = 9999.0 closest_player_dist = 9999.0
for ppt in player_pts: for ppt in player_pts:
dist = (ppt - testpt).length() dist = (ppt - testpt).length()
@ -376,7 +369,7 @@ class Map(Actor):
def register_map(maptype: type[Map]) -> None: def register_map(maptype: type[Map]) -> None:
"""Register a map class with the game.""" """Register a map class with the game."""
assert _babase.app.classic is not None assert babase.app.classic is not None
if maptype.name in _babase.app.classic.maps: if maptype.name in babase.app.classic.maps:
raise RuntimeError('map "' + maptype.name + '" already registered') raise RuntimeError('map "' + maptype.name + '" already registered')
_babase.app.classic.maps[maptype.name] = maptype babase.app.classic.maps[maptype.name] = maptype

View File

@ -4,22 +4,18 @@
from __future__ import annotations from __future__ import annotations
import logging
from dataclasses import dataclass from dataclasses import dataclass
from typing import TYPE_CHECKING, TypeVar, Generic, cast from typing import TYPE_CHECKING, TypeVar, Generic, cast
import _babase import babase
from babase._error import (
SessionPlayerNotFoundError,
print_exception,
ActorNotFoundError,
)
import _bascenev1 import _bascenev1
from bascenev1._messages import DeathType, DieMessage from bascenev1._messages import DeathType, DieMessage
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Sequence, Any, Callable from typing import Sequence, Any, Callable
import babase
import bascenev1 import bascenev1
PlayerT = TypeVar('PlayerT', bound='bascenev1.Player') PlayerT = TypeVar('PlayerT', bound='bascenev1.Player')
@ -130,7 +126,7 @@ class Player(Generic[TeamT]):
self.actor.handlemessage(DieMessage(how=DeathType.LEFT_GAME)) self.actor.handlemessage(DieMessage(how=DeathType.LEFT_GAME))
self.actor = None self.actor = None
except Exception: except Exception:
print_exception(f'Error killing actor on leave for {self}') logging.exception('Error killing actor on leave for %s.', self)
self._nodeactor = None self._nodeactor = None
del self._team del self._team
del self._customdata del self._customdata
@ -147,7 +143,7 @@ class Player(Generic[TeamT]):
try: try:
self.on_expire() self.on_expire()
except Exception: except Exception:
print_exception(f'Error in on_expire for {self}.') logging.exception('Error in on_expire for %s.', self)
self._nodeactor = None self._nodeactor = None
self.actor = None self.actor = None
@ -193,7 +189,7 @@ class Player(Generic[TeamT]):
assert self._postinited assert self._postinited
if bool(self._sessionplayer): if bool(self._sessionplayer):
return self._sessionplayer return self._sessionplayer
raise SessionPlayerNotFoundError() raise babase.SessionPlayerNotFoundError()
@property @property
def node(self) -> bascenev1.Node: def node(self) -> bascenev1.Node:
@ -216,8 +212,8 @@ class Player(Generic[TeamT]):
assert self._postinited assert self._postinited
assert not self._expired assert not self._expired
if self.actor is None: if self.actor is None:
raise ActorNotFoundError raise babase.ActorNotFoundError
return _babase.Vec3(self.node.position) return babase.Vec3(self.node.position)
def exists(self) -> bool: def exists(self) -> bool:
"""Whether the underlying player still exists. """Whether the underlying player still exists.

View File

@ -8,10 +8,11 @@ import copy
import logging import logging
from typing import Any, TYPE_CHECKING from typing import Any, TYPE_CHECKING
import _babase import babase
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Sequence from typing import Sequence
from bascenev1._session import Session from bascenev1._session import Session
PlaylistType = list[dict[str, Any]] PlaylistType = list[dict[str, Any]]
@ -35,18 +36,16 @@ def filter_playlist(
# pylint: disable=too-many-branches # pylint: disable=too-many-branches
# pylint: disable=too-many-statements # pylint: disable=too-many-statements
from bascenev1._map import get_filtered_map_name from bascenev1._map import get_filtered_map_name
from babase._error import MapNotFoundError
from babase._general import getclass
from bascenev1._gameactivity import GameActivity from bascenev1._gameactivity import GameActivity
assert _babase.app.classic is not None assert babase.app.classic is not None
goodlist: list[dict] = [] goodlist: list[dict] = []
unowned_maps: Sequence[str] unowned_maps: Sequence[str]
available_maps: list[str] = list(_babase.app.classic.maps.keys()) available_maps: list[str] = list(babase.app.classic.maps.keys())
if (remove_unowned or mark_unowned) and _babase.app.classic is not None: if (remove_unowned or mark_unowned) and babase.app.classic is not None:
unowned_maps = _babase.app.classic.store.get_unowned_maps() unowned_maps = babase.app.classic.store.get_unowned_maps()
unowned_game_types = _babase.app.classic.store.get_unowned_game_types() unowned_game_types = babase.app.classic.store.get_unowned_game_types()
else: else:
unowned_maps = [] unowned_maps = []
unowned_game_types = set() unowned_game_types = set()
@ -184,10 +183,10 @@ def filter_playlist(
'type' 'type'
] = 'bascenev1lib.game.targetpractice.TargetPracticeGame' ] = 'bascenev1lib.game.targetpractice.TargetPracticeGame'
gameclass = getclass(entry['type'], GameActivity) gameclass = babase.getclass(entry['type'], GameActivity)
if entry['settings']['map'] not in available_maps: if entry['settings']['map'] not in available_maps:
raise MapNotFoundError() raise babase.MapNotFoundError()
if remove_unowned and gameclass in unowned_game_types: if remove_unowned and gameclass in unowned_game_types:
continue continue
@ -206,7 +205,7 @@ def filter_playlist(
goodlist.append(entry) goodlist.append(entry)
except MapNotFoundError: except babase.MapNotFoundError:
logging.warning( logging.warning(
'Map \'%s\' not found while scanning playlist \'%s\'.', 'Map \'%s\' not found while scanning playlist \'%s\'.',
entry['settings']['map'], entry['settings']['map'],

View File

@ -6,7 +6,7 @@ from __future__ import annotations
import random import random
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import _babase import babase
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any from typing import Any
@ -43,9 +43,7 @@ def get_player_profile_icon(profilename: str) -> str:
(non-account profiles only) (non-account profiles only)
""" """
from babase._mgen.enums import SpecialChar appconfig = babase.app.config
appconfig = _babase.app.config
icon: str icon: str
try: try:
is_global = appconfig['Player Profiles'][profilename]['global'] is_global = appconfig['Player Profiles'][profilename]['global']
@ -55,7 +53,7 @@ def get_player_profile_icon(profilename: str) -> str:
try: try:
icon = appconfig['Player Profiles'][profilename]['icon'] icon = appconfig['Player Profiles'][profilename]['icon']
except KeyError: except KeyError:
icon = _babase.charstr(SpecialChar.LOGO) icon = babase.charstr(babase.SpecialChar.LOGO)
else: else:
icon = '' icon = ''
return icon return icon
@ -65,15 +63,13 @@ def get_player_profile_colors(
profilename: str | None, profiles: dict[str, dict[str, Any]] | None = None profilename: str | None, profiles: dict[str, dict[str, Any]] | None = None
) -> tuple[tuple[float, float, float], tuple[float, float, float]]: ) -> tuple[tuple[float, float, float], tuple[float, float, float]]:
"""Given a profile, return colors for them.""" """Given a profile, return colors for them."""
appconfig = _babase.app.config appconfig = babase.app.config
if profiles is None: if profiles is None:
profiles = appconfig['Player Profiles'] profiles = appconfig['Player Profiles']
# Special case: when being asked for a random color in kiosk mode, # Special case: when being asked for a random color in kiosk mode,
# always return default purple. # always return default purple.
if ( if (babase.app.demo_mode or babase.app.arcade_mode) and profilename is None:
_babase.app.demo_mode or _babase.app.arcade_mode
) and profilename is None:
color = (0.5, 0.4, 1.0) color = (0.5, 0.4, 1.0)
highlight = (0.4, 0.4, 0.5) highlight = (0.4, 0.4, 0.5)
else: else:

View File

@ -406,8 +406,6 @@ class Session:
this time, unless 'force' is True, in which case the new results this time, unless 'force' is True, in which case the new results
will replace the old. will replace the old.
""" """
from babase._general import Call
# Only pay attention if this is coming from our current activity. # Only pay attention if this is coming from our current activity.
if activity is not self._activity_retained: if activity is not self._activity_retained:
return return
@ -428,7 +426,8 @@ class Session:
# Set a timer to set in motion this activity's demise. # Set a timer to set in motion this activity's demise.
self._activity_end_timer = _bascenev1.BaseTimer( self._activity_end_timer = _bascenev1.BaseTimer(
delay, Call(self._complete_end_activity, activity, results) delay,
babase.Call(self._complete_end_activity, activity, results),
) )
def handlemessage(self, msg: Any) -> Any: def handlemessage(self, msg: Any) -> Any:
@ -675,13 +674,12 @@ class Session:
) -> None: ) -> None:
"""(internal)""" """(internal)"""
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from babase._apputils import garbage_collect
# Since things should be generally still right now, it's a good time # Since things should be generally still right now, it's a good time
# to run garbage collection to clear out any circular dependency # to run garbage collection to clear out any circular dependency
# loops. We keep this disabled normally to avoid non-deterministic # loops. We keep this disabled normally to avoid non-deterministic
# hitches. # hitches.
garbage_collect() babase.garbage_collect()
assert babase.app.classic is not None assert babase.app.classic is not None
with self.context: with self.context:

View File

@ -5,24 +5,18 @@ from __future__ import annotations
import random import random
import weakref import weakref
import logging
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from dataclasses import dataclass from dataclasses import dataclass
import _babase import babase
import _bascenev1 import _bascenev1
from babase._error import (
print_exception,
print_error,
SessionTeamNotFoundError,
SessionPlayerNotFoundError,
NotFoundError,
)
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any, Sequence from typing import Any, Sequence
import babase
import bascenev1 import bascenev1
@ -84,7 +78,7 @@ class PlayerRecord:
assert self._sessionteam is not None assert self._sessionteam is not None
team = self._sessionteam() team = self._sessionteam()
if team is None: if team is None:
raise SessionTeamNotFoundError() raise babase.SessionTeamNotFoundError()
return team return team
@property @property
@ -95,7 +89,7 @@ class PlayerRecord:
no longer exists. no longer exists.
""" """
if not self._sessionplayer: if not self._sessionplayer:
raise SessionPlayerNotFoundError() raise babase.SessionPlayerNotFoundError()
return self._sessionplayer return self._sessionplayer
def getname(self, full: bool = False) -> str: def getname(self, full: bool = False) -> str:
@ -213,13 +207,13 @@ class PlayerRecord:
if self._sessionplayer.activityplayer is not None: if self._sessionplayer.activityplayer is not None:
try: try:
our_pos = self._sessionplayer.activityplayer.position our_pos = self._sessionplayer.activityplayer.position
except NotFoundError: except babase.NotFoundError:
pass pass
if our_pos is None: if our_pos is None:
return return
# Jitter position a bit since these often come in clusters. # Jitter position a bit since these often come in clusters.
our_pos = _babase.Vec3( our_pos = babase.Vec3(
our_pos[0] + (random.random() - 0.5) * 2.0, our_pos[0] + (random.random() - 0.5) * 2.0,
our_pos[1] + (random.random() - 0.5) * 2.0, our_pos[1] + (random.random() - 0.5) * 2.0,
our_pos[2] + (random.random() - 0.5) * 2.0, our_pos[2] + (random.random() - 0.5) * 2.0,
@ -279,7 +273,7 @@ class Stats:
# Load our media into this activity's context. # Load our media into this activity's context.
if activity is not None: if activity is not None:
if activity.expired: if activity.expired:
print_error('unexpected finalized activity') logging.exception('Unexpected finalized activity.')
else: else:
with activity.context: with activity.context:
self._load_activity_media() self._load_activity_media()
@ -403,7 +397,7 @@ class Stats:
color=_math.normalized_color(player.team.color), color=_math.normalized_color(player.team.color),
) )
except Exception: except Exception:
print_exception('error showing big_message') logging.exception('Error showing big_message.')
# If we currently have a actor, pop up a score over it. # If we currently have a actor, pop up a score over it.
if display and showpoints: if display and showpoints:
@ -450,7 +444,7 @@ class Stats:
image=player.get_icon(), image=player.get_icon(),
) )
except Exception: except Exception:
print_exception('error announcing score') logging.exception('Error announcing score.')
s_player.score += points s_player.score += points
s_player.accumscore += points s_player.accumscore += points
@ -524,4 +518,4 @@ class Stats:
image=player.get_icon(), image=player.get_icon(),
) )
except Exception: except Exception:
print_exception('error announcing kill') logging.exception('Error announcing kill.')

View File

@ -5,14 +5,14 @@
from __future__ import annotations from __future__ import annotations
import weakref import weakref
import logging
from typing import TYPE_CHECKING, TypeVar, Generic from typing import TYPE_CHECKING, TypeVar, Generic
from babase._error import print_exception import babase
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Sequence from typing import Sequence
import babase
import bascenev1 import bascenev1
@ -170,7 +170,7 @@ class Team(Generic[PlayerT]):
try: try:
self.on_expire() self.on_expire()
except Exception: except Exception:
print_exception(f'Error in on_expire for {self}.') logging.exception('Error in on_expire for %s.', self)
del self._customdata del self._customdata
del self.players del self.players
@ -189,9 +189,8 @@ class Team(Generic[PlayerT]):
sessionteam = self._sessionteam() sessionteam = self._sessionteam()
if sessionteam is not None: if sessionteam is not None:
return sessionteam return sessionteam
from babase import _error
raise _error.SessionTeamNotFoundError() raise babase.SessionTeamNotFoundError()
class EmptyTeam(Team['bascenev1.EmptyPlayer']): class EmptyTeam(Team['bascenev1.EmptyPlayer']):