This commit is contained in:
indev 2020-04-11 11:17:00 +03:00
commit bafc80fe40
56 changed files with 176 additions and 188 deletions

View File

@ -4114,10 +4114,10 @@
"assets/build/windows/x64/python.exe": "https://files.ballistica.net/cache/ba1/25/a7/dc87c1be41605eb6fefd0145144c", "assets/build/windows/x64/python.exe": "https://files.ballistica.net/cache/ba1/25/a7/dc87c1be41605eb6fefd0145144c",
"assets/build/windows/x64/python37.dll": "https://files.ballistica.net/cache/ba1/b9/e4/d912f56e42e9991bcbb4c804cfcb", "assets/build/windows/x64/python37.dll": "https://files.ballistica.net/cache/ba1/b9/e4/d912f56e42e9991bcbb4c804cfcb",
"assets/build/windows/x64/pythonw.exe": "https://files.ballistica.net/cache/ba1/6c/bb/b6f52c306aa4e88061510e96cefe", "assets/build/windows/x64/pythonw.exe": "https://files.ballistica.net/cache/ba1/6c/bb/b6f52c306aa4e88061510e96cefe",
"build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/6b/88/a8f82a340a0fba36edfe95298871", "build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/85/4e/8e17f105c42bd7c399f4f60c43b3",
"build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d3/72/4ad974215d1cfd0db7f14af5f6c3", "build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/eb/b5/3a5b133d3a1d5a3de35fd3cfbbbc",
"build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/82/c3/388d9a77f8bde608d7cdf2891ad3", "build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/de/ce/80e52a4d428d8500a2095d6ce470",
"build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/6c/6f/d2ffeecb1e9a18678b1ec1695198", "build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/28/15/aecd6c5dd487f607e47da088bee2",
"build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/77/68/e7ac990ee0ec25dd6a459e637d9f", "build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/c6/78/f6383a7b421ecaac09d5cfd02107",
"build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/e8/ce/1091fea9004ca76f6b8ccde8b839" "build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/cf/7e/aa37853a635b2b89ea32f98db407"
} }

View File

@ -1483,6 +1483,7 @@
<w>sclx</w> <w>sclx</w>
<w>scly</w> <w>scly</w>
<w>scorescreen</w> <w>scorescreen</w>
<w>scoreteam</w>
<w>scoretxt</w> <w>scoretxt</w>
<w>scoreval</w> <w>scoreval</w>
<w>scorever</w> <w>scorever</w>

View File

@ -34,7 +34,7 @@ NOTE: This file was autogenerated by gendummymodule; do not edit by hand.
""" """
# (hash we can use to see if this file is out of date) # (hash we can use to see if this file is out of date)
# SOURCES_HASH=126196922259492504803685031830587478733 # SOURCES_HASH=106879997712807296258529817433289194930
# I'm sorry Pylint. I know this file saddens you. Be strong. # I'm sorry Pylint. I know this file saddens you. Be strong.
# pylint: disable=useless-suppression # pylint: disable=useless-suppression
@ -2191,12 +2191,12 @@ def get_price(item: str) -> Optional[str]:
return "" return ""
def get_public_login_id() -> str: def get_public_login_id() -> Optional[str]:
"""get_public_login_id() -> str """get_public_login_id() -> Optional[str]
(internal) (internal)
""" """
return str() return ""
def get_public_party_enabled() -> bool: def get_public_party_enabled() -> bool:

View File

@ -83,7 +83,7 @@ def award_local_achievement(achname: str) -> None:
"""For non-game-based achievements such as controller-connection ones.""" """For non-game-based achievements such as controller-connection ones."""
try: try:
ach = get_achievement(achname) ach = get_achievement(achname)
if ach is not None and not ach.complete: if not ach.complete:
# Report new achievements to the game-service. # Report new achievements to the game-service.
_ba.report_achievement(achname) _ba.report_achievement(achname)
@ -680,7 +680,7 @@ class Achievement:
# 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 = _ba.getactivity(doraise=False) activity: Optional[ba.Activity] = _ba.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

View File

@ -398,13 +398,13 @@ class App:
# Gameplay. # Gameplay.
self.teams_series_length = 7 self.teams_series_length = 7
self.ffa_series_length = 24 self.ffa_series_length = 24
self.coop_session_args: dict = {} self.coop_session_args: Dict = {}
# UI. # UI.
self.uicontroller: Optional[ba.UIController] = None self.uicontroller: Optional[ba.UIController] = None
self.main_menu_window: Optional[_ba.Widget] = None # FIXME: Kill this. self.main_menu_window: Optional[_ba.Widget] = None # FIXME: Kill this.
self.window_states: dict = {} # FIXME: Kill this. self.window_states: Dict = {} # FIXME: Kill this.
self.windows: dict = {} # FIXME: Kill this. self.windows: Dict = {} # FIXME: Kill this.
self.main_window: Optional[str] = None # FIXME: Kill this. self.main_window: Optional[str] = None # FIXME: Kill this.
self.main_menu_selection: Optional[str] = None # FIXME: Kill this. self.main_menu_selection: Optional[str] = None # FIXME: Kill this.
self.have_party_queue_window = False self.have_party_queue_window = False
@ -416,9 +416,9 @@ class App:
self.first_main_menu = True # FIXME: Move to mainmenu class. self.first_main_menu = True # FIXME: Move to mainmenu class.
self.did_menu_intro = False # FIXME: Move to mainmenu class. self.did_menu_intro = False # FIXME: Move to mainmenu class.
self.main_menu_resume_callbacks: list = [] # can probably go away self.main_menu_resume_callbacks: list = [] # can probably go away
self.special_offer = None self.special_offer: Optional[Dict] = None
self.league_rank_cache: dict = {} self.league_rank_cache: Dict = {}
self.tournament_info: dict = {} self.tournament_info: Dict = {}
self.account_tournament_list: Optional[Tuple[int, List[str]]] = None self.account_tournament_list: Optional[Tuple[int, List[str]]] = None
self.ping_thread_count = 0 self.ping_thread_count = 0
self.invite_confirm_windows: List[Any] = [] # FIXME: Don't use Any. self.invite_confirm_windows: List[Any] = [] # FIXME: Don't use Any.
@ -635,7 +635,7 @@ class App:
If there's a foreground host-activity that says it's pausable, tell it If there's a foreground host-activity that says it's pausable, tell it
to pause ..we now no longer pause if there are connected clients. to pause ..we now no longer pause if there are connected clients.
""" """
activity = _ba.get_foreground_host_activity() activity: Optional[ba.Activity] = _ba.get_foreground_host_activity()
if (activity is not None and activity.allow_pausing if (activity is not None and activity.allow_pausing
and not _ba.have_connected_clients()): and not _ba.have_connected_clients()):
from ba import _gameutils, _lang from ba import _gameutils, _lang
@ -698,7 +698,7 @@ class App:
# If we're in a host-session, tell them to end. # If we're in a host-session, tell them to end.
# This lets them tear themselves down gracefully. # This lets them tear themselves down gracefully.
host_session = _ba.get_foreground_host_session() host_session: Optional[ba.Session] = _ba.get_foreground_host_session()
if host_session is not None: if host_session is not None:
# Kick off a little transaction so we'll hopefully have all the # Kick off a little transaction so we'll hopefully have all the

View File

@ -173,8 +173,7 @@ def garbage_collect(session_end: bool = True) -> None:
gc.collect() gc.collect()
# Can be handy to print this to check for leaks between games. # Can be handy to print this to check for leaks between games.
# noinspection PyUnreachableCode if bool(False):
if False: # pylint: disable=using-constant-test
print('PY OBJ COUNT', len(gc.get_objects())) print('PY OBJ COUNT', len(gc.get_objects()))
if gc.garbage: if gc.garbage:
print('PYTHON GC FOUND', len(gc.garbage), 'UNCOLLECTIBLE OBJECTS:') print('PYTHON GC FOUND', len(gc.garbage), 'UNCOLLECTIBLE OBJECTS:')

View File

@ -192,7 +192,7 @@ class CoopSession(Session):
# If there's *no* players left in the current activity but there *is* # If there's *no* players left in the current activity but there *is*
# in the session, restart the activity to pull them into the game # in the session, restart the activity to pull them into the game
# (or quit if they're just in the lobby). # (or quit if they're just in the lobby).
if activity is not None and not activity.players and self.players: if not activity.players and self.players:
# Special exception for tourney games; don't auto-restart these. # Special exception for tourney games; don't auto-restart these.
if self.tournament_id is not None: if self.tournament_id is not None:

View File

@ -409,8 +409,7 @@ class TestClass(DependencyComponent):
def test_depset() -> None: def test_depset() -> None:
"""Test call to try this stuff out...""" """Test call to try this stuff out..."""
# noinspection PyUnreachableCode if bool(False):
if False: # pylint: disable=using-constant-test
print('running test_depset()...') print('running test_depset()...')
def doit() -> None: def doit() -> None:

View File

@ -52,7 +52,8 @@ class TeamGameResults:
def __init__(self) -> None: def __init__(self) -> None:
"""Instantiate a results instance.""" """Instantiate a results instance."""
self._game_set = False self._game_set = False
self._scores: Dict[int, Tuple[ReferenceType[ba.Team], int]] = {} self._scores: Dict[int, Tuple[ReferenceType[ba.Team],
Optional[int]]] = {}
self._teams: Optional[List[ReferenceType[ba.Team]]] = None self._teams: Optional[List[ReferenceType[ba.Team]]] = None
self._player_info: Optional[List[Dict[str, Any]]] = None self._player_info: Optional[List[Dict[str, Any]]] = None
self._lower_is_better: Optional[bool] = None self._lower_is_better: Optional[bool] = None
@ -183,19 +184,21 @@ class TeamGameResults:
if score[0]() is not None and score[1] is not None if score[0]() is not None and score[1] is not None
] ]
for score in scores: for score in scores:
assert score[1] is not None
sval = winners.setdefault(score[1], []) sval = winners.setdefault(score[1], [])
team = score[0]() team = score[0]()
assert team is not None assert team is not None
sval.append(team) sval.append(team)
results: List[Tuple[Optional[int], results: List[Tuple[Optional[int],
List[ba.Team]]] = list(winners.items()) List[ba.Team]]] = list(winners.items())
results.sort(reverse=not self._lower_is_better) results.sort(reverse=not self._lower_is_better, key=lambda x: x[0])
# Also group the 'None' scores. # Also group the 'None' scores.
none_teams: List[ba.Team] = [] none_teams: List[ba.Team] = []
for score in self._scores.values(): for score in self._scores.values():
if score[0]() is not None and score[1] is None: scoreteam = score[0]()
none_teams.append(score[0]()) if scoreteam is not None and score[1] is None:
none_teams.append(scoreteam)
# Add the Nones to the list (either as winners or losers # Add the Nones to the list (either as winners or losers
# depending on the rules). # depending on the rules).

View File

@ -27,7 +27,7 @@ import _ba
from ba._enums import TimeType, TimeFormat, SpecialChar from ba._enums import TimeType, TimeFormat, SpecialChar
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any, Dict, Sequence from typing import Any, Dict, Sequence, Optional
import ba import ba
TROPHY_CHARS = { TROPHY_CHARS = {
@ -97,7 +97,7 @@ def sharedobj(name: str) -> Any:
# We store these on the current context; whether its an activity or # We store these on the current context; whether its an activity or
# session. # session.
activity = _ba.getactivity(doraise=False) activity: Optional[ba.Activity] = _ba.getactivity(doraise=False)
if activity is not None: if activity is not None:
# Grab shared-objs dict. # Grab shared-objs dict.
@ -141,7 +141,7 @@ def sharedobj(name: str) -> Any:
"unrecognized shared object (activity context): '" + name + "unrecognized shared object (activity context): '" + name +
"'") "'")
else: else:
session = _ba.getsession(doraise=False) session: Optional[ba.Session] = _ba.getsession(doraise=False)
if session is not None: if session is not None:
# Grab shared-objs dict (creating if necessary). # Grab shared-objs dict (creating if necessary).

View File

@ -39,9 +39,8 @@ def getclass(name: str, subclassof: Type[T]) -> Type[T]:
Category: General Utility Functions Category: General Utility Functions
If 'subclassof' is given, the class will be checked to make sure The class will be checked to make sure it is a subclass of the provided
it is a subclass of the provided class, and a TypeError will be 'subclassof' class, and a TypeError will be raised if not.
raised if not.
""" """
import importlib import importlib
splits = name.split('.') splits = name.split('.')
@ -50,7 +49,7 @@ def getclass(name: str, subclassof: Type[T]) -> Type[T]:
module = importlib.import_module(modulename) module = importlib.import_module(modulename)
cls: Type = getattr(module, classname) cls: Type = getattr(module, classname)
if subclassof is not None and not issubclass(cls, subclassof): if not issubclass(cls, subclassof):
raise TypeError(name + ' is not a subclass of ' + str(subclassof)) raise TypeError(name + ' is not a subclass of ' + str(subclassof))
return cls return cls

View File

@ -432,6 +432,7 @@ def get_valid_languages() -> List[str]:
def is_custom_unicode_char(char: str) -> bool: def is_custom_unicode_char(char: str) -> bool:
"""Return whether a char is in the custom unicode range we use.""" """Return whether a char is in the custom unicode range we use."""
if not isinstance(char, str) or len(char) != 1: assert isinstance(char, str)
raise Exception("Invalid Input; not unicode or not length 1") if len(char) != 1:
raise Exception("Invalid Input; must be length 1")
return 0xE000 <= ord(char) <= 0xF8FF return 0xE000 <= ord(char) <= 0xF8FF

View File

@ -117,7 +117,8 @@ class Level:
def set_complete(self, val: bool) -> None: def set_complete(self, val: bool) -> None:
"""Set whether or not this level is complete.""" """Set whether or not this level is complete."""
old_val = self.complete old_val = self.complete
assert isinstance(old_val, bool) and isinstance(val, bool) assert isinstance(old_val, bool)
assert isinstance(val, bool)
if val != old_val: if val != old_val:
config = self._get_config_dict() config = self._get_config_dict()
config['Complete'] = val config['Complete'] = val

View File

@ -55,7 +55,8 @@ class JoinInfo:
# If we have a keyboard, grab keys for punch and pickup. # If we have a keyboard, grab keys for punch and pickup.
# FIXME: This of course is only correct on the local device; # FIXME: This of course is only correct on the local device;
# Should change this for net games. # Should change this for net games.
keyboard = _ba.get_input_device('Keyboard', '#1', doraise=False) keyboard: Optional[ba.InputDevice] = _ba.get_input_device(
'Keyboard', '#1', doraise=False)
if keyboard is not None: if keyboard is not None:
punch_key = keyboard.get_button_name( punch_key = keyboard.get_button_name(
_input.get_device_value(keyboard, 'buttonPunch')) _input.get_device_value(keyboard, 'buttonPunch'))
@ -398,8 +399,7 @@ class Chooser:
# list might have changed. # list might have changed.
input_device = self._player.get_input_device() input_device = self._player.get_input_device()
is_remote = input_device.is_remote_client is_remote = input_device.is_remote_client
is_test_input = (input_device is not None is_test_input = input_device.name.startswith('TestInput')
and input_device.name.startswith('TestInput'))
# Pull this player's list of unlocked characters. # Pull this player's list of unlocked characters.
if is_remote: if is_remote:

View File

@ -19,11 +19,16 @@
# SOFTWARE. # SOFTWARE.
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
"""Functionality related to modding.""" """Functionality related to modding."""
from __future__ import annotations
from typing import TYPE_CHECKING
import os import os
import _ba import _ba
if TYPE_CHECKING:
from typing import Optional
def get_human_readable_user_scripts_path() -> str: def get_human_readable_user_scripts_path() -> str:
"""Return a human readable location of user-scripts. """Return a human readable location of user-scripts.
@ -32,7 +37,7 @@ def get_human_readable_user_scripts_path() -> str:
""" """
from ba import _lang from ba import _lang
app = _ba.app app = _ba.app
path = app.user_scripts_directory path: Optional[str] = app.user_scripts_directory
if path is None: if path is None:
return '<Not Available>' return '<Not Available>'
@ -40,7 +45,8 @@ def get_human_readable_user_scripts_path() -> str:
# only visible to the user's processes and thus not really useful printed # only visible to the user's processes and thus not really useful printed
# in its entirety; lets print it as <External Storage>/myfilepath. # in its entirety; lets print it as <External Storage>/myfilepath.
if app.platform == 'android': if app.platform == 'android':
ext_storage_path = (_ba.android_get_external_storage_path()) ext_storage_path: Optional[str] = (
_ba.android_get_external_storage_path())
if (ext_storage_path is not None if (ext_storage_path is not None
and app.user_scripts_directory.startswith(ext_storage_path)): and app.user_scripts_directory.startswith(ext_storage_path)):
path = ('<' + path = ('<' +
@ -75,7 +81,7 @@ def show_user_scripts() -> None:
# they can see it. # they can see it.
if app.platform == 'android': if app.platform == 'android':
try: try:
usd = app.user_scripts_directory usd: Optional[str] = app.user_scripts_directory
if usd is not None and os.path.isdir(usd): if usd is not None and os.path.isdir(usd):
file_name = usd + '/about_this_folder.txt' file_name = usd + '/about_this_folder.txt'
with open(file_name, 'w') as outfile: with open(file_name, 'w') as outfile:

View File

@ -83,7 +83,7 @@ class MusicPlayer:
def __init__(self) -> None: def __init__(self) -> None:
self._have_set_initial_volume = False self._have_set_initial_volume = False
self._entry_to_play = None self._entry_to_play: Optional[Any] = None
self._volume = 1.0 self._volume = 1.0
self._actually_playing = False self._actually_playing = False

View File

@ -32,6 +32,7 @@ import _ba
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any, Dict, Union, Callable, Optional from typing import Any, Dict, Union, Callable, Optional
import socket import socket
import ba
ServerCallbackType = Callable[[Union[None, Dict[str, Any]]], None] ServerCallbackType = Callable[[Union[None, Dict[str, Any]]], None]
@ -82,7 +83,7 @@ class ServerCallThread(threading.Thread):
self._context = _ba.Context('current') self._context = _ba.Context('current')
# Save and restore the context we were created from. # Save and restore the context we were created from.
activity = _ba.getactivity(doraise=False) activity: Optional[ba.Activity] = _ba.getactivity(doraise=False)
self._activity = weakref.ref( self._activity = weakref.ref(
activity) if activity is not None else None activity) if activity is not None else None

View File

@ -746,7 +746,7 @@ class Session:
# Pass it to the current activity if it has already begun # Pass it to the current activity if it has already begun
# (otherwise it'll get passed once begin is called). # (otherwise it'll get passed once begin is called).
pass_to_activity = (activity is not None and activity.has_begun() pass_to_activity = (activity.has_begun()
and not activity.is_joining_activity) and not activity.is_joining_activity)
# If we're not allowing mid-game joins, don't pass; just announce # If we're not allowing mid-game joins, don't pass; just announce

View File

@ -256,7 +256,7 @@ class Stats:
self.orchestrahitsound3: Optional[ba.Sound] = None self.orchestrahitsound3: Optional[ba.Sound] = None
self.orchestrahitsound4: Optional[ba.Sound] = None self.orchestrahitsound4: Optional[ba.Sound] = None
def set_activity(self, activity: ba.Activity) -> None: def set_activity(self, activity: Optional[ba.Activity]) -> None:
"""Set the current activity for this instance.""" """Set the current activity for this instance."""
self._activity = None if activity is None else weakref.ref(activity) self._activity = None if activity is None else weakref.ref(activity)

View File

@ -30,7 +30,7 @@ if TYPE_CHECKING:
from typing import Dict, List, Any from typing import Dict, List, Any
def get_tournament_prize_strings(entry: Dict[str, Any]) -> List: def get_tournament_prize_strings(entry: Dict[str, Any]) -> List[str]:
"""Given a tournament entry, return strings for its prize levels.""" """Given a tournament entry, return strings for its prize levels."""
# pylint: disable=too-many-locals # pylint: disable=too-many-locals
from ba._enums import SpecialChar from ba._enums import SpecialChar
@ -54,22 +54,9 @@ def get_tournament_prize_strings(entry: Dict[str, Any]) -> List:
pvval = '' pvval = ''
if trophy_type is not None: if trophy_type is not None:
pvval += get_trophy_string(trophy_type) pvval += get_trophy_string(trophy_type)
# trophy_chars = {
# '1': SpecialChar.TROPHY1, # If we've got trophies but not for this entry, throw some space
# '2': SpecialChar.TROPHY2, # in to compensate so the ticket counts line up.
# '3': SpecialChar.TROPHY3,
# '0a': SpecialChar.TROPHY0A,
# '0b': SpecialChar.TROPHY0B,
# '4': SpecialChar.TROPHY4
# }
# if trophy_type in trophy_chars:
# pvval += _bs.specialchar(trophy_chars[trophy_type])
# else:
# from ba import err
# err.print_error(
# f"unrecognized trophy type: {trophy_type}", once=True)
# if we've got trophies but not for this entry, throw some space
# in to compensate so the ticket counts line up
if prize is not None: if prize is not None:
pvval = _ba.charstr( pvval = _ba.charstr(
SpecialChar.TICKET_BACKING) + str(prize) + pvval SpecialChar.TICKET_BACKING) + str(prize) + pvval

View File

@ -674,7 +674,8 @@ class CoopScoreScreen(ba.Activity):
our_score = None our_score = None
try: try:
our_high_scores.sort(reverse=self._score_order == 'increasing') our_high_scores.sort(reverse=self._score_order == 'increasing',
key=lambda x: x[0])
except Exception: except Exception:
ba.print_exception('Error sorting scores') ba.print_exception('Error sorting scores')
print('our_high_scores:', our_high_scores) print('our_high_scores:', our_high_scores)
@ -711,8 +712,7 @@ class CoopScoreScreen(ba.Activity):
order=self._score_order, order=self._score_order,
tournament_id=self.session.tournament_id, tournament_id=self.session.tournament_id,
score_type=self._score_type, score_type=self._score_type,
campaign=self._campaign.name campaign=self._campaign.name,
if self._campaign is not None else None,
level=self._level_name) level=self._level_name)
# Apply the transactions we've been adding locally. # Apply the transactions we've been adding locally.
@ -924,7 +924,8 @@ class CoopScoreScreen(ba.Activity):
results.remove(score) results.remove(score)
break break
results.append(our_score_entry) results.append(our_score_entry)
results.sort(reverse=self._score_order == 'increasing') results.sort(reverse=self._score_order == 'increasing',
key=lambda x: x[0])
# If we're not submitting our own score, we still want to change the # If we're not submitting our own score, we still want to change the
# name of our own score to 'Me'. # name of our own score to 'Me'.
@ -1028,8 +1029,9 @@ class CoopScoreScreen(ba.Activity):
self._score_link) self._score_link)
self._score_loading_status = None self._score_loading_status = None
if 'tournamentSecondsRemaining' in results: if 'tournamentSecondsRemaining' in results:
self._tournament_time_remaining = ( secs_remaining = results['tournamentSecondsRemaining']
results['tournamentSecondsRemaining']) assert isinstance(secs_remaining, int)
self._tournament_time_remaining = secs_remaining
self._tournament_time_remaining_text_timer = ba.Timer( self._tournament_time_remaining_text_timer = ba.Timer(
1.0, 1.0,
ba.WeakCall( ba.WeakCall(
@ -1088,7 +1090,7 @@ class CoopScoreScreen(ba.Activity):
elif p_count == 4: elif p_count == 4:
scale = 0.5 scale = 0.5
# make sure there's at least 10.. # Make sure there's at least 10.
while len(self._show_info['tops']) < 10: while len(self._show_info['tops']) < 10:
self._show_info['tops'].append([0, '-']) self._show_info['tops'].append([0, '-'])
@ -1400,10 +1402,10 @@ class CoopScoreScreen(ba.Activity):
transition_delay=1.0).autoretain() transition_delay=1.0).autoretain()
new_best = (best_rank > self._old_best_rank and best_rank > 0.0) new_best = (best_rank > self._old_best_rank and best_rank > 0.0)
was_string = ('' if self._old_best_rank is None else ba.Lstr( was_string = ba.Lstr(value=' ${A}',
value=' ${A}', subs=[('${A}',
subs=[('${A}', ba.Lstr(resource='scoreWasText')), ba.Lstr(resource='scoreWasText')),
('${COUNT}', str(self._old_best_rank))])) ('${COUNT}', str(self._old_best_rank))])
if not self._newly_complete: if not self._newly_complete:
Text(ba.Lstr(value='${A}${B}', Text(ba.Lstr(value='${A}${B}',
subs=[('${A}', subs=[('${A}',

View File

@ -80,11 +80,11 @@ class TeamSeriesVictoryScoreScreenActivity(TeamsScoreScreenActivity):
player_entries.append( player_entries.append(
(prec.player.team.sessiondata['score'], (prec.player.team.sessiondata['score'],
prec.get_name(full=True), prec)) prec.get_name(full=True), prec))
player_entries.sort(reverse=True) player_entries.sort(reverse=True, key=lambda x: x[0])
else: else:
for _pkey, prec in self.stats.get_records().items(): for _pkey, prec in self.stats.get_records().items():
player_entries.append((prec.score, prec.name_full, prec)) player_entries.append((prec.score, prec.name_full, prec))
player_entries.sort(reverse=True) player_entries.sort(reverse=True, key=lambda x: x[0])
ts_height = 300.0 ts_height = 300.0
ts_h_offs = -390.0 ts_h_offs = -390.0

View File

@ -135,7 +135,8 @@ class TeamsScoreScreenActivity(ScoreScreenActivity):
if player_entry is not None: if player_entry is not None:
player_records.append(player_entry) player_records.append(player_entry)
else: else:
raise Exception('FIXME; CODE PATH NEEDS FIXING') print('FIXME; CODE PATH NEEDS FIXING')
player_records = []
# player_records = [[ # player_records = [[
# _get_prec_score(p), name, p # _get_prec_score(p), name, p
# ] for name, p in list(self.stats.get_records().items())] # ] for name, p in list(self.stats.get_records().items())]

View File

@ -264,7 +264,8 @@ class ControlsGuide(ba.Actor):
# If we have a touchscreen, we only fade in if we have a player with # If we have a touchscreen, we only fade in if we have a player with
# an input device that is *not* the touchscreen. # an input device that is *not* the touchscreen.
touchscreen = _ba.get_input_device('TouchScreen', '#1', doraise=False) touchscreen: Optional[ba.InputDevice] = _ba.get_input_device(
'TouchScreen', '#1', doraise=False)
if touchscreen is not None: if touchscreen is not None:
# We look at the session's players; not the activity's. # We look at the session's players; not the activity's.

View File

@ -170,9 +170,7 @@ class Image(ba.Actor):
ba.animate(cmb, 'input1', keys) ba.animate(cmb, 'input1', keys)
ba.animate(self.node, 'opacity', o_keys) ba.animate(self.node, 'opacity', o_keys)
else: else:
if (transition is not self.Transition.FADE_IN assert transition is self.Transition.FADE_IN or transition is None
and transition is not None):
ba.print_error(f'Invalid transition: "{transition}"')
cmb.input0 = position[0] cmb.input0 = position[0]
cmb.input1 = position[1] cmb.input1 = position[1]
cmb.connectattr('output', self.node, 'position') cmb.connectattr('output', self.node, 'position')

View File

@ -187,9 +187,9 @@ class SpazBot(basespaz.Spaz):
""" """
assert self.node assert self.node
botpt = ba.Vec3(self.node.position) botpt = ba.Vec3(self.node.position)
closest_dist = None closest_dist: Optional[float] = None
closest_vel = None closest_vel: Optional[ba.Vec3] = None
closest = None closest: Optional[ba.Vec3] = None
assert self._player_pts is not None assert self._player_pts is not None
for plpt, plvel in self._player_pts: for plpt, plvel in self._player_pts:
dist = (plpt - botpt).length() dist = (plpt - botpt).length()
@ -985,7 +985,7 @@ class BotSet:
try: try:
if player.is_alive(): if player.is_alive():
assert isinstance(player.actor, basespaz.Spaz) assert isinstance(player.actor, basespaz.Spaz)
assert player.actor is not None and player.actor.node assert player.actor.node
player_pts.append((ba.Vec3(player.actor.node.position), player_pts.append((ba.Vec3(player.actor.node.position),
ba.Vec3(player.actor.node.velocity))) ba.Vec3(player.actor.node.velocity)))
except Exception: except Exception:
@ -999,7 +999,7 @@ class BotSet:
"""Immediately clear out any bots in the set.""" """Immediately clear out any bots in the set."""
# Don't do this if the activity is shutting down or dead. # Don't do this if the activity is shutting down or dead.
activity = ba.getactivity(doraise=False) activity: Optional[ba.Activity] = ba.getactivity(doraise=False)
if activity is None or activity.is_expired(): if activity is None or activity.is_expired():
return return

View File

@ -215,9 +215,7 @@ class Text(ba.Actor):
ba.animate(cmb, 'input1', keys) ba.animate(cmb, 'input1', keys)
ba.animate(self.node, 'opacity', o_keys) ba.animate(self.node, 'opacity', o_keys)
else: else:
if (transition is not self.Transition.FADE_IN assert transition is self.Transition.FADE_IN or transition is None
and transition is not None):
ba.print_error(f'Invalid transition: "{transition}"')
cmb.input0 = position[0] cmb.input0 = position[0]
cmb.input1 = position[1] cmb.input1 = position[1]
cmb.connectattr('output', self.node, 'position') cmb.connectattr('output', self.node, 'position')

View File

@ -45,16 +45,17 @@ class ConquestFlag(Flag):
self._team: Optional[ba.Team] = None self._team: Optional[ba.Team] = None
self.light: Optional[ba.Node] = None self.light: Optional[ba.Node] = None
def set_team(self, team: ba.Team) -> None:
"""Set the team that owns this flag."""
self._team = None if team is None else team
@property @property
def team(self) -> ba.Team: def team(self) -> ba.Team:
"""The team that owns this flag.""" """The team that owns this flag."""
assert self._team is not None assert self._team is not None
return self._team return self._team
@team.setter
def team(self, team: ba.Team) -> None:
"""Set the team that owns this flag."""
self._team = team
# ba_meta export game # ba_meta export game
class ConquestGame(ba.TeamGameActivity): class ConquestGame(ba.TeamGameActivity):
@ -165,7 +166,7 @@ class ConquestGame(ba.TeamGameActivity):
# Give teams a flag to start with. # Give teams a flag to start with.
for i in range(len(self.teams)): for i in range(len(self.teams)):
self._flags[i].set_team(self.teams[i]) self._flags[i].team = self.teams[i]
light = self._flags[i].light light = self._flags[i].light
assert light assert light
node = self._flags[i].node node = self._flags[i].node
@ -227,9 +228,12 @@ class ConquestGame(ba.TeamGameActivity):
flag = flagnode.getdelegate() flag = flagnode.getdelegate()
except Exception: except Exception:
return # Player may have left and his body hit the flag. return # Player may have left and his body hit the flag.
assert isinstance(player, ba.Player)
assert isinstance(flag, ConquestFlag)
assert flag.light
if flag.team is not player.team: if flag.team is not player.team:
flag.set_team(player.team) flag.team = player.team
flag.light.color = player.team.color flag.light.color = player.team.color
flag.node.color = player.team.color flag.node.color = player.team.color
self.stats.player_scored(player, 10, screenmessage=False) self.stats.player_scored(player, 10, screenmessage=False)

View File

@ -400,7 +400,8 @@ class EliminationGame(ba.TeamGameActivity):
self.map.get_start_position(team.get_id())) self.map.get_start_position(team.get_id()))
points.append( points.append(
((start_pos - player_pos).length(), start_pos)) ((start_pos - player_pos).length(), start_pos))
points.sort() # Hmm.. we need to sorting vectors too?
points.sort(key=lambda x: x[0])
return points[-1][1] return points[-1][1]
return None return None

View File

@ -590,8 +590,8 @@ class FootballCoopGame(ba.CoopGameActivity):
return return
flagpos = ba.Vec3(self._flag.node.position) flagpos = ba.Vec3(self._flag.node.position)
closest_bot = None closest_bot: Optional[spazbot.SpazBot] = None
closest_dist = None closest_dist = 0.0 # Always gets assigned first time through.
for bot in bots: for bot in bots:
# If a bot is picked up, he should forget about the flag. # If a bot is picked up, he should forget about the flag.
if bot.held_count > 0: if bot.held_count > 0:
@ -600,8 +600,8 @@ class FootballCoopGame(ba.CoopGameActivity):
botpos = ba.Vec3(bot.node.position) botpos = ba.Vec3(bot.node.position)
botdist = (botpos - flagpos).length() botdist = (botpos - flagpos).length()
if closest_bot is None or botdist < closest_dist: if closest_bot is None or botdist < closest_dist:
closest_dist = botdist
closest_bot = bot closest_bot = bot
closest_dist = botdist
if closest_bot is not None: if closest_bot is not None:
closest_bot.target_flag = self._flag closest_bot.target_flag = self._flag

View File

@ -959,9 +959,9 @@ class OnslaughtGame(ba.CoopGameActivity):
max_dudes, group_count, max_dudes, group_count,
max_level) max_level)
all_entries: List[Dict[str, Any]] = [] all_entries: List[Optional[Dict[str, Any]]] = []
for group in distribution: for group in distribution:
entries: List[Dict[str, Any]] = [] entries: List[Optional[Dict[str, Any]]] = []
for entry in group: for entry in group:
bot_level = bot_levels[entry[0] - 1] bot_level = bot_levels[entry[0] - 1]
bot_type = bot_level[random.randrange(len(bot_level))] bot_type = bot_level[random.randrange(len(bot_level))]

View File

@ -139,7 +139,7 @@ class RaceGame(ba.TeamGameActivity):
self._score_sound = ba.getsound('score') self._score_sound = ba.getsound('score')
self._swipsound = ba.getsound('swip') self._swipsound = ba.getsound('swip')
self._last_team_time: Optional[float] = None self._last_team_time: Optional[float] = None
self._front_race_region = None self._front_race_region: Optional[int] = None
self._nub_tex = ba.gettexture('nub') self._nub_tex = ba.gettexture('nub')
self._beep_1_sound = ba.getsound('raceBeep1') self._beep_1_sound = ba.getsound('raceBeep1')
self._beep_2_sound = ba.getsound('raceBeep2') self._beep_2_sound = ba.getsound('raceBeep2')
@ -190,7 +190,7 @@ class RaceGame(ba.TeamGameActivity):
def _flash_player(self, player: ba.Player, scale: float) -> None: def _flash_player(self, player: ba.Player, scale: float) -> None:
assert isinstance(player.actor, PlayerSpaz) assert isinstance(player.actor, PlayerSpaz)
assert player.actor is not None and player.actor.node assert player.actor.node
pos = player.actor.node.position pos = player.actor.node.position
light = ba.newnode('light', light = ba.newnode('light',
attrs={ attrs={
@ -213,9 +213,11 @@ class RaceGame(ba.TeamGameActivity):
player = playernode.getdelegate().getplayer() player = playernode.getdelegate().getplayer()
except Exception: except Exception:
player = None player = None
assert isinstance(player, ba.Player)
region = region_node.getdelegate() region = region_node.getdelegate()
if not player or not region: if not player or not region:
return return
assert isinstance(region, RaceRegion)
last_region = player.gamedata['last_region'] last_region = player.gamedata['last_region']
this_region = region.index this_region = region.index
@ -227,6 +229,7 @@ class RaceGame(ba.TeamGameActivity):
# blown over a region, etc). # blown over a region, etc).
if this_region > last_region + 2: if this_region > last_region + 2:
if player.is_alive(): if player.is_alive():
assert player.actor
player.actor.handlemessage(ba.DieMessage()) player.actor.handlemessage(ba.DieMessage())
ba.screenmessage(ba.Lstr( ba.screenmessage(ba.Lstr(
translate=('statements', 'Killing ${NAME} for' translate=('statements', 'Killing ${NAME} for'
@ -273,6 +276,7 @@ class RaceGame(ba.TeamGameActivity):
# Flash where the player is. # Flash where the player is.
self._flash_player(player, 1.0) self._flash_player(player, 1.0)
player.gamedata['finished'] = True player.gamedata['finished'] = True
assert player.actor
player.actor.handlemessage( player.actor.handlemessage(
ba.DieMessage(immediate=True)) ba.DieMessage(immediate=True))
@ -305,6 +309,7 @@ class RaceGame(ba.TeamGameActivity):
# Print their lap number over their head. # Print their lap number over their head.
try: try:
assert isinstance(player.actor, PlayerSpaz)
mathnode = ba.newnode('math', mathnode = ba.newnode('math',
owner=player.actor.node, owner=player.actor.node,
attrs={ attrs={
@ -529,7 +534,7 @@ class RaceGame(ba.TeamGameActivity):
pos: Optional[ba.Vec3] pos: Optional[ba.Vec3]
try: try:
assert isinstance(player.actor, PlayerSpaz) assert isinstance(player.actor, PlayerSpaz)
assert player.actor is not None and player.actor.node assert player.actor.node
pos = ba.Vec3(player.actor.node.position) pos = ba.Vec3(player.actor.node.position)
except Exception: except Exception:
pos = None pos = None
@ -550,9 +555,7 @@ class RaceGame(ba.TeamGameActivity):
p_list = [[player.gamedata['distance'], player] p_list = [[player.gamedata['distance'], player]
for player in self.players] for player in self.players]
p_list.sort(reverse=True) p_list.sort(reverse=True, key=lambda x: x[0])
# FIXME - need another way to sort p_list.
# It tries to compare ba.Player objects.
for i, plr in enumerate(p_list): for i, plr in enumerate(p_list):
try: try:
plr[1].gamedata['rank'] = i plr[1].gamedata['rank'] = i

View File

@ -725,7 +725,7 @@ class RunaroundGame(ba.CoopGameActivity):
t_sec = 0.0 t_sec = 0.0
base_delay = 0.5 base_delay = 0.5
delay = 0.0 delay = 0.0
bot_types: List[Dict[str, Any]] = [] bot_types: List[Optional[Dict[str, Any]]] = []
if self._preset in ['endless', 'endless_tournament']: if self._preset in ['endless', 'endless_tournament']:
level = self._wave level = self._wave

View File

@ -198,7 +198,7 @@ class TheLastStandGame(ba.CoopGameActivity):
try: try:
if player.is_alive(): if player.is_alive():
assert isinstance(player.actor, playerspaz.PlayerSpaz) assert isinstance(player.actor, playerspaz.PlayerSpaz)
assert player.actor is not None and player.actor.node assert player.actor.node
playerpts.append(player.actor.node.position) playerpts.append(player.actor.node.position)
except Exception as exc: except Exception as exc:
print('ERROR in _update_bots', exc) print('ERROR in _update_bots', exc)

View File

@ -243,8 +243,7 @@ class TutorialActivity(ba.Activity):
ba.set_analytics_screen('Tutorial Start') ba.set_analytics_screen('Tutorial Start')
_ba.increment_analytics_count('Tutorial start') _ba.increment_analytics_count('Tutorial start')
# noinspection PyUnreachableCode if bool(False):
if 0: # pylint: disable=using-constant-test
# Buttons on top. # Buttons on top.
text_y = 140 text_y = 140
buttons_y = 250 buttons_y = 250

View File

@ -322,6 +322,7 @@ def handle_app_invites_press(force_code: bool = False) -> None:
'enableAppInvites', False) and not app.on_tv) 'enableAppInvites', False) and not app.on_tv)
if force_code: if force_code:
do_app_invites = False do_app_invites = False
# FIXME: Should update this to grab a code before showing the invite UI. # FIXME: Should update this to grab a code before showing the invite UI.
if do_app_invites: if do_app_invites:
AppInviteWindow() AppInviteWindow()
@ -330,7 +331,7 @@ def handle_app_invites_press(force_code: bool = False) -> None:
ba.Lstr(resource='gatherWindow.requestingAPromoCodeText'), ba.Lstr(resource='gatherWindow.requestingAPromoCodeText'),
color=(0, 1, 0)) color=(0, 1, 0))
def handle_result(result: Dict[str, Any]) -> None: def handle_result(result: Optional[Dict[str, Any]]) -> None:
with ba.Context('ui'): with ba.Context('ui'):
if result is None: if result is None:
ba.screenmessage(ba.Lstr(resource='errorText'), ba.screenmessage(ba.Lstr(resource='errorText'),

View File

@ -357,19 +357,14 @@ class CoopBrowserWindow(ba.Window):
# Update all of our tourney buttons based on whats in data. # Update all of our tourney buttons based on whats in data.
for i, tbtn in enumerate(self._tournament_buttons): for i, tbtn in enumerate(self._tournament_buttons):
entry: Optional[Dict[str, Any]] assert data is not None
try: entry: Dict[str, Any] = data[i]
assert data is not None prize_y_offs = (34 if 'prizeRange3' in entry else
entry = data[i] 20 if 'prizeRange2' in entry else 12)
except Exception:
entry = None
prize_y_offs = (0 if entry is None else 34 if 'prizeRange3' in
entry else 20 if 'prizeRange2' in entry else 12)
x_offs = 90 x_offs = 90
# This seems to be a false alarm. # This seems to be a false alarm.
# pylint: disable=unbalanced-tuple-unpacking # pylint: disable=unbalanced-tuple-unpacking
assert entry is not None
pr1, pv1, pr2, pv2, pr3, pv3 = ( pr1, pv1, pr2, pv2, pr3, pv3 = (
get_tournament_prize_strings(entry)) get_tournament_prize_strings(entry))
# pylint: enable=unbalanced-tuple-unpacking # pylint: enable=unbalanced-tuple-unpacking
@ -427,7 +422,7 @@ class CoopBrowserWindow(ba.Window):
leader_name = '-' leader_name = '-'
leader_score: Union[str, ba.Lstr] = '-' leader_score: Union[str, ba.Lstr] = '-'
if entry is not None and entry['scores']: if entry['scores']:
score = tbtn['leader'] = copy.deepcopy(entry['scores'][0]) score = tbtn['leader'] = copy.deepcopy(entry['scores'][0])
leader_name = score[1] leader_name = score[1]
leader_score = ( leader_score = (
@ -441,15 +436,13 @@ class CoopBrowserWindow(ba.Window):
ba.textwidget(edit=tbtn['current_leader_name_text'], ba.textwidget(edit=tbtn['current_leader_name_text'],
text=ba.Lstr(value=leader_name)) text=ba.Lstr(value=leader_name))
self._tournament_leader_score_type = (None if entry is None else self._tournament_leader_score_type = (entry['scoreType'])
entry['scoreType'])
ba.textwidget(edit=tbtn['current_leader_score_text'], ba.textwidget(edit=tbtn['current_leader_score_text'],
text=leader_score) text=leader_score)
ba.buttonwidget(edit=tbtn['more_scores_button'], ba.buttonwidget(edit=tbtn['more_scores_button'],
label='-' if entry is None else ba.Lstr( label=ba.Lstr(resource=self._r + '.seeMoreText'))
resource=self._r + '.seeMoreText'))
out_of_time_text: Union[str, ba.Lstr] = ( out_of_time_text: Union[str, ba.Lstr] = (
'-' if entry is None or 'totalTime' not in entry else ba.Lstr( '-' if 'totalTime' not in entry else ba.Lstr(
resource=self._r + '.ofTotalTimeText', resource=self._r + '.ofTotalTimeText',
subs=[('${TOTAL}', subs=[('${TOTAL}',
ba.timestring(entry['totalTime'], ba.timestring(entry['totalTime'],
@ -458,16 +451,13 @@ class CoopBrowserWindow(ba.Window):
ba.textwidget(edit=tbtn['time_remaining_out_of_text'], ba.textwidget(edit=tbtn['time_remaining_out_of_text'],
text=out_of_time_text) text=out_of_time_text)
tbtn['time_remaining'] = 0 if entry is None else entry[ tbtn['time_remaining'] = entry['timeRemaining']
'timeRemaining']
tbtn['has_time_remaining'] = entry is not None tbtn['has_time_remaining'] = entry is not None
tbtn['tournament_id'] = (None if entry is None else tbtn['tournament_id'] = entry['tournamentID']
entry['tournamentID'])
tbtn['required_league'] = (None if 'requiredLeague' not in entry tbtn['required_league'] = (None if 'requiredLeague' not in entry
else entry['requiredLeague']) else entry['requiredLeague'])
game = (None if entry is None else game = ba.app.tournament_info[tbtn['tournament_id']]['game']
ba.app.tournament_info[tbtn['tournament_id']]['game'])
if game is None: if game is None:
ba.textwidget(edit=tbtn['button_text'], text='-') ba.textwidget(edit=tbtn['button_text'], text='-')
@ -491,7 +481,7 @@ class CoopBrowserWindow(ba.Window):
levelname).get_preview_texture(), levelname).get_preview_texture(),
opacity=1.0 if enabled else 0.5) opacity=1.0 if enabled else 0.5)
fee = None if entry is None else entry['fee'] fee = entry['fee']
if fee is None: if fee is None:
fee_var = None fee_var = None

View File

@ -149,7 +149,7 @@ class GatherWindow(ba.Window):
tabs_def: List[Tuple[str, ba.Lstr]] = [ tabs_def: List[Tuple[str, ba.Lstr]] = [
('about', ba.Lstr(resource=self._r + '.aboutText')) ('about', ba.Lstr(resource=self._r + '.aboutText'))
] ]
if True and _ba.get_account_misc_read_val('enablePublicParties', True): if _ba.get_account_misc_read_val('enablePublicParties', True):
tabs_def.append( tabs_def.append(
('internet', ba.Lstr(resource=self._r + '.internetText'))) ('internet', ba.Lstr(resource=self._r + '.internetText')))
if platform == 'android' and subplatform == 'google': if platform == 'android' and subplatform == 'google':
@ -1451,8 +1451,7 @@ class GatherWindow(ba.Window):
key=lambda p: ( key=lambda p: (
p['queue'] is None, # Show non-queued last. p['queue'] is None, # Show non-queued last.
p['ping'] if p['ping'] is not None else 999999, p['ping'] if p['ping'] is not None else 999999,
p['index'], p['index']))
p))
existing_selection = self._public_party_list_selection existing_selection = self._public_party_list_selection
first = True first = True

View File

@ -203,8 +203,7 @@ class KioskWindow(ba.Window):
self._b5: Optional[ba.Widget] self._b5: Optional[ba.Widget]
self._b6: Optional[ba.Widget] self._b6: Optional[ba.Widget]
# noinspection PyUnreachableCode if bool(False):
if False: # pylint: disable=using-constant-test
ba.textwidget( ba.textwidget(
parent=self._root_widget, parent=self._root_widget,
size=(0, 0), size=(0, 0),
@ -312,8 +311,7 @@ class KioskWindow(ba.Window):
self._b4 = self._b5 = self._b6 = None self._b4 = self._b5 = self._b6 = None
self._b7: Optional[ba.Widget] self._b7: Optional[ba.Widget]
# noinspection PyUnreachableCode if bool(False):
if False: # pylint: disable=using-constant-test
self._b7 = ba.buttonwidget( self._b7 = ba.buttonwidget(
parent=self._root_widget, parent=self._root_widget,
autoselect=True, autoselect=True,

View File

@ -134,7 +134,7 @@ class LeagueRankWindow(ba.Window):
self._season_popup_menu: Optional[popup_ui.PopupMenu] = None self._season_popup_menu: Optional[popup_ui.PopupMenu] = None
self._requested_season: Optional[str] = None self._requested_season: Optional[str] = None
self._season = None self._season: Optional[str] = None
# take note of our account state; we'll refresh later if this changes # take note of our account state; we'll refresh later if this changes
self._account_state = _ba.get_account_state() self._account_state = _ba.get_account_state()

View File

@ -703,7 +703,6 @@ class MainMenuWindow(ba.Window):
v += v_offset v += v_offset
h += h_offset h += h_offset
h_offset += d_h_offset h_offset += d_h_offset
custom_menu_entries = []
self._start_button = None self._start_button = None
ba.app.pause() ba.app.pause()

View File

@ -293,7 +293,7 @@ class PartyQueueWindow(ba.Window):
"""(internal)""" """(internal)"""
return self._line_bottom return self._line_bottom
def on_account_press(self, account_id: str, def on_account_press(self, account_id: Optional[str],
origin_widget: ba.Widget) -> None: origin_widget: ba.Widget) -> None:
"""A dude was clicked so we should show his account info.""" """A dude was clicked so we should show his account info."""
from bastd.ui.account import viewer from bastd.ui.account import viewer

View File

@ -30,7 +30,7 @@ import _ba
import ba import ba
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any, Type, Optional, Tuple, List from typing import Any, Type, Optional, Tuple, List, Dict
class PlaylistCustomizeBrowserWindow(ba.Window): class PlaylistCustomizeBrowserWindow(ba.Window):
@ -562,6 +562,7 @@ class PlaylistCustomizeBrowserWindow(ba.Window):
return return
if self._selected_playlist_name is None: if self._selected_playlist_name is None:
return return
plst: Optional[List[Dict[str, Any]]]
if self._selected_playlist_name == '__default__': if self._selected_playlist_name == '__default__':
plst = self._pvars.get_default_list_call() plst = self._pvars.get_default_list_call()
else: else:

View File

@ -30,7 +30,7 @@ import _ba
import ba import ba
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Type, Any, Dict, Callable, Optional, Union from typing import Type, Any, Dict, Callable, Optional, Union, List
class PlaylistEditGameWindow(ba.Window): class PlaylistEditGameWindow(ba.Window):
@ -197,7 +197,7 @@ class PlaylistEditGameWindow(ba.Window):
# Keep track of all the selectable widgets we make so we can wire # Keep track of all the selectable widgets we make so we can wire
# them up conveniently. # them up conveniently.
widget_column = [] widget_column: List[List[ba.Widget]] = []
# Map select button. # Map select button.
ba.textwidget(parent=self._subcontainer, ba.textwidget(parent=self._subcontainer,
@ -419,16 +419,17 @@ class PlaylistEditGameWindow(ba.Window):
else: else:
raise Exception() raise Exception()
# ok now wire up the column # Ok now wire up the column.
try: try:
# pylint: disable=unsubscriptable-object # pylint: disable=unsubscriptable-object
prev_widgets = None prev_widgets: Optional[List[ba.Widget]] = None
for cwdg in widget_column: for cwdg in widget_column:
if prev_widgets is not None: if prev_widgets is not None:
# wire our rightmost to their rightmost # Wire our rightmost to their rightmost.
ba.widget(edit=prev_widgets[-1], down_widget=cwdg[-1]) ba.widget(edit=prev_widgets[-1], down_widget=cwdg[-1])
ba.widget(cwdg[-1], up_widget=prev_widgets[-1]) ba.widget(cwdg[-1], up_widget=prev_widgets[-1])
# wire our leftmost to their leftmost
# Wire our leftmost to their leftmost.
ba.widget(edit=prev_widgets[0], down_widget=cwdg[0]) ba.widget(edit=prev_widgets[0], down_widget=cwdg[0])
ba.widget(cwdg[0], up_widget=prev_widgets[0]) ba.widget(cwdg[0], up_widget=prev_widgets[0])
prev_widgets = cwdg prev_widgets = cwdg
@ -452,14 +453,14 @@ class PlaylistEditGameWindow(ba.Window):
def _select_map(self) -> None: def _select_map(self) -> None:
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bastd.ui.playlist import mapselect from bastd.ui.playlist.mapselect import PlaylistMapSelectWindow
# Replace ourself with the map-select UI. # Replace ourself with the map-select UI.
ba.containerwidget(edit=self._root_widget, transition='out_left') ba.containerwidget(edit=self._root_widget, transition='out_left')
ba.app.main_menu_window = (mapselect.PlaylistMapSelectWindow( ba.app.main_menu_window = PlaylistMapSelectWindow(
self._gameclass, self._sessiontype, self._gameclass, self._sessiontype,
copy.deepcopy(self._getconfig()), self._edit_info, copy.deepcopy(self._getconfig()), self._edit_info,
self._completion_call).get_root_widget()) self._completion_call).get_root_widget()
def _choice_inc(self, setting_name: str, widget: ba.Widget, def _choice_inc(self, setting_name: str, widget: ba.Widget,
setting: Dict[str, Any], increment: int) -> None: setting: Dict[str, Any], increment: int) -> None:

View File

@ -141,14 +141,7 @@ class PopupMenuWindow(PopupWindow):
# we need to flatten them. # we need to flatten them.
choices_display_fin: List[str] = [] choices_display_fin: List[str] = []
for choice_display in choices_display: for choice_display in choices_display:
if isinstance(choice_display, ba.Lstr): choices_display_fin.append(choice_display.evaluate())
choices_display_fin.append(choice_display.evaluate())
else:
ba.print_error(
'PopupMenuWindow got a raw string in \'choices_display\';'
' please pass ba.Lstr values only',
once=True)
choices_display_fin.append(choice_display)
if maxwidth is None: if maxwidth is None:
maxwidth = width * 1.5 maxwidth = width * 1.5

View File

@ -69,7 +69,7 @@ class AdvancedSettingsWindow(ba.Window):
stack_offset=(0, -25) if app.small_ui else (0, 0))) stack_offset=(0, -25) if app.small_ui else (0, 0)))
self._prev_lang = "" self._prev_lang = ""
self._prev_lang_list: List[str] = [] self._prev_lang_list: List[str] = []
self._complete_langs_list = None self._complete_langs_list: Optional[List] = None
self._complete_langs_error = False self._complete_langs_error = False
self._language_popup: Optional[popup_ui.PopupMenu] = None self._language_popup: Optional[popup_ui.PopupMenu] = None

View File

@ -103,8 +103,7 @@ class ControlsSettingsWindow(ba.Window):
show_space_2 = True show_space_2 = True
height += space_height height += space_height
# noinspection PyUnreachableCode if bool(True):
if True: # pylint: disable=using-constant-test
show_remote = True show_remote = True
height += spacing height += spacing
else: else:

View File

@ -289,10 +289,7 @@ class SoundtrackBrowserWindow(ba.Window):
copy_word = copy_text.replace('${NAME}', '').strip() copy_word = copy_text.replace('${NAME}', '').strip()
base_name = self._get_soundtrack_display_name( base_name = self._get_soundtrack_display_name(
self._selected_soundtrack).evaluate() self._selected_soundtrack).evaluate()
if not isinstance(base_name, str): assert isinstance(base_name, str)
print('expected uni base_name 3fj0')
assert isinstance(base_name, bytes)
base_name = base_name.decode('utf-8')
# If it looks like a copy, strip digits and spaces off the end. # If it looks like a copy, strip digits and spaces off the end.
if copy_word in base_name: if copy_word in base_name:

View File

@ -205,8 +205,8 @@ class SoundtrackEditWindow(ba.Window):
] ]
# FIXME: We should probably convert this to use translations. # FIXME: We should probably convert this to use translations.
type_names_translated = get_resource('soundtrackTypeNames') type_names_translated = get_resource('soundtrackTypeNames')
prev_type_button = None prev_type_button: Optional[ba.Widget] = None
prev_test_button = None prev_test_button: Optional[ba.Widget] = None
for index, song_type in enumerate(types): for index, song_type in enumerate(types):
row = ba.rowwidget(parent=self._col, size=(self._width - 40, 40)) row = ba.rowwidget(parent=self._col, size=(self._width - 40, 40))

View File

@ -31,7 +31,8 @@ import _ba
import ba import ba
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any, Callable, Optional, Tuple, Dict, Union, Sequence from typing import (Any, Callable, Optional, Tuple, Dict, Union, Sequence,
List)
class StoreBrowserWindow(ba.Window): class StoreBrowserWindow(ba.Window):
@ -850,7 +851,7 @@ class StoreBrowserWindow(ba.Window):
maxwidth=700, maxwidth=700,
transition_delay=0.4) transition_delay=0.4)
prev_row_buttons = None prev_row_buttons: Optional[List] = None
this_row_buttons = [] this_row_buttons = []
delay = 0.3 delay = 0.3

View File

@ -518,10 +518,10 @@ class TournamentEntryWindow(popup.PopupWindow):
try: try:
ticket_count = _ba.get_account_ticket_count() ticket_count = _ba.get_account_ticket_count()
except Exception: except Exception:
# FIXME: should add a ba.NotSignedInError we can use here.
ticket_count = None ticket_count = None
ticket_cost = self._purchase_price ticket_cost = self._purchase_price
if (ticket_count is not None and ticket_cost is not None if ticket_count is not None and ticket_count < ticket_cost:
and ticket_count < ticket_cost):
getcurrency.show_get_tickets_prompt() getcurrency.show_get_tickets_prompt()
ba.playsound(ba.getsound('error')) ba.playsound(ba.getsound('error'))
return return

View File

@ -303,4 +303,6 @@ def make_hash(obj: Any) -> int:
for k, v in new_obj.items(): for k, v in new_obj.items():
new_obj[k] = make_hash(v) new_obj[k] = make_hash(v)
# NOTE: there is sorted works correctly because it compares only
# unique first values (i.e. dict keys)
return hash(tuple(frozenset(sorted(new_obj.items())))) return hash(tuple(frozenset(sorted(new_obj.items()))))

View File

@ -34,7 +34,7 @@ import traceback
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Dict, Any, Sequence from typing import Dict, Any, Sequence, Optional
def _get_default_config() -> Dict[str, Any]: def _get_default_config() -> Dict[str, Any]:
@ -176,7 +176,8 @@ def _run_process_until_exit(process: subprocess.Popen,
process.stdin.flush() process.stdin.flush()
config_dirty = False config_dirty = False
code = process.poll() code: Optional[int] = process.poll()
if code is not None: if code is not None:
print('BallisticaCore exited with code ' + str(code)) print('BallisticaCore exited with code ' + str(code))
break break

View File

@ -4270,7 +4270,7 @@ session.set_activity(foo) and then <a href="#function_ba_newnode">ba.newnode</a>
</dd> </dd>
<dt><h4><a name="method_ba_Stats__set_activity">set_activity()</a></dt></h4><dd> <dt><h4><a name="method_ba_Stats__set_activity">set_activity()</a></dt></h4><dd>
<p><span>set_activity(self, activity: <a href="#class_ba_Activity">ba.Activity</a>) -&gt; None</span></p> <p><span>set_activity(self, activity: Optional[<a href="#class_ba_Activity">ba.Activity</a>]) -&gt; None</span></p>
<p>Set the current activity for this instance.</p> <p>Set the current activity for this instance.</p>

View File

@ -467,8 +467,7 @@ def _apply_pylint_run_to_cache(projroot: Path, run: Any, dirtyfiles: List[str],
# Let's print a list of modules with no detected deps so we can make sure # Let's print a list of modules with no detected deps so we can make sure
# this is behaving. # this is behaving.
if no_deps_modules: if no_deps_modules:
# noinspection PyUnreachableCode if bool(False):
if False: # pylint: disable=using-constant-test
print('NOTE: no dependencies found for:', print('NOTE: no dependencies found for:',
', '.join(no_deps_modules)) ', '.join(no_deps_modules))
@ -487,7 +486,7 @@ def _apply_pylint_run_to_cache(projroot: Path, run: Any, dirtyfiles: List[str],
mname2 = paths_to_names.get(fname) mname2 = paths_to_names.get(fname)
if mname2 is None: if mname2 is None:
raise Exception('unable to get module name for "' + fname + '"') raise Exception('unable to get module name for "' + fname + '"')
counts = (None if mname2 is None else stats_by_module.get(mname2)) counts = stats_by_module.get(mname2)
# 'statement' count seems to be new and always non-zero; ignore it # 'statement' count seems to be new and always non-zero; ignore it
if counts is not None: if counts is not None:
@ -645,10 +644,12 @@ def _run_idea_inspections(projroot: Path,
if result.returncode != 0: if result.returncode != 0:
# In verbose mode this stuff got printed already. # In verbose mode this stuff got printed already.
if not verbose: if not verbose:
stdout = (result.stdout.decode() if isinstance( stdout = (
result.stdout, bytes) else str(result.stdout)) result.stdout.decode() if isinstance( # type: ignore
stderr = (result.stderr.decode() if isinstance( result.stdout, bytes) else str(result.stdout))
result.stdout, bytes) else str(result.stdout)) stderr = (
result.stderr.decode() if isinstance( # type: ignore
result.stdout, bytes) else str(result.stdout))
print(f'{displayname} inspection failure stdout:\n{stdout}' + print(f'{displayname} inspection failure stdout:\n{stdout}' +
f'{displayname} inspection failure stderr:\n{stderr}') f'{displayname} inspection failure stderr:\n{stderr}')
raise RuntimeError(f"{displayname} inspection failed.") raise RuntimeError(f"{displayname} inspection failed.")

View File

@ -317,6 +317,7 @@ def tool_config_install() -> None:
warn_unused_ignores = True warn_unused_ignores = True
warn_return_any = True warn_return_any = True
warn_redundant_casts = True warn_redundant_casts = True
warn_unreachable=True
disallow_incomplete_defs = True disallow_incomplete_defs = True
disallow_untyped_defs = True disallow_untyped_defs = True
disallow_untyped_decorators = True disallow_untyped_decorators = True