From ec5225856df0bb086e0d37555de56d84eba709eb Mon Sep 17 00:00:00 2001 From: Eric Froemling Date: Wed, 4 Dec 2019 08:43:23 -0800 Subject: [PATCH] latest cloudtool work --- .idea/dictionaries/ericf.xml | 9 ++ .idea/inspectionProfiles/Default.xml | 4 +- assets/src/data/scripts/_ba.py | 29 +++--- assets/src/data/scripts/ba/_activity.py | 4 +- assets/src/data/scripts/ba/_app.py | 4 +- assets/src/data/scripts/ba/_appdelegate.py | 6 +- assets/src/data/scripts/ba/_coopgame.py | 3 +- assets/src/data/scripts/ba/_coopsession.py | 5 +- assets/src/data/scripts/ba/_gameactivity.py | 22 +++-- assets/src/data/scripts/ba/_gameresults.py | 8 +- assets/src/data/scripts/ba/_level.py | 10 +- assets/src/data/scripts/ba/_lobby.py | 8 +- assets/src/data/scripts/ba/_map.py | 9 +- assets/src/data/scripts/ba/_music.py | 4 +- assets/src/data/scripts/ba/_netutils.py | 20 ++-- assets/src/data/scripts/ba/_profile.py | 3 +- .../scripts/bafoundation/entity/_entity.py | 7 +- .../scripts/bafoundation/entity/_field.py | 11 ++- .../scripts/bafoundation/entity/_support.py | 8 +- .../scripts/bafoundation/entity/_value.py | 12 ++- .../data/scripts/bafoundation/entity/util.py | 11 ++- .../data/scripts/bafoundation/executils.py | 32 +++---- assets/src/data/scripts/bafoundation/util.py | 10 +- .../scripts/bastd/activity/coopjoinscreen.py | 10 +- .../bastd/activity/teamsscorescreen.py | 4 +- .../data/scripts/bastd/actor/onscreentimer.py | 6 +- assets/src/data/scripts/bastd/actor/spaz.py | 8 +- .../src/data/scripts/bastd/actor/spazbot.py | 4 +- assets/src/data/scripts/bastd/appdelegate.py | 6 +- assets/src/data/scripts/bastd/game/assault.py | 5 +- .../data/scripts/bastd/game/capturetheflag.py | 5 +- .../src/data/scripts/bastd/game/chosenone.py | 5 +- .../src/data/scripts/bastd/game/conquest.py | 5 +- .../src/data/scripts/bastd/game/deathmatch.py | 5 +- .../data/scripts/bastd/game/easteregghunt.py | 5 +- .../data/scripts/bastd/game/elimination.py | 5 +- .../src/data/scripts/bastd/game/football.py | 5 +- assets/src/data/scripts/bastd/game/hockey.py | 5 +- .../src/data/scripts/bastd/game/keepaway.py | 5 +- .../data/scripts/bastd/game/kingofthehill.py | 5 +- .../data/scripts/bastd/game/meteorshower.py | 5 +- assets/src/data/scripts/bastd/game/race.py | 5 +- .../src/data/scripts/bastd/game/runaround.py | 6 +- .../data/scripts/bastd/game/targetpractice.py | 5 +- assets/src/data/scripts/bastd/maps.py | 15 ++- .../data/scripts/bastd/ui/account/settings.py | 3 +- assets/src/data/scripts/bastd/ui/continues.py | 4 +- .../src/data/scripts/bastd/ui/coop/browser.py | 4 +- assets/src/data/scripts/bastd/ui/gather.py | 9 +- .../scripts/bastd/ui/league/rankbutton.py | 8 +- .../scripts/bastd/ui/league/rankwindow.py | 8 +- assets/src/data/scripts/bastd/ui/mainmenu.py | 10 +- .../src/data/scripts/bastd/ui/profile/edit.py | 4 +- .../data/scripts/bastd/ui/settings/gamepad.py | 14 +-- .../bastd/ui/settings/gamepadadvanced.py | 34 +++---- .../data/scripts/bastd/ui/store/browser.py | 3 +- .../data/scripts/bastd/ui/tournamententry.py | 4 +- .../data/scripts/bastd/ui/tournamentscores.py | 4 +- assets/src/server/server.py | 4 +- config/config.json | 3 +- docs/ba_module.md | 4 +- tools/cloudtool | 95 ++++++++++++++++++- tools/efrotools/code.py | 3 +- tools/snippets | 4 +- 64 files changed, 372 insertions(+), 218 deletions(-) diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml index c28b9a2e..c3c99dac 100644 --- a/.idea/dictionaries/ericf.xml +++ b/.idea/dictionaries/ericf.xml @@ -11,6 +11,7 @@ aaah aaai aarch + abcdefghijklmnopqrstuvwxyz abeb abot abtn @@ -78,7 +79,13 @@ argval armeabi arraymodule + assetbundle assetcache + assetdata + assetpackage + assetpath + assettype + assettypestr astcenc astroid asus @@ -741,6 +748,7 @@ incrementbuild indentfilter indentstr + indexfilename indicies indstr inet @@ -1233,6 +1241,7 @@ pushdocs pushish pushlist + putasset pval pvars pvrtc diff --git a/.idea/inspectionProfiles/Default.xml b/.idea/inspectionProfiles/Default.xml index 02d0bc18..b2b87fba 100644 --- a/.idea/inspectionProfiles/Default.xml +++ b/.idea/inspectionProfiles/Default.xml @@ -88,7 +88,7 @@ - + - + \ No newline at end of file diff --git a/assets/src/data/scripts/_ba.py b/assets/src/data/scripts/_ba.py index dfeadb6b..14827d5f 100644 --- a/assets/src/data/scripts/_ba.py +++ b/assets/src/data/scripts/_ba.py @@ -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) -# SOURCES_HASH=221041082183416610193123748095056578345 +# SOURCES_HASH=161757749075580767394847135785091690137 # I'm sorry Pylint. I know this file saddens you. Be strong. # pylint: disable=useless-suppression @@ -388,7 +388,8 @@ class Material: label: str - def add_actions(self, actions: Tuple, + def add_actions(self, + actions: Tuple, conditions: Optional[Tuple] = None) -> None: """add_actions(actions: Tuple, conditions: Optional[Tuple] = None) -> None @@ -939,7 +940,9 @@ class Player: """ return None - def set_name(self, name: str, full_name: str = None, + def set_name(self, + name: str, + full_name: str = None, real: bool = True) -> None: """set_name(name: str, full_name: str = None, real: bool = True) -> None @@ -2050,7 +2053,8 @@ def get_idle_time() -> int: return int() -def get_input_device(name: str, unique_id: str, +def get_input_device(name: str, + unique_id: str, doraise: bool = True) -> ba.InputDevice: """get_input_device(name: str, unique_id: str, doraise: bool = True) -> ba.InputDevice @@ -3330,9 +3334,9 @@ def set_have_mods(have_mods: bool) -> None: return None -def set_internal_language_keys(listobj: List[Tuple[str, str]], - random_names_list: List[Tuple[str, str]] - ) -> None: +def set_internal_language_keys( + listobj: List[Tuple[str, str]], + random_names_list: List[Tuple[str, str]]) -> None: """set_internal_language_keys(listobj: List[Tuple[str, str]], random_names_list: List[Tuple[str, str]]) -> None @@ -3349,8 +3353,8 @@ def set_low_level_config_value(key: str, value: int) -> None: return None -def set_map_bounds(bounds: Tuple[float, float, float, float, float, float] - ) -> None: +def set_map_bounds( + bounds: Tuple[float, float, float, float, float, float]) -> None: """set_map_bounds(bounds: Tuple[float, float, float, float, float, float]) -> None @@ -3729,8 +3733,8 @@ def time(timetype: ba.TimeType = TimeType.SIM, return 0.0 -def time_format_check(time_format: ba.TimeFormat, - length: Union[float, int]) -> None: +def time_format_check(time_format: ba.TimeFormat, length: Union[float, + int]) -> None: """time_format_check(time_format: ba.TimeFormat, length: Union[float, int]) -> None @@ -3839,7 +3843,8 @@ def unlock_all_input() -> None: return None -def value_test(arg: str, change: float = None, +def value_test(arg: str, + change: float = None, absolute: float = None) -> float: """value_test(arg: str, change: float = None, absolute: float = None) -> float diff --git a/assets/src/data/scripts/ba/_activity.py b/assets/src/data/scripts/ba/_activity.py index 7fcd0b3c..6e0a1330 100644 --- a/assets/src/data/scripts/ba/_activity.py +++ b/assets/src/data/scripts/ba/_activity.py @@ -516,7 +516,9 @@ class Activity(DependencyComponent): def handlemessage(self, msg: Any) -> Any: """General message handling; can be passed any message object.""" - def end(self, results: Any = None, delay: float = 0.0, + def end(self, + results: Any = None, + delay: float = 0.0, force: bool = False) -> None: """Commences Activity shutdown and delivers results to the ba.Session. diff --git a/assets/src/data/scripts/ba/_app.py b/assets/src/data/scripts/ba/_app.py index 29e09f4b..550322bb 100644 --- a/assets/src/data/scripts/ba/_app.py +++ b/assets/src/data/scripts/ba/_app.py @@ -377,8 +377,8 @@ class App: self.main_menu_selection: Optional[str] = None # FIXME: Kill this. self.have_party_queue_window = False self.quit_window: Any = None - self.dismiss_wii_remotes_window_call: ( - Optional[Callable[[], Any]]) = None + self.dismiss_wii_remotes_window_call: (Optional[Callable[[], + Any]]) = None self.value_test_defaults: dict = {} self.main_menu_window_refresh_check_count = 0 self.first_main_menu = True # FIXME: Move to mainmenu class. diff --git a/assets/src/data/scripts/ba/_appdelegate.py b/assets/src/data/scripts/ba/_appdelegate.py index 94ce055f..12a8a13d 100644 --- a/assets/src/data/scripts/ba/_appdelegate.py +++ b/assets/src/data/scripts/ba/_appdelegate.py @@ -32,9 +32,9 @@ class AppDelegate: """Defines handlers for high level app functionality.""" def create_default_game_config_ui( - self, gameclass: Type[ba.GameActivity], - sessionclass: Type[ba.Session], config: Optional[Dict[str, Any]], - completion_call: Callable[[Optional[Dict[str, Any]]], None] + self, gameclass: Type[ba.GameActivity], sessionclass: Type[ba.Session], + config: Optional[Dict[str, Any]], + completion_call: Callable[[Optional[Dict[str, Any]]], None] ) -> None: """Launch a UI to configure the given game config. diff --git a/assets/src/data/scripts/ba/_coopgame.py b/assets/src/data/scripts/ba/_coopgame.py index b37e7092..94ce11de 100644 --- a/assets/src/data/scripts/ba/_coopgame.py +++ b/assets/src/data/scripts/ba/_coopgame.py @@ -202,7 +202,8 @@ class CoopGameActivity(GameActivity): spaz.play_big_death_sound = True return spaz - def _award_achievement(self, achievement_name: str, + def _award_achievement(self, + achievement_name: str, sound: bool = True) -> None: """Award an achievement. diff --git a/assets/src/data/scripts/ba/_coopsession.py b/assets/src/data/scripts/ba/_coopsession.py index 0bb87e8b..a62d5b21 100644 --- a/assets/src/data/scripts/ba/_coopsession.py +++ b/assets/src/data/scripts/ba/_coopsession.py @@ -207,9 +207,8 @@ class CoopSession(Session): else: self.end() - def _on_tournament_restart_menu_press(self, - resume_callback: Callable[[], Any] - ) -> None: + def _on_tournament_restart_menu_press( + self, resume_callback: Callable[[], Any]) -> None: # pylint: disable=cyclic-import from bastd.ui.tournamententry import TournamentEntryWindow from ba._gameactivity import GameActivity diff --git a/assets/src/data/scripts/ba/_gameactivity.py b/assets/src/data/scripts/ba/_gameactivity.py index 51e092f0..8cae41ec 100644 --- a/assets/src/data/scripts/ba/_gameactivity.py +++ b/assets/src/data/scripts/ba/_gameactivity.py @@ -48,9 +48,8 @@ class GameActivity(Activity): @classmethod def create_config_ui( - cls, sessionclass: Type[ba.Session], - config: Optional[Dict[str, Any]], - completion_call: Callable[[Optional[Dict[str, Any]]], None] + cls, sessionclass: Type[ba.Session], config: Optional[Dict[str, Any]], + completion_call: Callable[[Optional[Dict[str, Any]]], None] ) -> None: """Launch an in-game UI to configure settings for a game type. @@ -171,8 +170,8 @@ class GameActivity(Activity): return '' @classmethod - def get_description_display_string(cls, sessiontype: Type[ba.Session] - ) -> ba.Lstr: + def get_description_display_string( + cls, sessiontype: Type[ba.Session]) -> ba.Lstr: """Return a translated version of get_description(). Sub-classes should override get_description(); not this. @@ -181,8 +180,9 @@ class GameActivity(Activity): return Lstr(translate=('gameDescriptions', description)) @classmethod - def get_settings(cls, sessiontype: Type[ba.Session] - ) -> List[Tuple[str, Dict[str, Any]]]: + def get_settings( + cls, + sessiontype: Type[ba.Session]) -> List[Tuple[str, Dict[str, Any]]]: """ Called by the default ba.GameActivity.create_config_ui() implementation; should return a dict of config options to be presented @@ -643,8 +643,8 @@ class GameActivity(Activity): callback=WeakCall( self._on_tournament_query_response)) - def _on_tournament_query_response(self, - data: Optional[Dict[str, Any]]) -> None: + def _on_tournament_query_response(self, data: Optional[Dict[str, + Any]]) -> None: from ba._account import cache_tournament_info if data is not None: data_t = data['t'] # This used to be the whole payload. @@ -935,7 +935,9 @@ class GameActivity(Activity): animate(combine, 'input3', {0: 0, 1.0: 1, 4.0: 1, 5.0: 0}) _ba.timer(5.0, tnode.delete) - def end(self, results: Any = None, delay: float = 0.0, + def end(self, + results: Any = None, + delay: float = 0.0, force: bool = False) -> None: from ba._gameresults import TeamGameResults diff --git a/assets/src/data/scripts/ba/_gameresults.py b/assets/src/data/scripts/ba/_gameresults.py index 49c9289b..f71fde7b 100644 --- a/assets/src/data/scripts/ba/_gameresults.py +++ b/assets/src/data/scripts/ba/_gameresults.py @@ -187,8 +187,8 @@ class TeamGameResults: team = score[0]() assert team is not None sval.append(team) - results: List[Tuple[Optional[int], List[ba.Team]]] = list( - winners.items()) + results: List[Tuple[Optional[int], + List[ba.Team]]] = list(winners.items()) results.sort(reverse=not self._lower_is_better) # Also group the 'None' scores. @@ -200,8 +200,8 @@ class TeamGameResults: # Add the Nones to the list (either as winners or losers # depending on the rules). if none_teams: - nones: List[Tuple[Optional[int], List[ba.Team]]] = [(None, - none_teams)] + nones: List[Tuple[Optional[int], + List[ba.Team]]] = [(None, none_teams)] if self._none_is_winner: results = nones + results else: diff --git a/assets/src/data/scripts/ba/_level.py b/assets/src/data/scripts/ba/_level.py index 0b6254ec..7b95521b 100644 --- a/assets/src/data/scripts/ba/_level.py +++ b/assets/src/data/scripts/ba/_level.py @@ -171,11 +171,11 @@ class Level: if campaign is None: raise Exception("level is not in a campaign") campaign_config = campaign.get_config_dict() - val: Dict[str, Any] = campaign_config.setdefault( - self._name, { - 'Rating': 0.0, - 'Complete': False - }) + val: Dict[str, + Any] = campaign_config.setdefault(self._name, { + 'Rating': 0.0, + 'Complete': False + }) assert isinstance(val, dict) return val diff --git a/assets/src/data/scripts/ba/_lobby.py b/assets/src/data/scripts/ba/_lobby.py index e6ce50c6..0fa8afd0 100644 --- a/assets/src/data/scripts/ba/_lobby.py +++ b/assets/src/data/scripts/ba/_lobby.py @@ -47,10 +47,10 @@ class JoinInfo: from ba._enums import SpecialChar can_switch_teams = (len(lobby.teams) > 1) self._state = 0 - press_to_punch: Union[str, ba.Lstr] = _ba.charstr( - SpecialChar.LEFT_BUTTON) - press_to_bomb: Union[str, ba.Lstr] = _ba.charstr( - SpecialChar.RIGHT_BUTTON) + press_to_punch: Union[str, + ba.Lstr] = _ba.charstr(SpecialChar.LEFT_BUTTON) + press_to_bomb: Union[str, + ba.Lstr] = _ba.charstr(SpecialChar.RIGHT_BUTTON) # If we have a keyboard, grab keys for punch and pickup. # FIXME: This of course is only correct on the local device; diff --git a/assets/src/data/scripts/ba/_map.py b/assets/src/data/scripts/ba/_map.py index 7f2865aa..243d293e 100644 --- a/assets/src/data/scripts/ba/_map.py +++ b/assets/src/data/scripts/ba/_map.py @@ -293,7 +293,8 @@ class Map(Actor): # FIXME: this should be part of game; not map. self._next_ffa_start_index = 0 - def is_point_near_edge(self, point: ba.Vec3, + def is_point_near_edge(self, + point: ba.Vec3, running: bool = False) -> bool: """Return whether the provided point is near an edge of the map. @@ -306,7 +307,7 @@ class Map(Actor): return False def get_def_bound_box( - self, name: str + self, name: str ) -> Optional[Tuple[float, float, float, float, float, float]]: """Return a 6 member bounds tuple or None if it is not defined.""" try: @@ -352,8 +353,8 @@ class Map(Actor): pnt[2] + random.uniform(*z_range)) return pnt - def get_ffa_start_position(self, players: Sequence[ba.Player] - ) -> Sequence[float]: + def get_ffa_start_position( + self, players: Sequence[ba.Player]) -> Sequence[float]: """Return a random starting position in one of the FFA spawn areas. If a list of ba.Players is provided; the returned points will be diff --git a/assets/src/data/scripts/ba/_music.py b/assets/src/data/scripts/ba/_music.py index 191a1781..26ffa7ca 100644 --- a/assets/src/data/scripts/ba/_music.py +++ b/assets/src/data/scripts/ba/_music.py @@ -337,8 +337,8 @@ class ITunesThread(threading.Thread): self._commands.append(['GET_PLAYLISTS', callback]) self._commands_available.set() - def _handle_get_playlists_command(self, target: Callable[[List[str]], None] - ) -> None: + def _handle_get_playlists_command( + self, target: Callable[[List[str]], None]) -> None: from ba._general import Call try: playlists = _ba.itunes_get_playlists() diff --git a/assets/src/data/scripts/ba/_netutils.py b/assets/src/data/scripts/ba/_netutils.py index 48087c29..0871bdcf 100644 --- a/assets/src/data/scripts/ba/_netutils.py +++ b/assets/src/data/scripts/ba/_netutils.py @@ -158,19 +158,19 @@ class ServerCallThread(threading.Thread): from_other_thread=True) -def serverget(request: str, - data: Dict[str, Any], - callback: Optional[ServerCallbackType] = None, - response_type: ServerResponseType = ServerResponseType.JSON - ) -> None: +def serverget( + request: str, + data: Dict[str, Any], + callback: Optional[ServerCallbackType] = None, + response_type: ServerResponseType = ServerResponseType.JSON) -> None: """Make a call to the master server via a http GET.""" ServerCallThread(request, 'get', data, callback, response_type).start() -def serverput(request: str, - data: Dict[str, Any], - callback: Optional[ServerCallbackType] = None, - response_type: ServerResponseType = ServerResponseType.JSON - ) -> None: +def serverput( + request: str, + data: Dict[str, Any], + callback: Optional[ServerCallbackType] = None, + response_type: ServerResponseType = ServerResponseType.JSON) -> None: """Make a call to the master server via a http POST.""" ServerCallThread(request, 'post', data, callback, response_type).start() diff --git a/assets/src/data/scripts/ba/_profile.py b/assets/src/data/scripts/ba/_profile.py index ee193d75..18893c91 100644 --- a/assets/src/data/scripts/ba/_profile.py +++ b/assets/src/data/scripts/ba/_profile.py @@ -67,7 +67,8 @@ def get_player_profile_icon(profilename: str) -> str: def get_player_profile_colors( - profilename: Optional[str], profiles: Dict[str, Dict[str, Any]] = None + profilename: Optional[str], + profiles: Dict[str, Dict[str, Any]] = None ) -> Tuple[Tuple[float, float, float], Tuple[float, float, float]]: """Given a profile, return colors for them.""" bs_config = _ba.app.config diff --git a/assets/src/data/scripts/bafoundation/entity/_entity.py b/assets/src/data/scripts/bafoundation/entity/_entity.py index 0d46172a..db590c0e 100644 --- a/assets/src/data/scripts/bafoundation/entity/_entity.py +++ b/assets/src/data/scripts/bafoundation/entity/_entity.py @@ -43,7 +43,8 @@ class EntityMixin: class are accessible on the new type. """ - def __init__(self, d_data: Dict[str, Any] = None, + def __init__(self, + d_data: Dict[str, Any] = None, error: bool = False) -> None: super().__init__() if not isinstance(self, CompoundValue): @@ -69,8 +70,8 @@ class EntityMixin: assert isinstance(self, CompoundValue) self.apply_fields_to_data(self.d_data, error=error) - def copy_data(self, - target: Union[CompoundValue, BoundCompoundValue]) -> None: + def copy_data(self, target: Union[CompoundValue, + BoundCompoundValue]) -> None: """Copy data from a target Entity or compound-value. This first verifies that the target has a matching set of fields diff --git a/assets/src/data/scripts/bafoundation/entity/_field.py b/assets/src/data/scripts/bafoundation/entity/_field.py index 5ae74b4a..f3770cea 100644 --- a/assets/src/data/scripts/bafoundation/entity/_field.py +++ b/assets/src/data/scripts/bafoundation/entity/_field.py @@ -83,7 +83,9 @@ class Field(BaseField, Generic[T]): class CompoundField(BaseField, Generic[TC]): """Field consisting of a single compound value.""" - def __init__(self, d_key: str, value: TC, + def __init__(self, + d_key: str, + value: TC, store_default: bool = False) -> None: super().__init__(d_key) if __debug__ is True: @@ -283,7 +285,9 @@ class CompoundListField(BaseField, Generic[TC]): ie: mylist[10].fieldattr = 'foo' """ - def __init__(self, d_key: str, valuetype: TC, + def __init__(self, + d_key: str, + valuetype: TC, store_default: bool = False) -> None: super().__init__(d_key) self.d_value = valuetype @@ -421,7 +425,8 @@ class CompoundDictField(BaseField, Generic[TK, TC]): ... @overload - def __get__(self, obj: Any, + def __get__(self, + obj: Any, cls: Any = None) -> BoundCompoundDictField[TK, TC]: ... diff --git a/assets/src/data/scripts/bafoundation/entity/_support.py b/assets/src/data/scripts/bafoundation/entity/_support.py index 7d7b32fe..6be706e5 100644 --- a/assets/src/data/scripts/bafoundation/entity/_support.py +++ b/assets/src/data/scripts/bafoundation/entity/_support.py @@ -45,8 +45,8 @@ class BoundCompoundValue: Allows access to its values through our own equivalent attributes. """ - def __init__(self, value: CompoundValue, - d_data: Union[List[Any], Dict[str, Any]]): + def __init__(self, value: CompoundValue, d_data: Union[List[Any], + Dict[str, Any]]): self.d_value: CompoundValue self.d_data: Union[List[Any], Dict[str, Any]] # need to use base setters to avoid triggering our own overrides @@ -374,8 +374,8 @@ class BoundCompoundListField(Generic[TC]): class BoundCompoundDictField(Generic[TK, TC]): """A CompoundDictField bound to its entity sub-data.""" - def __init__(self, field: CompoundDictField[TK, TC], - d_data: Dict[Any, Any]): + def __init__(self, field: CompoundDictField[TK, TC], d_data: Dict[Any, + Any]): self.d_field = field self.d_data = d_data diff --git a/assets/src/data/scripts/bafoundation/entity/_value.py b/assets/src/data/scripts/bafoundation/entity/_value.py index 49192e12..acc5a0b8 100644 --- a/assets/src/data/scripts/bafoundation/entity/_value.py +++ b/assets/src/data/scripts/bafoundation/entity/_value.py @@ -146,7 +146,8 @@ class OptionalStringValue(SimpleValue[Optional[str]]): class BoolValue(SimpleValue[bool]): """Value consisting of a single bool.""" - def __init__(self, default: bool = False, + def __init__(self, + default: bool = False, store_default: bool = False) -> None: super().__init__(default, store_default, bool, (int, float)) @@ -246,7 +247,8 @@ class IntValue(SimpleValue[int]): class OptionalIntValue(SimpleValue[Optional[int]]): """Value consisting of a single int or None""" - def __init__(self, default: int = None, + def __init__(self, + default: int = None, store_default: bool = False) -> None: super().__init__(default, store_default, @@ -257,7 +259,8 @@ class OptionalIntValue(SimpleValue[Optional[int]]): class FloatValue(SimpleValue[float]): """Value consisting of a single float.""" - def __init__(self, default: float = 0.0, + def __init__(self, + default: float = 0.0, store_default: bool = False) -> None: super().__init__(default, store_default, float, (bool, int)) @@ -265,7 +268,8 @@ class FloatValue(SimpleValue[float]): class OptionalFloatValue(SimpleValue[Optional[float]]): """Value consisting of a single float or None.""" - def __init__(self, default: float = None, + def __init__(self, + default: float = None, store_default: bool = False) -> None: super().__init__(default, store_default, diff --git a/assets/src/data/scripts/bafoundation/entity/util.py b/assets/src/data/scripts/bafoundation/entity/util.py index f4a9c9d8..9ee3786e 100644 --- a/assets/src/data/scripts/bafoundation/entity/util.py +++ b/assets/src/data/scripts/bafoundation/entity/util.py @@ -30,9 +30,9 @@ if TYPE_CHECKING: from bafoundation.entity._support import BoundCompoundValue -def diff_compound_values(obj1: Union[BoundCompoundValue, CompoundValue], - obj2: Union[BoundCompoundValue, CompoundValue] - ) -> str: +def diff_compound_values( + obj1: Union[BoundCompoundValue, CompoundValue], + obj2: Union[BoundCompoundValue, CompoundValue]) -> str: """Generate a string showing differences between two compound values. Both must be associated with data and have the same set of fields. @@ -108,8 +108,9 @@ def have_matching_fields(val1: CompoundValue, val2: CompoundValue) -> bool: return val1.get_fields() == val2.get_fields() -def get_compound_value_and_data(obj: Union[BoundCompoundValue, CompoundValue] - ) -> Tuple[CompoundValue, Any]: +def get_compound_value_and_data( + obj: Union[BoundCompoundValue, CompoundValue] +) -> Tuple[CompoundValue, Any]: """Return value and data for bound or unbound compound values.""" # pylint: disable=cyclic-import from bafoundation.entity._support import BoundCompoundValue diff --git a/assets/src/data/scripts/bafoundation/executils.py b/assets/src/data/scripts/bafoundation/executils.py index 7116b69a..d9b0cc31 100644 --- a/assets/src/data/scripts/bafoundation/executils.py +++ b/assets/src/data/scripts/bafoundation/executils.py @@ -145,8 +145,8 @@ if TYPE_CHECKING: class _Call5Args(Generic[In1T, In2T, In3T, In4T, In5T, OutT]): """Five argument variant of call wrapper""" - def __init__(self, - _call: Callable[[In1T, In2T, In3T, In4T, In5T], OutT]): + def __init__(self, _call: Callable[[In1T, In2T, In3T, In4T, In5T], + OutT]): ... def __call__(self, _arg1: In1T, _arg2: In2T, _arg3: In3T, _arg4: In4T, @@ -156,9 +156,9 @@ if TYPE_CHECKING: class _Call6Args(Generic[In1T, In2T, In3T, In4T, In5T, In6T, OutT]): """Six argument variant of call wrapper""" - def __init__( - self, - _call: Callable[[In1T, In2T, In3T, In4T, In5T, In6T], OutT]): + def __init__(self, + _call: Callable[[In1T, In2T, In3T, In4T, In5T, In6T], + OutT]): ... def __call__(self, _arg1: In1T, _arg2: In2T, _arg3: In3T, _arg4: In4T, @@ -169,9 +169,8 @@ if TYPE_CHECKING: """Seven argument variant of call wrapper""" def __init__( - self, - _call: Callable[[In1T, In2T, In3T, In4T, In5T, In6T, In7T], - OutT]): + self, _call: Callable[[In1T, In2T, In3T, In4T, In5T, In6T, In7T], + OutT]): ... def __call__(self, _arg1: In1T, _arg2: In2T, _arg3: In3T, _arg4: In4T, @@ -240,8 +239,9 @@ if TYPE_CHECKING: # 3 arg call; no args bundled. # noinspection PyPep8Naming @overload - def Call(call: Callable[[In1T, In2T, In3T], OutT] - ) -> _Call3Args[In1T, In2T, In3T, OutT]: + def Call( + call: Callable[[In1T, In2T, In3T], OutT] + ) -> _Call3Args[In1T, In2T, In3T, OutT]: ... # 4 arg call; 4 args bundled. @@ -254,17 +254,17 @@ if TYPE_CHECKING: # 5 arg call; 5 args bundled. # noinspection PyPep8Naming @overload - def Call(call: Callable[[In1T, In2T, In3T, In4T, In5T], OutT], arg1: In1T, - arg2: In2T, arg3: In3T, arg4: In4T, - arg5: In5T) -> _CallNoArgs[OutT]: + def Call(call: Callable[[In1T, In2T, In3T, In4T, In5T], + OutT], arg1: In1T, arg2: In2T, arg3: In3T, + arg4: In4T, arg5: In5T) -> _CallNoArgs[OutT]: ... # 6 arg call; 6 args bundled. # noinspection PyPep8Naming @overload - def Call(call: Callable[[In1T, In2T, In3T, In4T, In5T, In6T], OutT], - arg1: In1T, arg2: In2T, arg3: In3T, arg4: In4T, arg5: In5T, - arg6: In6T) -> _CallNoArgs[OutT]: + def Call(call: Callable[[In1T, In2T, In3T, In4T, In5T, In6T], + OutT], arg1: In1T, arg2: In2T, arg3: In3T, + arg4: In4T, arg5: In5T, arg6: In6T) -> _CallNoArgs[OutT]: ... # 7 arg call; 7 args bundled. diff --git a/assets/src/data/scripts/bafoundation/util.py b/assets/src/data/scripts/bafoundation/util.py index 8af8f0cd..95b87d00 100644 --- a/assets/src/data/scripts/bafoundation/util.py +++ b/assets/src/data/scripts/bafoundation/util.py @@ -60,8 +60,9 @@ class DispatchMethodWrapper(Generic[TARG, TRET]): # noinspection PyTypeHints, PyProtectedMember -def dispatchmethod(func: Callable[[Any, TARG], TRET] - ) -> DispatchMethodWrapper[TARG, TRET]: +def dispatchmethod( + func: Callable[[Any, TARG], TRET] +) -> DispatchMethodWrapper[TARG, TRET]: """A variation of functools.singledispatch for methods.""" from functools import singledispatch, update_wrapper origwrapper: Any = singledispatch(func) @@ -224,8 +225,9 @@ class ValueDispatcher(Generic[TVAL, TRET]): return partial(self._add_handler, value) -def valuedispatch1arg(call: Callable[[TVAL, TARG], TRET] - ) -> ValueDispatcher1Arg[TVAL, TARG, TRET]: +def valuedispatch1arg( + call: Callable[[TVAL, TARG], TRET] +) -> ValueDispatcher1Arg[TVAL, TARG, TRET]: """Like valuedispatch but for functions taking an extra argument.""" return ValueDispatcher1Arg(call) diff --git a/assets/src/data/scripts/bastd/activity/coopjoinscreen.py b/assets/src/data/scripts/bastd/activity/coopjoinscreen.py index d9535f02..341f5e0b 100644 --- a/assets/src/data/scripts/bastd/activity/coopjoinscreen.py +++ b/assets/src/data/scripts/bastd/activity/coopjoinscreen.py @@ -98,10 +98,12 @@ class CoopJoiningActivity(JoiningActivity): spacing = 25 delay_inc = 0.1 - def _add_t(text: Union[str, ba.Lstr], - h_offs: float = 0.0, - scale: float = 1.0, - color: Sequence[float] = (1.0, 1.0, 1.0, 0.46)) -> None: + def _add_t( + text: Union[str, ba.Lstr], + h_offs: float = 0.0, + scale: float = 1.0, + color: Sequence[float] = (1.0, 1.0, 1.0, 0.46) + ) -> None: Text(text, scale=scale * 0.76, h_align='left', diff --git a/assets/src/data/scripts/bastd/activity/teamsscorescreen.py b/assets/src/data/scripts/bastd/activity/teamsscorescreen.py index 491f6843..d03fda46 100644 --- a/assets/src/data/scripts/bastd/activity/teamsscorescreen.py +++ b/assets/src/data/scripts/bastd/activity/teamsscorescreen.py @@ -118,8 +118,8 @@ class TeamsScoreScreenActivity(ScoreScreenActivity): assert self.stats valid_players = list(self.stats.get_records().items()) - def _get_player_score_set_entry(player: ba.Player - ) -> Optional[PlayerRecord]: + def _get_player_score_set_entry( + player: ba.Player) -> Optional[PlayerRecord]: for p_rec in valid_players: # PyCharm incorrectly thinks valid_players is a List[str] # noinspection PyUnresolvedReferences diff --git a/assets/src/data/scripts/bastd/actor/onscreentimer.py b/assets/src/data/scripts/bastd/actor/onscreentimer.py index 3a29f3ac..850c11c4 100644 --- a/assets/src/data/scripts/bastd/actor/onscreentimer.py +++ b/assets/src/data/scripts/bastd/actor/onscreentimer.py @@ -99,8 +99,10 @@ class OnScreenTimer(ba.Actor): self.inputnode.timemax = endtime_ms - self._starttime - def getstarttime(self, timeformat: ba.TimeFormat = ba.TimeFormat.SECONDS - ) -> Union[int, float]: + def getstarttime( + self, + timeformat: ba.TimeFormat = ba.TimeFormat.SECONDS + ) -> Union[int, float]: """Return the sim-time when start() was called. Time will be returned in seconds if timeformat is SECONDS or diff --git a/assets/src/data/scripts/bastd/actor/spaz.py b/assets/src/data/scripts/bastd/actor/spaz.py index f25533cc..e7987b4a 100644 --- a/assets/src/data/scripts/bastd/actor/spaz.py +++ b/assets/src/data/scripts/bastd/actor/spaz.py @@ -243,8 +243,8 @@ class Spaz(ba.Actor): self._bomb_held = False if self.default_shields: self.equip_shields() - self._dropped_bomb_callbacks: List[ - Callable[[Spaz, ba.Actor], Any]] = [] + self._dropped_bomb_callbacks: List[Callable[[Spaz, ba.Actor], + Any]] = [] self._score_text: Optional[ba.Node] = None self._score_text_hide_timer: Optional[ba.Timer] = None @@ -262,8 +262,8 @@ class Spaz(ba.Actor): self.punch_callback = None self.pick_up_powerup_callback = None - def add_dropped_bomb_callback(self, call: Callable[[Spaz, ba.Actor], Any] - ) -> None: + def add_dropped_bomb_callback( + self, call: Callable[[Spaz, ba.Actor], Any]) -> None: """ Add a call to be run whenever this Spaz drops a bomb. The spaz and the newly-dropped bomb are passed as arguments. diff --git a/assets/src/data/scripts/bastd/actor/spazbot.py b/assets/src/data/scripts/bastd/actor/spazbot.py index 4b2f7c4a..3ed515eb 100644 --- a/assets/src/data/scripts/bastd/actor/spazbot.py +++ b/assets/src/data/scripts/bastd/actor/spazbot.py @@ -179,8 +179,8 @@ class SpazBot(basespaz.Spaz): assert mval is not None return mval - def _get_target_player_pt(self - ) -> Tuple[Optional[ba.Vec3], Optional[ba.Vec3]]: + def _get_target_player_pt( + self) -> Tuple[Optional[ba.Vec3], Optional[ba.Vec3]]: """Returns the position and velocity of our target. Both values will be None in the case of no target. diff --git a/assets/src/data/scripts/bastd/appdelegate.py b/assets/src/data/scripts/bastd/appdelegate.py index d4252cee..5899e49a 100644 --- a/assets/src/data/scripts/bastd/appdelegate.py +++ b/assets/src/data/scripts/bastd/appdelegate.py @@ -33,9 +33,9 @@ class AppDelegate(ba.AppDelegate): """Defines handlers for high level app functionality.""" def create_default_game_config_ui( - self, gameclass: Type[ba.GameActivity], - sessionclass: Type[ba.Session], config: Optional[Dict[str, Any]], - completion_call: Callable[[Optional[Dict[str, Any]]], Any] + self, gameclass: Type[ba.GameActivity], sessionclass: Type[ba.Session], + config: Optional[Dict[str, Any]], + completion_call: Callable[[Optional[Dict[str, Any]]], Any] ) -> None: """(internal)""" diff --git a/assets/src/data/scripts/bastd/game/assault.py b/assets/src/data/scripts/bastd/game/assault.py index a9c959b0..5c58deb3 100644 --- a/assets/src/data/scripts/bastd/game/assault.py +++ b/assets/src/data/scripts/bastd/game/assault.py @@ -56,8 +56,9 @@ class AssaultGame(ba.TeamGameActivity): return ba.getmaps('team_flag') @classmethod - def get_settings(cls, sessiontype: Type[ba.Session] - ) -> List[Tuple[str, Dict[str, Any]]]: + def get_settings( + cls, + sessiontype: Type[ba.Session]) -> List[Tuple[str, Dict[str, Any]]]: return [('Score to Win', {'min_value': 1, 'default': 3}), ('Time Limit', { 'choices': [('None', 0), ('1 Minute', 60), diff --git a/assets/src/data/scripts/bastd/game/capturetheflag.py b/assets/src/data/scripts/bastd/game/capturetheflag.py index 32638e36..2396ffe1 100644 --- a/assets/src/data/scripts/bastd/game/capturetheflag.py +++ b/assets/src/data/scripts/bastd/game/capturetheflag.py @@ -89,8 +89,9 @@ class CaptureTheFlagGame(ba.TeamGameActivity): return ba.getmaps('team_flag') @classmethod - def get_settings(cls, sessiontype: Type[ba.Session] - ) -> List[Tuple[str, Dict[str, Any]]]: + def get_settings( + cls, + sessiontype: Type[ba.Session]) -> List[Tuple[str, Dict[str, Any]]]: return [ ('Score to Win', {'min_value': 1, 'default': 3}), ('Flag Touch Return Time', { diff --git a/assets/src/data/scripts/bastd/game/chosenone.py b/assets/src/data/scripts/bastd/game/chosenone.py index b821fce5..385427e4 100644 --- a/assets/src/data/scripts/bastd/game/chosenone.py +++ b/assets/src/data/scripts/bastd/game/chosenone.py @@ -62,8 +62,9 @@ class ChosenOneGame(ba.TeamGameActivity): return ba.getmaps('keep_away') @classmethod - def get_settings(cls, sessiontype: Type[ba.Session] - ) -> List[Tuple[str, Dict[str, Any]]]: + def get_settings( + cls, + sessiontype: Type[ba.Session]) -> List[Tuple[str, Dict[str, Any]]]: return [("Chosen One Time", { 'min_value': 10, 'default': 30, diff --git a/assets/src/data/scripts/bastd/game/conquest.py b/assets/src/data/scripts/bastd/game/conquest.py index 7589fbfb..7b716778 100644 --- a/assets/src/data/scripts/bastd/game/conquest.py +++ b/assets/src/data/scripts/bastd/game/conquest.py @@ -77,8 +77,9 @@ class ConquestGame(ba.TeamGameActivity): return ba.getmaps("conquest") @classmethod - def get_settings(cls, sessiontype: Type[ba.Session] - ) -> List[Tuple[str, Dict[str, Any]]]: + def get_settings( + cls, + sessiontype: Type[ba.Session]) -> List[Tuple[str, Dict[str, Any]]]: return [ ("Time Limit", { 'choices': [('None', 0), ('1 Minute', 60), diff --git a/assets/src/data/scripts/bastd/game/deathmatch.py b/assets/src/data/scripts/bastd/game/deathmatch.py index 585dc061..cb225b89 100644 --- a/assets/src/data/scripts/bastd/game/deathmatch.py +++ b/assets/src/data/scripts/bastd/game/deathmatch.py @@ -56,8 +56,9 @@ class DeathMatchGame(ba.TeamGameActivity): return ba.getmaps("melee") @classmethod - def get_settings(cls, sessiontype: Type[ba.Session] - ) -> List[Tuple[str, Dict[str, Any]]]: + def get_settings( + cls, + sessiontype: Type[ba.Session]) -> List[Tuple[str, Dict[str, Any]]]: settings: List[Tuple[str, Dict[str, Any]]] = [ ("Kills to Win Per Player", { 'min_value': 1, diff --git a/assets/src/data/scripts/bastd/game/easteregghunt.py b/assets/src/data/scripts/bastd/game/easteregghunt.py index 5a3b82f8..db2a330b 100644 --- a/assets/src/data/scripts/bastd/game/easteregghunt.py +++ b/assets/src/data/scripts/bastd/game/easteregghunt.py @@ -67,8 +67,9 @@ class EasterEggHuntGame(ba.TeamGameActivity): or issubclass(sessiontype, ba.FreeForAllSession)) @classmethod - def get_settings(cls, sessiontype: Type[ba.Session] - ) -> List[Tuple[str, Dict[str, Any]]]: + def get_settings( + cls, + sessiontype: Type[ba.Session]) -> List[Tuple[str, Dict[str, Any]]]: return [("Pro Mode", {'default': False})] def __init__(self, settings: Dict[str, Any]): diff --git a/assets/src/data/scripts/bastd/game/elimination.py b/assets/src/data/scripts/bastd/game/elimination.py index 9942e40c..dfcefc7d 100644 --- a/assets/src/data/scripts/bastd/game/elimination.py +++ b/assets/src/data/scripts/bastd/game/elimination.py @@ -193,8 +193,9 @@ class EliminationGame(ba.TeamGameActivity): return ba.getmaps("melee") @classmethod - def get_settings(cls, sessiontype: Type[ba.Session] - ) -> List[Tuple[str, Dict[str, Any]]]: + def get_settings( + cls, + sessiontype: Type[ba.Session]) -> List[Tuple[str, Dict[str, Any]]]: settings: List[Tuple[str, Dict[str, Any]]] = [ ("Lives Per Player", { 'default': 1, 'min_value': 1, diff --git a/assets/src/data/scripts/bastd/game/football.py b/assets/src/data/scripts/bastd/game/football.py index 8e2be912..ebe5690b 100644 --- a/assets/src/data/scripts/bastd/game/football.py +++ b/assets/src/data/scripts/bastd/game/football.py @@ -87,8 +87,9 @@ class FootballTeamGame(ba.TeamGameActivity): return ba.getmaps('football') @classmethod - def get_settings(cls, sessiontype: Type[ba.Session] - ) -> List[Tuple[str, Dict[str, Any]]]: + def get_settings( + cls, + sessiontype: Type[ba.Session]) -> List[Tuple[str, Dict[str, Any]]]: return [ ("Score to Win", { 'min_value': 7, diff --git a/assets/src/data/scripts/bastd/game/hockey.py b/assets/src/data/scripts/bastd/game/hockey.py index 1ea46696..52c0ea48 100644 --- a/assets/src/data/scripts/bastd/game/hockey.py +++ b/assets/src/data/scripts/bastd/game/hockey.py @@ -126,8 +126,9 @@ class HockeyGame(ba.TeamGameActivity): return ba.getmaps('hockey') @classmethod - def get_settings(cls, sessiontype: Type[ba.Session] - ) -> List[Tuple[str, Dict[str, Any]]]: + def get_settings( + cls, + sessiontype: Type[ba.Session]) -> List[Tuple[str, Dict[str, Any]]]: return [ ("Score to Win", { 'min_value': 1, 'default': 1, 'increment': 1 diff --git a/assets/src/data/scripts/bastd/game/keepaway.py b/assets/src/data/scripts/bastd/game/keepaway.py index aa5ff767..a6e39a1c 100644 --- a/assets/src/data/scripts/bastd/game/keepaway.py +++ b/assets/src/data/scripts/bastd/game/keepaway.py @@ -67,8 +67,9 @@ class KeepAwayGame(ba.TeamGameActivity): return ba.getmaps('keep_away') @classmethod - def get_settings(cls, sessiontype: Type[ba.Session] - ) -> List[Tuple[str, Dict[str, Any]]]: + def get_settings( + cls, + sessiontype: Type[ba.Session]) -> List[Tuple[str, Dict[str, Any]]]: return [ ("Hold Time", { 'min_value': 10, diff --git a/assets/src/data/scripts/bastd/game/kingofthehill.py b/assets/src/data/scripts/bastd/game/kingofthehill.py index 550e4fce..8dc5b73f 100644 --- a/assets/src/data/scripts/bastd/game/kingofthehill.py +++ b/assets/src/data/scripts/bastd/game/kingofthehill.py @@ -68,8 +68,9 @@ class KingOfTheHillGame(ba.TeamGameActivity): return ba.getmaps("king_of_the_hill") @classmethod - def get_settings(cls, sessiontype: Type[ba.Session] - ) -> List[Tuple[str, Dict[str, Any]]]: + def get_settings( + cls, + sessiontype: Type[ba.Session]) -> List[Tuple[str, Dict[str, Any]]]: return [("Hold Time", { 'min_value': 10, 'default': 30, diff --git a/assets/src/data/scripts/bastd/game/meteorshower.py b/assets/src/data/scripts/bastd/game/meteorshower.py index 4d07c39b..2f48e048 100644 --- a/assets/src/data/scripts/bastd/game/meteorshower.py +++ b/assets/src/data/scripts/bastd/game/meteorshower.py @@ -63,8 +63,9 @@ class MeteorShowerGame(ba.TeamGameActivity): return ['Rampage'] @classmethod - def get_settings(cls, sessiontype: Type[ba.Session] - ) -> List[Tuple[str, Dict[str, Any]]]: + def get_settings( + cls, + sessiontype: Type[ba.Session]) -> List[Tuple[str, Dict[str, Any]]]: return [("Epic Mode", {'default': False})] # We support teams, free-for-all, and co-op sessions. diff --git a/assets/src/data/scripts/bastd/game/race.py b/assets/src/data/scripts/bastd/game/race.py index 12dc755c..4a9490f2 100644 --- a/assets/src/data/scripts/bastd/game/race.py +++ b/assets/src/data/scripts/bastd/game/race.py @@ -87,8 +87,9 @@ class RaceGame(ba.TeamGameActivity): return ba.getmaps("race") @classmethod - def get_settings(cls, sessiontype: Type[ba.Session] - ) -> List[Tuple[str, Dict[str, Any]]]: + def get_settings( + cls, + sessiontype: Type[ba.Session]) -> List[Tuple[str, Dict[str, Any]]]: settings: List[Tuple[str, Dict[str, Any]]] = [ ("Laps", { 'min_value': 1, diff --git a/assets/src/data/scripts/bastd/game/runaround.py b/assets/src/data/scripts/bastd/game/runaround.py index 2938dd12..629a28b9 100644 --- a/assets/src/data/scripts/bastd/game/runaround.py +++ b/assets/src/data/scripts/bastd/game/runaround.py @@ -822,9 +822,9 @@ class RunaroundGame(ba.CoopGameActivity): elif path == 6: this_target_point_s *= 0.7 - def _add_defender( - defender_type: Tuple[Type[spazbot.SpazBot], float], - pnt: str) -> Tuple[float, Dict[str, Any]]: + def _add_defender(defender_type: Tuple[Type[spazbot.SpazBot], + float], + pnt: str) -> Tuple[float, Dict[str, Any]]: # FIXME: should look into this warning # pylint: disable=cell-var-from-loop return this_target_point_s * defender_type[1], { diff --git a/assets/src/data/scripts/bastd/game/targetpractice.py b/assets/src/data/scripts/bastd/game/targetpractice.py index ef00121c..50d0b045 100644 --- a/assets/src/data/scripts/bastd/game/targetpractice.py +++ b/assets/src/data/scripts/bastd/game/targetpractice.py @@ -60,8 +60,9 @@ class TargetPracticeGame(ba.TeamGameActivity): or issubclass(sessiontype, ba.TeamBaseSession)) @classmethod - def get_settings(cls, sessiontype: Type[ba.Session] - ) -> List[Tuple[str, Dict[str, Any]]]: + def get_settings( + cls, + sessiontype: Type[ba.Session]) -> List[Tuple[str, Dict[str, Any]]]: return [("Target Count", { 'min_value': 1, 'default': 3 diff --git a/assets/src/data/scripts/bastd/maps.py b/assets/src/data/scripts/bastd/maps.py index bfc14c4b..1db9c338 100644 --- a/assets/src/data/scripts/bastd/maps.py +++ b/assets/src/data/scripts/bastd/maps.py @@ -171,7 +171,8 @@ class FootballStadium(ba.Map): gnode.vr_camera_offset = (0, -0.8, -1.1) gnode.vr_near_clip = 0.5 - def is_point_near_edge(self, point: ba.Vec3, + def is_point_near_edge(self, + point: ba.Vec3, running: bool = False) -> bool: box_position = self.defs.boxes['edge_box'][0:3] box_scale = self.defs.boxes['edge_box'][6:9] @@ -814,7 +815,8 @@ class DoomShroom(ba.Map): gnode.vignette_outer = (0.76, 0.76, 0.76) gnode.vignette_inner = (0.95, 0.95, 0.99) - def is_point_near_edge(self, point: ba.Vec3, + def is_point_near_edge(self, + point: ba.Vec3, running: bool = False) -> bool: xpos = point.x zpos = point.z @@ -1162,7 +1164,8 @@ class TowerD(ba.Map): gnode.vignette_outer = (0.7, 0.73, 0.7) gnode.vignette_inner = (0.95, 0.95, 0.95) - def is_point_near_edge(self, point: ba.Vec3, + def is_point_near_edge(self, + point: ba.Vec3, running: bool = False) -> bool: # see if we're within edge_box boxes = self.defs.boxes @@ -1453,7 +1456,8 @@ class Courtyard(ba.Map): gnode.vignette_outer = (0.6, 0.6, 0.64) gnode.vignette_inner = (0.95, 0.95, 0.93) - def is_point_near_edge(self, point: ba.Vec3, + def is_point_near_edge(self, + point: ba.Vec3, running: bool = False) -> bool: # count anything off our ground level as safe (for our platforms) # see if we're within edge_box @@ -1549,7 +1553,8 @@ class Rampage(ba.Map): gnode.vignette_outer = (0.62, 0.64, 0.69) gnode.vignette_inner = (0.97, 0.95, 0.93) - def is_point_near_edge(self, point: ba.Vec3, + def is_point_near_edge(self, + point: ba.Vec3, running: bool = False) -> bool: box_position = self.defs.boxes['edge_box'][0:3] box_scale = self.defs.boxes['edge_box'][6:9] diff --git a/assets/src/data/scripts/bastd/ui/account/settings.py b/assets/src/data/scripts/bastd/ui/account/settings.py index 3867952d..da90e9e8 100644 --- a/assets/src/data/scripts/bastd/ui/account/settings.py +++ b/assets/src/data/scripts/bastd/ui/account/settings.py @@ -1057,7 +1057,8 @@ class AccountSettingsWindow(ba.OldWindow): ba.buttonwidget(edit=self._sign_out_button, label=ba.Lstr(resource=self._r + '.signingOutText')) - def _sign_in_press(self, account_type: str, + def _sign_in_press(self, + account_type: str, show_test_warning: bool = True) -> None: del show_test_warning # unused _ba.sign_in(account_type) diff --git a/assets/src/data/scripts/bastd/ui/continues.py b/assets/src/data/scripts/bastd/ui/continues.py index f59ce387..4e5b3e2b 100644 --- a/assets/src/data/scripts/bastd/ui/continues.py +++ b/assets/src/data/scripts/bastd/ui/continues.py @@ -36,8 +36,8 @@ class ContinuesWindow(ba.OldWindow): """A window to continue a game.""" def __init__(self, activity: ba.Activity, cost: int, - continue_call: Callable[[], Any], - cancel_call: Callable[[], Any]): + continue_call: Callable[[], Any], cancel_call: Callable[[], + Any]): self._activity = weakref.ref(activity) self._cost = cost self._continue_call = continue_call diff --git a/assets/src/data/scripts/bastd/ui/coop/browser.py b/assets/src/data/scripts/bastd/ui/coop/browser.py index 7ef92fe2..8bbe15d5 100644 --- a/assets/src/data/scripts/bastd/ui/coop/browser.py +++ b/assets/src/data/scripts/bastd/ui/coop/browser.py @@ -569,8 +569,8 @@ class CoopBrowserWindow(ba.OldWindow): ('' + str(free_tries_remaining))), color=(0.6, 0.6, 0.6, 1)) - def _on_tournament_query_response(self, - data: Optional[Dict[str, Any]]) -> None: + def _on_tournament_query_response(self, data: Optional[Dict[str, + Any]]) -> None: from ba.internal import cache_tournament_info app = ba.app if data is not None: diff --git a/assets/src/data/scripts/bastd/ui/gather.py b/assets/src/data/scripts/bastd/ui/gather.py index 8b8b4b80..486188e4 100644 --- a/assets/src/data/scripts/bastd/ui/gather.py +++ b/assets/src/data/scripts/bastd/ui/gather.py @@ -1351,8 +1351,8 @@ class GatherWindow(ba.OldWindow): ba.textwidget(edit=self._internet_host_max_party_size_value, text=str(val)) - def _on_public_party_query_result(self, result: Optional[Dict[str, Any]] - ) -> None: + def _on_public_party_query_result( + self, result: Optional[Dict[str, Any]]) -> None: with ba.Context('ui'): # any time we get any result at all, kill our loading status status_text = self._internet_join_status_text @@ -1806,9 +1806,8 @@ class GatherWindow(ba.OldWindow): fallback_resource='gatherWindow.stopAdvertisingText'), on_activate_call=self._on_stop_internet_advertising_press) - def _on_public_party_accessible_response(self, - data: Optional[Dict[str, Any]] - ) -> None: + def _on_public_party_accessible_response( + self, data: Optional[Dict[str, Any]]) -> None: # If we've got status text widgets, update them. text = self._internet_host_status_text if text: diff --git a/assets/src/data/scripts/bastd/ui/league/rankbutton.py b/assets/src/data/scripts/bastd/ui/league/rankbutton.py index 2145a18b..1674f16b 100644 --- a/assets/src/data/scripts/bastd/ui/league/rankbutton.py +++ b/assets/src/data/scripts/bastd/ui/league/rankbutton.py @@ -230,8 +230,8 @@ class LeagueRankButton: ba.print_exception('error doing smooth update') self._smooth_update_timer = None - def _update_for_league_rank_data(self, - data: Optional[Dict[str, Any]]) -> None: + def _update_for_league_rank_data(self, data: Optional[Dict[str, + Any]]) -> None: # pylint: disable=too-many-branches # pylint: disable=too-many-statements from ba.internal import get_league_rank_points @@ -340,8 +340,8 @@ class LeagueRankButton: ba.textwidget(edit=self._title_text, text=txt, color=t_color) ba.textwidget(edit=self._value_text, text=status_text) - def _on_power_ranking_query_response(self, data: Optional[Dict[str, Any]] - ) -> None: + def _on_power_ranking_query_response( + self, data: Optional[Dict[str, Any]]) -> None: from ba.internal import cache_league_rank_data self._doing_power_ranking_query = False cache_league_rank_data(data) diff --git a/assets/src/data/scripts/bastd/ui/league/rankwindow.py b/assets/src/data/scripts/bastd/ui/league/rankwindow.py index e7273a4e..e968e25c 100644 --- a/assets/src/data/scripts/bastd/ui/league/rankwindow.py +++ b/assets/src/data/scripts/bastd/ui/league/rankwindow.py @@ -210,8 +210,8 @@ class LeagueRankWindow(ba.OldWindow): else: ba.playsound(ba.getsound('error')) - def _on_power_ranking_query_response(self, data: Optional[Dict[str, Any]] - ) -> None: + def _on_power_ranking_query_response( + self, data: Optional[Dict[str, Any]]) -> None: from ba.internal import cache_league_rank_data self._doing_power_ranking_query = False # important: *only* cache this if we requested the current season.. @@ -607,8 +607,8 @@ class LeagueRankWindow(ba.OldWindow): '/highscores?list=powerRankings&v=2' + league_str + season_str + '&player=' + our_login_id) - def _update_for_league_rank_data(self, - data: Optional[Dict[str, Any]]) -> None: + def _update_for_league_rank_data(self, data: Optional[Dict[str, + Any]]) -> None: # pylint: disable=too-many-statements # pylint: disable=too-many-branches # pylint: disable=too-many-locals diff --git a/assets/src/data/scripts/bastd/ui/mainmenu.py b/assets/src/data/scripts/bastd/ui/mainmenu.py index 199d25eb..0eb34d9d 100644 --- a/assets/src/data/scripts/bastd/ui/mainmenu.py +++ b/assets/src/data/scripts/bastd/ui/mainmenu.py @@ -400,8 +400,9 @@ class MainMenuWindow(ba.OldWindow): size=(0, 0), scale=3.0 * t_scale) - def _refresh_not_in_game(self, positions: List[Tuple[float, float, float]] - ) -> Tuple[float, float, float]: + def _refresh_not_in_game( + self, positions: List[Tuple[float, float, float]] + ) -> Tuple[float, float, float]: # pylint: disable=too-many-branches # pylint: disable=too-many-locals # pylint: disable=too-many-statements @@ -654,8 +655,9 @@ class MainMenuWindow(ba.OldWindow): self._tdelay += self._t_delay_inc return h, v, scale - def _refresh_in_game(self, positions: List[Tuple[float, float, float]] - ) -> Tuple[float, float, float]: + def _refresh_in_game( + self, positions: List[Tuple[float, float, float]] + ) -> Tuple[float, float, float]: # pylint: disable=too-many-branches # pylint: disable=too-many-locals # pylint: disable=too-many-statements diff --git a/assets/src/data/scripts/bastd/ui/profile/edit.py b/assets/src/data/scripts/bastd/ui/profile/edit.py index 1ebb79a5..1bf15491 100644 --- a/assets/src/data/scripts/bastd/ui/profile/edit.py +++ b/assets/src/data/scripts/bastd/ui/profile/edit.py @@ -538,8 +538,8 @@ class EditProfileWindow(ba.OldWindow): tint_color=self._color, tint2_color=self._highlight) - def _make_picker(self, picker_type: str, - origin: Tuple[float, float]) -> None: + def _make_picker(self, picker_type: str, origin: Tuple[float, + float]) -> None: from bastd.ui import colorpicker if picker_type == 'color': initial_color = self._color diff --git a/assets/src/data/scripts/bastd/ui/settings/gamepad.py b/assets/src/data/scripts/bastd/ui/settings/gamepad.py index a89c27cc..a8db2d07 100644 --- a/assets/src/data/scripts/bastd/ui/settings/gamepad.py +++ b/assets/src/data/scripts/bastd/ui/settings/gamepad.py @@ -769,13 +769,13 @@ class AwaitGamepadInputWindow(ba.OldWindow): """Window for capturing a gamepad button press.""" def __init__( - self, - gamepad: ba.InputDevice, - button: str, - callback: Callable[[str, Dict[str, Any], AwaitGamepadInputWindow], - Any], - message: ba.Lstr = None, - message2: ba.Lstr = None): + self, + gamepad: ba.InputDevice, + button: str, + callback: Callable[[str, Dict[str, Any], AwaitGamepadInputWindow], + Any], + message: ba.Lstr = None, + message2: ba.Lstr = None): if message is None: print('AwaitGamepadInputWindow message is None!') message = ba.Lstr( diff --git a/assets/src/data/scripts/bastd/ui/settings/gamepadadvanced.py b/assets/src/data/scripts/bastd/ui/settings/gamepadadvanced.py index c55f7614..cfb3e7c6 100644 --- a/assets/src/data/scripts/bastd/ui/settings/gamepadadvanced.py +++ b/assets/src/data/scripts/bastd/ui/settings/gamepadadvanced.py @@ -348,12 +348,12 @@ class GamepadAdvancedSettingsWindow(ba.OldWindow): for child in self._subcontainer.get_children(): ba.widget(edit=child, show_buffer_bottom=30, show_buffer_top=30) - def _capture_button(self, - pos: Tuple[float, float], - name: ba.Lstr, - control: str, - message: Optional[ba.Lstr] = None - ) -> Tuple[ba.Widget, ba.Widget]: + def _capture_button( + self, + pos: Tuple[float, float], + name: ba.Lstr, + control: str, + message: Optional[ba.Lstr] = None) -> Tuple[ba.Widget, ba.Widget]: if message is None: message = ba.Lstr(resource=self._parent_window.get_r() + '.pressAnyButtonText') @@ -416,17 +416,17 @@ class GamepadAdvancedSettingsWindow(ba.OldWindow): ba.textwidget(edit=self._textwidgets[control], text=self._parent_window.get_control_value_name(control)) - def _config_value_editor(self, - name: ba.Lstr, - control: str, - position: Tuple[float, float], - min_val: float = 0.0, - max_val: float = 100.0, - increment: float = 1.0, - change_sound: bool = True, - x_offset: float = 0.0, - displayname: ba.Lstr = None - ) -> Tuple[ba.Widget, ba.Widget]: + def _config_value_editor( + self, + name: ba.Lstr, + control: str, + position: Tuple[float, float], + min_val: float = 0.0, + max_val: float = 100.0, + increment: float = 1.0, + change_sound: bool = True, + x_offset: float = 0.0, + displayname: ba.Lstr = None) -> Tuple[ba.Widget, ba.Widget]: if displayname is None: displayname = name diff --git a/assets/src/data/scripts/bastd/ui/store/browser.py b/assets/src/data/scripts/bastd/ui/store/browser.py index ae9d2048..67c1ed5f 100644 --- a/assets/src/data/scripts/bastd/ui/store/browser.py +++ b/assets/src/data/scripts/bastd/ui/store/browser.py @@ -445,7 +445,8 @@ class StoreBrowserWindow(ba.OldWindow): resource='getTicketsWindow.unavailableText'), color=(1, 0, 0)) - def _do_purchase_check(self, item: str, + def _do_purchase_check(self, + item: str, is_ticket_purchase: bool = False) -> None: from ba.internal import serverget diff --git a/assets/src/data/scripts/bastd/ui/tournamententry.py b/assets/src/data/scripts/bastd/ui/tournamententry.py index 931be250..a30516c7 100644 --- a/assets/src/data/scripts/bastd/ui/tournamententry.py +++ b/assets/src/data/scripts/bastd/ui/tournamententry.py @@ -308,8 +308,8 @@ class TournamentEntryWindow(popup.PopupWindow): self._update() self._restore_state() - def _on_tournament_query_response(self, - data: Optional[Dict[str, Any]]) -> None: + def _on_tournament_query_response(self, data: Optional[Dict[str, + Any]]) -> None: from ba.internal import cache_tournament_info self._running_query = False if data is not None: diff --git a/assets/src/data/scripts/bastd/ui/tournamentscores.py b/assets/src/data/scripts/bastd/ui/tournamentscores.py index 0e003e06..0a8f50e4 100644 --- a/assets/src/data/scripts/bastd/ui/tournamentscores.py +++ b/assets/src/data/scripts/bastd/ui/tournamentscores.py @@ -124,8 +124,8 @@ class TournamentScoresWindow(popup_ui.PopupWindow): callback=ba.WeakCall( self._on_tournament_query_response)) - def _on_tournament_query_response(self, - data: Optional[Dict[str, Any]]) -> None: + def _on_tournament_query_response(self, data: Optional[Dict[str, + Any]]) -> None: if data is not None: # this used to be the whole payload data_t: List[Dict[str, Any]] = data['t'] diff --git a/assets/src/server/server.py b/assets/src/server/server.py index b7407e46..e4e6d865 100755 --- a/assets/src/server/server.py +++ b/assets/src/server/server.py @@ -123,8 +123,8 @@ def _get_default_config() -> Dict[str, Any]: def _run_process_until_exit(process: subprocess.Popen, input_commands: Sequence[str], - restart_minutes: int, - config: Dict[str, Any]) -> None: + restart_minutes: int, config: Dict[str, + Any]) -> None: # So we pass our initial config. config_dirty = True diff --git a/config/config.json b/config/config.json index 9f698fd9..eb36cd72 100644 --- a/config/config.json +++ b/config/config.json @@ -25,7 +25,8 @@ "bs_mapdefs_football_stadium", "bs_mapdefs_tower_d", "bs_mapdefs_hockey_stadium", - "bs_mapdefs_roundabout" + "bs_mapdefs_roundabout", + "yaml" ], "python_paths": [ "assets/src/data/scripts", diff --git a/docs/ba_module.md b/docs/ba_module.md index f65d20f4..9df195ee 100644 --- a/docs/ba_module.md +++ b/docs/ba_module.md @@ -1,6 +1,6 @@ - -

last updated on 2019-11-21 for Ballistica version 1.5.0 build 20001

+ +

last updated on 2019-11-29 for Ballistica version 1.5.0 build 20001

This page documents the Python classes and functions in the 'ba' module, which are the ones most relevant to modding in Ballistica. If you come across something you feel should be included here or could be better explained, please let me know. Happy modding!


diff --git a/tools/cloudtool b/tools/cloudtool index fe4b47a1..d702bce4 100755 --- a/tools/cloudtool +++ b/tools/cloudtool @@ -27,13 +27,15 @@ from __future__ import annotations import sys import os +from enum import Enum +from pathlib import Path from typing import TYPE_CHECKING import urllib.request import urllib.parse import urllib.error from dataclasses import dataclass -from pathlib import Path import json +import subprocess if TYPE_CHECKING: from typing import Optional, Dict, Any @@ -60,8 +62,12 @@ CLREND = '\033[0m' # End. CMD_LOGIN = 'login' CMD_LOGOUT = 'logout' +CMD_PUTASSET = 'putasset' CMD_HELP = 'help' +ASSET_PATH_VALID_CHARS = 'abcdefghijklmnopqrstuvwxyz0123456789_' +ASSET_PATH_MAX_LENGTH = 128 + @dataclass class StateData: @@ -81,6 +87,74 @@ class CleanError(Exception): """Exception resulting in a clean error string print and exit.""" +class AssetType(Enum): + """Types for asset files.""" + TEXTURE = 'texture' + SOUND = 'sound' + + +class Asset: + """Data for a single asset.""" + + def __init__(self, assettype: AssetType) -> None: + self.assettype = assettype + print('INITING ASSET OF TYPE', assettype) + + +def validate_asset_path(path: str) -> None: + """Throw an exception on an invalid asset path.""" + names = path.split('/') + for name in names: + if not name: + raise CleanError(f'Found empty component in asset path "{path}".') + for char in name: + if char not in ASSET_PATH_VALID_CHARS: + raise CleanError( + f'Found invalid char "{char}" in asset path "{path}".') + + +class AssetBundle: + """Data for local or remote asset bundles.""" + + def __init__(self) -> None: + self.assets: Dict[str, Asset] = {} + + @classmethod + def load_from_disk(cls, path: Path) -> AssetBundle: + """Load an asset bundle from an existing one on disk.""" + import yaml + indexfilename = 'assetbundle.yaml' + bundle = AssetBundle() + + if not path.is_dir(): + raise CleanError(f'Directory not found: "{path}"') + + with open(Path(path, indexfilename)) as infile: + index = yaml.safe_load(infile) + if not isinstance(index, dict): + raise CleanError(f'Root dict not found in {indexfilename}') + assets = index.get('assets') + if not isinstance(assets, dict): + raise CleanError(f'No "assets" dict found in {indexfilename}') + for assetpath, assetdata in assets.items(): + validate_asset_path(assetpath) + if len(assetpath) > ASSET_PATH_MAX_LENGTH: + raise CleanError(f'Asset path is too long: "{assetpath}"') + if not isinstance(assetdata, dict): + raise CleanError( + f'Invalid asset data for {assetpath} in {indexfilename}') + assettypestr = assetdata.get('type') + if not isinstance(assettypestr, str): + raise CleanError( + f'Invalid asset type for {assetpath} in {indexfilename}') + assettype = AssetType(assettypestr) + + print('looking at', assetpath, assetdata) + bundle.assets[assetpath] = Asset(assettype) + + return bundle + + class App: """Context for a run of the tool.""" @@ -95,6 +169,14 @@ class App: raise CleanError( 'This tool must be run from ballistica project root.') + # Also run project prereqs checks so we can hopefully inform the user + # of missing python modules/etc. instead of just failing cryptically. + try: + subprocess.run(['make', '--quiet', 'prereqs'], check=True) + except subprocess.CalledProcessError: + raise CleanError('"make prereqs" check failed. ' + 'Install missing requirements and try again.') + self._load_cache() if len(sys.argv) < 2: @@ -106,6 +188,8 @@ class App: self.do_login() elif cmd == CMD_LOGOUT: self.do_logout() + elif cmd == CMD_PUTASSET: + self.do_putasset() else: # For all other commands, simply pass them to the server verbatim. self.do_misc_command() @@ -182,6 +266,15 @@ class App: self._state.login_token = None print(f'{CLRGRN}Cloudtool is now logged out.{CLREND}') + def do_putasset(self) -> None: + """Run a putasset command.""" + + if len(sys.argv) != 3: + raise CleanError('Expected a path to an assetpackage directory.') + + path = Path(sys.argv[2]) + _bundle = AssetBundle.load_from_disk(path) + def do_misc_command(self) -> None: """Run a miscellaneous command.""" diff --git a/tools/efrotools/code.py b/tools/efrotools/code.py index a747ce5c..976300c7 100644 --- a/tools/efrotools/code.py +++ b/tools/efrotools/code.py @@ -504,7 +504,8 @@ def _filter_module_name(mpath: str) -> str: return mpath[:-9] if mpath.endswith('.__init__') else mpath -def runmypy(filenames: List[str], full: bool = False, +def runmypy(filenames: List[str], + full: bool = False, check: bool = True) -> None: """Run MyPy on provided filenames.""" args = [ diff --git a/tools/snippets b/tools/snippets index 536fff9a..4ade4673 100755 --- a/tools/snippets +++ b/tools/snippets @@ -293,7 +293,7 @@ def gen_fulltest_buildfile_linux() -> None: dayoffset = datetime.datetime.now().timetuple().tm_yday targets = ['build', 'server-build'] - linflav = 'LINUX_FLAVOR=linux64-u19s' + linflav = 'LINUX_FLAVOR=u18s' lines = [] for target in targets: lines.append(f'{linflav} make linux-{target}') @@ -714,7 +714,7 @@ def checkenv() -> None: for modname, minver, packagename in [ ('pylint', [2, 4, 4], None), ('mypy', [0, 740], None), - ('yapf', [0, 28, 0], None), + ('yapf', [0, 29, 0], None), ('typing_extensions', None, None), ('pytz', None, None), ('yaml', None, 'PyYAML'),