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
from _babase import (
have_chars,
android_get_external_files_dir,
is_os_playing_music,
getsimplesound,
@ -275,6 +276,7 @@ __all__ = [
'getsimplesound',
'is_os_playing_music',
'android_get_external_files_dir',
'have_chars',
]
# We want stuff to show up as babase.Foo instead of babase._sub.Foo.

View File

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

View File

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

View File

@ -4,8 +4,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING
import logging
import _babase
import babase
if TYPE_CHECKING:
from typing import Any
@ -23,15 +24,15 @@ def get_input_device_mapped_value(
# pylint: disable=too-many-return-statements
# pylint: disable=too-many-branches
app = _babase.app
app = babase.app
assert app.classic is not None
useragentstring = app.classic.user_agent_string
platform = app.classic.platform
subplatform = app.classic.subplatform
appconfig = _babase.app.config
appconfig = babase.app.config
# iiRcade: hard-code for a/b/c/x for now...
if _babase.app.iircade_mode:
if babase.app.iircade_mode:
return {
'triggerRun2': 19,
'unassignedButtonsRun': False,
@ -97,7 +98,7 @@ def get_input_device_mapped_value(
}.get(name, -1)
# 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']:
return {
'triggerRun2': 23,
@ -516,7 +517,7 @@ def get_input_device_mapped_value(
# Reasonable defaults.
if platform == 'android':
if _babase.is_running_on_fire_tv():
if babase.is_running_on_fire_tv():
# Mostly same as default firetv controller.
return {
'triggerRun2': 23,
@ -575,11 +576,7 @@ def _gen_android_input_hash() -> str:
except PermissionError:
pass
except Exception:
from babase import _error
_error.print_exception(
'error in _gen_android_input_hash inner loop'
)
logging.exception('Error in _gen_android_input_hash inner loop.')
return md5.hexdigest()
@ -591,7 +588,7 @@ def get_input_device_map_hash() -> str:
(Different Android versions, for example, may return different
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.
# Need to replace with a modern equivalent.
@ -604,9 +601,7 @@ def get_input_device_map_hash() -> str:
app.classic.input_map_hash = ''
return app.classic.input_map_hash
except Exception:
from babase import _error
_error.print_exception('Exception in get_input_map_hash')
logging.exception('Error in get_input_map_hash.')
return ''
return ''
@ -618,7 +613,7 @@ def get_input_device_config(
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.setdefault(name, {})
if default:

View File

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

View File

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

View File

@ -146,6 +146,7 @@ from bascenev1._profile import (
get_player_profile_icon,
get_player_profile_colors,
)
from bascenev1._map import get_map_display_string
from bascenev1._campaign import init_campaigns
from bascenev1._appmode import SceneV1AppMode
from bascenev1._session import Session
@ -413,6 +414,7 @@ __all__ = [
'set_master_server_source',
'init_campaigns',
'register_map',
'get_map_display_string',
]
# 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
import _babase
import babase
import _bascenev1
from babase._mgen.enums import InputType, UIScale
from bascenev1._activity import Activity
# 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
if TYPE_CHECKING:
import babase
import bascenev1
from bascenev1._lobby import JoinInfo
@ -36,22 +35,21 @@ class EndSessionActivity(Activity[EmptyPlayer, EmptyTeam]):
def on_transition_in(self) -> None:
super().on_transition_in()
_babase.fade_screen(False)
_babase.lock_all_input()
babase.fade_screen(False)
babase.lock_all_input()
def on_begin(self) -> None:
# pylint: disable=cyclic-import
assert _babase.app.classic is not None
from babase._general import Call
assert babase.app.classic is not None
main_menu_session = _babase.app.classic.get_main_menu_session()
main_menu_session = babase.app.classic.get_main_menu_session()
super().on_begin()
_babase.unlock_all_input()
assert _babase.app.classic is not None
_babase.app.classic.ads.call_after_ad(
Call(_bascenev1.new_host_session, main_menu_session)
babase.unlock_all_input()
assert babase.app.classic is not None
babase.app.classic.ads.call_after_ad(
babase.Call(_bascenev1.new_host_session, main_menu_session)
)
@ -90,7 +88,7 @@ class JoinActivity(Activity[EmptyPlayer, EmptyTeam]):
self._tips_text = TipsText()
setmusic(MusicType.CHAR_SELECT)
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]):
@ -142,7 +140,7 @@ class ScoreScreenActivity(Activity[EmptyPlayer, EmptyTeam]):
def __init__(self, settings: dict):
super().__init__(settings)
self._birth_time = _babase.apptime()
self._birth_time = babase.apptime()
self._min_view_time = 5.0
self._allow_server_transition = False
self._background: bascenev1.Actor | None = None
@ -154,16 +152,16 @@ class ScoreScreenActivity(Activity[EmptyPlayer, EmptyTeam]):
self._server_transitioning: bool | None = None
def on_player_join(self, player: EmptyPlayer) -> None:
from babase._general import WeakCall
super().on_player_join(player)
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
# 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:
from bascenev1lib.actor.tipstext import TipsText
@ -180,20 +178,19 @@ class ScoreScreenActivity(Activity[EmptyPlayer, EmptyTeam]):
def on_begin(self) -> None:
# pylint: disable=cyclic-import
from bascenev1lib.actor.text import Text
from babase import _language
super().on_begin()
# Pop up a 'press any button to continue' statement after our
# min-view-time show a 'press any button to continue..'
# thing after a bit.
assert _babase.app.classic is not None
if _babase.app.ui_v1.uiscale is UIScale.LARGE:
assert babase.app.classic is not None
if babase.app.ui_v1.uiscale is babase.UIScale.LARGE:
# FIXME: Need a better way to determine whether we've probably
# got a keyboard.
sval = _language.Lstr(resource='pressAnyKeyButtonText')
sval = babase.Lstr(resource='pressAnyKeyButtonText')
else:
sval = _language.Lstr(resource='pressAnyButtonText')
sval = babase.Lstr(resource='pressAnyButtonText')
Text(
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.
if (
self._allow_server_transition
and _babase.app.classic is not None
and _babase.app.classic.server is not None
and babase.app.classic is not None
and babase.app.classic.server is not None
and self._server_transitioning is None
):
self._server_transitioning = (
_babase.app.classic.server.handle_transition()
babase.app.classic.server.handle_transition()
)
assert isinstance(self._server_transitioning, bool)
@ -237,10 +234,10 @@ class ScoreScreenActivity(Activity[EmptyPlayer, EmptyTeam]):
if not self.is_transitioning_out() and player:
player.assigninput(
(
InputType.JUMP_PRESS,
InputType.PUNCH_PRESS,
InputType.BOMB_PRESS,
InputType.PICK_UP_PRESS,
babase.InputType.JUMP_PRESS,
babase.InputType.PUNCH_PRESS,
babase.InputType.BOMB_PRESS,
babase.InputType.PICK_UP_PRESS,
),
self._player_press,
)

View File

@ -96,7 +96,6 @@ class CoopGameActivity(GameActivity[PlayerT, TeamT]):
def _show_remaining_achievements(self) -> None:
# pylint: disable=cyclic-import
from babase._language import Lstr
from bascenev1lib.actor.text import Text
assert babase.app.classic is not None
@ -112,7 +111,7 @@ class CoopGameActivity(GameActivity[PlayerT, TeamT]):
vrmode = babase.app.vr_mode
if achievements:
Text(
Lstr(resource='achievementsRemainingText'),
babase.Lstr(resource='achievementsRemainingText'),
host_only=True,
position=(ts_h_offs - 10 + 40, v_offs - 10),
transition=Text.Transition.FADE_IN,
@ -182,9 +181,7 @@ class CoopGameActivity(GameActivity[PlayerT, TeamT]):
if ach.hard_mode_only and campaign.name == 'Easy':
return
except Exception:
from babase._error import print_exception
print_exception()
logging.exception('Error in _award_achievement.')
# 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

View File

@ -178,11 +178,9 @@ class CoopSession(Session):
return self._custom_menu_ui
def on_player_leave(self, sessionplayer: bascenev1.SessionPlayer) -> None:
from babase._general import WeakCall
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:
"""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-statements
# pylint: disable=cyclic-import
from babase._language import Lstr
from babase._general import WeakCall
from bascenev1lib.activity.coopscore import CoopScoreScreen
from bascenev1lib.tutorial import TutorialActivity
from bascenev1._gameresults import GameResults
from bascenev1._player import PlayerInfo
from bascenev1._activitytypes import JoinActivity, TransitionActivity
from bascenev1._coopgame import CoopGameActivity
from bascenev1._score import ScoreType
from bascenev1lib.activity.coopscore import CoopScoreScreen
from bascenev1lib.tutorial import TutorialActivity
app = babase.app
classic = app.classic
@ -346,9 +343,9 @@ class CoopSession(Session):
if self.tournament_id is not None:
self._custom_menu_ui = [
{
'label': Lstr(resource='restartText'),
'label': babase.Lstr(resource='restartText'),
'resume_on_call': False,
'call': WeakCall(
'call': babase.WeakCall(
self._on_tournament_restart_menu_press
),
}
@ -356,8 +353,8 @@ class CoopSession(Session):
else:
self._custom_menu_ui = [
{
'label': Lstr(resource='restartText'),
'call': WeakCall(self.restart),
'label': babase.Lstr(resource='restartText'),
'call': babase.WeakCall(self.restart),
}
]

View File

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

View File

@ -6,15 +6,14 @@ from __future__ import annotations
import random
from typing import TYPE_CHECKING
import _babase
import babase
import _bascenev1
from babase import _math
from bascenev1._actor import Actor
if TYPE_CHECKING:
from typing import Sequence, Any
import babase
import bascenev1
@ -38,9 +37,7 @@ def get_map_display_string(name: str) -> babase.Lstr:
Category: **Asset Functions**
"""
from babase import _language
return _language.Lstr(translate=('mapsNames', name))
return babase.Lstr(translate=('mapsNames', name))
def get_map_class(name: str) -> type[Map]:
@ -48,15 +45,13 @@ def get_map_class(name: str) -> type[Map]:
Category: **Asset Functions**
"""
assert _babase.app.classic is not None
assert babase.app.classic is not None
name = get_filtered_map_name(name)
try:
mapclass: type[Map] = _babase.app.classic.maps[name]
mapclass: type[Map] = babase.app.classic.maps[name]
return mapclass
except KeyError:
from babase import _error
raise _error.NotFoundError(f"Map not found: '{name}'") from None
raise babase.NotFoundError(f"Map not found: '{name}'") from None
class Map(Actor):
@ -133,9 +128,7 @@ class Map(Actor):
try:
self.preloaddata = _bascenev1.getactivity().preloads[type(self)]
except Exception as exc:
from babase import _error
raise _error.NotFoundError(
raise babase.NotFoundError(
'Preload data not found for '
+ str(type(self))
+ '; make sure to call the type\'s preload()'
@ -262,7 +255,7 @@ class Map(Actor):
return (
None
if val is None
else _math.vec3validate(val)
else babase.vec3validate(val)
if __debug__
else val
)
@ -336,7 +329,7 @@ class Map(Actor):
farthestpt_dist = -1.0
farthestpt = None
for _i in range(10):
testpt = _babase.Vec3(_getpt())
testpt = babase.Vec3(_getpt())
closest_player_dist = 9999.0
for ppt in player_pts:
dist = (ppt - testpt).length()
@ -376,7 +369,7 @@ class Map(Actor):
def register_map(maptype: type[Map]) -> None:
"""Register a map class with the game."""
assert _babase.app.classic is not None
if maptype.name in _babase.app.classic.maps:
assert babase.app.classic is not None
if maptype.name in babase.app.classic.maps:
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
import logging
from dataclasses import dataclass
from typing import TYPE_CHECKING, TypeVar, Generic, cast
import _babase
from babase._error import (
SessionPlayerNotFoundError,
print_exception,
ActorNotFoundError,
)
import babase
import _bascenev1
from bascenev1._messages import DeathType, DieMessage
if TYPE_CHECKING:
from typing import Sequence, Any, Callable
import babase
import bascenev1
PlayerT = TypeVar('PlayerT', bound='bascenev1.Player')
@ -130,7 +126,7 @@ class Player(Generic[TeamT]):
self.actor.handlemessage(DieMessage(how=DeathType.LEFT_GAME))
self.actor = None
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
del self._team
del self._customdata
@ -147,7 +143,7 @@ class Player(Generic[TeamT]):
try:
self.on_expire()
except Exception:
print_exception(f'Error in on_expire for {self}.')
logging.exception('Error in on_expire for %s.', self)
self._nodeactor = None
self.actor = None
@ -193,7 +189,7 @@ class Player(Generic[TeamT]):
assert self._postinited
if bool(self._sessionplayer):
return self._sessionplayer
raise SessionPlayerNotFoundError()
raise babase.SessionPlayerNotFoundError()
@property
def node(self) -> bascenev1.Node:
@ -216,8 +212,8 @@ class Player(Generic[TeamT]):
assert self._postinited
assert not self._expired
if self.actor is None:
raise ActorNotFoundError
return _babase.Vec3(self.node.position)
raise babase.ActorNotFoundError
return babase.Vec3(self.node.position)
def exists(self) -> bool:
"""Whether the underlying player still exists.

View File

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

View File

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

View File

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

View File

@ -5,24 +5,18 @@ from __future__ import annotations
import random
import weakref
import logging
from typing import TYPE_CHECKING
from dataclasses import dataclass
import _babase
import babase
import _bascenev1
from babase._error import (
print_exception,
print_error,
SessionTeamNotFoundError,
SessionPlayerNotFoundError,
NotFoundError,
)
if TYPE_CHECKING:
from typing import Any, Sequence
import babase
import bascenev1
@ -84,7 +78,7 @@ class PlayerRecord:
assert self._sessionteam is not None
team = self._sessionteam()
if team is None:
raise SessionTeamNotFoundError()
raise babase.SessionTeamNotFoundError()
return team
@property
@ -95,7 +89,7 @@ class PlayerRecord:
no longer exists.
"""
if not self._sessionplayer:
raise SessionPlayerNotFoundError()
raise babase.SessionPlayerNotFoundError()
return self._sessionplayer
def getname(self, full: bool = False) -> str:
@ -213,13 +207,13 @@ class PlayerRecord:
if self._sessionplayer.activityplayer is not None:
try:
our_pos = self._sessionplayer.activityplayer.position
except NotFoundError:
except babase.NotFoundError:
pass
if our_pos is None:
return
# 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[1] + (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.
if activity is not None:
if activity.expired:
print_error('unexpected finalized activity')
logging.exception('Unexpected finalized activity.')
else:
with activity.context:
self._load_activity_media()
@ -403,7 +397,7 @@ class Stats:
color=_math.normalized_color(player.team.color),
)
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 display and showpoints:
@ -450,7 +444,7 @@ class Stats:
image=player.get_icon(),
)
except Exception:
print_exception('error announcing score')
logging.exception('Error announcing score.')
s_player.score += points
s_player.accumscore += points
@ -524,4 +518,4 @@ class Stats:
image=player.get_icon(),
)
except Exception:
print_exception('error announcing kill')
logging.exception('Error announcing kill.')

View File

@ -5,14 +5,14 @@
from __future__ import annotations
import weakref
import logging
from typing import TYPE_CHECKING, TypeVar, Generic
from babase._error import print_exception
import babase
if TYPE_CHECKING:
from typing import Sequence
import babase
import bascenev1
@ -170,7 +170,7 @@ class Team(Generic[PlayerT]):
try:
self.on_expire()
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.players
@ -189,9 +189,8 @@ class Team(Generic[PlayerT]):
sessionteam = self._sessionteam()
if sessionteam is not None:
return sessionteam
from babase import _error
raise _error.SessionTeamNotFoundError()
raise babase.SessionTeamNotFoundError()
class EmptyTeam(Team['bascenev1.EmptyPlayer']):