bombsquad-plugin-manager/plugins/minigames/you_vs_bombsquad.py
brostosjoined fcd4cc8169 🐍💼
2024-01-24 21:14:55 +03:00

486 lines
20 KiB
Python

# Ported to api 8 by brostos using baport.(https://github.com/bombsquad-community/baport)
"""you vs BombSquad / Created by: byANG3L"""
# ba_meta require api 8
# (see https://ballistica.net/wiki/meta-tag-system)
from __future__ import annotations
from typing import TYPE_CHECKING
import babase
import bauiv1 as bui
import bascenev1 as bs
import _babase
import random
from bascenev1lib.actor.spazbot import SpazBotSet, BrawlerBot, SpazBotDiedMessage
from bascenev1lib.actor.onscreentimer import OnScreenTimer
if TYPE_CHECKING:
from typing import Any, Optional
lang = bs.app.lang.language
if lang == 'Spanish':
name = 'Tu vs BombSquad'
name_easy = 'Tu vs BS Fácil'
name_easy_epic = 'Tu vs BS Fácil Épico'
name_hard = 'Tu vs BS Difícil'
name_hard_epic = 'Tu vs BS Difícil Épico'
else:
name = 'You vs BombSquad'
name_easy = 'You vs BS Easy'
name_easy_epic = 'You vs BS Easy Epic'
name_hard = 'You vs BS Hard'
name_hard_epic = 'You vs BS Hard Epic'
# def ba_get_api_version():
# return 6
def ba_get_levels():
return [babase._level.Level(
name_easy,
gametype=TUvsBombSquad,
settings={},
preview_texture_name='footballStadiumPreview'),
babase._level.Level(
name_easy_epic,
gametype=TUvsBombSquad,
settings={'Epic Mode': True},
preview_texture_name='footballStadiumPreview'),
babase._level.Level(
name_hard,
gametype=TUvsBombSquad,
settings={'Hard Mode': True},
preview_texture_name='footballStadiumPreview'),
babase._level.Level(
name_hard_epic,
gametype=TUvsBombSquad,
settings={'Hard Mode': True,
'Epic Mode': True},
preview_texture_name='footballStadiumPreview')]
#### BOTS ####
class SpazBot(BrawlerBot):
character = 'Spaz'
color=(0.1,0.35,0.1)
highlight=(1,0.15,0.15)
class ZoeBot(BrawlerBot):
character = 'Zoe'
color=(0.6,0.6,0.6)
highlight=(0,1,0)
class SnakeBot(BrawlerBot):
character = 'Snake Shadow'
color=(1,1,1)
highlight=(0.55,0.8,0.55)
class MelBot(BrawlerBot):
character = 'Mel'
color=(1,1,1)
highlight=(0.1,0.6,0.1)
class JackBot(BrawlerBot):
character = 'Jack Morgan'
color=(1,0.2,0.1)
highlight=(1,1,0)
class SantaBot(BrawlerBot):
character = 'Santa Claus'
color=(1,0,0)
highlight=(1,1,1)
class FrostyBot(BrawlerBot):
character = 'Frosty'
color=(0.5,0.5,1)
highlight=(1,0.5,0)
class BonesBot(BrawlerBot):
character = 'Bones'
color=(0.6,0.9,1)
highlight=(0.6,0.9,1)
class BernardBot(BrawlerBot):
character = 'Bernard'
color=(0.7,0.5,0.0)
highlight=(0.6,0.5,0.8)
class PascalBot(BrawlerBot):
character = 'Pascal'
color=(0.3,0.5,0.8)
highlight=(1,0,0)
class TaobaoBot(BrawlerBot):
character = 'Taobao Mascot'
color=(1,0.5,0)
highlight=(1,1,1)
class BBot(BrawlerBot):
character = 'B-9000'
color=(0.5,0.5,0.5)
highlight=(1,0,0)
class AgentBot(BrawlerBot):
character = 'Agent Johnson'
color=(0.3,0.3,0.33)
highlight=(1,0.5,0.3)
class GrumbledorfBot(BrawlerBot):
character = 'Grumbledorf'
color=(0.2,0.4,1.0)
highlight=(0.06,0.15,0.4)
class PixelBot(BrawlerBot):
character = 'Pixel'
color=(0,1,0.7)
highlight=(0.65,0.35,0.75)
class BunnyBot(BrawlerBot):
character = 'Easter Bunny'
color=(1,1,1)
highlight=(1,0.5,0.5)
class Player(bs.Player['Team']):
"""Our player type for this game."""
class Team(bs.Team[Player]):
"""Our team type for this game."""
# ba_meta export bascenev1.GameActivity
class TUvsBombSquad(bs.TeamGameActivity[Player, Team]):
"""A game type based on acquiring kills."""
name = name
description = 'Defeat all enemies.'
scoreconfig = bs.ScoreConfig(label='Time',
scoretype=bs.ScoreType.MILLISECONDS,
lower_is_better=True)
@classmethod
def get_available_settings(
cls, sessiontype: Type[bs.Session]) -> List[babase.Setting]:
settings = [
bs.BoolSetting('Hard Mode', default=False),
bs.BoolSetting('Epic Mode', default=False),
]
return settings
@classmethod
def supports_session_type(cls, sessiontype: Type[bs.Session]) -> bool:
return (issubclass(sessiontype, bs.CoopSession)
or issubclass(sessiontype, bs.MultiTeamSession))
@classmethod
def get_supported_maps(cls, sessiontype: Type[bs.Session]) -> List[str]:
return ['Football Stadium']
def __init__(self, settings: dict):
super().__init__(settings)
self._winsound = bs.getsound('score')
self._won = False
self._timer: Optional[OnScreenTimer] = None
self._bots = SpazBotSet()
self._hard_mode = bool(settings['Hard Mode'])
self._epic_mode = bool(settings['Epic Mode'])
# Base class overrides.
self.slow_motion = self._epic_mode
self.default_music = (bs.MusicType.EPIC if self._epic_mode else
bs.MusicType.SURVIVAL)
self._spaz_easy: list = [[(-5.4146, 0.9515, -3.0379), 23.0],
[(-5.4146, 0.9515, 1.0379), 23.0]]
self._spaz_hard: list = [[(11.4146, 0.9515, -5.0379), 3.0],
[(-8.4146, 0.9515, -5.0379), 5.0],
[(5.4146, 0.9515, -3.0379), 8.0],
[(5.4146, 0.9515, 1.0379), 8.0]]
self._zoe_easy: list = [[(5.4146, 0.9515, -1.0379), 23.0],
[(-5.4146, 0.9515, 5.0379), 23.0]]
self._zoe_hard: list = [[(-11.4146, 0.9515, -5.0379), 3.0],
[(8.4146, 0.9515, -3.0379), 5.0],
[(-5.4146, 0.9515, -3.0379), 8.0],
[(-5.4146, 0.9515, 1.0379), 8.0]]
self._snake_easy: list = [[(-5.4146, 0.9515, -1.0379), 23.0],
[(5.4146, 0.9515, -5.0379), 23.0]]
self._snake_hard: list = [[(11.4146, 0.9515, -3.0379), 3.0],
[(-8.4146, 0.9515, -3.0379), 5.0],
[(5.4146, 0.9515, -1.0379), 8.0],
[(5.4146, 0.9515, 1.0379), 8.0]]
self._kronk_easy: list = [[(8.4146, 0.9515, 1.0379), 10.0],
[(5.4146, 0.9515, 3.0379), 23.0]]
self._kronk_hard: list = [[(-11.4146, 0.9515, -3.0379), 3.0],
[(8.4146, 0.9515, -1.0379), 5.0],
[(-5.4146, 0.9515, -1.0379), 8.0],
[(5.4146, 0.9515, 1.0379), 8.0]]
self._mel_easy: list = [[(5.4146, 0.9515, 1.0379), 23.0],
[(-11.4146, 0.9515, 1.0379), 3.0]]
self._mel_hard: list = [[(11.4146, 0.9515, -1.0379), 3.0],
[(-8.4146, 0.9515, -1.0379), 5.0],
[(5.4146, 0.9515, 1.0379), 8.0],
[(5.4146, 0.9515, 5.0379), 8.0]]
self._jack_easy: list = [[(-8.4146, 0.9515, 1.0379), 10.0],
[(5.4146, 0.9515, 1.0379), 23.0]]
self._jack_hard: list = [[(-11.4146, 0.9515, -1.0379), 3.0],
[(8.4146, 0.9515, 1.0379), 5.0],
[(-5.4146, 0.9515, 1.0379), 8.0],
[(-5.4146, 0.9515, 5.0379), 8.0],
[(5.4146, 0.9515, -5.0379), 8.0]]
self._frosty_easy: list = [[(8.4146, 0.9515, 1.0379), 10.0],
[(8.4146, 0.9515, -5.0379), 10.0]]
self._frosty_hard: list = [[(-11.4146, 0.9515, 1.0379), 3.0],
[(-5.4146, 0.9515, 3.0379), 8.0],
[(-5.4146, 0.9515, -5.0379), 8.0],
[(5.4146, 0.9515, 3.0379), 8.0]]
self._bunny_easy: list = [[(-8.4146, 0.9515, 3.0379), 10.0],
[(5.4146, 0.9515, 5.0379), 23.0]]
self._bunny_hard: list = [[(8.4146, 0.9515, -5.0379), 5.0],
[(-5.4146, 0.9515, -5.0379), 8.0],
[(-5.4146, 0.9515, 3.0379), 8.0],
[(8.4146, 0.9515, 3.0379), 5.0]]
self._bones_easy: list = [[(11.4146, 0.9515, -5.0379), 3.0],
[(-8.4146, 0.9515, -5.0379), 10.0]]
self._bones_hard: list = [[(5.4146, 0.9515, -3.0379), 8.0],
[(-5.4146, 0.9515, 3.0379), 8.0],
[(5.4146, 0.9515, 1.0379), 8.0],
[(8.4146, 0.9515, 3.0379), 5.0]]
self._bernard_easy: list = [[(-11.4146, 0.9515, -5.0379), 3.0],
[(8.4146, 0.9515, -3.0379), 10.0]]
self._bernard_hard: list = [[(-5.4146, 0.9515, -3.0379), 8.0],
[(5.4146, 0.9515, 1.0379), 8.0],
[(-5.4146, 0.9515, 1.0379), 8.0],
[(-8.4146, 0.9515, 3.0379), 5.0]]
self._pascal_easy: list = [[(11.4146, 0.9515, -3.0379), 3.0],
[(-8.4146, 0.9515, -3.0379), 10.0]]
self._pascal_hard: list = [[(5.4146, 0.9515, -1.0379), 8.0],
[(-5.4146, 0.9515, 1.0379), 8.0],
[(5.4146, 0.9515, 1.0379), 8.0],
[(8.4146, 0.9515, 1.0379), 5.0]]
self._taobao_easy: list = [[(-11.4146, 0.9515, -3.0379), 3.0],
[(8.4146, 0.9515, -1.0379), 10.0]]
self._taobao_hard: list = [[(-5.4146, 0.9515, -1.0379), 8.0],
[(5.4146, 0.9515, 1.0379), 8.0],
[(-5.4146, 0.9515, 1.0379), 8.0],
[(-5.4146, 0.9515, 1.0379), 8.0]]
self._bbot_easy: list = [[(11.4146, 0.9515, -1.0379), 3.0],
[(-8.4146, 0.9515, -1.0379), 10.0]]
self._bbot_hard: list = [[(-5.4146, 0.9515, 1.0379), 8.0],
[(8.4146, 0.9515, 1.0379), 5.0],
[(-5.4146, 0.9515, 1.0379), 8.0],
[(-5.4146, 0.9515, 1.0379), 8.0]]
self._agent_easy: list = [[(-11.4146, 0.9515, -1.0379), 3.0],
[(8.4146, 0.9515, 1.0379), 10.0]]
self._agent_hard: list = [[(5.4146, 0.9515, 5.0379), 8.0],
[(-8.4146, 0.9515, 1.0379), 5.0],
[(-11.4146, 0.9515, 1.0379), 3.0],
[(-11.4146, 0.9515, 1.0379), 3.0]]
self._wizard_easy: list = [[(11.4146, 0.9515, 1.0379), 3.0],
[(-8.4146, 0.9515, 1.0379), 10.0]]
self._wizard_hard: list = [[(-5.4146, 0.9515, 5.0379), 8.0],
[(8.4146, 0.9515, 5.0379), 5.0],
[(-5.4146, 0.9515, 1.0379), 8.0],
[(11.4146, 0.9515, 1.0379), 3.0]]
self._pixel_easy: list = [[(-5.4146, 0.9515, -5.0379), 23.0]]
self._pixel_hard: list = [[(5.4146, 0.9515, -5.0379), 8.0],
[(5.4146, 0.9515, 3.0379), 5.0],
[(-8.4146, 0.9515, 5.0379), 5.0]]
self._santa_easy: list = [[(-8.4146, 0.9515, 5.0379), 23.0]]
self._santa_hard: list = [[(-8.4146, 0.9515, 1.0379), 5.0],
[(-8.4146, 0.9515, 5.0379), 5.0],
[(5.4146, 0.9515, 1.0379), 8.0]]
def on_begin(self) -> None:
super().on_begin()
self.setup_standard_powerup_drops()
self._timer = OnScreenTimer()
bs.timer(4.0, self._timer.start)
for i in range(len(self._spaz_easy)):
self._spawn_bots(4.0, SpazBot,
self._spaz_easy[i][0], self._spaz_easy[i][1])
for i in range(len(self._zoe_easy)):
self._spawn_bots(4.0, ZoeBot,
self._zoe_easy[i][0], self._zoe_easy[i][1])
for i in range(len(self._snake_easy)):
self._spawn_bots(4.0, SnakeBot,
self._snake_easy[i][0], self._snake_easy[i][1])
for i in range(len(self._kronk_easy)):
self._spawn_bots(4.0, BrawlerBot,
self._kronk_easy[i][0], self._kronk_easy[i][1])
for i in range(len(self._mel_easy)):
self._spawn_bots(4.0, MelBot,
self._mel_easy[i][0], self._mel_easy[i][1])
for i in range(len(self._jack_easy)):
self._spawn_bots(4.0, JackBot,
self._jack_easy[i][0], self._jack_easy[i][1])
for i in range(len(self._santa_easy)):
self._spawn_bots(4.0, SantaBot,
self._santa_easy[i][0], self._santa_easy[i][1])
for i in range(len(self._frosty_easy)):
self._spawn_bots(4.0, FrostyBot,
self._frosty_easy[i][0], self._frosty_easy[i][1])
for i in range(len(self._bunny_easy)):
self._spawn_bots(4.0, BunnyBot,
self._bunny_easy[i][0], self._bunny_easy[i][1])
for i in range(len(self._bones_easy)):
self._spawn_bots(4.0, BonesBot,
self._bones_easy[i][0], self._bones_easy[i][1])
for i in range(len(self._bernard_easy)):
self._spawn_bots(4.0, BernardBot,
self._bernard_easy[i][0], self._bernard_easy[i][1])
for i in range(len(self._pascal_easy)):
self._spawn_bots(4.0, PascalBot,
self._pascal_easy[i][0], self._pascal_easy[i][1])
for i in range(len(self._taobao_easy)):
self._spawn_bots(4.0, TaobaoBot,
self._taobao_easy[i][0], self._taobao_easy[i][1])
for i in range(len(self._bbot_easy)):
self._spawn_bots(4.0, BBot,
self._bbot_easy[i][0], self._bbot_easy[i][1])
for i in range(len(self._agent_easy)):
self._spawn_bots(4.0, AgentBot,
self._agent_easy[i][0], self._agent_easy[i][1])
for i in range(len(self._wizard_easy)):
self._spawn_bots(4.0, GrumbledorfBot,
self._wizard_easy[i][0], self._wizard_easy[i][1])
for i in range(len(self._pixel_easy)):
self._spawn_bots(4.0, PixelBot,
self._pixel_easy[i][0], self._pixel_easy[i][1])
if self._hard_mode:
for i in range(len(self._spaz_hard)):
self._spawn_bots(4.0, SpazBot,
self._spaz_hard[i][0], self._spaz_hard[i][1])
for i in range(len(self._zoe_hard)):
self._spawn_bots(4.0, ZoeBot,
self._zoe_hard[i][0], self._zoe_hard[i][1])
for i in range(len(self._snake_hard)):
self._spawn_bots(4.0, SnakeBot,
self._snake_hard[i][0], self._snake_hard[i][1])
for i in range(len(self._kronk_hard)):
self._spawn_bots(4.0, BrawlerBot,
self._kronk_hard[i][0], self._kronk_hard[i][1])
for i in range(len(self._mel_hard)):
self._spawn_bots(4.0, MelBot,
self._mel_hard[i][0], self._mel_hard[i][1])
for i in range(len(self._jack_hard)):
self._spawn_bots(4.0, JackBot,
self._jack_hard[i][0], self._jack_hard[i][1])
for i in range(len(self._santa_hard)):
self._spawn_bots(4.0, SantaBot,
self._santa_hard[i][0], self._santa_hard[i][1])
for i in range(len(self._frosty_hard)):
self._spawn_bots(4.0, FrostyBot,
self._frosty_hard[i][0], self._frosty_hard[i][1])
for i in range(len(self._bunny_hard)):
self._spawn_bots(4.0, BunnyBot,
self._bunny_hard[i][0], self._bunny_hard[i][1])
for i in range(len(self._bones_hard)):
self._spawn_bots(4.0, BonesBot,
self._bones_hard[i][0], self._bones_hard[i][1])
for i in range(len(self._bernard_hard)):
self._spawn_bots(4.0, BernardBot,
self._bernard_hard[i][0], self._bernard_hard[i][1])
for i in range(len(self._pascal_hard)):
self._spawn_bots(4.0, PascalBot,
self._pascal_hard[i][0], self._pascal_hard[i][1])
for i in range(len(self._taobao_hard)):
self._spawn_bots(4.0, TaobaoBot,
self._taobao_hard[i][0], self._taobao_hard[i][1])
for i in range(len(self._bbot_hard)):
self._spawn_bots(4.0, BBot,
self._bbot_hard[i][0], self._bbot_hard[i][1])
for i in range(len(self._agent_hard)):
self._spawn_bots(4.0, AgentBot,
self._agent_hard[i][0], self._agent_hard[i][1])
for i in range(len(self._wizard_hard)):
self._spawn_bots(4.0, GrumbledorfBot,
self._wizard_hard[i][0], self._wizard_hard[i][1])
for i in range(len(self._pixel_hard)):
self._spawn_bots(4.0, PixelBot,
self._pixel_hard[i][0], self._pixel_hard[i][1])
def _spawn_bots(self, time: float, bot: Any,
pos: float, spawn_time: float) -> None:
bs.timer(time, lambda: self._bots.spawn_bot(
bot, pos=pos, spawn_time=spawn_time))
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),
)
return
self.spawn_player(player)
# Called for each spawning player.
def spawn_player(self, player: Player) -> bs.Actor:
# Let's spawn close to the center.
spawn_center = (0.0728, 0.0227, -1.9888)
pos = (spawn_center[0] + random.uniform(-0.5, 0.5), spawn_center[1],
spawn_center[2] + random.uniform(-0.5, 0.5))
return self.spawn_player_spaz(player, position=pos)
def _check_if_won(self) -> None:
# Simply end the game if there's no living bots.
# FIXME: Should also make sure all bots have been spawned;
# if spawning is spread out enough that we're able to kill
# all living bots before the next spawns, it would incorrectly
# count as a win.
if not self._bots.have_living_bots():
self._won = True
self.end_game()
# Called for miscellaneous messages.
def handlemessage(self, msg: Any) -> Any:
# A player has died.
if isinstance(msg, bs.PlayerDiedMessage):
super().handlemessage(msg) # Augment standard behavior.
self.respawn_player(msg.getplayer(Player))
# A spaz-bot has died.
elif isinstance(msg, SpazBotDiedMessage):
# Unfortunately the bot-set will always tell us there are living
# bots if we ask here (the currently-dying bot isn't officially
# marked dead yet) ..so lets push a call into the event loop to
# check once this guy has finished dying.
babase.pushcall(self._check_if_won)
# Let the base class handle anything we don't.
else:
return super().handlemessage(msg)
return None
# When this is called, we should fill out results and end the game
# *regardless* of whether is has been won. (this may be called due
# to a tournament ending or other external reason).
def end_game(self) -> None:
# Stop our on-screen timer so players can see what they got.
assert self._timer is not None
self._timer.stop()
results = bs.GameResults()
# If we won, set our score to the elapsed time in milliseconds.
# (there should just be 1 team here since this is co-op).
# ..if we didn't win, leave scores as default (None) which means
# we lost.
if self._won:
elapsed_time_ms = int((bs.time() - self._timer.starttime) * 1000.0)
bs.cameraflash()
self._winsound.play()
for team in self.teams:
for player in team.players:
if player.actor:
player.actor.handlemessage(bs.CelebrateMessage())
results.set_team_score(team, elapsed_time_ms)
# Ends the activity.
self.end(results)