mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-02-06 15:47:06 +08:00
Merge branch 'master' into pubsync
This commit is contained in:
commit
c0f55750db
@ -771,7 +771,10 @@ class App:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
# Ok, we're good to go.
|
# Ok, we're good to go.
|
||||||
self.coop_session_args = {'campaign': campaignname, 'level': levelname}
|
self.coop_session_args = {
|
||||||
|
'campaign': campaignname,
|
||||||
|
'level': levelname,
|
||||||
|
}
|
||||||
for arg_name, arg_val in list(args.items()):
|
for arg_name, arg_val in list(args.items()):
|
||||||
self.coop_session_args[arg_name] = arg_val
|
self.coop_session_args[arg_name] = arg_val
|
||||||
|
|
||||||
@ -782,8 +785,8 @@ class App:
|
|||||||
except Exception:
|
except Exception:
|
||||||
from ba import _error
|
from ba import _error
|
||||||
_error.print_exception()
|
_error.print_exception()
|
||||||
from bastd import mainmenu
|
from bastd.mainmenu import MainMenuSession
|
||||||
_ba.new_host_session(mainmenu.MainMenuSession)
|
_ba.new_host_session(MainMenuSession)
|
||||||
|
|
||||||
_ba.fade_screen(False, endcall=_fade_end)
|
_ba.fade_screen(False, endcall=_fade_end)
|
||||||
return True
|
return True
|
||||||
|
|||||||
@ -353,6 +353,7 @@ class CoopSession(Session):
|
|||||||
if results.get_score_type() in ('seconds', 'milliseconds',
|
if results.get_score_type() in ('seconds', 'milliseconds',
|
||||||
'time'):
|
'time'):
|
||||||
score_type = 'time'
|
score_type = 'time'
|
||||||
|
|
||||||
# Results contains milliseconds; ScoreScreen wants
|
# Results contains milliseconds; ScoreScreen wants
|
||||||
# hundredths; need to fix :-/
|
# hundredths; need to fix :-/
|
||||||
if score is not None:
|
if score is not None:
|
||||||
|
|||||||
@ -289,10 +289,10 @@ class GameActivity(Activity):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def supports_session_type(cls, sessiontype: Type[ba.Session]) -> bool:
|
def supports_session_type(cls, sessiontype: Type[ba.Session]) -> bool:
|
||||||
"""Return whether this game supports the provided Session type."""
|
"""Return whether this game supports the provided Session type."""
|
||||||
from ba import _teambasesession
|
from ba._teambasesession import TeamBaseSession
|
||||||
|
|
||||||
# By default, games support any versus mode
|
# By default, games support any versus mode
|
||||||
return issubclass(sessiontype, _teambasesession.TeamBaseSession)
|
return issubclass(sessiontype, TeamBaseSession)
|
||||||
|
|
||||||
def __init__(self, settings: Dict[str, Any]):
|
def __init__(self, settings: Dict[str, Any]):
|
||||||
"""Instantiate the Activity."""
|
"""Instantiate the Activity."""
|
||||||
@ -546,6 +546,7 @@ class GameActivity(Activity):
|
|||||||
|
|
||||||
self.end_game()
|
self.end_game()
|
||||||
|
|
||||||
|
# FIXME: this logic should live in the session classes.
|
||||||
def _game_begin_analytics(self) -> None:
|
def _game_begin_analytics(self) -> None:
|
||||||
"""Update analytics events for the start of the game."""
|
"""Update analytics events for the start of the game."""
|
||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
|
|||||||
@ -191,7 +191,7 @@ class TeamGameResults:
|
|||||||
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] = []
|
||||||
|
|||||||
@ -60,26 +60,29 @@ def filter_playlist(playlist: PlaylistType,
|
|||||||
unowned_game_types = set()
|
unowned_game_types = set()
|
||||||
|
|
||||||
for entry in copy.deepcopy(playlist):
|
for entry in copy.deepcopy(playlist):
|
||||||
# 'map' used to be called 'level' here
|
# 'map' used to be called 'level' here.
|
||||||
if 'level' in entry:
|
if 'level' in entry:
|
||||||
entry['map'] = entry['level']
|
entry['map'] = entry['level']
|
||||||
del entry['level']
|
del entry['level']
|
||||||
# we now stuff map into settings instead of it being its own thing
|
|
||||||
|
# We now stuff map into settings instead of it being its own thing.
|
||||||
if 'map' in entry:
|
if 'map' in entry:
|
||||||
entry['settings']['map'] = entry['map']
|
entry['settings']['map'] = entry['map']
|
||||||
del entry['map']
|
del entry['map']
|
||||||
# update old map names to new ones
|
|
||||||
|
# Update old map names to new ones.
|
||||||
entry['settings']['map'] = _map.get_filtered_map_name(
|
entry['settings']['map'] = _map.get_filtered_map_name(
|
||||||
entry['settings']['map'])
|
entry['settings']['map'])
|
||||||
if remove_unowned and entry['settings']['map'] in unowned_maps:
|
if remove_unowned and entry['settings']['map'] in unowned_maps:
|
||||||
continue
|
continue
|
||||||
# ok, for each game in our list, try to import the module and grab
|
|
||||||
|
# Ok, for each game in our list, try to import the module and grab
|
||||||
# the actual game class. add successful ones to our initial list
|
# the actual game class. add successful ones to our initial list
|
||||||
# to present to the user
|
# to present to the user.
|
||||||
if not isinstance(entry['type'], str):
|
if not isinstance(entry['type'], str):
|
||||||
raise Exception("invalid entry format")
|
raise Exception("invalid entry format")
|
||||||
try:
|
try:
|
||||||
# do some type filters for backwards compat.
|
# Do some type filters for backwards compat.
|
||||||
if entry['type'] in ('Assault.AssaultGame',
|
if entry['type'] in ('Assault.AssaultGame',
|
||||||
'Happy_Thoughts.HappyThoughtsGame',
|
'Happy_Thoughts.HappyThoughtsGame',
|
||||||
'bsAssault.AssaultGame',
|
'bsAssault.AssaultGame',
|
||||||
@ -147,7 +150,7 @@ def filter_playlist(playlist: PlaylistType,
|
|||||||
if mark_unowned and gameclass in unowned_game_types:
|
if mark_unowned and gameclass in unowned_game_types:
|
||||||
entry['is_unowned_game'] = True
|
entry['is_unowned_game'] = True
|
||||||
|
|
||||||
# make sure all settings the game defines are present
|
# Make sure all settings the game defines are present.
|
||||||
neededsettings = gameclass.get_settings(sessiontype)
|
neededsettings = gameclass.get_settings(sessiontype)
|
||||||
for setting_name, setting in neededsettings:
|
for setting_name, setting in neededsettings:
|
||||||
if (setting_name not in entry['settings']
|
if (setting_name not in entry['settings']
|
||||||
@ -164,6 +167,7 @@ def filter_playlist(playlist: PlaylistType,
|
|||||||
|
|
||||||
def get_default_free_for_all_playlist() -> PlaylistType:
|
def get_default_free_for_all_playlist() -> PlaylistType:
|
||||||
"""Return a default playlist for free-for-all mode."""
|
"""Return a default playlist for free-for-all mode."""
|
||||||
|
|
||||||
# NOTE: these are currently using old type/map names,
|
# NOTE: these are currently using old type/map names,
|
||||||
# but filtering translates them properly to the new ones.
|
# but filtering translates them properly to the new ones.
|
||||||
# (is kinda a handy way to ensure filtering is working).
|
# (is kinda a handy way to ensure filtering is working).
|
||||||
@ -177,8 +181,7 @@ def get_default_free_for_all_playlist() -> PlaylistType:
|
|||||||
'map': 'Doom Shroom'
|
'map': 'Doom Shroom'
|
||||||
},
|
},
|
||||||
'type': 'bs_death_match.DeathMatchGame'
|
'type': 'bs_death_match.DeathMatchGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Chosen One Gets Gloves': True,
|
'Chosen One Gets Gloves': True,
|
||||||
'Chosen One Gets Shield': False,
|
'Chosen One Gets Shield': False,
|
||||||
@ -189,8 +192,7 @@ def get_default_free_for_all_playlist() -> PlaylistType:
|
|||||||
'map': 'Monkey Face'
|
'map': 'Monkey Face'
|
||||||
},
|
},
|
||||||
'type': 'bs_chosen_one.ChosenOneGame'
|
'type': 'bs_chosen_one.ChosenOneGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Hold Time': 30,
|
'Hold Time': 30,
|
||||||
'Respawn Times': 1.0,
|
'Respawn Times': 1.0,
|
||||||
@ -198,15 +200,13 @@ def get_default_free_for_all_playlist() -> PlaylistType:
|
|||||||
'map': 'Zigzag'
|
'map': 'Zigzag'
|
||||||
},
|
},
|
||||||
'type': 'bs_king_of_the_hill.KingOfTheHillGame'
|
'type': 'bs_king_of_the_hill.KingOfTheHillGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Epic Mode': False,
|
'Epic Mode': False,
|
||||||
'map': 'Rampage'
|
'map': 'Rampage'
|
||||||
},
|
},
|
||||||
'type': 'bs_meteor_shower.MeteorShowerGame'
|
'type': 'bs_meteor_shower.MeteorShowerGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Epic Mode': 1,
|
'Epic Mode': 1,
|
||||||
'Lives Per Player': 1,
|
'Lives Per Player': 1,
|
||||||
@ -215,8 +215,7 @@ def get_default_free_for_all_playlist() -> PlaylistType:
|
|||||||
'map': 'Tip Top'
|
'map': 'Tip Top'
|
||||||
},
|
},
|
||||||
'type': 'bs_elimination.EliminationGame'
|
'type': 'bs_elimination.EliminationGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Hold Time': 30,
|
'Hold Time': 30,
|
||||||
'Respawn Times': 1.0,
|
'Respawn Times': 1.0,
|
||||||
@ -224,8 +223,7 @@ def get_default_free_for_all_playlist() -> PlaylistType:
|
|||||||
'map': 'The Pad'
|
'map': 'The Pad'
|
||||||
},
|
},
|
||||||
'type': 'bs_keep_away.KeepAwayGame'
|
'type': 'bs_keep_away.KeepAwayGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Epic Mode': True,
|
'Epic Mode': True,
|
||||||
'Kills to Win Per Player': 10,
|
'Kills to Win Per Player': 10,
|
||||||
@ -234,8 +232,7 @@ def get_default_free_for_all_playlist() -> PlaylistType:
|
|||||||
'map': 'Rampage'
|
'map': 'Rampage'
|
||||||
},
|
},
|
||||||
'type': 'bs_death_match.DeathMatchGame'
|
'type': 'bs_death_match.DeathMatchGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Bomb Spawning': 1000,
|
'Bomb Spawning': 1000,
|
||||||
'Epic Mode': False,
|
'Epic Mode': False,
|
||||||
@ -246,8 +243,7 @@ def get_default_free_for_all_playlist() -> PlaylistType:
|
|||||||
'map': 'Big G'
|
'map': 'Big G'
|
||||||
},
|
},
|
||||||
'type': 'bs_race.RaceGame'
|
'type': 'bs_race.RaceGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Hold Time': 30,
|
'Hold Time': 30,
|
||||||
'Respawn Times': 1.0,
|
'Respawn Times': 1.0,
|
||||||
@ -255,8 +251,7 @@ def get_default_free_for_all_playlist() -> PlaylistType:
|
|||||||
'map': 'Happy Thoughts'
|
'map': 'Happy Thoughts'
|
||||||
},
|
},
|
||||||
'type': 'bs_king_of_the_hill.KingOfTheHillGame'
|
'type': 'bs_king_of_the_hill.KingOfTheHillGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Enable Impact Bombs': 1,
|
'Enable Impact Bombs': 1,
|
||||||
'Enable Triple Bombs': False,
|
'Enable Triple Bombs': False,
|
||||||
@ -264,8 +259,7 @@ def get_default_free_for_all_playlist() -> PlaylistType:
|
|||||||
'map': 'Doom Shroom'
|
'map': 'Doom Shroom'
|
||||||
},
|
},
|
||||||
'type': 'bs_target_practice.TargetPracticeGame'
|
'type': 'bs_target_practice.TargetPracticeGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Epic Mode': False,
|
'Epic Mode': False,
|
||||||
'Lives Per Player': 5,
|
'Lives Per Player': 5,
|
||||||
@ -274,8 +268,7 @@ def get_default_free_for_all_playlist() -> PlaylistType:
|
|||||||
'map': 'Step Right Up'
|
'map': 'Step Right Up'
|
||||||
},
|
},
|
||||||
'type': 'bs_elimination.EliminationGame'
|
'type': 'bs_elimination.EliminationGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Epic Mode': False,
|
'Epic Mode': False,
|
||||||
'Kills to Win Per Player': 10,
|
'Kills to Win Per Player': 10,
|
||||||
@ -284,8 +277,7 @@ def get_default_free_for_all_playlist() -> PlaylistType:
|
|||||||
'map': 'Crag Castle'
|
'map': 'Crag Castle'
|
||||||
},
|
},
|
||||||
'type': 'bs_death_match.DeathMatchGame'
|
'type': 'bs_death_match.DeathMatchGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'map': 'Lake Frigid',
|
'map': 'Lake Frigid',
|
||||||
'settings': {
|
'settings': {
|
||||||
'Bomb Spawning': 0,
|
'Bomb Spawning': 0,
|
||||||
@ -296,7 +288,7 @@ def get_default_free_for_all_playlist() -> PlaylistType:
|
|||||||
'map': 'Lake Frigid'
|
'map': 'Lake Frigid'
|
||||||
},
|
},
|
||||||
'type': 'bs_race.RaceGame'
|
'type': 'bs_race.RaceGame'
|
||||||
}] # yapf: disable
|
}]
|
||||||
|
|
||||||
|
|
||||||
def get_default_teams_playlist() -> PlaylistType:
|
def get_default_teams_playlist() -> PlaylistType:
|
||||||
@ -317,8 +309,7 @@ def get_default_teams_playlist() -> PlaylistType:
|
|||||||
'map': 'Bridgit'
|
'map': 'Bridgit'
|
||||||
},
|
},
|
||||||
'type': 'bs_capture_the_flag.CTFGame'
|
'type': 'bs_capture_the_flag.CTFGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Epic Mode': False,
|
'Epic Mode': False,
|
||||||
'Respawn Times': 1.0,
|
'Respawn Times': 1.0,
|
||||||
@ -327,8 +318,7 @@ def get_default_teams_playlist() -> PlaylistType:
|
|||||||
'map': 'Step Right Up'
|
'map': 'Step Right Up'
|
||||||
},
|
},
|
||||||
'type': 'bs_assault.AssaultGame'
|
'type': 'bs_assault.AssaultGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Balance Total Lives': False,
|
'Balance Total Lives': False,
|
||||||
'Epic Mode': False,
|
'Epic Mode': False,
|
||||||
@ -339,8 +329,7 @@ def get_default_teams_playlist() -> PlaylistType:
|
|||||||
'map': 'Rampage'
|
'map': 'Rampage'
|
||||||
},
|
},
|
||||||
'type': 'bs_elimination.EliminationGame'
|
'type': 'bs_elimination.EliminationGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Epic Mode': False,
|
'Epic Mode': False,
|
||||||
'Kills to Win Per Player': 5,
|
'Kills to Win Per Player': 5,
|
||||||
@ -349,8 +338,7 @@ def get_default_teams_playlist() -> PlaylistType:
|
|||||||
'map': 'Roundabout'
|
'map': 'Roundabout'
|
||||||
},
|
},
|
||||||
'type': 'bs_death_match.DeathMatchGame'
|
'type': 'bs_death_match.DeathMatchGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Respawn Times': 1.0,
|
'Respawn Times': 1.0,
|
||||||
'Score to Win': 1,
|
'Score to Win': 1,
|
||||||
@ -358,8 +346,7 @@ def get_default_teams_playlist() -> PlaylistType:
|
|||||||
'map': 'Hockey Stadium'
|
'map': 'Hockey Stadium'
|
||||||
},
|
},
|
||||||
'type': 'bs_hockey.HockeyGame'
|
'type': 'bs_hockey.HockeyGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Hold Time': 30,
|
'Hold Time': 30,
|
||||||
'Respawn Times': 1.0,
|
'Respawn Times': 1.0,
|
||||||
@ -367,8 +354,7 @@ def get_default_teams_playlist() -> PlaylistType:
|
|||||||
'map': 'Monkey Face'
|
'map': 'Monkey Face'
|
||||||
},
|
},
|
||||||
'type': 'bs_keep_away.KeepAwayGame'
|
'type': 'bs_keep_away.KeepAwayGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Balance Total Lives': False,
|
'Balance Total Lives': False,
|
||||||
'Epic Mode': True,
|
'Epic Mode': True,
|
||||||
@ -379,8 +365,7 @@ def get_default_teams_playlist() -> PlaylistType:
|
|||||||
'map': 'Tip Top'
|
'map': 'Tip Top'
|
||||||
},
|
},
|
||||||
'type': 'bs_elimination.EliminationGame'
|
'type': 'bs_elimination.EliminationGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Epic Mode': False,
|
'Epic Mode': False,
|
||||||
'Respawn Times': 1.0,
|
'Respawn Times': 1.0,
|
||||||
@ -389,8 +374,7 @@ def get_default_teams_playlist() -> PlaylistType:
|
|||||||
'map': 'Crag Castle'
|
'map': 'Crag Castle'
|
||||||
},
|
},
|
||||||
'type': 'bs_assault.AssaultGame'
|
'type': 'bs_assault.AssaultGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Epic Mode': False,
|
'Epic Mode': False,
|
||||||
'Kills to Win Per Player': 5,
|
'Kills to Win Per Player': 5,
|
||||||
@ -399,15 +383,13 @@ def get_default_teams_playlist() -> PlaylistType:
|
|||||||
'map': 'Doom Shroom'
|
'map': 'Doom Shroom'
|
||||||
},
|
},
|
||||||
'type': 'bs_death_match.DeathMatchGame'
|
'type': 'bs_death_match.DeathMatchGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Epic Mode': False,
|
'Epic Mode': False,
|
||||||
'map': 'Rampage'
|
'map': 'Rampage'
|
||||||
},
|
},
|
||||||
'type': 'bs_meteor_shower.MeteorShowerGame'
|
'type': 'bs_meteor_shower.MeteorShowerGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Epic Mode': False,
|
'Epic Mode': False,
|
||||||
'Flag Idle Return Time': 30,
|
'Flag Idle Return Time': 30,
|
||||||
@ -418,8 +400,7 @@ def get_default_teams_playlist() -> PlaylistType:
|
|||||||
'map': 'Roundabout'
|
'map': 'Roundabout'
|
||||||
},
|
},
|
||||||
'type': 'bs_capture_the_flag.CTFGame'
|
'type': 'bs_capture_the_flag.CTFGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Respawn Times': 1.0,
|
'Respawn Times': 1.0,
|
||||||
'Score to Win': 21,
|
'Score to Win': 21,
|
||||||
@ -427,8 +408,7 @@ def get_default_teams_playlist() -> PlaylistType:
|
|||||||
'map': 'Football Stadium'
|
'map': 'Football Stadium'
|
||||||
},
|
},
|
||||||
'type': 'bs_football.FootballTeamGame'
|
'type': 'bs_football.FootballTeamGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Epic Mode': True,
|
'Epic Mode': True,
|
||||||
'Respawn Times': 0.25,
|
'Respawn Times': 0.25,
|
||||||
@ -437,8 +417,7 @@ def get_default_teams_playlist() -> PlaylistType:
|
|||||||
'map': 'Bridgit'
|
'map': 'Bridgit'
|
||||||
},
|
},
|
||||||
'type': 'bs_assault.AssaultGame'
|
'type': 'bs_assault.AssaultGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'map': 'Doom Shroom',
|
'map': 'Doom Shroom',
|
||||||
'settings': {
|
'settings': {
|
||||||
'Enable Impact Bombs': 1,
|
'Enable Impact Bombs': 1,
|
||||||
@ -447,8 +426,7 @@ def get_default_teams_playlist() -> PlaylistType:
|
|||||||
'map': 'Doom Shroom'
|
'map': 'Doom Shroom'
|
||||||
},
|
},
|
||||||
'type': 'bs_target_practice.TargetPracticeGame'
|
'type': 'bs_target_practice.TargetPracticeGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Hold Time': 30,
|
'Hold Time': 30,
|
||||||
'Respawn Times': 1.0,
|
'Respawn Times': 1.0,
|
||||||
@ -456,8 +434,7 @@ def get_default_teams_playlist() -> PlaylistType:
|
|||||||
'map': 'Tip Top'
|
'map': 'Tip Top'
|
||||||
},
|
},
|
||||||
'type': 'bs_king_of_the_hill.KingOfTheHillGame'
|
'type': 'bs_king_of_the_hill.KingOfTheHillGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Epic Mode': False,
|
'Epic Mode': False,
|
||||||
'Respawn Times': 1.0,
|
'Respawn Times': 1.0,
|
||||||
@ -466,8 +443,7 @@ def get_default_teams_playlist() -> PlaylistType:
|
|||||||
'map': 'Zigzag'
|
'map': 'Zigzag'
|
||||||
},
|
},
|
||||||
'type': 'bs_assault.AssaultGame'
|
'type': 'bs_assault.AssaultGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Epic Mode': False,
|
'Epic Mode': False,
|
||||||
'Flag Idle Return Time': 30,
|
'Flag Idle Return Time': 30,
|
||||||
@ -478,8 +454,7 @@ def get_default_teams_playlist() -> PlaylistType:
|
|||||||
'map': 'Happy Thoughts'
|
'map': 'Happy Thoughts'
|
||||||
},
|
},
|
||||||
'type': 'bs_capture_the_flag.CTFGame'
|
'type': 'bs_capture_the_flag.CTFGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Bomb Spawning': 1000,
|
'Bomb Spawning': 1000,
|
||||||
'Epic Mode': True,
|
'Epic Mode': True,
|
||||||
@ -489,8 +464,7 @@ def get_default_teams_playlist() -> PlaylistType:
|
|||||||
'map': 'Big G'
|
'map': 'Big G'
|
||||||
},
|
},
|
||||||
'type': 'bs_race.RaceGame'
|
'type': 'bs_race.RaceGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Epic Mode': False,
|
'Epic Mode': False,
|
||||||
'Kills to Win Per Player': 5,
|
'Kills to Win Per Player': 5,
|
||||||
@ -499,8 +473,7 @@ def get_default_teams_playlist() -> PlaylistType:
|
|||||||
'map': 'Monkey Face'
|
'map': 'Monkey Face'
|
||||||
},
|
},
|
||||||
'type': 'bs_death_match.DeathMatchGame'
|
'type': 'bs_death_match.DeathMatchGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Hold Time': 30,
|
'Hold Time': 30,
|
||||||
'Respawn Times': 1.0,
|
'Respawn Times': 1.0,
|
||||||
@ -508,8 +481,7 @@ def get_default_teams_playlist() -> PlaylistType:
|
|||||||
'map': 'Lake Frigid'
|
'map': 'Lake Frigid'
|
||||||
},
|
},
|
||||||
'type': 'bs_keep_away.KeepAwayGame'
|
'type': 'bs_keep_away.KeepAwayGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Epic Mode': False,
|
'Epic Mode': False,
|
||||||
'Flag Idle Return Time': 30,
|
'Flag Idle Return Time': 30,
|
||||||
@ -520,8 +492,7 @@ def get_default_teams_playlist() -> PlaylistType:
|
|||||||
'map': 'Tip Top'
|
'map': 'Tip Top'
|
||||||
},
|
},
|
||||||
'type': 'bs_capture_the_flag.CTFGame'
|
'type': 'bs_capture_the_flag.CTFGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Balance Total Lives': False,
|
'Balance Total Lives': False,
|
||||||
'Epic Mode': False,
|
'Epic Mode': False,
|
||||||
@ -532,8 +503,7 @@ def get_default_teams_playlist() -> PlaylistType:
|
|||||||
'map': 'Crag Castle'
|
'map': 'Crag Castle'
|
||||||
},
|
},
|
||||||
'type': 'bs_elimination.EliminationGame'
|
'type': 'bs_elimination.EliminationGame'
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
'settings': {
|
'settings': {
|
||||||
'Epic Mode': True,
|
'Epic Mode': True,
|
||||||
'Respawn Times': 0.25,
|
'Respawn Times': 0.25,
|
||||||
@ -541,4 +511,4 @@ def get_default_teams_playlist() -> PlaylistType:
|
|||||||
'map': 'Zigzag'
|
'map': 'Zigzag'
|
||||||
},
|
},
|
||||||
'type': 'bs_conquest.ConquestGame'
|
'type': 'bs_conquest.ConquestGame'
|
||||||
}] # yapf: disable
|
}]
|
||||||
|
|||||||
@ -75,13 +75,14 @@ class Session:
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Annotate our attrs at class level so they're available for introspection.
|
# Note: even though these are instance vars, we annotate them at the
|
||||||
teams: List[ba.Team]
|
# class level so that docs generation can access their types.
|
||||||
campaign: Optional[ba.Campaign]
|
campaign: Optional[ba.Campaign]
|
||||||
lobby: ba.Lobby
|
lobby: ba.Lobby
|
||||||
min_players: int
|
|
||||||
max_players: int
|
max_players: int
|
||||||
|
min_players: int
|
||||||
players: List[ba.Player]
|
players: List[ba.Player]
|
||||||
|
teams: List[ba.Team]
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
depsets: Sequence[ba.DependencySet],
|
depsets: Sequence[ba.DependencySet],
|
||||||
@ -97,7 +98,6 @@ class Session:
|
|||||||
instances; one for each ba.Activity the session may potentially run.
|
instances; one for each ba.Activity the session may potentially run.
|
||||||
"""
|
"""
|
||||||
# pylint: disable=too-many-statements
|
# pylint: disable=too-many-statements
|
||||||
# pylint: disable=too-many-branches
|
|
||||||
# pylint: disable=too-many-locals
|
# pylint: disable=too-many-locals
|
||||||
# pylint: disable=cyclic-import
|
# pylint: disable=cyclic-import
|
||||||
from ba._lobby import Lobby
|
from ba._lobby import Lobby
|
||||||
@ -108,26 +108,23 @@ class Session:
|
|||||||
from ba._error import DependencyError
|
from ba._error import DependencyError
|
||||||
from ba._dependency import Dependency, AssetPackage
|
from ba._dependency import Dependency, AssetPackage
|
||||||
|
|
||||||
# print(' WOULD LOOK AT DEP SETS', depsets)
|
# First off, resolve all dependency-sets we were passed.
|
||||||
|
# If things are missing, we'll try to gather them into a single
|
||||||
# first off, resolve all dep-sets we were passed.
|
# missing-deps exception if possible to give the caller a clean
|
||||||
# if things are missing, we'll try to gather them into
|
# path to download missing stuff and try again.
|
||||||
# a single missing-deps exception if possible
|
|
||||||
# to give the caller a clean path to download missing
|
|
||||||
# stuff and try again.
|
|
||||||
missing_asset_packages: Set[str] = set()
|
missing_asset_packages: Set[str] = set()
|
||||||
for depset in depsets:
|
for depset in depsets:
|
||||||
try:
|
try:
|
||||||
depset.resolve()
|
depset.resolve()
|
||||||
except DependencyError as exc:
|
except DependencyError as exc:
|
||||||
# we gather/report missing assets only; barf on anything else
|
# Gather/report missing assets only; barf on anything else.
|
||||||
if all(issubclass(d.cls, AssetPackage) for d in exc.deps):
|
if all(issubclass(d.cls, AssetPackage) for d in exc.deps):
|
||||||
for dep in exc.deps:
|
for dep in exc.deps:
|
||||||
assert isinstance(dep.config, str)
|
assert isinstance(dep.config, str)
|
||||||
missing_asset_packages.add(dep.config)
|
missing_asset_packages.add(dep.config)
|
||||||
else:
|
else:
|
||||||
missing_info = [(d.cls, d.config) for d in exc.deps]
|
missing_info = [(d.cls, d.config) for d in exc.deps]
|
||||||
raise Exception(
|
raise RuntimeError(
|
||||||
f'Missing non-asset dependencies: {missing_info}')
|
f'Missing non-asset dependencies: {missing_info}')
|
||||||
|
|
||||||
# Throw a combined exception if we found anything missing.
|
# Throw a combined exception if we found anything missing.
|
||||||
@ -146,11 +143,6 @@ class Session:
|
|||||||
# print('Would set host-session asset-reqs to:',
|
# print('Would set host-session asset-reqs to:',
|
||||||
# required_asset_packages)
|
# required_asset_packages)
|
||||||
|
|
||||||
if team_names is None:
|
|
||||||
team_names = ['Good Guys']
|
|
||||||
if team_colors is None:
|
|
||||||
team_colors = [(0.6, 0.2, 1.0)]
|
|
||||||
|
|
||||||
# First thing, wire up our internal engine data.
|
# First thing, wire up our internal engine data.
|
||||||
self._sessiondata = _ba.register_session(self)
|
self._sessiondata = _ba.register_session(self)
|
||||||
|
|
||||||
@ -159,8 +151,8 @@ class Session:
|
|||||||
# FIXME: This stuff shouldn't be here.
|
# FIXME: This stuff shouldn't be here.
|
||||||
self.sharedobjs: Dict[str, Any] = {}
|
self.sharedobjs: Dict[str, Any] = {}
|
||||||
|
|
||||||
# TeamGameActivity uses this to display a help overlay on
|
# TeamGameActivity uses this to display a help overlay on the first
|
||||||
# the first activity only.
|
# activity only.
|
||||||
self.have_shown_controls_help_overlay = False
|
self.have_shown_controls_help_overlay = False
|
||||||
|
|
||||||
self.campaign = None
|
self.campaign = None
|
||||||
@ -186,9 +178,8 @@ class Session:
|
|||||||
|
|
||||||
self._activity_weak: ReferenceType[ba.Activity]
|
self._activity_weak: ReferenceType[ba.Activity]
|
||||||
self._activity_weak = weakref.ref(_EmptyObj()) # type: ignore
|
self._activity_weak = weakref.ref(_EmptyObj()) # type: ignore
|
||||||
|
|
||||||
if self._activity_weak() is not None:
|
if self._activity_weak() is not None:
|
||||||
raise Exception("error creating empty weak ref")
|
raise Exception("Error creating empty activity weak ref.")
|
||||||
|
|
||||||
self._next_activity: Optional[ba.Activity] = None
|
self._next_activity: Optional[ba.Activity] = None
|
||||||
self.wants_to_end = False
|
self.wants_to_end = False
|
||||||
@ -196,7 +187,10 @@ class Session:
|
|||||||
self.min_players = min_players
|
self.min_players = min_players
|
||||||
self.max_players = max_players
|
self.max_players = max_players
|
||||||
|
|
||||||
|
# Create Teams.
|
||||||
if self._use_teams:
|
if self._use_teams:
|
||||||
|
assert team_names is not None
|
||||||
|
assert team_colors is not None
|
||||||
for i, color in enumerate(team_colors):
|
for i, color in enumerate(team_colors):
|
||||||
team = Team(team_id=self._next_team_id,
|
team = Team(team_id=self._next_team_id,
|
||||||
name=GameActivity.get_team_display_string(
|
name=GameActivity.get_team_display_string(
|
||||||
@ -210,8 +204,8 @@ class Session:
|
|||||||
self.on_team_join(team)
|
self.on_team_join(team)
|
||||||
except Exception:
|
except Exception:
|
||||||
from ba import _error
|
from ba import _error
|
||||||
_error.print_exception('exception in on_team_join for',
|
_error.print_exception(
|
||||||
self)
|
f'Error in on_team_join for {self}.')
|
||||||
|
|
||||||
self.lobby = Lobby()
|
self.lobby = Lobby()
|
||||||
self.stats = Stats()
|
self.stats = Stats()
|
||||||
@ -242,8 +236,8 @@ class Session:
|
|||||||
|
|
||||||
if len(self.players) >= self.max_players:
|
if len(self.players) >= self.max_players:
|
||||||
|
|
||||||
# Print a rejection message *only* to the client trying to join
|
# Print a rejection message *only* to the client trying to
|
||||||
# (prevents spamming everyone else in the game).
|
# join (prevents spamming everyone else in the game).
|
||||||
_ba.playsound(_ba.getsound('error'))
|
_ba.playsound(_ba.getsound('error'))
|
||||||
_ba.screenmessage(
|
_ba.screenmessage(
|
||||||
Lstr(resource='playerLimitReachedText',
|
Lstr(resource='playerLimitReachedText',
|
||||||
@ -291,7 +285,7 @@ class Session:
|
|||||||
_error.print_exception(
|
_error.print_exception(
|
||||||
'Error in Lobby.remove_chooser()')
|
'Error in Lobby.remove_chooser()')
|
||||||
|
|
||||||
# *if* he was actually in the game, announce his departure
|
# *If* they were actually in the game, announce their departure.
|
||||||
if team is not None:
|
if team is not None:
|
||||||
_ba.screenmessage(
|
_ba.screenmessage(
|
||||||
Lstr(resource='playerLeftText',
|
Lstr(resource='playerLeftText',
|
||||||
@ -302,7 +296,7 @@ class Session:
|
|||||||
# team lists every activity)
|
# team lists every activity)
|
||||||
if team is not None and player in team.players:
|
if team is not None and player in team.players:
|
||||||
|
|
||||||
# Testing.. can remove this eventually.
|
# Testing; can remove this eventually.
|
||||||
if isinstance(self, FreeForAllSession):
|
if isinstance(self, FreeForAllSession):
|
||||||
if len(team.players) != 1:
|
if len(team.players) != 1:
|
||||||
_error.print_error("expected 1 player in FFA team")
|
_error.print_error("expected 1 player in FFA team")
|
||||||
@ -328,7 +322,7 @@ class Session:
|
|||||||
player.set_activity(None)
|
player.set_activity(None)
|
||||||
player.set_node(None)
|
player.set_node(None)
|
||||||
|
|
||||||
# reset the player - this will remove its actor-ref and clear
|
# Reset the player; this will remove its actor-ref and clear
|
||||||
# its calls/etc
|
# its calls/etc
|
||||||
try:
|
try:
|
||||||
with _ba.Context(activity):
|
with _ba.Context(activity):
|
||||||
@ -377,6 +371,7 @@ class Session:
|
|||||||
except Exception:
|
except Exception:
|
||||||
_error.print_exception(
|
_error.print_exception(
|
||||||
'exception in on_team_leave for session', self)
|
'exception in on_team_leave for session', self)
|
||||||
|
|
||||||
# Clear the team's session-data (so dying stuff will
|
# Clear the team's session-data (so dying stuff will
|
||||||
# have proper context).
|
# have proper context).
|
||||||
try:
|
try:
|
||||||
@ -454,20 +449,22 @@ class Session:
|
|||||||
"""
|
"""
|
||||||
from ba._general import Call
|
from ba._general import Call
|
||||||
from ba._enums import TimeType
|
from ba._enums import TimeType
|
||||||
# only pay attention if this is coming from our current activity..
|
|
||||||
|
# Only pay attention if this is coming from our current activity.
|
||||||
if activity is not self._activity_retained:
|
if activity is not self._activity_retained:
|
||||||
return
|
return
|
||||||
|
|
||||||
# if this activity hasn't begun yet, just set it up to end immediately
|
# If this activity hasn't begun yet, just set it up to end immediately
|
||||||
# once it does
|
# once it does.
|
||||||
if not activity.has_begun():
|
if not activity.has_begun():
|
||||||
activity.set_immediate_end(results, delay, force)
|
activity.set_immediate_end(results, delay, force)
|
||||||
|
|
||||||
# the activity has already begun; get ready to end it..
|
# The activity has already begun; get ready to end it.
|
||||||
else:
|
else:
|
||||||
if (not activity.has_ended()) or force:
|
if (not activity.has_ended()) or force:
|
||||||
activity.set_has_ended(True)
|
activity.set_has_ended(True)
|
||||||
# set a timer to set in motion this activity's demise
|
|
||||||
|
# Set a timer to set in motion this activity's demise.
|
||||||
self._activity_end_timer = _ba.Timer(
|
self._activity_end_timer = _ba.Timer(
|
||||||
delay,
|
delay,
|
||||||
Call(self._complete_end_activity, activity, results),
|
Call(self._complete_end_activity, activity, results),
|
||||||
@ -483,8 +480,8 @@ class Session:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
if isinstance(msg, PlayerProfilesChangedMessage):
|
if isinstance(msg, PlayerProfilesChangedMessage):
|
||||||
# if we have a current activity with a lobby, ask it to
|
# If we have a current activity with a lobby, ask it to reload
|
||||||
# reload profiles
|
# profiles.
|
||||||
with _ba.Context(self):
|
with _ba.Context(self):
|
||||||
self.lobby.reload_profiles()
|
self.lobby.reload_profiles()
|
||||||
return None
|
return None
|
||||||
@ -511,7 +508,7 @@ class Session:
|
|||||||
"Session.set_activity() cannot be called recursively.")
|
"Session.set_activity() cannot be called recursively.")
|
||||||
|
|
||||||
if activity.session is not _ba.getsession():
|
if activity.session is not _ba.getsession():
|
||||||
raise Exception("provided activity's session is not current")
|
raise Exception("Provided Activity's Session is not current.")
|
||||||
|
|
||||||
# Quietly ignore this if the whole session is going down.
|
# Quietly ignore this if the whole session is going down.
|
||||||
if self._ending:
|
if self._ending:
|
||||||
@ -574,7 +571,7 @@ class Session:
|
|||||||
prev_activity._transitioning_out = True
|
prev_activity._transitioning_out = True
|
||||||
# pylint: enable=protected-access
|
# pylint: enable=protected-access
|
||||||
|
|
||||||
# activity will be None until the next one begins.
|
# Activity will be None until the next one begins.
|
||||||
with _ba.Context(prev_activity):
|
with _ba.Context(prev_activity):
|
||||||
prev_activity.on_transition_out()
|
prev_activity.on_transition_out()
|
||||||
|
|
||||||
@ -613,6 +610,7 @@ class Session:
|
|||||||
_ba.timer(activity.transition_time,
|
_ba.timer(activity.transition_time,
|
||||||
prev_activity._destroy,
|
prev_activity._destroy,
|
||||||
timetype=TimeType.REAL)
|
timetype=TimeType.REAL)
|
||||||
|
|
||||||
# Just run immediately.
|
# Just run immediately.
|
||||||
else:
|
else:
|
||||||
# noinspection PyProtectedMember
|
# noinspection PyProtectedMember
|
||||||
@ -720,6 +718,7 @@ class Session:
|
|||||||
_ba.playsound(_ba.getsound('error'))
|
_ba.playsound(_ba.getsound('error'))
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Otherwise just add players on the fly.
|
# Otherwise just add players on the fly.
|
||||||
else:
|
else:
|
||||||
self._add_chosen_player(chooser)
|
self._add_chosen_player(chooser)
|
||||||
|
|||||||
@ -53,7 +53,7 @@ class TeamBaseSession(Session):
|
|||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
"""Set up playlists and launches a ba.Activity to accept joiners."""
|
"""Set up playlists and launches a ba.Activity to accept joiners."""
|
||||||
# pylint: disable=cyclic-import
|
# pylint: disable=cyclic-import
|
||||||
from ba import _playlist as bsplaylist
|
from ba import _playlist
|
||||||
from bastd.activity import multiteamjoinscreen
|
from bastd.activity import multiteamjoinscreen
|
||||||
app = _ba.app
|
app = _ba.app
|
||||||
cfg = app.config
|
cfg = app.config
|
||||||
@ -67,6 +67,7 @@ class TeamBaseSession(Session):
|
|||||||
|
|
||||||
# print('FIXME: TEAM BASE SESSION WOULD CALC DEPS.')
|
# print('FIXME: TEAM BASE SESSION WOULD CALC DEPS.')
|
||||||
depsets: Sequence[ba.DependencySet] = []
|
depsets: Sequence[ba.DependencySet] = []
|
||||||
|
|
||||||
super().__init__(depsets,
|
super().__init__(depsets,
|
||||||
team_names=team_names,
|
team_names=team_names,
|
||||||
team_colors=team_colors,
|
team_colors=team_colors,
|
||||||
@ -100,22 +101,23 @@ class TeamBaseSession(Session):
|
|||||||
|
|
||||||
if (self._playlist_name != '__default__'
|
if (self._playlist_name != '__default__'
|
||||||
and self._playlist_name in playlists):
|
and self._playlist_name in playlists):
|
||||||
|
|
||||||
# Make sure to copy this, as we muck with it in place once we've
|
# Make sure to copy this, as we muck with it in place once we've
|
||||||
# got it and we don't want that to affect our config.
|
# got it and we don't want that to affect our config.
|
||||||
playlist = copy.deepcopy(playlists[self._playlist_name])
|
playlist = copy.deepcopy(playlists[self._playlist_name])
|
||||||
else:
|
else:
|
||||||
if self._use_teams:
|
if self._use_teams:
|
||||||
playlist = bsplaylist.get_default_teams_playlist()
|
playlist = _playlist.get_default_teams_playlist()
|
||||||
else:
|
else:
|
||||||
playlist = bsplaylist.get_default_free_for_all_playlist()
|
playlist = _playlist.get_default_free_for_all_playlist()
|
||||||
|
|
||||||
# Resolve types and whatnot to get our final playlist.
|
# Resolve types and whatnot to get our final playlist.
|
||||||
playlist_resolved = bsplaylist.filter_playlist(playlist,
|
playlist_resolved = _playlist.filter_playlist(playlist,
|
||||||
sessiontype=type(self),
|
sessiontype=type(self),
|
||||||
add_resolved_type=True)
|
add_resolved_type=True)
|
||||||
|
|
||||||
if not playlist_resolved:
|
if not playlist_resolved:
|
||||||
raise Exception("playlist contains no valid games")
|
raise RuntimeError("Playlist contains no valid games.")
|
||||||
|
|
||||||
self._playlist = ShuffleList(playlist_resolved,
|
self._playlist = ShuffleList(playlist_resolved,
|
||||||
shuffle=self._playlist_randomize)
|
shuffle=self._playlist_randomize)
|
||||||
@ -176,22 +178,21 @@ class TeamBaseSession(Session):
|
|||||||
TeamSeriesVictoryScoreScreenActivity)
|
TeamSeriesVictoryScoreScreenActivity)
|
||||||
from ba import _activitytypes
|
from ba import _activitytypes
|
||||||
|
|
||||||
# If we have a tutorial to show,
|
# If we have a tutorial to show, that's the first thing we do no
|
||||||
# that's the first thing we do no matter what.
|
# matter what.
|
||||||
if self._tutorial_activity_instance is not None:
|
if self._tutorial_activity_instance is not None:
|
||||||
self.set_activity(self._tutorial_activity_instance)
|
self.set_activity(self._tutorial_activity_instance)
|
||||||
self._tutorial_activity_instance = None
|
self._tutorial_activity_instance = None
|
||||||
|
|
||||||
# If we're leaving the tutorial activity,
|
# If we're leaving the tutorial activity, pop a transition activity
|
||||||
# pop a transition activity to transition
|
# to transition us into a round gracefully (otherwise we'd snap from
|
||||||
# us into a round gracefully (otherwise we'd
|
# one terrain to another instantly).
|
||||||
# snap from one terrain to another instantly).
|
|
||||||
elif isinstance(activity, TutorialActivity):
|
elif isinstance(activity, TutorialActivity):
|
||||||
self.set_activity(
|
self.set_activity(
|
||||||
_ba.new_activity(_activitytypes.TransitionActivity))
|
_ba.new_activity(_activitytypes.TransitionActivity))
|
||||||
|
|
||||||
# If we're in a between-round activity or a restart-activity,
|
# If we're in a between-round activity or a restart-activity, hop
|
||||||
# hop into a round.
|
# into a round.
|
||||||
elif isinstance(
|
elif isinstance(
|
||||||
activity,
|
activity,
|
||||||
(_activitytypes.JoiningActivity, _activitytypes.TransitionActivity,
|
(_activitytypes.JoiningActivity, _activitytypes.TransitionActivity,
|
||||||
@ -203,6 +204,7 @@ class TeamBaseSession(Session):
|
|||||||
self._game_number = 0
|
self._game_number = 0
|
||||||
for team in self.teams:
|
for team in self.teams:
|
||||||
team.sessiondata['score'] = 0
|
team.sessiondata['score'] = 0
|
||||||
|
|
||||||
# Otherwise just set accum (per-game) scores.
|
# Otherwise just set accum (per-game) scores.
|
||||||
else:
|
else:
|
||||||
self.stats.reset_accum()
|
self.stats.reset_accum()
|
||||||
@ -216,7 +218,7 @@ class TeamBaseSession(Session):
|
|||||||
# Instantiate the next now so they have plenty of time to load.
|
# Instantiate the next now so they have plenty of time to load.
|
||||||
self._instantiate_next_game()
|
self._instantiate_next_game()
|
||||||
|
|
||||||
# (re)register all players and wire stats to our next activity
|
# (Re)register all players and wire stats to our next activity.
|
||||||
for player in self.players:
|
for player in self.players:
|
||||||
# ..but only ones who have been placed on a team
|
# ..but only ones who have been placed on a team
|
||||||
# (ie: no longer sitting in the lobby).
|
# (ie: no longer sitting in the lobby).
|
||||||
@ -321,6 +323,7 @@ class ShuffleList:
|
|||||||
continue
|
continue
|
||||||
if test_obj['type'] == self.last_gotten['type']:
|
if test_obj['type'] == self.last_gotten['type']:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Sufficiently different; lets go with it.
|
# Sufficiently different; lets go with it.
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
@ -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)
|
||||||
@ -923,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'.
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -290,6 +290,9 @@ class CaptureTheFlagGame(ba.TeamGameActivity):
|
|||||||
if (not team.gamedata['home_flag_at_base']
|
if (not team.gamedata['home_flag_at_base']
|
||||||
and flag.held_count == 0):
|
and flag.held_count == 0):
|
||||||
time_out_counting_down = True
|
time_out_counting_down = True
|
||||||
|
if flag.time_out_respawn_time is None:
|
||||||
|
flag.reset_return_times()
|
||||||
|
assert flag.time_out_respawn_time is not None
|
||||||
flag.time_out_respawn_time -= 1
|
flag.time_out_respawn_time -= 1
|
||||||
if flag.time_out_respawn_time <= 0:
|
if flag.time_out_respawn_time <= 0:
|
||||||
flag.handlemessage(ba.DieMessage())
|
flag.handlemessage(ba.DieMessage())
|
||||||
|
|||||||
@ -59,7 +59,7 @@ class Icon(ba.Actor):
|
|||||||
|
|
||||||
icon = player.get_icon()
|
icon = player.get_icon()
|
||||||
self.node = ba.newnode('image',
|
self.node = ba.newnode('image',
|
||||||
owner=self,
|
delegate=self,
|
||||||
attrs={
|
attrs={
|
||||||
'texture': icon['texture'],
|
'texture': icon['texture'],
|
||||||
'tint_texture': icon['tint_texture'],
|
'tint_texture': icon['tint_texture'],
|
||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -69,6 +69,7 @@ class Puck(ba.Actor):
|
|||||||
'position': self._spawn_pos,
|
'position': self._spawn_pos,
|
||||||
'materials': pmats
|
'materials': pmats
|
||||||
})
|
})
|
||||||
|
ba.animate(self.node, "model_scale", {0: 0, 0.2: 1.3, 0.26: 1})
|
||||||
|
|
||||||
def handlemessage(self, msg: Any) -> Any:
|
def handlemessage(self, msg: Any) -> Any:
|
||||||
if isinstance(msg, ba.DieMessage):
|
if isinstance(msg, ba.DieMessage):
|
||||||
|
|||||||
@ -430,11 +430,11 @@ class OnslaughtGame(ba.CoopGameActivity):
|
|||||||
{'entries': [
|
{'entries': [
|
||||||
{'type': spazbot.ChargerBotProShielded,
|
{'type': spazbot.ChargerBotProShielded,
|
||||||
'point': 'bottom_right'},
|
'point': 'bottom_right'},
|
||||||
{'type': spazbot.ChargerBotProShielded, 'point': 'Bottom'}
|
{'type': spazbot.ChargerBotProShielded, 'point': 'bottom'}
|
||||||
if player_count > 2 else None,
|
if player_count > 2 else None,
|
||||||
{'type': spazbot.ChargerBotProShielded,
|
{'type': spazbot.ChargerBotProShielded,
|
||||||
'point': 'bottom_left'},
|
'point': 'bottom_left'},
|
||||||
{'type': spazbot.ChargerBotProShielded, 'point': 'Top'}
|
{'type': spazbot.ChargerBotProShielded, 'point': 'top'}
|
||||||
if hard else None,
|
if hard else None,
|
||||||
{'type': spazbot.BomberBotProStatic,
|
{'type': spazbot.BomberBotProStatic,
|
||||||
'point': 'turret_top_middle'},
|
'point': 'turret_top_middle'},
|
||||||
|
|||||||
@ -555,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
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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()))))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user