Modernized onslaught code and other cleanup

This commit is contained in:
Eric Froemling 2020-05-24 01:40:38 -07:00
parent e6755d9be8
commit 72be5c0b8d
18 changed files with 669 additions and 651 deletions

View File

@ -4132,16 +4132,16 @@
"assets/build/windows/x64/python.exe": "https://files.ballistica.net/cache/ba1/25/a7/dc87c1be41605eb6fefd0145144c", "assets/build/windows/x64/python.exe": "https://files.ballistica.net/cache/ba1/25/a7/dc87c1be41605eb6fefd0145144c",
"assets/build/windows/x64/python37.dll": "https://files.ballistica.net/cache/ba1/b9/e4/d912f56e42e9991bcbb4c804cfcb", "assets/build/windows/x64/python37.dll": "https://files.ballistica.net/cache/ba1/b9/e4/d912f56e42e9991bcbb4c804cfcb",
"assets/build/windows/x64/pythonw.exe": "https://files.ballistica.net/cache/ba1/6c/bb/b6f52c306aa4e88061510e96cefe", "assets/build/windows/x64/pythonw.exe": "https://files.ballistica.net/cache/ba1/6c/bb/b6f52c306aa4e88061510e96cefe",
"build/prefab/linux-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b1/22/e87fa53bad26b90154a8ac2383b5", "build/prefab/linux-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/5a/42/5238d5de1cf94a07a513ea2b3e1b",
"build/prefab/linux-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/75/8f/4eabb293c30168da4ef63047c8de", "build/prefab/linux-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/39/48/2f0e4350a080373301de625e2cc4",
"build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/7d/cf/0260a6399173881606846ea7080b", "build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/c0/1d/dbc0a5e2ca05b626cbeffd6def6c",
"build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/04/29/28d7d0ef9ac8fc9816bf002afaa8", "build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/ec/a8/5c58d6b5e1d844640334c35ad3af",
"build/prefab/mac-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/56/3b/09554ebdb31e64d3ddc145bc1eb8", "build/prefab/mac-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/3d/0a/76b615f9bcb9bf4f0ca745060d40",
"build/prefab/mac-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6f/2b/d0629250709393bc39dd30f54043", "build/prefab/mac-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/01/6b/0f623ac481e3553e352c1cd3cb7e",
"build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/cc/30/f7120527ef4a402a656f38af1e65", "build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/c4/a5/3cad1ced77551369dc56c6bca5fb",
"build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/fa/66/963c96391fcb5dae4da0999d04dc", "build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/3b/3f/55094817619cae66f941a9f6db8c",
"build/prefab/windows-server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/84/fd/db055e722538fba088572f9c7423", "build/prefab/windows-server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/ec/6b/7aa29831a746672f9984cbb1dbf1",
"build/prefab/windows-server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/7b/f0/82920a407e5627da5b32bd3d7364", "build/prefab/windows-server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/07/4c/00a6136d0bd5573946d10e294720",
"build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/d0/0c/a8bb182f1762d13521da694d0a3c", "build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/8d/8d/af068e67244cbb28444b27ae66d7",
"build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/6d/57/baa2f3d7ba2345d94535ff2f04cb" "build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/f4/62/eb7cb26c952df481b757dcf53f9c"
} }

View File

@ -525,10 +525,7 @@ class Activity(DependencyComponent, Generic[PlayerType, TeamType]):
(internal) (internal)
""" """
# Is this ever still happening?... assert not self._has_begun
if self._has_begun:
print_error("_begin called twice; this shouldn't happen")
return
# Inherit stats from the session. # Inherit stats from the session.
self._stats = session.stats self._stats = session.stats
@ -791,6 +788,7 @@ class Activity(DependencyComponent, Generic[PlayerType, TeamType]):
if player: if player:
try: try:
sessionplayer = player.sessionplayer sessionplayer = player.sessionplayer
player.reset()
sessionplayer.set_node(None) sessionplayer.set_node(None)
sessionplayer.set_activity(None) sessionplayer.set_activity(None)
sessionplayer.gameplayer = None sessionplayer.gameplayer = None
@ -818,7 +816,7 @@ class Activity(DependencyComponent, Generic[PlayerType, TeamType]):
self._activity_data.destroy() self._activity_data.destroy()
except Exception: except Exception:
print_exception( print_exception(
'Exception during ba.Activity._expire() destroying data:') 'Error during ba.Activity._expire() destroying data:')
def _prune_dead_actors(self) -> None: def _prune_dead_actors(self) -> None:
self._actor_refs = [a for a in self._actor_refs if a] self._actor_refs = [a for a in self._actor_refs if a]

View File

@ -1094,10 +1094,10 @@ class GameActivity(Activity[PlayerType, TeamType]):
def _standard_drop_powerup(self, index: int, expire: bool = True) -> None: def _standard_drop_powerup(self, index: int, expire: bool = True) -> None:
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bastd.actor import powerupbox from bastd.actor.powerupbox import PowerupBox, PowerupBoxFactory
powerupbox.PowerupBox( PowerupBox(
position=self.map.powerup_spawn_points[index], position=self.map.powerup_spawn_points[index],
poweruptype=powerupbox.get_factory().get_random_powerup_type(), poweruptype=PowerupBoxFactory.get().get_random_powerup_type(),
expire=expire).autoretain() expire=expire).autoretain()
def _standard_drop_powerups(self) -> None: def _standard_drop_powerups(self) -> None:

View File

@ -99,6 +99,12 @@ class Player(Generic[TeamType]):
self._nodeactor = NodeActor(node) self._nodeactor = NodeActor(node)
sessionplayer.set_node(node) sessionplayer.set_node(node)
def reset(self) -> None:
"""(internal)"""
self._nodeactor = None
self.actor = None
self.team = None # type: ignore
@property @property
def sessionplayer(self) -> ba.SessionPlayer: def sessionplayer(self) -> ba.SessionPlayer:
"""Return the ba.SessionPlayer corresponding to this Player. """Return the ba.SessionPlayer corresponding to this Player.

View File

@ -139,7 +139,7 @@ class FlagPickedUpMessage:
@dataclass @dataclass
class FlagDeathMessage: class FlagDiedMessage:
"""A message saying a ba.Flag has died. """A message saying a ba.Flag has died.
category: Message Classes category: Message Classes
@ -335,7 +335,7 @@ class Flag(ba.Actor):
if self.node: if self.node:
self.node.delete() self.node.delete()
if not msg.immediate: if not msg.immediate:
self.activity.handlemessage(FlagDeathMessage(self)) self.activity.handlemessage(FlagDiedMessage(self))
elif isinstance(msg, ba.HitMessage): elif isinstance(msg, ba.HitMessage):
assert self.node assert self.node
assert msg.force_direction is not None assert msg.force_direction is not None

View File

@ -90,18 +90,6 @@ class PlayerSpaz(Spaz):
self._player = player self._player = player
self._drive_player_position() self._drive_player_position()
# @property
# def player(self, playertype: Type[PlayerType]) -> PlayerType:
# """The ba.Player associated with this Spaz.
# If the player no longer exists, raises an ba.PlayerNotFoundError.
# """
# player = self._player
# assert isinstance(player, playertype)
# if not player:
# raise ba.PlayerNotFoundError()
# return player
@overload @overload
def getplayer(self, def getplayer(self,
playertype: Type[PlayerType], playertype: Type[PlayerType],

View File

@ -182,21 +182,21 @@ class PowerupBoxFactory:
self._lastpoweruptype = ptype self._lastpoweruptype = ptype
return ptype return ptype
@staticmethod
def get_factory() -> PowerupBoxFactory: def get() -> PowerupBoxFactory:
"""Return a shared ba.PowerupBoxFactory object, creating if necessary.""" """Return a shared ba.PowerupBoxFactory object, creating if needed."""
activity = ba.getactivity() activity = ba.getactivity()
if activity is None: if activity is None:
raise RuntimeError('no current activity') raise RuntimeError('no current activity')
try: try:
# FIXME: et better way to store stuff with activity # FIXME: et better way to store stuff with activity
# pylint: disable=protected-access # pylint: disable=protected-access
# noinspection PyProtectedMember # noinspection PyProtectedMember
return activity._shared_powerup_factory # type: ignore return activity._shared_powerup_factory # type: ignore
except Exception: except Exception:
factory = activity._shared_powerup_factory = ( # type: ignore factory = activity._shared_powerup_factory = ( # type: ignore
PowerupBoxFactory()) PowerupBoxFactory())
return factory return factory
class PowerupBox(ba.Actor): class PowerupBox(ba.Actor):
@ -229,7 +229,7 @@ class PowerupBox(ba.Actor):
super().__init__() super().__init__()
factory = get_factory() factory = PowerupBoxFactory.get()
self.poweruptype = poweruptype self.poweruptype = poweruptype
self._powersgiven = False self._powersgiven = False
@ -293,7 +293,7 @@ class PowerupBox(ba.Actor):
self._handlemessage_sanity_check() self._handlemessage_sanity_check()
if isinstance(msg, ba.PowerupAcceptMessage): if isinstance(msg, ba.PowerupAcceptMessage):
factory = get_factory() factory = PowerupBoxFactory.get()
assert self.node assert self.node
if self.poweruptype == 'health': if self.poweruptype == 'health':
ba.playsound(factory.health_powerup_sound, ba.playsound(factory.health_powerup_sound,

View File

@ -28,7 +28,7 @@ from typing import TYPE_CHECKING
import ba import ba
from bastd.actor import bomb as stdbomb from bastd.actor import bomb as stdbomb
from bastd.actor import powerupbox from bastd.actor.powerupbox import PowerupBoxFactory
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import (Any, Sequence, Optional, Dict, List, Union, Callable, from typing import (Any, Sequence, Optional, Dict, List, Union, Callable,
@ -147,7 +147,7 @@ class Spaz(ba.Actor):
extras_material = [] extras_material = []
if can_accept_powerups: if can_accept_powerups:
pam = powerupbox.get_factory().powerup_accept_material pam = PowerupBoxFactory.get().powerup_accept_material
materials.append(pam) materials.append(pam)
roller_materials.append(pam) roller_materials.append(pam)
extras_material.append(pam) extras_material.append(pam)
@ -252,7 +252,7 @@ class Spaz(ba.Actor):
self._score_text_hide_timer: Optional[ba.Timer] = None self._score_text_hide_timer: Optional[ba.Timer] = None
self._last_stand_pos: Optional[Sequence[float]] = None self._last_stand_pos: Optional[Sequence[float]] = None
# deprecated stuff.. need to make these into lists # Deprecated stuff.. should make these into lists.
self.punch_callback: Optional[Callable[[Spaz], Any]] = None self.punch_callback: Optional[Callable[[Spaz], Any]] = None
self.pick_up_powerup_callback: Optional[Callable[[Spaz], Any]] = None self.pick_up_powerup_callback: Optional[Callable[[Spaz], Any]] = None
@ -273,6 +273,7 @@ class Spaz(ba.Actor):
Add a call to be run whenever this Spaz drops a bomb. Add a call to be run whenever this Spaz drops a bomb.
The spaz and the newly-dropped bomb are passed as arguments. The spaz and the newly-dropped bomb are passed as arguments.
""" """
assert not self.expired
self._dropped_bomb_callbacks.append(call) self._dropped_bomb_callbacks.append(call)
def is_alive(self) -> bool: def is_alive(self) -> bool:
@ -725,7 +726,7 @@ class Spaz(ba.Actor):
if self.pick_up_powerup_callback is not None: if self.pick_up_powerup_callback is not None:
self.pick_up_powerup_callback(self) self.pick_up_powerup_callback(self)
if msg.poweruptype == 'triple_bombs': if msg.poweruptype == 'triple_bombs':
tex = powerupbox.get_factory().tex_bomb tex = PowerupBoxFactory.get().tex_bomb
self._flash_billboard(tex) self._flash_billboard(tex)
self.set_bomb_count(3) self.set_bomb_count(3)
if self.powerups_expire: if self.powerups_expire:
@ -785,7 +786,7 @@ class Spaz(ba.Actor):
timeformat=ba.TimeFormat.MILLISECONDS)) timeformat=ba.TimeFormat.MILLISECONDS))
elif msg.poweruptype == 'punch': elif msg.poweruptype == 'punch':
self._has_boxing_gloves = True self._has_boxing_gloves = True
tex = powerupbox.get_factory().tex_punch tex = PowerupBoxFactory.get().tex_punch
self._flash_billboard(tex) self._flash_billboard(tex)
self.equip_boxing_gloves() self.equip_boxing_gloves()
if self.powerups_expire: if self.powerups_expire:
@ -845,7 +846,7 @@ class Spaz(ba.Actor):
if m != factory.curse_material)) if m != factory.curse_material))
self.node.curse_death_time = 0 self.node.curse_death_time = 0
self.hitpoints = self.hitpoints_max self.hitpoints = self.hitpoints_max
self._flash_billboard(powerupbox.get_factory().tex_health) self._flash_billboard(PowerupBoxFactory.get().tex_health)
self.node.hurt = 0 self.node.hurt = 0
self._last_hit_time = None self._last_hit_time = None
self._num_times_hit = 0 self._num_times_hit = 0
@ -1292,7 +1293,7 @@ class Spaz(ba.Actor):
if self.land_mine_count != 0: if self.land_mine_count != 0:
self.node.counter_text = 'x' + str(self.land_mine_count) self.node.counter_text = 'x' + str(self.land_mine_count)
self.node.counter_texture = ( self.node.counter_texture = (
powerupbox.get_factory().tex_land_mines) PowerupBoxFactory.get().tex_land_mines)
else: else:
self.node.counter_text = '' self.node.counter_text = ''
@ -1380,13 +1381,13 @@ class Spaz(ba.Actor):
ba.playsound(sound, position=pos, volume=5.0) ba.playsound(sound, position=pos, volume=5.0)
def _get_bomb_type_tex(self) -> ba.Texture: def _get_bomb_type_tex(self) -> ba.Texture:
bomb_factory = powerupbox.get_factory() factory = PowerupBoxFactory.get()
if self.bomb_type == 'sticky': if self.bomb_type == 'sticky':
return bomb_factory.tex_sticky_bombs return factory.tex_sticky_bombs
if self.bomb_type == 'ice': if self.bomb_type == 'ice':
return bomb_factory.tex_ice_bombs return factory.tex_ice_bombs
if self.bomb_type == 'impact': if self.bomb_type == 'impact':
return bomb_factory.tex_impact_bombs return factory.tex_impact_bombs
raise ValueError('invalid bomb type') raise ValueError('invalid bomb type')
def _flash_billboard(self, tex: ba.Texture) -> None: def _flash_billboard(self, tex: ba.Texture) -> None:
@ -1411,7 +1412,7 @@ class Spaz(ba.Actor):
def _gloves_wear_off_flash(self) -> None: def _gloves_wear_off_flash(self) -> None:
if self.node: if self.node:
self.node.boxing_gloves_flashing = True self.node.boxing_gloves_flashing = True
self.node.billboard_texture = powerupbox.get_factory().tex_punch self.node.billboard_texture = PowerupBoxFactory.get().tex_punch
self.node.billboard_opacity = 1.0 self.node.billboard_opacity = 1.0
self.node.billboard_cross_out = True self.node.billboard_cross_out = True
@ -1425,21 +1426,21 @@ class Spaz(ba.Actor):
self._punch_cooldown = factory.punch_cooldown self._punch_cooldown = factory.punch_cooldown
self._has_boxing_gloves = False self._has_boxing_gloves = False
if self.node: if self.node:
ba.playsound(powerupbox.get_factory().powerdown_sound, ba.playsound(PowerupBoxFactory.get().powerdown_sound,
position=self.node.position) position=self.node.position)
self.node.boxing_gloves = False self.node.boxing_gloves = False
self.node.billboard_opacity = 0.0 self.node.billboard_opacity = 0.0
def _multi_bomb_wear_off_flash(self) -> None: def _multi_bomb_wear_off_flash(self) -> None:
if self.node: if self.node:
self.node.billboard_texture = powerupbox.get_factory().tex_bomb self.node.billboard_texture = PowerupBoxFactory.get().tex_bomb
self.node.billboard_opacity = 1.0 self.node.billboard_opacity = 1.0
self.node.billboard_cross_out = True self.node.billboard_cross_out = True
def _multi_bomb_wear_off(self) -> None: def _multi_bomb_wear_off(self) -> None:
self.set_bomb_count(self.default_bomb_count) self.set_bomb_count(self.default_bomb_count)
if self.node: if self.node:
ba.playsound(powerupbox.get_factory().powerdown_sound, ba.playsound(PowerupBoxFactory.get().powerdown_sound,
position=self.node.position) position=self.node.position)
self.node.billboard_opacity = 0.0 self.node.billboard_opacity = 0.0
@ -1452,6 +1453,6 @@ class Spaz(ba.Actor):
def _bomb_wear_off(self) -> None: def _bomb_wear_off(self) -> None:
self.bomb_type = self.bomb_type_default self.bomb_type = self.bomb_type_default
if self.node: if self.node:
ba.playsound(powerupbox.get_factory().powerdown_sound, ba.playsound(PowerupBoxFactory.get().powerdown_sound,
position=self.node.position) position=self.node.position)
self.node.billboard_opacity = 0.0 self.node.billboard_opacity = 0.0

View File

@ -547,7 +547,7 @@ class CaptureTheFlagGame(ba.TeamGameActivity[Player, Team]):
# Augment standard behavior. # Augment standard behavior.
super().handlemessage(msg) super().handlemessage(msg)
self.respawn_player(msg.getplayer(Player)) self.respawn_player(msg.getplayer(Player))
elif isinstance(msg, stdflag.FlagDeathMessage): elif isinstance(msg, stdflag.FlagDiedMessage):
assert isinstance(msg.flag, CTFFlag) assert isinstance(msg.flag, CTFFlag)
ba.timer(0.1, ba.Call(self._spawn_flag_for_team, msg.flag.team)) ba.timer(0.1, ba.Call(self._spawn_flag_for_team, msg.flag.team))
elif isinstance(msg, stdflag.FlagPickedUpMessage): elif isinstance(msg, stdflag.FlagPickedUpMessage):

View File

@ -36,6 +36,7 @@ from bastd.actor.bomb import TNTSpawner
from bastd.actor.playerspaz import PlayerSpaz from bastd.actor.playerspaz import PlayerSpaz
from bastd.actor.scoreboard import Scoreboard from bastd.actor.scoreboard import Scoreboard
from bastd.actor.respawnicon import RespawnIcon from bastd.actor.respawnicon import RespawnIcon
from bastd.actor.powerupbox import PowerupBoxFactory, PowerupBox
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any, List, Type, Dict, Sequence, Optional, Union from typing import Any, List, Type, Dict, Sequence, Optional, Union
@ -105,6 +106,7 @@ class FootballTeamGame(ba.TeamGameActivity[Player, Team]):
'default': 1.0 'default': 1.0
}), }),
] ]
default_music = ba.MusicType.FOOTBALL
@classmethod @classmethod
def supports_session_type(cls, sessiontype: Type[ba.Session]) -> bool: def supports_session_type(cls, sessiontype: Type[ba.Session]) -> bool:
@ -125,13 +127,15 @@ class FootballTeamGame(ba.TeamGameActivity[Player, Team]):
self._score_sound = ba.getsound('score') self._score_sound = ba.getsound('score')
self._swipsound = ba.getsound('swip') self._swipsound = ba.getsound('swip')
self._whistle_sound = ba.getsound('refWhistle') self._whistle_sound = ba.getsound('refWhistle')
self.score_region_material = ba.Material() self._score_region_material = ba.Material()
self.score_region_material.add_actions( self._score_region_material.add_actions(
conditions=('they_have_material', conditions=('they_have_material',
stdflag.get_factory().flagmaterial), stdflag.get_factory().flagmaterial),
actions=(('modify_part_collision', 'collide', actions=(
True), ('modify_part_collision', 'physical', False), ('modify_part_collision', 'collide', True),
('call', 'at_connect', self._handle_score))) ('modify_part_collision', 'physical', False),
('call', 'at_connect', self._handle_score),
))
self._flag_spawn_pos: Optional[Sequence[float]] = None self._flag_spawn_pos: Optional[Sequence[float]] = None
self._score_regions: List[ba.NodeActor] = [] self._score_regions: List[ba.NodeActor] = []
self._flag: Optional[FootballFlag] = None self._flag: Optional[FootballFlag] = None
@ -158,10 +162,6 @@ class FootballTeamGame(ba.TeamGameActivity[Player, Team]):
return 'score ${ARG1} touchdowns', touchdowns return 'score ${ARG1} touchdowns', touchdowns
return 'score a touchdown' return 'score a touchdown'
def on_transition_in(self) -> None:
self.default_music = ba.MusicType.FOOTBALL
super().on_transition_in()
def on_begin(self) -> None: def on_begin(self) -> None:
super().on_begin() super().on_begin()
self.setup_standard_time_limit(self._time_limit) self.setup_standard_time_limit(self._time_limit)
@ -176,7 +176,7 @@ class FootballTeamGame(ba.TeamGameActivity[Player, Team]):
'position': defs.boxes['goal1'][0:3], 'position': defs.boxes['goal1'][0:3],
'scale': defs.boxes['goal1'][6:9], 'scale': defs.boxes['goal1'][6:9],
'type': 'box', 'type': 'box',
'materials': (self.score_region_material, ) 'materials': (self._score_region_material, )
}))) })))
self._score_regions.append( self._score_regions.append(
ba.NodeActor( ba.NodeActor(
@ -185,7 +185,7 @@ class FootballTeamGame(ba.TeamGameActivity[Player, Team]):
'position': defs.boxes['goal2'][0:3], 'position': defs.boxes['goal2'][0:3],
'scale': defs.boxes['goal2'][6:9], 'scale': defs.boxes['goal2'][6:9],
'type': 'box', 'type': 'box',
'materials': (self.score_region_material, ) 'materials': (self._score_region_material, )
}))) })))
self._update_scoreboard() self._update_scoreboard()
ba.playsound(self._chant_sound) ba.playsound(self._chant_sound)
@ -282,7 +282,7 @@ class FootballTeamGame(ba.TeamGameActivity[Player, Team]):
self.respawn_player(msg.getplayer(Player)) self.respawn_player(msg.getplayer(Player))
# Respawn dead flags. # Respawn dead flags.
elif isinstance(msg, stdflag.FlagDeathMessage): elif isinstance(msg, stdflag.FlagDiedMessage):
if not self.has_ended(): if not self.has_ended():
self._flag_respawn_timer = ba.Timer(3.0, self._spawn_flag) self._flag_respawn_timer = ba.Timer(3.0, self._spawn_flag)
self._flag_respawn_light = ba.NodeActor( self._flag_respawn_light = ba.NodeActor(
@ -333,6 +333,7 @@ class FootballCoopGame(ba.CoopGameActivity[Player, Team]):
name = 'Football' name = 'Football'
tips = ['Use the pick-up button to grab the flag < ${PICKUP} >'] tips = ['Use the pick-up button to grab the flag < ${PICKUP} >']
score_info = ba.ScoreInfo(scoretype=ba.ScoreType.MILLISECONDS, version='B') score_info = ba.ScoreInfo(scoretype=ba.ScoreType.MILLISECONDS, version='B')
default_music = ba.MusicType.FOOTBALL
# FIXME: Need to update co-op games to use get_score_info. # FIXME: Need to update co-op games to use get_score_info.
def get_score_type(self) -> str: def get_score_type(self) -> str:
@ -369,16 +370,18 @@ class FootballCoopGame(ba.CoopGameActivity[Player, Team]):
self._score_region_material.add_actions( self._score_region_material.add_actions(
conditions=('they_have_material', conditions=('they_have_material',
stdflag.get_factory().flagmaterial), stdflag.get_factory().flagmaterial),
actions=(('modify_part_collision', 'collide', actions=(
True), ('modify_part_collision', 'physical', False), ('modify_part_collision', 'collide', True),
('call', 'at_connect', self._handle_score))) ('modify_part_collision', 'physical', False),
('call', 'at_connect', self._handle_score),
))
self._powerup_center = (0, 2, 0) self._powerup_center = (0, 2, 0)
self._powerup_spread = (10, 5.5) self._powerup_spread = (10, 5.5)
self._player_has_dropped_bomb = False self._player_has_dropped_bomb = False
self._player_has_punched = False self._player_has_punched = False
self._scoreboard: Optional[Scoreboard] = None self._scoreboard: Optional[Scoreboard] = None
self._flag_spawn_pos: Optional[Sequence[float]] = None self._flag_spawn_pos: Optional[Sequence[float]] = None
self.score_regions: List[ba.NodeActor] = [] self._score_regions: List[ba.NodeActor] = []
self._exclude_powerups: List[str] = [] self._exclude_powerups: List[str] = []
self._have_tnt = False self._have_tnt = False
self._bot_types_initial: Optional[List[Type[spazbot.SpazBot]]] = None self._bot_types_initial: Optional[List[Type[spazbot.SpazBot]]] = None
@ -392,14 +395,13 @@ class FootballCoopGame(ba.CoopGameActivity[Player, Team]):
self._bots = spazbot.BotSet() self._bots = spazbot.BotSet()
self._bot_spawn_timer: Optional[ba.Timer] = None self._bot_spawn_timer: Optional[ba.Timer] = None
self._powerup_drop_timer: Optional[ba.Timer] = None self._powerup_drop_timer: Optional[ba.Timer] = None
self.scoring_team: Optional[Team] = None self._scoring_team: Optional[Team] = None
self._final_time_ms: Optional[int] = None self._final_time_ms: Optional[int] = None
self._time_text_timer: Optional[ba.Timer] = None self._time_text_timer: Optional[ba.Timer] = None
self._flag_respawn_light: Optional[ba.Actor] = None self._flag_respawn_light: Optional[ba.Actor] = None
self._flag: Optional[FootballFlag] = None self._flag: Optional[FootballFlag] = None
def on_transition_in(self) -> None: def on_transition_in(self) -> None:
self.default_music = ba.MusicType.FOOTBALL
super().on_transition_in() super().on_transition_in()
self._scoreboard = Scoreboard() self._scoreboard = Scoreboard()
self._flag_spawn_pos = self.map.get_flag_position(None) self._flag_spawn_pos = self.map.get_flag_position(None)
@ -407,7 +409,7 @@ class FootballCoopGame(ba.CoopGameActivity[Player, Team]):
# Set up the two score regions. # Set up the two score regions.
defs = self.map.defs defs = self.map.defs
self.score_regions.append( self._score_regions.append(
ba.NodeActor( ba.NodeActor(
ba.newnode('region', ba.newnode('region',
attrs={ attrs={
@ -416,7 +418,7 @@ class FootballCoopGame(ba.CoopGameActivity[Player, Team]):
'type': 'box', 'type': 'box',
'materials': [self._score_region_material] 'materials': [self._score_region_material]
}))) })))
self.score_regions.append( self._score_regions.append(
ba.NodeActor( ba.NodeActor(
ba.newnode('region', ba.newnode('region',
attrs={ attrs={
@ -608,12 +610,11 @@ class FootballCoopGame(ba.CoopGameActivity[Player, Team]):
closest_bot.target_flag = self._flag closest_bot.target_flag = self._flag
def _drop_powerup(self, index: int, poweruptype: str = None) -> None: def _drop_powerup(self, index: int, poweruptype: str = None) -> None:
from bastd.actor import powerupbox
if poweruptype is None: if poweruptype is None:
poweruptype = (powerupbox.get_factory().get_random_powerup_type( poweruptype = (PowerupBoxFactory.get().get_random_powerup_type(
excludetypes=self._exclude_powerups)) excludetypes=self._exclude_powerups))
powerupbox.PowerupBox(position=self.map.powerup_spawn_points[index], PowerupBox(position=self.map.powerup_spawn_points[index],
poweruptype=poweruptype).autoretain() poweruptype=poweruptype).autoretain()
def _start_powerup_drops(self) -> None: def _start_powerup_drops(self) -> None:
self._powerup_drop_timer = ba.Timer(3.0, self._powerup_drop_timer = ba.Timer(3.0,
@ -624,7 +625,6 @@ class FootballCoopGame(ba.CoopGameActivity[Player, Team]):
standard_points: bool = False, standard_points: bool = False,
poweruptype: str = None) -> None: poweruptype: str = None) -> None:
"""Generic powerup drop.""" """Generic powerup drop."""
from bastd.actor import powerupbox
if standard_points: if standard_points:
spawnpoints = self.map.powerup_spawn_points spawnpoints = self.map.powerup_spawn_points
for i, _point in enumerate(spawnpoints): for i, _point in enumerate(spawnpoints):
@ -638,9 +638,9 @@ class FootballCoopGame(ba.CoopGameActivity[Player, Team]):
-self._powerup_spread[1], self._powerup_spread[1])) -self._powerup_spread[1], self._powerup_spread[1]))
# Drop one random one somewhere. # Drop one random one somewhere.
powerupbox.PowerupBox( PowerupBox(
position=point, position=point,
poweruptype=powerupbox.get_factory().get_random_powerup_type( poweruptype=PowerupBoxFactory.get().get_random_powerup_type(
excludetypes=self._exclude_powerups)).autoretain() excludetypes=self._exclude_powerups)).autoretain()
def _kill_flag(self) -> None: def _kill_flag(self) -> None:
@ -664,8 +664,8 @@ class FootballCoopGame(ba.CoopGameActivity[Player, Team]):
# See which score region it was. # See which score region it was.
region = ba.get_collision_info('source_node') region = ba.get_collision_info('source_node')
i = None i = None
for i in range(len(self.score_regions)): for i in range(len(self._score_regions)):
if region == self.score_regions[i].node: if region == self._score_regions[i].node:
break break
for team in [self.teams[0], self._bot_team]: for team in [self.teams[0], self._bot_team]:
@ -740,7 +740,7 @@ class FootballCoopGame(ba.CoopGameActivity[Player, Team]):
self._scoreboard.set_team_value(team, team.score, win_score) self._scoreboard.set_team_value(team, team.score, win_score)
if team.score >= win_score: if team.score >= win_score:
if not have_scoring_team: if not have_scoring_team:
self.scoring_team = team self._scoring_team = team
if team is self._bot_team: if team is self._bot_team:
self.continue_or_end_game() self.continue_or_end_game()
else: else:
@ -835,7 +835,7 @@ class FootballCoopGame(ba.CoopGameActivity[Player, Team]):
self._award_achievement('Super Mega Punch') self._award_achievement('Super Mega Punch')
# Respawn dead flags. # Respawn dead flags.
elif isinstance(msg, stdflag.FlagDeathMessage): elif isinstance(msg, stdflag.FlagDiedMessage):
assert isinstance(msg.flag, FootballFlag) assert isinstance(msg.flag, FootballFlag)
msg.flag.respawn_timer = ba.Timer(3.0, self._spawn_flag) msg.flag.respawn_timer = ba.Timer(3.0, self._spawn_flag)
self._flag_respawn_light = ba.NodeActor( self._flag_respawn_light = ba.NodeActor(

View File

@ -29,7 +29,7 @@ from typing import TYPE_CHECKING
import ba import ba
from bastd.actor.scoreboard import Scoreboard from bastd.actor.scoreboard import Scoreboard
from bastd.actor import powerupbox from bastd.actor.powerupbox import PowerupBoxFactory
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any, Sequence, Dict, Type, List, Optional, Union from typing import Any, Sequence, Dict, Type, List, Optional, Union
@ -137,6 +137,7 @@ class HockeyGame(ba.TeamGameActivity[Player, Team]):
'default': 1.0 'default': 1.0
}), }),
] ]
default_music = ba.MusicType.HOCKEY
@classmethod @classmethod
def supports_session_type(cls, sessiontype: Type[ba.Session]) -> bool: def supports_session_type(cls, sessiontype: Type[ba.Session]) -> bool:
@ -182,7 +183,7 @@ class HockeyGame(ba.TeamGameActivity[Player, Team]):
# We want the puck to kill powerups; not get stopped by them # We want the puck to kill powerups; not get stopped by them
self.puck_material.add_actions( self.puck_material.add_actions(
conditions=('they_have_material', conditions=('they_have_material',
powerupbox.get_factory().powerup_material), PowerupBoxFactory.get().powerup_material),
actions=(('modify_part_collision', 'physical', False), actions=(('modify_part_collision', 'physical', False),
('message', 'their_node', 'at_connect', ba.DieMessage()))) ('message', 'their_node', 'at_connect', ba.DieMessage())))
self._score_region_material = ba.Material() self._score_region_material = ba.Material()
@ -205,10 +206,6 @@ class HockeyGame(ba.TeamGameActivity[Player, Team]):
return 'score a goal' return 'score a goal'
return 'score ${ARG1} goals', self.settings_raw['Score to Win'] return 'score ${ARG1} goals', self.settings_raw['Score to Win']
def on_transition_in(self) -> None:
self.default_music = ba.MusicType.HOCKEY
super().on_transition_in()
def on_begin(self) -> None: def on_begin(self) -> None:
super().on_begin() super().on_begin()
@ -328,7 +325,6 @@ class HockeyGame(ba.TeamGameActivity[Player, Team]):
self.end(results=results) self.end(results=results)
def _update_scoreboard(self) -> None: def _update_scoreboard(self) -> None:
""" update scoreboard and check for winners """
winscore = self.settings_raw['Score to Win'] winscore = self.settings_raw['Score to Win']
for team in self.teams: for team in self.teams:
self._scoreboard.set_team_value(team, team.gamedata['score'], self._scoreboard.set_team_value(team, team.gamedata['score'],

View File

@ -31,7 +31,7 @@ from typing import TYPE_CHECKING
import ba import ba
from bastd.actor.playerspaz import PlayerSpaz from bastd.actor.playerspaz import PlayerSpaz
from bastd.actor.scoreboard import Scoreboard from bastd.actor.scoreboard import Scoreboard
from bastd.actor.flag import (Flag, FlagDroppedMessage, FlagDeathMessage, from bastd.actor.flag import (Flag, FlagDroppedMessage, FlagDiedMessage,
FlagPickedUpMessage) FlagPickedUpMessage)
if TYPE_CHECKING: if TYPE_CHECKING:
@ -270,7 +270,7 @@ class KeepAwayGame(ba.TeamGameActivity[Player, Team]):
# Augment standard behavior. # Augment standard behavior.
super().handlemessage(msg) super().handlemessage(msg)
self.respawn_player(msg.getplayer(Player)) self.respawn_player(msg.getplayer(Player))
elif isinstance(msg, FlagDeathMessage): elif isinstance(msg, FlagDiedMessage):
self._spawn_flag() self._spawn_flag()
elif isinstance(msg, (FlagDroppedMessage, FlagPickedUpMessage)): elif isinstance(msg, (FlagDroppedMessage, FlagPickedUpMessage)):
self._update_flag_state() self._update_flag_state()

File diff suppressed because it is too large Load Diff

View File

@ -33,6 +33,7 @@ from bastd.actor import spazbot
from bastd.actor.bomb import TNTSpawner from bastd.actor.bomb import TNTSpawner
from bastd.actor.scoreboard import Scoreboard from bastd.actor.scoreboard import Scoreboard
from bastd.actor.respawnicon import RespawnIcon from bastd.actor.respawnicon import RespawnIcon
from bastd.actor.powerupbox import PowerupBox, PowerupBoxFactory
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Type, Any, List, Dict, Tuple, Sequence, Optional from typing import Type, Any, List, Dict, Tuple, Sequence, Optional
@ -482,12 +483,11 @@ class RunaroundGame(ba.CoopGameActivity[Player, Team]):
self._player_has_picked_up_powerup = True self._player_has_picked_up_powerup = True
def _drop_powerup(self, index: int, poweruptype: str = None) -> None: def _drop_powerup(self, index: int, poweruptype: str = None) -> None:
from bastd.actor import powerupbox
if poweruptype is None: if poweruptype is None:
poweruptype = (powerupbox.get_factory().get_random_powerup_type( poweruptype = (PowerupBoxFactory.get().get_random_powerup_type(
excludetypes=self._exclude_powerups)) excludetypes=self._exclude_powerups))
powerupbox.PowerupBox(position=self.map.powerup_spawn_points[index], PowerupBox(position=self.map.powerup_spawn_points[index],
poweruptype=poweruptype).autoretain() poweruptype=poweruptype).autoretain()
def _start_powerup_drops(self) -> None: def _start_powerup_drops(self) -> None:
ba.timer(3.0, self._drop_powerups, repeat=True) ba.timer(3.0, self._drop_powerups, repeat=True)
@ -496,7 +496,6 @@ class RunaroundGame(ba.CoopGameActivity[Player, Team]):
standard_points: bool = False, standard_points: bool = False,
force_first: str = None) -> None: force_first: str = None) -> None:
""" Generic powerup drop """ """ Generic powerup drop """
from bastd.actor import powerupbox
# If its been a minute since our last wave finished emerging, stop # If its been a minute since our last wave finished emerging, stop
# giving out land-mine powerups. (prevents players from waiting # giving out land-mine powerups. (prevents players from waiting
@ -522,9 +521,9 @@ class RunaroundGame(ba.CoopGameActivity[Player, Team]):
# drop one random one somewhere.. # drop one random one somewhere..
assert self._exclude_powerups is not None assert self._exclude_powerups is not None
powerupbox.PowerupBox( PowerupBox(
position=pos, position=pos,
poweruptype=powerupbox.get_factory().get_random_powerup_type( poweruptype=PowerupBoxFactory.get().get_random_powerup_type(
excludetypes=self._exclude_powerups + excludetypes=self._exclude_powerups +
extra_excludes)).autoretain() extra_excludes)).autoretain()

View File

@ -71,6 +71,7 @@ class TargetPracticeGame(ba.TeamGameActivity[Player, Team]):
'default': True 'default': True
}), }),
] ]
default_music = ba.MusicType.FORWARD_MARCH
@classmethod @classmethod
def get_supported_maps(cls, sessiontype: Type[ba.Session]) -> List[str]: def get_supported_maps(cls, sessiontype: Type[ba.Session]) -> List[str]:
@ -92,9 +93,6 @@ class TargetPracticeGame(ba.TeamGameActivity[Player, Team]):
self._enable_impact_bombs = bool(settings['Enable Impact Bombs']) self._enable_impact_bombs = bool(settings['Enable Impact Bombs'])
self._enable_triple_bombs = bool(settings['Enable Triple Bombs']) self._enable_triple_bombs = bool(settings['Enable Triple Bombs'])
# Base class overrides
self.default_music = ba.MusicType.FORWARD_MARCH
def on_team_join(self, team: Team) -> None: def on_team_join(self, team: Team) -> None:
if self.has_begun(): if self.has_begun():
self.update_scoreboard() self.update_scoreboard()

View File

@ -30,6 +30,7 @@ from bastd.actor import spazbot
from bastd.actor.playerspaz import PlayerSpaz from bastd.actor.playerspaz import PlayerSpaz
from bastd.actor.bomb import TNTSpawner from bastd.actor.bomb import TNTSpawner
from bastd.actor.scoreboard import Scoreboard from bastd.actor.scoreboard import Scoreboard
from bastd.actor.powerupbox import PowerupBoxFactory, PowerupBox
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any, Dict, Type, List, Optional, Sequence from typing import Any, Dict, Type, List, Optional, Sequence
@ -137,12 +138,11 @@ class TheLastStandGame(ba.CoopGameActivity[Player, Team]):
ba.WeakCall(self._update_bots)) ba.WeakCall(self._update_bots))
def _drop_powerup(self, index: int, poweruptype: str = None) -> None: def _drop_powerup(self, index: int, poweruptype: str = None) -> None:
from bastd.actor import powerupbox
if poweruptype is None: if poweruptype is None:
poweruptype = (powerupbox.get_factory().get_random_powerup_type( poweruptype = (PowerupBoxFactory.get().get_random_powerup_type(
excludetypes=self._excludepowerups)) excludetypes=self._excludepowerups))
powerupbox.PowerupBox(position=self.map.powerup_spawn_points[index], PowerupBox(position=self.map.powerup_spawn_points[index],
poweruptype=poweruptype).autoretain() poweruptype=poweruptype).autoretain()
def _start_powerup_drops(self) -> None: def _start_powerup_drops(self) -> None:
self._powerup_drop_timer = ba.Timer(3.0, self._powerup_drop_timer = ba.Timer(3.0,
@ -171,7 +171,7 @@ class TheLastStandGame(ba.CoopGameActivity[Player, Team]):
# Drop one random one somewhere. # Drop one random one somewhere.
powerupbox.PowerupBox( powerupbox.PowerupBox(
position=drop_pt, position=drop_pt,
poweruptype=powerupbox.get_factory().get_random_powerup_type( poweruptype=PowerupBoxFactory.get().get_random_powerup_type(
excludetypes=self._excludepowerups)).autoretain() excludetypes=self._excludepowerups)).autoretain()
def do_end(self, outcome: str) -> None: def do_end(self, outcome: str) -> None:

View File

@ -858,8 +858,8 @@ def _preload1() -> None:
]: ]:
ba.gettexture(tex) ba.gettexture(tex)
ba.gettexture('bg') ba.gettexture('bg')
from bastd.actor import powerupbox from bastd.actor.powerupbox import PowerupBoxFactory
powerupbox.get_factory() PowerupBoxFactory.get()
ba.timer(0.1, _preload2) ba.timer(0.1, _preload2)

View File

@ -1,5 +1,5 @@
<!-- THIS FILE IS AUTO GENERATED; DO NOT EDIT BY HAND --> <!-- THIS FILE IS AUTO GENERATED; DO NOT EDIT BY HAND -->
<h4><em>last updated on 2020-05-23 for Ballistica version 1.5.0 build 20026</em></h4> <h4><em>last updated on 2020-05-24 for Ballistica version 1.5.0 build 20026</em></h4>
<p>This page documents the Python classes and functions in the 'ba' module, <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> 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> <hr>