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