mirror of
https://github.com/bombsquad-community/plugin-manager.git
synced 2025-10-08 14:54:36 +00:00
more
This commit is contained in:
parent
0d5f03d62b
commit
d99d0cad72
10 changed files with 2839 additions and 1 deletions
254
plugins/minigames/extinction.py
Normal file
254
plugins/minigames/extinction.py
Normal file
|
|
@ -0,0 +1,254 @@
|
|||
# Ported to api 8 by brostos using baport.(https://github.com/bombsquad-community/baport)
|
||||
"""For 1.7.33"""
|
||||
|
||||
# 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.bomb import BombFactory, Blast, ImpactMessage
|
||||
from bascenev1lib.actor.onscreentimer import OnScreenTimer
|
||||
from bascenev1lib.gameutils import SharedObjects
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Sequence, Optional, Type
|
||||
|
||||
|
||||
def ba_get_api_version():
|
||||
return 8
|
||||
|
||||
def ba_get_levels():
|
||||
return [babase._level.Level(
|
||||
'Extinction',
|
||||
gametype=NewMeteorShowerGame,
|
||||
settings={'Epic Mode': False},
|
||||
preview_texture_name='footballStadiumPreview'),
|
||||
babase._level.Level(
|
||||
'Epic Extinction',
|
||||
gametype=NewMeteorShowerGame,
|
||||
settings={'Epic Mode': True},
|
||||
preview_texture_name='footballStadiumPreview')]
|
||||
|
||||
class Meteor(bs.Actor):
|
||||
"""A giant meteor instead of bombs."""
|
||||
|
||||
def __init__(self,
|
||||
pos: Sequence[float] = (0.0, 1.0, 0.0),
|
||||
velocity: Sequence[float] = (0.0, 0.0, 0.0)):
|
||||
super().__init__()
|
||||
|
||||
shared = SharedObjects.get()
|
||||
factory = BombFactory.get()
|
||||
|
||||
materials = (shared.object_material,
|
||||
factory.impact_blast_material)
|
||||
|
||||
self.pos = (pos[0], pos[1], pos[2])
|
||||
self.velocity = (velocity[0], velocity[1], velocity[2])
|
||||
|
||||
self.node = bs.newnode(
|
||||
'prop',
|
||||
delegate=self,
|
||||
attrs={
|
||||
'position': self.pos,
|
||||
'velocity': self.velocity,
|
||||
'mesh': factory.sticky_bomb_mesh,
|
||||
'color_texture': factory.tnt_tex,
|
||||
'mesh_scale': 3.0,
|
||||
'body_scale': 2.99,
|
||||
'body': 'sphere',
|
||||
'shadow_size': 0.5,
|
||||
'reflection': 'soft',
|
||||
'reflection_scale': [0.45],
|
||||
'materials': materials
|
||||
})
|
||||
|
||||
def explode(self) -> None:
|
||||
Blast(position=self.node.position,
|
||||
velocity=self.node.velocity,
|
||||
blast_type='tnt',
|
||||
blast_radius=2.0)
|
||||
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, bs.DieMessage):
|
||||
if self.node:
|
||||
self.node.delete()
|
||||
elif isinstance(msg, ImpactMessage):
|
||||
self.explode()
|
||||
self.handlemessage(bs.DieMessage())
|
||||
else:
|
||||
super().handlemessage(msg)
|
||||
|
||||
|
||||
class Player(bs.Player['Team']):
|
||||
"""Our player type for this game."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.death_time: Optional[float] = None
|
||||
|
||||
class Team(bs.Team[Player]):
|
||||
"""Our team type for this game."""
|
||||
|
||||
|
||||
# ba_meta export bascenev1.GameActivity
|
||||
class NewMeteorShowerGame(bs.TeamGameActivity[Player, Team]):
|
||||
"""Minigame by Jetz."""
|
||||
|
||||
name = 'Extinction'
|
||||
description = 'Survive the Extinction.'
|
||||
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:
|
||||
return (issubclass(sessiontype, bs.FreeForAllSession)
|
||||
or issubclass(sessiontype, bs.DualTeamSession))
|
||||
|
||||
def __init__(self, settings: dict):
|
||||
super().__init__(settings)
|
||||
|
||||
self._epic_mode = bool(settings['Epic Mode'])
|
||||
self._last_player_death_time: Optiobal[float] = None
|
||||
self._meteor_time = 2.0
|
||||
self._timer: Optional[OnScreenTimer] = None
|
||||
|
||||
self.default_music = (bs.MusicType.EPIC
|
||||
if self._epic_mode else bs.MusicType.SURVIVAL)
|
||||
|
||||
if self._epic_mode:
|
||||
self.slow_motion = True
|
||||
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
|
||||
delay = 5.0 if len(self.players) > 2 else 2.5
|
||||
if self._epic_mode:
|
||||
delay *= 0.25
|
||||
bs.timer(delay, self._decrement_meteor_time, repeat=True)
|
||||
|
||||
delay = 3.0
|
||||
if self._epic_mode:
|
||||
delay *= 0.25
|
||||
bs.timer(delay, self._set_meteor_timer)
|
||||
|
||||
self._timer = OnScreenTimer()
|
||||
self._timer.start()
|
||||
self._check_end_game()
|
||||
|
||||
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 spawn_player(self, player: Player) -> None:
|
||||
spaz = self.spawn_player_spaz(player)
|
||||
|
||||
spaz.connect_controls_to_player(enable_punch=False,
|
||||
enable_pickup=False,
|
||||
enable_bomb=False,
|
||||
enable_jump=False)
|
||||
spaz.play_big_death_sound = True
|
||||
|
||||
return spaz
|
||||
|
||||
def on_player_leave(self, player: Player) -> None:
|
||||
super().on_player_leave(player)
|
||||
|
||||
self._check_end_game()
|
||||
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, bs.PlayerDiedMessage):
|
||||
curtime = bs.time()
|
||||
|
||||
msg.getplayer(Player).death_time = curtime
|
||||
bs.timer(1.0, self._check_end_game)
|
||||
else:
|
||||
return super().handlemessage(msg)
|
||||
|
||||
def _spawn_meteors(self) -> None:
|
||||
pos = (random.randint(-6, 7), 12,
|
||||
random.uniform(-2, 1))
|
||||
velocity = (random.randint(-11, 11), 0,
|
||||
random.uniform(-5, 5))
|
||||
Meteor(pos=pos, velocity=velocity).autoretain()
|
||||
|
||||
def _spawn_meteors_cluster(self) -> None:
|
||||
delay = 0.0
|
||||
for _i in range(random.randrange(1, 3)):
|
||||
bs.timer(delay, self._spawn_meteors)
|
||||
delay += 1
|
||||
self._set_meteor_timer()
|
||||
|
||||
def _decrement_meteor_time(self) -> None:
|
||||
self._meteor_time = max(0.01, self._meteor_time * 0.9)
|
||||
|
||||
def _set_meteor_timer(self) -> None:
|
||||
bs.timer((1.0 + 0.2 * random.random()) * self._meteor_time,
|
||||
self._spawn_meteors_cluster)
|
||||
|
||||
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)
|
||||
Loading…
Add table
Add a link
Reference in a new issue