More type safety cleanup

This commit is contained in:
Eric Froemling 2020-05-28 23:19:12 -07:00
parent c783538831
commit a44821e03e
23 changed files with 355 additions and 278 deletions

View File

@ -438,6 +438,7 @@
<w>diemessages</w>
<w>difflib</w>
<w>dilateerode</w>
<w>dincrease</w>
<w>dingsound</w>
<w>dingsoundhigh</w>
<w>dirmanifest</w>
@ -1539,6 +1540,8 @@
<w>resample</w>
<w>resourcetypeinfo</w>
<w>respawn</w>
<w>respawnable</w>
<w>respawned</w>
<w>respawnicon</w>
<w>responsetype</w>
<w>returncode</w>
@ -1689,8 +1692,10 @@
<w>sparx</w>
<w>spawner</w>
<w>spawners</w>
<w>spawninfo</w>
<w>spawnpoints</w>
<w>spawnpt</w>
<w>spawnrate</w>
<w>spawntype</w>
<w>spaz</w>
<w>spazappearance</w>

View File

@ -6,6 +6,7 @@
"ba_data/python/ba/__pycache__/_activity.cpython-37.opt-1.pyc",
"ba_data/python/ba/__pycache__/_activitytypes.cpython-37.opt-1.pyc",
"ba_data/python/ba/__pycache__/_actor.cpython-37.opt-1.pyc",
"ba_data/python/ba/__pycache__/_analytics.cpython-37.opt-1.pyc",
"ba_data/python/ba/__pycache__/_app.cpython-37.opt-1.pyc",
"ba_data/python/ba/__pycache__/_appconfig.cpython-37.opt-1.pyc",
"ba_data/python/ba/__pycache__/_appdelegate.cpython-37.opt-1.pyc",
@ -61,6 +62,7 @@
"ba_data/python/ba/_activity.py",
"ba_data/python/ba/_activitytypes.py",
"ba_data/python/ba/_actor.py",
"ba_data/python/ba/_analytics.py",
"ba_data/python/ba/_app.py",
"ba_data/python/ba/_appconfig.py",
"ba_data/python/ba/_appdelegate.py",
@ -124,6 +126,7 @@
"ba_data/python/bastd/__init__.py",
"ba_data/python/bastd/__pycache__/__init__.cpython-37.opt-1.pyc",
"ba_data/python/bastd/__pycache__/appdelegate.cpython-37.opt-1.pyc",
"ba_data/python/bastd/__pycache__/gameutils.cpython-37.opt-1.pyc",
"ba_data/python/bastd/__pycache__/mainmenu.cpython-37.opt-1.pyc",
"ba_data/python/bastd/__pycache__/maps.cpython-37.opt-1.pyc",
"ba_data/python/bastd/__pycache__/stdmap.cpython-37.opt-1.pyc",
@ -227,6 +230,7 @@
"ba_data/python/bastd/game/runaround.py",
"ba_data/python/bastd/game/targetpractice.py",
"ba_data/python/bastd/game/thelaststand.py",
"ba_data/python/bastd/gameutils.py",
"ba_data/python/bastd/mainmenu.py",
"ba_data/python/bastd/mapdata/__init__.py",
"ba_data/python/bastd/mapdata/__pycache__/__init__.cpython-37.opt-1.pyc",

View File

@ -179,6 +179,7 @@ SCRIPT_TARGETS_PY_PUBLIC = \
build/ba_data/python/ba/_benchmark.py \
build/ba_data/python/ba/_tournament.py \
build/ba_data/python/ba/_messages.py \
build/ba_data/python/ba/_analytics.py \
build/ba_data/python/ba/_freeforallsession.py \
build/ba_data/python/ba/_score.py \
build/ba_data/python/ba/_playlist.py \
@ -200,6 +201,7 @@ SCRIPT_TARGETS_PY_PUBLIC = \
build/ba_data/python/ba/_nodeactor.py \
build/ba_data/python/ba/_teamgame.py \
build/ba_data/python/ba/ui/__init__.py \
build/ba_data/python/bastd/gameutils.py \
build/ba_data/python/bastd/mainmenu.py \
build/ba_data/python/bastd/maps.py \
build/ba_data/python/bastd/appdelegate.py \
@ -407,6 +409,7 @@ SCRIPT_TARGETS_PYC_PUBLIC = \
build/ba_data/python/ba/__pycache__/_benchmark.cpython-37.opt-1.pyc \
build/ba_data/python/ba/__pycache__/_tournament.cpython-37.opt-1.pyc \
build/ba_data/python/ba/__pycache__/_messages.cpython-37.opt-1.pyc \
build/ba_data/python/ba/__pycache__/_analytics.cpython-37.opt-1.pyc \
build/ba_data/python/ba/__pycache__/_freeforallsession.cpython-37.opt-1.pyc \
build/ba_data/python/ba/__pycache__/_score.cpython-37.opt-1.pyc \
build/ba_data/python/ba/__pycache__/_playlist.cpython-37.opt-1.pyc \
@ -428,6 +431,7 @@ SCRIPT_TARGETS_PYC_PUBLIC = \
build/ba_data/python/ba/__pycache__/_nodeactor.cpython-37.opt-1.pyc \
build/ba_data/python/ba/__pycache__/_teamgame.cpython-37.opt-1.pyc \
build/ba_data/python/ba/ui/__pycache__/__init__.cpython-37.opt-1.pyc \
build/ba_data/python/bastd/__pycache__/gameutils.cpython-37.opt-1.pyc \
build/ba_data/python/bastd/__pycache__/mainmenu.cpython-37.opt-1.pyc \
build/ba_data/python/bastd/__pycache__/maps.cpython-37.opt-1.pyc \
build/ba_data/python/bastd/__pycache__/appdelegate.cpython-37.opt-1.pyc \
@ -795,6 +799,11 @@ build/ba_data/python/ba/__pycache__/_messages.cpython-37.opt-1.pyc: \
@echo Compiling script: $^
@rm -rf $@ && $(TOOLS_DIR)/snippets compile_python_files $^ && chmod 444 $@
build/ba_data/python/ba/__pycache__/_analytics.cpython-37.opt-1.pyc: \
build/ba_data/python/ba/_analytics.py
@echo Compiling script: $^
@rm -rf $@ && $(TOOLS_DIR)/snippets compile_python_files $^ && chmod 444 $@
build/ba_data/python/ba/__pycache__/_freeforallsession.cpython-37.opt-1.pyc: \
build/ba_data/python/ba/_freeforallsession.py
@echo Compiling script: $^
@ -900,6 +909,11 @@ build/ba_data/python/ba/ui/__pycache__/__init__.cpython-37.opt-1.pyc: \
@echo Compiling script: $^
@rm -rf $@ && $(TOOLS_DIR)/snippets compile_python_files $^ && chmod 444 $@
build/ba_data/python/bastd/__pycache__/gameutils.cpython-37.opt-1.pyc: \
build/ba_data/python/bastd/gameutils.py
@echo Compiling script: $^
@rm -rf $@ && $(TOOLS_DIR)/snippets compile_python_files $^ && chmod 444 $@
build/ba_data/python/bastd/__pycache__/mainmenu.cpython-37.opt-1.pyc: \
build/ba_data/python/bastd/mainmenu.py
@echo Compiling script: $^

View File

@ -29,6 +29,7 @@ from ba._player import Player
from ba._error import print_exception, print_error, SessionTeamNotFoundError
from ba._dependency import DependencyComponent
from ba._general import Call, verify_object_death
from ba._messages import UNHANDLED
import _ba
if TYPE_CHECKING:
@ -414,6 +415,8 @@ class Activity(DependencyComponent, Generic[PlayerType, TeamType]):
def handlemessage(self, msg: Any) -> Any:
"""General message handling; can be passed any message object."""
del msg # Unused arg.
return UNHANDLED
def end(self,
results: Any = None,

View File

@ -46,7 +46,8 @@ class Actor:
Actors act as controllers, combining some number of ba.Nodes,
ba.Textures, ba.Sounds, etc. into a high-level cohesive unit.
Some example actors include Bomb, Flag, and Spaz classes in bastd.
Some example actors include the Bomb, Flag, and Spaz classes that
live in the bastd.actor.* modules.
One key feature of Actors is that they generally 'die'
(killing off or transitioning out their nodes) when the last Python

View File

@ -0,0 +1,91 @@
# Copyright (c) 2011-2020 Eric Froemling
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# -----------------------------------------------------------------------------
"""Functionality related to analytics."""
from __future__ import annotations
from typing import TYPE_CHECKING
import _ba
if TYPE_CHECKING:
pass
def game_begin_analytics() -> None:
"""Update analytics events for the start of a game."""
# pylint: disable=too-many-branches
# pylint: disable=cyclic-import
from ba._dualteamsession import DualTeamSession
from ba._freeforallsession import FreeForAllSession
from ba._coopsession import CoopSession
from ba._gameactivity import GameActivity
activity = _ba.getactivity(False)
session = _ba.getsession(False)
# Fail gracefully if we didn't cleanly get a session and game activity.
if not activity or not session or not isinstance(activity, GameActivity):
return
if isinstance(session, CoopSession):
campaign = session.campaign
assert campaign is not None
_ba.set_analytics_screen(
'Coop Game: ' + campaign.name + ' ' +
campaign.get_level(_ba.app.coop_session_args['level']).name)
_ba.increment_analytics_count('Co-op round start')
if len(activity.players) == 1:
_ba.increment_analytics_count('Co-op round start 1 human player')
elif len(activity.players) == 2:
_ba.increment_analytics_count('Co-op round start 2 human players')
elif len(activity.players) == 3:
_ba.increment_analytics_count('Co-op round start 3 human players')
elif len(activity.players) >= 4:
_ba.increment_analytics_count('Co-op round start 4+ human players')
elif isinstance(session, DualTeamSession):
_ba.set_analytics_screen('Teams Game: ' + activity.get_name())
_ba.increment_analytics_count('Teams round start')
if len(activity.players) == 1:
_ba.increment_analytics_count('Teams round start 1 human player')
elif 1 < len(activity.players) < 8:
_ba.increment_analytics_count('Teams round start ' +
str(len(activity.players)) +
' human players')
elif len(activity.players) >= 8:
_ba.increment_analytics_count('Teams round start 8+ human players')
elif isinstance(session, FreeForAllSession):
_ba.set_analytics_screen('FreeForAll Game: ' + activity.get_name())
_ba.increment_analytics_count('Free-for-all round start')
if len(activity.players) == 1:
_ba.increment_analytics_count(
'Free-for-all round start 1 human player')
elif 1 < len(activity.players) < 8:
_ba.increment_analytics_count('Free-for-all round start ' +
str(len(activity.players)) +
' human players')
elif len(activity.players) >= 8:
_ba.increment_analytics_count(
'Free-for-all round start 8+ human players')
# For some analytics tracking on the c layer.
_ba.reset_game_activity_tracking()

View File

@ -29,8 +29,11 @@ from typing import TYPE_CHECKING, TypeVar
from ba._activity import Activity
from ba._score import ScoreInfo
from ba._lang import Lstr
from ba._messages import PlayerDiedMessage
from ba._messages import PlayerDiedMessage, StandMessage, DieMessage, DeathType
from ba._error import NotFoundError, print_error, print_exception
from ba._general import Call, WeakCall
from ba._player import PlayerInfo
from ba import _map
import _ba
if TYPE_CHECKING:
@ -65,6 +68,17 @@ class GameActivity(Activity[PlayerType, TeamType]):
# Default get_score_info() will return this if not None.
score_info: Optional[ba.ScoreInfo] = None
# Override some defaults.
allow_pausing = True
allow_kick_idle_players = True
# Whether to show points for kills.
show_kill_points = True
# If not None, the music type that should play in on_transition_in()
# (unless overridden by the map).
default_music: Optional[ba.MusicType] = None
@classmethod
def create_settings_ui(
cls,
@ -139,7 +153,7 @@ class GameActivity(Activity[PlayerType, TeamType]):
Classes which want to change their description depending on the session
can override this method.
"""
del sessiontype # unused arg
del sessiontype # Unused arg.
return cls.description if cls.description is not None else ''
@classmethod
@ -223,8 +237,7 @@ class GameActivity(Activity[PlayerType, TeamType]):
implementation; should return a list of map names valid
for this game-type for the given ba.Session type.
"""
from ba import _map
del sessiontype # unused arg
del sessiontype # Unused arg.
return _map.getmaps('melee')
@classmethod
@ -234,7 +247,6 @@ class GameActivity(Activity[PlayerType, TeamType]):
This is used when viewing game-lists or showing what game
is up next in a series.
"""
from ba import _map
name = cls.get_display_string(config['settings'])
# In newer configs, map is in settings; it used to be in the
@ -268,42 +280,16 @@ class GameActivity(Activity[PlayerType, TeamType]):
def __init__(self, settings: Dict[str, Any]):
"""Instantiate the Activity."""
from ba import _map
super().__init__(settings)
# Set some defaults.
self.allow_pausing = True
self.allow_kick_idle_players = True
# Whether to show points for kills.
self.show_kill_points = True
# If not None, the music type that should play in on_transition_in()
# (unless overridden by the map).
self.default_music: Optional[ba.MusicType] = None
# Holds some flattened info about the player set at the point
# when on_begin() is called.
self.initial_player_info: Optional[List[ba.PlayerInfo]] = None
# Go ahead and get our map loading.
map_name: str
if 'map' in settings:
map_name = settings['map']
else:
# If settings doesn't specify a map, pick a random one from the
# list of supported ones.
unowned_maps = _map.get_unowned_maps()
valid_maps: List[str] = [
m for m in self.get_supported_maps(type(self.session))
if m not in unowned_maps
]
if not valid_maps:
_ba.screenmessage(Lstr(resource='noValidMapsErrorText'))
raise Exception('No valid maps')
map_name = valid_maps[random.randrange(len(valid_maps))]
self._map_type = _map.get_map_class(self._calc_map_name(settings))
self._spawn_sound = _ba.getsound('spawn')
self._map_type = _map.get_map_class(map_name)
self._map_type.preload()
self._map: Optional[ba.Map] = None
self._powerup_drop_timer: Optional[ba.Timer] = None
@ -422,8 +408,8 @@ class GameActivity(Activity[PlayerType, TeamType]):
# Make our map.
self._map = self._map_type()
# Give our map a chance to override the music
# (for happy-thoughts and other such themed maps).
# Give our map a chance to override the music.
# (for happy-thoughts and other such themed maps)
map_music = self._map_type.get_music_type()
music = map_music if map_music is not None else self.default_music
@ -470,13 +456,11 @@ class GameActivity(Activity[PlayerType, TeamType]):
# pylint: disable=cyclic-import
from bastd.ui.continues import ContinuesWindow
from ba._gameutils import sharedobj
from ba._general import WeakCall
from ba._coopsession import CoopSession
from ba._enums import TimeType
try:
if _ba.get_account_misc_read_val('enableContinues', False):
session = self.session
# We only support continuing in non-tournament games.
@ -510,82 +494,21 @@ class GameActivity(Activity[PlayerType, TeamType]):
return
except Exception:
print_exception('error continuing game')
print_exception('Error handling continues.')
self.end_game()
# FIXME: this logic should live in the session classes.
def _game_begin_analytics(self) -> None:
"""Update analytics events for the start of the game."""
# pylint: disable=too-many-branches
from ba._dualteamsession import DualTeamSession
from ba._freeforallsession import FreeForAllSession
from ba._coopsession import CoopSession
session = self.session
if isinstance(session, CoopSession):
campaign = session.campaign
assert campaign is not None
_ba.set_analytics_screen(
'Coop Game: ' + campaign.name + ' ' +
campaign.get_level(_ba.app.coop_session_args['level']).name)
_ba.increment_analytics_count('Co-op round start')
if len(self.players) == 1:
_ba.increment_analytics_count(
'Co-op round start 1 human player')
elif len(self.players) == 2:
_ba.increment_analytics_count(
'Co-op round start 2 human players')
elif len(self.players) == 3:
_ba.increment_analytics_count(
'Co-op round start 3 human players')
elif len(self.players) >= 4:
_ba.increment_analytics_count(
'Co-op round start 4+ human players')
elif isinstance(session, DualTeamSession):
_ba.set_analytics_screen('Teams Game: ' + self.get_name())
_ba.increment_analytics_count('Teams round start')
if len(self.players) == 1:
_ba.increment_analytics_count(
'Teams round start 1 human player')
elif 1 < len(self.players) < 8:
_ba.increment_analytics_count('Teams round start ' +
str(len(self.players)) +
' human players')
elif len(self.players) >= 8:
_ba.increment_analytics_count(
'Teams round start 8+ human players')
elif isinstance(session, FreeForAllSession):
_ba.set_analytics_screen('FreeForAll Game: ' + self.get_name())
_ba.increment_analytics_count('Free-for-all round start')
if len(self.players) == 1:
_ba.increment_analytics_count(
'Free-for-all round start 1 human player')
elif 1 < len(self.players) < 8:
_ba.increment_analytics_count('Free-for-all round start ' +
str(len(self.players)) +
' human players')
elif len(self.players) >= 8:
_ba.increment_analytics_count(
'Free-for-all round start 8+ human players')
# For some analytics tracking on the c layer.
_ba.reset_game_activity_tracking()
def on_begin(self) -> None:
from ba._general import WeakCall
from ba._player import PlayerInfo
from ba._analytics import game_begin_analytics
super().on_begin()
try:
self._game_begin_analytics()
except Exception:
print_exception('error in game-begin-analytics')
game_begin_analytics()
# We don't do this in on_transition_in because it may depend on
# players/teams which aren't available until now.
_ba.timer(0.001, WeakCall(self.show_scoreboard_info))
_ba.timer(1.0, WeakCall(self.show_info))
_ba.timer(2.5, WeakCall(self._show_tip))
_ba.timer(0.001, self._show_scoreboard_info)
_ba.timer(1.0, self._show_info)
_ba.timer(2.5, self._show_tip)
# Store some basic info about players present at start time.
self.initial_player_info = [
@ -600,7 +523,6 @@ class GameActivity(Activity[PlayerType, TeamType]):
# If this is a tournament, query info about it such as how much
# time is left.
tournament_id = self.session.tournament_id
if tournament_id is not None:
_ba.tournament_query(
args={
@ -628,9 +550,6 @@ class GameActivity(Activity[PlayerType, TeamType]):
self.spawn_player(player)
def on_player_leave(self, player: PlayerType) -> None:
from ba._general import Call
from ba._messages import DieMessage, DeathType
super().on_player_leave(player)
# If the player has an actor, send it a deferred die message.
@ -669,8 +588,10 @@ class GameActivity(Activity[PlayerType, TeamType]):
victim_player=player,
importance=importance,
showpoints=self.show_kill_points)
return None
return super().handlemessage(msg)
def show_scoreboard_info(self) -> None:
def _show_scoreboard_info(self) -> None:
"""Create the game info display.
This is the thing in the top left corner showing the name
@ -682,8 +603,8 @@ class GameActivity(Activity[PlayerType, TeamType]):
from ba._nodeactor import NodeActor
sb_name = self.get_instance_scoreboard_display_string()
# the description can be either a string or a sequence with args
# to swap in post-translation
# The description can be either a string or a sequence with args
# to swap in post-translation.
sb_desc_in = self.get_instance_description_short()
sb_desc_l: Sequence
if isinstance(sb_desc_in, str):
@ -754,10 +675,9 @@ class GameActivity(Activity[PlayerType, TeamType]):
1.0: 1.0
})
def show_info(self) -> None:
def _show_info(self) -> None:
"""Show the game description."""
from ba._gameutils import animate
from ba._general import Call
from bastd.actor.zoomtext import ZoomText
name = self.get_instance_display_string()
ZoomText(name,
@ -786,7 +706,7 @@ class GameActivity(Activity[PlayerType, TeamType]):
translation = Lstr(translate=('gameDescriptions', desc_l[0]),
subs=subs)
# do some standard filters (epic mode, etc)
# Do some standard filters (epic mode, etc).
if self.settings_raw.get('Epic Mode', False):
translation = Lstr(resource='epicDescriptionFilterText',
subs=[('${DESCRIPTION}', translation)])
@ -822,7 +742,8 @@ class GameActivity(Activity[PlayerType, TeamType]):
# pylint: disable=too-many-locals
from ba._gameutils import animate
from ba._enums import SpecialChar
# if there's any tips left on the list, display one..
# If there's any tips left on the list, display one.
if self.tips:
tip = self.tips.pop(random.randrange(len(self.tips)))
tip_title = Lstr(value='${A}:',
@ -837,7 +758,7 @@ class GameActivity(Activity[PlayerType, TeamType]):
tip = tip['tip']
assert isinstance(tip, str)
# a few subs..
# A few substitutions...
tip_lstr = Lstr(translate=('tips', tip),
subs=[('${PICKUP}',
_ba.charstr(SpecialChar.TOP_BUTTON))])
@ -947,26 +868,6 @@ class GameActivity(Activity[PlayerType, TeamType]):
print('WARNING: default end_game() implementation called;'
' your game should override this.')
def spawn_player_if_exists(self, player: PlayerType) -> None:
"""
A utility method which calls self.spawn_player() *only* if the
ba.Player provided still exists; handy for use in timers and whatnot.
There is no need to override this; just override spawn_player().
"""
if player:
self.spawn_player(player)
def spawn_player(self, player: PlayerType) -> ba.Actor:
"""Spawn *something* for the provided ba.Player.
The default implementation simply calls spawn_player_spaz().
"""
if not player:
raise TypeError('spawn_player() called for nonexistent player')
return self.spawn_player_spaz(player)
def respawn_player(self,
player: PlayerType,
respawn_time: Optional[float] = None) -> None:
@ -992,21 +893,39 @@ class GameActivity(Activity[PlayerType, TeamType]):
else:
respawn_time = 7.0
# If this standard setting is present, factor it in
# If this standard setting is present, factor it in.
if 'Respawn Times' in self.settings_raw:
respawn_time *= self.settings_raw['Respawn Times']
# we want whole seconds
# We want whole seconds.
assert respawn_time is not None
respawn_time = round(max(1.0, respawn_time), 0)
if player.actor and not self.has_ended():
from ba._general import WeakCall
from bastd.actor.respawnicon import RespawnIcon
player.gamedata['respawn_timer'] = _ba.Timer(
respawn_time, WeakCall(self.spawn_player_if_exists, player))
player.gamedata['respawn_icon'] = RespawnIcon(player, respawn_time)
def spawn_player_if_exists(self, player: PlayerType) -> None:
"""
A utility method which calls self.spawn_player() *only* if the
ba.Player provided still exists; handy for use in timers and whatnot.
There is no need to override this; just override spawn_player().
"""
if player:
self.spawn_player(player)
def spawn_player(self, player: PlayerType) -> ba.Actor:
"""Spawn *something* for the provided ba.Player.
The default implementation simply calls spawn_player_spaz().
"""
assert player # Dead references should never be passed as args.
return self.spawn_player_spaz(player)
def spawn_player_spaz(self,
player: PlayerType,
position: Sequence[float] = (0, 0, 0),
@ -1015,7 +934,6 @@ class GameActivity(Activity[PlayerType, TeamType]):
# pylint: disable=too-many-locals
# pylint: disable=cyclic-import
from ba import _math
from ba import _messages
from ba._gameutils import animate
from ba._coopsession import CoopSession
from bastd.actor.playerspaz import PlayerSpaz
@ -1051,7 +969,7 @@ class GameActivity(Activity[PlayerType, TeamType]):
# Move to the stand position and add a flash of light.
spaz.handlemessage(
_messages.StandMessage(
StandMessage(
position,
angle if angle is not None else random.uniform(0, 360)))
_ba.playsound(self._spawn_sound, 1, position=spaz.node.position)
@ -1061,30 +979,14 @@ class GameActivity(Activity[PlayerType, TeamType]):
_ba.timer(0.5, light.delete)
return spaz
def project_flag_stand(self, pos: Sequence[float]) -> None:
"""Project a flag-stand onto the ground at the given position.
Useful for games such as capture-the-flag to show where a
movable flag originated from.
"""
from ba._general import WeakCall
# Need to do this in a timer for it to work.. need to look into that.
# (might not still be the case?...)
_ba.pushcall(WeakCall(self._project_flag_stand, pos[:3]))
def _project_flag_stand(self, pos: Sequence[float]) -> None:
_ba.emitfx(position=pos, emit_type='flag_stand')
def setup_standard_powerup_drops(self, enable_tnt: bool = True) -> None:
"""Create standard powerup drops for the current map."""
# pylint: disable=cyclic-import
from bastd.actor import powerupbox
from ba import _general
self._powerup_drop_timer = _ba.Timer(
powerupbox.DEFAULT_POWERUP_INTERVAL,
_general.WeakCall(self._standard_drop_powerups),
repeat=True)
from bastd.actor.powerupbox import DEFAULT_POWERUP_INTERVAL
self._powerup_drop_timer = _ba.Timer(DEFAULT_POWERUP_INTERVAL,
WeakCall(
self._standard_drop_powerups),
repeat=True)
self._standard_drop_powerups()
if enable_tnt:
self._tnt_spawners = {}
@ -1100,19 +1002,16 @@ class GameActivity(Activity[PlayerType, TeamType]):
def _standard_drop_powerups(self) -> None:
"""Standard powerup drop."""
from ba import _general
# Drop one powerup per point.
points = self.map.powerup_spawn_points
for i in range(len(points)):
_ba.timer(i * 0.4, _general.WeakCall(self._standard_drop_powerup,
i))
_ba.timer(i * 0.4, WeakCall(self._standard_drop_powerup, i))
def _setup_standard_tnt_drops(self) -> None:
"""Standard tnt drop."""
# pylint: disable=cyclic-import
from bastd.actor.bomb import TNTSpawner
for i, point in enumerate(self.map.tnt_points):
assert self._tnt_spawners is not None
if self._tnt_spawners.get(i) is None:
@ -1126,7 +1025,6 @@ class GameActivity(Activity[PlayerType, TeamType]):
If the time-limit expires, end_game() will be called.
"""
from ba._gameutils import sharedobj
from ba._general import WeakCall
from ba._nodeactor import NodeActor
if duration <= 0.0:
return
@ -1200,7 +1098,6 @@ class GameActivity(Activity[PlayerType, TeamType]):
This will be displayed at the top of the screen.
If the time-limit expires, end_game() will be called.
"""
from ba._general import WeakCall
from ba._nodeactor import NodeActor
from ba._enums import TimeType
if duration <= 0.0:
@ -1337,3 +1234,21 @@ class GameActivity(Activity[PlayerType, TeamType]):
maxwidth=800,
trail=trail,
color=color).autoretain()
def _calc_map_name(self, settings: Dict[str, Any]) -> str:
map_name: str
if 'map' in settings:
map_name = settings['map']
else:
# If settings doesn't specify a map, pick a random one from the
# list of supported ones.
unowned_maps = _map.get_unowned_maps()
valid_maps: List[str] = [
m for m in self.get_supported_maps(type(self.session))
if m not in unowned_maps
]
if not valid_maps:
_ba.screenmessage(Lstr(resource='noValidMapsErrorText'))
raise Exception('No valid maps')
map_name = valid_maps[random.randrange(len(valid_maps))]
return map_name

View File

@ -19,9 +19,11 @@
# SOFTWARE.
# -----------------------------------------------------------------------------
"""Utility functionality pertaining to gameplay."""
from __future__ import annotations
from typing import TYPE_CHECKING
# from typing_extensions import Protocol
import _ba
from ba._enums import TimeType, TimeFormat, SpecialChar
@ -39,6 +41,15 @@ TROPHY_CHARS = {
'4': SpecialChar.TROPHY4
}
# class Respawnable(Protocol):
# """A Protocol for objects able to be respawned.
# Category: Protocols
# """
# respawn_timer: Optional[ba.Timer]
# respawn_icon: Optional[RespawnIcon]
def get_trophy_string(trophy_id: str) -> str:
"""Given a trophy id, returns a string to visualize it."""

View File

@ -271,7 +271,7 @@ class DirectoryScan:
cbits = lbits[1].split('(')
if len(cbits) > 1 and cbits[0].isidentifier():
classname = cbits[0]
break # success!
break # Success!
if classname is None:
self.results.warnings += (
'Warning: ' + str(subpath) + ': class definition not found'
@ -291,7 +291,7 @@ class DirectoryScan:
and l[1] == 'require' and l[2] == 'api' and l[3].isdigit()
]
# we're successful if we find exactly one properly formatted line
# We're successful if we find exactly one properly formatted line.
if len(lines) == 1:
return int(lines[0][3])

View File

@ -59,14 +59,13 @@ class TeamGameActivity(GameActivity[PlayerType, TeamType]):
or issubclass(sessiontype, FreeForAllSession))
def __init__(self, settings: Dict[str, Any]):
super().__init__(settings)
# By default we don't show kill-points in free-for-all.
# By default we don't show kill-points in free-for-all sessions.
# (there's usually some activity-specific score and we don't
# wanna confuse things)
if isinstance(_ba.getsession(), FreeForAllSession):
self._show_kill_points = False
if isinstance(self.session, FreeForAllSession):
self.show_kill_points = False
def on_transition_in(self) -> None:
# pylint: disable=cyclic-import
@ -78,7 +77,6 @@ class TeamGameActivity(GameActivity[PlayerType, TeamType]):
# (unless we're being run in co-op mode, in which case we leave
# it up to them)
if not isinstance(self.session, CoopSession):
# FIXME: Need an elegant way to store on session.
if not self.session.have_shown_controls_help_overlay:
delay = 4.0
lifespan = 10.0
@ -151,6 +149,7 @@ class TeamGameActivity(GameActivity[PlayerType, TeamType]):
if not isinstance(session, CoopSession):
do_announce = not self.has_ended()
super().end(results, delay=2.0 + announce_delay, force=force)
# Need to do this *after* end end call so that results is valid.
assert isinstance(results, TeamGameResults)
if do_announce and isinstance(session, MultiTeamSession):

View File

@ -67,41 +67,58 @@ class FlagFactory:
self.flagmaterial = ba.Material()
self.flagmaterial.add_actions(
conditions=(('we_are_younger_than', 100),
'and', ('they_have_material',
ba.sharedobj('object_material'))),
actions=('modify_node_collision', 'collide', False))
conditions=(
('we_are_younger_than', 100),
'and',
('they_have_material', ba.sharedobj('object_material')),
),
actions=('modify_node_collision', 'collide', False),
)
self.flagmaterial.add_actions(
conditions=('they_have_material',
ba.sharedobj('footing_material')),
actions=(('message', 'our_node', 'at_connect', 'footing', 1),
('message', 'our_node', 'at_disconnect', 'footing', -1)))
conditions=(
'they_have_material',
ba.sharedobj('footing_material'),
),
actions=(
('message', 'our_node', 'at_connect', 'footing', 1),
('message', 'our_node', 'at_disconnect', 'footing', -1),
),
)
self.impact_sound = ba.getsound('metalHit')
self.skid_sound = ba.getsound('metalSkid')
self.flagmaterial.add_actions(
conditions=('they_have_material',
ba.sharedobj('footing_material')),
actions=(('impact_sound', self.impact_sound, 2, 5),
('skid_sound', self.skid_sound, 2, 5)))
conditions=(
'they_have_material',
ba.sharedobj('footing_material'),
),
actions=(
('impact_sound', self.impact_sound, 2, 5),
('skid_sound', self.skid_sound, 2, 5),
),
)
self.no_hit_material = ba.Material()
self.no_hit_material.add_actions(
conditions=(('they_have_material',
ba.sharedobj('pickup_material')),
'or', ('they_have_material',
ba.sharedobj('attack_material'))),
actions=('modify_part_collision', 'collide', False))
conditions=(
('they_have_material', ba.sharedobj('pickup_material')),
'or',
('they_have_material', ba.sharedobj('attack_material')),
),
actions=('modify_part_collision', 'collide', False),
)
# We also don't want anything moving it.
self.no_hit_material.add_actions(
conditions=(('they_have_material',
ba.sharedobj('object_material')), 'or',
('they_dont_have_material',
ba.sharedobj('footing_material'))),
conditions=(
('they_have_material', ba.sharedobj('object_material')),
'or',
('they_dont_have_material', ba.sharedobj('footing_material')),
),
actions=(('modify_part_collision', 'collide', False),
('modify_part_collision', 'physical', False)))
('modify_part_collision', 'physical', False)),
)
self.flag_texture = ba.gettexture('flagColor')
@ -353,3 +370,13 @@ class Flag(ba.Actor):
self.activity.handlemessage(FlagDroppedMessage(self, msg.node))
else:
super().handlemessage(msg)
@staticmethod
def project_stand(pos: Sequence[float]) -> None:
"""Project a flag-stand onto the ground at the given position.
Useful for games such as capture-the-flag to show where a
movable flag originated from.
"""
assert len(pos) == 3
ba.emitfx(position=pos, emit_type='flag_stand')

View File

@ -121,7 +121,7 @@ class AssaultGame(ba.TeamGameActivity[Player, Team]):
'radius': 0.1,
'color': sessionteam.color
})
self.project_flag_stand(base_pos)
Flag.project_stand(base_pos)
flag = Flag(touchable=False,
position=base_pos,
color=sessionteam.color)

View File

@ -190,7 +190,7 @@ class CaptureTheFlagGame(ba.TeamGameActivity[Player, Team]):
# Create our team instance and its initial values.
base_pos = self.map.get_flag_position(sessionteam.id)
self.project_flag_stand(base_pos)
Flag.project_stand(base_pos)
ba.newnode('light',
attrs={

View File

@ -145,7 +145,7 @@ class ChosenOneGame(ba.TeamGameActivity[Player, Team]):
self.setup_standard_time_limit(self._time_limit)
self.setup_standard_powerup_drops()
self._flag_spawn_pos = self.map.get_flag_position(None)
self.project_flag_stand(self._flag_spawn_pos)
Flag.project_stand(self._flag_spawn_pos)
self._set_chosen_one_player(None)
pos = self._flag_spawn_pos

View File

@ -167,8 +167,7 @@ class ConquestGame(ba.TeamGameActivity[Player, Team]):
touchable=False,
materials=[self._extraflagmat])
self._flags.append(flag)
# FIXME: Move next few lines to the flag class.
self.project_flag_stand(point)
Flag.project_stand(point)
flag.light = ba.newnode('light',
owner=flag.node,
attrs={

View File

@ -198,15 +198,11 @@ class EasterEggHuntGame(ba.TeamGameActivity[Player, Team]):
# Respawn dead players.
if isinstance(msg, ba.PlayerDiedMessage):
# Augment standard behavior.
super().handlemessage(msg)
player = msg.getplayer(Player)
if not player:
return
self.stats.player_was_killed(player)
# Respawn them shortly.
player = msg.getplayer(Player)
assert self.initial_player_info is not None
respawn_time = 2.0 + len(self.initial_player_info) * 1.0
player.respawn_timer = ba.Timer(
@ -226,7 +222,8 @@ class EasterEggHuntGame(ba.TeamGameActivity[Player, Team]):
pos[2] + random.uniform(-spread, spread))))
else:
# Default handler.
super().handlemessage(msg)
return super().handlemessage(msg)
return None
def _update_scoreboard(self) -> None:
for team in self.teams:

View File

@ -798,21 +798,17 @@ class FootballCoopGame(ba.CoopGameActivity[Player, Team]):
def handlemessage(self, msg: Any) -> Any:
""" handle high-level game messages """
if isinstance(msg, ba.PlayerDiedMessage):
# Respawn dead players.
player = msg.getplayer(Player)
self.stats.player_was_killed(player)
assert self.initial_player_info is not None
respawn_time = 2.0 + len(self.initial_player_info) * 1.0
# Augment standard behavior.
super().handlemessage(msg)
# Respawn them shortly.
player = msg.getplayer(Player)
assert self.initial_player_info is not None
respawn_time = 2.0 + len(self.initial_player_info) * 1.0
player.respawn_timer = ba.Timer(
respawn_time, ba.Call(self.spawn_player_if_exists, player))
player.respawn_icon = RespawnIcon(player, respawn_time)
# Augment standard behavior.
super().handlemessage(msg)
elif isinstance(msg, SpazBotDiedMessage):
# Every time a bad guy dies, spawn a new one.
@ -848,7 +844,8 @@ class FootballCoopGame(ba.CoopGameActivity[Player, Team]):
loop=True)
ba.timer(3.0, self._flag_respawn_light.node.delete)
else:
super().handlemessage(msg)
return super().handlemessage(msg)
return None
def _handle_player_dropped_bomb(self, player: Spaz,
bomb: ba.Actor) -> None:

View File

@ -138,7 +138,7 @@ class KeepAwayGame(ba.TeamGameActivity[Player, Team]):
self._spawn_flag()
self._update_timer = ba.Timer(1.0, call=self._tick, repeat=True)
self._update_flag_state()
self.project_flag_stand(self._flag_spawn_pos)
Flag.project_stand(self._flag_spawn_pos)
def _tick(self) -> None:
self._update_flag_state()

View File

@ -150,7 +150,7 @@ class KingOfTheHillGame(ba.TeamGameActivity[Player, Team]):
self._flag_pos = self.map.get_flag_position(None)
ba.timer(1.0, self._tick, repeat=True)
self._flag_state = FlagState.NEW
self.project_flag_stand(self._flag_pos)
Flag.project_stand(self._flag_pos)
self._flag = Flag(position=self._flag_pos,
touchable=False,

View File

@ -1108,13 +1108,14 @@ class RunaroundGame(ba.CoopGameActivity[Player, Team]):
self._score += msg.score
self._update_scores()
# Respawn dead players.
elif isinstance(msg, ba.PlayerDiedMessage):
# Augment standard behavior.
super().handlemessage(msg)
self._a_player_has_been_killed = True
player = msg.getplayer(Player)
self.stats.player_was_killed(player)
# Respawn them shortly.
player = msg.getplayer(Player)
assert self.initial_player_info is not None
respawn_time = 2.0 + len(self.initial_player_info) * 1.0
player.respawn_timer = ba.Timer(

View File

@ -23,6 +23,7 @@
from __future__ import annotations
import random
from dataclasses import dataclass
from typing import TYPE_CHECKING
import ba
@ -42,6 +43,14 @@ if TYPE_CHECKING:
from bastd.actor.spazbot import SpazBot
@dataclass
class SpawnInfo:
"""Spawning info for a particular bot type."""
spawnrate: float
increase: float
dincrease: float
class Player(ba.Player['Team']):
"""Our player type for this game."""
@ -78,7 +87,7 @@ class TheLastStandGame(ba.CoopGameActivity[Player, Team]):
self._tntspawnpos = (0, 5.5, -6)
self._powerup_center = (0, 7, -4.14)
self._powerup_spread = (7, 2)
self._preset = self.settings_raw.get('preset', 'default')
self._preset = str(settings.get('preset', 'default'))
self._excludepowerups: List[str] = []
self._scoreboard: Optional[Scoreboard] = None
self._score = 0
@ -90,21 +99,22 @@ class TheLastStandGame(ba.CoopGameActivity[Player, Team]):
self._bot_update_timer: Optional[ba.Timer] = None
self._powerup_drop_timer = None
# For each bot type: [spawn-rate, increase, d_increase]
# For each bot type: [spawnrate, increase, d_increase]
self._bot_spawn_types = {
BomberBot: [1.00, 0.00, 0.000],
BomberBotPro: [0.00, 0.05, 0.001],
BomberBotProShielded: [0.00, 0.02, 0.002],
BrawlerBot: [1.00, 0.00, 0.000],
BrawlerBotPro: [0.00, 0.05, 0.001],
BrawlerBotProShielded: [0.00, 0.02, 0.002],
TriggerBot: [0.30, 0.00, 0.000],
TriggerBotPro: [0.00, 0.05, 0.001],
TriggerBotProShielded: [0.00, 0.02, 0.002],
ChargerBot: [0.30, 0.05, 0.000],
StickyBot: [0.10, 0.03, 0.001],
ExplodeyBot: [0.05, 0.02, 0.002]
} # yapf: disable
BomberBot: SpawnInfo(1.00, 0.00, 0.000),
BomberBotPro: SpawnInfo(0.00, 0.05, 0.001),
BomberBotProShielded: SpawnInfo(0.00, 0.02, 0.002),
BrawlerBot: SpawnInfo(1.00, 0.00, 0.000),
BrawlerBotPro: SpawnInfo(0.00, 0.05, 0.001),
BrawlerBotProShielded: SpawnInfo(0.00, 0.02, 0.002),
TriggerBot: SpawnInfo(0.30, 0.00, 0.000),
TriggerBotPro: SpawnInfo(0.00, 0.05, 0.001),
TriggerBotProShielded: SpawnInfo(0.00, 0.02, 0.002),
ChargerBot: SpawnInfo(0.30, 0.05, 0.000),
StickyBot: SpawnInfo(0.10, 0.03, 0.001),
ExplodeyBot: SpawnInfo(0.05, 0.02, 0.002)
} # yapf: disable
def on_transition_in(self) -> None:
super().on_transition_in()
@ -121,8 +131,6 @@ class TheLastStandGame(ba.CoopGameActivity[Player, Team]):
ba.timer(0.001, ba.WeakCall(self._start_bot_updates))
self.setup_low_life_warning_sound()
self._update_scores()
# Our TNT spawner (if applicable).
self._tntspawner = TNTSpawner(position=self._tntspawnpos,
respawn_time=10.0)
@ -225,17 +233,17 @@ class TheLastStandGame(ba.CoopGameActivity[Player, Team]):
# Normalize our bot type total and find a random number within that.
total = 0.0
for spawntype in self._bot_spawn_types.items():
total += spawntype[1][0]
for spawninfo in self._bot_spawn_types.values():
total += spawninfo.spawnrate
randval = random.random() * total
# Now go back through and see where this value falls.
total = 0
bottype: Optional[Type[SpazBot]] = None
for spawntype in self._bot_spawn_types.items():
total += spawntype[1][0]
for spawntype, spawninfo in self._bot_spawn_types.items():
total += spawninfo.spawnrate
if randval <= total:
bottype = spawntype[0]
bottype = spawntype
break
spawn_time = 1.0
assert bottype is not None
@ -243,9 +251,9 @@ class TheLastStandGame(ba.CoopGameActivity[Player, Team]):
# After every spawn we adjust our ratios slightly to get more
# difficult.
for spawntype in self._bot_spawn_types.items():
spawntype[1][0] += spawntype[1][1] # incr spawn rate
spawntype[1][1] += spawntype[1][2] # incr spawn rate incr rate
for spawninfo in self._bot_spawn_types.values():
spawninfo.spawnrate += spawninfo.increase
spawninfo.increase += spawninfo.dincrease
def _update_scores(self) -> None:
score = self._score

View File

@ -0,0 +1,28 @@
# Copyright (c) 2011-2020 Eric Froemling
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# -----------------------------------------------------------------------------
"""Various utilities useful for gameplay."""
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import Sequence

View File

@ -1,5 +1,5 @@
<!-- THIS FILE IS AUTO GENERATED; DO NOT EDIT BY HAND -->
<h4><em>last updated on 2020-05-28 for Ballistica version 1.5.0 build 20032</em></h4>
<h4><em>last updated on 2020-05-28 for Ballistica version 1.5.0 build 20033</em></h4>
<p>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 <a href="mailto:support@froemling.net">let me know</a>. Happy modding!</p>
<hr>
@ -604,7 +604,8 @@ is a convenient way to access this same functionality.</p>
<p> Actors act as controllers, combining some number of <a href="#class_ba_Node">ba.Nodes</a>,
<a href="#class_ba_Texture">ba.Textures</a>, <a href="#class_ba_Sound">ba.Sounds</a>, etc. into a high-level cohesive unit.</p>
<p> Some example actors include Bomb, Flag, and Spaz classes in bastd.</p>
<p> Some example actors include the Bomb, Flag, and Spaz classes that
live in the bastd.actor.* modules.</p>
<p> One key feature of Actors is that they generally 'die'
(killing off or transitioning out their nodes) when the last Python
@ -1584,7 +1585,7 @@ start_long_action(callback_when_done=<a href="#class_ba_ContextCall">ba.ContextC
</dd>
</dl>
<h3>Methods Inherited:</h3>
<h5><a href="#method_ba_GameActivity__add_actor_weak_ref">add_actor_weak_ref()</a>, <a href="#method_ba_GameActivity__add_player">add_player()</a>, <a href="#method_ba_GameActivity__add_team">add_team()</a>, <a href="#method_ba_GameActivity__begin">begin()</a>, <a href="#method_ba_GameActivity__continue_or_end_game">continue_or_end_game()</a>, <a href="#method_ba_GameActivity__create_player">create_player()</a>, <a href="#method_ba_GameActivity__create_settings_ui">create_settings_ui()</a>, <a href="#method_ba_GameActivity__create_team">create_team()</a>, <a href="#method_ba_GameActivity__dep_is_present">dep_is_present()</a>, <a href="#method_ba_GameActivity__destroy">destroy()</a>, <a href="#method_ba_GameActivity__end">end()</a>, <a href="#method_ba_GameActivity__end_game">end_game()</a>, <a href="#method_ba_GameActivity__get_description">get_description()</a>, <a href="#method_ba_GameActivity__get_description_display_string">get_description_display_string()</a>, <a href="#method_ba_GameActivity__get_display_string">get_display_string()</a>, <a href="#method_ba_GameActivity__get_dynamic_deps">get_dynamic_deps()</a>, <a href="#method_ba_GameActivity__get_game_settings">get_game_settings()</a>, <a href="#method_ba_GameActivity__get_instance_description">get_instance_description()</a>, <a href="#method_ba_GameActivity__get_instance_description_short">get_instance_description_short()</a>, <a href="#method_ba_GameActivity__get_instance_display_string">get_instance_display_string()</a>, <a href="#method_ba_GameActivity__get_instance_scoreboard_display_string">get_instance_scoreboard_display_string()</a>, <a href="#method_ba_GameActivity__get_name">get_name()</a>, <a href="#method_ba_GameActivity__get_score_info">get_score_info()</a>, <a href="#method_ba_GameActivity__get_settings_display_string">get_settings_display_string()</a>, <a href="#method_ba_GameActivity__get_supported_maps">get_supported_maps()</a>, <a href="#method_ba_GameActivity__get_team_display_string">get_team_display_string()</a>, <a href="#method_ba_GameActivity__handlemessage">handlemessage()</a>, <a href="#method_ba_GameActivity__has_begun">has_begun()</a>, <a href="#method_ba_GameActivity__has_ended">has_ended()</a>, <a href="#method_ba_GameActivity__has_transitioned_in">has_transitioned_in()</a>, <a href="#method_ba_GameActivity__is_transitioning_out">is_transitioning_out()</a>, <a href="#method_ba_GameActivity__is_waiting_for_continue">is_waiting_for_continue()</a>, <a href="#method_ba_GameActivity__on_continue">on_continue()</a>, <a href="#method_ba_GameActivity__on_expire">on_expire()</a>, <a href="#method_ba_GameActivity__on_player_join">on_player_join()</a>, <a href="#method_ba_GameActivity__on_player_leave">on_player_leave()</a>, <a href="#method_ba_GameActivity__on_team_join">on_team_join()</a>, <a href="#method_ba_GameActivity__on_team_leave">on_team_leave()</a>, <a href="#method_ba_GameActivity__on_transition_in">on_transition_in()</a>, <a href="#method_ba_GameActivity__on_transition_out">on_transition_out()</a>, <a href="#method_ba_GameActivity__project_flag_stand">project_flag_stand()</a>, <a href="#method_ba_GameActivity__remove_player">remove_player()</a>, <a href="#method_ba_GameActivity__remove_team">remove_team()</a>, <a href="#method_ba_GameActivity__respawn_player">respawn_player()</a>, <a href="#method_ba_GameActivity__retain_actor">retain_actor()</a>, <a href="#method_ba_GameActivity__set_has_ended">set_has_ended()</a>, <a href="#method_ba_GameActivity__set_immediate_end">set_immediate_end()</a>, <a href="#method_ba_GameActivity__setup_standard_powerup_drops">setup_standard_powerup_drops()</a>, <a href="#method_ba_GameActivity__setup_standard_time_limit">setup_standard_time_limit()</a>, <a href="#method_ba_GameActivity__show_info">show_info()</a>, <a href="#method_ba_GameActivity__show_scoreboard_info">show_scoreboard_info()</a>, <a href="#method_ba_GameActivity__show_zoom_message">show_zoom_message()</a>, <a href="#method_ba_GameActivity__spawn_player">spawn_player()</a>, <a href="#method_ba_GameActivity__spawn_player_if_exists">spawn_player_if_exists()</a>, <a href="#method_ba_GameActivity__transition_in">transition_in()</a>, <a href="#method_ba_GameActivity__transition_out">transition_out()</a></h5>
<h5><a href="#method_ba_GameActivity__add_actor_weak_ref">add_actor_weak_ref()</a>, <a href="#method_ba_GameActivity__add_player">add_player()</a>, <a href="#method_ba_GameActivity__add_team">add_team()</a>, <a href="#method_ba_GameActivity__begin">begin()</a>, <a href="#method_ba_GameActivity__continue_or_end_game">continue_or_end_game()</a>, <a href="#method_ba_GameActivity__create_player">create_player()</a>, <a href="#method_ba_GameActivity__create_settings_ui">create_settings_ui()</a>, <a href="#method_ba_GameActivity__create_team">create_team()</a>, <a href="#method_ba_GameActivity__dep_is_present">dep_is_present()</a>, <a href="#method_ba_GameActivity__destroy">destroy()</a>, <a href="#method_ba_GameActivity__end">end()</a>, <a href="#method_ba_GameActivity__end_game">end_game()</a>, <a href="#method_ba_GameActivity__get_description">get_description()</a>, <a href="#method_ba_GameActivity__get_description_display_string">get_description_display_string()</a>, <a href="#method_ba_GameActivity__get_display_string">get_display_string()</a>, <a href="#method_ba_GameActivity__get_dynamic_deps">get_dynamic_deps()</a>, <a href="#method_ba_GameActivity__get_game_settings">get_game_settings()</a>, <a href="#method_ba_GameActivity__get_instance_description">get_instance_description()</a>, <a href="#method_ba_GameActivity__get_instance_description_short">get_instance_description_short()</a>, <a href="#method_ba_GameActivity__get_instance_display_string">get_instance_display_string()</a>, <a href="#method_ba_GameActivity__get_instance_scoreboard_display_string">get_instance_scoreboard_display_string()</a>, <a href="#method_ba_GameActivity__get_name">get_name()</a>, <a href="#method_ba_GameActivity__get_score_info">get_score_info()</a>, <a href="#method_ba_GameActivity__get_settings_display_string">get_settings_display_string()</a>, <a href="#method_ba_GameActivity__get_supported_maps">get_supported_maps()</a>, <a href="#method_ba_GameActivity__get_team_display_string">get_team_display_string()</a>, <a href="#method_ba_GameActivity__handlemessage">handlemessage()</a>, <a href="#method_ba_GameActivity__has_begun">has_begun()</a>, <a href="#method_ba_GameActivity__has_ended">has_ended()</a>, <a href="#method_ba_GameActivity__has_transitioned_in">has_transitioned_in()</a>, <a href="#method_ba_GameActivity__is_transitioning_out">is_transitioning_out()</a>, <a href="#method_ba_GameActivity__is_waiting_for_continue">is_waiting_for_continue()</a>, <a href="#method_ba_GameActivity__on_continue">on_continue()</a>, <a href="#method_ba_GameActivity__on_expire">on_expire()</a>, <a href="#method_ba_GameActivity__on_player_join">on_player_join()</a>, <a href="#method_ba_GameActivity__on_player_leave">on_player_leave()</a>, <a href="#method_ba_GameActivity__on_team_join">on_team_join()</a>, <a href="#method_ba_GameActivity__on_team_leave">on_team_leave()</a>, <a href="#method_ba_GameActivity__on_transition_in">on_transition_in()</a>, <a href="#method_ba_GameActivity__on_transition_out">on_transition_out()</a>, <a href="#method_ba_GameActivity__remove_player">remove_player()</a>, <a href="#method_ba_GameActivity__remove_team">remove_team()</a>, <a href="#method_ba_GameActivity__respawn_player">respawn_player()</a>, <a href="#method_ba_GameActivity__retain_actor">retain_actor()</a>, <a href="#method_ba_GameActivity__set_has_ended">set_has_ended()</a>, <a href="#method_ba_GameActivity__set_immediate_end">set_immediate_end()</a>, <a href="#method_ba_GameActivity__setup_standard_powerup_drops">setup_standard_powerup_drops()</a>, <a href="#method_ba_GameActivity__setup_standard_time_limit">setup_standard_time_limit()</a>, <a href="#method_ba_GameActivity__show_zoom_message">show_zoom_message()</a>, <a href="#method_ba_GameActivity__spawn_player">spawn_player()</a>, <a href="#method_ba_GameActivity__spawn_player_if_exists">spawn_player_if_exists()</a>, <a href="#method_ba_GameActivity__transition_in">transition_in()</a>, <a href="#method_ba_GameActivity__transition_out">transition_out()</a></h5>
<h3>Methods Defined or Overridden:</h3>
<h5><a href="#method_ba_CoopGameActivity____init__">&lt;constructor&gt;</a>, <a href="#method_ba_CoopGameActivity__celebrate">celebrate()</a>, <a href="#method_ba_CoopGameActivity__fade_to_red">fade_to_red()</a>, <a href="#method_ba_CoopGameActivity__get_score_type">get_score_type()</a>, <a href="#method_ba_CoopGameActivity__on_begin">on_begin()</a>, <a href="#method_ba_CoopGameActivity__setup_low_life_warning_sound">setup_low_life_warning_sound()</a>, <a href="#method_ba_CoopGameActivity__spawn_player_spaz">spawn_player_spaz()</a>, <a href="#method_ba_CoopGameActivity__supports_session_type">supports_session_type()</a></h5>
<dl>
@ -2143,7 +2144,7 @@ its time with lingering corpses, sound effects, etc.</p>
<h3>Methods Inherited:</h3>
<h5><a href="#method_ba_Activity__add_actor_weak_ref">add_actor_weak_ref()</a>, <a href="#method_ba_Activity__add_player">add_player()</a>, <a href="#method_ba_Activity__add_team">add_team()</a>, <a href="#method_ba_Activity__begin">begin()</a>, <a href="#method_ba_Activity__create_player">create_player()</a>, <a href="#method_ba_Activity__create_team">create_team()</a>, <a href="#method_ba_Activity__dep_is_present">dep_is_present()</a>, <a href="#method_ba_Activity__destroy">destroy()</a>, <a href="#method_ba_Activity__get_dynamic_deps">get_dynamic_deps()</a>, <a href="#method_ba_Activity__has_begun">has_begun()</a>, <a href="#method_ba_Activity__has_ended">has_ended()</a>, <a href="#method_ba_Activity__has_transitioned_in">has_transitioned_in()</a>, <a href="#method_ba_Activity__is_transitioning_out">is_transitioning_out()</a>, <a href="#method_ba_Activity__on_expire">on_expire()</a>, <a href="#method_ba_Activity__on_team_join">on_team_join()</a>, <a href="#method_ba_Activity__on_team_leave">on_team_leave()</a>, <a href="#method_ba_Activity__on_transition_out">on_transition_out()</a>, <a href="#method_ba_Activity__remove_player">remove_player()</a>, <a href="#method_ba_Activity__remove_team">remove_team()</a>, <a href="#method_ba_Activity__retain_actor">retain_actor()</a>, <a href="#method_ba_Activity__set_has_ended">set_has_ended()</a>, <a href="#method_ba_Activity__set_immediate_end">set_immediate_end()</a>, <a href="#method_ba_Activity__transition_in">transition_in()</a>, <a href="#method_ba_Activity__transition_out">transition_out()</a></h5>
<h3>Methods Defined or Overridden:</h3>
<h5><a href="#method_ba_GameActivity____init__">&lt;constructor&gt;</a>, <a href="#method_ba_GameActivity__continue_or_end_game">continue_or_end_game()</a>, <a href="#method_ba_GameActivity__create_settings_ui">create_settings_ui()</a>, <a href="#method_ba_GameActivity__end">end()</a>, <a href="#method_ba_GameActivity__end_game">end_game()</a>, <a href="#method_ba_GameActivity__get_description">get_description()</a>, <a href="#method_ba_GameActivity__get_description_display_string">get_description_display_string()</a>, <a href="#method_ba_GameActivity__get_display_string">get_display_string()</a>, <a href="#method_ba_GameActivity__get_game_settings">get_game_settings()</a>, <a href="#method_ba_GameActivity__get_instance_description">get_instance_description()</a>, <a href="#method_ba_GameActivity__get_instance_description_short">get_instance_description_short()</a>, <a href="#method_ba_GameActivity__get_instance_display_string">get_instance_display_string()</a>, <a href="#method_ba_GameActivity__get_instance_scoreboard_display_string">get_instance_scoreboard_display_string()</a>, <a href="#method_ba_GameActivity__get_name">get_name()</a>, <a href="#method_ba_GameActivity__get_score_info">get_score_info()</a>, <a href="#method_ba_GameActivity__get_settings_display_string">get_settings_display_string()</a>, <a href="#method_ba_GameActivity__get_supported_maps">get_supported_maps()</a>, <a href="#method_ba_GameActivity__get_team_display_string">get_team_display_string()</a>, <a href="#method_ba_GameActivity__handlemessage">handlemessage()</a>, <a href="#method_ba_GameActivity__is_waiting_for_continue">is_waiting_for_continue()</a>, <a href="#method_ba_GameActivity__on_begin">on_begin()</a>, <a href="#method_ba_GameActivity__on_continue">on_continue()</a>, <a href="#method_ba_GameActivity__on_player_join">on_player_join()</a>, <a href="#method_ba_GameActivity__on_player_leave">on_player_leave()</a>, <a href="#method_ba_GameActivity__on_transition_in">on_transition_in()</a>, <a href="#method_ba_GameActivity__project_flag_stand">project_flag_stand()</a>, <a href="#method_ba_GameActivity__respawn_player">respawn_player()</a>, <a href="#method_ba_GameActivity__setup_standard_powerup_drops">setup_standard_powerup_drops()</a>, <a href="#method_ba_GameActivity__setup_standard_time_limit">setup_standard_time_limit()</a>, <a href="#method_ba_GameActivity__show_info">show_info()</a>, <a href="#method_ba_GameActivity__show_scoreboard_info">show_scoreboard_info()</a>, <a href="#method_ba_GameActivity__show_zoom_message">show_zoom_message()</a>, <a href="#method_ba_GameActivity__spawn_player">spawn_player()</a>, <a href="#method_ba_GameActivity__spawn_player_if_exists">spawn_player_if_exists()</a>, <a href="#method_ba_GameActivity__spawn_player_spaz">spawn_player_spaz()</a>, <a href="#method_ba_GameActivity__supports_session_type">supports_session_type()</a></h5>
<h5><a href="#method_ba_GameActivity____init__">&lt;constructor&gt;</a>, <a href="#method_ba_GameActivity__continue_or_end_game">continue_or_end_game()</a>, <a href="#method_ba_GameActivity__create_settings_ui">create_settings_ui()</a>, <a href="#method_ba_GameActivity__end">end()</a>, <a href="#method_ba_GameActivity__end_game">end_game()</a>, <a href="#method_ba_GameActivity__get_description">get_description()</a>, <a href="#method_ba_GameActivity__get_description_display_string">get_description_display_string()</a>, <a href="#method_ba_GameActivity__get_display_string">get_display_string()</a>, <a href="#method_ba_GameActivity__get_game_settings">get_game_settings()</a>, <a href="#method_ba_GameActivity__get_instance_description">get_instance_description()</a>, <a href="#method_ba_GameActivity__get_instance_description_short">get_instance_description_short()</a>, <a href="#method_ba_GameActivity__get_instance_display_string">get_instance_display_string()</a>, <a href="#method_ba_GameActivity__get_instance_scoreboard_display_string">get_instance_scoreboard_display_string()</a>, <a href="#method_ba_GameActivity__get_name">get_name()</a>, <a href="#method_ba_GameActivity__get_score_info">get_score_info()</a>, <a href="#method_ba_GameActivity__get_settings_display_string">get_settings_display_string()</a>, <a href="#method_ba_GameActivity__get_supported_maps">get_supported_maps()</a>, <a href="#method_ba_GameActivity__get_team_display_string">get_team_display_string()</a>, <a href="#method_ba_GameActivity__handlemessage">handlemessage()</a>, <a href="#method_ba_GameActivity__is_waiting_for_continue">is_waiting_for_continue()</a>, <a href="#method_ba_GameActivity__on_begin">on_begin()</a>, <a href="#method_ba_GameActivity__on_continue">on_continue()</a>, <a href="#method_ba_GameActivity__on_player_join">on_player_join()</a>, <a href="#method_ba_GameActivity__on_player_leave">on_player_leave()</a>, <a href="#method_ba_GameActivity__on_transition_in">on_transition_in()</a>, <a href="#method_ba_GameActivity__respawn_player">respawn_player()</a>, <a href="#method_ba_GameActivity__setup_standard_powerup_drops">setup_standard_powerup_drops()</a>, <a href="#method_ba_GameActivity__setup_standard_time_limit">setup_standard_time_limit()</a>, <a href="#method_ba_GameActivity__show_zoom_message">show_zoom_message()</a>, <a href="#method_ba_GameActivity__spawn_player">spawn_player()</a>, <a href="#method_ba_GameActivity__spawn_player_if_exists">spawn_player_if_exists()</a>, <a href="#method_ba_GameActivity__spawn_player_spaz">spawn_player_spaz()</a>, <a href="#method_ba_GameActivity__supports_session_type">supports_session_type()</a></h5>
<dl>
<dt><h4><a name="method_ba_GameActivity____init__">&lt;constructor&gt;</a></dt></h4><dd>
<p><span>ba.GameActivity(settings: Dict[str, Any])</span></p>
@ -2455,15 +2456,6 @@ start playing music, etc. It does not yet have access to players
or teams, however. They remain owned by the previous Activity
up until <a href="#method_ba_Activity__on_begin">ba.Activity.on_begin</a>() is called.</p>
</dd>
<dt><h4><a name="method_ba_GameActivity__project_flag_stand">project_flag_stand()</a></dt></h4><dd>
<p><span>project_flag_stand(self, pos: Sequence[float]) -&gt; None</span></p>
<p>Project a flag-stand onto the ground at the given position.</p>
<p>Useful for games such as capture-the-flag to show where a
movable flag originated from.</p>
</dd>
<dt><h4><a name="method_ba_GameActivity__respawn_player">respawn_player()</a></dt></h4><dd>
<p><span>respawn_player(self, player: PlayerType, respawn_time: Optional[float] = None) -&gt; None</span></p>
@ -2490,21 +2482,6 @@ duration in seconds.
This will be displayed at the top of the screen.
If the time-limit expires, end_game() will be called.</p>
</dd>
<dt><h4><a name="method_ba_GameActivity__show_info">show_info()</a></dt></h4><dd>
<p><span>show_info(self) -&gt; None</span></p>
<p>Show the game description.</p>
</dd>
<dt><h4><a name="method_ba_GameActivity__show_scoreboard_info">show_scoreboard_info()</a></dt></h4><dd>
<p><span>show_scoreboard_info(self) -&gt; None</span></p>
<p>Create the game info display.</p>
<p>This is the thing in the top left corner showing the name
and short description of the game.</p>
</dd>
<dt><h4><a name="method_ba_GameActivity__show_zoom_message">show_zoom_message()</a></dt></h4><dd>
<p><span>show_zoom_message(self, message: <a href="#class_ba_Lstr">ba.Lstr</a>, color: Sequence[float] = (0.9, 0.4, 0.0), scale: float = 0.8, duration: float = 2.0, trail: bool = False) -&gt; None</span></p>
@ -5028,7 +5005,7 @@ of the session.</p>
</dd>
</dl>
<h3>Methods Inherited:</h3>
<h5><a href="#method_ba_GameActivity__add_actor_weak_ref">add_actor_weak_ref()</a>, <a href="#method_ba_GameActivity__add_player">add_player()</a>, <a href="#method_ba_GameActivity__add_team">add_team()</a>, <a href="#method_ba_GameActivity__begin">begin()</a>, <a href="#method_ba_GameActivity__continue_or_end_game">continue_or_end_game()</a>, <a href="#method_ba_GameActivity__create_player">create_player()</a>, <a href="#method_ba_GameActivity__create_settings_ui">create_settings_ui()</a>, <a href="#method_ba_GameActivity__create_team">create_team()</a>, <a href="#method_ba_GameActivity__dep_is_present">dep_is_present()</a>, <a href="#method_ba_GameActivity__destroy">destroy()</a>, <a href="#method_ba_GameActivity__end_game">end_game()</a>, <a href="#method_ba_GameActivity__get_description">get_description()</a>, <a href="#method_ba_GameActivity__get_description_display_string">get_description_display_string()</a>, <a href="#method_ba_GameActivity__get_display_string">get_display_string()</a>, <a href="#method_ba_GameActivity__get_dynamic_deps">get_dynamic_deps()</a>, <a href="#method_ba_GameActivity__get_game_settings">get_game_settings()</a>, <a href="#method_ba_GameActivity__get_instance_description">get_instance_description()</a>, <a href="#method_ba_GameActivity__get_instance_description_short">get_instance_description_short()</a>, <a href="#method_ba_GameActivity__get_instance_display_string">get_instance_display_string()</a>, <a href="#method_ba_GameActivity__get_instance_scoreboard_display_string">get_instance_scoreboard_display_string()</a>, <a href="#method_ba_GameActivity__get_name">get_name()</a>, <a href="#method_ba_GameActivity__get_score_info">get_score_info()</a>, <a href="#method_ba_GameActivity__get_settings_display_string">get_settings_display_string()</a>, <a href="#method_ba_GameActivity__get_supported_maps">get_supported_maps()</a>, <a href="#method_ba_GameActivity__get_team_display_string">get_team_display_string()</a>, <a href="#method_ba_GameActivity__handlemessage">handlemessage()</a>, <a href="#method_ba_GameActivity__has_begun">has_begun()</a>, <a href="#method_ba_GameActivity__has_ended">has_ended()</a>, <a href="#method_ba_GameActivity__has_transitioned_in">has_transitioned_in()</a>, <a href="#method_ba_GameActivity__is_transitioning_out">is_transitioning_out()</a>, <a href="#method_ba_GameActivity__is_waiting_for_continue">is_waiting_for_continue()</a>, <a href="#method_ba_GameActivity__on_continue">on_continue()</a>, <a href="#method_ba_GameActivity__on_expire">on_expire()</a>, <a href="#method_ba_GameActivity__on_player_join">on_player_join()</a>, <a href="#method_ba_GameActivity__on_player_leave">on_player_leave()</a>, <a href="#method_ba_GameActivity__on_team_join">on_team_join()</a>, <a href="#method_ba_GameActivity__on_team_leave">on_team_leave()</a>, <a href="#method_ba_GameActivity__on_transition_out">on_transition_out()</a>, <a href="#method_ba_GameActivity__project_flag_stand">project_flag_stand()</a>, <a href="#method_ba_GameActivity__remove_player">remove_player()</a>, <a href="#method_ba_GameActivity__remove_team">remove_team()</a>, <a href="#method_ba_GameActivity__respawn_player">respawn_player()</a>, <a href="#method_ba_GameActivity__retain_actor">retain_actor()</a>, <a href="#method_ba_GameActivity__set_has_ended">set_has_ended()</a>, <a href="#method_ba_GameActivity__set_immediate_end">set_immediate_end()</a>, <a href="#method_ba_GameActivity__setup_standard_powerup_drops">setup_standard_powerup_drops()</a>, <a href="#method_ba_GameActivity__setup_standard_time_limit">setup_standard_time_limit()</a>, <a href="#method_ba_GameActivity__show_info">show_info()</a>, <a href="#method_ba_GameActivity__show_scoreboard_info">show_scoreboard_info()</a>, <a href="#method_ba_GameActivity__show_zoom_message">show_zoom_message()</a>, <a href="#method_ba_GameActivity__spawn_player">spawn_player()</a>, <a href="#method_ba_GameActivity__spawn_player_if_exists">spawn_player_if_exists()</a>, <a href="#method_ba_GameActivity__transition_in">transition_in()</a>, <a href="#method_ba_GameActivity__transition_out">transition_out()</a></h5>
<h5><a href="#method_ba_GameActivity__add_actor_weak_ref">add_actor_weak_ref()</a>, <a href="#method_ba_GameActivity__add_player">add_player()</a>, <a href="#method_ba_GameActivity__add_team">add_team()</a>, <a href="#method_ba_GameActivity__begin">begin()</a>, <a href="#method_ba_GameActivity__continue_or_end_game">continue_or_end_game()</a>, <a href="#method_ba_GameActivity__create_player">create_player()</a>, <a href="#method_ba_GameActivity__create_settings_ui">create_settings_ui()</a>, <a href="#method_ba_GameActivity__create_team">create_team()</a>, <a href="#method_ba_GameActivity__dep_is_present">dep_is_present()</a>, <a href="#method_ba_GameActivity__destroy">destroy()</a>, <a href="#method_ba_GameActivity__end_game">end_game()</a>, <a href="#method_ba_GameActivity__get_description">get_description()</a>, <a href="#method_ba_GameActivity__get_description_display_string">get_description_display_string()</a>, <a href="#method_ba_GameActivity__get_display_string">get_display_string()</a>, <a href="#method_ba_GameActivity__get_dynamic_deps">get_dynamic_deps()</a>, <a href="#method_ba_GameActivity__get_game_settings">get_game_settings()</a>, <a href="#method_ba_GameActivity__get_instance_description">get_instance_description()</a>, <a href="#method_ba_GameActivity__get_instance_description_short">get_instance_description_short()</a>, <a href="#method_ba_GameActivity__get_instance_display_string">get_instance_display_string()</a>, <a href="#method_ba_GameActivity__get_instance_scoreboard_display_string">get_instance_scoreboard_display_string()</a>, <a href="#method_ba_GameActivity__get_name">get_name()</a>, <a href="#method_ba_GameActivity__get_score_info">get_score_info()</a>, <a href="#method_ba_GameActivity__get_settings_display_string">get_settings_display_string()</a>, <a href="#method_ba_GameActivity__get_supported_maps">get_supported_maps()</a>, <a href="#method_ba_GameActivity__get_team_display_string">get_team_display_string()</a>, <a href="#method_ba_GameActivity__handlemessage">handlemessage()</a>, <a href="#method_ba_GameActivity__has_begun">has_begun()</a>, <a href="#method_ba_GameActivity__has_ended">has_ended()</a>, <a href="#method_ba_GameActivity__has_transitioned_in">has_transitioned_in()</a>, <a href="#method_ba_GameActivity__is_transitioning_out">is_transitioning_out()</a>, <a href="#method_ba_GameActivity__is_waiting_for_continue">is_waiting_for_continue()</a>, <a href="#method_ba_GameActivity__on_continue">on_continue()</a>, <a href="#method_ba_GameActivity__on_expire">on_expire()</a>, <a href="#method_ba_GameActivity__on_player_join">on_player_join()</a>, <a href="#method_ba_GameActivity__on_player_leave">on_player_leave()</a>, <a href="#method_ba_GameActivity__on_team_join">on_team_join()</a>, <a href="#method_ba_GameActivity__on_team_leave">on_team_leave()</a>, <a href="#method_ba_GameActivity__on_transition_out">on_transition_out()</a>, <a href="#method_ba_GameActivity__remove_player">remove_player()</a>, <a href="#method_ba_GameActivity__remove_team">remove_team()</a>, <a href="#method_ba_GameActivity__respawn_player">respawn_player()</a>, <a href="#method_ba_GameActivity__retain_actor">retain_actor()</a>, <a href="#method_ba_GameActivity__set_has_ended">set_has_ended()</a>, <a href="#method_ba_GameActivity__set_immediate_end">set_immediate_end()</a>, <a href="#method_ba_GameActivity__setup_standard_powerup_drops">setup_standard_powerup_drops()</a>, <a href="#method_ba_GameActivity__setup_standard_time_limit">setup_standard_time_limit()</a>, <a href="#method_ba_GameActivity__show_zoom_message">show_zoom_message()</a>, <a href="#method_ba_GameActivity__spawn_player">spawn_player()</a>, <a href="#method_ba_GameActivity__spawn_player_if_exists">spawn_player_if_exists()</a>, <a href="#method_ba_GameActivity__transition_in">transition_in()</a>, <a href="#method_ba_GameActivity__transition_out">transition_out()</a></h5>
<h3>Methods Defined or Overridden:</h3>
<h5><a href="#method_ba_TeamGameActivity____init__">&lt;constructor&gt;</a>, <a href="#method_ba_TeamGameActivity__end">end()</a>, <a href="#method_ba_TeamGameActivity__on_begin">on_begin()</a>, <a href="#method_ba_TeamGameActivity__on_transition_in">on_transition_in()</a>, <a href="#method_ba_TeamGameActivity__spawn_player_spaz">spawn_player_spaz()</a>, <a href="#method_ba_TeamGameActivity__supports_session_type">supports_session_type()</a></h5>
<dl>