Modernized runaround code

This commit is contained in:
Eric Froemling 2020-06-02 20:11:10 -07:00
parent 5b4282eb11
commit ed102842c5
2 changed files with 270 additions and 260 deletions

View File

@ -1752,6 +1752,7 @@
<w>spazappearance</w>
<w>spazbot</w>
<w>spazfactory</w>
<w>spaztype</w>
<w>spazzes</w>
<w>spcall</w>
<w>spcstr</w>

View File

@ -26,6 +26,8 @@
from __future__ import annotations
import random
from dataclasses import dataclass
from enum import Enum
from typing import TYPE_CHECKING
import ba
@ -42,7 +44,46 @@ from bastd.actor.spazbot import (
BomberBotPro, BrawlerBotPro)
if TYPE_CHECKING:
from typing import Type, Any, List, Dict, Tuple, Sequence, Optional
from typing import Type, Any, List, Dict, Tuple, Sequence, Optional, Union
class Preset(Enum):
"""Play presets."""
ENDLESS = 'endless'
ENDLESS_TOURNAMENT = 'endless_tournament'
PRO = 'pro'
PRO_EASY = 'pro_easy'
UBER = 'uber'
UBER_EASY = 'uber_easy'
TOURNAMENT = 'tournament'
TOURNAMENT_UBER = 'tournament_uber'
class Point(Enum):
"""Where we can spawn stuff and the corresponding map attr name."""
BOTTOM_LEFT = 'bot_spawn_bottom_left'
BOTTOM_RIGHT = 'bot_spawn_bottom_right'
START = 'bot_spawn_start'
@dataclass
class Spawn:
"""Defines a bot spawn."""
type: Type[SpazBot]
path: int = 0
point: Optional[Point] = None
@dataclass
class Spacing:
"""Defines spacing between spawns."""
duration: float
@dataclass
class Wave:
"""Defines a wave of enemies."""
entries: List[Union[Spawn, Spacing, None]]
class Player(ba.Player['Team']):
@ -90,7 +131,7 @@ class RunaroundGame(ba.CoopGameActivity[Player, Team]):
settings['map'] = 'Tower D'
super().__init__(settings)
shared = SharedObjects.get()
self._preset = str(settings.get('preset', 'pro'))
self._preset = Preset(settings.get('preset', 'pro'))
self._player_death_sound = ba.getsound('playerDeath')
self._new_wave_sound = ba.getsound('scoreHit01')
@ -112,9 +153,11 @@ class RunaroundGame(ba.CoopGameActivity[Player, Team]):
self._score_region_material = ba.Material()
self._score_region_material.add_actions(
conditions=('they_have_material', shared.player_material),
actions=(('modify_part_collision', 'collide',
True), ('modify_part_collision', 'physical', False),
('call', 'at_connect', self._handle_reached_end)))
actions=(
('modify_part_collision', 'collide', True),
('modify_part_collision', 'physical', False),
('call', 'at_connect', self._handle_reached_end),
))
self._last_wave_end_time = ba.time()
self._player_has_picked_up_powerup = False
@ -129,7 +172,7 @@ class RunaroundGame(ba.CoopGameActivity[Player, Team]):
self._dingsoundhigh = ba.getsound('dingSmallHigh')
self._exclude_powerups: Optional[List[str]] = None
self._have_tnt: Optional[bool] = None
self._waves: Optional[List[Dict[str, Any]]] = None
self._waves: Optional[List[Wave]] = None
self._bots = SpazBotSet()
self._tntspawner: Optional[TNTSpawner] = None
self._lives_bg: Optional[ba.NodeActor] = None
@ -161,206 +204,186 @@ class RunaroundGame(ba.CoopGameActivity[Player, Team]):
def on_begin(self) -> None:
super().on_begin()
player_count = len(self.players)
hard = self._preset not in ['pro_easy', 'uber_easy']
hard = self._preset not in {Preset.PRO_EASY, Preset.UBER_EASY}
if self._preset in ['pro', 'pro_easy', 'tournament']:
if self._preset in {Preset.PRO, Preset.PRO_EASY, Preset.TOURNAMENT}:
self._exclude_powerups = ['curse']
self._have_tnt = True
self._waves = [
{'entries': [
{'type': BomberBot, 'path': 3 if hard else 2},
{'type': BomberBot, 'path': 2},
{'type': BomberBot, 'path': 2} if hard else None,
{'type': BomberBot, 'path': 2} if player_count > 1
else None,
{'type': BomberBot, 'path': 1} if hard else None,
{'type': BomberBot, 'path': 1} if player_count > 2
else None,
{'type': BomberBot, 'path': 1} if player_count > 3
else None,
]},
{'entries': [
{'type': BomberBot, 'path': 1} if hard else None,
{'type': BomberBot, 'path': 2} if hard else None,
{'type': BomberBot, 'path': 2},
{'type': BomberBot, 'path': 2},
{'type': BomberBot, 'path': 2} if player_count > 3
else None,
{'type': BrawlerBot, 'path': 3},
{'type': BrawlerBot, 'path': 3},
{'type': BrawlerBot, 'path': 3} if hard else None,
{'type': BrawlerBot, 'path': 3} if player_count > 1
else None,
{'type': BrawlerBot, 'path': 3} if player_count > 2
else None,
]},
{'entries': [
{'type': ChargerBot, 'path': 2} if hard else None,
{'type': ChargerBot, 'path': 2} if player_count > 2
else None,
{'type': TriggerBot, 'path': 2},
{'type': TriggerBot, 'path': 2} if player_count > 1
else None,
{'type': 'spacing', 'duration': 3.0},
{'type': BomberBot, 'path': 2} if hard else None,
{'type': BomberBot, 'path': 2} if hard else None,
{'type': BomberBot, 'path': 2},
{'type': BomberBot, 'path': 3} if hard else None,
{'type': BomberBot, 'path': 3},
{'type': BomberBot, 'path': 3},
{'type': BomberBot, 'path': 3} if player_count > 3
else None,
]},
{'entries': [
{'type': TriggerBot, 'path': 1} if hard else None,
{'type': 'spacing', 'duration': 1.0} if hard else None,
{'type': TriggerBot, 'path': 2},
{'type': 'spacing', 'duration': 1.0},
{'type': TriggerBot, 'path': 3},
{'type': 'spacing', 'duration': 1.0},
{'type': TriggerBot, 'path': 1} if hard else None,
{'type': 'spacing', 'duration': 1.0} if hard else None,
{'type': TriggerBot, 'path': 2},
{'type': 'spacing', 'duration': 1.0},
{'type': TriggerBot, 'path': 3},
{'type': 'spacing', 'duration': 1.0},
{'type': TriggerBot, 'path': 1}
if (player_count > 1 and hard) else None,
{'type': 'spacing', 'duration': 1.0},
{'type': TriggerBot, 'path': 2} if player_count > 2
else None,
{'type': 'spacing', 'duration': 1.0},
{'type': TriggerBot, 'path': 3} if player_count > 3
else None,
{'type': 'spacing', 'duration': 1.0},
]},
{'entries': [
{'type': ChargerBotProShielded if hard
else ChargerBot, 'path': 1},
{'type': BrawlerBot, 'path': 2} if hard else None,
{'type': BrawlerBot, 'path': 2},
{'type': BrawlerBot, 'path': 2},
{'type': BrawlerBot, 'path': 3} if hard else None,
{'type': BrawlerBot, 'path': 3},
{'type': BrawlerBot, 'path': 3},
{'type': BrawlerBot, 'path': 3} if player_count > 1
else None,
{'type': BrawlerBot, 'path': 3} if player_count > 2
else None,
{'type': BrawlerBot, 'path': 3} if player_count > 3
else None,
]},
{'entries': [
{'type': BomberBotProShielded, 'path': 3},
{'type': 'spacing', 'duration': 1.5},
{'type': BomberBotProShielded, 'path': 2},
{'type': 'spacing', 'duration': 1.5},
{'type': BomberBotProShielded, 'path': 1} if hard
else None,
{'type': 'spacing', 'duration': 1.0} if hard else None,
{'type': BomberBotProShielded, 'path': 3},
{'type': 'spacing', 'duration': 1.5},
{'type': BomberBotProShielded, 'path': 2},
{'type': 'spacing', 'duration': 1.5},
{'type': BomberBotProShielded, 'path': 1} if hard
else None,
{'type': 'spacing', 'duration': 1.5} if hard else None,
{'type': BomberBotProShielded, 'path': 3}
if player_count > 1 else None,
{'type': 'spacing', 'duration': 1.5},
{'type': BomberBotProShielded, 'path': 2}
if player_count > 2 else None,
{'type': 'spacing', 'duration': 1.5},
{'type': BomberBotProShielded, 'path': 1}
if player_count > 3 else None,
]},
] # yapf: disable
elif self._preset in ['uber_easy', 'uber', 'tournament_uber']:
Wave(entries=[
Spawn(BomberBot, path=3 if hard else 2),
Spawn(BomberBot, path=2),
Spawn(BomberBot, path=2) if hard else None,
Spawn(BomberBot, path=2) if player_count > 1 else None,
Spawn(BomberBot, path=1) if hard else None,
Spawn(BomberBot, path=1) if player_count > 2 else None,
Spawn(BomberBot, path=1) if player_count > 3 else None,
]),
Wave(entries=[
Spawn(BomberBot, path=1) if hard else None,
Spawn(BomberBot, path=2) if hard else None,
Spawn(BomberBot, path=2),
Spawn(BomberBot, path=2),
Spawn(BomberBot, path=2) if player_count > 3 else None,
Spawn(BrawlerBot, path=3),
Spawn(BrawlerBot, path=3),
Spawn(BrawlerBot, path=3) if hard else None,
Spawn(BrawlerBot, path=3) if player_count > 1 else None,
Spawn(BrawlerBot, path=3) if player_count > 2 else None,
]),
Wave(entries=[
Spawn(ChargerBot, path=2) if hard else None,
Spawn(ChargerBot, path=2) if player_count > 2 else None,
Spawn(TriggerBot, path=2),
Spawn(TriggerBot, path=2) if player_count > 1 else None,
Spacing(duration=3.0),
Spawn(BomberBot, path=2) if hard else None,
Spawn(BomberBot, path=2) if hard else None,
Spawn(BomberBot, path=2),
Spawn(BomberBot, path=3) if hard else None,
Spawn(BomberBot, path=3),
Spawn(BomberBot, path=3),
Spawn(BomberBot, path=3) if player_count > 3 else None,
]),
Wave(entries=[
Spawn(TriggerBot, path=1) if hard else None,
Spacing(duration=1.0) if hard else None,
Spawn(TriggerBot, path=2),
Spacing(duration=1.0),
Spawn(TriggerBot, path=3),
Spacing(duration=1.0),
Spawn(TriggerBot, path=1) if hard else None,
Spacing(duration=1.0) if hard else None,
Spawn(TriggerBot, path=2),
Spacing(duration=1.0),
Spawn(TriggerBot, path=3),
Spacing(duration=1.0),
Spawn(TriggerBot, path=1) if (
player_count > 1 and hard) else None,
Spacing(duration=1.0),
Spawn(TriggerBot, path=2) if player_count > 2 else None,
Spacing(duration=1.0),
Spawn(TriggerBot, path=3) if player_count > 3 else None,
Spacing(duration=1.0),
]),
Wave(entries=[
Spawn(ChargerBotProShielded if hard else ChargerBot,
path=1),
Spawn(BrawlerBot, path=2) if hard else None,
Spawn(BrawlerBot, path=2),
Spawn(BrawlerBot, path=2),
Spawn(BrawlerBot, path=3) if hard else None,
Spawn(BrawlerBot, path=3),
Spawn(BrawlerBot, path=3),
Spawn(BrawlerBot, path=3) if player_count > 1 else None,
Spawn(BrawlerBot, path=3) if player_count > 2 else None,
Spawn(BrawlerBot, path=3) if player_count > 3 else None,
]),
Wave(entries=[
Spawn(BomberBotProShielded, path=3),
Spacing(duration=1.5),
Spawn(BomberBotProShielded, path=2),
Spacing(duration=1.5),
Spawn(BomberBotProShielded, path=1) if hard else None,
Spacing(duration=1.0) if hard else None,
Spawn(BomberBotProShielded, path=3),
Spacing(duration=1.5),
Spawn(BomberBotProShielded, path=2),
Spacing(duration=1.5),
Spawn(BomberBotProShielded, path=1) if hard else None,
Spacing(duration=1.5) if hard else None,
Spawn(BomberBotProShielded, path=3
) if player_count > 1 else None,
Spacing(duration=1.5),
Spawn(BomberBotProShielded, path=2
) if player_count > 2 else None,
Spacing(duration=1.5),
Spawn(BomberBotProShielded, path=1
) if player_count > 3 else None,
]),
]
elif self._preset in {
Preset.UBER_EASY, Preset.UBER, Preset.TOURNAMENT_UBER
}:
self._exclude_powerups = []
self._have_tnt = True
self._waves = [
{'entries': [
{'type': TriggerBot, 'path': 1} if hard else None,
{'type': TriggerBot, 'path': 2},
{'type': TriggerBot, 'path': 2},
{'type': TriggerBot, 'path': 3},
{'type': BrawlerBotPro if hard
else BrawlerBot, 'point': 'bottom_left'},
{'type': BrawlerBotPro, 'point': 'bottom_right'}
if player_count > 2 else None,
]},
{'entries': [
{'type': ChargerBot, 'path': 2},
{'type': ChargerBot, 'path': 3},
{'type': ChargerBot, 'path': 1} if hard else None,
{'type': ChargerBot, 'path': 2},
{'type': ChargerBot, 'path': 3},
{'type': ChargerBot, 'path': 1} if player_count > 2
else None,
]},
{'entries': [
{'type': BomberBotProShielded, 'path': 1} if hard
else None,
{'type': BomberBotProShielded, 'path': 2},
{'type': BomberBotProShielded, 'path': 2},
{'type': BomberBotProShielded, 'path': 3},
{'type': BomberBotProShielded, 'path': 3},
{'type': ChargerBot, 'point': 'bottom_right'},
{'type': ChargerBot, 'point': 'bottom_left'}
if player_count > 2 else None,
]},
{'entries': [
{'type': TriggerBotPro, 'path': 1}
if hard else None,
{'type': TriggerBotPro, 'path': 1 if hard else 2},
{'type': TriggerBotPro, 'path': 1 if hard else 2},
{'type': TriggerBotPro, 'path': 1 if hard else 2},
{'type': TriggerBotPro, 'path': 1 if hard else 2},
{'type': TriggerBotPro, 'path': 1 if hard else 2},
{'type': TriggerBotPro, 'path': 1 if hard else 2}
if player_count > 1 else None,
{'type': TriggerBotPro, 'path': 1 if hard else 2}
if player_count > 3 else None,
]},
{'entries': [
{'type': TriggerBotProShielded if hard
else TriggerBotPro, 'point': 'bottom_left'},
{'type': TriggerBotProShielded,
'point': 'bottom_right'}
if hard else None,
{'type': TriggerBotProShielded,
'point': 'bottom_right'}
if player_count > 2 else None,
{'type': BomberBot, 'path': 3},
{'type': BomberBot, 'path': 3},
{'type': 'spacing', 'duration': 5.0},
{'type': BrawlerBot, 'path': 2},
{'type': BrawlerBot, 'path': 2},
{'type': 'spacing', 'duration': 5.0},
{'type': TriggerBot, 'path': 1} if hard else None,
{'type': TriggerBot, 'path': 1} if hard else None,
]},
{'entries': [
{'type': BomberBotProShielded, 'path': 2},
{'type': BomberBotProShielded, 'path': 2} if hard
else None,
{'type': StickyBot, 'point': 'bottom_right'},
{'type': BomberBotProShielded, 'path': 2},
{'type': BomberBotProShielded, 'path': 2},
{'type': StickyBot, 'point': 'bottom_right'}
if player_count > 2 else None,
{'type': BomberBotProShielded, 'path': 2},
{'type': ExplodeyBot, 'point': 'bottom_left'},
{'type': BomberBotProShielded, 'path': 2},
{'type': BomberBotProShielded, 'path': 2}
if player_count > 1 else None,
{'type': 'spacing', 'duration': 5.0},
{'type': StickyBot, 'point': 'bottom_left'},
{'type': 'spacing', 'duration': 2.0},
{'type': ExplodeyBot, 'point': 'bottom_right'},
]},
] # yapf: disable
elif self._preset in ['endless', 'endless_tournament']:
Wave(entries=[
Spawn(TriggerBot, path=1) if hard else None,
Spawn(TriggerBot, path=2),
Spawn(TriggerBot, path=2),
Spawn(TriggerBot, path=3),
Spawn(BrawlerBotPro if hard else BrawlerBot,
point=Point.BOTTOM_LEFT),
Spawn(BrawlerBotPro, point=Point.BOTTOM_RIGHT
) if player_count > 2 else None,
]),
Wave(entries=[
Spawn(ChargerBot, path=2),
Spawn(ChargerBot, path=3),
Spawn(ChargerBot, path=1) if hard else None,
Spawn(ChargerBot, path=2),
Spawn(ChargerBot, path=3),
Spawn(ChargerBot, path=1) if player_count > 2 else None,
]),
Wave(entries=[
Spawn(BomberBotProShielded, path=1) if hard else None,
Spawn(BomberBotProShielded, path=2),
Spawn(BomberBotProShielded, path=2),
Spawn(BomberBotProShielded, path=3),
Spawn(BomberBotProShielded, path=3),
Spawn(ChargerBot, point=Point.BOTTOM_RIGHT),
Spawn(ChargerBot, point=Point.BOTTOM_LEFT
) if player_count > 2 else None,
]),
Wave(entries=[
Spawn(TriggerBotPro, path=1) if hard else None,
Spawn(TriggerBotPro, path=1 if hard else 2),
Spawn(TriggerBotPro, path=1 if hard else 2),
Spawn(TriggerBotPro, path=1 if hard else 2),
Spawn(TriggerBotPro, path=1 if hard else 2),
Spawn(TriggerBotPro, path=1 if hard else 2),
Spawn(TriggerBotPro, path=1 if hard else 2
) if player_count > 1 else None,
Spawn(TriggerBotPro, path=1 if hard else 2
) if player_count > 3 else None,
]),
Wave(entries=[
Spawn(TriggerBotProShielded if hard else TriggerBotPro,
point=Point.BOTTOM_LEFT),
Spawn(TriggerBotProShielded, point=Point.BOTTOM_RIGHT
) if hard else None,
Spawn(TriggerBotProShielded, point=Point.BOTTOM_RIGHT
) if player_count > 2 else None,
Spawn(BomberBot, path=3),
Spawn(BomberBot, path=3),
Spacing(duration=5.0),
Spawn(BrawlerBot, path=2),
Spawn(BrawlerBot, path=2),
Spacing(duration=5.0),
Spawn(TriggerBot, path=1) if hard else None,
Spawn(TriggerBot, path=1) if hard else None,
]),
Wave(entries=[
Spawn(BomberBotProShielded, path=2),
Spawn(BomberBotProShielded, path=2) if hard else None,
Spawn(StickyBot, point=Point.BOTTOM_RIGHT),
Spawn(BomberBotProShielded, path=2),
Spawn(BomberBotProShielded, path=2),
Spawn(StickyBot, point=Point.BOTTOM_RIGHT
) if player_count > 2 else None,
Spawn(BomberBotProShielded, path=2),
Spawn(ExplodeyBot, point=Point.BOTTOM_LEFT),
Spawn(BomberBotProShielded, path=2),
Spawn(BomberBotProShielded, path=2
) if player_count > 1 else None,
Spacing(duration=5.0),
Spawn(StickyBot, point=Point.BOTTOM_LEFT),
Spacing(duration=2.0),
Spawn(ExplodeyBot, point=Point.BOTTOM_RIGHT),
]),
]
elif self._preset in {Preset.ENDLESS, Preset.ENDLESS_TOURNAMENT}:
self._exclude_powerups = []
self._have_tnt = True
@ -480,7 +503,7 @@ class RunaroundGame(ba.CoopGameActivity[Player, Team]):
self._spawn_center[1],
self._spawn_center[2] + random.uniform(-1.5, 1.5))
spaz = self.spawn_player_spaz(player, position=pos)
if self._preset in ['pro_easy', 'uber_easy']:
if self._preset in {Preset.PRO_EASY, Preset.UBER_EASY}:
spaz.impact_scale = 0.25
# Add the material that causes us to hit the player-wall.
@ -580,7 +603,7 @@ class RunaroundGame(ba.CoopGameActivity[Player, Team]):
self._time_bonus_timer = None
self._time_bonus_text = None
if self._preset in ['endless', 'endless_tournament']:
if self._preset in {Preset.ENDLESS, Preset.ENDLESS_TOURNAMENT}:
won = False
else:
assert self._waves is not None
@ -604,7 +627,7 @@ class RunaroundGame(ba.CoopGameActivity[Player, Team]):
if won:
# Completion achievements:
if self._preset in ['pro', 'pro_easy']:
if self._preset in {Preset.PRO, Preset.PRO_EASY}:
self._award_achievement('Pro Runaround Victory',
sound=False)
if self._lives == self._start_lives:
@ -612,7 +635,7 @@ class RunaroundGame(ba.CoopGameActivity[Player, Team]):
if not self._player_has_picked_up_powerup:
self._award_achievement('Precision Bombing',
sound=False)
elif self._preset in ['uber', 'uber_easy']:
elif self._preset in {Preset.UBER, Preset.UBER_EASY}:
self._award_achievement('Uber Runaround Victory',
sound=False)
if self._lives == self._start_lives:
@ -717,13 +740,13 @@ class RunaroundGame(ba.CoopGameActivity[Player, Team]):
t_sec = 0.0
base_delay = 0.5
delay = 0.0
bot_types: List[Optional[Dict[str, Any]]] = []
bot_types: List[Union[Spawn, Spacing, None]] = []
if self._preset in ['endless', 'endless_tournament']:
if self._preset in {Preset.ENDLESS, Preset.ENDLESS_TOURNAMENT}:
level = self._wavenum
target_points = (level + 1) * 8.0
group_count = random.randint(1, 3)
entries = []
entries: List[Union[Spawn, Spacing, None]] = []
spaz_types: List[Tuple[Type[SpazBot], float]] = []
if level < 6:
spaz_types += [(BomberBot, 5.0)]
@ -811,13 +834,11 @@ class RunaroundGame(ba.CoopGameActivity[Player, Team]):
this_target_point_s *= 0.7
def _add_defender(defender_type: Tuple[Type[SpazBot], float],
pnt: str) -> Tuple[float, Dict[str, Any]]:
# FIXME: should look into this warning
pnt: Point) -> Tuple[float, Spawn]:
# This is ok because we call it immediately.
# pylint: disable=cell-var-from-loop
return this_target_point_s * defender_type[1], {
'type': defender_type[0],
'point': pnt
}
return this_target_point_s * defender_type[1], Spawn(
defender_type[0], point=pnt)
# Add defenders.
defender_type1 = defender_types[random.randrange(
@ -829,10 +850,10 @@ class RunaroundGame(ba.CoopGameActivity[Player, Team]):
or (group == 2 and level > 5)):
if random.random() < min(0.75, (level - 1) * 0.11):
this_target_point_s, defender1 = _add_defender(
defender_type1, 'bottom_left')
defender_type1, Point.BOTTOM_LEFT)
if random.random() < min(0.75, (level - 1) * 0.04):
this_target_point_s, defender2 = _add_defender(
defender_type2, 'bottom_right')
defender_type2, Point.BOTTOM_RIGHT)
spaz_type = spaz_types[random.randrange(len(spaz_types))]
member_count = max(
@ -846,12 +867,9 @@ class RunaroundGame(ba.CoopGameActivity[Player, Team]):
this_path = random.randint(1, 3) # Random.
else:
this_path = path
entries.append({'type': spaz_type[0], 'path': this_path})
entries.append(Spawn(spaz_type[0], path=this_path))
if spacing != 0.0:
entries.append({
'type': 'spacing',
'duration': spacing
})
entries.append(Spacing(duration=spacing))
if defender1 is not None:
entries.append(defender1)
@ -866,15 +884,15 @@ class RunaroundGame(ba.CoopGameActivity[Player, Team]):
spacing = 1.0
else:
spacing = 1.0
entries.append({'type': 'spacing', 'duration': spacing})
entries.append(Spacing(duration=spacing))
wave = {'entries': entries}
wave = Wave(entries=entries)
else:
assert self._waves is not None
wave = self._waves[self._wavenum - 1]
bot_types += wave['entries']
bot_types += wave.entries
self._time_bonus_mult = 1.0
this_flawless_bonus = 0
non_runner_spawn_time = 1.0
@ -882,36 +900,27 @@ class RunaroundGame(ba.CoopGameActivity[Player, Team]):
for info in bot_types:
if info is None:
continue
bot_type = info['type']
path = -1
if bot_type is not None:
if bot_type == 'non_runner_delay':
non_runner_spawn_time += info['duration']
continue
if bot_type == 'spacing':
t_sec += info['duration']
continue
try:
path = info['path']
except Exception:
path = random.randint(1, 3)
self._time_bonus_mult += bot_type.points_mult * 0.02
this_flawless_bonus += bot_type.points_mult * 5
if isinstance(info, Spacing):
t_sec += info.duration
continue
bot_type = info.type
path = info.path
self._time_bonus_mult += bot_type.points_mult * 0.02
this_flawless_bonus += bot_type.points_mult * 5
# If its got a position, use that.
try:
point = info['point']
except Exception:
point = 'start'
if info.point is not None:
point = info.point
else:
point = Point.START
# Space our our slower bots.
delay = base_delay
delay /= self._get_bot_speed(bot_type)
t_sec += delay * 0.5
tcall = ba.Call(self.add_bot_at_point, point, {
'type': bot_type,
'path': path
}, 0.1 if point == 'start' else non_runner_spawn_time)
tcall = ba.Call(
self.add_bot_at_point, point, bot_type, path,
0.1 if point is Point.START else non_runner_spawn_time)
ba.timer(t_sec, tcall)
t_sec += delay * 0.5
@ -954,12 +963,12 @@ class RunaroundGame(ba.CoopGameActivity[Player, Team]):
# player could fill the whole map with them)
self._last_wave_end_time = ba.time() + t_sec
totalwaves = str(len(self._waves)) if self._waves is not None else '??'
txtval = ba.Lstr(
value='${A} ${B}',
subs=[('${A}', ba.Lstr(resource='waveText')),
('${B}', str(self._wavenum) +
('' if self._preset in ['endless', 'endless_tournament']
else f'/{totalwaves}'))])
txtval = ba.Lstr(value='${A} ${B}',
subs=[('${A}', ba.Lstr(resource='waveText')),
('${B}',
str(self._wavenum) + ('' if self._preset in {
Preset.ENDLESS, Preset.ENDLESS_TOURNAMENT
} else f'/{totalwaves}'))])
self._wave_text = ba.NodeActor(
ba.newnode('text',
attrs={
@ -987,20 +996,20 @@ class RunaroundGame(ba.CoopGameActivity[Player, Team]):
setattr(spaz, 'r_walk_speed', self._get_bot_speed(spaz_type))
def add_bot_at_point(self,
point: str,
spaz_info: Dict[str, Any],
point: Point,
spaztype: Type[SpazBot],
path: int,
spawn_time: float = 0.1) -> None:
"""Add the given type bot with the given delay (in seconds)."""
# Don't add if the game has ended.
if self._game_over:
return
pos = self.map.defs.points['bot_spawn_' + point][:3]
self._bots.spawn_bot(spaz_info['type'],
pos = self.map.defs.points[point.value][:3]
self._bots.spawn_bot(spaztype,
pos=pos,
spawn_time=spawn_time,
on_spawn_call=ba.Call(self._on_bot_spawn,
spaz_info['path']))
on_spawn_call=ba.Call(self._on_bot_spawn, path))
def _update_time_bonus(self) -> None:
self._time_bonus = int(self._time_bonus * 0.91)
@ -1022,7 +1031,7 @@ class RunaroundGame(ba.CoopGameActivity[Player, Team]):
def _update_scores(self) -> None:
score = self._score
if self._preset == 'endless':
if self._preset is Preset.ENDLESS:
if score >= 500:
self._award_achievement('Runaround Master')
if score >= 1000:
@ -1148,8 +1157,8 @@ class RunaroundGame(ba.CoopGameActivity[Player, Team]):
ba.playsound(self._dingsound if importance == 1 else
self._dingsoundhigh,
volume=0.6)
except Exception as exc:
print('EXC in Runaround on SpazBotDiedMessage:', exc)
except Exception:
ba.print_exception('Error on SpazBotDiedMessage')
# Normally we pull scores from the score-set, but if there's no
# player lets be explicit.