bombsquad-plugin-manager/plugins/minigames/bot_chase.py
2024-01-26 13:12:06 +00:00

222 lines
7.5 KiB
Python

# Ported to api 8 by brostos using baport.(https://github.com/bombsquad-community/baport)
# ba_meta require api 8
from __future__ import annotations
from typing import TYPE_CHECKING
import babase
import bauiv1 as bui
import bascenev1 as bs
import random
from bascenev1lib.actor.spazbot import BrawlerBot, SpazBotSet, SpazBot, SpazBotDiedMessage
from bascenev1lib.actor.bomb import Bomb
from bascenev1lib.actor.spaz import Spaz
from bascenev1lib.actor.onscreentimer import OnScreenTimer
if TYPE_CHECKING:
from typing import Any, List, Type, Optional
# def ba_get_api_version():
# return 6
def ba_get_levels():
return [babase._level.Level(
'Bot Chase', gametype=BotChaseGame,
settings={},
preview_texture_name='footballStadiumPreview')]
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:
# Coop session unused
return (issubclass(sessiontype, bs.FreeForAllSession) or issubclass(sessiontype, bs.DualTeamSession) or issubclass(sessiontype, bs.CoopSession))
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',
subs=[('${PLAYER}', player.getname(full=True))]),
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)
spaz.bomb_count = 3
spaz.bomb_type = 'normal'
# cerdo gordo
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
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')]
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()
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)
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:
self._bots.spawn_bot(MrSpazBot, pos=(random.choice(
[1, -1, 2, -2]), 1.34, random.choice([1, -1, 2, -2])), spawn_time=2.0)
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))
self.end(results=results)