Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update gamemode for API 8 #183

Merged
merged 3 commits into from
Jul 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions plugins/minigames.json
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,12 @@
}
],
"versions": {
"2.0.0": {
"api_version": 8,
"commit_sha": "8f281f9",
"released_on": "30-07-2023",
"md5sum": "c512cd21244f9537b7ff98438a3e6ef8"
},
"1.0.0": {
"api_version": 7,
"commit_sha": "7219487",
Expand Down
219 changes: 14 additions & 205 deletions plugins/minigames/yeeting_party.py
Original file line number Diff line number Diff line change
@@ -1,224 +1,33 @@
# Made by your friend: @[Just] Freak#4999
# Made by your friend: Freaku

# ba_meta require api 7
from __future__ import annotations

from typing import TYPE_CHECKING
import babase
import bascenev1 as bs
from bascenev1lib.game.deathmatch import Player, DeathMatchGame

import ba
from bastd.actor.playerspaz import PlayerSpaz
from bastd.actor.scoreboard import Scoreboard

if TYPE_CHECKING:
from typing import Any, Type, List, Dict, Tuple, Union, Sequence, Optional


class Player(ba.Player['Team']):
"""Our player type for this game."""


class Team(ba.Team[Player]):
"""Our team type for this game."""

def __init__(self) -> None:
self.score = 0


# ba_meta export game
class BoxingGame(ba.TeamGameActivity[Player, Team]):
# ba_meta require api 8
# ba_meta export bascenev1.GameActivity
class YeetingGame(DeathMatchGame):
"""A game of yeeting people out of map"""

name = 'Yeeting Party!'
description = 'Yeet your enemies out of the map'

# 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]:
def get_supported_maps(cls, sessiontype):
return ['Bridgit', 'Rampage', 'Monkey Face']

def __init__(self, settings: dict):
super().__init__(settings)
self._scoreboard = Scoreboard()
self._score_to_win: Optional[int] = None
self._dingsound = ba.getsound('dingSmall')
self._epic_mode = bool(settings['Epic Mode'])
self._kills_to_win_per_player = int(
settings['Kills to Win Per Player'])
self._time_limit = float(settings['Time Limit'])
self._allow_negative_scores = bool(
settings.get('Allow Negative Scores', False))

# Base class overrides.
self.slow_motion = self._epic_mode
self.default_music = (ba.MusicType.EPIC if self._epic_mode else
ba.MusicType.TO_THE_DEATH)

def get_instance_description(self) -> Union[str, Sequence]:
def get_instance_description(self):
return 'Yeet ${ARG1} enemies out of the map!', self._score_to_win

def get_instance_description_short(self) -> Union[str, Sequence]:
def get_instance_description_short(self):
return 'yeet ${ARG1} enemies', self._score_to_win

def on_team_join(self, team: Team) -> None:
if self.has_begun():
self._update_scoreboard()

def getRandomPowerupPoint(self) -> None:
myMap = self.map.getname()
if myMap == 'Doom Shroom':
while True:
x = random.uniform(-1.0, 1.0)
y = random.uniform(-1.0, 1.0)
if x*x+y*y < 1.0:
break
return ((8.0*x, 2.5, -3.5+5.0*y))
elif myMap == 'Rampage':
x = random.uniform(-6.0, 7.0)
y = random.uniform(-6.0, -2.5)
return ((x, 5.2, y))
else:
x = random.uniform(-5.0, 5.0)
y = random.uniform(-6.0, 0.0)
return ((x, 8.0, y))

def on_begin(self) -> None:
super().on_begin()
ba.screenmessage("start Yeeting", color=(0.2, 1, 1))
self.setup_standard_time_limit(self._time_limit)
# Base kills needed to win on the size of the largest team.
self._score_to_win = (self._kills_to_win_per_player *
max(1, max(len(t.players) for t in self.teams)))
self._update_scoreboard()

def spawn_player(self, player: Player) -> ba.Actor:
def setup_standard_powerup_drops(self, enable_tnt: bool = True) -> None:
pass

def spawn_player(self, player: Player):
spaz = self.spawn_player_spaz(player)

# Let's reconnect this player's controls to this
# spaz but *without* the ability to attack or pick stuff up.
spaz.connect_controls_to_player(enable_punch=False,
enable_jump=True,
enable_bomb=False,
enable_pickup=True)
spaz.connect_controls_to_player(enable_punch=False, enable_bomb=False)
return spaz

def handlemessage(self, msg: Any) -> Any:

if isinstance(msg, ba.PlayerDiedMessage):

# Augment standard behavior.
super().handlemessage(msg)

player = msg.getplayer(Player)
self.respawn_player(player)

killer = msg.getkillerplayer(Player)
if killer is None:
return None

# Handle team-kills.
if killer.team is player.team:

# In free-for-all, killing yourself loses you a point.
if isinstance(self.session, ba.FreeForAllSession):
new_score = player.team.score - 1
if not self._allow_negative_scores:
new_score = max(0, new_score)
player.team.score = new_score

# In teams-mode it gives a point to the other team.
else:
ba.playsound(self._dingsound)
for team in self.teams:
if team is not killer.team:
team.score += 1

# Killing someone on another team nets a kill.
else:
killer.team.score += 1
ba.playsound(self._dingsound)

# In FFA show scores since its hard to find on the scoreboard.
if isinstance(killer.actor, PlayerSpaz) and killer.actor:
killer.actor.set_score_text(str(killer.team.score) + '/' +
str(self._score_to_win),
color=killer.team.color,
flash=True)

self._update_scoreboard()

# If someone has won, set a timer to end shortly.
# (allows the dust to clear and draws to occur if deaths are
# close enough)
assert self._score_to_win is not None
if any(team.score >= self._score_to_win for team in self.teams):
ba.timer(0.5, self.end_game)

else:
return super().handlemessage(msg)
return None

def _update_scoreboard(self) -> None:
for team in self.teams:
self._scoreboard.set_team_value(team, team.score,
self._score_to_win)

def end_game(self) -> None:
results = ba.GameResults()
for team in self.teams:
results.set_team_score(team, team.score)
self.end(results=results)