bombsquad-plugin-manager/plugins/minigames/last_punch_stand.py

273 lines
8.7 KiB
Python
Raw Normal View History

2023-05-15 15:56:45 +05:30
# ba_meta require api 7
from typing import Sequence
2023-05-15 10:58:00 +00:00
import ba
import _ba
import random
2023-05-15 15:56:45 +05:30
from bastd.actor.spaz import Spaz
from bastd.actor.scoreboard import Scoreboard
2023-05-15 10:58:00 +00:00
2023-05-15 15:56:45 +05:30
class Player(ba.Player['Team']):
2023-05-15 10:58:00 +00:00
"""Our player type for this game."""
2023-05-15 15:56:45 +05:30
class Team(ba.Team[Player]):
2023-05-15 10:58:00 +00:00
"""Our team type for this game."""
def __init__(self) -> None:
super().__init__()
self.score = 1
2023-05-15 15:56:45 +05:30
class ChooseingSpazHitMessage:
2023-05-15 10:58:00 +00:00
def __init__(self, hitter: Player) -> None:
self.hitter = hitter
2023-05-15 15:56:45 +05:30
class ChooseingSpazDieMessage:
2023-05-15 10:58:00 +00:00
def __init__(self, killer: Player) -> None:
self.killer = killer
2023-05-15 15:56:45 +05:30
class ChooseingSpaz(Spaz):
2023-05-15 10:58:00 +00:00
def __init__(
self,
pos: Sequence[float],
color: Sequence[float] = (1.0, 1.0, 1.0),
highlight: Sequence[float] = (0.5, 0.5, 0.5),
):
super().__init__(color, highlight, "Spaz", None, True, True, False, False)
self.last_player_attacked_by = None
self.stand(pos)
self.loc = ba.newnode(
2023-05-15 15:56:45 +05:30
'locator',
attrs={
'shape': 'circleOutline',
'position': pos,
'color': color,
'opacity': 1,
'draw_beauty': False,
'additive': True,
},
)
2023-05-15 10:58:00 +00:00
self.node.connectattr("position", self.loc, "position")
ba.animate_array(self.loc, "size", 1, keys={0: [0.5,], 1: [2,], 1.5: [0.5]}, loop=True)
2023-05-15 15:56:45 +05:30
2023-05-15 10:58:00 +00:00
def handlemessage(self, msg):
if isinstance(msg, ba.FreezeMessage):
return
2023-05-15 15:56:45 +05:30
2023-05-15 10:58:00 +00:00
if isinstance(msg, ba.PowerupMessage):
if not (msg.poweruptype == "health"):
return
2023-05-15 15:56:45 +05:30
2023-05-15 10:58:00 +00:00
super().handlemessage(msg)
2023-05-15 15:56:45 +05:30
2023-05-15 10:58:00 +00:00
if isinstance(msg, ba.HitMessage):
self.handlemessage(ba.PowerupMessage("health"))
2023-05-15 15:56:45 +05:30
2023-05-15 10:58:00 +00:00
player = msg.get_source_player(Player)
if self.is_alive():
self.activity.handlemessage(ChooseingSpazHitMessage(player))
self.last_player_attacked_by = player
2023-05-15 15:56:45 +05:30
2023-05-15 10:58:00 +00:00
elif isinstance(msg, ba.DieMessage):
player = self.last_player_attacked_by
2023-05-15 15:56:45 +05:30
2023-05-15 10:58:00 +00:00
if msg.how.value != ba.DeathType.GENERIC.value:
self._dead = True
self.activity.handlemessage(ChooseingSpazDieMessage(player))
2023-05-15 15:56:45 +05:30
2023-05-15 10:58:00 +00:00
self.loc.delete()
2023-05-15 15:56:45 +05:30
2023-05-15 10:58:00 +00:00
def stand(self, pos=(0, 0, 0), angle=0):
self.handlemessage(ba.StandMessage(pos, angle))
2023-05-15 15:56:45 +05:30
2023-05-15 10:58:00 +00:00
def recolor(self, color, highlight=(1, 1, 1)):
self.node.color = color
self.node.highlight = highlight
self.loc.color = color
2023-05-15 15:56:45 +05:30
2023-05-15 10:58:00 +00:00
class ChooseBilbord(ba.Actor):
def __init__(self, player: Player, delay=0.1) -> None:
super().__init__()
2023-05-15 15:56:45 +05:30
2023-05-15 10:58:00 +00:00
icon = player.get_icon()
self.scale = 100
2023-05-15 15:56:45 +05:30
2023-05-15 10:58:00 +00:00
self.node = ba.newnode(
'image',
delegate=self,
attrs={
"position": (60, -125),
'texture': icon['texture'],
'tint_texture': icon['tint_texture'],
'tint_color': icon['tint_color'],
'tint2_color': icon['tint2_color'],
'opacity': 1.0,
'absolute_scale': True,
'attach': "topLeft"
},
)
self.name_node = ba.newnode(
'text',
owner=self.node,
attrs={
'position': (60, -185),
'text': ba.Lstr(value=player.getname()),
'color': ba.safecolor(player.team.color),
'h_align': 'center',
'v_align': 'center',
'vr_depth': 410,
'flatness': 1.0,
'h_attach': 'left',
'v_attach': 'top',
'maxwidth': self.scale
},
)
ba.animate_array(self.node, "scale", keys={
0 + delay: [0, 0], 0.05 + delay: [self.scale, self.scale]}, size=1)
ba.animate(self.name_node, "scale", {0 + delay: 0, 0.07 + delay: 1})
def handlemessage(self, msg):
super().handlemessage(msg)
if isinstance(msg, ba.DieMessage):
ba.animate_array(self.node, "scale", keys={0: self.node.scale, 0.05: [0, 0]}, size=1)
ba.animate(self.name_node, "scale", {0: self.name_node.scale, 0.07: 0})
def __delete():
self.node.delete()
self.name_node.delete()
ba.timer(0.2, __delete)
2023-05-15 15:56:45 +05:30
# ba_meta export game
2023-05-15 10:58:00 +00:00
2023-05-15 15:56:45 +05:30
class LastPunchStand(ba.TeamGameActivity[Player, Team]):
2023-05-15 10:58:00 +00:00
name = "Last Punch Stand"
description = "Last one punchs the choosing spaz wins"
tips = [
'keep punching the choosing spaz to be last punched player at times up!',
'you can not frezz the choosing spaz',
"evry time you punch the choosing spaz, you will get one point",
]
default_music = ba.MusicType.TO_THE_DEATH
available_settings = [
ba.FloatSetting("min time limit (in seconds)", 50.0, min_value=30.0),
ba.FloatSetting("max time limit (in seconds)", 160.0, 60),
]
def __init__(self, settings: dict):
super().__init__(settings)
self._min_timelimit = settings["min time limit (in seconds)"]
self._max_timelimit = settings["max time limit (in seconds)"]
if (self._min_timelimit > self._max_timelimit):
self._max_timelimit = self._min_timelimit
self._choosing_spaz_defcolor = (0.5, 0.5, 0.5)
self.choosing_spaz = None
self.choosed_player = None
self.times_uped = False
self.scoreboard = Scoreboard()
def times_up(self):
self.times_uped = True
for player in self.players:
if self.choosed_player and (player.team.id != self.choosed_player.team.id):
player.actor._cursed = True
player.actor.curse_explode()
self.end_game()
def __get_spaz_bot_spawn_point(self):
if len(self.map.tnt_points) > 0:
return self.map.tnt_points[random.randint(0, len(self.map.tnt_points)-1)]
else:
return (0, 6, 0)
def spaw_bot(self):
"spawns a choosing bot"
self.choosing_spaz = ChooseingSpaz(self.__get_spaz_bot_spawn_point())
self.choose_bilbord = None
def on_begin(self) -> None:
super().on_begin()
time_limit = random.randint(self._min_timelimit, self._max_timelimit)
self.spaw_bot()
ba.timer(time_limit, self.times_up)
self.setup_standard_powerup_drops(False)
def end_game(self) -> None:
results = ba.GameResults()
for team in self.teams:
if self.choosed_player and (team.id == self.choosed_player.team.id):
team.score += 100
results.set_team_score(team, team.score)
self.end(results=results)
def change_choosed_player(self, hitter: Player):
if hitter:
self.choosing_spaz.recolor(hitter.color, hitter.highlight)
self.choosed_player = hitter
hitter.team.score += 1
self.choose_bilbord = ChooseBilbord(hitter)
self.hide_score_board()
else:
self.choosing_spaz.recolor(self._choosing_spaz_defcolor)
self.choosed_player = None
self.choose_bilbord = None
self.show_score_board()
def show_score_board(self):
self.scoreboard = Scoreboard()
for team in self.teams:
self.scoreboard.set_team_value(team, team.score)
def hide_score_board(self):
self.scoreboard = None
def _watch_dog_(self):
"checks if choosing spaz exists"
# choosing spaz wont respawn if death type if generic
# this becuse we dont want to keep respawn him when he dies because of losing referce
# but sometimes "choosing spaz" dies naturaly and his death type is generic! so it wont respawn back again
# thats why we have this function; to check if spaz exits in the case that he didnt respawned
if self.choosing_spaz:
if self.choosing_spaz._dead:
self.spaw_bot()
else:
self.spaw_bot()
def handlemessage(self, msg):
super().handlemessage(msg)
if isinstance(msg, ChooseingSpazHitMessage):
hitter = msg.hitter
if self.choosing_spaz.node and hitter:
self.change_choosed_player(hitter)
elif isinstance(msg, ChooseingSpazDieMessage):
self.spaw_bot()
self.change_choosed_player(None)
elif isinstance(msg, ba.PlayerDiedMessage):
player = msg.getplayer(Player)
if not (self.has_ended() or self.times_uped):
self.respawn_player(player, 0)
if self.choosed_player and (player.getname(True) == self.choosed_player.getname(True)):
self.change_choosed_player(None)
self._watch_dog_()