mirror of
https://github.com/hypervortex/VH-Bombsquad-Modded-Server-Files
synced 2025-11-07 17:36:08 +00:00
Delete dist directory
This commit is contained in:
parent
2e2c838750
commit
867634cc5c
1779 changed files with 0 additions and 565850 deletions
622
dist/ba_root/mods/games/lib.py
vendored
622
dist/ba_root/mods/games/lib.py
vendored
|
|
@ -1,622 +0,0 @@
|
|||
# Released under the MIT License. See LICENSE for details.
|
||||
#
|
||||
"""Defines the King of the Hill game."""
|
||||
|
||||
# ba_meta require api 6
|
||||
# (see https://ballistica.net/wiki/meta-tag-system)
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import weakref
|
||||
from enum import Enum
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import ba
|
||||
from bastd.actor.flag import Flag
|
||||
from bastd.actor.playerspaz import PlayerSpaz
|
||||
from bastd.actor.scoreboard import Scoreboard
|
||||
from bastd.gameutils import SharedObjects
|
||||
from dataclasses import dataclass
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Optional, Sequence, Union
|
||||
|
||||
|
||||
class FlagState(Enum):
|
||||
"""States our single flag can be in."""
|
||||
NEW = 0
|
||||
UNCONTESTED = 1
|
||||
CONTESTED = 2
|
||||
HELD = 3
|
||||
|
||||
|
||||
class Player(ba.Player['Team']):
|
||||
"""Our player type for this game."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.time_at_flag = 0
|
||||
self.lives = 0
|
||||
self.icons: list[Icon] = []
|
||||
self.death_time: Optional[float] = None
|
||||
self.distance_txt: Optional[ba.Node] = None
|
||||
self.last_region = 0
|
||||
self.lap = 0
|
||||
self.distance = 0.0
|
||||
self.finished = False
|
||||
self.rank: Optional[int] = None
|
||||
|
||||
|
||||
class Team(ba.Team[Player]):
|
||||
"""Our team type for this game."""
|
||||
|
||||
def __init__(self, time_remaining=None) -> None:
|
||||
self.time_remaining = time_remaining
|
||||
self.survival_seconds: Optional[int] = None
|
||||
self.spawn_order: list[Player] = []
|
||||
self.score = 0
|
||||
self.time: Optional[float] = None
|
||||
self.lap = 0
|
||||
self.finished = False
|
||||
|
||||
#def __init__(self):
|
||||
# self.survival_seconds: Optional[int] = None
|
||||
# self.spawn_order: list[Player] = []
|
||||
# self.score = 0
|
||||
# self.time: Optional[float] = None
|
||||
# self.lap = 0
|
||||
# self.finished = False
|
||||
|
||||
|
||||
|
||||
class kth(ba.TeamGameActivity[Player, Team]):
|
||||
"""Game where a team wins by holding a 'hill' for a set amount of time."""
|
||||
|
||||
name = 'King of the Hillx'
|
||||
description = 'Secure the flag for a set length of time.'
|
||||
available_settings = [
|
||||
ba.IntSetting(
|
||||
'Hold Time',
|
||||
min_value=10,
|
||||
default=30,
|
||||
increment=10,
|
||||
),
|
||||
ba.IntChoiceSetting(
|
||||
'Time Limit',
|
||||
choices=[
|
||||
('None', 0),
|
||||
('1 Minute', 60),
|
||||
('2 Minutes', 120),
|
||||
('5 Minutes', 300),
|
||||
('10 Minutes', 600),
|
||||
('20 Minutes', 1200),
|
||||
],
|
||||
default=0,
|
||||
),
|
||||
ba.FloatChoiceSetting(
|
||||
'Respawn Times',
|
||||
choices=[
|
||||
('Shorter', 0.25),
|
||||
('Short', 0.5),
|
||||
('Normal', 1.0),
|
||||
('Long', 2.0),
|
||||
('Longer', 4.0),
|
||||
],
|
||||
default=1.0,
|
||||
),
|
||||
]
|
||||
scoreconfig = ba.ScoreConfig(label='Time Held')
|
||||
|
||||
@classmethod
|
||||
def supports_session_type(cls, sessiontype: type[ba.Session]) -> bool:
|
||||
return issubclass(sessiontype, ba.MultiTeamSession)
|
||||
|
||||
@classmethod
|
||||
def get_supported_maps(cls, sessiontype: type[ba.Session]) -> list[str]:
|
||||
return ba.getmaps('king_of_the_hill')
|
||||
|
||||
def __init__(self, settings: dict):
|
||||
super().__init__(settings)
|
||||
|
||||
|
||||
def get_instance_description(self) -> Union[str, Sequence]:
|
||||
return 'Secure the flag for ${ARG1} seconds.', self._hold_time
|
||||
|
||||
def get_instance_description_short(self) -> Union[str, Sequence]:
|
||||
return 'secure the flag for ${ARG1} seconds', self._hold_time
|
||||
|
||||
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
shared = SharedObjects.get()
|
||||
|
||||
|
||||
def end_game(self) -> None:
|
||||
results = ba.GameResults()
|
||||
for team in self.teams:
|
||||
results.set_team_score(team, self._hold_time - team.time_remaining)
|
||||
self.end(results=results, announce_delay=0)
|
||||
|
||||
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, ba.PlayerDiedMessage):
|
||||
super().handlemessage(msg) # Augment default.
|
||||
|
||||
# =====================================================================================================================================================================
|
||||
|
||||
|
||||
|
||||
|
||||
from bastd.actor.spazfactory import SpazFactory
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Sequence, Optional, Union
|
||||
|
||||
|
||||
class Icon(ba.Actor):
|
||||
"""Creates in in-game icon on screen."""
|
||||
|
||||
def __init__(self,
|
||||
player: Player,
|
||||
position: tuple[float, float],
|
||||
scale: float,
|
||||
show_lives: bool = True,
|
||||
show_death: bool = True,
|
||||
name_scale: float = 1.0,
|
||||
name_maxwidth: float = 115.0,
|
||||
flatness: float = 1.0,
|
||||
shadow: float = 1.0):
|
||||
super().__init__()
|
||||
|
||||
self._player = player
|
||||
self._show_lives = show_lives
|
||||
self._show_death = show_death
|
||||
self._name_scale = name_scale
|
||||
self._outline_tex = ba.gettexture('characterIconMask')
|
||||
|
||||
icon = player.get_icon()
|
||||
self.node = ba.newnode('image',
|
||||
delegate=self,
|
||||
attrs={
|
||||
'texture': icon['texture'],
|
||||
'tint_texture': icon['tint_texture'],
|
||||
'tint_color': icon['tint_color'],
|
||||
'vr_depth': 400,
|
||||
'tint2_color': icon['tint2_color'],
|
||||
'mask_texture': self._outline_tex,
|
||||
'opacity': 1.0,
|
||||
'absolute_scale': True,
|
||||
'attach': 'bottomCenter'
|
||||
})
|
||||
self._name_text = ba.newnode(
|
||||
'text',
|
||||
owner=self.node,
|
||||
attrs={
|
||||
'text': ba.Lstr(value=player.getname()),
|
||||
'color': ba.safecolor(player.team.color),
|
||||
'h_align': 'center',
|
||||
'v_align': 'center',
|
||||
'vr_depth': 410,
|
||||
'maxwidth': name_maxwidth,
|
||||
'shadow': shadow,
|
||||
'flatness': flatness,
|
||||
'h_attach': 'center',
|
||||
'v_attach': 'bottom'
|
||||
})
|
||||
if self._show_lives:
|
||||
self._lives_text = ba.newnode('text',
|
||||
owner=self.node,
|
||||
attrs={
|
||||
'text': 'x0',
|
||||
'color': (1, 1, 0.5),
|
||||
'h_align': 'left',
|
||||
'vr_depth': 430,
|
||||
'shadow': 1.0,
|
||||
'flatness': 1.0,
|
||||
'h_attach': 'center',
|
||||
'v_attach': 'bottom'
|
||||
})
|
||||
self.set_position_and_scale(position, scale)
|
||||
|
||||
def set_position_and_scale(self, position: tuple[float, float],
|
||||
scale: float) -> None:
|
||||
"""(Re)position the icon."""
|
||||
assert self.node
|
||||
self.node.position = position
|
||||
self.node.scale = [70.0 * scale]
|
||||
self._name_text.position = (position[0], position[1] + scale * 52.0)
|
||||
self._name_text.scale = 1.0 * scale * self._name_scale
|
||||
if self._show_lives:
|
||||
self._lives_text.position = (position[0] + scale * 10.0,
|
||||
position[1] - scale * 43.0)
|
||||
self._lives_text.scale = 1.0 * scale
|
||||
|
||||
def update_for_lives(self) -> None:
|
||||
"""Update for the target player's current lives."""
|
||||
if self._player:
|
||||
lives = self._player.lives
|
||||
else:
|
||||
lives = 0
|
||||
if self._show_lives:
|
||||
if lives > 0:
|
||||
self._lives_text.text = 'x' + str(lives - 1)
|
||||
else:
|
||||
self._lives_text.text = ''
|
||||
if lives == 0:
|
||||
self._name_text.opacity = 0.2
|
||||
assert self.node
|
||||
self.node.color = (0.7, 0.3, 0.3)
|
||||
self.node.opacity = 0.2
|
||||
|
||||
def handle_player_spawned(self) -> None:
|
||||
"""Our player spawned; hooray!"""
|
||||
if not self.node:
|
||||
return
|
||||
self.node.opacity = 1.0
|
||||
self.update_for_lives()
|
||||
|
||||
def handle_player_died(self) -> None:
|
||||
"""Well poo; our player died."""
|
||||
if not self.node:
|
||||
return
|
||||
if self._show_death:
|
||||
ba.animate(
|
||||
self.node, 'opacity', {
|
||||
0.00: 1.0,
|
||||
0.05: 0.0,
|
||||
0.10: 1.0,
|
||||
0.15: 0.0,
|
||||
0.20: 1.0,
|
||||
0.25: 0.0,
|
||||
0.30: 1.0,
|
||||
0.35: 0.0,
|
||||
0.40: 1.0,
|
||||
0.45: 0.0,
|
||||
0.50: 1.0,
|
||||
0.55: 0.2
|
||||
})
|
||||
lives = self._player.lives
|
||||
if lives == 0:
|
||||
ba.timer(0.6, self.update_for_lives)
|
||||
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, ba.DieMessage):
|
||||
self.node.delete()
|
||||
return None
|
||||
return super().handlemessage(msg)
|
||||
|
||||
|
||||
class eli(ba.TeamGameActivity[Player, Team]):
|
||||
"""Game type where last player(s) left alive win."""
|
||||
|
||||
name = 'Eliminationx'
|
||||
description = 'Last remaining alive wins.'
|
||||
scoreconfig = ba.ScoreConfig(label='Survived',
|
||||
scoretype=ba.ScoreType.SECONDS,
|
||||
none_is_winner=True)
|
||||
# Show messages when players die since it's meaningful here.
|
||||
announce_player_deaths = True
|
||||
|
||||
allow_mid_activity_joins = False
|
||||
|
||||
@classmethod
|
||||
def get_available_settings(
|
||||
cls, sessiontype: type[ba.Session]) -> list[ba.Setting]:
|
||||
settings = [
|
||||
ba.IntSetting(
|
||||
'Lives Per Player',
|
||||
default=1,
|
||||
min_value=1,
|
||||
max_value=10,
|
||||
increment=1,
|
||||
),
|
||||
ba.IntChoiceSetting(
|
||||
'Time Limit',
|
||||
choices=[
|
||||
('None', 0),
|
||||
('1 Minute', 60),
|
||||
('2 Minutes', 120),
|
||||
('5 Minutes', 300),
|
||||
('10 Minutes', 600),
|
||||
('20 Minutes', 1200),
|
||||
],
|
||||
default=0,
|
||||
),
|
||||
ba.FloatChoiceSetting(
|
||||
'Respawn Times',
|
||||
choices=[
|
||||
('Shorter', 0.25),
|
||||
('Short', 0.5),
|
||||
('Normal', 1.0),
|
||||
('Long', 2.0),
|
||||
('Longer', 4.0),
|
||||
],
|
||||
default=1.0,
|
||||
),
|
||||
ba.BoolSetting('Epic Mode', default=False),
|
||||
]
|
||||
if issubclass(sessiontype, ba.DualTeamSession):
|
||||
settings.append(ba.BoolSetting('Solo Mode', default=False))
|
||||
settings.append(
|
||||
ba.BoolSetting('Balance Total Lives', default=False))
|
||||
return settings
|
||||
|
||||
@classmethod
|
||||
def supports_session_type(cls, sessiontype: type[ba.Session]) -> bool:
|
||||
return (issubclass(sessiontype, ba.DualTeamSession)
|
||||
or issubclass(sessiontype, ba.FreeForAllSession))
|
||||
|
||||
@classmethod
|
||||
def get_supported_maps(cls, sessiontype: type[ba.Session]) -> list[str]:
|
||||
return ba.getmaps('melee')
|
||||
|
||||
def __init__(self, settings: dict):
|
||||
super().__init__(settings)
|
||||
|
||||
def get_instance_description(self) -> Union[str, Sequence]:
|
||||
return 'Last team standing wins.' if isinstance(
|
||||
self.session, ba.DualTeamSession) else 'Last one standing wins.'
|
||||
|
||||
def get_instance_description_short(self) -> Union[str, Sequence]:
|
||||
return 'last team standing wins' if isinstance(
|
||||
self.session, ba.DualTeamSession) else 'last one standing wins'
|
||||
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
|
||||
# ========================
|
||||
|
||||
|
||||
# ba_meta export game
|
||||
class dm(ba.TeamGameActivity[Player, Team]):
|
||||
"""A game type based on acquiring kills."""
|
||||
|
||||
name = 'Death Matchx'
|
||||
description = 'Kill a set number of enemies to win.'
|
||||
|
||||
# Print messages when players die since it matters here.
|
||||
announce_player_deaths = True
|
||||
|
||||
@classmethod
|
||||
def get_available_settings(
|
||||
cls, sessiontype: type[ba.Session]) -> list[ba.Setting]:
|
||||
settings = [
|
||||
ba.IntSetting(
|
||||
'Kills to Win Per Player',
|
||||
min_value=1,
|
||||
default=5,
|
||||
increment=1,
|
||||
),
|
||||
ba.IntChoiceSetting(
|
||||
'Time Limit',
|
||||
choices=[
|
||||
('None', 0),
|
||||
('1 Minute', 60),
|
||||
('2 Minutes', 120),
|
||||
('5 Minutes', 300),
|
||||
('10 Minutes', 600),
|
||||
('20 Minutes', 1200),
|
||||
],
|
||||
default=0,
|
||||
),
|
||||
ba.FloatChoiceSetting(
|
||||
'Respawn Times',
|
||||
choices=[
|
||||
('Shorter', 0.25),
|
||||
('Short', 0.5),
|
||||
('Normal', 1.0),
|
||||
('Long', 2.0),
|
||||
('Longer', 4.0),
|
||||
],
|
||||
default=1.0,
|
||||
),
|
||||
ba.BoolSetting('Epic Mode', default=False),
|
||||
]
|
||||
|
||||
# In teams mode, a suicide gives a point to the other team, but in
|
||||
# free-for-all it subtracts from your own score. By default we clamp
|
||||
# this at zero to benefit new players, but pro players might like to
|
||||
# be able to go negative. (to avoid a strategy of just
|
||||
# suiciding until you get a good drop)
|
||||
if issubclass(sessiontype, ba.FreeForAllSession):
|
||||
settings.append(
|
||||
ba.BoolSetting('Allow Negative Scores', default=False))
|
||||
|
||||
return settings
|
||||
|
||||
@classmethod
|
||||
def supports_session_type(cls, sessiontype: type[ba.Session]) -> bool:
|
||||
return (issubclass(sessiontype, ba.DualTeamSession)
|
||||
or issubclass(sessiontype, ba.FreeForAllSession))
|
||||
|
||||
@classmethod
|
||||
def get_supported_maps(cls, sessiontype: type[ba.Session]) -> list[str]:
|
||||
return ba.getmaps('melee')
|
||||
|
||||
def __init__(self, settings: dict):
|
||||
super().__init__(settings)
|
||||
|
||||
|
||||
def get_instance_description(self) -> Union[str, Sequence]:
|
||||
return 'Crush ${ARG1} of your enemies.', self._score_to_win
|
||||
|
||||
def get_instance_description_short(self) -> Union[str, Sequence]:
|
||||
return 'kill ${ARG1} enemies', self._score_to_win
|
||||
|
||||
|
||||
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
|
||||
|
||||
# ====================
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# ba_meta export game
|
||||
class ms(ba.TeamGameActivity[Player, Team]):
|
||||
"""Minigame involving dodging falling bombs."""
|
||||
|
||||
name = 'Meteor Showerx'
|
||||
description = 'Dodge the falling bombs.'
|
||||
available_settings = [ba.BoolSetting('Epic Mode', default=False)]
|
||||
scoreconfig = ba.ScoreConfig(label='Survived',
|
||||
scoretype=ba.ScoreType.MILLISECONDS,
|
||||
version='B')
|
||||
|
||||
# Print messages when players die (since its meaningful in this game).
|
||||
announce_player_deaths = True
|
||||
|
||||
# Don't allow joining after we start
|
||||
# (would enable leave/rejoin tomfoolery).
|
||||
allow_mid_activity_joins = False
|
||||
|
||||
# We're currently hard-coded for one map.
|
||||
@classmethod
|
||||
def get_supported_maps(cls, sessiontype: type[ba.Session]) -> list[str]:
|
||||
return ['Rampage']
|
||||
|
||||
# We support teams, free-for-all, and co-op sessions.
|
||||
@classmethod
|
||||
def supports_session_type(cls, sessiontype: type[ba.Session]) -> bool:
|
||||
return (issubclass(sessiontype, ba.DualTeamSession)
|
||||
or issubclass(sessiontype, ba.FreeForAllSession)
|
||||
or issubclass(sessiontype, ba.CoopSession))
|
||||
|
||||
def __init__(self, settings: dict):
|
||||
super().__init__(settings)
|
||||
|
||||
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
|
||||
# =====================
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class RaceMine:
|
||||
"""Holds info about a mine on the track."""
|
||||
point: Sequence[float]
|
||||
mine: Optional[Bomb]
|
||||
|
||||
|
||||
class RaceRegion(ba.Actor):
|
||||
"""Region used to track progress during a race."""
|
||||
|
||||
def __init__(self, pt: Sequence[float], index: int):
|
||||
super().__init__()
|
||||
activity = self.activity
|
||||
assert isinstance(activity, RaceGame)
|
||||
self.pos = pt
|
||||
self.index = index
|
||||
self.node = ba.newnode(
|
||||
'region',
|
||||
delegate=self,
|
||||
attrs={
|
||||
'position': pt[:3],
|
||||
'scale': (pt[3] * 2.0, pt[4] * 2.0, pt[5] * 2.0),
|
||||
'type': 'box',
|
||||
'materials': [activity.race_region_material]
|
||||
})
|
||||
|
||||
|
||||
|
||||
# ba_meta export game
|
||||
class rg(ba.TeamGameActivity[Player, Team]):
|
||||
"""Game of racing around a track."""
|
||||
|
||||
name = 'Racex'
|
||||
description = 'Run real fast!'
|
||||
scoreconfig = ba.ScoreConfig(label='Time',
|
||||
lower_is_better=True,
|
||||
scoretype=ba.ScoreType.MILLISECONDS)
|
||||
|
||||
@classmethod
|
||||
def get_available_settings(
|
||||
cls, sessiontype: type[ba.Session]) -> list[ba.Setting]:
|
||||
settings = [
|
||||
ba.IntSetting('Laps', min_value=1, default=3, increment=1),
|
||||
ba.IntChoiceSetting(
|
||||
'Time Limit',
|
||||
default=0,
|
||||
choices=[
|
||||
('None', 0),
|
||||
('1 Minute', 60),
|
||||
('2 Minutes', 120),
|
||||
('5 Minutes', 300),
|
||||
('10 Minutes', 600),
|
||||
('20 Minutes', 1200),
|
||||
],
|
||||
),
|
||||
ba.IntChoiceSetting(
|
||||
'Mine Spawning',
|
||||
default=4000,
|
||||
choices=[
|
||||
('No Mines', 0),
|
||||
('8 Seconds', 8000),
|
||||
('4 Seconds', 4000),
|
||||
('2 Seconds', 2000),
|
||||
],
|
||||
),
|
||||
ba.IntChoiceSetting(
|
||||
'Bomb Spawning',
|
||||
choices=[
|
||||
('None', 0),
|
||||
('8 Seconds', 8000),
|
||||
('4 Seconds', 4000),
|
||||
('2 Seconds', 2000),
|
||||
('1 Second', 1000),
|
||||
],
|
||||
default=2000,
|
||||
),
|
||||
ba.BoolSetting('Epic Mode', default=False),
|
||||
]
|
||||
|
||||
# We have some specific settings in teams mode.
|
||||
if issubclass(sessiontype, ba.DualTeamSession):
|
||||
settings.append(
|
||||
ba.BoolSetting('Entire Team Must Finish', default=False))
|
||||
return settings
|
||||
|
||||
@classmethod
|
||||
def supports_session_type(cls, sessiontype: type[ba.Session]) -> bool:
|
||||
return issubclass(sessiontype, ba.MultiTeamSession)
|
||||
|
||||
@classmethod
|
||||
def get_supported_maps(cls, sessiontype: type[ba.Session]) -> list[str]:
|
||||
return ba.getmaps('race')
|
||||
|
||||
def __init__(self, settings: dict):
|
||||
self._race_started = False
|
||||
super().__init__(settings)
|
||||
|
||||
|
||||
|
||||
def get_instance_description(self) -> Union[str, Sequence]:
|
||||
if (isinstance(self.session, ba.DualTeamSession)
|
||||
and self._entire_team_must_finish):
|
||||
t_str = ' Your entire team has to finish.'
|
||||
else:
|
||||
t_str = ''
|
||||
|
||||
if self._laps > 1:
|
||||
return 'Run ${ARG1} laps.' + t_str, self._laps
|
||||
return 'Run 1 lap.' + t_str
|
||||
|
||||
def get_instance_description_short(self) -> Union[str, Sequence]:
|
||||
if self._laps > 1:
|
||||
return 'run ${ARG1} laps', self._laps
|
||||
return 'run 1 lap'
|
||||
|
||||
|
||||
|
||||
def on_player_leave(self, player: Player) -> None:
|
||||
super().on_player_leave(player)
|
||||
|
||||
|
||||
|
||||
def on_begin(self) -> None:
|
||||
from bastd.actor.onscreentimer import OnScreenTimer
|
||||
super().on_begin()
|
||||
Loading…
Add table
Add a link
Reference in a new issue