Update MusicalFlags.py for 1.7.20+

• 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)
This commit is contained in:
! Freaku 2023-07-28 16:17:13 +05:30 committed by GitHub
parent ecf6dafddd
commit a8c848a34e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -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)