From a8c848a34ecf19f2e51812871737695387b34a36 Mon Sep 17 00:00:00 2001 From: ! Freaku <92618708+Freaku17@users.noreply.github.com> Date: Fri, 28 Jul 2023 16:17:13 +0530 Subject: [PATCH] Update MusicalFlags.py for 1.7.20+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Added Round Timer for each round Fixes 3 major issues: • If "friends" are doing timepass instead of grabbing flags • If player leaves match when others have got flags • Adds support for infinite players (earlier supported only 13 players due to limited flag colors list) --- Gamemodes/MusicalFlags.py | 148 +++++++++++++++++++++++--------------- 1 file changed, 91 insertions(+), 57 deletions(-) diff --git a/Gamemodes/MusicalFlags.py b/Gamemodes/MusicalFlags.py index 1d34ca6..835b101 100644 --- a/Gamemodes/MusicalFlags.py +++ b/Gamemodes/MusicalFlags.py @@ -1,5 +1,5 @@ ## Made by MattZ45986 on GitHub -## Ported by: Freaku / @[Just] Freak#4999 +## Ported by your friend: Freaku #Bug Fixes & Improvements as well... @@ -12,73 +12,67 @@ from __future__ import annotations from typing import TYPE_CHECKING -import _ba,ba,random,math -from bastd.actor.flag import Flag,FlagPickedUpMessage -from bastd.actor.playerspaz import PlayerSpaz +import _babase, random, math +import bascenev1 as bs +from bascenev1lib.actor.flag import Flag,FlagPickedUpMessage +from bascenev1lib.actor.playerspaz import PlayerSpaz if TYPE_CHECKING: from typing import Any, Type, List, Dict, Tuple, Union, Sequence, Optional -class Player(ba.Player['Team']): +class Player(bs.Player['Team']): def __init__(self) -> None: self.done: bool = False self.survived: bool = True -class Team(ba.Team[Player]): +class Team(bs.Team[Player]): def __init__(self) -> None: self.score = 0 -# ba_meta require api 7 -# ba_meta export game -class MFGame(ba.TeamGameActivity[Player, Team]): +# ba_meta require api 8 +# ba_meta export bascenev1.GameActivity +class MFGame(bs.TeamGameActivity[Player, Team]): name = 'Musical Flags' description = "Don't be the one stuck without a flag!" @classmethod def get_available_settings( - cls, sessiontype: Type[ba.Session]) -> List[ba.Setting]: + cls, sessiontype: Type[bs.Session]) -> List[babase.Setting]: settings = [ - ba.IntChoiceSetting( - 'Time Limit', - choices=[ - ('None', 0), - ('1 Minute', 60), - ('2 Minutes', 120), - ('5 Minutes', 300), - ('10 Minutes', 600), - ('20 Minutes', 1200), - ], - default=0, + bs.IntSetting( + 'Max Round Time', + min_value=15, + default=25, + increment=5, ), - ba.BoolSetting('Epic Mode', default=False), - ba.BoolSetting('Enable Running', default=True), - ba.BoolSetting('Enable Punching', default=False), - ba.BoolSetting('Enable Bottom Credit', True) + bs.BoolSetting('Epic Mode', default=False), + bs.BoolSetting('Enable Running', default=True), + bs.BoolSetting('Enable Punching', default=False), + bs.BoolSetting('Enable Bottom Credit', True) ] return settings @classmethod - def supports_session_type(cls, sessiontype: Type[ba.Session]) -> bool: - return (issubclass(sessiontype, ba.DualTeamSession) - or issubclass(sessiontype, ba.FreeForAllSession)) + def supports_session_type(cls, sessiontype: Type[bs.Session]) -> bool: + return (issubclass(sessiontype, bs.DualTeamSession) + or issubclass(sessiontype, bs.FreeForAllSession)) @classmethod - def get_supported_maps(cls, sessiontype: Type[ba.Session]) -> List[str]: + def get_supported_maps(cls, sessiontype: Type[bs.Session]) -> List[str]: return ['Doom Shroom'] def __init__(self, settings: dict): super().__init__(settings) self.nodes = [] - self._dingsound = ba.getsound('dingSmall') + self._dingsound = bs.getsound('dingSmall') self._epic_mode = bool(settings['Epic Mode']) self.credit_text = bool(settings['Enable Bottom Credit']) - self._time_limit = float(settings['Time Limit']) self.is_punch = bool(settings['Enable Punching']) self.is_run = bool(settings['Enable Running']) - self._textRound = ba.newnode('text', + self._textRound = bs.newnode('text', attrs={'text': '', 'position': (0, -38), 'scale': 1, @@ -90,10 +84,16 @@ class MFGame(ba.TeamGameActivity[Player, Team]): 'h_attach': 'center', 'h_align': 'center', 'v_align': 'center'}) + self.round_time = int(settings['Max Round Time']) + self.reset_round_time = int(settings['Max Round Time']) + self.should_die_occur = True + self.round_time_textnode = bs.newnode('text', + attrs={ + 'text': "",'flatness':1.0,'h_align':'center','h_attach':'center','v_attach':'top','v_align':'center','position':(0,-15),'scale':0.9,'color':(1,0.7,0.9)}) self.slow_motion = self._epic_mode # A cool music, matching our gamemode theme - self.default_music = ba.MusicType.FLAG_CATCHER + self.default_music = bs.MusicType.FLAG_CATCHER def get_instance_description(self) -> Union[str, Sequence]: return 'Catch Flag for yourself' @@ -103,8 +103,8 @@ class MFGame(ba.TeamGameActivity[Player, Team]): def on_player_join(self, player: Player) -> None: if self.has_begun(): - ba.screenmessage( - ba.Lstr(resource='playerDelayedJoinText', + bs.broadcastmessage( + bs.Lstr(resource='playerDelayedJoinText', subs=[('${PLAYER}', player.getname(full=True))]), color=(0, 1, 0),transient=True) player.survived = False @@ -114,7 +114,7 @@ class MFGame(ba.TeamGameActivity[Player, Team]): def on_player_leave(self, player: Player) -> None: super().on_player_leave(player) # A departing player may trigger game-over. - self.checkEnd() + bs.timer(0, self.checkEnd) def on_begin(self) -> None: super().on_begin() @@ -123,12 +123,35 @@ class MFGame(ba.TeamGameActivity[Player, Team]): self.nodes = [] self.flags = [] self.spawned = [] - self.setup_standard_time_limit(self._time_limit) import base64 - exec(base64.b64decode("aWYgc2VsZi5jcmVkaXRfdGV4dDoKICAgICMjIFBlb3BsZSBzdGVhbGVkIGNyZWRpdHMgc28gdGhhdHMgd2h5IEkgZW5jb2RlZCB0aGlzLi4uCiAgICAjIyBFdmVuIHRobyB0aGVyZSBpcyBhIG9wdGlvbiwgdGhleSBjaGFuZ2VkIGNyZWF0ZWQgYnkKICAgICMjIGxpa2Ugd3RmIGlzIHRoaWVyIHByb2JsZW0/PwoKICAgICMjIEFueXdheXMgaGF2ZSBhIGdvb2QgZGF5IQogICAgdCA9IGJhLm5ld25vZGUoJ3RleHQnLAogICAgICAgICAgICAgICBhdHRycz17ICd0ZXh0JzoiUG9ydGVkIGJ5IO6BiEZyZWFrdVxuTWFkZSBieSBNYXR0WjQ1OTg2IiwgIyMgRGlzYWJsZSAnRW5hYmxlIEJvdHRvbSBDcmVkaXRzJyB3aGVuIG1ha2luZyBwbGF5bGlzdCwgTm8gbmVlZCB0byBlZGl0IHRoaXMgbG92ZWx5Li4uCiAgICAgICAgJ3NjYWxlJzowLjcsCiAgICAgICAgJ3Bvc2l0aW9uJzooMCwwKSwKICAgICAgICAnc2hhZG93JzowLjUsCiAgICAgICAgJ2ZsYXRuZXNzJzoxLjIsCiAgICAgICAgJ2NvbG9yJzooMSwgMSwgMSksCiAgICAgICAgJ2hfYWxpZ24nOidjZW50ZXInLAogICAgICAgICd2X2F0dGFjaCc6J2JvdHRvbSd9KQ==").decode('UTF-8')) + exec(base64.b64decode("aWYgc2VsZi5jcmVkaXRfdGV4dDoKICAgICMjIFBlb3BsZSBzdGVhbGVkIGNyZWRpdHMgc28gdGhhdHMgd2h5IEkgZW5jb2RlZCB0aGlzLi4uCiAgICAjIyBFdmVuIHRobyB0aGVyZSBpcyBhIG9wdGlvbiwgdGhleSBjaGFuZ2VkIGNyZWF0ZWQgYnkKICAgICMjIGxpa2Ugd3RmIGlzIHRoaWVyIHByb2JsZW0/PwoKICAgICMjIEFueXdheXMgaGF2ZSBhIGdvb2QgZGF5IQogICAgdCA9IGJzLm5ld25vZGUoJ3RleHQnLAogICAgICAgICAgICAgICBhdHRycz17ICd0ZXh0JzoiUG9ydGVkIGJ5IO6BiEZyZWFrdVxuTWFkZSBieSBNYXR0WjQ1OTg2IiwgIyMgRGlzYWJsZSAnRW5hYmxlIEJvdHRvbSBDcmVkaXRzJyB3aGVuIG1ha2luZyBwbGF5bGlzdCwgTm8gbmVlZCB0byBlZGl0IHRoaXMgbG92ZWx5Li4uCiAgICAgICAgJ3NjYWxlJzowLjcsCiAgICAgICAgJ3Bvc2l0aW9uJzooMCwwKSwKICAgICAgICAnc2hhZG93JzowLjUsCiAgICAgICAgJ2ZsYXRuZXNzJzoxLjIsCiAgICAgICAgJ2NvbG9yJzooMSwgMSwgMSksCiAgICAgICAgJ2hfYWxpZ24nOidjZW50ZXInLAogICAgICAgICd2X2F0dGFjaCc6J2JvdHRvbSd9KQ==").decode('UTF-8')) self.makeRound() self._textRound.text = 'Round ' + str(self.roundNum) - ba.timer(5, self.checkEnd) + bs.timer(3, self.checkEnd) + self.keepcalling = bs.timer(1, self._timeround, True) + + def _timeround(self): + if self.round_time == 0 and self.should_die_occur: + self.should_die_occur = False + self.round_time_textnode.opacity = 0 + bs.broadcastmessage('Proceeding Round...') + for player in self.spawned: + if not player.done: + try: + player.survived = False + player.actor.handlemessage(bs.StandMessage((0,3,-2))) + bs.timer(0.5,bs.Call(player.actor.handlemessage, bs.FreezeMessage())) + bs.timer(1.5,bs.Call(player.actor.handlemessage, bs.FreezeMessage())) + bs.timer(2.5,bs.Call(player.actor.handlemessage, bs.FreezeMessage())) + bs.timer(3,bs.Call(player.actor.handlemessage, bs.ShouldShatterMessage())) + except: pass + bs.timer(3.5,self.killRound) + bs.timer(3.55,self.makeRound) + self.round_time_textnode.opacity = 0 + self.round_time = self.reset_round_time + else: + self.round_time_textnode.text = "Time: " + str(self.round_time) + self.round_time -= 1 def makeRound(self): for player in self.players: @@ -137,6 +160,9 @@ class MFGame(ba.TeamGameActivity[Player, Team]): self._textRound.text = 'Round ' + str(self.roundNum) self.flags = [] self.spawned = [] + self.should_die_occur = True + self.round_time = self.reset_round_time + self.round_time_textnode.opacity = 1 angle = random.randint(0,359) c=0 for player in self.players: @@ -151,6 +177,12 @@ class MFGame(ba.TeamGameActivity[Player, Team]): try: spacing = 360 // (c) except: self.checkEnd() colors = [(1,0,0),(0,1,0),(0,0,1),(1,1,0),(1,0,1),(0,1,1),(0,0,0),(0.5,0.8,0),(0,0.8,0.5),(0.8,0.25,0.7),(0,0.27,0.55),(2,2,0.6),(0.4,3,0.85)] + + # Add support for more than 13 players + if c > 12: + for i in range(c-12): + colors.append((random.uniform(0.1, 1), random.uniform(0.1, 1), random.uniform(0.1, 1))) + # Smart Mathematics: # All Flags spawn same distance from the players for i in range(c-1): @@ -164,16 +196,16 @@ class MFGame(ba.TeamGameActivity[Player, Team]): def killRound(self): self.numPickedUp = 0 for player in self.players: - if player.is_alive(): player.actor.handlemessage(ba.DieMessage()) + if player.is_alive(): player.actor.handlemessage(bs.DieMessage()) for flag in self.flags: flag.node.delete() for light in self.nodes: light.delete() - def spawn_player(self, player: Player, pos: tuple = (0,0,0)) -> ba.Actor: + def spawn_player(self, player: Player, pos: tuple = (0,0,0)) -> bs.Actor: spaz = self.spawn_player_spaz(player) if pos == (0,0,0): pos = (-.5+random.random()*2,3+random.random()*2,-5+random.random()*2) spaz.connect_controls_to_player(enable_punch=self.is_punch, enable_bomb=False, enable_run=self.is_run) - spaz.handlemessage(ba.StandMessage(pos)) + spaz.handlemessage(bs.StandMessage(pos)) return spaz def check_respawn(self, player): @@ -182,35 +214,37 @@ class MFGame(ba.TeamGameActivity[Player, Team]): def handlemessage(self, msg: Any) -> Any: - if isinstance(msg, ba.PlayerDiedMessage): + if isinstance(msg, bs.PlayerDiedMessage): super().handlemessage(msg) player = msg.getplayer(Player) - ba.timer(0.1, ba.Call(self.check_respawn, player)) - ba.timer(0.5, self.checkEnd) + bs.timer(0.1, bs.Call(self.check_respawn, player)) + bs.timer(0.5, self.checkEnd) elif isinstance(msg, FlagPickedUpMessage): self.numPickedUp += 1 msg.node.getdelegate(PlayerSpaz, True).getplayer(Player, True).done = True - l = ba.newnode('light', + l = bs.newnode('light', owner=None, attrs={'color':msg.node.color, 'position':(msg.node.position_center), 'intensity':1}) self.nodes.append(l) - msg.flag.handlemessage(ba.DieMessage()) - msg.node.handlemessage(ba.DieMessage()) + msg.flag.handlemessage(bs.DieMessage()) + msg.node.handlemessage(bs.DieMessage()) msg.node.delete() if self.numPickedUp == len(self.flags): + self.round_time_textnode.opacity = 0 + self.round_time = self.reset_round_time for player in self.spawned: if not player.done: try: player.survived = False - ba.screenmessage("No Flag? "+player.getname()) - player.actor.handlemessage(ba.StandMessage((0,3,-2))) - ba.timer(0.5,ba.Call(player.actor.handlemessage, ba.FreezeMessage())) - ba.timer(3,ba.Call(player.actor.handlemessage, ba.ShouldShatterMessage())) + bs.broadcastmessage("No Flag? "+player.getname()) + player.actor.handlemessage(bs.StandMessage((0,3,-2))) + bs.timer(0.5,bs.Call(player.actor.handlemessage, bs.FreezeMessage())) + bs.timer(3,bs.Call(player.actor.handlemessage, bs.ShouldShatterMessage())) except: pass - ba.timer(3.5,self.killRound) - ba.timer(3.55,self.makeRound) + bs.timer(3.5,self.killRound) + bs.timer(3.55,self.makeRound) else: return super().handlemessage(msg) return None @@ -224,10 +258,10 @@ class MFGame(ba.TeamGameActivity[Player, Team]): for player in self.players: if player.survived: player.team.score += 10 - ba.timer(2.5, self.end_game) + bs.timer(2.5, self.end_game) def end_game(self) -> None: - results = ba.GameResults() + results = bs.GameResults() for team in self.teams: results.set_team_score(team, team.score) - self.end(results=results) + self.end(results=results) \ No newline at end of file