bombsquad-plugin-manager/plugins/minigames/bot_chase.py

219 lines
7.4 KiB
Python
Raw Permalink Normal View History

2025-01-26 16:18:19 +05:30
# ba_meta require api 9
2024-01-26 16:07:34 +03:00
from __future__ import annotations
from typing import TYPE_CHECKING
import babase
import bascenev1 as bs
import random
2025-01-26 16:18:19 +05:30
from bascenev1lib.actor.spazbot import SpazBotSet, SpazBot, SpazBotDiedMessage
2024-01-26 16:07:34 +03:00
from bascenev1lib.actor.onscreentimer import OnScreenTimer
if TYPE_CHECKING:
from typing import Any, List, Type, Optional
class Player(bs.Player['Team']):
"""Our player type for this game"""
def __init__(self) -> None:
super().__init__()
self.death_time: Optional[float] = None
class MrSpazBot(SpazBot):
"""Our bot type for this game"""
character = 'Spaz'
run = True
charge_dist_min = 10.0
charge_dist_max = 9999.0
charge_speed_min = 1.0
charge_speed_max = 1.0
throw_dist_min = 9999
throw_dist_max = 9999
class Team(bs.Team[Player]):
"""Our team type for this minigame"""
# ba_meta export bascenev1.GameActivity
class BotChaseGame(bs.TeamGameActivity[Player, Team]):
"""Our goal is to survive from spawning bots"""
name = 'Bot Chase'
description = 'Try to survive from bots!'
available_settings = [
bs.BoolSetting(
'Epic Mode',
default=False
),
]
announce_player_deaths = True
@classmethod
def get_supported_maps(cls, sessiontype: Type[bs.Session]) -> List[str]:
return ['Football Stadium']
@classmethod
def supports_session_type(cls, sessiontype: Type[bs.Session]) -> bool:
2024-01-26 13:12:06 +00:00
# Coop session unused
return (issubclass(sessiontype, bs.FreeForAllSession) or issubclass(sessiontype, bs.DualTeamSession) or issubclass(sessiontype, bs.CoopSession))
2024-01-26 16:07:34 +03:00
def __init__(self, settings: dict):
super().__init__(settings)
self._bots = SpazBotSet()
self._epic_mode = bool(settings['Epic Mode'])
self._timer: Optional[OnScreenTimer] = None
self._last_player_death_time: Optional[float] = None
if self._epic_mode:
self.slow_motion = True
self.default_music = (bs.MusicType.EPIC if self._epic_mode else bs.MusicType.FORWARD_MARCH)
def on_player_join(self, player: Player) -> None:
if self.has_begun():
bs.broadcastmessage(
babase.Lstr(resource='playerDelayedJoinText',
2024-01-26 13:12:06 +00:00
subs=[('${PLAYER}', player.getname(full=True))]),
2024-01-26 16:07:34 +03:00
color=(0, 1, 0),
)
assert self._timer is not None
player.death_time = self._timer.getstarttime()
return
self.spawn_player(player)
def on_player_leave(self, player: Player) -> None:
super().on_player_leave(player)
self._check_end_game()
def spawn_player(self, player: Player) -> bs.Actor:
spaz = self.spawn_player_spaz(player)
spaz.connect_controls_to_player(enable_punch=True,
enable_bomb=True,
enable_pickup=True)
2024-01-26 13:12:06 +00:00
2024-01-26 16:07:34 +03:00
spaz.bomb_count = 3
spaz.bomb_type = 'normal'
2024-01-26 13:12:06 +00:00
# cerdo gordo
2024-01-26 16:07:34 +03:00
spaz.node.color_mask_texture = bs.gettexture('melColorMask')
spaz.node.color_texture = bs.gettexture('melColor')
spaz.node.head_mesh = bs.getmesh('melHead')
spaz.node.hand_mesh = bs.getmesh('melHand')
spaz.node.torso_mesh = bs.getmesh('melTorso')
spaz.node.pelvis_mesh = bs.getmesh('kronkPelvis')
spaz.node.upper_arm_mesh = bs.getmesh('melUpperArm')
spaz.node.forearm_mesh = bs.getmesh('melForeArm')
spaz.node.upper_leg_mesh = bs.getmesh('melUpperLeg')
spaz.node.lower_leg_mesh = bs.getmesh('melLowerLeg')
spaz.node.toes_mesh = bs.getmesh('melToes')
spaz.node.style = 'mel'
# Sounds cerdo gordo
2024-01-26 13:12:06 +00:00
mel_sounds = [bs.getsound('mel01'), bs.getsound('mel02'), bs.getsound('mel03'), bs.getsound('mel04'), bs.getsound('mel05'),
bs.getsound('mel06'), bs.getsound('mel07'), bs.getsound('mel08'), bs.getsound('mel09'), bs.getsound('mel10')]
2024-01-26 16:07:34 +03:00
spaz.node.jump_sounds = mel_sounds
spaz.node.attack_sounds = mel_sounds
spaz.node.impact_sounds = mel_sounds
spaz.node.pickup_sounds = mel_sounds
spaz.node.death_sounds = [bs.getsound('melDeath01')]
spaz.node.fall_sounds = [bs.getsound('melFall01')]
spaz.play_big_death_sound = True
return spaz
def on_begin(self) -> None:
super().on_begin()
2024-01-26 13:12:06 +00:00
self._bots.spawn_bot(MrSpazBot, pos=(random.choice(
[1, -1, 2, -2]), 1.34, random.choice([1, -1, 2, -2])), spawn_time=2.0)
self._bots.spawn_bot(MrSpazBot, pos=(random.choice(
[1, -1, 2, -2]), 1.34, random.choice([1, -1, 2, -2])), spawn_time=2.0)
2024-01-26 16:07:34 +03:00
self._timer = OnScreenTimer()
self._timer.start()
bs.timer(10.0, self._spawn_this_bot, repeat=True)
bs.timer(5.0, self._check_end_game)
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, bs.PlayerDiedMessage):
super().handlemessage(msg)
curtime = bs.time()
msg.getplayer(Player).death_time = curtime
if isinstance(self.session, bs.CoopSession):
babase.pushcall(self._check_end_game)
self._last_player_death_time = curtime
else:
bs.timer(1.0, self._check_end_game)
elif isinstance(msg, SpazBotDiedMessage):
self._spawn_this_bot()
else:
return super().handlemessage(msg)
return None
def _spawn_this_bot(self) -> None:
2024-01-26 13:12:06 +00:00
self._bots.spawn_bot(MrSpazBot, pos=(random.choice(
[1, -1, 2, -2]), 1.34, random.choice([1, -1, 2, -2])), spawn_time=2.0)
2024-01-26 16:07:34 +03:00
def _check_end_game(self) -> None:
living_team_count = 0
for team in self.teams:
for player in team.players:
if player.is_alive():
living_team_count += 1
break
if isinstance(self.session, bs.CoopSession):
if living_team_count <= 0:
self.end_game()
else:
if living_team_count <= 1:
self.end_game()
def end_game(self) -> None:
cur_time = bs.time()
assert self._timer is not None
start_time = self._timer.getstarttime()
for team in self.teams:
for player in team.players:
survived = False
if player.death_time is None:
survived = True
player.death_time = cur_time + 1
score = int(player.death_time - self._timer.getstarttime())
if survived:
score += 50
self.stats.player_scored(player, score, screenmessage=False)
self._timer.stop(endtime=self._last_player_death_time)
results = bs.GameResults()
for team in self.teams:
longest_life = 0.0
for player in team.players:
assert player.death_time is not None
longest_life = max(longest_life,
player.death_time - start_time)
results.set_team_score(team, int(1000.0 * longest_life))
2024-01-26 13:12:06 +00:00
self.end(results=results)
2025-06-24 00:55:09 +05:30
# ba_meta export babase.Plugin
class plugin(babase.Plugin):
def __init__(self):
## Campaign support ##
babase.app.classic.add_coop_practice_level(bs.Level(
2024-02-15 19:39:53 +00:00
name='Bot Chase', gametype=BotChaseGame,
settings={},
preview_texture_name='footballStadiumPreview'))