From 3681f4e2532517e2392956d28af9a452870be73d Mon Sep 17 00:00:00 2001 From: A Dhextras <104954857+dhextras@users.noreply.github.com> Date: Thu, 20 Jul 2023 22:19:02 +0530 Subject: [PATCH 01/60] Update soccer.py --- plugins/minigames/soccer.py | 130 ++++++++++++++++++------------------ 1 file changed, 66 insertions(+), 64 deletions(-) diff --git a/plugins/minigames/soccer.py b/plugins/minigames/soccer.py index d86c7d5..fccbd4a 100644 --- a/plugins/minigames/soccer.py +++ b/plugins/minigames/soccer.py @@ -2,23 +2,24 @@ # BY Stary_Agent """Hockey game and support classes.""" -# ba_meta require api 7 +# ba_meta require api 8 # (see https://ballistica.net/wiki/meta-tag-system) from __future__ import annotations from typing import TYPE_CHECKING -import ba -from bastd.actor.playerspaz import PlayerSpaz -from bastd.actor.scoreboard import Scoreboard -from bastd.actor.powerupbox import PowerupBoxFactory -from bastd.gameutils import SharedObjects +import babase +import bauiv1 as bui +import bascenev1 as bs +from bascenev1lib.actor.playerspaz import PlayerSpaz +from bascenev1lib.actor.scoreboard import Scoreboard +from bascenev1lib.actor.powerupbox import PowerupBoxFactory +from bascenev1lib.gameutils import SharedObjects if TYPE_CHECKING: from typing import Any, Sequence, Dict, Type, List, Optional, Union - class PuckDiedMessage: """Inform something that a puck has died.""" @@ -26,7 +27,7 @@ class PuckDiedMessage: self.puck = puck -class Puck(ba.Actor): +class Puck(bs.Actor): """A lovely giant hockey puck.""" def __init__(self, position: Sequence[float] = (0.0, 1.0, 0.0)): @@ -41,10 +42,10 @@ class Puck(ba.Actor): assert activity is not None assert isinstance(activity, HockeyGame) pmats = [shared.object_material, activity.puck_material] - self.node = ba.newnode('prop', + self.node = bs.newnode('prop', delegate=self, attrs={ - 'model': activity.puck_model, + 'mesh': activity.puck_model, 'color_texture': activity.puck_tex, 'body': 'sphere', 'reflection': 'soft', @@ -54,10 +55,10 @@ class Puck(ba.Actor): 'position': self._spawn_pos, 'materials': pmats }) - ba.animate(self.node, 'model_scale', {0: 0, 0.2: 1.3, 0.26: 1}) + bs.animate(self.node, 'mesh_scale', {0: 0, 0.2: 1.3, 0.26: 1}) def handlemessage(self, msg: Any) -> Any: - if isinstance(msg, ba.DieMessage): + if isinstance(msg, bs.DieMessage): assert self.node self.node.delete() activity = self._activity() @@ -65,11 +66,11 @@ class Puck(ba.Actor): activity.handlemessage(PuckDiedMessage(self)) # If we go out of bounds, move back to where we started. - elif isinstance(msg, ba.OutOfBoundsMessage): + elif isinstance(msg, bs.OutOfBoundsMessage): assert self.node self.node.position = self._spawn_pos - elif isinstance(msg, ba.HitMessage): + elif isinstance(msg, bs.HitMessage): assert self.node assert msg.force_direction is not None self.node.handlemessage( @@ -90,31 +91,31 @@ class Puck(ba.Actor): super().handlemessage(msg) -class Player(ba.Player['Team']): +class Player(bs.Player['Team']): """Our player type for this game.""" -class Team(ba.Team[Player]): +class Team(bs.Team[Player]): """Our team type for this game.""" def __init__(self) -> None: self.score = 0 -# ba_meta export game -class HockeyGame(ba.TeamGameActivity[Player, Team]): +# ba_meta export bascenev1.GameActivity +class HockeyGame(bs.TeamGameActivity[Player, Team]): """Ice hockey game.""" name = 'Epic Soccer' description = 'Score some goals.' available_settings = [ - ba.IntSetting( + bs.IntSetting( 'Score to Win', min_value=1, default=1, increment=1, ), - ba.IntChoiceSetting( + bs.IntChoiceSetting( 'Time Limit', choices=[ ('None', 0), @@ -126,7 +127,7 @@ class HockeyGame(ba.TeamGameActivity[Player, Team]): ], default=0, ), - ba.FloatChoiceSetting( + bs.FloatChoiceSetting( 'Respawn Times', choices=[ ('Shorter', 0.1), @@ -138,31 +139,32 @@ class HockeyGame(ba.TeamGameActivity[Player, Team]): default=1.0, ), ] - default_music = ba.MusicType.HOCKEY + default_music = bs.MusicType.HOCKEY @classmethod - def supports_session_type(cls, sessiontype: Type[ba.Session]) -> bool: - return issubclass(sessiontype, ba.DualTeamSession) + def supports_session_type(cls, sessiontype: Type[bs.Session]) -> bool: + return issubclass(sessiontype, bs.DualTeamSession) @classmethod - def get_supported_maps(cls, sessiontype: Type[ba.Session]) -> List[str]: - return ba.getmaps('football') + def get_supported_maps(cls, sessiontype: Type[bs.Session]) -> List[str]: + assert babase.app.classic is not None + return babase.app.classic.getmaps('football') def __init__(self, settings: dict): super().__init__(settings) shared = SharedObjects.get() self.slow_motion = True self._scoreboard = Scoreboard() - self._cheer_sound = ba.getsound('cheer') - self._chant_sound = ba.getsound('crowdChant') - self._foghorn_sound = ba.getsound('foghorn') - self._swipsound = ba.getsound('swip') - self._whistle_sound = ba.getsound('refWhistle') - self.puck_model = ba.getmodel('bomb') - self.puck_tex = ba.gettexture('landMine') - self.puck_scored_tex = ba.gettexture('landMineLit') - self._puck_sound = ba.getsound('metalHit') - self.puck_material = ba.Material() + self._cheer_sound = bui.getsound('cheer') + self._chant_sound = bui.getsound('crowdChant') + self._foghorn_sound = bui.getsound('foghorn') + self._swipsound = bui.getsound('swip') + self._whistle_sound = bui.getsound('refWhistle') + self.puck_model = bs.getmesh('bomb') + self.puck_tex = bs.gettexture('landMine') + self.puck_scored_tex = bs.gettexture('landMineLit') + self._puck_sound = bs.getsound('metalHit') + self.puck_material = bs.Material() self.puck_material.add_actions(actions=(('modify_part_collision', 'friction', 0.5))) self.puck_material.add_actions(conditions=('they_have_material', @@ -193,15 +195,15 @@ class HockeyGame(ba.TeamGameActivity[Player, Team]): conditions=('they_have_material', PowerupBoxFactory.get().powerup_material), actions=(('modify_part_collision', 'physical', False), - ('message', 'their_node', 'at_connect', ba.DieMessage()))) - self._score_region_material = ba.Material() + ('message', 'their_node', 'at_connect', bs.DieMessage()))) + self._score_region_material = bs.Material() self._score_region_material.add_actions( conditions=('they_have_material', self.puck_material), actions=(('modify_part_collision', 'collide', True), ('modify_part_collision', 'physical', False), ('call', 'at_connect', self._handle_score))) self._puck_spawn_pos: Optional[Sequence[float]] = None - self._score_regions: Optional[List[ba.NodeActor]] = None + self._score_regions: Optional[List[bs.NodeActor]] = None self._puck: Optional[Puck] = None self._score_to_win = int(settings['Score to Win']) self._time_limit = float(settings['Time Limit']) @@ -228,8 +230,8 @@ class HockeyGame(ba.TeamGameActivity[Player, Team]): defs = self.map.defs self._score_regions = [] self._score_regions.append( - ba.NodeActor( - ba.newnode('region', + bs.NodeActor( + bs.newnode('region', attrs={ 'position': defs.boxes['goal1'][0:3], 'scale': defs.boxes['goal1'][6:9], @@ -237,8 +239,8 @@ class HockeyGame(ba.TeamGameActivity[Player, Team]): 'materials': [self._score_region_material] }))) self._score_regions.append( - ba.NodeActor( - ba.newnode('region', + bs.NodeActor( + bs.newnode('region', attrs={ 'position': defs.boxes['goal2'][0:3], 'scale': defs.boxes['goal2'][6:9], @@ -246,19 +248,19 @@ class HockeyGame(ba.TeamGameActivity[Player, Team]): 'materials': [self._score_region_material] }))) self._update_scoreboard() - ba.playsound(self._chant_sound) + self._chant_sound.play() def on_team_join(self, team: Team) -> None: self._update_scoreboard() def _handle_puck_player_collide(self) -> None: - collision = ba.getcollision() + collision = bs.getcollision() try: puck = collision.sourcenode.getdelegate(Puck, True) player = collision.opposingnode.getdelegate(PlayerSpaz, True).getplayer( Player, True) - except ba.NotFoundError: + except bs.NotFoundError: return puck.last_players_to_touch[player.team.id] = player @@ -277,7 +279,7 @@ class HockeyGame(ba.TeamGameActivity[Player, Team]): if self._puck.scored: return - region = ba.getcollision().sourcenode + region = bs.getcollision().sourcenode index = 0 for index in range(len(self._score_regions)): if region == self._score_regions[index].node: @@ -291,7 +293,7 @@ class HockeyGame(ba.TeamGameActivity[Player, Team]): # Tell all players to celebrate. for player in team.players: if player.actor: - player.actor.handlemessage(ba.CelebrateMessage(2.0)) + player.actor.handlemessage(bs.CelebrateMessage(2.0)) # If we've got the player from the scoring team that last # touched us, give them points. @@ -306,30 +308,30 @@ class HockeyGame(ba.TeamGameActivity[Player, Team]): if team.score >= self._score_to_win: self.end_game() - ba.playsound(self._foghorn_sound) - ba.playsound(self._cheer_sound) + self._foghorn_sound.play() + self._cheer_sound.play() self._puck.scored = True # Change puck texture to something cool self._puck.node.color_texture = self.puck_scored_tex # Kill the puck (it'll respawn itself shortly). - ba.timer(1.0, self._kill_puck) + bs.timer(1.0, self._kill_puck) - light = ba.newnode('light', + light = bs.newnode('light', attrs={ - 'position': ba.getcollision().position, + 'position': bs.getcollision().position, 'height_attenuated': False, 'color': (1, 0, 0) }) - ba.animate(light, 'intensity', {0: 0, 0.5: 1, 1.0: 0}, loop=True) - ba.timer(1.0, light.delete) + bs.animate(light, 'intensity', {0: 0, 0.5: 1, 1.0: 0}, loop=True) + bs.timer(1.0, light.delete) - ba.cameraflash(duration=10.0) + bs.cameraflash(duration=10.0) self._update_scoreboard() 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) @@ -342,7 +344,7 @@ class HockeyGame(ba.TeamGameActivity[Player, Team]): def handlemessage(self, msg: Any) -> Any: # Respawn dead players if they're still in the game. - if isinstance(msg, ba.PlayerDiedMessage): + if isinstance(msg, bs.PlayerDiedMessage): # Augment standard behavior... super().handlemessage(msg) self.respawn_player(msg.getplayer(Player)) @@ -350,23 +352,23 @@ class HockeyGame(ba.TeamGameActivity[Player, Team]): # Respawn dead pucks. elif isinstance(msg, PuckDiedMessage): if not self.has_ended(): - ba.timer(3.0, self._spawn_puck) + bs.timer(3.0, self._spawn_puck) else: super().handlemessage(msg) def _flash_puck_spawn(self) -> None: - light = ba.newnode('light', + light = bs.newnode('light', attrs={ 'position': self._puck_spawn_pos, 'height_attenuated': False, 'color': (1, 0, 0) }) - ba.animate(light, 'intensity', {0.0: 0, 0.25: 1, 0.5: 0}, loop=True) - ba.timer(1.0, light.delete) + bs.animate(light, 'intensity', {0.0: 0, 0.25: 1, 0.5: 0}, loop=True) + bs.timer(1.0, light.delete) def _spawn_puck(self) -> None: - ba.playsound(self._swipsound) - ba.playsound(self._whistle_sound) + self._swipsound.play() + self._whistle_sound.play() self._flash_puck_spawn() assert self._puck_spawn_pos is not None self._puck = Puck(position=self._puck_spawn_pos) From e4a317c8a93520619c0383f36876e91940294456 Mon Sep 17 00:00:00 2001 From: A Dhextras <104954857+dhextras@users.noreply.github.com> Date: Thu, 20 Jul 2023 22:22:06 +0530 Subject: [PATCH 02/60] Update minigames.json --- plugins/minigames.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index ae4f540..477e2b8 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -14,6 +14,7 @@ } ], "versions": { + "2.0.0":null, "1.0.0": { "api_version": 7, "commit_sha": "e59073b", @@ -612,4 +613,4 @@ } } } -} \ No newline at end of file +} From a941899b19bc243f9fc9cbfbb28fd0c94dc93fab Mon Sep 17 00:00:00 2001 From: dhextras Date: Thu, 20 Jul 2023 16:56:57 +0000 Subject: [PATCH 03/60] [ci] auto-format --- plugins/minigames/soccer.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/minigames/soccer.py b/plugins/minigames/soccer.py index fccbd4a..cd9b4f5 100644 --- a/plugins/minigames/soccer.py +++ b/plugins/minigames/soccer.py @@ -20,6 +20,7 @@ from bascenev1lib.gameutils import SharedObjects if TYPE_CHECKING: from typing import Any, Sequence, Dict, Type, List, Optional, Union + class PuckDiedMessage: """Inform something that a puck has died.""" From c84632fecee4df1644f8805e8e687a6a41339361 Mon Sep 17 00:00:00 2001 From: dhextras Date: Thu, 20 Jul 2023 16:56:58 +0000 Subject: [PATCH 04/60] [ci] apply-version-metadata --- plugins/minigames.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index 477e2b8..de4d140 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -14,7 +14,12 @@ } ], "versions": { - "2.0.0":null, + "2.0.0": { + "api_version": 8, + "commit_sha": "a941899", + "released_on": "20-07-2023", + "md5sum": "19f033445a8fe30fc7f4f62d94a54444" + }, "1.0.0": { "api_version": 7, "commit_sha": "e59073b", @@ -613,4 +618,4 @@ } } } -} +} \ No newline at end of file From dd28dc6467a5b5e3865cdb1e113131f7e58a409d Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Sun, 23 Jul 2023 13:53:28 +0200 Subject: [PATCH 05/60] Add files via upload Updated dodge_the_ball minigame to api 8 --- plugins/minigames/dodge_the_ball.py | 793 ++++++++++++++-------------- 1 file changed, 397 insertions(+), 396 deletions(-) diff --git a/plugins/minigames/dodge_the_ball.py b/plugins/minigames/dodge_the_ball.py index a950131..7d1648d 100644 --- a/plugins/minigames/dodge_the_ball.py +++ b/plugins/minigames/dodge_the_ball.py @@ -6,18 +6,20 @@ # Feel free to edit. -# ba_meta require api 7 +# ba_meta require api 8 from __future__ import annotations from typing import TYPE_CHECKING -import ba -from random import choice +import babase +import bauiv1 as bui +import bascenev1 as bs +from random import choice from enum import Enum -from bastd.actor.bomb import Blast -from bastd.actor.popuptext import PopupText -from bastd.actor.powerupbox import PowerupBox -from bastd.actor.onscreencountdown import OnScreenCountdown -from bastd.gameutils import SharedObjects +from bascenev1lib.actor.bomb import Blast +from bascenev1lib.actor.popuptext import PopupText +from bascenev1lib.actor.powerupbox import PowerupBox +from bascenev1lib.actor.onscreencountdown import OnScreenCountdown +from bascenev1lib.gameutils import SharedObjects if TYPE_CHECKING: from typing import NoReturn, Sequence, Any @@ -39,31 +41,28 @@ class BallType(Enum): # increase the next ball speed but less than MEDIUM. # Ball color is crimson(purple+red = pinky color type). - -# this dict decide the ball_type spawning rate like powerup box +# this dict decide the ball_type spawning rate like powerup box ball_type_dict: dict[BallType, int] = { BallType.EASY: 3, BallType.MEDIUM: 2, BallType.HARD: 1, -} +}; - -class Ball(ba.Actor): +class Ball(bs.Actor): """ Shooting Ball """ - - def __init__(self, - position: Sequence[float], - velocity: Sequence[float], - texture: ba.Texture, - body_scale: float = 1.0, - gravity_scale: float = 1.0, - ) -> NoReturn: - - super().__init__() - - shared = SharedObjects.get() - - ball_material = ba.Material() + def __init__(self, + position: Sequence[float], + velocity: Sequence[float], + texture: babase.Texture, + body_scale: float = 1.0, + gravity_scale: float = 1.0, + ) -> NoReturn: + + super().__init__(); + + shared = SharedObjects.get(); + + ball_material = bs.Material(); ball_material.add_actions( conditions=( ( @@ -75,9 +74,9 @@ class Ball(ba.Actor): ('they_have_material', shared.object_material), ), actions=('modify_node_collision', 'collide', False), - ) - - self.node = ba.newnode( + ); + + self.node = bs.newnode( 'prop', delegate=self, attrs={ @@ -85,41 +84,41 @@ class Ball(ba.Actor): 'position': position, 'velocity': velocity, 'body_scale': body_scale, - 'model': ba.getmodel('frostyPelvis'), - 'model_scale': body_scale, + 'mesh': bs.getmesh('frostyPelvis'), + 'mesh_scale': body_scale, 'color_texture': texture, 'gravity_scale': gravity_scale, - 'density': 4.0, # increase density of ball so ball collide with player with heavy force. # ammm very bad grammer + 'density': 4.0, # increase density of ball so ball collide with player with heavy force. # ammm very bad grammer 'materials': (ball_material,), - }, - ) - + }, + ); + # die the ball manually incase the ball doesn't fall the outside of the map - ba.timer(2.5, ba.WeakCall(self.handlemessage, ba.DieMessage())) - + bs.timer(2.5, bs.WeakCall(self.handlemessage, bs.DieMessage())); + # i am not handling anything in this ball Class(except for diemessage). # all game things and logics going to be in the box class def handlemessage(self, msg: Any) -> Any: - - if isinstance(msg, ba.DieMessage): - self.node.delete() + + if isinstance(msg, bs.DieMessage): + self.node.delete(); else: - super().handlemessage(msg) - - -class Box(ba.Actor): + super().handlemessage(msg); + + +class Box(bs.Actor): """ A box that spawn midle of map as a decoration perpose """ + + def __init__(self, + position: Sequence[float], + velocity: Sequence[float], + ) -> NoReturn: + + super().__init__(); - def __init__(self, - position: Sequence[float], - velocity: Sequence[float], - ) -> NoReturn: - - super().__init__() - - shared = SharedObjects.get() + shared = SharedObjects.get(); # self.ball_jump = 0.0; - no_hit_material = ba.Material() + no_hit_material = bs.Material(); # we don't need that the box was move and collide with objects. no_hit_material.add_actions( conditions=( @@ -128,7 +127,7 @@ class Box(ba.Actor): ('they_have_material', shared.attack_material), ), actions=('modify_part_collision', 'collide', False), - ) + ); no_hit_material.add_actions( conditions=( @@ -140,43 +139,43 @@ class Box(ba.Actor): ('modify_part_collision', 'collide', False), ('modify_part_collision', 'physical', False), ), - ) - - self.node = ba.newnode( + ); + + self.node = bs.newnode( 'prop', delegate=self, attrs={ 'body': 'box', 'position': position, - 'model': ba.getmodel('powerup'), - 'light_model': ba.getmodel('powerupSimple'), + 'mesh': bs.getmesh('powerup'), + 'light_mesh': bs.getmesh('powerupSimple'), 'shadow_size': 0.5, 'body_scale': 1.4, - 'model_scale': 1.4, - 'color_texture': ba.gettexture('landMineLit'), + 'mesh_scale': 1.4, + 'color_texture': bs.gettexture('landMineLit'), 'reflection': 'powerup', 'reflection_scale': [1.0], 'materials': (no_hit_material,), - }, - ) + }, + ); # light - self.light = ba.newnode( + self.light = bs.newnode( "light", - owner=self.node, + owner = self.node, attrs={ - 'radius': 0.2, - 'intensity': 0.8, - 'color': (0.0, 1.0, 0.0), + 'radius' : 0.2, + 'intensity' : 0.8, + 'color': (0.0, 1.0, 0.0), } - ) - self.node.connectattr("position", self.light, "position") - # Drawing circle and circleOutline in radius of 3, - # so player can see that how close he is to the box. - # If player is inside this circle the ball speed will increase. - circle = ba.newnode( + ); + self.node.connectattr("position", self.light, "position"); + # Drawing circle and circleOutline in radius of 3, + # so player can see that how close he is to the box. + # If player is inside this circle the ball speed will increase. + circle = bs.newnode( "locator", - owner=self.node, - attrs={ + owner = self.node, + attrs = { 'shape': 'circle', 'color': (1.0, 0.0, 0.0), 'opacity': 0.1, @@ -185,12 +184,12 @@ class Box(ba.Actor): 'additive': True, }, ) - self.node.connectattr("position", circle, "position") + self.node.connectattr("position", circle, "position"); # also adding a outline cause its look nice. - circle_outline = ba.newnode( + circle_outline = bs.newnode( "locator", - owner=self.node, - attrs={ + owner = self.node, + attrs = { 'shape': 'circleOutline', 'color': (1.0, 1.0, 0.0), 'opacity': 0.1, @@ -198,185 +197,187 @@ class Box(ba.Actor): 'draw_beauty': False, 'additive': True, }, - ) - self.node.connectattr("position", circle_outline, "position") - + ); + self.node.connectattr("position", circle_outline, "position"); + # all ball attribute that we need. - self.ball_type: BallType = BallType.EASY - self.shoot_timer: ba.Timer | None = None - self.shoot_speed: float = 0.0 + self.ball_type: BallType = BallType.EASY; + self.shoot_timer: bs.Timer | None = None; + self.shoot_speed: float = 0.0; # this force the shoot if player is inside the red circle. - self.force_shoot_speed: float = 0.0 - self.ball_mag = 3000 - self.ball_gravity: float = 1.0 - self.ball_tex: ba.Texture | None = None - # only for Hard ball_type - self.player_facing_direction: list[float, float] = [0.0, 0.0] + self.force_shoot_speed: float = 0.0; + self.ball_mag = 3000; + self.ball_gravity: float = 1.0; + self.ball_tex: babase.Texture | None = None; + # only for Hard ball_type + self.player_facing_direction: list[float, float] = [0.0, 0.0]; # ball shoot soound. - self.shoot_sound = ba.getsound('laserReverse') - - # same as "powerupdist" - self.ball_type_dist: list[BallType] = [] + self.shoot_sound = bs.getsound('laserReverse'); + + # same as "powerupdist" + self.ball_type_dist: list[BallType] = []; for ball in ball_type_dict: for _ in range(ball_type_dict[ball]): - self.ball_type_dist.append(ball) - + self.ball_type_dist.append(ball); + # Here main logic of game goes here. # like shoot balls, shoot speed, anything we want goes here(except for some thing). def start_shoot(self) -> NoReturn: - + # getting all allive players in a list. - alive_players_list = self.activity.get_alive_players() - + alive_players_list = self.activity.get_alive_players(); + # make sure that list is not Empty. if len(alive_players_list) > 0: - + # choosing a random player from list. - target_player = choice(alive_players_list) - # highlight the target player - self.highlight_target_player(target_player) - + target_player = choice(alive_players_list); + # highlight the target player + self.highlight_target_player(target_player); + # to finding difference between player and box. # we just need to subtract player pos and ball pos. # Same logic as eric applied in Target Practice Gamemode. - difference = ba.Vec3(target_player.position) - ba.Vec3(self.node.position) - + difference = babase.Vec3(target_player.position) - babase.Vec3(self.node.position); + # discard Y position so ball shoot more straight. difference[1] = 0.0 - + # and now, this length method returns distance in float. # we're gonna use this value for calculating player analog stick - distance = difference.length() - + distance = difference.length(); + # shoot a random BallType - self.upgrade_ball_type(choice(self.ball_type_dist)) - + self.upgrade_ball_type(choice(self.ball_type_dist)); + # and check the ball_type and upgrade it gravity_scale, texture, next ball speed. - self.check_ball_type(self.ball_type) - + self.check_ball_type(self.ball_type); + # For HARD ball i am just focusing on player analog stick facing direction. # Not very accurate and that's we need. if self.ball_type == BallType.HARD: - self.calculate_player_analog_stick(target_player, distance) + self.calculate_player_analog_stick(target_player, distance); else: - self.player_facing_direction = [0.0, 0.0] - - pos = self.node.position - + self.player_facing_direction = [0.0, 0.0]; + + pos = self.node.position; + if self.ball_type == BallType.MEDIUM or self.ball_type == BallType.HARD: # Target head by increasing Y pos. # How this work? cause ball gravity_scale is ...... - pos = (pos[0], pos[1]+.25, pos[2]) - + pos = (pos[0], pos[1]+.25, pos[2]); + # ball is generating.. ball = Ball( - position=pos, - velocity=(0.0, 0.0, 0.0), - texture=self.ball_tex, - gravity_scale=self.ball_gravity, - body_scale=1.0, - ).autoretain() - + position = pos, + velocity = (0.0, 0.0, 0.0), + texture = self.ball_tex, + gravity_scale = self.ball_gravity, + body_scale = 1.0, + ).autoretain(); + # shoot Animation and sound. - self.shoot_animation() - + self.shoot_animation(); + # force the shoot speed if player try to go inside the red circle. if self.force_shoot_speed != 0.0: - self.shoot_speed = self.force_shoot_speed - + self.shoot_speed = self.force_shoot_speed; + # push the ball to the player ball.node.handlemessage( - 'impulse', + 'impulse', self.node.position[0], # ball spawn position X self.node.position[1], # Y self.node.position[2], # Z - 0, 0, 0, # velocity x,y,z - self.ball_mag, # magnetude - 0.000, # magnetude velocity + 0, 0, 0, # velocity x,y,z + self.ball_mag, # magnetude + 0.000, # magnetude velocity 0.000, # radius 0.000, # idk - difference[0] + self.player_facing_direction[0], # force direction X - difference[1], # force direction Y - difference[2] + self.player_facing_direction[1], # force direction Z - ) + difference[0] + self.player_facing_direction[0], # force direction X + difference[1] , # force direction Y + difference[2] + self.player_facing_direction[1], # force direction Z + ); # creating our timer and shoot the ball again.(and we create a loop) - self.shoot_timer = ba.Timer(self.shoot_speed, self.start_shoot) - + self.shoot_timer = bs.Timer(self.shoot_speed, self.start_shoot); + def upgrade_ball_type(self, ball_type: BallType) -> NoReturn: - - self.ball_type = ball_type + + self.ball_type = ball_type; def check_ball_type(self, ball_type: BallType) -> NoReturn: - - if ball_type == BallType.EASY: - self.shoot_speed = 0.8 - self.ball_gravity = 1.0 - # next ball shoot speed - self.ball_mag = 3000 - # box light color and ball tex - self.light.color = (1.0, 1.0, 0.0) - self.ball_tex = ba.gettexture('egg4') - elif ball_type == BallType.MEDIUM: - self.ball_mag = 3000 - # decrease the gravity scale so, ball shoot without falling and straight. - self.ball_gravity = 0.0 - # next ball shoot speed. - self.shoot_speed = 0.4 - # box light color and ball tex. - self.light.color = (1.0, 0.0, 1.0) - self.ball_tex = ba.gettexture('egg3') - elif ball_type == BallType.HARD: - self.ball_mag = 2500 - self.ball_gravity = 0.0 - # next ball shoot speed. - self.shoot_speed = 0.6 - # box light color and ball tex. - self.light.color = (1.0, 0.2, 1.0) - self.ball_tex = ba.gettexture('egg1') - + + if ball_type == BallType.EASY: + self.shoot_speed = 0.8; + self.ball_gravity = 1.0; + # next ball shoot speed + self.ball_mag = 3000; + # box light color and ball tex + self.light.color = (1.0, 1.0, 0.0); + self.ball_tex = bs.gettexture('egg4'); + elif ball_type == BallType.MEDIUM: + self.ball_mag = 3000; + # decrease the gravity scale so, ball shoot without falling and straight. + self.ball_gravity = 0.0; + # next ball shoot speed. + self.shoot_speed = 0.4; + # box light color and ball tex. + self.light.color = (1.0, 0.0, 1.0); + self.ball_tex = bs.gettexture('egg3'); + elif ball_type == BallType.HARD: + self.ball_mag = 2500; + self.ball_gravity = 0.0; + # next ball shoot speed. + self.shoot_speed = 0.6; + # box light color and ball tex. + self.light.color = (1.0, 0.2, 1.0); + self.ball_tex = bs.gettexture('egg1'); + def shoot_animation(self) -> NoReturn: - - ba.animate( + + bs.animate( self.node, - "model_scale", { + "mesh_scale",{ 0.00: 1.4, 0.05: 1.7, 0.10: 1.4, } - ) + ); # playing shoot sound. - ba.playsound(self.shoot_sound, position=self.node.position) - - def highlight_target_player(self, player: ba.Player) -> NoReturn: + # self.shoot_sound, position = self.node.position.play(); + self.shoot_sound.play() + + def highlight_target_player(self, player: bs.Player) -> NoReturn: + # adding light - light = ba.newnode( + light = bs.newnode( "light", - owner=self.node, + owner = self.node, attrs={ - 'radius': 0.0, - 'intensity': 1.0, - 'color': (1.0, 0.0, 0.0), + 'radius':0.0, + 'intensity':1.0, + 'color': (1.0, 0.0, 0.0), } - ) - ba.animate( - light, - "radius", { - 0.05: 0.02, - 0.10: 0.07, - 0.15: 0.15, - 0.20: 0.13, - 0.25: 0.10, - 0.30: 0.05, - 0.35: 0.02, - 0.40: 0.00, - } - ) + ); + bs.animate( + light, + "radius",{ + 0.05: 0.02, + 0.10: 0.07, + 0.15: 0.15, + 0.20: 0.13, + 0.25: 0.10, + 0.30: 0.05, + 0.35: 0.02, + 0.40: 0.00, + } + ); # And a circle outline with ugly animation. - circle_outline = ba.newnode( + circle_outline = bs.newnode( "locator", - owner=player.actor.node, + owner = player.actor.node, attrs={ 'shape': 'circleOutline', 'color': (1.0, 0.0, 0.0), @@ -384,279 +385,277 @@ class Box(ba.Actor): 'draw_beauty': False, 'additive': True, }, - ) - ba.animate_array( + ); + bs.animate_array( circle_outline, - 'size', + 'size', 1, { - 0.05: [0.5], - 0.10: [0.8], - 0.15: [1.5], - 0.20: [2.0], - 0.25: [1.8], - 0.30: [1.3], - 0.35: [0.6], - 0.40: [0.0], - } - ) - + 0.05: [0.5], + 0.10: [0.8], + 0.15: [1.5], + 0.20: [2.0], + 0.25: [1.8], + 0.30: [1.3], + 0.35: [0.6], + 0.40: [0.0], + } + ); + # coonect it and... - player.actor.node.connectattr("position", light, "position") - player.actor.node.connectattr("position", circle_outline, "position") - + player.actor.node.connectattr("position", light, "position"); + player.actor.node.connectattr("position", circle_outline, "position"); + # immediately delete the node after another player has been targeted. - self.shoot_speed = 0.5 if self.shoot_speed == 0.0 else self.shoot_speed - ba.timer(self.shoot_speed, light.delete) - ba.timer(self.shoot_speed, circle_outline.delete) - - def calculate_player_analog_stick(self, player: ba.Player, distance: float) -> NoReturn: + self.shoot_speed = 0.5 if self.shoot_speed == 0.0 else self.shoot_speed; + bs.timer(self.shoot_speed, light.delete); + bs.timer(self.shoot_speed, circle_outline.delete); + + def calculate_player_analog_stick(self, player:bs.Player, distance: float) -> NoReturn: # at first i was very confused how i can read the player analog stick \ # then i saw TheMikirog#1984 autorun plugin code. # and i got it how analog stick values are works. # just need to store analog stick facing direction and need some calculation according how far player pushed analog stick. # Notice that how vertical direction is inverted, so we need to put a minus infront of veriable.(so ball isn't shoot at wrong direction). - self.player_facing_direction[0] = player.actor.node.move_left_right - self.player_facing_direction[1] = -player.actor.node.move_up_down - + self.player_facing_direction[0] = player.actor.node.move_left_right; + self.player_facing_direction[1] = -player.actor.node.move_up_down; + # if player is too close and the player pushing his analog stick fully the ball shoot's too far away to player. # so, we need to reduce the value of "self.player_facing_direction" to fix this problem. if distance <= 3: - self.player_facing_direction[0] = 0.4 if self.player_facing_direction[0] > 0 else -0.4 - self.player_facing_direction[1] = 0.4 if self.player_facing_direction[0] > 0 else -0.4 + self.player_facing_direction[0] = 0.4 if self.player_facing_direction[0] > 0 else -0.4; + self.player_facing_direction[1] = 0.4 if self.player_facing_direction[0] > 0 else -0.4; # same problem to long distance but in reverse, the ball can't reach to the player, # its because player analog stick value is between 1 and -1, # and this value is low to shoot ball forward to Player if player is too far from the box. # so. let's increase to 1.5 if player pushed analog stick fully. elif distance > 6.5: # So many calculation according to how analog stick pushed by player. - # Horizontal(left-right) calculation + # Horizontal(left-right) calculation if self.player_facing_direction[0] > 0.4: - self.player_facing_direction[0] = 1.5 + self.player_facing_direction[0] = 1.5; elif self.player_facing_direction[0] < -0.4: - self.player_facing_direction[0] = -1.5 + self.player_facing_direction[0] = -1.5; else: if self.player_facing_direction[0] > 0.0: - self.player_facing_direction[0] = 0.2 + self.player_facing_direction[0] = 0.2; elif self.player_facing_direction[0] < 0.0: - self.player_facing_direction[0] = -0.2 + self.player_facing_direction[0] = -0.2; else: - self.player_facing_direction[0] = 0.0 - + self.player_facing_direction[0] = 0.0; + # Vertical(up-down) calculation. if self.player_facing_direction[1] > 0.4: - self.player_facing_direction[1] = 1.5 + self.player_facing_direction[1] = 1.5; elif self.player_facing_direction[1] < -0.4: - self.player_facing_direction[1] = -1.5 + self.player_facing_direction[1] = -1.5; else: if self.player_facing_direction[1] > 0.0: - self.player_facing_direction[1] = 0.2 + self.player_facing_direction[1] = 0.2; elif self.player_facing_direction[1] < 0.0: - self.player_facing_direction[1] = -0.2 + self.player_facing_direction[1] = -0.2; else: - self.player_facing_direction[1] = -0.0 - + self.player_facing_direction[1] = -0.0; + # if we want stop the ball shootes def stop_shoot(self) -> NoReturn: - # Kill the timer. - self.shoot_timer = None + # Kill the timer. + self.shoot_timer = None; + - -class Player(ba.Player['Team']): +class Player(bs.Player['Team']): """Our player type for this game.""" -class Team(ba.Team[Player]): +class Team(bs.Team[Player]): """Our team type for this game.""" # almost 80 % for game we done in box class. -# now remain things, like name, seetings, scoring, cooldonw, +# now remain things, like name, seetings, scoring, cooldonw, # and main thing don't allow player to camp inside of box are going in this class. -# ba_meta export game - - -class DodgeTheBall(ba.TeamGameActivity[Player, Team]): - +# ba_meta export bascenev1.GameActivity +class DodgeTheBall(bs.TeamGameActivity[Player, Team]): + # defining name, description and settings.. - name = 'Dodge the ball' - description = 'Survive from shooting balls' - + name = 'Dodge the ball'; + description = 'Survive from shooting balls'; + available_settings = [ - ba.IntSetting( + bs.IntSetting( 'Cooldown', - min_value=20, - default=45, - increment=5, + min_value = 20, + default = 45, + increment = 5, ), - ba.BoolSetting('Epic Mode', default=False) + bs.BoolSetting('Epic Mode', default=False) ] # Don't allow joining after we start. - allow_mid_activity_joins = False - + allow_mid_activity_joins = False; + @classmethod - def supports_session_type(cls, sessiontype: type[ba.Session]) -> bool: + def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool: # We support team and ffa sessions. - return issubclass(sessiontype, ba.FreeForAllSession) or issubclass( - sessiontype, ba.DualTeamSession, - ) - + return issubclass(sessiontype, bs.FreeForAllSession) or issubclass( + sessiontype, bs.DualTeamSession, + ); + @classmethod - def get_supported_maps(cls, sessiontype: type[ba.Session]) -> list[str]: + def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]: # This Game mode need a flat and perfect shape map where can player fall outside map. # bombsquad have "Doom Shroom" map. # Not perfect map for this game mode but its fine for this gamemode. # the problem is that Doom Shroom is not a perfect circle and not flat also. - return ['Doom Shroom'] - + return ['Doom Shroom']; + def __init__(self, settings: dict): - super().__init__(settings) - self._epic_mode = bool(settings['Epic Mode']) - self.countdown_time = int(settings['Cooldown']) - - self.check_player_pos_timer: ba.Timer | None = None - self.shield_drop_timer: ba.Timer | None = None + super().__init__(settings); + self._epic_mode = bool(settings['Epic Mode']); + self.countdown_time = int(settings['Cooldown']); + + self.check_player_pos_timer: bs.Timer | None = None; + self.shield_drop_timer: bs.Timer | None = None; # cooldown and Box - self._countdown: OnScreenCountdown | None = None - self.box: Box | None = None - + self._countdown: OnScreenCountdown | None = None; + self.box: Box | None = None; + # this lists for scoring. - self.joined_player_list: list[ba.Player] = [] - self.dead_player_list: list[ba.Player] = [] - + self.joined_player_list: list[bs.Player] = []; + self.dead_player_list: list[bs.Player] = []; + # normally play RUN AWAY music cause is match with our gamemode at.. my point, # but in epic switch to EPIC. - self.slow_motion = self._epic_mode + self.slow_motion = self._epic_mode; self.default_music = ( - ba.MusicType.EPIC if self._epic_mode else ba.MusicType.RUN_AWAY - ) - + bs.MusicType.EPIC if self._epic_mode else bs.MusicType.RUN_AWAY + ); + def get_instance_description(self) -> str | Sequence: - return 'Keep away as possible as you can' - + return 'Keep away as possible as you can'; + # add a tiny text under our game name. def get_instance_description_short(self) -> str | Sequence: - return 'Dodge the shooting balls' + return 'Dodge the shooting balls'; def on_begin(self) -> NoReturn: - super().on_begin() - + super().on_begin(); + # spawn our box at middle of the map self.box = Box( position=(0.5, 2.7, -3.9), velocity=(0.0, 0.0, 0.0), - ).autoretain() - - # create our cooldown + ).autoretain(); + + # create our cooldown self._countdown = OnScreenCountdown( - duration=self.countdown_time, - endcall=self.play_victory_sound_and_end, - ) - + duration = self.countdown_time, + endcall = self.play_victory_sound_and_end, + ); + # and starts the cooldown and shootes. - ba.timer(5.0, self._countdown.start) - ba.timer(5.0, self.box.start_shoot) - + bs.timer(5.0, self._countdown.start); + bs.timer(5.0, self.box.start_shoot); + # start checking all player pos. - ba.timer(5.0, self.check_player_pos) - + bs.timer(5.0, self.check_player_pos); + # drop shield every ten Seconds # need five seconds delay Because shootes start after 5 seconds. - ba.timer(15.0, self.drop_shield) - + bs.timer(15.0, self.drop_shield); + # This function returns all alive players in game. # i thinck you see this function in Box class. - def get_alive_players(self) -> Sequence[ba.Player]: - - alive_players = [] - + def get_alive_players(self) -> Sequence[bs.Player]: + + alive_players = []; + for team in self.teams: for player in team.players: if player.is_alive(): - alive_players.append(player) - - return alive_players - + alive_players.append(player); + + return alive_players; + # let's disallowed camping inside of box by doing a blast and increasing ball shoot speed. def check_player_pos(self): - + for player in self.get_alive_players(): - - # same logic as applied for the ball - difference = ba.Vec3(player.position) - ba.Vec3(self.box.node.position) - - distance = difference.length() - - if distance < 3: - self.box.force_shoot_speed = 0.2 - else: - self.box.force_shoot_speed = 0.0 - - if distance < 0.5: - Blast( - position=self.box.node.position, - velocity=self.box.node.velocity, - blast_type='normal', - blast_radius=1.0, - ).autoretain() - - PopupText( - position=self.box.node.position, - text='Keep away from me', - random_offset=0.0, - scale=2.0, - color=self.box.light.color, - ).autoretain() - + + # same logic as applied for the ball + difference = babase.Vec3(player.position) - babase.Vec3(self.box.node.position); + + distance = difference.length(); + + if distance < 3: + self.box.force_shoot_speed = 0.2; + else: + self.box.force_shoot_speed = 0.0; + + if distance < 0.5: + Blast( + position = self.box.node.position, + velocity = self.box.node.velocity, + blast_type = 'normal', + blast_radius = 1.0, + ).autoretain(); + + PopupText( + position = self.box.node.position, + text = 'Keep away from me', + random_offset = 0.0, + scale = 2.0, + color = self.box.light.color, + ).autoretain(); + # create our timer and start looping it - self.check_player_pos_timer = ba.Timer(0.1, self.check_player_pos) - + self.check_player_pos_timer = bs.Timer(0.1, self.check_player_pos); + # drop useless shield's too give player temptation. def drop_shield(self) -> NoReturn: - - pos = self.box.node.position - - PowerupBox( - position=(pos[0] + 4.0, pos[1] + 3.0, pos[2]), - poweruptype='shield', - ).autoretain() - - PowerupBox( - position=(pos[0] - 4.0, pos[1] + 3.0, pos[2]), - poweruptype='shield', - ).autoretain() - - self.shield_drop_timer = ba.Timer(10.0, self.drop_shield) - + + pos = self.box.node.position; + + PowerupBox( + position = (pos[0] + 4.0, pos[1] + 3.0, pos[2]), + poweruptype = 'shield', + ).autoretain(); + + PowerupBox( + position = (pos[0] - 4.0, pos[1] + 3.0, pos[2]), + poweruptype = 'shield', + ).autoretain(); + + self.shield_drop_timer = bs.Timer(10.0, self.drop_shield); + # when cooldown time up i don't want that the game end immediately. def play_victory_sound_and_end(self) -> NoReturn: - + # kill timers - self.box.stop_shoot() + self.box.stop_shoot(); self.check_player_pos_timer = None self.shield_drop_timer = None - ba.timer(2.0, self.end_game) - + bs.timer(2.0, self.end_game); + # this function runs when A player spawn in map def spawn_player(self, player: Player) -> NoReturn: - spaz = self.spawn_player_spaz(player) + spaz = self.spawn_player_spaz(player); # reconnect this player's controls. # without bomb, punch and pickup. spaz.connect_controls_to_player( enable_punch=False, enable_bomb=False, enable_pickup=False, - ) - + ); + # storing all players for ScorinG. - self.joined_player_list.append(player) - + self.joined_player_list.append(player); + # Also lets have them make some noise when they die. - spaz.play_big_death_sound = True - + spaz.play_big_death_sound = True; + # very helpful function to check end game when player dead or leav. def _check_end_game(self) -> bool: - + living_team_count = 0 for team in self.teams: for player in team.players: @@ -674,51 +673,51 @@ class DodgeTheBall(ba.TeamGameActivity[Player, Team]): # this function called when player leave. def on_player_leave(self, player: Player) -> NoReturn: # Augment default behavior. - super().on_player_leave(player) + super().on_player_leave(player); # checking end game. - self._check_end_game() + self._check_end_game(); # this gamemode needs to handle only one msg "PlayerDiedMessage". def handlemessage(self, msg: Any) -> Any: - - if isinstance(msg, ba.PlayerDiedMessage): + + if isinstance(msg, bs.PlayerDiedMessage): # Augment standard behavior. - super().handlemessage(msg) - + super().handlemessage(msg); + # and storing the dead player records in our dead_player_list. - self.dead_player_list.append(msg.getplayer(Player)) - + self.dead_player_list.append(msg.getplayer(Player)); + # check the end game. - ba.timer(1.0, self._check_end_game) - + bs.timer(1.0, self._check_end_game); + def end_game(self): # kill timers self.box.stop_shoot() self.check_player_pos_timer = None self.shield_drop_timer = None - + # here the player_dead_list and joined_player_list gonna be very helpful. for team in self.teams: for player in team.players: - + # for scoring i am just following the index of the player_dead_list. # for dead list... # 0th index player dead first. # 1st index player dead second. # and so on... - # i think you got it... maybe + # i think you got it... maybe # sometime we also got a empty list # if we got a empty list that means all players are survived or maybe only one player playing and he/she survived. if len(self.dead_player_list) > 0: - + for index, dead_player in enumerate(self.dead_player_list): # if this condition is true we find the dead player \ # and his index with enumerate function. if player == dead_player: # updating with one, because i don't want to give 0 score to first dead player. - index += 1 + index += 1 break # and if this statement is true we just find a survived player. # for survived player i am giving the highest score according to how many players are joined. @@ -727,39 +726,41 @@ class DodgeTheBall(ba.TeamGameActivity[Player, Team]): # for survived player i am giving the highest score according to how many players are joined. else: index = len(self.joined_player_list) - + # and here i am following Table of 10 for scoring. # very lazY. score = int(10 * index) - + self.stats.player_scored(player, score, screenmessage=False) # Ok now calc game results: set a score for each team and then tell \ # the game to end. - results = ba.GameResults() + results = bs.GameResults() # Remember that 'free-for-all' mode is simply a special form \ # of 'teams' mode where each player gets their own team, so we can \ # just always deal in teams and have all cases covered. # hmmm... some eric comments might be helpful to you. for team in self.teams: - + max_index = 0 for player in team.players: - # for the team, we choose only one player who survived longest. - # same logic.. - if len(self.dead_player_list) > 0: + # for the team, we choose only one player who survived longest. + # same logic.. + if len(self.dead_player_list) > 0: for index, dead_player in enumerate(self.dead_player_list): if player == dead_player: index += 1 break elif index == len(self.dead_player_list) - 1: index = len(self.joined_player_list) - else: + else: index = len(self.joined_player_list) - - max_index = max(max_index, index) + + max_index = max(max_index, index) # set the team score - results.set_team_score(team, int(10 * max_index)) + results.set_team_score(team, int(10 * max_index)) # and end the game self.end(results=results) + + \ No newline at end of file From 4fb675cff672b0a3cfc3884b4897e7b479c286d8 Mon Sep 17 00:00:00 2001 From: SenjuZoro Date: Sun, 23 Jul 2023 12:05:54 +0000 Subject: [PATCH 06/60] [ci] auto-format --- plugins/minigames/dodge_the_ball.py | 706 ++++++++++++++-------------- 1 file changed, 354 insertions(+), 352 deletions(-) diff --git a/plugins/minigames/dodge_the_ball.py b/plugins/minigames/dodge_the_ball.py index 7d1648d..2bb1d92 100644 --- a/plugins/minigames/dodge_the_ball.py +++ b/plugins/minigames/dodge_the_ball.py @@ -13,7 +13,7 @@ from typing import TYPE_CHECKING import babase import bauiv1 as bui import bascenev1 as bs -from random import choice +from random import choice from enum import Enum from bascenev1lib.actor.bomb import Blast from bascenev1lib.actor.popuptext import PopupText @@ -41,28 +41,31 @@ class BallType(Enum): # increase the next ball speed but less than MEDIUM. # Ball color is crimson(purple+red = pinky color type). -# this dict decide the ball_type spawning rate like powerup box + +# this dict decide the ball_type spawning rate like powerup box ball_type_dict: dict[BallType, int] = { BallType.EASY: 3, BallType.MEDIUM: 2, BallType.HARD: 1, -}; +} + class Ball(bs.Actor): """ Shooting Ball """ - def __init__(self, - position: Sequence[float], - velocity: Sequence[float], - texture: babase.Texture, - body_scale: float = 1.0, - gravity_scale: float = 1.0, - ) -> NoReturn: - - super().__init__(); - - shared = SharedObjects.get(); - - ball_material = bs.Material(); + + def __init__(self, + position: Sequence[float], + velocity: Sequence[float], + texture: babase.Texture, + body_scale: float = 1.0, + gravity_scale: float = 1.0, + ) -> NoReturn: + + super().__init__() + + shared = SharedObjects.get() + + ball_material = bs.Material() ball_material.add_actions( conditions=( ( @@ -74,8 +77,8 @@ class Ball(bs.Actor): ('they_have_material', shared.object_material), ), actions=('modify_node_collision', 'collide', False), - ); - + ) + self.node = bs.newnode( 'prop', delegate=self, @@ -88,37 +91,37 @@ class Ball(bs.Actor): 'mesh_scale': body_scale, 'color_texture': texture, 'gravity_scale': gravity_scale, - 'density': 4.0, # increase density of ball so ball collide with player with heavy force. # ammm very bad grammer + 'density': 4.0, # increase density of ball so ball collide with player with heavy force. # ammm very bad grammer 'materials': (ball_material,), - }, - ); - + }, + ) + # die the ball manually incase the ball doesn't fall the outside of the map - bs.timer(2.5, bs.WeakCall(self.handlemessage, bs.DieMessage())); - + bs.timer(2.5, bs.WeakCall(self.handlemessage, bs.DieMessage())) + # i am not handling anything in this ball Class(except for diemessage). # all game things and logics going to be in the box class def handlemessage(self, msg: Any) -> Any: - + if isinstance(msg, bs.DieMessage): - self.node.delete(); + self.node.delete() else: - super().handlemessage(msg); - - + super().handlemessage(msg) + + class Box(bs.Actor): """ A box that spawn midle of map as a decoration perpose """ - - def __init__(self, - position: Sequence[float], - velocity: Sequence[float], - ) -> NoReturn: - - super().__init__(); - shared = SharedObjects.get(); + def __init__(self, + position: Sequence[float], + velocity: Sequence[float], + ) -> NoReturn: + + super().__init__() + + shared = SharedObjects.get() # self.ball_jump = 0.0; - no_hit_material = bs.Material(); + no_hit_material = bs.Material() # we don't need that the box was move and collide with objects. no_hit_material.add_actions( conditions=( @@ -127,7 +130,7 @@ class Box(bs.Actor): ('they_have_material', shared.attack_material), ), actions=('modify_part_collision', 'collide', False), - ); + ) no_hit_material.add_actions( conditions=( @@ -139,8 +142,8 @@ class Box(bs.Actor): ('modify_part_collision', 'collide', False), ('modify_part_collision', 'physical', False), ), - ); - + ) + self.node = bs.newnode( 'prop', delegate=self, @@ -156,26 +159,26 @@ class Box(bs.Actor): 'reflection': 'powerup', 'reflection_scale': [1.0], 'materials': (no_hit_material,), - }, - ); + }, + ) # light self.light = bs.newnode( "light", - owner = self.node, + owner=self.node, attrs={ - 'radius' : 0.2, - 'intensity' : 0.8, - 'color': (0.0, 1.0, 0.0), + 'radius': 0.2, + 'intensity': 0.8, + 'color': (0.0, 1.0, 0.0), } - ); - self.node.connectattr("position", self.light, "position"); - # Drawing circle and circleOutline in radius of 3, - # so player can see that how close he is to the box. - # If player is inside this circle the ball speed will increase. + ) + self.node.connectattr("position", self.light, "position") + # Drawing circle and circleOutline in radius of 3, + # so player can see that how close he is to the box. + # If player is inside this circle the ball speed will increase. circle = bs.newnode( "locator", - owner = self.node, - attrs = { + owner=self.node, + attrs={ 'shape': 'circle', 'color': (1.0, 0.0, 0.0), 'opacity': 0.1, @@ -184,12 +187,12 @@ class Box(bs.Actor): 'additive': True, }, ) - self.node.connectattr("position", circle, "position"); + self.node.connectattr("position", circle, "position") # also adding a outline cause its look nice. circle_outline = bs.newnode( "locator", - owner = self.node, - attrs = { + owner=self.node, + attrs={ 'shape': 'circleOutline', 'color': (1.0, 1.0, 0.0), 'opacity': 0.1, @@ -197,187 +200,186 @@ class Box(bs.Actor): 'draw_beauty': False, 'additive': True, }, - ); - self.node.connectattr("position", circle_outline, "position"); - + ) + self.node.connectattr("position", circle_outline, "position") + # all ball attribute that we need. - self.ball_type: BallType = BallType.EASY; - self.shoot_timer: bs.Timer | None = None; - self.shoot_speed: float = 0.0; + self.ball_type: BallType = BallType.EASY + self.shoot_timer: bs.Timer | None = None + self.shoot_speed: float = 0.0 # this force the shoot if player is inside the red circle. - self.force_shoot_speed: float = 0.0; - self.ball_mag = 3000; - self.ball_gravity: float = 1.0; - self.ball_tex: babase.Texture | None = None; - # only for Hard ball_type - self.player_facing_direction: list[float, float] = [0.0, 0.0]; + self.force_shoot_speed: float = 0.0 + self.ball_mag = 3000 + self.ball_gravity: float = 1.0 + self.ball_tex: babase.Texture | None = None + # only for Hard ball_type + self.player_facing_direction: list[float, float] = [0.0, 0.0] # ball shoot soound. - self.shoot_sound = bs.getsound('laserReverse'); - - # same as "powerupdist" - self.ball_type_dist: list[BallType] = []; + self.shoot_sound = bs.getsound('laserReverse') + + # same as "powerupdist" + self.ball_type_dist: list[BallType] = [] for ball in ball_type_dict: for _ in range(ball_type_dict[ball]): - self.ball_type_dist.append(ball); - + self.ball_type_dist.append(ball) + # Here main logic of game goes here. # like shoot balls, shoot speed, anything we want goes here(except for some thing). def start_shoot(self) -> NoReturn: - + # getting all allive players in a list. - alive_players_list = self.activity.get_alive_players(); - + alive_players_list = self.activity.get_alive_players() + # make sure that list is not Empty. if len(alive_players_list) > 0: - + # choosing a random player from list. - target_player = choice(alive_players_list); - # highlight the target player - self.highlight_target_player(target_player); - + target_player = choice(alive_players_list) + # highlight the target player + self.highlight_target_player(target_player) + # to finding difference between player and box. # we just need to subtract player pos and ball pos. # Same logic as eric applied in Target Practice Gamemode. - difference = babase.Vec3(target_player.position) - babase.Vec3(self.node.position); - + difference = babase.Vec3(target_player.position) - babase.Vec3(self.node.position) + # discard Y position so ball shoot more straight. difference[1] = 0.0 - + # and now, this length method returns distance in float. # we're gonna use this value for calculating player analog stick - distance = difference.length(); - + distance = difference.length() + # shoot a random BallType - self.upgrade_ball_type(choice(self.ball_type_dist)); - + self.upgrade_ball_type(choice(self.ball_type_dist)) + # and check the ball_type and upgrade it gravity_scale, texture, next ball speed. - self.check_ball_type(self.ball_type); - + self.check_ball_type(self.ball_type) + # For HARD ball i am just focusing on player analog stick facing direction. # Not very accurate and that's we need. if self.ball_type == BallType.HARD: - self.calculate_player_analog_stick(target_player, distance); + self.calculate_player_analog_stick(target_player, distance) else: - self.player_facing_direction = [0.0, 0.0]; - - pos = self.node.position; - + self.player_facing_direction = [0.0, 0.0] + + pos = self.node.position + if self.ball_type == BallType.MEDIUM or self.ball_type == BallType.HARD: # Target head by increasing Y pos. # How this work? cause ball gravity_scale is ...... - pos = (pos[0], pos[1]+.25, pos[2]); - + pos = (pos[0], pos[1]+.25, pos[2]) + # ball is generating.. ball = Ball( - position = pos, - velocity = (0.0, 0.0, 0.0), - texture = self.ball_tex, - gravity_scale = self.ball_gravity, - body_scale = 1.0, - ).autoretain(); - + position=pos, + velocity=(0.0, 0.0, 0.0), + texture=self.ball_tex, + gravity_scale=self.ball_gravity, + body_scale=1.0, + ).autoretain() + # shoot Animation and sound. - self.shoot_animation(); - + self.shoot_animation() + # force the shoot speed if player try to go inside the red circle. if self.force_shoot_speed != 0.0: - self.shoot_speed = self.force_shoot_speed; - + self.shoot_speed = self.force_shoot_speed + # push the ball to the player ball.node.handlemessage( - 'impulse', + 'impulse', self.node.position[0], # ball spawn position X self.node.position[1], # Y self.node.position[2], # Z - 0, 0, 0, # velocity x,y,z - self.ball_mag, # magnetude - 0.000, # magnetude velocity + 0, 0, 0, # velocity x,y,z + self.ball_mag, # magnetude + 0.000, # magnetude velocity 0.000, # radius 0.000, # idk - difference[0] + self.player_facing_direction[0], # force direction X - difference[1] , # force direction Y - difference[2] + self.player_facing_direction[1], # force direction Z - ); + difference[0] + self.player_facing_direction[0], # force direction X + difference[1], # force direction Y + difference[2] + self.player_facing_direction[1], # force direction Z + ) # creating our timer and shoot the ball again.(and we create a loop) - self.shoot_timer = bs.Timer(self.shoot_speed, self.start_shoot); - + self.shoot_timer = bs.Timer(self.shoot_speed, self.start_shoot) + def upgrade_ball_type(self, ball_type: BallType) -> NoReturn: - - self.ball_type = ball_type; + + self.ball_type = ball_type def check_ball_type(self, ball_type: BallType) -> NoReturn: - - if ball_type == BallType.EASY: - self.shoot_speed = 0.8; - self.ball_gravity = 1.0; - # next ball shoot speed - self.ball_mag = 3000; - # box light color and ball tex - self.light.color = (1.0, 1.0, 0.0); - self.ball_tex = bs.gettexture('egg4'); - elif ball_type == BallType.MEDIUM: - self.ball_mag = 3000; - # decrease the gravity scale so, ball shoot without falling and straight. - self.ball_gravity = 0.0; - # next ball shoot speed. - self.shoot_speed = 0.4; - # box light color and ball tex. - self.light.color = (1.0, 0.0, 1.0); - self.ball_tex = bs.gettexture('egg3'); - elif ball_type == BallType.HARD: - self.ball_mag = 2500; - self.ball_gravity = 0.0; - # next ball shoot speed. - self.shoot_speed = 0.6; - # box light color and ball tex. - self.light.color = (1.0, 0.2, 1.0); - self.ball_tex = bs.gettexture('egg1'); - + + if ball_type == BallType.EASY: + self.shoot_speed = 0.8 + self.ball_gravity = 1.0 + # next ball shoot speed + self.ball_mag = 3000 + # box light color and ball tex + self.light.color = (1.0, 1.0, 0.0) + self.ball_tex = bs.gettexture('egg4') + elif ball_type == BallType.MEDIUM: + self.ball_mag = 3000 + # decrease the gravity scale so, ball shoot without falling and straight. + self.ball_gravity = 0.0 + # next ball shoot speed. + self.shoot_speed = 0.4 + # box light color and ball tex. + self.light.color = (1.0, 0.0, 1.0) + self.ball_tex = bs.gettexture('egg3') + elif ball_type == BallType.HARD: + self.ball_mag = 2500 + self.ball_gravity = 0.0 + # next ball shoot speed. + self.shoot_speed = 0.6 + # box light color and ball tex. + self.light.color = (1.0, 0.2, 1.0) + self.ball_tex = bs.gettexture('egg1') + def shoot_animation(self) -> NoReturn: - + bs.animate( self.node, - "mesh_scale",{ + "mesh_scale", { 0.00: 1.4, 0.05: 1.7, 0.10: 1.4, } - ); + ) # playing shoot sound. # self.shoot_sound, position = self.node.position.play(); self.shoot_sound.play() - def highlight_target_player(self, player: bs.Player) -> NoReturn: - + # adding light light = bs.newnode( "light", - owner = self.node, + owner=self.node, attrs={ - 'radius':0.0, - 'intensity':1.0, - 'color': (1.0, 0.0, 0.0), + 'radius': 0.0, + 'intensity': 1.0, + 'color': (1.0, 0.0, 0.0), } - ); + ) bs.animate( - light, - "radius",{ - 0.05: 0.02, - 0.10: 0.07, - 0.15: 0.15, - 0.20: 0.13, - 0.25: 0.10, - 0.30: 0.05, - 0.35: 0.02, - 0.40: 0.00, - } - ); + light, + "radius", { + 0.05: 0.02, + 0.10: 0.07, + 0.15: 0.15, + 0.20: 0.13, + 0.25: 0.10, + 0.30: 0.05, + 0.35: 0.02, + 0.40: 0.00, + } + ) # And a circle outline with ugly animation. circle_outline = bs.newnode( "locator", - owner = player.actor.node, + owner=player.actor.node, attrs={ 'shape': 'circleOutline', 'color': (1.0, 0.0, 0.0), @@ -385,82 +387,82 @@ class Box(bs.Actor): 'draw_beauty': False, 'additive': True, }, - ); + ) bs.animate_array( circle_outline, - 'size', + 'size', 1, { - 0.05: [0.5], - 0.10: [0.8], - 0.15: [1.5], - 0.20: [2.0], - 0.25: [1.8], - 0.30: [1.3], - 0.35: [0.6], - 0.40: [0.0], - } - ); - + 0.05: [0.5], + 0.10: [0.8], + 0.15: [1.5], + 0.20: [2.0], + 0.25: [1.8], + 0.30: [1.3], + 0.35: [0.6], + 0.40: [0.0], + } + ) + # coonect it and... - player.actor.node.connectattr("position", light, "position"); - player.actor.node.connectattr("position", circle_outline, "position"); - + player.actor.node.connectattr("position", light, "position") + player.actor.node.connectattr("position", circle_outline, "position") + # immediately delete the node after another player has been targeted. - self.shoot_speed = 0.5 if self.shoot_speed == 0.0 else self.shoot_speed; - bs.timer(self.shoot_speed, light.delete); - bs.timer(self.shoot_speed, circle_outline.delete); - - def calculate_player_analog_stick(self, player:bs.Player, distance: float) -> NoReturn: + self.shoot_speed = 0.5 if self.shoot_speed == 0.0 else self.shoot_speed + bs.timer(self.shoot_speed, light.delete) + bs.timer(self.shoot_speed, circle_outline.delete) + + def calculate_player_analog_stick(self, player: bs.Player, distance: float) -> NoReturn: # at first i was very confused how i can read the player analog stick \ # then i saw TheMikirog#1984 autorun plugin code. # and i got it how analog stick values are works. # just need to store analog stick facing direction and need some calculation according how far player pushed analog stick. # Notice that how vertical direction is inverted, so we need to put a minus infront of veriable.(so ball isn't shoot at wrong direction). - self.player_facing_direction[0] = player.actor.node.move_left_right; - self.player_facing_direction[1] = -player.actor.node.move_up_down; - + self.player_facing_direction[0] = player.actor.node.move_left_right + self.player_facing_direction[1] = -player.actor.node.move_up_down + # if player is too close and the player pushing his analog stick fully the ball shoot's too far away to player. # so, we need to reduce the value of "self.player_facing_direction" to fix this problem. if distance <= 3: - self.player_facing_direction[0] = 0.4 if self.player_facing_direction[0] > 0 else -0.4; - self.player_facing_direction[1] = 0.4 if self.player_facing_direction[0] > 0 else -0.4; + self.player_facing_direction[0] = 0.4 if self.player_facing_direction[0] > 0 else -0.4 + self.player_facing_direction[1] = 0.4 if self.player_facing_direction[0] > 0 else -0.4 # same problem to long distance but in reverse, the ball can't reach to the player, # its because player analog stick value is between 1 and -1, # and this value is low to shoot ball forward to Player if player is too far from the box. # so. let's increase to 1.5 if player pushed analog stick fully. elif distance > 6.5: # So many calculation according to how analog stick pushed by player. - # Horizontal(left-right) calculation + # Horizontal(left-right) calculation if self.player_facing_direction[0] > 0.4: - self.player_facing_direction[0] = 1.5; + self.player_facing_direction[0] = 1.5 elif self.player_facing_direction[0] < -0.4: - self.player_facing_direction[0] = -1.5; + self.player_facing_direction[0] = -1.5 else: if self.player_facing_direction[0] > 0.0: - self.player_facing_direction[0] = 0.2; + self.player_facing_direction[0] = 0.2 elif self.player_facing_direction[0] < 0.0: - self.player_facing_direction[0] = -0.2; + self.player_facing_direction[0] = -0.2 else: - self.player_facing_direction[0] = 0.0; - + self.player_facing_direction[0] = 0.0 + # Vertical(up-down) calculation. if self.player_facing_direction[1] > 0.4: - self.player_facing_direction[1] = 1.5; + self.player_facing_direction[1] = 1.5 elif self.player_facing_direction[1] < -0.4: - self.player_facing_direction[1] = -1.5; + self.player_facing_direction[1] = -1.5 else: if self.player_facing_direction[1] > 0.0: - self.player_facing_direction[1] = 0.2; + self.player_facing_direction[1] = 0.2 elif self.player_facing_direction[1] < 0.0: - self.player_facing_direction[1] = -0.2; + self.player_facing_direction[1] = -0.2 else: - self.player_facing_direction[1] = -0.0; - + self.player_facing_direction[1] = -0.0 + # if we want stop the ball shootes def stop_shoot(self) -> NoReturn: - # Kill the timer. - self.shoot_timer = None; - + # Kill the timer. + self.shoot_timer = None + class Player(bs.Player['Team']): """Our player type for this game.""" @@ -470,192 +472,194 @@ class Team(bs.Team[Player]): """Our team type for this game.""" # almost 80 % for game we done in box class. -# now remain things, like name, seetings, scoring, cooldonw, +# now remain things, like name, seetings, scoring, cooldonw, # and main thing don't allow player to camp inside of box are going in this class. # ba_meta export bascenev1.GameActivity + + class DodgeTheBall(bs.TeamGameActivity[Player, Team]): - + # defining name, description and settings.. - name = 'Dodge the ball'; - description = 'Survive from shooting balls'; - + name = 'Dodge the ball' + description = 'Survive from shooting balls' + available_settings = [ bs.IntSetting( 'Cooldown', - min_value = 20, - default = 45, - increment = 5, + min_value=20, + default=45, + increment=5, ), bs.BoolSetting('Epic Mode', default=False) ] # Don't allow joining after we start. - allow_mid_activity_joins = False; - + allow_mid_activity_joins = False + @classmethod def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool: # We support team and ffa sessions. return issubclass(sessiontype, bs.FreeForAllSession) or issubclass( sessiontype, bs.DualTeamSession, - ); - + ) + @classmethod def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]: # This Game mode need a flat and perfect shape map where can player fall outside map. # bombsquad have "Doom Shroom" map. # Not perfect map for this game mode but its fine for this gamemode. # the problem is that Doom Shroom is not a perfect circle and not flat also. - return ['Doom Shroom']; - + return ['Doom Shroom'] + def __init__(self, settings: dict): - super().__init__(settings); - self._epic_mode = bool(settings['Epic Mode']); - self.countdown_time = int(settings['Cooldown']); - - self.check_player_pos_timer: bs.Timer | None = None; - self.shield_drop_timer: bs.Timer | None = None; + super().__init__(settings) + self._epic_mode = bool(settings['Epic Mode']) + self.countdown_time = int(settings['Cooldown']) + + self.check_player_pos_timer: bs.Timer | None = None + self.shield_drop_timer: bs.Timer | None = None # cooldown and Box - self._countdown: OnScreenCountdown | None = None; - self.box: Box | None = None; - + self._countdown: OnScreenCountdown | None = None + self.box: Box | None = None + # this lists for scoring. - self.joined_player_list: list[bs.Player] = []; - self.dead_player_list: list[bs.Player] = []; - + self.joined_player_list: list[bs.Player] = [] + self.dead_player_list: list[bs.Player] = [] + # normally play RUN AWAY music cause is match with our gamemode at.. my point, # but in epic switch to EPIC. - self.slow_motion = self._epic_mode; + self.slow_motion = self._epic_mode self.default_music = ( bs.MusicType.EPIC if self._epic_mode else bs.MusicType.RUN_AWAY - ); - + ) + def get_instance_description(self) -> str | Sequence: - return 'Keep away as possible as you can'; - + return 'Keep away as possible as you can' + # add a tiny text under our game name. def get_instance_description_short(self) -> str | Sequence: - return 'Dodge the shooting balls'; + return 'Dodge the shooting balls' def on_begin(self) -> NoReturn: - super().on_begin(); - + super().on_begin() + # spawn our box at middle of the map self.box = Box( position=(0.5, 2.7, -3.9), velocity=(0.0, 0.0, 0.0), - ).autoretain(); - - # create our cooldown + ).autoretain() + + # create our cooldown self._countdown = OnScreenCountdown( - duration = self.countdown_time, - endcall = self.play_victory_sound_and_end, - ); - + duration=self.countdown_time, + endcall=self.play_victory_sound_and_end, + ) + # and starts the cooldown and shootes. - bs.timer(5.0, self._countdown.start); - bs.timer(5.0, self.box.start_shoot); - + bs.timer(5.0, self._countdown.start) + bs.timer(5.0, self.box.start_shoot) + # start checking all player pos. - bs.timer(5.0, self.check_player_pos); - + bs.timer(5.0, self.check_player_pos) + # drop shield every ten Seconds # need five seconds delay Because shootes start after 5 seconds. - bs.timer(15.0, self.drop_shield); - + bs.timer(15.0, self.drop_shield) + # This function returns all alive players in game. # i thinck you see this function in Box class. def get_alive_players(self) -> Sequence[bs.Player]: - - alive_players = []; - + + alive_players = [] + for team in self.teams: for player in team.players: if player.is_alive(): - alive_players.append(player); - - return alive_players; - + alive_players.append(player) + + return alive_players + # let's disallowed camping inside of box by doing a blast and increasing ball shoot speed. def check_player_pos(self): - + for player in self.get_alive_players(): - - # same logic as applied for the ball - difference = babase.Vec3(player.position) - babase.Vec3(self.box.node.position); - - distance = difference.length(); - - if distance < 3: - self.box.force_shoot_speed = 0.2; - else: - self.box.force_shoot_speed = 0.0; - - if distance < 0.5: - Blast( - position = self.box.node.position, - velocity = self.box.node.velocity, - blast_type = 'normal', - blast_radius = 1.0, - ).autoretain(); - - PopupText( - position = self.box.node.position, - text = 'Keep away from me', - random_offset = 0.0, - scale = 2.0, - color = self.box.light.color, - ).autoretain(); - + + # same logic as applied for the ball + difference = babase.Vec3(player.position) - babase.Vec3(self.box.node.position) + + distance = difference.length() + + if distance < 3: + self.box.force_shoot_speed = 0.2 + else: + self.box.force_shoot_speed = 0.0 + + if distance < 0.5: + Blast( + position=self.box.node.position, + velocity=self.box.node.velocity, + blast_type='normal', + blast_radius=1.0, + ).autoretain() + + PopupText( + position=self.box.node.position, + text='Keep away from me', + random_offset=0.0, + scale=2.0, + color=self.box.light.color, + ).autoretain() + # create our timer and start looping it - self.check_player_pos_timer = bs.Timer(0.1, self.check_player_pos); - + self.check_player_pos_timer = bs.Timer(0.1, self.check_player_pos) + # drop useless shield's too give player temptation. def drop_shield(self) -> NoReturn: - - pos = self.box.node.position; - - PowerupBox( - position = (pos[0] + 4.0, pos[1] + 3.0, pos[2]), - poweruptype = 'shield', - ).autoretain(); - - PowerupBox( - position = (pos[0] - 4.0, pos[1] + 3.0, pos[2]), - poweruptype = 'shield', - ).autoretain(); - - self.shield_drop_timer = bs.Timer(10.0, self.drop_shield); - + + pos = self.box.node.position + + PowerupBox( + position=(pos[0] + 4.0, pos[1] + 3.0, pos[2]), + poweruptype='shield', + ).autoretain() + + PowerupBox( + position=(pos[0] - 4.0, pos[1] + 3.0, pos[2]), + poweruptype='shield', + ).autoretain() + + self.shield_drop_timer = bs.Timer(10.0, self.drop_shield) + # when cooldown time up i don't want that the game end immediately. def play_victory_sound_and_end(self) -> NoReturn: - + # kill timers - self.box.stop_shoot(); + self.box.stop_shoot() self.check_player_pos_timer = None self.shield_drop_timer = None - bs.timer(2.0, self.end_game); - + bs.timer(2.0, self.end_game) + # this function runs when A player spawn in map def spawn_player(self, player: Player) -> NoReturn: - spaz = self.spawn_player_spaz(player); + spaz = self.spawn_player_spaz(player) # reconnect this player's controls. # without bomb, punch and pickup. spaz.connect_controls_to_player( enable_punch=False, enable_bomb=False, enable_pickup=False, - ); - + ) + # storing all players for ScorinG. - self.joined_player_list.append(player); - + self.joined_player_list.append(player) + # Also lets have them make some noise when they die. - spaz.play_big_death_sound = True; - + spaz.play_big_death_sound = True + # very helpful function to check end game when player dead or leav. def _check_end_game(self) -> bool: - + living_team_count = 0 for team in self.teams: for player in team.players: @@ -673,51 +677,51 @@ class DodgeTheBall(bs.TeamGameActivity[Player, Team]): # this function called when player leave. def on_player_leave(self, player: Player) -> NoReturn: # Augment default behavior. - super().on_player_leave(player); + super().on_player_leave(player) # checking end game. - self._check_end_game(); + self._check_end_game() # this gamemode needs to handle only one msg "PlayerDiedMessage". def handlemessage(self, msg: Any) -> Any: - + if isinstance(msg, bs.PlayerDiedMessage): # Augment standard behavior. - super().handlemessage(msg); - + super().handlemessage(msg) + # and storing the dead player records in our dead_player_list. - self.dead_player_list.append(msg.getplayer(Player)); - + self.dead_player_list.append(msg.getplayer(Player)) + # check the end game. - bs.timer(1.0, self._check_end_game); - + bs.timer(1.0, self._check_end_game) + def end_game(self): # kill timers self.box.stop_shoot() self.check_player_pos_timer = None self.shield_drop_timer = None - + # here the player_dead_list and joined_player_list gonna be very helpful. for team in self.teams: for player in team.players: - + # for scoring i am just following the index of the player_dead_list. # for dead list... # 0th index player dead first. # 1st index player dead second. # and so on... - # i think you got it... maybe + # i think you got it... maybe # sometime we also got a empty list # if we got a empty list that means all players are survived or maybe only one player playing and he/she survived. if len(self.dead_player_list) > 0: - + for index, dead_player in enumerate(self.dead_player_list): # if this condition is true we find the dead player \ # and his index with enumerate function. if player == dead_player: # updating with one, because i don't want to give 0 score to first dead player. - index += 1 + index += 1 break # and if this statement is true we just find a survived player. # for survived player i am giving the highest score according to how many players are joined. @@ -726,11 +730,11 @@ class DodgeTheBall(bs.TeamGameActivity[Player, Team]): # for survived player i am giving the highest score according to how many players are joined. else: index = len(self.joined_player_list) - + # and here i am following Table of 10 for scoring. # very lazY. score = int(10 * index) - + self.stats.player_scored(player, score, screenmessage=False) # Ok now calc game results: set a score for each team and then tell \ @@ -742,25 +746,23 @@ class DodgeTheBall(bs.TeamGameActivity[Player, Team]): # just always deal in teams and have all cases covered. # hmmm... some eric comments might be helpful to you. for team in self.teams: - + max_index = 0 for player in team.players: - # for the team, we choose only one player who survived longest. - # same logic.. - if len(self.dead_player_list) > 0: + # for the team, we choose only one player who survived longest. + # same logic.. + if len(self.dead_player_list) > 0: for index, dead_player in enumerate(self.dead_player_list): if player == dead_player: index += 1 break elif index == len(self.dead_player_list) - 1: index = len(self.joined_player_list) - else: + else: index = len(self.joined_player_list) - - max_index = max(max_index, index) + + max_index = max(max_index, index) # set the team score - results.set_team_score(team, int(10 * max_index)) + results.set_team_score(team, int(10 * max_index)) # and end the game self.end(results=results) - - \ No newline at end of file From 8209a3eeb0550447febd188b2a8e702a60e0dce9 Mon Sep 17 00:00:00 2001 From: Rikko Date: Sun, 23 Jul 2023 20:36:51 +0530 Subject: [PATCH 07/60] Update plugin updation example --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f062de6..33f9f93 100644 --- a/README.md +++ b/README.md @@ -149,17 +149,17 @@ diff --git a/plugins/utilities/sample_plugin.py b/plugins/utilities/sample_plugi index ebb7dcc..da2b312 100644 --- a/plugins/utilities/sample_plugin.py +++ b/plugins/utilities/sample_plugin.py -@@ -5,6 +5,7 @@ import ba - class Main(ba.Plugin): +@@ -5,6 +5,7 @@ import babase + class Main(babase.Plugin): def on_app_running(self): - ba.screenmessage("Hi! I am a sample plugin!") + babase.screenmessage("Hi! I am a sample plugin!") def has_settings_ui(self): return True def show_settings_ui(self, source_widget): -- ba.screenmessage("You tapped my settings!") -+ ba.screenmessage("Hey! This is my new screenmessage!") +- babase.screenmessage("You tapped my settings!") ++ babase.screenmessage("Hey! This is my new screenmessage!") ``` To name this new version as `1.1.0`, add `"1.1.0": null,` just above the previous plugin version in `utilities.json`: From 88841cdd4b5b6fd2521ad74dd308eba7f93f0c08 Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Sun, 23 Jul 2023 17:19:22 +0200 Subject: [PATCH 08/60] Update minigames.json --- plugins/minigames.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index de4d140..c889daf 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -457,6 +457,7 @@ } ], "versions": { + "2.0.0":null, "1.0.0": { "api_version": 7, "commit_sha": "7219487", @@ -618,4 +619,4 @@ } } } -} \ No newline at end of file +} From 1d5a6f3d2c3a6bc746ff5d7ece6bcbd27f903abe Mon Sep 17 00:00:00 2001 From: SenjuZoro Date: Sun, 23 Jul 2023 15:19:54 +0000 Subject: [PATCH 09/60] [ci] apply-version-metadata --- plugins/minigames.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index c889daf..bf184ea 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -457,7 +457,12 @@ } ], "versions": { - "2.0.0":null, + "2.0.0": { + "api_version": 7, + "commit_sha": "88841cd", + "released_on": "23-07-2023", + "md5sum": "afca5167b564a7f7c0bdc53c3e52d198" + }, "1.0.0": { "api_version": 7, "commit_sha": "7219487", @@ -619,4 +624,4 @@ } } } -} +} \ No newline at end of file From 1a8037eedcc81561de7781c2bb94800a63976fc3 Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Sun, 23 Jul 2023 17:29:34 +0200 Subject: [PATCH 10/60] Update minigames.json --- plugins/minigames.json | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index bf184ea..cb3d688 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -457,12 +457,6 @@ } ], "versions": { - "2.0.0": { - "api_version": 7, - "commit_sha": "88841cd", - "released_on": "23-07-2023", - "md5sum": "afca5167b564a7f7c0bdc53c3e52d198" - }, "1.0.0": { "api_version": 7, "commit_sha": "7219487", @@ -482,6 +476,7 @@ } ], "versions": { + "2.0.0":null, "1.0.0": { "api_version": 7, "commit_sha": "7219487", @@ -624,4 +619,4 @@ } } } -} \ No newline at end of file +} From f39e240d0d6f06c9952e4f12a6db6af512e91f51 Mon Sep 17 00:00:00 2001 From: SenjuZoro Date: Sun, 23 Jul 2023 15:30:02 +0000 Subject: [PATCH 11/60] [ci] apply-version-metadata --- plugins/minigames.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index cb3d688..6303e42 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -476,7 +476,12 @@ } ], "versions": { - "2.0.0":null, + "2.0.0": { + "api_version": 8, + "commit_sha": "1a8037e", + "released_on": "23-07-2023", + "md5sum": "916e37f6e1a8a5be3dd0389ed2c4b261" + }, "1.0.0": { "api_version": 7, "commit_sha": "7219487", @@ -619,4 +624,4 @@ } } } -} +} \ No newline at end of file From 6db1bef848c5c3ee834f9e4540b7e9023d97bd30 Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Sun, 23 Jul 2023 17:40:41 +0200 Subject: [PATCH 12/60] Collector updated Collector minigame updated to api 8 Author Mikirog --- plugins/minigames/Collector.py | 636 +++++++++++++++++++++++++++++++++ 1 file changed, 636 insertions(+) create mode 100644 plugins/minigames/Collector.py diff --git a/plugins/minigames/Collector.py b/plugins/minigames/Collector.py new file mode 100644 index 0000000..da4b416 --- /dev/null +++ b/plugins/minigames/Collector.py @@ -0,0 +1,636 @@ +# ba_meta require api 8 +# (see https://ballistica.net/wiki/meta-tag-system) + +''' + Gamemode: Collector + Creator: TheMikirog + Website: https://bombsquadjoyride.blogspot.com/ + + This is a gamemode purely made by me just to spite unchallenged modders + out there that put out crap to the market. + We don't want gamemodes that are just the existing ones + with some novelties! Gamers deserve more! + + In this gamemode you have to kill others in order to get their Capsules. + Capsules can be collected and staked in your inventory, + how many as you please. + After you kill an enemy that carries some of them, + they drop a respective amount of Capsules they carried + two more. + Your task is to collect these Capsules, + get to the flag and score them KOTH style. + You can't score if you don't have any Capsules with you. + The first player or team to get to the required ammount wins. + This is a gamemode all about trying to stay alive + and picking your battles in order to win. + A rare skill in BombSquad, where everyone is overly aggressive. +''' + +from __future__ import annotations + +import weakref +from enum import Enum +from typing import TYPE_CHECKING + +import babase +import bauiv1 as bui +import bascenev1 as bs +import random +from bascenev1lib.actor.flag import Flag +from bascenev1lib.actor.popuptext import PopupText +from bascenev1lib.actor.playerspaz import PlayerSpaz +from bascenev1lib.actor.scoreboard import Scoreboard +from bascenev1lib.gameutils import SharedObjects + +if TYPE_CHECKING: + from typing import Any, Sequence + + +lang = bs.app.lang.language +if lang == 'Spanish': + name = 'Coleccionista' + description = ('Elimina a tus oponentes para robar sus cápsulas.\n' + '¡Recolecta y anota en el punto de depósito!') + description_ingame = 'Obtén ${ARG1} cápsulas de tus enemigos.' + description_short = 'colecciona ${ARG1} cápsulas' + tips = [( + '¡Si tu oponente cae fuera del mapa, sus cápsulas desapareceran!\n' + 'No intestes matar a tus enemigos arrojándolos al vacio.'), + 'No te apresures. ¡Puedes perder tus cápsulas rápidamente!', + ('¡No dejes que el jugador con más cápsulas anote!\n' + '¡Intenta atraparlo si puedes!'), + ('¡Las Capsulas de la Suerte te dan 4 cápsulas en lugar de 2' + 'y tienen un 8% de probabilidad de aparecer después de matar'), + ('¡No te quedes en un solo lugar! Muevete más rapido que tu enemigo, ' + '¡con suerte conseguirás algunas cápsulas!'), + ] + capsules_to_win = 'Cápsulas para Ganar' + capsules_death = 'Cápsulas al Morir' + lucky_capsules = 'Cápsulas de la Suerte' + bonus = '¡BONUS!' + full_capacity = '¡Capacidad Completa!' +else: + name = 'Collector' + description = ('Kill your opponents to steal their Capsules.\n' + 'Collect them and score at the Deposit point!') + description_ingame = 'Score ${ARG1} capsules from your enemies.' + description_short = 'collect ${ARG1} capsules' + tips = [( + 'Making you opponent fall down the pit makes his Capsules wasted!\n' + 'Try not to kill enemies by throwing them off the cliff.'), + 'Don\'t be too reckless. You can lose your loot quite quickly!', + ('Don\'t let the leading player score his Capsules ' + 'at the Deposit Point!\nTry to catch him if you can!'), + ('Lucky Capsules give 4 to your inventory and they have 8% chance ' + 'of spawning after kill!'), + ('Don\'t camp in one place! Make your move first, ' + 'so hopefully you get some dough!'), + ] + capsules_to_win = 'Capsules to Win' + capsules_death = 'Capsules on Death' + lucky_capsules = 'Allow Lucky Capsules' + bonus = 'BONUS!' + full_capacity = 'Full Capacity!' + + +class FlagState(Enum): + """States our single flag can be in.""" + + NEW = 0 + UNCONTESTED = 1 + CONTESTED = 2 + HELD = 3 + + +class Player(bs.Player['Team']): + """Our player type for this game.""" + + def __init__(self) -> None: + self.time_at_flag = 0 + self.capsules = 0 + self.light = None + + +class Team(bs.Team[Player]): + """Our team type for this game.""" + + def __init__(self) -> None: + self.score = 0 + + +# ba_meta export bascenev1.GameActivity +class CollectorGame(bs.TeamGameActivity[Player, Team]): + + name = name + description = description + tips = tips + + # Print messages when players die since it matters here. + announce_player_deaths = True + + @classmethod + def get_available_settings( + cls, sessiontype: type[bs.Session] + ) -> list[babase.Setting]: + settings = [ + bs.IntSetting( + capsules_to_win, + min_value=1, + default=10, + increment=1, + ), + bs.IntSetting( + capsules_death, + min_value=1, + max_value=10, + default=2, + increment=1, + ), + bs.IntChoiceSetting( + 'Time Limit', + choices=[ + ('None', 0), + ('1 Minute', 60), + ('2 Minutes', 120), + ('5 Minutes', 300), + ('10 Minutes', 600), + ('20 Minutes', 1200), + ], + default=0, + ), + bs.FloatChoiceSetting( + 'Respawn Times', + choices=[ + ('Shorter', 0.25), + ('Short', 0.5), + ('Normal', 1.0), + ('Long', 2.0), + ('Longer', 4.0), + ], + default=1.0, + ), + bs.BoolSetting(lucky_capsules, default=True), + bs.BoolSetting('Epic Mode', default=False), + ] + return settings + + @classmethod + 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[bs.Session]) -> list[str]: + return bs.app.classic.getmaps('keep_away') + + def __init__(self, settings: dict): + super().__init__(settings) + shared = SharedObjects.get() + self._scoreboard = Scoreboard() + self._score_to_win: int | None = None + self._swipsound = bs.getsound('swip') + self._lucky_sound = bs.getsound('ding') + + self._flag_pos: Sequence[float] | None = None + self._flag_state: FlagState | None = None + self._flag: Flag | None = None + self._flag_light: bs.Node | None = None + self._scoring_team: weakref.ref[Team] | None = None + self._time_limit = float(settings['Time Limit']) + self._epic_mode = bool(settings['Epic Mode']) + + self._capsules_to_win = int(settings[capsules_to_win]) + self._capsules_death = int(settings[capsules_death]) + self._lucky_capsules = bool(settings[lucky_capsules]) + self._capsules: list[Any] = [] + + self._capsule_mesh = bs.getmesh('bomb') + self._capsule_tex = bs.gettexture('bombColor') + self._capsule_lucky_tex = bs.gettexture('bombStickyColor') + self._collect_sound = bs.getsound('powerup01') + self._lucky_collect_sound = bs.getsound('cashRegister2') + + self._capsule_material = bs.Material() + self._capsule_material.add_actions( + conditions=('they_have_material', shared.player_material), + actions=('call', 'at_connect', self._on_capsule_player_collide), + ) + + self._flag_region_material = bs.Material() + self._flag_region_material.add_actions( + conditions=('they_have_material', shared.player_material), + actions=( + ('modify_part_collision', 'collide', True), + ('modify_part_collision', 'physical', False), + ( + 'call', + 'at_connect', + babase.Call(self._handle_player_flag_region_collide, True), + ), + ( + 'call', + 'at_disconnect', + babase.Call(self._handle_player_flag_region_collide, False), + ), + ), + ) + + # Base class overrides. + self.slow_motion = self._epic_mode + self.default_music = ( + bs.MusicType.EPIC if self._epic_mode else bs.MusicType.SCARY + ) + + def get_instance_description(self) -> str | Sequence: + return description_ingame, self._score_to_win + + def get_instance_description_short(self) -> str | Sequence: + return description_short, self._score_to_win + + def create_team(self, sessionteam: bs.SessionTeam) -> Team: + return Team() + + def on_team_join(self, team: Team) -> None: + self._update_scoreboard() + + def on_begin(self) -> None: + super().on_begin() + shared = SharedObjects.get() + self.setup_standard_time_limit(self._time_limit) + self.setup_standard_powerup_drops() + + # Base kills needed to win on the size of the largest team. + self._score_to_win = self._capsules_to_win * max( + 1, max(len(t.players) for t in self.teams) + ) + self._update_scoreboard() + + if isinstance(self.session, bs.FreeForAllSession): + self._flag_pos = self.map.get_flag_position(random.randint(0, 1)) + else: + self._flag_pos = self.map.get_flag_position(None) + + bs.timer(1.0, self._tick, repeat=True) + self._flag_state = FlagState.NEW + Flag.project_stand(self._flag_pos) + self._flag = Flag( + position=self._flag_pos, touchable=False, color=(1, 1, 1) + ) + self._flag_light = bs.newnode( + 'light', + attrs={ + 'position': self._flag_pos, + 'intensity': 0.2, + 'height_attenuated': False, + 'radius': 0.4, + 'color': (0.2, 0.2, 0.2), + }, + ) + # Flag region. + flagmats = [self._flag_region_material, shared.region_material] + bs.newnode( + 'region', + attrs={ + 'position': self._flag_pos, + 'scale': (1.8, 1.8, 1.8), + 'type': 'sphere', + 'materials': flagmats, + }, + ) + self._update_flag_state() + + def _tick(self) -> None: + self._update_flag_state() + + if self._scoring_team is None: + scoring_team = None + else: + scoring_team = self._scoring_team() + + if not scoring_team: + return + + if isinstance(self.session, bs.FreeForAllSession): + players = self.players + else: + players = scoring_team.players + + for player in players: + if player.time_at_flag > 0: + self.stats.player_scored( + player, 3, screenmessage=False, display=False + ) + if player.capsules > 0: + if self._flag_state != FlagState.HELD: + return + if scoring_team.score >= self._score_to_win: + return + + player.capsules -= 1 + scoring_team.score += 1 + self._handle_capsule_storage(( + self._flag_pos[0], + self._flag_pos[1]+1, + self._flag_pos[2] + ), player) + self._collect_sound.play(0.8, position=self._flag_pos) + + self._update_scoreboard() + if player.capsules > 0: + assert self._flag is not None + self._flag.set_score_text( + str(self._score_to_win - scoring_team.score)) + + # winner + if scoring_team.score >= self._score_to_win: + self.end_game() + + def end_game(self) -> None: + results = bs.GameResults() + for team in self.teams: + results.set_team_score(team, team.score) + self.end(results=results, announce_delay=0) + + def _update_flag_state(self) -> None: + holding_teams = set( + player.team for player in self.players if player.time_at_flag + ) + prev_state = self._flag_state + assert self._flag_light + assert self._flag is not None + assert self._flag.node + if len(holding_teams) > 1: + self._flag_state = FlagState.CONTESTED + self._scoring_team = None + self._flag_light.color = (0.6, 0.6, 0.1) + self._flag.node.color = (1.0, 1.0, 0.4) + elif len(holding_teams) == 1: + holding_team = list(holding_teams)[0] + self._flag_state = FlagState.HELD + self._scoring_team = weakref.ref(holding_team) + self._flag_light.color = babase.normalized_color(holding_team.color) + self._flag.node.color = holding_team.color + else: + self._flag_state = FlagState.UNCONTESTED + self._scoring_team = None + self._flag_light.color = (0.2, 0.2, 0.2) + self._flag.node.color = (1, 1, 1) + if self._flag_state != prev_state: + self._swipsound.play() + + def _handle_player_flag_region_collide(self, colliding: bool) -> None: + try: + spaz = bs.getcollision().opposingnode.getdelegate(PlayerSpaz, True) + except bs.NotFoundError: + return + + if not spaz.is_alive(): + return + + player = spaz.getplayer(Player, True) + + # Different parts of us can collide so a single value isn't enough + # also don't count it if we're dead (flying heads shouldn't be able to + # win the game :-) + if colliding and player.is_alive(): + player.time_at_flag += 1 + else: + player.time_at_flag = max(0, player.time_at_flag - 1) + + self._update_flag_state() + + def _update_scoreboard(self) -> None: + for team in self.teams: + self._scoreboard.set_team_value( + team, team.score, self._score_to_win + ) + + def _drop_capsule(self, player: Player) -> None: + pt = player.node.position + + # Throw out capsules that the victim has + 2 more to keep the game running + for i in range(player.capsules + self._capsules_death): + # How far from each other these capsules should spawn + w = 0.6 + # How much these capsules should fly after spawning + s = 0.005 - (player.capsules * 0.01) + self._capsules.append( + Capsule( + position=(pt[0] + random.uniform(-w, w), + pt[1] + 0.75 + random.uniform(-w, w), + pt[2]), + velocity=(random.uniform(-s, s), + random.uniform(-s, s), + random.uniform(-s, s)), + lucky=False)) + if random.randint(1, 12) == 1 and self._lucky_capsules: + # How far from each other these capsules should spawn + w = 0.6 + # How much these capsules should fly after spawning + s = 0.005 + self._capsules.append( + Capsule( + position=(pt[0] + random.uniform(-w, w), + pt[1] + 0.75 + random.uniform(-w, w), + pt[2]), + velocity=(random.uniform(-s, s), + random.uniform(-s, s), + random.uniform(-s, s)), + lucky=True)) + + def _on_capsule_player_collide(self) -> None: + if self.has_ended(): + return + collision = bs.getcollision() + + # Be defensive here; we could be hitting the corpse of a player + # who just left/etc. + try: + capsule = collision.sourcenode.getdelegate(Capsule, True) + player = collision.opposingnode.getdelegate( + PlayerSpaz, True + ).getplayer(Player, True) + except bs.NotFoundError: + return + + if not player.is_alive(): + return + + if capsule.node.color_texture == self._capsule_lucky_tex: + player.capsules += 4 + PopupText( + bonus, + color=(1, 1, 0), + scale=1.5, + position=capsule.node.position + ).autoretain() + self._lucky_collect_sound.play(1.0, position=capsule.node.position) + bs.emitfx( + position=capsule.node.position, + velocity=(0, 0, 0), + count=int(6.4+random.random()*24), + scale=1.2, + spread=2.0, + chunk_type='spark') + bs.emitfx( + position=capsule.node.position, + velocity=(0, 0, 0), + count=int(4.0+random.random()*6), + emit_type='tendrils') + else: + player.capsules += 1 + self._collect_sound.play(0.6, position=capsule.node.position) + # create a flash + light = bs.newnode( + 'light', + attrs={ + 'position': capsule.node.position, + 'height_attenuated': False, + 'radius': 0.1, + 'color': (1, 1, 0)}) + + # Create a short text informing about your inventory + self._handle_capsule_storage(player.position, player) + + bs.animate(light, 'intensity', { + 0: 0, + 0.1: 0.5, + 0.2: 0 + }, loop=False) + bs.timer(0.2, light.delete) + capsule.handlemessage(bs.DieMessage()) + + def _update_player_light(self, player: Player, capsules: int) -> None: + if player.light: + intensity = 0.04 * capsules + bs.animate(player.light, 'intensity', { + 0.0: player.light.intensity, + 0.1: intensity + }) + + def newintensity(): + player.light.intensity = intensity + bs.timer(0.1, newintensity) + else: + player.light = bs.newnode( + 'light', + attrs={ + 'height_attenuated': False, + 'radius': 0.2, + 'intensity': 0.0, + 'color': (0.2, 1, 0.2) + }) + player.node.connectattr('position', player.light, 'position') + + def _handle_capsule_storage(self, pos: float, player: Player) -> None: + capsules = player.capsules + text = str(capsules) + scale = 1.75 + (0.02 * capsules) + if capsules > 10: + player.capsules = 10 + text = full_capacity + color = (1, 0.85, 0) + elif capsules > 7: + color = (1, 0, 0) + scale = 2.4 + elif capsules > 5: + color = (1, 0.4, 0.4) + scale = 2.1 + elif capsules > 3: + color = (1, 1, 0.4) + scale = 2.0 + else: + color = (1, 1, 1) + scale = 1.9 + PopupText( + text, + color=color, + scale=scale, + position=(pos[0], pos[1]-1, pos[2]) + ).autoretain() + self._update_player_light(player, capsules) + + def handlemessage(self, msg: Any) -> Any: + if isinstance(msg, bs.PlayerDiedMessage): + super().handlemessage(msg) # Augment default. + # No longer can count as time_at_flag once dead. + player = msg.getplayer(Player) + player.time_at_flag = 0 + self._update_flag_state() + self._drop_capsule(player) + player.capsules = 0 + self._update_player_light(player, 0) + self.respawn_player(player) + else: + return super().handlemessage(msg) + + +class Capsule(bs.Actor): + + def __init__(self, + position: Sequence[float] = (0.0, 1.0, 0.0), + velocity: Sequence[float] = (0.0, 0.5, 0.0), + lucky: bool = False): + super().__init__() + shared = SharedObjects.get() + activity = self.getactivity() + + # spawn just above the provided point + self._spawn_pos = (position[0], position[1], position[2]) + + if lucky: + activity._lucky_sound.play(1.0, self._spawn_pos) + + self.node = bs.newnode( + 'prop', + attrs={ + 'mesh': activity._capsule_mesh, + 'color_texture': activity._capsule_lucky_tex if lucky else ( + activity._capsule_tex), + 'body': 'crate' if lucky else 'capsule', + 'reflection': 'powerup' if lucky else 'soft', + 'body_scale': 0.65 if lucky else 0.3, + 'density': 6.0 if lucky else 4.0, + 'reflection_scale': [0.15], + 'shadow_size': 0.65 if lucky else 0.6, + 'position': self._spawn_pos, + 'velocity': velocity, + 'materials': [ + shared.object_material, activity._capsule_material] + }, + delegate=self) + bs.animate(self.node, 'mesh_scale', { + 0.0: 0.0, + 0.1: 0.9 if lucky else 0.6, + 0.16: 0.8 if lucky else 0.5 + }) + self._light_capsule = bs.newnode( + 'light', + attrs={ + 'position': self._spawn_pos, + 'height_attenuated': False, + 'radius': 0.5 if lucky else 0.1, + 'color': (0.2, 0.2, 0) if lucky else (0.2, 1, 0.2) + }) + self.node.connectattr('position', self._light_capsule, 'position') + + def handlemessage(self, msg: Any): + if isinstance(msg, bs.DieMessage): + self.node.delete() + bs.animate(self._light_capsule, 'intensity', { + 0: 1.0, + 0.05: 0.0 + }, loop=False) + bs.timer(0.05, self._light_capsule.delete) + elif isinstance(msg, bs.OutOfBoundsMessage): + self.handlemessage(bs.DieMessage()) + elif isinstance(msg, bs.HitMessage): + self.node.handlemessage( + 'impulse', + msg.pos[0], msg.pos[1], msg.pos[2], + msg.velocity[0]/8, msg.velocity[1]/8, msg.velocity[2]/8, + 1.0*msg.magnitude, 1.0*msg.velocity_magnitude, msg.radius, 0, + msg.force_direction[0], msg.force_direction[1], + msg.force_direction[2]) + else: + return super().handlemessage(msg) From 968616aad974e52f4647a25afab09dc5f0d8d640 Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Sun, 23 Jul 2023 17:42:15 +0200 Subject: [PATCH 13/60] Update minigames.json --- plugins/minigames.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index 6303e42..f91eb44 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -457,6 +457,7 @@ } ], "versions": { + "2.0.0":null, "1.0.0": { "api_version": 7, "commit_sha": "7219487", @@ -624,4 +625,4 @@ } } } -} \ No newline at end of file +} From 713f81df68eb07acc66513cd5afc02c0a55349d0 Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Sun, 23 Jul 2023 17:50:18 +0200 Subject: [PATCH 14/60] Delete Collector.py --- plugins/minigames/Collector.py | 636 --------------------------------- 1 file changed, 636 deletions(-) delete mode 100644 plugins/minigames/Collector.py diff --git a/plugins/minigames/Collector.py b/plugins/minigames/Collector.py deleted file mode 100644 index da4b416..0000000 --- a/plugins/minigames/Collector.py +++ /dev/null @@ -1,636 +0,0 @@ -# ba_meta require api 8 -# (see https://ballistica.net/wiki/meta-tag-system) - -''' - Gamemode: Collector - Creator: TheMikirog - Website: https://bombsquadjoyride.blogspot.com/ - - This is a gamemode purely made by me just to spite unchallenged modders - out there that put out crap to the market. - We don't want gamemodes that are just the existing ones - with some novelties! Gamers deserve more! - - In this gamemode you have to kill others in order to get their Capsules. - Capsules can be collected and staked in your inventory, - how many as you please. - After you kill an enemy that carries some of them, - they drop a respective amount of Capsules they carried + two more. - Your task is to collect these Capsules, - get to the flag and score them KOTH style. - You can't score if you don't have any Capsules with you. - The first player or team to get to the required ammount wins. - This is a gamemode all about trying to stay alive - and picking your battles in order to win. - A rare skill in BombSquad, where everyone is overly aggressive. -''' - -from __future__ import annotations - -import weakref -from enum import Enum -from typing import TYPE_CHECKING - -import babase -import bauiv1 as bui -import bascenev1 as bs -import random -from bascenev1lib.actor.flag import Flag -from bascenev1lib.actor.popuptext import PopupText -from bascenev1lib.actor.playerspaz import PlayerSpaz -from bascenev1lib.actor.scoreboard import Scoreboard -from bascenev1lib.gameutils import SharedObjects - -if TYPE_CHECKING: - from typing import Any, Sequence - - -lang = bs.app.lang.language -if lang == 'Spanish': - name = 'Coleccionista' - description = ('Elimina a tus oponentes para robar sus cápsulas.\n' - '¡Recolecta y anota en el punto de depósito!') - description_ingame = 'Obtén ${ARG1} cápsulas de tus enemigos.' - description_short = 'colecciona ${ARG1} cápsulas' - tips = [( - '¡Si tu oponente cae fuera del mapa, sus cápsulas desapareceran!\n' - 'No intestes matar a tus enemigos arrojándolos al vacio.'), - 'No te apresures. ¡Puedes perder tus cápsulas rápidamente!', - ('¡No dejes que el jugador con más cápsulas anote!\n' - '¡Intenta atraparlo si puedes!'), - ('¡Las Capsulas de la Suerte te dan 4 cápsulas en lugar de 2' - 'y tienen un 8% de probabilidad de aparecer después de matar'), - ('¡No te quedes en un solo lugar! Muevete más rapido que tu enemigo, ' - '¡con suerte conseguirás algunas cápsulas!'), - ] - capsules_to_win = 'Cápsulas para Ganar' - capsules_death = 'Cápsulas al Morir' - lucky_capsules = 'Cápsulas de la Suerte' - bonus = '¡BONUS!' - full_capacity = '¡Capacidad Completa!' -else: - name = 'Collector' - description = ('Kill your opponents to steal their Capsules.\n' - 'Collect them and score at the Deposit point!') - description_ingame = 'Score ${ARG1} capsules from your enemies.' - description_short = 'collect ${ARG1} capsules' - tips = [( - 'Making you opponent fall down the pit makes his Capsules wasted!\n' - 'Try not to kill enemies by throwing them off the cliff.'), - 'Don\'t be too reckless. You can lose your loot quite quickly!', - ('Don\'t let the leading player score his Capsules ' - 'at the Deposit Point!\nTry to catch him if you can!'), - ('Lucky Capsules give 4 to your inventory and they have 8% chance ' - 'of spawning after kill!'), - ('Don\'t camp in one place! Make your move first, ' - 'so hopefully you get some dough!'), - ] - capsules_to_win = 'Capsules to Win' - capsules_death = 'Capsules on Death' - lucky_capsules = 'Allow Lucky Capsules' - bonus = 'BONUS!' - full_capacity = 'Full Capacity!' - - -class FlagState(Enum): - """States our single flag can be in.""" - - NEW = 0 - UNCONTESTED = 1 - CONTESTED = 2 - HELD = 3 - - -class Player(bs.Player['Team']): - """Our player type for this game.""" - - def __init__(self) -> None: - self.time_at_flag = 0 - self.capsules = 0 - self.light = None - - -class Team(bs.Team[Player]): - """Our team type for this game.""" - - def __init__(self) -> None: - self.score = 0 - - -# ba_meta export bascenev1.GameActivity -class CollectorGame(bs.TeamGameActivity[Player, Team]): - - name = name - description = description - tips = tips - - # Print messages when players die since it matters here. - announce_player_deaths = True - - @classmethod - def get_available_settings( - cls, sessiontype: type[bs.Session] - ) -> list[babase.Setting]: - settings = [ - bs.IntSetting( - capsules_to_win, - min_value=1, - default=10, - increment=1, - ), - bs.IntSetting( - capsules_death, - min_value=1, - max_value=10, - default=2, - increment=1, - ), - bs.IntChoiceSetting( - 'Time Limit', - choices=[ - ('None', 0), - ('1 Minute', 60), - ('2 Minutes', 120), - ('5 Minutes', 300), - ('10 Minutes', 600), - ('20 Minutes', 1200), - ], - default=0, - ), - bs.FloatChoiceSetting( - 'Respawn Times', - choices=[ - ('Shorter', 0.25), - ('Short', 0.5), - ('Normal', 1.0), - ('Long', 2.0), - ('Longer', 4.0), - ], - default=1.0, - ), - bs.BoolSetting(lucky_capsules, default=True), - bs.BoolSetting('Epic Mode', default=False), - ] - return settings - - @classmethod - 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[bs.Session]) -> list[str]: - return bs.app.classic.getmaps('keep_away') - - def __init__(self, settings: dict): - super().__init__(settings) - shared = SharedObjects.get() - self._scoreboard = Scoreboard() - self._score_to_win: int | None = None - self._swipsound = bs.getsound('swip') - self._lucky_sound = bs.getsound('ding') - - self._flag_pos: Sequence[float] | None = None - self._flag_state: FlagState | None = None - self._flag: Flag | None = None - self._flag_light: bs.Node | None = None - self._scoring_team: weakref.ref[Team] | None = None - self._time_limit = float(settings['Time Limit']) - self._epic_mode = bool(settings['Epic Mode']) - - self._capsules_to_win = int(settings[capsules_to_win]) - self._capsules_death = int(settings[capsules_death]) - self._lucky_capsules = bool(settings[lucky_capsules]) - self._capsules: list[Any] = [] - - self._capsule_mesh = bs.getmesh('bomb') - self._capsule_tex = bs.gettexture('bombColor') - self._capsule_lucky_tex = bs.gettexture('bombStickyColor') - self._collect_sound = bs.getsound('powerup01') - self._lucky_collect_sound = bs.getsound('cashRegister2') - - self._capsule_material = bs.Material() - self._capsule_material.add_actions( - conditions=('they_have_material', shared.player_material), - actions=('call', 'at_connect', self._on_capsule_player_collide), - ) - - self._flag_region_material = bs.Material() - self._flag_region_material.add_actions( - conditions=('they_have_material', shared.player_material), - actions=( - ('modify_part_collision', 'collide', True), - ('modify_part_collision', 'physical', False), - ( - 'call', - 'at_connect', - babase.Call(self._handle_player_flag_region_collide, True), - ), - ( - 'call', - 'at_disconnect', - babase.Call(self._handle_player_flag_region_collide, False), - ), - ), - ) - - # Base class overrides. - self.slow_motion = self._epic_mode - self.default_music = ( - bs.MusicType.EPIC if self._epic_mode else bs.MusicType.SCARY - ) - - def get_instance_description(self) -> str | Sequence: - return description_ingame, self._score_to_win - - def get_instance_description_short(self) -> str | Sequence: - return description_short, self._score_to_win - - def create_team(self, sessionteam: bs.SessionTeam) -> Team: - return Team() - - def on_team_join(self, team: Team) -> None: - self._update_scoreboard() - - def on_begin(self) -> None: - super().on_begin() - shared = SharedObjects.get() - self.setup_standard_time_limit(self._time_limit) - self.setup_standard_powerup_drops() - - # Base kills needed to win on the size of the largest team. - self._score_to_win = self._capsules_to_win * max( - 1, max(len(t.players) for t in self.teams) - ) - self._update_scoreboard() - - if isinstance(self.session, bs.FreeForAllSession): - self._flag_pos = self.map.get_flag_position(random.randint(0, 1)) - else: - self._flag_pos = self.map.get_flag_position(None) - - bs.timer(1.0, self._tick, repeat=True) - self._flag_state = FlagState.NEW - Flag.project_stand(self._flag_pos) - self._flag = Flag( - position=self._flag_pos, touchable=False, color=(1, 1, 1) - ) - self._flag_light = bs.newnode( - 'light', - attrs={ - 'position': self._flag_pos, - 'intensity': 0.2, - 'height_attenuated': False, - 'radius': 0.4, - 'color': (0.2, 0.2, 0.2), - }, - ) - # Flag region. - flagmats = [self._flag_region_material, shared.region_material] - bs.newnode( - 'region', - attrs={ - 'position': self._flag_pos, - 'scale': (1.8, 1.8, 1.8), - 'type': 'sphere', - 'materials': flagmats, - }, - ) - self._update_flag_state() - - def _tick(self) -> None: - self._update_flag_state() - - if self._scoring_team is None: - scoring_team = None - else: - scoring_team = self._scoring_team() - - if not scoring_team: - return - - if isinstance(self.session, bs.FreeForAllSession): - players = self.players - else: - players = scoring_team.players - - for player in players: - if player.time_at_flag > 0: - self.stats.player_scored( - player, 3, screenmessage=False, display=False - ) - if player.capsules > 0: - if self._flag_state != FlagState.HELD: - return - if scoring_team.score >= self._score_to_win: - return - - player.capsules -= 1 - scoring_team.score += 1 - self._handle_capsule_storage(( - self._flag_pos[0], - self._flag_pos[1]+1, - self._flag_pos[2] - ), player) - self._collect_sound.play(0.8, position=self._flag_pos) - - self._update_scoreboard() - if player.capsules > 0: - assert self._flag is not None - self._flag.set_score_text( - str(self._score_to_win - scoring_team.score)) - - # winner - if scoring_team.score >= self._score_to_win: - self.end_game() - - def end_game(self) -> None: - results = bs.GameResults() - for team in self.teams: - results.set_team_score(team, team.score) - self.end(results=results, announce_delay=0) - - def _update_flag_state(self) -> None: - holding_teams = set( - player.team for player in self.players if player.time_at_flag - ) - prev_state = self._flag_state - assert self._flag_light - assert self._flag is not None - assert self._flag.node - if len(holding_teams) > 1: - self._flag_state = FlagState.CONTESTED - self._scoring_team = None - self._flag_light.color = (0.6, 0.6, 0.1) - self._flag.node.color = (1.0, 1.0, 0.4) - elif len(holding_teams) == 1: - holding_team = list(holding_teams)[0] - self._flag_state = FlagState.HELD - self._scoring_team = weakref.ref(holding_team) - self._flag_light.color = babase.normalized_color(holding_team.color) - self._flag.node.color = holding_team.color - else: - self._flag_state = FlagState.UNCONTESTED - self._scoring_team = None - self._flag_light.color = (0.2, 0.2, 0.2) - self._flag.node.color = (1, 1, 1) - if self._flag_state != prev_state: - self._swipsound.play() - - def _handle_player_flag_region_collide(self, colliding: bool) -> None: - try: - spaz = bs.getcollision().opposingnode.getdelegate(PlayerSpaz, True) - except bs.NotFoundError: - return - - if not spaz.is_alive(): - return - - player = spaz.getplayer(Player, True) - - # Different parts of us can collide so a single value isn't enough - # also don't count it if we're dead (flying heads shouldn't be able to - # win the game :-) - if colliding and player.is_alive(): - player.time_at_flag += 1 - else: - player.time_at_flag = max(0, player.time_at_flag - 1) - - self._update_flag_state() - - def _update_scoreboard(self) -> None: - for team in self.teams: - self._scoreboard.set_team_value( - team, team.score, self._score_to_win - ) - - def _drop_capsule(self, player: Player) -> None: - pt = player.node.position - - # Throw out capsules that the victim has + 2 more to keep the game running - for i in range(player.capsules + self._capsules_death): - # How far from each other these capsules should spawn - w = 0.6 - # How much these capsules should fly after spawning - s = 0.005 - (player.capsules * 0.01) - self._capsules.append( - Capsule( - position=(pt[0] + random.uniform(-w, w), - pt[1] + 0.75 + random.uniform(-w, w), - pt[2]), - velocity=(random.uniform(-s, s), - random.uniform(-s, s), - random.uniform(-s, s)), - lucky=False)) - if random.randint(1, 12) == 1 and self._lucky_capsules: - # How far from each other these capsules should spawn - w = 0.6 - # How much these capsules should fly after spawning - s = 0.005 - self._capsules.append( - Capsule( - position=(pt[0] + random.uniform(-w, w), - pt[1] + 0.75 + random.uniform(-w, w), - pt[2]), - velocity=(random.uniform(-s, s), - random.uniform(-s, s), - random.uniform(-s, s)), - lucky=True)) - - def _on_capsule_player_collide(self) -> None: - if self.has_ended(): - return - collision = bs.getcollision() - - # Be defensive here; we could be hitting the corpse of a player - # who just left/etc. - try: - capsule = collision.sourcenode.getdelegate(Capsule, True) - player = collision.opposingnode.getdelegate( - PlayerSpaz, True - ).getplayer(Player, True) - except bs.NotFoundError: - return - - if not player.is_alive(): - return - - if capsule.node.color_texture == self._capsule_lucky_tex: - player.capsules += 4 - PopupText( - bonus, - color=(1, 1, 0), - scale=1.5, - position=capsule.node.position - ).autoretain() - self._lucky_collect_sound.play(1.0, position=capsule.node.position) - bs.emitfx( - position=capsule.node.position, - velocity=(0, 0, 0), - count=int(6.4+random.random()*24), - scale=1.2, - spread=2.0, - chunk_type='spark') - bs.emitfx( - position=capsule.node.position, - velocity=(0, 0, 0), - count=int(4.0+random.random()*6), - emit_type='tendrils') - else: - player.capsules += 1 - self._collect_sound.play(0.6, position=capsule.node.position) - # create a flash - light = bs.newnode( - 'light', - attrs={ - 'position': capsule.node.position, - 'height_attenuated': False, - 'radius': 0.1, - 'color': (1, 1, 0)}) - - # Create a short text informing about your inventory - self._handle_capsule_storage(player.position, player) - - bs.animate(light, 'intensity', { - 0: 0, - 0.1: 0.5, - 0.2: 0 - }, loop=False) - bs.timer(0.2, light.delete) - capsule.handlemessage(bs.DieMessage()) - - def _update_player_light(self, player: Player, capsules: int) -> None: - if player.light: - intensity = 0.04 * capsules - bs.animate(player.light, 'intensity', { - 0.0: player.light.intensity, - 0.1: intensity - }) - - def newintensity(): - player.light.intensity = intensity - bs.timer(0.1, newintensity) - else: - player.light = bs.newnode( - 'light', - attrs={ - 'height_attenuated': False, - 'radius': 0.2, - 'intensity': 0.0, - 'color': (0.2, 1, 0.2) - }) - player.node.connectattr('position', player.light, 'position') - - def _handle_capsule_storage(self, pos: float, player: Player) -> None: - capsules = player.capsules - text = str(capsules) - scale = 1.75 + (0.02 * capsules) - if capsules > 10: - player.capsules = 10 - text = full_capacity - color = (1, 0.85, 0) - elif capsules > 7: - color = (1, 0, 0) - scale = 2.4 - elif capsules > 5: - color = (1, 0.4, 0.4) - scale = 2.1 - elif capsules > 3: - color = (1, 1, 0.4) - scale = 2.0 - else: - color = (1, 1, 1) - scale = 1.9 - PopupText( - text, - color=color, - scale=scale, - position=(pos[0], pos[1]-1, pos[2]) - ).autoretain() - self._update_player_light(player, capsules) - - def handlemessage(self, msg: Any) -> Any: - if isinstance(msg, bs.PlayerDiedMessage): - super().handlemessage(msg) # Augment default. - # No longer can count as time_at_flag once dead. - player = msg.getplayer(Player) - player.time_at_flag = 0 - self._update_flag_state() - self._drop_capsule(player) - player.capsules = 0 - self._update_player_light(player, 0) - self.respawn_player(player) - else: - return super().handlemessage(msg) - - -class Capsule(bs.Actor): - - def __init__(self, - position: Sequence[float] = (0.0, 1.0, 0.0), - velocity: Sequence[float] = (0.0, 0.5, 0.0), - lucky: bool = False): - super().__init__() - shared = SharedObjects.get() - activity = self.getactivity() - - # spawn just above the provided point - self._spawn_pos = (position[0], position[1], position[2]) - - if lucky: - activity._lucky_sound.play(1.0, self._spawn_pos) - - self.node = bs.newnode( - 'prop', - attrs={ - 'mesh': activity._capsule_mesh, - 'color_texture': activity._capsule_lucky_tex if lucky else ( - activity._capsule_tex), - 'body': 'crate' if lucky else 'capsule', - 'reflection': 'powerup' if lucky else 'soft', - 'body_scale': 0.65 if lucky else 0.3, - 'density': 6.0 if lucky else 4.0, - 'reflection_scale': [0.15], - 'shadow_size': 0.65 if lucky else 0.6, - 'position': self._spawn_pos, - 'velocity': velocity, - 'materials': [ - shared.object_material, activity._capsule_material] - }, - delegate=self) - bs.animate(self.node, 'mesh_scale', { - 0.0: 0.0, - 0.1: 0.9 if lucky else 0.6, - 0.16: 0.8 if lucky else 0.5 - }) - self._light_capsule = bs.newnode( - 'light', - attrs={ - 'position': self._spawn_pos, - 'height_attenuated': False, - 'radius': 0.5 if lucky else 0.1, - 'color': (0.2, 0.2, 0) if lucky else (0.2, 1, 0.2) - }) - self.node.connectattr('position', self._light_capsule, 'position') - - def handlemessage(self, msg: Any): - if isinstance(msg, bs.DieMessage): - self.node.delete() - bs.animate(self._light_capsule, 'intensity', { - 0: 1.0, - 0.05: 0.0 - }, loop=False) - bs.timer(0.05, self._light_capsule.delete) - elif isinstance(msg, bs.OutOfBoundsMessage): - self.handlemessage(bs.DieMessage()) - elif isinstance(msg, bs.HitMessage): - self.node.handlemessage( - 'impulse', - msg.pos[0], msg.pos[1], msg.pos[2], - msg.velocity[0]/8, msg.velocity[1]/8, msg.velocity[2]/8, - 1.0*msg.magnitude, 1.0*msg.velocity_magnitude, msg.radius, 0, - msg.force_direction[0], msg.force_direction[1], - msg.force_direction[2]) - else: - return super().handlemessage(msg) From e8bbb6189bbb90c44454b8b528fde1c41aeea0b7 Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Sun, 23 Jul 2023 17:51:10 +0200 Subject: [PATCH 15/60] Collector updated Collector minigame updated to api 8 Author: Mikirog --- plugins/minigames/collector.py | 163 ++++++++++++++++----------------- 1 file changed, 78 insertions(+), 85 deletions(-) diff --git a/plugins/minigames/collector.py b/plugins/minigames/collector.py index 0f9bbc3..da4b416 100644 --- a/plugins/minigames/collector.py +++ b/plugins/minigames/collector.py @@ -1,4 +1,4 @@ -# ba_meta require api 7 +# ba_meta require api 8 # (see https://ballistica.net/wiki/meta-tag-system) ''' @@ -31,19 +31,21 @@ import weakref from enum import Enum from typing import TYPE_CHECKING -import ba +import babase +import bauiv1 as bui +import bascenev1 as bs import random -from bastd.actor.flag import Flag -from bastd.actor.popuptext import PopupText -from bastd.actor.playerspaz import PlayerSpaz -from bastd.actor.scoreboard import Scoreboard -from bastd.gameutils import SharedObjects +from bascenev1lib.actor.flag import Flag +from bascenev1lib.actor.popuptext import PopupText +from bascenev1lib.actor.playerspaz import PlayerSpaz +from bascenev1lib.actor.scoreboard import Scoreboard +from bascenev1lib.gameutils import SharedObjects if TYPE_CHECKING: from typing import Any, Sequence -lang = ba.app.lang.language +lang = bs.app.lang.language if lang == 'Spanish': name = 'Coleccionista' description = ('Elimina a tus oponentes para robar sus cápsulas.\n' @@ -99,7 +101,7 @@ class FlagState(Enum): HELD = 3 -class Player(ba.Player['Team']): +class Player(bs.Player['Team']): """Our player type for this game.""" def __init__(self) -> None: @@ -108,15 +110,15 @@ class Player(ba.Player['Team']): self.light = None -class Team(ba.Team[Player]): +class Team(bs.Team[Player]): """Our team type for this game.""" def __init__(self) -> None: self.score = 0 -# ba_meta export game -class CollectorGame(ba.TeamGameActivity[Player, Team]): +# ba_meta export bascenev1.GameActivity +class CollectorGame(bs.TeamGameActivity[Player, Team]): name = name description = description @@ -127,23 +129,23 @@ class CollectorGame(ba.TeamGameActivity[Player, Team]): @classmethod def get_available_settings( - cls, sessiontype: type[ba.Session] - ) -> list[ba.Setting]: + cls, sessiontype: type[bs.Session] + ) -> list[babase.Setting]: settings = [ - ba.IntSetting( + bs.IntSetting( capsules_to_win, min_value=1, default=10, increment=1, ), - ba.IntSetting( + bs.IntSetting( capsules_death, min_value=1, max_value=10, default=2, increment=1, ), - ba.IntChoiceSetting( + bs.IntChoiceSetting( 'Time Limit', choices=[ ('None', 0), @@ -155,7 +157,7 @@ class CollectorGame(ba.TeamGameActivity[Player, Team]): ], default=0, ), - ba.FloatChoiceSetting( + bs.FloatChoiceSetting( 'Respawn Times', choices=[ ('Shorter', 0.25), @@ -166,33 +168,33 @@ class CollectorGame(ba.TeamGameActivity[Player, Team]): ], default=1.0, ), - ba.BoolSetting(lucky_capsules, default=True), - ba.BoolSetting('Epic Mode', default=False), + bs.BoolSetting(lucky_capsules, default=True), + bs.BoolSetting('Epic Mode', 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 + 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]: - return ba.getmaps('keep_away') + def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]: + return bs.app.classic.getmaps('keep_away') def __init__(self, settings: dict): super().__init__(settings) shared = SharedObjects.get() self._scoreboard = Scoreboard() self._score_to_win: int | None = None - self._swipsound = ba.getsound('swip') - self._lucky_sound = ba.getsound('ding') + self._swipsound = bs.getsound('swip') + self._lucky_sound = bs.getsound('ding') self._flag_pos: Sequence[float] | None = None self._flag_state: FlagState | None = None self._flag: Flag | None = None - self._flag_light: ba.Node | None = None + self._flag_light: bs.Node | None = None self._scoring_team: weakref.ref[Team] | None = None self._time_limit = float(settings['Time Limit']) self._epic_mode = bool(settings['Epic Mode']) @@ -202,19 +204,19 @@ class CollectorGame(ba.TeamGameActivity[Player, Team]): self._lucky_capsules = bool(settings[lucky_capsules]) self._capsules: list[Any] = [] - self._capsule_model = ba.getmodel('bomb') - self._capsule_tex = ba.gettexture('bombColor') - self._capsule_lucky_tex = ba.gettexture('bombStickyColor') - self._collect_sound = ba.getsound('powerup01') - self._lucky_collect_sound = ba.getsound('cashRegister2') + self._capsule_mesh = bs.getmesh('bomb') + self._capsule_tex = bs.gettexture('bombColor') + self._capsule_lucky_tex = bs.gettexture('bombStickyColor') + self._collect_sound = bs.getsound('powerup01') + self._lucky_collect_sound = bs.getsound('cashRegister2') - self._capsule_material = ba.Material() + self._capsule_material = bs.Material() self._capsule_material.add_actions( conditions=('they_have_material', shared.player_material), actions=('call', 'at_connect', self._on_capsule_player_collide), ) - self._flag_region_material = ba.Material() + self._flag_region_material = bs.Material() self._flag_region_material.add_actions( conditions=('they_have_material', shared.player_material), actions=( @@ -223,12 +225,12 @@ class CollectorGame(ba.TeamGameActivity[Player, Team]): ( 'call', 'at_connect', - ba.Call(self._handle_player_flag_region_collide, True), + babase.Call(self._handle_player_flag_region_collide, True), ), ( 'call', 'at_disconnect', - ba.Call(self._handle_player_flag_region_collide, False), + babase.Call(self._handle_player_flag_region_collide, False), ), ), ) @@ -236,7 +238,7 @@ class CollectorGame(ba.TeamGameActivity[Player, Team]): # Base class overrides. self.slow_motion = self._epic_mode self.default_music = ( - ba.MusicType.EPIC if self._epic_mode else ba.MusicType.SCARY + bs.MusicType.EPIC if self._epic_mode else bs.MusicType.SCARY ) def get_instance_description(self) -> str | Sequence: @@ -245,7 +247,7 @@ class CollectorGame(ba.TeamGameActivity[Player, Team]): def get_instance_description_short(self) -> str | Sequence: return description_short, self._score_to_win - def create_team(self, sessionteam: ba.SessionTeam) -> Team: + def create_team(self, sessionteam: bs.SessionTeam) -> Team: return Team() def on_team_join(self, team: Team) -> None: @@ -263,18 +265,18 @@ class CollectorGame(ba.TeamGameActivity[Player, Team]): ) self._update_scoreboard() - if isinstance(self.session, ba.FreeForAllSession): + if isinstance(self.session, bs.FreeForAllSession): self._flag_pos = self.map.get_flag_position(random.randint(0, 1)) else: self._flag_pos = self.map.get_flag_position(None) - ba.timer(1.0, self._tick, repeat=True) + bs.timer(1.0, self._tick, repeat=True) self._flag_state = FlagState.NEW Flag.project_stand(self._flag_pos) self._flag = Flag( position=self._flag_pos, touchable=False, color=(1, 1, 1) ) - self._flag_light = ba.newnode( + self._flag_light = bs.newnode( 'light', attrs={ 'position': self._flag_pos, @@ -286,7 +288,7 @@ class CollectorGame(ba.TeamGameActivity[Player, Team]): ) # Flag region. flagmats = [self._flag_region_material, shared.region_material] - ba.newnode( + bs.newnode( 'region', attrs={ 'position': self._flag_pos, @@ -308,7 +310,7 @@ class CollectorGame(ba.TeamGameActivity[Player, Team]): if not scoring_team: return - if isinstance(self.session, ba.FreeForAllSession): + if isinstance(self.session, bs.FreeForAllSession): players = self.players else: players = scoring_team.players @@ -331,10 +333,7 @@ class CollectorGame(ba.TeamGameActivity[Player, Team]): self._flag_pos[1]+1, self._flag_pos[2] ), player) - ba.playsound( - self._collect_sound, - 0.8, - position=self._flag_pos) + self._collect_sound.play(0.8, position=self._flag_pos) self._update_scoreboard() if player.capsules > 0: @@ -347,7 +346,7 @@ class CollectorGame(ba.TeamGameActivity[Player, Team]): 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, announce_delay=0) @@ -369,7 +368,7 @@ class CollectorGame(ba.TeamGameActivity[Player, Team]): holding_team = list(holding_teams)[0] self._flag_state = FlagState.HELD self._scoring_team = weakref.ref(holding_team) - self._flag_light.color = ba.normalized_color(holding_team.color) + self._flag_light.color = babase.normalized_color(holding_team.color) self._flag.node.color = holding_team.color else: self._flag_state = FlagState.UNCONTESTED @@ -377,12 +376,12 @@ class CollectorGame(ba.TeamGameActivity[Player, Team]): self._flag_light.color = (0.2, 0.2, 0.2) self._flag.node.color = (1, 1, 1) if self._flag_state != prev_state: - ba.playsound(self._swipsound) + self._swipsound.play() def _handle_player_flag_region_collide(self, colliding: bool) -> None: try: - spaz = ba.getcollision().opposingnode.getdelegate(PlayerSpaz, True) - except ba.NotFoundError: + spaz = bs.getcollision().opposingnode.getdelegate(PlayerSpaz, True) + except bs.NotFoundError: return if not spaz.is_alive(): @@ -442,7 +441,7 @@ class CollectorGame(ba.TeamGameActivity[Player, Team]): def _on_capsule_player_collide(self) -> None: if self.has_ended(): return - collision = ba.getcollision() + collision = bs.getcollision() # Be defensive here; we could be hitting the corpse of a player # who just left/etc. @@ -451,7 +450,7 @@ class CollectorGame(ba.TeamGameActivity[Player, Team]): player = collision.opposingnode.getdelegate( PlayerSpaz, True ).getplayer(Player, True) - except ba.NotFoundError: + except bs.NotFoundError: return if not player.is_alive(): @@ -465,30 +464,24 @@ class CollectorGame(ba.TeamGameActivity[Player, Team]): scale=1.5, position=capsule.node.position ).autoretain() - ba.playsound( - self._lucky_collect_sound, - 1.0, - position=capsule.node.position) - ba.emitfx( + self._lucky_collect_sound.play(1.0, position=capsule.node.position) + bs.emitfx( position=capsule.node.position, velocity=(0, 0, 0), count=int(6.4+random.random()*24), scale=1.2, spread=2.0, chunk_type='spark') - ba.emitfx( + bs.emitfx( position=capsule.node.position, velocity=(0, 0, 0), count=int(4.0+random.random()*6), emit_type='tendrils') else: player.capsules += 1 - ba.playsound( - self._collect_sound, - 0.6, - position=capsule.node.position) + self._collect_sound.play(0.6, position=capsule.node.position) # create a flash - light = ba.newnode( + light = bs.newnode( 'light', attrs={ 'position': capsule.node.position, @@ -499,27 +492,27 @@ class CollectorGame(ba.TeamGameActivity[Player, Team]): # Create a short text informing about your inventory self._handle_capsule_storage(player.position, player) - ba.animate(light, 'intensity', { + bs.animate(light, 'intensity', { 0: 0, 0.1: 0.5, 0.2: 0 }, loop=False) - ba.timer(0.2, light.delete) - capsule.handlemessage(ba.DieMessage()) + bs.timer(0.2, light.delete) + capsule.handlemessage(bs.DieMessage()) def _update_player_light(self, player: Player, capsules: int) -> None: if player.light: intensity = 0.04 * capsules - ba.animate(player.light, 'intensity', { + bs.animate(player.light, 'intensity', { 0.0: player.light.intensity, 0.1: intensity }) def newintensity(): player.light.intensity = intensity - ba.timer(0.1, newintensity) + bs.timer(0.1, newintensity) else: - player.light = ba.newnode( + player.light = bs.newnode( 'light', attrs={ 'height_attenuated': False, @@ -558,7 +551,7 @@ class CollectorGame(ba.TeamGameActivity[Player, Team]): self._update_player_light(player, capsules) def handlemessage(self, msg: Any) -> Any: - if isinstance(msg, ba.PlayerDiedMessage): + if isinstance(msg, bs.PlayerDiedMessage): super().handlemessage(msg) # Augment default. # No longer can count as time_at_flag once dead. player = msg.getplayer(Player) @@ -572,7 +565,7 @@ class CollectorGame(ba.TeamGameActivity[Player, Team]): return super().handlemessage(msg) -class Capsule(ba.Actor): +class Capsule(bs.Actor): def __init__(self, position: Sequence[float] = (0.0, 1.0, 0.0), @@ -586,12 +579,12 @@ class Capsule(ba.Actor): self._spawn_pos = (position[0], position[1], position[2]) if lucky: - ba.playsound(activity._lucky_sound, 1.0, self._spawn_pos) + activity._lucky_sound.play(1.0, self._spawn_pos) - self.node = ba.newnode( + self.node = bs.newnode( 'prop', attrs={ - 'model': activity._capsule_model, + 'mesh': activity._capsule_mesh, 'color_texture': activity._capsule_lucky_tex if lucky else ( activity._capsule_tex), 'body': 'crate' if lucky else 'capsule', @@ -606,12 +599,12 @@ class Capsule(ba.Actor): shared.object_material, activity._capsule_material] }, delegate=self) - ba.animate(self.node, 'model_scale', { + bs.animate(self.node, 'mesh_scale', { 0.0: 0.0, 0.1: 0.9 if lucky else 0.6, 0.16: 0.8 if lucky else 0.5 }) - self._light_capsule = ba.newnode( + self._light_capsule = bs.newnode( 'light', attrs={ 'position': self._spawn_pos, @@ -622,16 +615,16 @@ class Capsule(ba.Actor): self.node.connectattr('position', self._light_capsule, 'position') def handlemessage(self, msg: Any): - if isinstance(msg, ba.DieMessage): + if isinstance(msg, bs.DieMessage): self.node.delete() - ba.animate(self._light_capsule, 'intensity', { + bs.animate(self._light_capsule, 'intensity', { 0: 1.0, 0.05: 0.0 }, loop=False) - ba.timer(0.05, self._light_capsule.delete) - elif isinstance(msg, ba.OutOfBoundsMessage): - self.handlemessage(ba.DieMessage()) - elif isinstance(msg, ba.HitMessage): + bs.timer(0.05, self._light_capsule.delete) + elif isinstance(msg, bs.OutOfBoundsMessage): + self.handlemessage(bs.DieMessage()) + elif isinstance(msg, bs.HitMessage): self.node.handlemessage( 'impulse', msg.pos[0], msg.pos[1], msg.pos[2], From a53a312e3f2c446f6db529d84f0295ebb8d5a2ac Mon Sep 17 00:00:00 2001 From: SenjuZoro Date: Sun, 23 Jul 2023 15:53:04 +0000 Subject: [PATCH 16/60] [ci] apply-version-metadata --- plugins/minigames.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index f91eb44..c773c72 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -457,7 +457,12 @@ } ], "versions": { - "2.0.0":null, + "2.0.0": { + "api_version": 8, + "commit_sha": "e8bbb61", + "released_on": "23-07-2023", + "md5sum": "1acbeecffada937bdd745f4e4d43f1be" + }, "1.0.0": { "api_version": 7, "commit_sha": "7219487", @@ -625,4 +630,4 @@ } } } -} +} \ No newline at end of file From fd6c6949f87d3d10db4392e8cbc37c583dee5cd4 Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Sun, 23 Jul 2023 20:33:36 +0200 Subject: [PATCH 17/60] boxing updated Super boxing updated to api 8 --- plugins/minigames/boxing.py | 84 +++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/plugins/minigames/boxing.py b/plugins/minigames/boxing.py index 35a7c75..9208784 100644 --- a/plugins/minigames/boxing.py +++ b/plugins/minigames/boxing.py @@ -1,20 +1,22 @@ -# ba_meta require api 7 +# ba_meta require api 8 # (see https://ballistica.net/wiki/meta-tag-system) from __future__ import annotations from typing import TYPE_CHECKING -import ba -from bastd.actor.playerspaz import PlayerSpaz -from bastd.actor.scoreboard import Scoreboard -from bastd.game.deathmatch import DeathMatchGame +import babase +import bauiv1 as bui +import bascenev1 as bs +from bascenev1lib.actor.playerspaz import PlayerSpaz +from bascenev1lib.actor.scoreboard import Scoreboard +from bascenev1lib.game.deathmatch import DeathMatchGame if TYPE_CHECKING: from typing import Any, Sequence -lang = ba.app.lang.language +lang = bs.app.lang.language if lang == 'Spanish': name = 'Super Boxeo' @@ -33,7 +35,7 @@ else: class NewPlayerSpaz(PlayerSpaz): def __init__(self, - player: ba.Player, + player: bs.Player, color: Sequence[float] = (1.0, 1.0, 1.0), highlight: Sequence[float] = (0.5, 0.5, 0.5), character: str = 'Spaz', @@ -44,16 +46,16 @@ class NewPlayerSpaz(PlayerSpaz): highlight=highlight, character=character, powerups_expire=powerups_expire) - from bastd.gameutils import SharedObjects + from bascenev1lib.gameutils import SharedObjects shared = SharedObjects.get() self._super_jump = super_jump self.jump_mode = False - self.super_jump_material = ba.Material() + self.super_jump_material = bs.Material() self.super_jump_material.add_actions( conditions=('they_have_material', shared.footing_material), actions=( - ('call', 'at_connect', ba.Call(self.jump_state, True)), - ('call', 'at_disconnect', ba.Call(self.jump_state, False)) + ('call', 'at_connect', babase.Call(self.jump_state, True)), + ('call', 'at_disconnect', babase.Call(self.jump_state, False)) ), ) self.node.roller_materials += (self.super_jump_material, ) @@ -68,7 +70,7 @@ class NewPlayerSpaz(PlayerSpaz): """ if not self.node: return - t_ms = ba.time(timeformat=ba.TimeFormat.MILLISECONDS) + t_ms = int(bs.time() * 1000.0) assert isinstance(t_ms, int) if t_ms - self.last_jump_time_ms >= self._jump_cooldown: self.node.jump_pressed = True @@ -81,15 +83,15 @@ class NewPlayerSpaz(PlayerSpaz): self.node.position[0], self.node.position[1], self.node.position[2], - 0, 0, 0, 150, 150, 0, 0, 0, 1, 0 + 0, 0, 0, 95, 95, 0, 0, 0, 1, 0 ) - ba.timer(0.0, do_jump) - ba.timer(0.1, do_jump) - ba.timer(0.2, do_jump) + bs.timer(0.0, do_jump) + bs.timer(0.1, do_jump) + bs.timer(0.2, do_jump) self._turbo_filter_add_press('jump') -# ba_meta export game +# ba_meta export bascenev1.GameActivity class BoxingGame(DeathMatchGame): name = name @@ -97,16 +99,16 @@ class BoxingGame(DeathMatchGame): @classmethod def get_available_settings( - cls, sessiontype: type[ba.Session] - ) -> list[ba.Setting]: + cls, sessiontype: type[bs.Session] + ) -> list[babase.Setting]: settings = [ - ba.IntSetting( + bs.IntSetting( 'Kills to Win Per Player', min_value=1, default=5, increment=1, ), - ba.IntChoiceSetting( + bs.IntChoiceSetting( 'Time Limit', choices=[ ('None', 0), @@ -118,7 +120,7 @@ class BoxingGame(DeathMatchGame): ], default=0, ), - ba.FloatChoiceSetting( + bs.FloatChoiceSetting( 'Respawn Times', choices=[ ('Shorter', 0.25), @@ -129,9 +131,9 @@ class BoxingGame(DeathMatchGame): ], default=1.0, ), - ba.BoolSetting(super_jump_text, default=False), - ba.BoolSetting(enable_powerups, default=False), - ba.BoolSetting('Epic Mode', default=False), + bs.BoolSetting(super_jump_text, default=False), + bs.BoolSetting(enable_powerups, default=False), + bs.BoolSetting('Epic Mode', default=False), ] # In teams mode, a suicide gives a point to the other team, but in @@ -139,9 +141,9 @@ class BoxingGame(DeathMatchGame): # 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): + if issubclass(sessiontype, bs.FreeForAllSession): settings.append( - ba.BoolSetting('Allow Negative Scores', default=False) + bs.BoolSetting('Allow Negative Scores', default=False) ) return settings @@ -150,7 +152,7 @@ class BoxingGame(DeathMatchGame): super().__init__(settings) self._scoreboard = Scoreboard() self._score_to_win: int | None = None - self._dingsound = ba.getsound('dingSmall') + self._dingsound = bs.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']) @@ -163,11 +165,11 @@ class BoxingGame(DeathMatchGame): # 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 + bs.MusicType.EPIC if self._epic_mode else bs.MusicType.TO_THE_DEATH ) def on_begin(self) -> None: - ba.TeamGameActivity.on_begin(self) + bs.TeamGameActivity.on_begin(self) self.setup_standard_time_limit(self._time_limit) if self._enable_powerups: self.setup_standard_powerup_drops() @@ -180,7 +182,7 @@ class BoxingGame(DeathMatchGame): def _standard_drop_powerup(self, index: int, expire: bool = True) -> None: # pylint: disable=cyclic-import - from bastd.actor.powerupbox import PowerupBox, PowerupBoxFactory + from bascenev1lib.actor.powerupbox import PowerupBox, PowerupBoxFactory PowerupBox( position=self.map.powerup_spawn_points[index], @@ -191,13 +193,13 @@ class BoxingGame(DeathMatchGame): expire=expire, ).autoretain() - def spawn_player(self, player: Player) -> ba.Actor: + def spawn_player(self, player: Player) -> bs.Actor: import random - from ba import _math - from ba._gameutils import animate - from ba._coopsession import CoopSession + from babase import _math + from bascenev1._gameutils import animate + from bascenev1._coopsession import CoopSession - if isinstance(self.session, ba.DualTeamSession): + if isinstance(self.session, bs.DualTeamSession): position = self.map.get_start_position(player.team.id) else: # otherwise do free-for-all spawn locations @@ -208,7 +210,7 @@ class BoxingGame(DeathMatchGame): highlight = player.highlight light_color = _math.normalized_color(color) - display_color = ba.safecolor(color, target_intensity=0.75) + display_color = babase.safecolor(color, target_intensity=0.75) spaz = NewPlayerSpaz(color=color, highlight=highlight, @@ -224,14 +226,14 @@ class BoxingGame(DeathMatchGame): # Move to the stand position and add a flash of light. spaz.handlemessage( - ba.StandMessage( + bs.StandMessage( position, angle if angle is not None else random.uniform(0, 360))) - ba.playsound(self._spawn_sound, 1, position=spaz.node.position) - light = ba.newnode('light', attrs={'color': light_color}) + self._spawn_sound.play(1, position=spaz.node.position) + light = bs.newnode('light', attrs={'color': light_color}) spaz.node.connectattr('position', light, 'position') animate(light, 'intensity', {0: 0, 0.25: 1, 0.5: 0}) - ba.timer(0.5, light.delete) + bs.timer(0.5, light.delete) # custom spaz.connect_controls_to_player(enable_bomb=False) From da2f43e266ce1e6f6c896679048bd29c9ea81c4e Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Sun, 23 Jul 2023 20:34:43 +0200 Subject: [PATCH 18/60] Update minigames.json --- plugins/minigames.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index c773c72..7a4e794 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -115,6 +115,7 @@ } ], "versions": { + "2.0.0:null, "1.0.0": { "api_version": 7, "commit_sha": "2fda676", @@ -630,4 +631,4 @@ } } } -} \ No newline at end of file +} From 626387255f7d267c7fac6516941172e4353882fa Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Sun, 23 Jul 2023 20:45:19 +0200 Subject: [PATCH 19/60] Update minigames.json --- plugins/minigames.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index 7a4e794..688f6c2 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -115,7 +115,7 @@ } ], "versions": { - "2.0.0:null, + "2.0.0":null, "1.0.0": { "api_version": 7, "commit_sha": "2fda676", From 522948c26899d72d9bfd98ca07ce6142c4ea9e42 Mon Sep 17 00:00:00 2001 From: SenjuZoro Date: Sun, 23 Jul 2023 18:45:49 +0000 Subject: [PATCH 20/60] [ci] apply-version-metadata --- plugins/minigames.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index 688f6c2..d4b2bec 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -115,7 +115,12 @@ } ], "versions": { - "2.0.0":null, + "2.0.0": { + "api_version": 8, + "commit_sha": "6263872", + "released_on": "23-07-2023", + "md5sum": "9789ad3583f1d92d4e4b7bc03d09591d" + }, "1.0.0": { "api_version": 7, "commit_sha": "2fda676", @@ -631,4 +636,4 @@ } } } -} +} \ No newline at end of file From 9a4eb7a9f5f7e490bdb745079ab1bd175695441a Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Mon, 24 Jul 2023 02:17:59 +0200 Subject: [PATCH 21/60] quake original minigame Bringing back good ol' quake game from 1.4 Now available on latest BS (api 8) --- plugins/minigames/quake_original.py | 616 ++++++++++++++++++++++++++++ 1 file changed, 616 insertions(+) create mode 100644 plugins/minigames/quake_original.py diff --git a/plugins/minigames/quake_original.py b/plugins/minigames/quake_original.py new file mode 100644 index 0000000..6af5849 --- /dev/null +++ b/plugins/minigames/quake_original.py @@ -0,0 +1,616 @@ +# Created By Idk +# Ported to 1.7 by Yan + +# ba_meta require api 8 +from __future__ import annotations + +from typing import TYPE_CHECKING + +from bascenev1lib.actor.powerupbox import PowerupBox as Powerup +from bascenev1lib.actor.playerspaz import PlayerSpaz +from bascenev1lib.actor.scoreboard import Scoreboard +from bascenev1lib.gameutils import SharedObjects + +import bascenev1lib.actor.bomb +import bascenev1lib.actor.spaz +import weakref +import random +import math +import babase +import bauiv1 as bui +import bascenev1 as bs + +if TYPE_CHECKING: + pass + + +class TouchedToSpaz(object): + pass + +class TouchedToAnything(object): + pass + +class TouchedToFootingMaterial(object): + pass + +class QuakeBallFactory(object): + """Components used by QuakeBall stuff + + category: Game Classes + + """ + _STORENAME = babase.storagename() + @classmethod + def get(cls) -> QuakeBallFactory: + """Get/create a shared bascenev1lib.actor.bomb.BombFactory object.""" + activity = bs.getactivity() + factory = activity.customdata.get(cls._STORENAME) + if factory is None: + factory = QuakeBallFactory() + activity.customdata[cls._STORENAME] = factory + assert isinstance(factory, QuakeBallFactory) + return factory + + def __init__(self): + shared = SharedObjects.get() + + self.ball_material = bs.Material() + + self.ball_material.add_actions( + conditions=((('we_are_younger_than', 5), 'or', ('they_are_younger_than', 50)), + 'and', ('they_have_material', shared.object_material)), + actions=(('modify_node_collision', 'collide', False))) + + self.ball_material.add_actions( + conditions=('they_have_material', shared.pickup_material), + actions=(('modify_part_collision', 'use_node_collide', False))) + + self.ball_material.add_actions( + actions=('modify_part_collision', 'friction', 0)) + + self.ball_material.add_actions( + conditions=('they_have_material', shared.player_material), + actions=(('modify_part_collision', 'physical', False), + ('message', 'our_node', 'at_connect', TouchedToSpaz()))) + + self.ball_material.add_actions( + conditions=(('they_dont_have_material', shared.player_material), 'and', + ('they_have_material', shared.object_material)), + actions=('message', 'our_node', 'at_connect', TouchedToAnything())) + + self.ball_material.add_actions( + conditions=(('they_dont_have_material', shared.player_material), 'and', + ('they_have_material', shared.footing_material)), + actions=('message', 'our_node', 'at_connect', TouchedToFootingMaterial())) + + def give(self, spaz): + spaz.punch_callback = self.shot + self.last_shot = int(bs.time() * 1000) + + def shot(self, spaz): + time = int(bs.time() * 1000) + if time - self.last_shot > 0.6: + self.last_shot = time + p1 = spaz.node.position_center + p2 = spaz.node.position_forward + direction = [p1[0]-p2[0], p2[1]-p1[1], p1[2]-p2[2]] + direction[1] = 0.0 + + mag = 10.0/babase.Vec3(*direction).length() + vel = [v * mag for v in direction] + QuakeBall( + position=spaz.node.position, + velocity=(vel[0]*2, vel[1]*2, vel[2]*2), + owner=spaz._player, + source_player=spaz._player, + color=spaz.node.color).autoretain() + + +class QuakeBall(bs.Actor): + + def __init__(self, + position=(0, 5, 0), + velocity=(0, 2, 0), + source_player=None, + owner=None, + color=(random.random(), random.random(), random.random()), + light_radius=0 + ): + super().__init__() + + shared = SharedObjects.get() + b_shared = QuakeBallFactory.get() + + self.source_player = source_player + self.owner = owner + + self.node = bs.newnode('prop', delegate=self, attrs={ + 'position': position, + 'velocity': velocity, + 'mesh': bs.getmesh('impactBomb'), + 'body': 'sphere', + 'color_texture': bs.gettexture('bunnyColor'), + 'mesh_scale': 0.2, + 'is_area_of_interest': True, + 'body_scale': 0.8, + 'materials': [shared.object_material, + b_shared.ball_material]}) + + self.light_node = bs.newnode('light', attrs={ + 'position':position, + 'color': color, + 'radius': 0.1+light_radius, + 'volume_intensity_scale': 15.0}) + + self.node.connectattr('position', self.light_node, 'position') + self.emit_time = bs.Timer(0.015, bs.WeakCall(self.emit), repeat=True) + self.life_time = bs.Timer(5.0, bs.WeakCall(self.handlemessage, bs.DieMessage())) + + def emit(self): + bs.emitfx( + position=self.node.position, + velocity=self.node.velocity, + count=10, + scale=0.4, + spread=0.01, + chunk_type='spark') + + def handlemessage(self, m): + if isinstance(m, TouchedToAnything): + node = bs.getcollision().opposingnode + if node is not None and node.exists(): + v = self.node.velocity + t = self.node.position + hitdir = self.node.velocity + m = self.node + node.handlemessage( + bs.HitMessage( + pos=t, + velocity=v, + magnitude=babase.Vec3(*v).length()*40, + velocity_magnitude=babase.Vec3(*v).length()*40, + radius=0, + srcnode=self.node, + source_player=self.source_player, + force_direction=hitdir)) + + self.node.handlemessage(bs.DieMessage()) + + elif isinstance(m, bs.DieMessage): + if self.node.exists(): + velocity = self.node.velocity + explosion = bs.newnode('explosion', attrs={ + 'position': self.node.position, + 'velocity': (velocity[0], max(-1.0,velocity[1]), velocity[2]), + 'radius': 1, + 'big': False}) + + bs.getsound(random.choice(['impactHard', 'impactHard2', 'impactHard3'])).play(), + position=self.node.position + + self.emit_time = None + self.light_node.delete() + self.node.delete() + + elif isinstance(m, bs.OutOfBoundsMessage): + self.handlemessage(bs.DieMessage()) + + elif isinstance(m, bs.HitMessage): + self.node.handlemessage('impulse', m.pos[0], m.pos[1], m.pos[2], + m.velocity[0], m.velocity[1], m.velocity[2], + 1.0*m.magnitude, 1.0*m.velocity_magnitude, m.radius,0, + m.force_direction[0], m.force_direction[1], m.force_direction[2]) + + elif isinstance(m, TouchedToSpaz): + node = bs.getcollision() .opposingnode + if node is not None and node.exists() and node != self.owner \ + and node.getdelegate(object)._player.team != self.owner.team: + node.handlemessage(bs.FreezeMessage()) + v = self.node.velocity + t = self.node.position + hitdir = self.node.velocity + + node.handlemessage( + bs.HitMessage( + pos=t, + velocity=(10, 10, 10), + magnitude=50, + velocity_magnitude=50, + radius=0, + srcnode=self.node, + source_player=self.source_player, + force_direction=hitdir)) + + self.node.handlemessage(bs.DieMessage()) + + elif isinstance(m, TouchedToFootingMaterial): + bs.getsound('blip').play(), + position=self.node.position + else: + super().handlemessage(m) + + + + +class Player(bs.Player['Team']): + ... + + +class Team(bs.Team[Player]): + """Our team type for this game.""" + + def __init__(self) -> None: + self.score = 0 + +# ba_meta export bascenev1.GameActivity +class QuakeGame(bs.TeamGameActivity[Player, Team]): + """A game type based on acquiring kills.""" + + name = 'Quake' + description = 'Kill a set number of enemies to win.' + + # Print messages when players die since it matters here. + announce_player_deaths = True + + @classmethod + 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[bs.Session]) -> list[str]: + return ['Doom Shroom', 'Monkey Face', 'Football Stadium'] + + @classmethod + def get_available_settings( + cls, sessiontype: type[bs.Session] + ) -> list[babase.Setting]: + settings = [ + bs.IntSetting( + 'Kills to Win Per Player', + min_value=1, + default=5, + increment=1, + ), + bs.IntChoiceSetting( + 'Time Limit', + choices=[ + ('None', 0), + ('1 Minute', 60), + ('2 Minutes', 120), + ('5 Minutes', 300), + ('10 Minutes', 600), + ('20 Minutes', 1200), + ], + default=0, + ), + bs.FloatChoiceSetting( + 'Respawn Times', + choices=[ + ('Shorter', 0.25), + ('Short', 0.5), + ('Normal', 1.0), + ('Long', 2.0), + ('Longer', 4.0), + ], + default=1.0, + ), + bs.IntChoiceSetting( + 'Graphics', + choices=[ + ('Normal', 1), + ('High', 2) + ], + default=1), + bs.BoolSetting('Fast Movespeed', default=True), + bs.BoolSetting('Enable Jump', default=False), + bs.BoolSetting('Enable Pickup', default=False), + bs.BoolSetting('Enable Bomb', default=False), + bs.BoolSetting('Obstacles', default=False), + bs.IntChoiceSetting( + 'Obstacles Shape', + choices=[ + ('Cube', 1), + ('Sphere', 2), + ('Puck', 3), + ('Egg', 4), + ('Random', 5), + ], + default=1), + bs.BoolSetting('Obstacles Bounces Shots', default=False), + bs.IntSetting( + 'Obstacle Count', + min_value=1, + default=16, + increment=1, + ), + bs.BoolSetting('Random Obstacle Color', default=True), + bs.BoolSetting('Epic Mode', default=False), + ] + return settings + + def __init__(self, settings: dict): + super().__init__(settings) + self._scoreboard = Scoreboard() + self._score_to_win: int | None = None + self._dingsound = bs.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 = ( + bs.MusicType.EPIC if self._epic_mode else bs.MusicType.TO_THE_DEATH + ) + self.settings = settings + + def get_instance_description(self) -> str | Sequence: + return 'Crush ${ARG1} of your enemies.', self._score_to_win + + def get_instance_description_short(self) -> str | Sequence: + return 'kill ${ARG1} enemies', self._score_to_win + + def on_team_join(self, team: Team) -> None: + if self.has_begun(): + self._update_scoreboard() + + def on_begin(self) -> None: + super().on_begin() + self.dingsound = bs.getsound('dingSmall') + self.setup_standard_time_limit(self._time_limit) + + self.drop_shield() + self.drop_shield_timer = bs.Timer(8.001, bs.WeakCall(self.drop_shield), repeat=True) + + shared = SharedObjects.get() + if self.settings['Obstacles']: + count = self.settings['Obstacle Count'] + map = bs.getactivity()._map.getname() + for i in range(count): + if map == 'Football Stadium': + radius = (random.uniform(-10, 1), + 6, + random.uniform(-4.5, 4.5)) \ + if i > count/2 else (random.uniform(10, 1), 6, random.uniform(-4.5, 4.5)) + else: + radius = (random.uniform(-10,1), + 6, + random.uniform(-8,8)) \ + if i > count/2 else (random.uniform(10, 1), 6, random.uniform(-8, 8)) + + Obstacle( + position=radius, + graphics=self.settings['Graphics'], + random_color=self.settings['Random Obstacle Color'], + rebound=self.settings['Obstacles Bounces Shots'], + shape=int(self.settings['Obstacles Shape'])).autoretain() + + if self.settings['Graphics'] == 2: + bs.getactivity().globalsnode.tint = (bs.getactivity().globalsnode.tint[0]-0.6, bs.getactivity().globalsnode.tint[1]-0.6, bs.getactivity().globalsnode.tint[2]-0.6) + light = bs.newnode('light', attrs={ + 'position': (9, 10, 0) if map == 'Football Stadium' else (6, 7, -2) \ + if not map == 'Rampage' else (6, 11, -2) if not map == 'The Pad' else (6, 8.5, -2), + 'color': (0.4, 0.4, 0.45), + 'radius': 1, + 'intensity': 6, + 'volume_intensity_scale': 10.0}) + + light2 = bs.newnode('light', attrs={ + 'position': (-9, 10, 0) if map == 'Football Stadium' else (-6, 7, -2) \ + if not map == 'Rampage' else (-6, 11, -2) if not map == 'The Pad' else (-6, 8.5, -2), + 'color': (0.4, 0.4, 0.45), + 'radius': 1, + 'intensity': 6, + 'volume_intensity_scale': 10.0}) + + if len(self.teams) > 0: + self._score_to_win = self.settings['Kills to Win Per Player']*max(1, max(len(t.players) for t in self.teams)) + else: + self._score_to_win = self.settings['Kills to Win Per Player'] + self._update_scoreboard() + + def drop_shield(self): + p = Powerup( + poweruptype='shield', + position=(random.uniform(-10, 10), 6, random.uniform(-5, 5))).autoretain() + + bs.getsound('dingSmall').play() + + p_light = bs.newnode('light', attrs={ + 'position': (0, 0, 0), + 'color': (0.3, 0.0, 0.4), + 'radius': 0.3, + 'intensity': 2, + 'volume_intensity_scale': 10.0}) + + p.node.connectattr('position', p_light, 'position') + + bs.animate(p_light, 'intensity', {0: 2, 8000: 0}) + + def check_exists(): + if p is None or p.node.exists() == False: + delete_light() + del_checker() + + self._checker = bs.Timer(0.1,babase.Call(check_exists), repeat=True) + + def del_checker(): + if self._checker is not None: + self._checker = None + + def delete_light(): + if p_light.exists(): + p_light.delete() + + bs.timer(6.9, babase.Call(del_checker)) + bs.timer(7.0, babase.Call(delete_light)) + + def spawn_player(self, player: bs.Player): + spaz = self.spawn_player_spaz(player) + QuakeBallFactory().give(spaz) + spaz.connect_controls_to_player( + enable_jump=self.settings['Enable Jump'], + enable_punch=True, + enable_pickup=self.settings['Enable Pickup'], + enable_bomb=self.settings['Enable Bomb'], + enable_run=True, + enable_fly=False) + + if self.settings['Fast Movespeed']: spaz.node.hockey = True + spaz.spaz_light = bs.newnode('light', attrs={ + 'position': (0, 0, 0), + 'color': spaz.node.color, + 'radius': 0.12, + 'intensity': 1, + 'volume_intensity_scale': 10.0}) + + spaz.node.connectattr('position', spaz.spaz_light, 'position') + + def handlemessage(self, msg: Any) -> Any: + + if isinstance(msg, bs.PlayerDiedMessage): + + # Augment standard behavior. + super().handlemessage(msg) + + player = msg.getplayer(Player) + self.respawn_player(player) + + killer = msg.getkillerplayer(Player) + if hasattr(player.actor, 'spaz_light'): + player.actor.spaz_light.delete() + 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, bs.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: + self._dingsound.play() + 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 + self._dingsound.play() + + # 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): + bs.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 = bs.GameResults() + for team in self.teams: + results.set_team_score(team, team.score) + self.end(results=results) + +class Obstacle(bs.Actor): + + def __init__(self, + position: tuple(float, float, float), + graphics: bool, + random_color: bool, + rebound: bool, + shape: int) -> None: + super().__init__() + + shared = SharedObjects.get() + if shape == 1: + mesh = 'tnt' + body = 'crate' + elif shape == 2: + mesh = 'bomb' + body = 'sphere' + elif shape == 3: + mesh = 'puck' + body = 'puck' + elif shape == 4: + mesh = 'egg' + body = 'capsule' + elif shape == 5: + pair = random.choice([ + {'mesh':'tnt', 'body':'crate'}, + {'mesh':'bomb', 'body':'sphere'}, + {'mesh':'puckModel', 'body':'puck'}, + {'mesh':'egg', 'body':'capsule'} + ]) + mesh = pair['mesh'] + body = pair['body'] + + self.node = bs.newnode('prop', delegate=self, attrs={ + 'position': position, + 'mesh': bs.getmesh(mesh), + 'body': body, + 'body_scale': 1.3, + 'mesh_scale': 1.3, + 'reflection': 'powerup', + 'reflection_scale': [0.7], + 'color_texture': bs.gettexture('bunnyColor'), + 'materials': [shared.footing_material if rebound else shared.object_material, + shared.footing_material]}) + + if graphics == 2: + self.light_node = bs.newnode('light', attrs={ + 'position': (0, 0, 0), + 'color': ((0.8, 0.2, 0.2) if i < count/2 else (0.2, 0.2, 0.8)) \ + if not random_color else ((random.uniform(0, 1.1), random.uniform(0, 1.1), random.uniform(0, 1.1))), + 'radius': 0.2, + 'intensity': 1, + 'volume_intensity_scale': 10.0}) + + self.node.connectattr('position', self.light_node, 'position') + + def handlemessage(self, m): + if isinstance(m, bs.DieMessage): + if self.node.exists(): + if hasattr(self, 'light_node'): + self.light_node.delete() + self.node.delete() + + elif isinstance(m, bs.OutOfBoundsMessage): + if self.node.exists(): + self.handlemessage(bs.DieMessage()) + + elif isinstance(m, bs.HitMessage): + self.node.handlemessage('impulse', m.pos[0], m.pos[1], m.pos[2], + m.velocity[0], m.velocity[1], m.velocity[2], + m.magnitude, m.velocity_magnitude, m.radius,0, + m.velocity[0], m.velocity[1], m.velocity[2]) \ No newline at end of file From 12d51c3b1d7569bf5958b0432cbf8be2f5b81b09 Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Mon, 24 Jul 2023 02:23:09 +0200 Subject: [PATCH 22/60] Update minigames.json --- plugins/minigames.json | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index d4b2bec..03ec0b3 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -597,6 +597,21 @@ } } }, + "quake_original": { + "description": "Good ol' Quake minigame", + "external_url": "", + "authors": [ + { + "name": "Unknown", + "email": "", + "discord": "" + } + ], + "versions": { + "1.0.0":null + } + } + }, "ufo_fight": { "description": "Fight the UFO boss!", "external_url": "", @@ -636,4 +651,4 @@ } } } -} \ No newline at end of file +} From 2b046cb433db749abd8380dd89fa5beacaea9bf8 Mon Sep 17 00:00:00 2001 From: SenjuZoro Date: Mon, 24 Jul 2023 00:25:32 +0000 Subject: [PATCH 23/60] [ci] auto-format --- plugins/minigames/quake_original.py | 82 ++++++++++++++++------------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/plugins/minigames/quake_original.py b/plugins/minigames/quake_original.py index 6af5849..84ff0f6 100644 --- a/plugins/minigames/quake_original.py +++ b/plugins/minigames/quake_original.py @@ -27,19 +27,23 @@ if TYPE_CHECKING: class TouchedToSpaz(object): pass + class TouchedToAnything(object): pass + class TouchedToFootingMaterial(object): pass + class QuakeBallFactory(object): """Components used by QuakeBall stuff - + category: Game Classes - + """ _STORENAME = babase.storagename() + @classmethod def get(cls) -> QuakeBallFactory: """Get/create a shared bascenev1lib.actor.bomb.BombFactory object.""" @@ -50,7 +54,7 @@ class QuakeBallFactory(object): activity.customdata[cls._STORENAME] = factory assert isinstance(factory, QuakeBallFactory) return factory - + def __init__(self): shared = SharedObjects.get() @@ -58,7 +62,7 @@ class QuakeBallFactory(object): self.ball_material.add_actions( conditions=((('we_are_younger_than', 5), 'or', ('they_are_younger_than', 50)), - 'and', ('they_have_material', shared.object_material)), + 'and', ('they_have_material', shared.object_material)), actions=(('modify_node_collision', 'collide', False))) self.ball_material.add_actions( @@ -81,7 +85,7 @@ class QuakeBallFactory(object): self.ball_material.add_actions( conditions=(('they_dont_have_material', shared.player_material), 'and', ('they_have_material', shared.footing_material)), - actions=('message', 'our_node', 'at_connect', TouchedToFootingMaterial())) + actions=('message', 'our_node', 'at_connect', TouchedToFootingMaterial())) def give(self, spaz): spaz.punch_callback = self.shot @@ -115,7 +119,7 @@ class QuakeBall(bs.Actor): owner=None, color=(random.random(), random.random(), random.random()), light_radius=0 - ): + ): super().__init__() shared = SharedObjects.get() @@ -137,7 +141,7 @@ class QuakeBall(bs.Actor): b_shared.ball_material]}) self.light_node = bs.newnode('light', attrs={ - 'position':position, + 'position': position, 'color': color, 'radius': 0.1+light_radius, 'volume_intensity_scale': 15.0}) @@ -181,12 +185,12 @@ class QuakeBall(bs.Actor): velocity = self.node.velocity explosion = bs.newnode('explosion', attrs={ 'position': self.node.position, - 'velocity': (velocity[0], max(-1.0,velocity[1]), velocity[2]), + 'velocity': (velocity[0], max(-1.0, velocity[1]), velocity[2]), 'radius': 1, 'big': False}) bs.getsound(random.choice(['impactHard', 'impactHard2', 'impactHard3'])).play(), - position=self.node.position + position = self.node.position self.emit_time = None self.light_node.delete() @@ -198,7 +202,7 @@ class QuakeBall(bs.Actor): elif isinstance(m, bs.HitMessage): self.node.handlemessage('impulse', m.pos[0], m.pos[1], m.pos[2], m.velocity[0], m.velocity[1], m.velocity[2], - 1.0*m.magnitude, 1.0*m.velocity_magnitude, m.radius,0, + 1.0*m.magnitude, 1.0*m.velocity_magnitude, m.radius, 0, m.force_direction[0], m.force_direction[1], m.force_direction[2]) elif isinstance(m, TouchedToSpaz): @@ -225,13 +229,11 @@ class QuakeBall(bs.Actor): elif isinstance(m, TouchedToFootingMaterial): bs.getsound('blip').play(), - position=self.node.position + position = self.node.position else: super().handlemessage(m) - - class Player(bs.Player['Team']): ... @@ -243,6 +245,8 @@ class Team(bs.Team[Player]): self.score = 0 # ba_meta export bascenev1.GameActivity + + class QuakeGame(bs.TeamGameActivity[Player, Team]): """A game type based on acquiring kills.""" @@ -376,12 +380,12 @@ class QuakeGame(bs.TeamGameActivity[Player, Team]): radius = (random.uniform(-10, 1), 6, random.uniform(-4.5, 4.5)) \ - if i > count/2 else (random.uniform(10, 1), 6, random.uniform(-4.5, 4.5)) + if i > count/2 else (random.uniform(10, 1), 6, random.uniform(-4.5, 4.5)) else: - radius = (random.uniform(-10,1), + radius = (random.uniform(-10, 1), 6, - random.uniform(-8,8)) \ - if i > count/2 else (random.uniform(10, 1), 6, random.uniform(-8, 8)) + random.uniform(-8, 8)) \ + if i > count/2 else (random.uniform(10, 1), 6, random.uniform(-8, 8)) Obstacle( position=radius, @@ -391,26 +395,28 @@ class QuakeGame(bs.TeamGameActivity[Player, Team]): shape=int(self.settings['Obstacles Shape'])).autoretain() if self.settings['Graphics'] == 2: - bs.getactivity().globalsnode.tint = (bs.getactivity().globalsnode.tint[0]-0.6, bs.getactivity().globalsnode.tint[1]-0.6, bs.getactivity().globalsnode.tint[2]-0.6) + bs.getactivity().globalsnode.tint = (bs.getactivity( + ).globalsnode.tint[0]-0.6, bs.getactivity().globalsnode.tint[1]-0.6, bs.getactivity().globalsnode.tint[2]-0.6) light = bs.newnode('light', attrs={ - 'position': (9, 10, 0) if map == 'Football Stadium' else (6, 7, -2) \ - if not map == 'Rampage' else (6, 11, -2) if not map == 'The Pad' else (6, 8.5, -2), + 'position': (9, 10, 0) if map == 'Football Stadium' else (6, 7, -2) + if not map == 'Rampage' else (6, 11, -2) if not map == 'The Pad' else (6, 8.5, -2), 'color': (0.4, 0.4, 0.45), 'radius': 1, 'intensity': 6, 'volume_intensity_scale': 10.0}) light2 = bs.newnode('light', attrs={ - 'position': (-9, 10, 0) if map == 'Football Stadium' else (-6, 7, -2) \ - if not map == 'Rampage' else (-6, 11, -2) if not map == 'The Pad' else (-6, 8.5, -2), + 'position': (-9, 10, 0) if map == 'Football Stadium' else (-6, 7, -2) + if not map == 'Rampage' else (-6, 11, -2) if not map == 'The Pad' else (-6, 8.5, -2), 'color': (0.4, 0.4, 0.45), 'radius': 1, 'intensity': 6, 'volume_intensity_scale': 10.0}) if len(self.teams) > 0: - self._score_to_win = self.settings['Kills to Win Per Player']*max(1, max(len(t.players) for t in self.teams)) - else: + self._score_to_win = self.settings['Kills to Win Per Player'] * \ + max(1, max(len(t.players) for t in self.teams)) + else: self._score_to_win = self.settings['Kills to Win Per Player'] self._update_scoreboard() @@ -437,7 +443,7 @@ class QuakeGame(bs.TeamGameActivity[Player, Team]): delete_light() del_checker() - self._checker = bs.Timer(0.1,babase.Call(check_exists), repeat=True) + self._checker = bs.Timer(0.1, babase.Call(check_exists), repeat=True) def del_checker(): if self._checker is not None: @@ -461,7 +467,8 @@ class QuakeGame(bs.TeamGameActivity[Player, Team]): enable_run=True, enable_fly=False) - if self.settings['Fast Movespeed']: spaz.node.hockey = True + if self.settings['Fast Movespeed']: + spaz.node.hockey = True spaz.spaz_light = bs.newnode('light', attrs={ 'position': (0, 0, 0), 'color': spaz.node.color, @@ -542,6 +549,7 @@ class QuakeGame(bs.TeamGameActivity[Player, Team]): results.set_team_score(team, team.score) self.end(results=results) + class Obstacle(bs.Actor): def __init__(self, @@ -553,7 +561,7 @@ class Obstacle(bs.Actor): super().__init__() shared = SharedObjects.get() - if shape == 1: + if shape == 1: mesh = 'tnt' body = 'crate' elif shape == 2: @@ -567,11 +575,11 @@ class Obstacle(bs.Actor): body = 'capsule' elif shape == 5: pair = random.choice([ - {'mesh':'tnt', 'body':'crate'}, - {'mesh':'bomb', 'body':'sphere'}, - {'mesh':'puckModel', 'body':'puck'}, - {'mesh':'egg', 'body':'capsule'} - ]) + {'mesh': 'tnt', 'body': 'crate'}, + {'mesh': 'bomb', 'body': 'sphere'}, + {'mesh': 'puckModel', 'body': 'puck'}, + {'mesh': 'egg', 'body': 'capsule'} + ]) mesh = pair['mesh'] body = pair['body'] @@ -587,11 +595,11 @@ class Obstacle(bs.Actor): 'materials': [shared.footing_material if rebound else shared.object_material, shared.footing_material]}) - if graphics == 2: + if graphics == 2: self.light_node = bs.newnode('light', attrs={ 'position': (0, 0, 0), - 'color': ((0.8, 0.2, 0.2) if i < count/2 else (0.2, 0.2, 0.8)) \ - if not random_color else ((random.uniform(0, 1.1), random.uniform(0, 1.1), random.uniform(0, 1.1))), + 'color': ((0.8, 0.2, 0.2) if i < count/2 else (0.2, 0.2, 0.8)) + if not random_color else ((random.uniform(0, 1.1), random.uniform(0, 1.1), random.uniform(0, 1.1))), 'radius': 0.2, 'intensity': 1, 'volume_intensity_scale': 10.0}) @@ -612,5 +620,5 @@ class Obstacle(bs.Actor): elif isinstance(m, bs.HitMessage): self.node.handlemessage('impulse', m.pos[0], m.pos[1], m.pos[2], m.velocity[0], m.velocity[1], m.velocity[2], - m.magnitude, m.velocity_magnitude, m.radius,0, - m.velocity[0], m.velocity[1], m.velocity[2]) \ No newline at end of file + m.magnitude, m.velocity_magnitude, m.radius, 0, + m.velocity[0], m.velocity[1], m.velocity[2]) From 185480da2980e86979cde24daf6bd0791b5ec99e Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Mon, 24 Jul 2023 02:30:29 +0200 Subject: [PATCH 24/60] Update minigames.json --- plugins/minigames.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index 03ec0b3..b4fd626 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -651,4 +651,4 @@ } } } -} + From 42c05fae0a00dbccffa75731b37cd597bfddf1c1 Mon Sep 17 00:00:00 2001 From: SenjuZoro Date: Mon, 24 Jul 2023 00:30:58 +0000 Subject: [PATCH 25/60] [ci] apply-version-metadata --- plugins/minigames.json | 82 ++++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index b4fd626..510551e 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -607,48 +607,52 @@ "discord": "" } ], - "versions": { - "1.0.0":null - } - } - }, - "ufo_fight": { - "description": "Fight the UFO boss!", - "external_url": "", - "authors": [ - { - "name": "Cross Joy", - "email": "cross.joy.official@gmail.com", - "discord": "Cross Joy#0721" - } - ], "versions": { "1.0.0": { - "api_version": 7, - "commit_sha": "7219487", - "released_on": "15-05-2023", - "md5sum": "81617b130716996368b7d8f20f3a5154" - } - } - }, - "yeeting_party": { - "description": "Yeet your enemies out of the map!", - "external_url": "", - "authors": [ - { - "name": "Freaku", - "email": "", - "discord": "[Just] Freak#4999" - } - ], - "versions": { - "1.0.0": { - "api_version": 7, - "commit_sha": "7219487", - "released_on": "15-05-2023", - "md5sum": "197a377652ab0c3bfbe1ca07833924b4" + "api_version": 8, + "commit_sha": "185480d", + "released_on": "24-07-2023", + "md5sum": "f68395cc90dc8cddb166a23b2da81b7b" } } } + }, + "ufo_fight": { + "description": "Fight the UFO boss!", + "external_url": "", + "authors": [ + { + "name": "Cross Joy", + "email": "cross.joy.official@gmail.com", + "discord": "Cross Joy#0721" + } + ], + "versions": { + "1.0.0": { + "api_version": 7, + "commit_sha": "7219487", + "released_on": "15-05-2023", + "md5sum": "81617b130716996368b7d8f20f3a5154" + } + } + }, + "yeeting_party": { + "description": "Yeet your enemies out of the map!", + "external_url": "", + "authors": [ + { + "name": "Freaku", + "email": "", + "discord": "[Just] Freak#4999" + } + ], + "versions": { + "1.0.0": { + "api_version": 7, + "commit_sha": "7219487", + "released_on": "15-05-2023", + "md5sum": "197a377652ab0c3bfbe1ca07833924b4" + } + } } - +} \ No newline at end of file From 07f9ac7251126eec91e4943773d626a1344081de Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Mon, 24 Jul 2023 12:25:05 +0200 Subject: [PATCH 26/60] SuperSmash minigame SuperSmash minigame updated to api 8 Note: the file consist of 2 modes --> SuperSmash: Deathmatch based supersmash --> SuperSmash Elimination: Elimination based supersmash --- plugins/minigames/SuperSmash.py | 954 ++++++++++++++++++++++++++++++++ 1 file changed, 954 insertions(+) create mode 100644 plugins/minigames/SuperSmash.py diff --git a/plugins/minigames/SuperSmash.py b/plugins/minigames/SuperSmash.py new file mode 100644 index 0000000..2ffb589 --- /dev/null +++ b/plugins/minigames/SuperSmash.py @@ -0,0 +1,954 @@ +# To learn more, see https://ballistica.net/wiki/meta-tag-system +# ba_meta require api 8 + +from __future__ import annotations + +from typing import TYPE_CHECKING + +import babase +import random +import bauiv1 as bui +import bascenev1 as bs +from babase import _math +from bascenev1lib.actor.spaz import Spaz +from bascenev1lib.actor.spazfactory import SpazFactory +from bascenev1lib.actor.scoreboard import Scoreboard +from bascenev1lib.game import elimination +from bascenev1lib.game.elimination import Icon, Player, Team +from bascenev1lib.actor.bomb import Bomb, Blast +from bascenev1lib.actor.playerspaz import PlayerSpaz, PlayerSpazHurtMessage + +if TYPE_CHECKING: + from typing import Any, Type, List, Sequence, Optional + + +class Icon(Icon): + 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 > 1: + 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 + +class PowBox(Bomb): + + def __init__(self, + position: Sequence[float] = (0.0, 1.0, 0.0), + velocity: Sequence[float] = (0.0, 0.0, 0.0)) -> None: + Bomb.__init__(self, + position, + velocity, + bomb_type='tnt', + blast_radius=2.5, + source_player=None, + owner=None) + self.set_pow_text() + + def set_pow_text(self) -> None: + m = bs.newnode('math', + owner=self.node, + attrs={'input1': (0, 0.7, 0), + 'operation': 'add'}) + self.node.connectattr('position', m, 'input2') + + self._pow_text = bs.newnode('text', + owner=self.node, + attrs={'text':'POW!', + 'in_world': True, + 'shadow': 1.0, + 'flatness': 1.0, + 'color': (1, 1, 0.4), + 'scale':0.0, + 'h_align':'center'}) + m.connectattr('output', self._pow_text, 'position') + bs.animate(self._pow_text, 'scale', {0: 0.0, 1.0: 0.01}) + + def pow(self) -> None: + self.explode() + + def handlemessage(self, m: Any) -> Any: + if isinstance(m, babase.PickedUpMessage): + self._heldBy = m.node + elif isinstance(m, bs.DroppedMessage): + bs.timer(0.6, self.pow) + Bomb.handlemessage(self, m) + +class SSPlayerSpaz(PlayerSpaz): + multiplyer = 1 + is_dead = False + + def oob_effect(self) -> None: + if self.is_dead: + return + self.is_dead = True + if self.multiplyer > 1.25: + blast_type = 'tnt' + radius = min(self.multiplyer * 5, 20) + else: + # penalty for killing people with low multiplyer + blast_type = 'ice' + radius = 7.5 + Blast(position=self.node.position, + blast_radius=radius, + blast_type=blast_type).autoretain() + + def handlemessage(self, msg: Any) -> Any: + if isinstance(msg, bs.HitMessage): + if not self.node: + return None + if self.node.invincible: + SpazFactory.get().block_sound.play(1.0, position=self.node.position) + return True + + # If we were recently hit, don't count this as another. + # (so punch flurries and bomb pileups essentially count as 1 hit) + local_time = int(bs.time() * 1000) + assert isinstance(local_time, int) + if (self._last_hit_time is None + or local_time - self._last_hit_time > 1000): + self._num_times_hit += 1 + self._last_hit_time = local_time + + mag = msg.magnitude * self.impact_scale + velocity_mag = msg.velocity_magnitude * self.impact_scale + damage_scale = 0.22 + + # If they've got a shield, deliver it to that instead. + if self.shield: + if msg.flat_damage: + damage = msg.flat_damage * self.impact_scale + else: + # Hit our spaz with an impulse but tell it to only return + # theoretical damage; not apply the impulse. + assert msg.force_direction is not None + self.node.handlemessage( + 'impulse', msg.pos[0], msg.pos[1], msg.pos[2], + msg.velocity[0], msg.velocity[1], msg.velocity[2], mag, + velocity_mag, msg.radius, 1, msg.force_direction[0], + msg.force_direction[1], msg.force_direction[2]) + damage = damage_scale * self.node.damage + + assert self.shield_hitpoints is not None + self.shield_hitpoints -= int(damage) + self.shield.hurt = ( + 1.0 - + float(self.shield_hitpoints) / self.shield_hitpoints_max) + + # Its a cleaner event if a hit just kills the shield + # without damaging the player. + # However, massive damage events should still be able to + # damage the player. This hopefully gives us a happy medium. + max_spillover = SpazFactory.get().max_shield_spillover_damage + if self.shield_hitpoints <= 0: + + # FIXME: Transition out perhaps? + self.shield.delete() + self.shield = None + SpazFactory.get().shield_down_sound.play(1.0, position=self.node.position) + + # Emit some cool looking sparks when the shield dies. + npos = self.node.position + bs.emitfx(position=(npos[0], npos[1] + 0.9, npos[2]), + velocity=self.node.velocity, + count=random.randrange(20, 30), + scale=1.0, + spread=0.6, + chunk_type='spark') + + else: + SpazFactory.get().shield_hit_sound.play(0.5, position=self.node.position) + + # Emit some cool looking sparks on shield hit. + assert msg.force_direction is not None + bs.emitfx(position=msg.pos, + velocity=(msg.force_direction[0] * 1.0, + msg.force_direction[1] * 1.0, + msg.force_direction[2] * 1.0), + count=min(30, 5 + int(damage * 0.005)), + scale=0.5, + spread=0.3, + chunk_type='spark') + + # If they passed our spillover threshold, + # pass damage along to spaz. + if self.shield_hitpoints <= -max_spillover: + leftover_damage = -max_spillover - self.shield_hitpoints + shield_leftover_ratio = leftover_damage / damage + + # Scale down the magnitudes applied to spaz accordingly. + mag *= shield_leftover_ratio + velocity_mag *= shield_leftover_ratio + else: + return True # Good job shield! + else: + shield_leftover_ratio = 1.0 + + if msg.flat_damage: + damage = int(msg.flat_damage * self.impact_scale * + shield_leftover_ratio) + else: + # Hit it with an impulse and get the resulting damage. + assert msg.force_direction is not None + self.node.handlemessage( + 'impulse', msg.pos[0], msg.pos[1], msg.pos[2], + msg.velocity[0], msg.velocity[1], msg.velocity[2], mag, + velocity_mag, msg.radius, 0, msg.force_direction[0], + msg.force_direction[1], msg.force_direction[2]) + + damage = int(damage_scale * self.node.damage) + self.node.handlemessage('hurt_sound') + + # Play punch impact sound based on damage if it was a punch. + if msg.hit_type == 'punch': + self.on_punched(damage) + + # If damage was significant, lets show it. + # if damage > 350: + # assert msg.force_direction is not None + # babase.show_damage_count('-' + str(int(damage / 10)) + '%', + # msg.pos, msg.force_direction) + + # Let's always add in a super-punch sound with boxing + # gloves just to differentiate them. + if msg.hit_subtype == 'super_punch': + SpazFactory.get().punch_sound_stronger.play(1.0, position=self.node.position) + if damage > 500: + sounds = SpazFactory.get().punch_sound_strong + sound = sounds[random.randrange(len(sounds))] + else: + sound = SpazFactory.get().punch_sound + sound.play(1.0, position=self.node.position) + + # Throw up some chunks. + assert msg.force_direction is not None + bs.emitfx(position=msg.pos, + velocity=(msg.force_direction[0] * 0.5, + msg.force_direction[1] * 0.5, + msg.force_direction[2] * 0.5), + count=min(10, 1 + int(damage * 0.0025)), + scale=0.3, + spread=0.03) + + bs.emitfx(position=msg.pos, + chunk_type='sweat', + velocity=(msg.force_direction[0] * 1.3, + msg.force_direction[1] * 1.3 + 5.0, + msg.force_direction[2] * 1.3), + count=min(30, 1 + int(damage * 0.04)), + scale=0.9, + spread=0.28) + + # Momentary flash. + hurtiness = damage * 0.003 + punchpos = (msg.pos[0] + msg.force_direction[0] * 0.02, + msg.pos[1] + msg.force_direction[1] * 0.02, + msg.pos[2] + msg.force_direction[2] * 0.02) + flash_color = (1.0, 0.8, 0.4) + light = bs.newnode( + 'light', + attrs={ + 'position': punchpos, + 'radius': 0.12 + hurtiness * 0.12, + 'intensity': 0.3 * (1.0 + 1.0 * hurtiness), + 'height_attenuated': False, + 'color': flash_color + }) + bs.timer(0.06, light.delete) + + flash = bs.newnode('flash', + attrs={ + 'position': punchpos, + 'size': 0.17 + 0.17 * hurtiness, + 'color': flash_color + }) + bs.timer(0.06, flash.delete) + + if msg.hit_type == 'impact': + assert msg.force_direction is not None + bs.emitfx(position=msg.pos, + velocity=(msg.force_direction[0] * 2.0, + msg.force_direction[1] * 2.0, + msg.force_direction[2] * 2.0), + count=min(10, 1 + int(damage * 0.01)), + scale=0.4, + spread=0.1) + if self.hitpoints > 0: + + # It's kinda crappy to die from impacts, so lets reduce + # impact damage by a reasonable amount *if* it'll keep us alive + if msg.hit_type == 'impact' and damage > self.hitpoints: + # Drop damage to whatever puts us at 10 hit points, + # or 200 less than it used to be whichever is greater + # (so it *can* still kill us if its high enough) + newdamage = max(damage - 200, self.hitpoints - 10) + damage = newdamage + self.node.handlemessage('flash') + + # If we're holding something, drop it. + if damage > 0.0 and self.node.hold_node: + self.node.hold_node = None + # self.hitpoints -= damage + self.multiplyer += min(damage / 2000, 0.15) + if damage/2000 > 0.05: + self.set_score_text(str(int((self.multiplyer-1)*100))+'%') + # self.node.hurt = 1.0 - float( + # self.hitpoints) / self.hitpoints_max + self.node.hurt = 0.0 + + # If we're cursed, *any* damage blows us up. + if self._cursed and damage > 0: + bs.timer( + 0.05, + bs.WeakCall(self.curse_explode, + msg.get_source_player(bs.Player))) + + # If we're frozen, shatter.. otherwise die if we hit zero + # if self.frozen and (damage > 200 or self.hitpoints <= 0): + # self.shatter() + # elif self.hitpoints <= 0: + # self.node.handlemessage( + # bs.DieMessage(how=babase.DeathType.IMPACT)) + + # If we're dead, take a look at the smoothed damage value + # (which gives us a smoothed average of recent damage) and shatter + # us if its grown high enough. + # if self.hitpoints <= 0: + # damage_avg = self.node.damage_smoothed * damage_scale + # if damage_avg > 1000: + # self.shatter() + + source_player = msg.get_source_player(type(self._player)) + if source_player: + self.last_player_attacked_by = source_player + self.last_attacked_time = bs.time() + self.last_attacked_type = (msg.hit_type, msg.hit_subtype) + Spaz.handlemessage(self, bs.HitMessage) # Augment standard behavior. + activity = self._activity() + if activity is not None and self._player.exists(): + activity.handlemessage(PlayerSpazHurtMessage(self)) + + elif isinstance(msg, bs.DieMessage): + self.oob_effect() + super().handlemessage(msg) + elif isinstance(msg, bs.PowerupMessage): + if msg.poweruptype == 'health': + if self.multiplyer > 2: + self.multiplyer *= 0.5 + else: + self.multiplyer *= 0.75 + self.multiplyer = max(1, self.multiplyer) + self.set_score_text(str(int((self.multiplyer-1)*100))+"%") + super().handlemessage(msg) + else: + super().handlemessage(msg) + + +class Player(bs.Player['Team']): + """Our player type for this game.""" + + +class Team(bs.Team[Player]): + """Our team type for this game.""" + + def __init__(self) -> None: + self.score = 0 + + +# ba_meta export bascenev1.GameActivity +class SuperSmash(bs.TeamGameActivity[Player, Team]): + + name = 'Super Smash' + description = 'Knock everyone off the map.' + + # Print messages when players die since it matters here. + announce_player_deaths = True + + @classmethod + def get_available_settings( + cls, sessiontype: Type[bs.Session]) -> List[babase.Setting]: + settings = [ + bs.IntSetting( + 'Kills to Win Per Player', + min_value=1, + default=5, + increment=1, + ), + bs.IntChoiceSetting( + 'Time Limit', + choices=[ + ('None', 0), + ('1 Minute', 60), + ('2 Minutes', 120), + ('5 Minutes', 300), + ('10 Minutes', 600), + ('20 Minutes', 1200), + ], + default=0, + ), + bs.FloatChoiceSetting( + 'Respawn Times', + choices=[ + ('Shorter', 0.25), + ('Short', 0.5), + ('Normal', 1.0), + ('Long', 2.0), + ('Longer', 4.0), + ], + default=1.0, + ), + bs.BoolSetting('Boxing Gloves', default=False), + bs.BoolSetting('Epic Mode', default=False), + ] + if issubclass(sessiontype, bs.FreeForAllSession): + settings.append( + bs.BoolSetting('Allow Negative Scores', default=False)) + return settings + + @classmethod + 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[bs.Session]) -> List[str]: + maps = bs.app.classic.getmaps('melee') + for m in ['Lake Frigid', 'Hockey Stadium', 'Football Stadium']: + # remove maps without bounds + maps.remove(m) + return maps + + def __init__(self, settings: dict): + super().__init__(settings) + self._scoreboard = Scoreboard() + self._score_to_win: int | None = None + self._dingsound = bs.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)) + self._boxing_gloves = bool(settings['Boxing Gloves']) + + # Base class overrides. + self.slow_motion = self._epic_mode + self.default_music = (bs.MusicType.EPIC if self._epic_mode else + bs.MusicType.SURVIVAL) + + def get_instance_description(self) -> str | Sequence: + return 'Knock everyone off the map.' + + def get_instance_description_short(self) -> str | Sequence: + return 'Knock off the map.' + + def on_begin(self) -> None: + super().on_begin() + self._start_time = bs.time() + self.setup_standard_time_limit(self._time_limit) + self.setup_standard_powerup_drops(enable_tnt=False) + self._pow = None + self._tnt_drop_timer = bs.timer(1.0 * 0.30, + bs.WeakCall(self._drop_pow_box), + repeat=True) + + # 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 _drop_pow_box(self) -> None: + if self._pow is not None and self._pow: + return + if len(self.map.tnt_points) == 0: + return + pos = random.choice(self.map.tnt_points) + pos = (pos[0], pos[1] + 1, pos[2]) + self._pow = PowBox(position=pos, velocity=(0.0, 1.0, 0.0)) + + def spawn_player(self, player: Player) -> bs.Actor: + if isinstance(self.session, bs.DualTeamSession): + position = self.map.get_start_position(player.team.id) + else: + # otherwise do free-for-all spawn locations + position = self.map.get_ffa_start_position(self.players) + angle = None + + name = player.getname() + light_color = _math.normalized_color(player.color) + display_color = babase.safecolor(player.color, target_intensity=0.75) + + spaz = SSPlayerSpaz(color=player.color, + highlight=player.highlight, + character=player.character, + player=player) + + player.actor = spaz + assert spaz.node + + # If this is co-op and we're on Courtyard or Runaround, add the + # material that allows us to collide with the player-walls. + # FIXME: Need to generalize this. + if isinstance(self.session, bs.CoopSession) and self.map.getname() in [ + 'Courtyard', 'Tower D' + ]: + mat = self.map.preloaddata['collide_with_wall_material'] + assert isinstance(spaz.node.materials, tuple) + assert isinstance(spaz.node.roller_materials, tuple) + spaz.node.materials += (mat, ) + spaz.node.roller_materials += (mat, ) + + spaz.node.name = name + spaz.node.name_color = display_color + spaz.connect_controls_to_player() + + # Move to the stand position and add a flash of light. + spaz.handlemessage( + bs.StandMessage( + position, + angle if angle is not None else random.uniform(0, 360))) + self._spawn_sound.play(1, position=spaz.node.position) + light = bs.newnode('light', attrs={'color': light_color}) + spaz.node.connectattr('position', light, 'position') + bs.animate(light, 'intensity', {0: 0, 0.25: 1, 0.5: 0}) + bs.timer(0.5, light.delete) + + if self._boxing_gloves: + spaz.equip_boxing_gloves() + + return spaz + + def handlemessage(self, msg: Any) -> Any: + + if isinstance(msg, bs.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, bs.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: + self._dingsound.play() + 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 + self._dingsound.play() + + # In FFA show scores since its hard to find on the scoreboard. + if isinstance(killer.actor, SSPlayerSpaz) 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): + bs.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 = bs.GameResults() + for team in self.teams: + results.set_team_score(team, team.score) + self.end(results=results) + + +class Player2(bs.Player['Team']): + """Our player type for this game.""" + + def __init__(self) -> None: + self.lives = 0 + self.icons: List[Icon] = [] + + +class Team2(bs.Team[Player]): + """Our team type for this game.""" + + def __init__(self) -> None: + self.survival_seconds: Optional[int] = None + self.spawn_order: List[Player] = [] + + +# ba_meta export bascenev1.GameActivity +class SuperSmashElimination(bs.TeamGameActivity[Player2, Team2]): + + name = 'Super Smash Elimination' + description = 'Knock everyone off the map.' + scoreconfig = bs.ScoreConfig(label='Survived', + scoretype=bs.ScoreType.SECONDS, + none_is_winner=True) + + # Print messages when players die since it matters here. + announce_player_deaths = True + + @classmethod + def get_available_settings( + cls, sessiontype: Type[bs.Session]) -> List[babase.Setting]: + settings = [ + bs.IntSetting( + 'Lives (0 = Unlimited)', + min_value=0, + default=3, + increment=1, + ), + bs.IntChoiceSetting( + 'Time Limit', + choices=[ + ('None', 0), + ('1 Minute', 60), + ('2 Minutes', 120), + ('5 Minutes', 300), + ('10 Minutes', 600), + ('20 Minutes', 1200), + ], + default=0, + ), + bs.FloatChoiceSetting( + 'Respawn Times', + choices=[ + ('Shorter', 0.25), + ('Short', 0.5), + ('Normal', 1.0), + ('Long', 2.0), + ('Longer', 4.0), + ], + default=1.0, + ), + bs.BoolSetting('Boxing Gloves', default=False), + bs.BoolSetting('Epic Mode', default=False), + ] + return settings + + @classmethod + 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[bs.Session]) -> List[str]: + maps = bs.app.classic.getmaps('melee') + for m in ['Lake Frigid', 'Hockey Stadium', 'Football Stadium']: + # remove maps without bounds + maps.remove(m) + return maps + + def __init__(self, settings: dict): + super().__init__(settings) + self.lives = int(settings['Lives (0 = Unlimited)']) + self.time_limit_only = (self.lives == 0) + if self.time_limit_only: + settings['Time Limit'] = max(60, settings['Time Limit']) + + self._epic_mode = bool(settings['Epic Mode']) + self._time_limit = float(settings['Time Limit']) + + self._start_time: Optional[float] = 1.0 + + self._boxing_gloves = bool(settings['Boxing Gloves']) + self._solo_mode = bool(settings.get('Solo Mode', False)) + + # Base class overrides. + self.slow_motion = self._epic_mode + self.default_music = (bs.MusicType.EPIC if self._epic_mode else + bs.MusicType.SURVIVAL) + + def get_instance_description(self) -> str | Sequence: + return 'Knock everyone off the map.' + + def get_instance_description_short(self) -> str | Sequence: + return 'Knock off the map.' + + def on_begin(self) -> None: + super().on_begin() + self._start_time = bs.time() + self.setup_standard_time_limit(self._time_limit) + self.setup_standard_powerup_drops(enable_tnt=False) + self._pow = None + self._tnt_drop_timer = bs.timer(1.0 * 0.30, + bs.WeakCall(self._drop_pow_box), + repeat=True) + self._update_icons() + bs.timer(1.0, self.check_end_game, repeat=True) + + def _drop_pow_box(self) -> None: + if self._pow is not None and self._pow: + return + if len(self.map.tnt_points) == 0: + return + pos = random.choice(self.map.tnt_points) + pos = (pos[0], pos[1] + 1, pos[2]) + self._pow = PowBox(position=pos, velocity=(0.0, 1.0, 0.0)) + + def on_player_join(self, player: Player) -> None: + + if self.has_begun(): + if (all(teammate.lives == 0 for teammate in player.team.players) + and player.team.survival_seconds is None): + player.team.survival_seconds = 0 + bs.broadcastmessage( + babase.Lstr(resource='playerDelayedJoinText', + subs=[('${PLAYER}', player.getname(full=True))]), + color=(0, 1, 0), + ) + return + + player.lives = self.lives + # create our icon and spawn + player.icons = [Icon(player, + position=(0.0, 50), + scale=0.8)] + if player.lives > 0 or self.time_limit_only: + self.spawn_player(player) + + # dont waste time doing this until begin + if self.has_begun(): + self._update_icons() + + def on_player_leave(self, player: Player) -> None: + super().on_player_leave(player) + player.icons = None + + # update icons in a moment since our team + # will be gone from the list then + bs.timer(0.0, self._update_icons) + bs.timer(0.1, self.check_end_game, repeat=True) + + def _update_icons(self) -> None: + # pylint: disable=too-many-branches + + # In free-for-all mode, everyone is just lined up along the bottom. + if isinstance(self.session, bs.FreeForAllSession): + count = len(self.teams) + x_offs = 85 + xval = x_offs * (count - 1) * -0.5 + for team in self.teams: + if len(team.players) > 1: + print('WTF have', len(team.players), 'players in ffa team') + elif len(team.players) == 1: + player = team.players[0] + if len(player.icons) != 1: + print( + 'WTF have', + len(player.icons), + 'icons in non-solo elim') + for icon in player.icons: + icon.set_position_and_scale((xval, 30), 0.7) + icon.update_for_lives() + xval += x_offs + + # In teams mode we split up teams. + else: + if self._solo_mode: + # First off, clear out all icons. + for player in self.players: + player.icons = [] + + # Now for each team, cycle through our available players + # adding icons. + for team in self.teams: + if team.id == 0: + xval = -60 + x_offs = -78 + else: + xval = 60 + x_offs = 78 + is_first = True + test_lives = 1 + while True: + players_with_lives = [ + p for p in team.spawn_order + if p and p.lives >= test_lives + ] + if not players_with_lives: + break + for player in players_with_lives: + player.icons.append( + Icon(player, + position=(xval, (40 if is_first else 25)), + scale=1.0 if is_first else 0.5, + name_maxwidth=130 if is_first else 75, + name_scale=0.8 if is_first else 1.0, + flatness=0.0 if is_first else 1.0, + shadow=0.5 if is_first else 1.0, + show_death=is_first, + show_lives=False)) + xval += x_offs * (0.8 if is_first else 0.56) + is_first = False + test_lives += 1 + # Non-solo mode. + else: + for team in self.teams: + if team.id == 0: + xval = -50 + x_offs = -85 + else: + xval = 50 + x_offs = 85 + for player in team.players: + if len(player.icons) != 1: + print( + 'WTF have', + len(player.icons), + 'icons in non-solo elim') + for icon in player.icons: + icon.set_position_and_scale((xval, 30), 0.7) + icon.update_for_lives() + xval += x_offs + + # overriding the default character spawning.. + def spawn_player(self, player: Player) -> bs.Actor: + if isinstance(self.session, bs.DualTeamSession): + position = self.map.get_start_position(player.team.id) + else: + # otherwise do free-for-all spawn locations + position = self.map.get_ffa_start_position(self.players) + angle = None + + name = player.getname() + light_color = _math.normalized_color(player.color) + display_color = babase.safecolor(player.color, target_intensity=0.75) + + spaz = SSPlayerSpaz(color=player.color, + highlight=player.highlight, + character=player.character, + player=player) + + player.actor = spaz + assert spaz.node + + # If this is co-op and we're on Courtyard or Runaround, add the + # material that allows us to collide with the player-walls. + # FIXME: Need to generalize this. + if isinstance(self.session, bs.CoopSession) and self.map.getname() in [ + 'Courtyard', 'Tower D' + ]: + mat = self.map.preloaddata['collide_with_wall_material'] + assert isinstance(spaz.node.materials, tuple) + assert isinstance(spaz.node.roller_materials, tuple) + spaz.node.materials += (mat, ) + spaz.node.roller_materials += (mat, ) + + spaz.node.name = name + spaz.node.name_color = display_color + spaz.connect_controls_to_player() + + # Move to the stand position and add a flash of light. + spaz.handlemessage( + bs.StandMessage( + position, + angle if angle is not None else random.uniform(0, 360))) + self._spawn_sound.play(1, position=spaz.node.position) + light = bs.newnode('light', attrs={'color': light_color}) + spaz.node.connectattr('position', light, 'position') + bs.animate(light, 'intensity', {0: 0, 0.25: 1, 0.5: 0}) + bs.timer(0.5, light.delete) + + # If we have any icons, update their state. + for icon in player.icons: + icon.handle_player_spawned() + + if self._boxing_gloves: + spaz.equip_boxing_gloves() + + return spaz + + def _get_total_team_lives(self, team: Team) -> int: + return sum(player.lives for player in team.players) + + def handlemessage(self, msg: Any) -> Any: + + if isinstance(msg, bs.PlayerDiedMessage): + # Augment standard behavior. + super().handlemessage(msg) + player: Player = msg.getplayer(Player) + + player.lives -= 1 + if player.lives < 0: + player.lives = 0 + + # if we have any icons, update their state + for icon in player.icons: + icon.handle_player_died() + + # play big death sound on our last death + # or for every one in solo mode + if player.lives == 0: + SpazFactory.get().single_player_death_sound.play() + + # if we hit zero lives we're dead and the game might be over + if player.lives == 0 and not self.time_limit_only: + # If the whole team is now dead, mark their survival time. + if self._get_total_team_lives(player.team) == 0: + assert self._start_time is not None + player.team.survival_seconds = int(bs.time() - + self._start_time) + # we still have lives; yay! + else: + self.respawn_player(player) + + bs.timer(0.1, self.check_end_game, repeat=True) + + else: + return super().handlemessage(msg) + return None + + def check_end_game(self) -> None: + if len(self._get_living_teams()) < 2: + bs.timer(0.5, self.end_game) + + def _get_living_teams(self) -> List[Team]: + return [ + team for team in self.teams + if len(team.players) > 0 and any(player.lives > 0 + for player in team.players) + ] + + def end_game(self) -> None: + if self.has_ended(): + return + results = bs.GameResults() + self._vs_text = None # Kill our 'vs' if its there. + for team in self.teams: + results.set_team_score(team, team.survival_seconds) + self.end(results=results) From d1c561992d5474301e77f438cdf27ed489f2926c Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Mon, 24 Jul 2023 12:31:56 +0200 Subject: [PATCH 27/60] Update minigames.json --- plugins/minigames.json | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index 510551e..24cf114 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -654,5 +654,24 @@ "md5sum": "197a377652ab0c3bfbe1ca07833924b4" } } - } -} \ No newline at end of file + }, + "supersmash": { + "description": "SuperSmash", + "external_url": "", + "authors": [ + { + "name": "Mrmaxmeier", + "email": "", + "discord": "" + }, + { + "name": "JoseAngel", + "email": "", + "discord": "joseang3l" + } + ], + "versions": { + "1.0.0": null + } + }, +} From 604bbe1d6e207afe7e62a070655e8990b1d72219 Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Mon, 24 Jul 2023 12:33:24 +0200 Subject: [PATCH 28/60] Update minigames.json --- plugins/minigames.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index 24cf114..52773fa 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -673,5 +673,5 @@ "versions": { "1.0.0": null } - }, + } } From 9b885781d15987e5ea59280aa2ca67efcfabd728 Mon Sep 17 00:00:00 2001 From: SenjuZoro Date: Mon, 24 Jul 2023 10:34:30 +0000 Subject: [PATCH 29/60] [ci] auto-format --- plugins/minigames/SuperSmash.py | 1576 ++++++++++++++++--------------- 1 file changed, 789 insertions(+), 787 deletions(-) diff --git a/plugins/minigames/SuperSmash.py b/plugins/minigames/SuperSmash.py index 2ffb589..3736360 100644 --- a/plugins/minigames/SuperSmash.py +++ b/plugins/minigames/SuperSmash.py @@ -19,936 +19,938 @@ from bascenev1lib.actor.bomb import Bomb, Blast from bascenev1lib.actor.playerspaz import PlayerSpaz, PlayerSpazHurtMessage if TYPE_CHECKING: - from typing import Any, Type, List, Sequence, Optional + from typing import Any, Type, List, Sequence, Optional class Icon(Icon): - 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 > 1: - 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 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 > 1: + 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 + class PowBox(Bomb): - def __init__(self, - position: Sequence[float] = (0.0, 1.0, 0.0), - velocity: Sequence[float] = (0.0, 0.0, 0.0)) -> None: - Bomb.__init__(self, - position, - velocity, - bomb_type='tnt', - blast_radius=2.5, - source_player=None, - owner=None) - self.set_pow_text() + def __init__(self, + position: Sequence[float] = (0.0, 1.0, 0.0), + velocity: Sequence[float] = (0.0, 0.0, 0.0)) -> None: + Bomb.__init__(self, + position, + velocity, + bomb_type='tnt', + blast_radius=2.5, + source_player=None, + owner=None) + self.set_pow_text() - def set_pow_text(self) -> None: - m = bs.newnode('math', - owner=self.node, - attrs={'input1': (0, 0.7, 0), - 'operation': 'add'}) - self.node.connectattr('position', m, 'input2') + def set_pow_text(self) -> None: + m = bs.newnode('math', + owner=self.node, + attrs={'input1': (0, 0.7, 0), + 'operation': 'add'}) + self.node.connectattr('position', m, 'input2') - self._pow_text = bs.newnode('text', - owner=self.node, - attrs={'text':'POW!', - 'in_world': True, - 'shadow': 1.0, - 'flatness': 1.0, - 'color': (1, 1, 0.4), - 'scale':0.0, - 'h_align':'center'}) - m.connectattr('output', self._pow_text, 'position') - bs.animate(self._pow_text, 'scale', {0: 0.0, 1.0: 0.01}) + self._pow_text = bs.newnode('text', + owner=self.node, + attrs={'text': 'POW!', + 'in_world': True, + 'shadow': 1.0, + 'flatness': 1.0, + 'color': (1, 1, 0.4), + 'scale': 0.0, + 'h_align': 'center'}) + m.connectattr('output', self._pow_text, 'position') + bs.animate(self._pow_text, 'scale', {0: 0.0, 1.0: 0.01}) - def pow(self) -> None: - self.explode() + def pow(self) -> None: + self.explode() + + def handlemessage(self, m: Any) -> Any: + if isinstance(m, babase.PickedUpMessage): + self._heldBy = m.node + elif isinstance(m, bs.DroppedMessage): + bs.timer(0.6, self.pow) + Bomb.handlemessage(self, m) - def handlemessage(self, m: Any) -> Any: - if isinstance(m, babase.PickedUpMessage): - self._heldBy = m.node - elif isinstance(m, bs.DroppedMessage): - bs.timer(0.6, self.pow) - Bomb.handlemessage(self, m) class SSPlayerSpaz(PlayerSpaz): - multiplyer = 1 - is_dead = False + multiplyer = 1 + is_dead = False - def oob_effect(self) -> None: - if self.is_dead: - return - self.is_dead = True - if self.multiplyer > 1.25: - blast_type = 'tnt' - radius = min(self.multiplyer * 5, 20) - else: - # penalty for killing people with low multiplyer - blast_type = 'ice' - radius = 7.5 - Blast(position=self.node.position, - blast_radius=radius, - blast_type=blast_type).autoretain() + def oob_effect(self) -> None: + if self.is_dead: + return + self.is_dead = True + if self.multiplyer > 1.25: + blast_type = 'tnt' + radius = min(self.multiplyer * 5, 20) + else: + # penalty for killing people with low multiplyer + blast_type = 'ice' + radius = 7.5 + Blast(position=self.node.position, + blast_radius=radius, + blast_type=blast_type).autoretain() - def handlemessage(self, msg: Any) -> Any: - if isinstance(msg, bs.HitMessage): - if not self.node: - return None - if self.node.invincible: - SpazFactory.get().block_sound.play(1.0, position=self.node.position) - return True + def handlemessage(self, msg: Any) -> Any: + if isinstance(msg, bs.HitMessage): + if not self.node: + return None + if self.node.invincible: + SpazFactory.get().block_sound.play(1.0, position=self.node.position) + return True - # If we were recently hit, don't count this as another. - # (so punch flurries and bomb pileups essentially count as 1 hit) - local_time = int(bs.time() * 1000) - assert isinstance(local_time, int) - if (self._last_hit_time is None - or local_time - self._last_hit_time > 1000): - self._num_times_hit += 1 - self._last_hit_time = local_time + # If we were recently hit, don't count this as another. + # (so punch flurries and bomb pileups essentially count as 1 hit) + local_time = int(bs.time() * 1000) + assert isinstance(local_time, int) + if (self._last_hit_time is None + or local_time - self._last_hit_time > 1000): + self._num_times_hit += 1 + self._last_hit_time = local_time - mag = msg.magnitude * self.impact_scale - velocity_mag = msg.velocity_magnitude * self.impact_scale - damage_scale = 0.22 + mag = msg.magnitude * self.impact_scale + velocity_mag = msg.velocity_magnitude * self.impact_scale + damage_scale = 0.22 - # If they've got a shield, deliver it to that instead. - if self.shield: - if msg.flat_damage: - damage = msg.flat_damage * self.impact_scale - else: - # Hit our spaz with an impulse but tell it to only return - # theoretical damage; not apply the impulse. - assert msg.force_direction is not None - self.node.handlemessage( - 'impulse', msg.pos[0], msg.pos[1], msg.pos[2], - msg.velocity[0], msg.velocity[1], msg.velocity[2], mag, - velocity_mag, msg.radius, 1, msg.force_direction[0], - msg.force_direction[1], msg.force_direction[2]) - damage = damage_scale * self.node.damage + # If they've got a shield, deliver it to that instead. + if self.shield: + if msg.flat_damage: + damage = msg.flat_damage * self.impact_scale + else: + # Hit our spaz with an impulse but tell it to only return + # theoretical damage; not apply the impulse. + assert msg.force_direction is not None + self.node.handlemessage( + 'impulse', msg.pos[0], msg.pos[1], msg.pos[2], + msg.velocity[0], msg.velocity[1], msg.velocity[2], mag, + velocity_mag, msg.radius, 1, msg.force_direction[0], + msg.force_direction[1], msg.force_direction[2]) + damage = damage_scale * self.node.damage - assert self.shield_hitpoints is not None - self.shield_hitpoints -= int(damage) - self.shield.hurt = ( - 1.0 - - float(self.shield_hitpoints) / self.shield_hitpoints_max) + assert self.shield_hitpoints is not None + self.shield_hitpoints -= int(damage) + self.shield.hurt = ( + 1.0 - + float(self.shield_hitpoints) / self.shield_hitpoints_max) - # Its a cleaner event if a hit just kills the shield - # without damaging the player. - # However, massive damage events should still be able to - # damage the player. This hopefully gives us a happy medium. - max_spillover = SpazFactory.get().max_shield_spillover_damage - if self.shield_hitpoints <= 0: + # Its a cleaner event if a hit just kills the shield + # without damaging the player. + # However, massive damage events should still be able to + # damage the player. This hopefully gives us a happy medium. + max_spillover = SpazFactory.get().max_shield_spillover_damage + if self.shield_hitpoints <= 0: - # FIXME: Transition out perhaps? - self.shield.delete() - self.shield = None - SpazFactory.get().shield_down_sound.play(1.0, position=self.node.position) + # FIXME: Transition out perhaps? + self.shield.delete() + self.shield = None + SpazFactory.get().shield_down_sound.play(1.0, position=self.node.position) - # Emit some cool looking sparks when the shield dies. - npos = self.node.position - bs.emitfx(position=(npos[0], npos[1] + 0.9, npos[2]), - velocity=self.node.velocity, - count=random.randrange(20, 30), - scale=1.0, - spread=0.6, - chunk_type='spark') + # Emit some cool looking sparks when the shield dies. + npos = self.node.position + bs.emitfx(position=(npos[0], npos[1] + 0.9, npos[2]), + velocity=self.node.velocity, + count=random.randrange(20, 30), + scale=1.0, + spread=0.6, + chunk_type='spark') - else: - SpazFactory.get().shield_hit_sound.play(0.5, position=self.node.position) + else: + SpazFactory.get().shield_hit_sound.play(0.5, position=self.node.position) - # Emit some cool looking sparks on shield hit. - assert msg.force_direction is not None - bs.emitfx(position=msg.pos, - velocity=(msg.force_direction[0] * 1.0, - msg.force_direction[1] * 1.0, - msg.force_direction[2] * 1.0), - count=min(30, 5 + int(damage * 0.005)), - scale=0.5, - spread=0.3, - chunk_type='spark') + # Emit some cool looking sparks on shield hit. + assert msg.force_direction is not None + bs.emitfx(position=msg.pos, + velocity=(msg.force_direction[0] * 1.0, + msg.force_direction[1] * 1.0, + msg.force_direction[2] * 1.0), + count=min(30, 5 + int(damage * 0.005)), + scale=0.5, + spread=0.3, + chunk_type='spark') - # If they passed our spillover threshold, - # pass damage along to spaz. - if self.shield_hitpoints <= -max_spillover: - leftover_damage = -max_spillover - self.shield_hitpoints - shield_leftover_ratio = leftover_damage / damage + # If they passed our spillover threshold, + # pass damage along to spaz. + if self.shield_hitpoints <= -max_spillover: + leftover_damage = -max_spillover - self.shield_hitpoints + shield_leftover_ratio = leftover_damage / damage - # Scale down the magnitudes applied to spaz accordingly. - mag *= shield_leftover_ratio - velocity_mag *= shield_leftover_ratio - else: - return True # Good job shield! - else: - shield_leftover_ratio = 1.0 + # Scale down the magnitudes applied to spaz accordingly. + mag *= shield_leftover_ratio + velocity_mag *= shield_leftover_ratio + else: + return True # Good job shield! + else: + shield_leftover_ratio = 1.0 - if msg.flat_damage: - damage = int(msg.flat_damage * self.impact_scale * - shield_leftover_ratio) - else: - # Hit it with an impulse and get the resulting damage. - assert msg.force_direction is not None - self.node.handlemessage( - 'impulse', msg.pos[0], msg.pos[1], msg.pos[2], - msg.velocity[0], msg.velocity[1], msg.velocity[2], mag, - velocity_mag, msg.radius, 0, msg.force_direction[0], - msg.force_direction[1], msg.force_direction[2]) + if msg.flat_damage: + damage = int(msg.flat_damage * self.impact_scale * + shield_leftover_ratio) + else: + # Hit it with an impulse and get the resulting damage. + assert msg.force_direction is not None + self.node.handlemessage( + 'impulse', msg.pos[0], msg.pos[1], msg.pos[2], + msg.velocity[0], msg.velocity[1], msg.velocity[2], mag, + velocity_mag, msg.radius, 0, msg.force_direction[0], + msg.force_direction[1], msg.force_direction[2]) - damage = int(damage_scale * self.node.damage) - self.node.handlemessage('hurt_sound') + damage = int(damage_scale * self.node.damage) + self.node.handlemessage('hurt_sound') - # Play punch impact sound based on damage if it was a punch. - if msg.hit_type == 'punch': - self.on_punched(damage) + # Play punch impact sound based on damage if it was a punch. + if msg.hit_type == 'punch': + self.on_punched(damage) - # If damage was significant, lets show it. - # if damage > 350: - # assert msg.force_direction is not None - # babase.show_damage_count('-' + str(int(damage / 10)) + '%', - # msg.pos, msg.force_direction) + # If damage was significant, lets show it. + # if damage > 350: + # assert msg.force_direction is not None + # babase.show_damage_count('-' + str(int(damage / 10)) + '%', + # msg.pos, msg.force_direction) - # Let's always add in a super-punch sound with boxing - # gloves just to differentiate them. - if msg.hit_subtype == 'super_punch': - SpazFactory.get().punch_sound_stronger.play(1.0, position=self.node.position) - if damage > 500: - sounds = SpazFactory.get().punch_sound_strong - sound = sounds[random.randrange(len(sounds))] - else: - sound = SpazFactory.get().punch_sound - sound.play(1.0, position=self.node.position) + # Let's always add in a super-punch sound with boxing + # gloves just to differentiate them. + if msg.hit_subtype == 'super_punch': + SpazFactory.get().punch_sound_stronger.play(1.0, position=self.node.position) + if damage > 500: + sounds = SpazFactory.get().punch_sound_strong + sound = sounds[random.randrange(len(sounds))] + else: + sound = SpazFactory.get().punch_sound + sound.play(1.0, position=self.node.position) - # Throw up some chunks. - assert msg.force_direction is not None - bs.emitfx(position=msg.pos, - velocity=(msg.force_direction[0] * 0.5, - msg.force_direction[1] * 0.5, - msg.force_direction[2] * 0.5), - count=min(10, 1 + int(damage * 0.0025)), - scale=0.3, - spread=0.03) + # Throw up some chunks. + assert msg.force_direction is not None + bs.emitfx(position=msg.pos, + velocity=(msg.force_direction[0] * 0.5, + msg.force_direction[1] * 0.5, + msg.force_direction[2] * 0.5), + count=min(10, 1 + int(damage * 0.0025)), + scale=0.3, + spread=0.03) - bs.emitfx(position=msg.pos, - chunk_type='sweat', - velocity=(msg.force_direction[0] * 1.3, - msg.force_direction[1] * 1.3 + 5.0, - msg.force_direction[2] * 1.3), - count=min(30, 1 + int(damage * 0.04)), - scale=0.9, - spread=0.28) + bs.emitfx(position=msg.pos, + chunk_type='sweat', + velocity=(msg.force_direction[0] * 1.3, + msg.force_direction[1] * 1.3 + 5.0, + msg.force_direction[2] * 1.3), + count=min(30, 1 + int(damage * 0.04)), + scale=0.9, + spread=0.28) - # Momentary flash. - hurtiness = damage * 0.003 - punchpos = (msg.pos[0] + msg.force_direction[0] * 0.02, - msg.pos[1] + msg.force_direction[1] * 0.02, - msg.pos[2] + msg.force_direction[2] * 0.02) - flash_color = (1.0, 0.8, 0.4) - light = bs.newnode( - 'light', - attrs={ - 'position': punchpos, - 'radius': 0.12 + hurtiness * 0.12, - 'intensity': 0.3 * (1.0 + 1.0 * hurtiness), - 'height_attenuated': False, - 'color': flash_color - }) - bs.timer(0.06, light.delete) + # Momentary flash. + hurtiness = damage * 0.003 + punchpos = (msg.pos[0] + msg.force_direction[0] * 0.02, + msg.pos[1] + msg.force_direction[1] * 0.02, + msg.pos[2] + msg.force_direction[2] * 0.02) + flash_color = (1.0, 0.8, 0.4) + light = bs.newnode( + 'light', + attrs={ + 'position': punchpos, + 'radius': 0.12 + hurtiness * 0.12, + 'intensity': 0.3 * (1.0 + 1.0 * hurtiness), + 'height_attenuated': False, + 'color': flash_color + }) + bs.timer(0.06, light.delete) - flash = bs.newnode('flash', - attrs={ - 'position': punchpos, - 'size': 0.17 + 0.17 * hurtiness, - 'color': flash_color - }) - bs.timer(0.06, flash.delete) + flash = bs.newnode('flash', + attrs={ + 'position': punchpos, + 'size': 0.17 + 0.17 * hurtiness, + 'color': flash_color + }) + bs.timer(0.06, flash.delete) - if msg.hit_type == 'impact': - assert msg.force_direction is not None - bs.emitfx(position=msg.pos, - velocity=(msg.force_direction[0] * 2.0, - msg.force_direction[1] * 2.0, - msg.force_direction[2] * 2.0), - count=min(10, 1 + int(damage * 0.01)), - scale=0.4, - spread=0.1) - if self.hitpoints > 0: + if msg.hit_type == 'impact': + assert msg.force_direction is not None + bs.emitfx(position=msg.pos, + velocity=(msg.force_direction[0] * 2.0, + msg.force_direction[1] * 2.0, + msg.force_direction[2] * 2.0), + count=min(10, 1 + int(damage * 0.01)), + scale=0.4, + spread=0.1) + if self.hitpoints > 0: - # It's kinda crappy to die from impacts, so lets reduce - # impact damage by a reasonable amount *if* it'll keep us alive - if msg.hit_type == 'impact' and damage > self.hitpoints: - # Drop damage to whatever puts us at 10 hit points, - # or 200 less than it used to be whichever is greater - # (so it *can* still kill us if its high enough) - newdamage = max(damage - 200, self.hitpoints - 10) - damage = newdamage - self.node.handlemessage('flash') + # It's kinda crappy to die from impacts, so lets reduce + # impact damage by a reasonable amount *if* it'll keep us alive + if msg.hit_type == 'impact' and damage > self.hitpoints: + # Drop damage to whatever puts us at 10 hit points, + # or 200 less than it used to be whichever is greater + # (so it *can* still kill us if its high enough) + newdamage = max(damage - 200, self.hitpoints - 10) + damage = newdamage + self.node.handlemessage('flash') - # If we're holding something, drop it. - if damage > 0.0 and self.node.hold_node: - self.node.hold_node = None - # self.hitpoints -= damage - self.multiplyer += min(damage / 2000, 0.15) - if damage/2000 > 0.05: - self.set_score_text(str(int((self.multiplyer-1)*100))+'%') - # self.node.hurt = 1.0 - float( - # self.hitpoints) / self.hitpoints_max - self.node.hurt = 0.0 + # If we're holding something, drop it. + if damage > 0.0 and self.node.hold_node: + self.node.hold_node = None + # self.hitpoints -= damage + self.multiplyer += min(damage / 2000, 0.15) + if damage/2000 > 0.05: + self.set_score_text(str(int((self.multiplyer-1)*100))+'%') + # self.node.hurt = 1.0 - float( + # self.hitpoints) / self.hitpoints_max + self.node.hurt = 0.0 - # If we're cursed, *any* damage blows us up. - if self._cursed and damage > 0: - bs.timer( - 0.05, - bs.WeakCall(self.curse_explode, - msg.get_source_player(bs.Player))) + # If we're cursed, *any* damage blows us up. + if self._cursed and damage > 0: + bs.timer( + 0.05, + bs.WeakCall(self.curse_explode, + msg.get_source_player(bs.Player))) - # If we're frozen, shatter.. otherwise die if we hit zero - # if self.frozen and (damage > 200 or self.hitpoints <= 0): - # self.shatter() - # elif self.hitpoints <= 0: - # self.node.handlemessage( - # bs.DieMessage(how=babase.DeathType.IMPACT)) + # If we're frozen, shatter.. otherwise die if we hit zero + # if self.frozen and (damage > 200 or self.hitpoints <= 0): + # self.shatter() + # elif self.hitpoints <= 0: + # self.node.handlemessage( + # bs.DieMessage(how=babase.DeathType.IMPACT)) - # If we're dead, take a look at the smoothed damage value - # (which gives us a smoothed average of recent damage) and shatter - # us if its grown high enough. - # if self.hitpoints <= 0: - # damage_avg = self.node.damage_smoothed * damage_scale - # if damage_avg > 1000: - # self.shatter() + # If we're dead, take a look at the smoothed damage value + # (which gives us a smoothed average of recent damage) and shatter + # us if its grown high enough. + # if self.hitpoints <= 0: + # damage_avg = self.node.damage_smoothed * damage_scale + # if damage_avg > 1000: + # self.shatter() - source_player = msg.get_source_player(type(self._player)) - if source_player: - self.last_player_attacked_by = source_player - self.last_attacked_time = bs.time() - self.last_attacked_type = (msg.hit_type, msg.hit_subtype) - Spaz.handlemessage(self, bs.HitMessage) # Augment standard behavior. - activity = self._activity() - if activity is not None and self._player.exists(): - activity.handlemessage(PlayerSpazHurtMessage(self)) + source_player = msg.get_source_player(type(self._player)) + if source_player: + self.last_player_attacked_by = source_player + self.last_attacked_time = bs.time() + self.last_attacked_type = (msg.hit_type, msg.hit_subtype) + Spaz.handlemessage(self, bs.HitMessage) # Augment standard behavior. + activity = self._activity() + if activity is not None and self._player.exists(): + activity.handlemessage(PlayerSpazHurtMessage(self)) - elif isinstance(msg, bs.DieMessage): - self.oob_effect() - super().handlemessage(msg) - elif isinstance(msg, bs.PowerupMessage): - if msg.poweruptype == 'health': - if self.multiplyer > 2: - self.multiplyer *= 0.5 - else: - self.multiplyer *= 0.75 - self.multiplyer = max(1, self.multiplyer) - self.set_score_text(str(int((self.multiplyer-1)*100))+"%") - super().handlemessage(msg) - else: - super().handlemessage(msg) + elif isinstance(msg, bs.DieMessage): + self.oob_effect() + super().handlemessage(msg) + elif isinstance(msg, bs.PowerupMessage): + if msg.poweruptype == 'health': + if self.multiplyer > 2: + self.multiplyer *= 0.5 + else: + self.multiplyer *= 0.75 + self.multiplyer = max(1, self.multiplyer) + self.set_score_text(str(int((self.multiplyer-1)*100))+"%") + super().handlemessage(msg) + else: + super().handlemessage(msg) class Player(bs.Player['Team']): - """Our player type for this game.""" + """Our player type for this game.""" class Team(bs.Team[Player]): - """Our team type for this game.""" + """Our team type for this game.""" - def __init__(self) -> None: - self.score = 0 + def __init__(self) -> None: + self.score = 0 # ba_meta export bascenev1.GameActivity class SuperSmash(bs.TeamGameActivity[Player, Team]): - name = 'Super Smash' - description = 'Knock everyone off the map.' + name = 'Super Smash' + description = 'Knock everyone off the map.' - # Print messages when players die since it matters here. - announce_player_deaths = True + # Print messages when players die since it matters here. + announce_player_deaths = True - @classmethod - def get_available_settings( - cls, sessiontype: Type[bs.Session]) -> List[babase.Setting]: - settings = [ - bs.IntSetting( - 'Kills to Win Per Player', - min_value=1, - default=5, - increment=1, - ), - bs.IntChoiceSetting( - 'Time Limit', - choices=[ - ('None', 0), - ('1 Minute', 60), - ('2 Minutes', 120), - ('5 Minutes', 300), - ('10 Minutes', 600), - ('20 Minutes', 1200), - ], - default=0, - ), - bs.FloatChoiceSetting( - 'Respawn Times', - choices=[ - ('Shorter', 0.25), - ('Short', 0.5), - ('Normal', 1.0), - ('Long', 2.0), - ('Longer', 4.0), - ], - default=1.0, - ), - bs.BoolSetting('Boxing Gloves', default=False), - bs.BoolSetting('Epic Mode', default=False), - ] - if issubclass(sessiontype, bs.FreeForAllSession): - settings.append( - bs.BoolSetting('Allow Negative Scores', default=False)) - return settings + @classmethod + def get_available_settings( + cls, sessiontype: Type[bs.Session]) -> List[babase.Setting]: + settings = [ + bs.IntSetting( + 'Kills to Win Per Player', + min_value=1, + default=5, + increment=1, + ), + bs.IntChoiceSetting( + 'Time Limit', + choices=[ + ('None', 0), + ('1 Minute', 60), + ('2 Minutes', 120), + ('5 Minutes', 300), + ('10 Minutes', 600), + ('20 Minutes', 1200), + ], + default=0, + ), + bs.FloatChoiceSetting( + 'Respawn Times', + choices=[ + ('Shorter', 0.25), + ('Short', 0.5), + ('Normal', 1.0), + ('Long', 2.0), + ('Longer', 4.0), + ], + default=1.0, + ), + bs.BoolSetting('Boxing Gloves', default=False), + bs.BoolSetting('Epic Mode', default=False), + ] + if issubclass(sessiontype, bs.FreeForAllSession): + settings.append( + bs.BoolSetting('Allow Negative Scores', default=False)) + return settings - @classmethod - def supports_session_type(cls, sessiontype: Type[bs.Session]) -> bool: - return (issubclass(sessiontype, bs.DualTeamSession) - or issubclass(sessiontype, bs.FreeForAllSession)) + @classmethod + 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[bs.Session]) -> List[str]: - maps = bs.app.classic.getmaps('melee') - for m in ['Lake Frigid', 'Hockey Stadium', 'Football Stadium']: - # remove maps without bounds - maps.remove(m) - return maps + @classmethod + def get_supported_maps(cls, sessiontype: Type[bs.Session]) -> List[str]: + maps = bs.app.classic.getmaps('melee') + for m in ['Lake Frigid', 'Hockey Stadium', 'Football Stadium']: + # remove maps without bounds + maps.remove(m) + return maps - def __init__(self, settings: dict): - super().__init__(settings) - self._scoreboard = Scoreboard() - self._score_to_win: int | None = None - self._dingsound = bs.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)) - self._boxing_gloves = bool(settings['Boxing Gloves']) + def __init__(self, settings: dict): + super().__init__(settings) + self._scoreboard = Scoreboard() + self._score_to_win: int | None = None + self._dingsound = bs.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)) + self._boxing_gloves = bool(settings['Boxing Gloves']) - # Base class overrides. - self.slow_motion = self._epic_mode - self.default_music = (bs.MusicType.EPIC if self._epic_mode else - bs.MusicType.SURVIVAL) + # Base class overrides. + self.slow_motion = self._epic_mode + self.default_music = (bs.MusicType.EPIC if self._epic_mode else + bs.MusicType.SURVIVAL) - def get_instance_description(self) -> str | Sequence: - return 'Knock everyone off the map.' + def get_instance_description(self) -> str | Sequence: + return 'Knock everyone off the map.' - def get_instance_description_short(self) -> str | Sequence: - return 'Knock off the map.' + def get_instance_description_short(self) -> str | Sequence: + return 'Knock off the map.' - def on_begin(self) -> None: - super().on_begin() - self._start_time = bs.time() - self.setup_standard_time_limit(self._time_limit) - self.setup_standard_powerup_drops(enable_tnt=False) - self._pow = None - self._tnt_drop_timer = bs.timer(1.0 * 0.30, - bs.WeakCall(self._drop_pow_box), - repeat=True) + def on_begin(self) -> None: + super().on_begin() + self._start_time = bs.time() + self.setup_standard_time_limit(self._time_limit) + self.setup_standard_powerup_drops(enable_tnt=False) + self._pow = None + self._tnt_drop_timer = bs.timer(1.0 * 0.30, + bs.WeakCall(self._drop_pow_box), + repeat=True) - # 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() + # 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 _drop_pow_box(self) -> None: - if self._pow is not None and self._pow: - return - if len(self.map.tnt_points) == 0: - return - pos = random.choice(self.map.tnt_points) - pos = (pos[0], pos[1] + 1, pos[2]) - self._pow = PowBox(position=pos, velocity=(0.0, 1.0, 0.0)) + def _drop_pow_box(self) -> None: + if self._pow is not None and self._pow: + return + if len(self.map.tnt_points) == 0: + return + pos = random.choice(self.map.tnt_points) + pos = (pos[0], pos[1] + 1, pos[2]) + self._pow = PowBox(position=pos, velocity=(0.0, 1.0, 0.0)) - def spawn_player(self, player: Player) -> bs.Actor: - if isinstance(self.session, bs.DualTeamSession): - position = self.map.get_start_position(player.team.id) - else: - # otherwise do free-for-all spawn locations - position = self.map.get_ffa_start_position(self.players) - angle = None + def spawn_player(self, player: Player) -> bs.Actor: + if isinstance(self.session, bs.DualTeamSession): + position = self.map.get_start_position(player.team.id) + else: + # otherwise do free-for-all spawn locations + position = self.map.get_ffa_start_position(self.players) + angle = None - name = player.getname() - light_color = _math.normalized_color(player.color) - display_color = babase.safecolor(player.color, target_intensity=0.75) + name = player.getname() + light_color = _math.normalized_color(player.color) + display_color = babase.safecolor(player.color, target_intensity=0.75) - spaz = SSPlayerSpaz(color=player.color, - highlight=player.highlight, - character=player.character, - player=player) + spaz = SSPlayerSpaz(color=player.color, + highlight=player.highlight, + character=player.character, + player=player) - player.actor = spaz - assert spaz.node + player.actor = spaz + assert spaz.node - # If this is co-op and we're on Courtyard or Runaround, add the - # material that allows us to collide with the player-walls. - # FIXME: Need to generalize this. - if isinstance(self.session, bs.CoopSession) and self.map.getname() in [ - 'Courtyard', 'Tower D' - ]: - mat = self.map.preloaddata['collide_with_wall_material'] - assert isinstance(spaz.node.materials, tuple) - assert isinstance(spaz.node.roller_materials, tuple) - spaz.node.materials += (mat, ) - spaz.node.roller_materials += (mat, ) + # If this is co-op and we're on Courtyard or Runaround, add the + # material that allows us to collide with the player-walls. + # FIXME: Need to generalize this. + if isinstance(self.session, bs.CoopSession) and self.map.getname() in [ + 'Courtyard', 'Tower D' + ]: + mat = self.map.preloaddata['collide_with_wall_material'] + assert isinstance(spaz.node.materials, tuple) + assert isinstance(spaz.node.roller_materials, tuple) + spaz.node.materials += (mat, ) + spaz.node.roller_materials += (mat, ) - spaz.node.name = name - spaz.node.name_color = display_color - spaz.connect_controls_to_player() + spaz.node.name = name + spaz.node.name_color = display_color + spaz.connect_controls_to_player() - # Move to the stand position and add a flash of light. - spaz.handlemessage( - bs.StandMessage( - position, - angle if angle is not None else random.uniform(0, 360))) - self._spawn_sound.play(1, position=spaz.node.position) - light = bs.newnode('light', attrs={'color': light_color}) - spaz.node.connectattr('position', light, 'position') - bs.animate(light, 'intensity', {0: 0, 0.25: 1, 0.5: 0}) - bs.timer(0.5, light.delete) + # Move to the stand position and add a flash of light. + spaz.handlemessage( + bs.StandMessage( + position, + angle if angle is not None else random.uniform(0, 360))) + self._spawn_sound.play(1, position=spaz.node.position) + light = bs.newnode('light', attrs={'color': light_color}) + spaz.node.connectattr('position', light, 'position') + bs.animate(light, 'intensity', {0: 0, 0.25: 1, 0.5: 0}) + bs.timer(0.5, light.delete) - if self._boxing_gloves: - spaz.equip_boxing_gloves() + if self._boxing_gloves: + spaz.equip_boxing_gloves() - return spaz + return spaz - def handlemessage(self, msg: Any) -> Any: + def handlemessage(self, msg: Any) -> Any: - if isinstance(msg, bs.PlayerDiedMessage): - # Augment standard behavior. - super().handlemessage(msg) + if isinstance(msg, bs.PlayerDiedMessage): + # Augment standard behavior. + super().handlemessage(msg) - player = msg.getplayer(Player) - self.respawn_player(player) + player = msg.getplayer(Player) + self.respawn_player(player) - killer = msg.getkillerplayer(Player) - if killer is None: - return None + killer = msg.getkillerplayer(Player) + if killer is None: + return None - # Handle team-kills. - if killer.team is player.team: + # Handle team-kills. + if killer.team is player.team: - # In free-for-all, killing yourself loses you a point. - if isinstance(self.session, bs.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 free-for-all, killing yourself loses you a point. + if isinstance(self.session, bs.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: - self._dingsound.play() - for team in self.teams: - if team is not killer.team: - team.score += 1 + # In teams-mode it gives a point to the other team. + else: + self._dingsound.play() + 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 - self._dingsound.play() + # Killing someone on another team nets a kill. + else: + killer.team.score += 1 + self._dingsound.play() - # In FFA show scores since its hard to find on the scoreboard. - if isinstance(killer.actor, SSPlayerSpaz) and killer.actor: - killer.actor.set_score_text(str(killer.team.score) + '/' + - str(self._score_to_win), - color=killer.team.color, - flash=True) + # In FFA show scores since its hard to find on the scoreboard. + if isinstance(killer.actor, SSPlayerSpaz) 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() + 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): - bs.timer(0.5, self.end_game) + # 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): + bs.timer(0.5, self.end_game) - else: - return super().handlemessage(msg) - return None + 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 _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 = bs.GameResults() - for team in self.teams: - results.set_team_score(team, team.score) - self.end(results=results) + def end_game(self) -> None: + results = bs.GameResults() + for team in self.teams: + results.set_team_score(team, team.score) + self.end(results=results) class Player2(bs.Player['Team']): - """Our player type for this game.""" + """Our player type for this game.""" - def __init__(self) -> None: - self.lives = 0 - self.icons: List[Icon] = [] + def __init__(self) -> None: + self.lives = 0 + self.icons: List[Icon] = [] class Team2(bs.Team[Player]): - """Our team type for this game.""" + """Our team type for this game.""" - def __init__(self) -> None: - self.survival_seconds: Optional[int] = None - self.spawn_order: List[Player] = [] + def __init__(self) -> None: + self.survival_seconds: Optional[int] = None + self.spawn_order: List[Player] = [] # ba_meta export bascenev1.GameActivity class SuperSmashElimination(bs.TeamGameActivity[Player2, Team2]): - name = 'Super Smash Elimination' - description = 'Knock everyone off the map.' - scoreconfig = bs.ScoreConfig(label='Survived', - scoretype=bs.ScoreType.SECONDS, - none_is_winner=True) + name = 'Super Smash Elimination' + description = 'Knock everyone off the map.' + scoreconfig = bs.ScoreConfig(label='Survived', + scoretype=bs.ScoreType.SECONDS, + none_is_winner=True) - # Print messages when players die since it matters here. - announce_player_deaths = True + # Print messages when players die since it matters here. + announce_player_deaths = True - @classmethod - def get_available_settings( - cls, sessiontype: Type[bs.Session]) -> List[babase.Setting]: - settings = [ - bs.IntSetting( - 'Lives (0 = Unlimited)', - min_value=0, - default=3, - increment=1, - ), - bs.IntChoiceSetting( - 'Time Limit', - choices=[ - ('None', 0), - ('1 Minute', 60), - ('2 Minutes', 120), - ('5 Minutes', 300), - ('10 Minutes', 600), - ('20 Minutes', 1200), - ], - default=0, - ), - bs.FloatChoiceSetting( - 'Respawn Times', - choices=[ - ('Shorter', 0.25), - ('Short', 0.5), - ('Normal', 1.0), - ('Long', 2.0), - ('Longer', 4.0), - ], - default=1.0, - ), - bs.BoolSetting('Boxing Gloves', default=False), - bs.BoolSetting('Epic Mode', default=False), - ] - return settings + @classmethod + def get_available_settings( + cls, sessiontype: Type[bs.Session]) -> List[babase.Setting]: + settings = [ + bs.IntSetting( + 'Lives (0 = Unlimited)', + min_value=0, + default=3, + increment=1, + ), + bs.IntChoiceSetting( + 'Time Limit', + choices=[ + ('None', 0), + ('1 Minute', 60), + ('2 Minutes', 120), + ('5 Minutes', 300), + ('10 Minutes', 600), + ('20 Minutes', 1200), + ], + default=0, + ), + bs.FloatChoiceSetting( + 'Respawn Times', + choices=[ + ('Shorter', 0.25), + ('Short', 0.5), + ('Normal', 1.0), + ('Long', 2.0), + ('Longer', 4.0), + ], + default=1.0, + ), + bs.BoolSetting('Boxing Gloves', default=False), + bs.BoolSetting('Epic Mode', default=False), + ] + return settings - @classmethod - def supports_session_type(cls, sessiontype: Type[bs.Session]) -> bool: - return (issubclass(sessiontype, bs.DualTeamSession) - or issubclass(sessiontype, bs.FreeForAllSession)) + @classmethod + 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[bs.Session]) -> List[str]: - maps = bs.app.classic.getmaps('melee') - for m in ['Lake Frigid', 'Hockey Stadium', 'Football Stadium']: - # remove maps without bounds - maps.remove(m) - return maps + @classmethod + def get_supported_maps(cls, sessiontype: Type[bs.Session]) -> List[str]: + maps = bs.app.classic.getmaps('melee') + for m in ['Lake Frigid', 'Hockey Stadium', 'Football Stadium']: + # remove maps without bounds + maps.remove(m) + return maps - def __init__(self, settings: dict): - super().__init__(settings) - self.lives = int(settings['Lives (0 = Unlimited)']) - self.time_limit_only = (self.lives == 0) - if self.time_limit_only: - settings['Time Limit'] = max(60, settings['Time Limit']) + def __init__(self, settings: dict): + super().__init__(settings) + self.lives = int(settings['Lives (0 = Unlimited)']) + self.time_limit_only = (self.lives == 0) + if self.time_limit_only: + settings['Time Limit'] = max(60, settings['Time Limit']) - self._epic_mode = bool(settings['Epic Mode']) - self._time_limit = float(settings['Time Limit']) + self._epic_mode = bool(settings['Epic Mode']) + self._time_limit = float(settings['Time Limit']) - self._start_time: Optional[float] = 1.0 + self._start_time: Optional[float] = 1.0 - self._boxing_gloves = bool(settings['Boxing Gloves']) - self._solo_mode = bool(settings.get('Solo Mode', False)) + self._boxing_gloves = bool(settings['Boxing Gloves']) + self._solo_mode = bool(settings.get('Solo Mode', False)) - # Base class overrides. - self.slow_motion = self._epic_mode - self.default_music = (bs.MusicType.EPIC if self._epic_mode else - bs.MusicType.SURVIVAL) + # Base class overrides. + self.slow_motion = self._epic_mode + self.default_music = (bs.MusicType.EPIC if self._epic_mode else + bs.MusicType.SURVIVAL) - def get_instance_description(self) -> str | Sequence: - return 'Knock everyone off the map.' + def get_instance_description(self) -> str | Sequence: + return 'Knock everyone off the map.' - def get_instance_description_short(self) -> str | Sequence: - return 'Knock off the map.' + def get_instance_description_short(self) -> str | Sequence: + return 'Knock off the map.' - def on_begin(self) -> None: - super().on_begin() - self._start_time = bs.time() - self.setup_standard_time_limit(self._time_limit) - self.setup_standard_powerup_drops(enable_tnt=False) - self._pow = None - self._tnt_drop_timer = bs.timer(1.0 * 0.30, - bs.WeakCall(self._drop_pow_box), - repeat=True) - self._update_icons() - bs.timer(1.0, self.check_end_game, repeat=True) + def on_begin(self) -> None: + super().on_begin() + self._start_time = bs.time() + self.setup_standard_time_limit(self._time_limit) + self.setup_standard_powerup_drops(enable_tnt=False) + self._pow = None + self._tnt_drop_timer = bs.timer(1.0 * 0.30, + bs.WeakCall(self._drop_pow_box), + repeat=True) + self._update_icons() + bs.timer(1.0, self.check_end_game, repeat=True) - def _drop_pow_box(self) -> None: - if self._pow is not None and self._pow: - return - if len(self.map.tnt_points) == 0: - return - pos = random.choice(self.map.tnt_points) - pos = (pos[0], pos[1] + 1, pos[2]) - self._pow = PowBox(position=pos, velocity=(0.0, 1.0, 0.0)) + def _drop_pow_box(self) -> None: + if self._pow is not None and self._pow: + return + if len(self.map.tnt_points) == 0: + return + pos = random.choice(self.map.tnt_points) + pos = (pos[0], pos[1] + 1, pos[2]) + self._pow = PowBox(position=pos, velocity=(0.0, 1.0, 0.0)) - def on_player_join(self, player: Player) -> None: + def on_player_join(self, player: Player) -> None: - if self.has_begun(): - if (all(teammate.lives == 0 for teammate in player.team.players) - and player.team.survival_seconds is None): - player.team.survival_seconds = 0 - bs.broadcastmessage( - babase.Lstr(resource='playerDelayedJoinText', - subs=[('${PLAYER}', player.getname(full=True))]), - color=(0, 1, 0), - ) - return + if self.has_begun(): + if (all(teammate.lives == 0 for teammate in player.team.players) + and player.team.survival_seconds is None): + player.team.survival_seconds = 0 + bs.broadcastmessage( + babase.Lstr(resource='playerDelayedJoinText', + subs=[('${PLAYER}', player.getname(full=True))]), + color=(0, 1, 0), + ) + return - player.lives = self.lives - # create our icon and spawn - player.icons = [Icon(player, - position=(0.0, 50), - scale=0.8)] - if player.lives > 0 or self.time_limit_only: - self.spawn_player(player) + player.lives = self.lives + # create our icon and spawn + player.icons = [Icon(player, + position=(0.0, 50), + scale=0.8)] + if player.lives > 0 or self.time_limit_only: + self.spawn_player(player) - # dont waste time doing this until begin - if self.has_begun(): - self._update_icons() + # dont waste time doing this until begin + if self.has_begun(): + self._update_icons() - def on_player_leave(self, player: Player) -> None: - super().on_player_leave(player) - player.icons = None + def on_player_leave(self, player: Player) -> None: + super().on_player_leave(player) + player.icons = None - # update icons in a moment since our team - # will be gone from the list then - bs.timer(0.0, self._update_icons) - bs.timer(0.1, self.check_end_game, repeat=True) + # update icons in a moment since our team + # will be gone from the list then + bs.timer(0.0, self._update_icons) + bs.timer(0.1, self.check_end_game, repeat=True) - def _update_icons(self) -> None: - # pylint: disable=too-many-branches + def _update_icons(self) -> None: + # pylint: disable=too-many-branches - # In free-for-all mode, everyone is just lined up along the bottom. - if isinstance(self.session, bs.FreeForAllSession): - count = len(self.teams) - x_offs = 85 - xval = x_offs * (count - 1) * -0.5 - for team in self.teams: - if len(team.players) > 1: - print('WTF have', len(team.players), 'players in ffa team') - elif len(team.players) == 1: - player = team.players[0] - if len(player.icons) != 1: - print( - 'WTF have', - len(player.icons), - 'icons in non-solo elim') - for icon in player.icons: - icon.set_position_and_scale((xval, 30), 0.7) - icon.update_for_lives() - xval += x_offs + # In free-for-all mode, everyone is just lined up along the bottom. + if isinstance(self.session, bs.FreeForAllSession): + count = len(self.teams) + x_offs = 85 + xval = x_offs * (count - 1) * -0.5 + for team in self.teams: + if len(team.players) > 1: + print('WTF have', len(team.players), 'players in ffa team') + elif len(team.players) == 1: + player = team.players[0] + if len(player.icons) != 1: + print( + 'WTF have', + len(player.icons), + 'icons in non-solo elim') + for icon in player.icons: + icon.set_position_and_scale((xval, 30), 0.7) + icon.update_for_lives() + xval += x_offs - # In teams mode we split up teams. - else: - if self._solo_mode: - # First off, clear out all icons. - for player in self.players: - player.icons = [] + # In teams mode we split up teams. + else: + if self._solo_mode: + # First off, clear out all icons. + for player in self.players: + player.icons = [] - # Now for each team, cycle through our available players - # adding icons. - for team in self.teams: - if team.id == 0: - xval = -60 - x_offs = -78 - else: - xval = 60 - x_offs = 78 - is_first = True - test_lives = 1 - while True: - players_with_lives = [ - p for p in team.spawn_order - if p and p.lives >= test_lives - ] - if not players_with_lives: - break - for player in players_with_lives: - player.icons.append( - Icon(player, - position=(xval, (40 if is_first else 25)), - scale=1.0 if is_first else 0.5, - name_maxwidth=130 if is_first else 75, - name_scale=0.8 if is_first else 1.0, - flatness=0.0 if is_first else 1.0, - shadow=0.5 if is_first else 1.0, - show_death=is_first, - show_lives=False)) - xval += x_offs * (0.8 if is_first else 0.56) - is_first = False - test_lives += 1 - # Non-solo mode. - else: - for team in self.teams: - if team.id == 0: - xval = -50 - x_offs = -85 - else: - xval = 50 - x_offs = 85 - for player in team.players: - if len(player.icons) != 1: - print( - 'WTF have', - len(player.icons), - 'icons in non-solo elim') - for icon in player.icons: - icon.set_position_and_scale((xval, 30), 0.7) - icon.update_for_lives() - xval += x_offs + # Now for each team, cycle through our available players + # adding icons. + for team in self.teams: + if team.id == 0: + xval = -60 + x_offs = -78 + else: + xval = 60 + x_offs = 78 + is_first = True + test_lives = 1 + while True: + players_with_lives = [ + p for p in team.spawn_order + if p and p.lives >= test_lives + ] + if not players_with_lives: + break + for player in players_with_lives: + player.icons.append( + Icon(player, + position=(xval, (40 if is_first else 25)), + scale=1.0 if is_first else 0.5, + name_maxwidth=130 if is_first else 75, + name_scale=0.8 if is_first else 1.0, + flatness=0.0 if is_first else 1.0, + shadow=0.5 if is_first else 1.0, + show_death=is_first, + show_lives=False)) + xval += x_offs * (0.8 if is_first else 0.56) + is_first = False + test_lives += 1 + # Non-solo mode. + else: + for team in self.teams: + if team.id == 0: + xval = -50 + x_offs = -85 + else: + xval = 50 + x_offs = 85 + for player in team.players: + if len(player.icons) != 1: + print( + 'WTF have', + len(player.icons), + 'icons in non-solo elim') + for icon in player.icons: + icon.set_position_and_scale((xval, 30), 0.7) + icon.update_for_lives() + xval += x_offs - # overriding the default character spawning.. - def spawn_player(self, player: Player) -> bs.Actor: - if isinstance(self.session, bs.DualTeamSession): - position = self.map.get_start_position(player.team.id) - else: - # otherwise do free-for-all spawn locations - position = self.map.get_ffa_start_position(self.players) - angle = None + # overriding the default character spawning.. + def spawn_player(self, player: Player) -> bs.Actor: + if isinstance(self.session, bs.DualTeamSession): + position = self.map.get_start_position(player.team.id) + else: + # otherwise do free-for-all spawn locations + position = self.map.get_ffa_start_position(self.players) + angle = None - name = player.getname() - light_color = _math.normalized_color(player.color) - display_color = babase.safecolor(player.color, target_intensity=0.75) + name = player.getname() + light_color = _math.normalized_color(player.color) + display_color = babase.safecolor(player.color, target_intensity=0.75) - spaz = SSPlayerSpaz(color=player.color, - highlight=player.highlight, - character=player.character, - player=player) + spaz = SSPlayerSpaz(color=player.color, + highlight=player.highlight, + character=player.character, + player=player) - player.actor = spaz - assert spaz.node + player.actor = spaz + assert spaz.node - # If this is co-op and we're on Courtyard or Runaround, add the - # material that allows us to collide with the player-walls. - # FIXME: Need to generalize this. - if isinstance(self.session, bs.CoopSession) and self.map.getname() in [ - 'Courtyard', 'Tower D' - ]: - mat = self.map.preloaddata['collide_with_wall_material'] - assert isinstance(spaz.node.materials, tuple) - assert isinstance(spaz.node.roller_materials, tuple) - spaz.node.materials += (mat, ) - spaz.node.roller_materials += (mat, ) + # If this is co-op and we're on Courtyard or Runaround, add the + # material that allows us to collide with the player-walls. + # FIXME: Need to generalize this. + if isinstance(self.session, bs.CoopSession) and self.map.getname() in [ + 'Courtyard', 'Tower D' + ]: + mat = self.map.preloaddata['collide_with_wall_material'] + assert isinstance(spaz.node.materials, tuple) + assert isinstance(spaz.node.roller_materials, tuple) + spaz.node.materials += (mat, ) + spaz.node.roller_materials += (mat, ) - spaz.node.name = name - spaz.node.name_color = display_color - spaz.connect_controls_to_player() + spaz.node.name = name + spaz.node.name_color = display_color + spaz.connect_controls_to_player() - # Move to the stand position and add a flash of light. - spaz.handlemessage( - bs.StandMessage( - position, - angle if angle is not None else random.uniform(0, 360))) - self._spawn_sound.play(1, position=spaz.node.position) - light = bs.newnode('light', attrs={'color': light_color}) - spaz.node.connectattr('position', light, 'position') - bs.animate(light, 'intensity', {0: 0, 0.25: 1, 0.5: 0}) - bs.timer(0.5, light.delete) + # Move to the stand position and add a flash of light. + spaz.handlemessage( + bs.StandMessage( + position, + angle if angle is not None else random.uniform(0, 360))) + self._spawn_sound.play(1, position=spaz.node.position) + light = bs.newnode('light', attrs={'color': light_color}) + spaz.node.connectattr('position', light, 'position') + bs.animate(light, 'intensity', {0: 0, 0.25: 1, 0.5: 0}) + bs.timer(0.5, light.delete) - # If we have any icons, update their state. - for icon in player.icons: - icon.handle_player_spawned() + # If we have any icons, update their state. + for icon in player.icons: + icon.handle_player_spawned() - if self._boxing_gloves: - spaz.equip_boxing_gloves() + if self._boxing_gloves: + spaz.equip_boxing_gloves() - return spaz + return spaz - def _get_total_team_lives(self, team: Team) -> int: - return sum(player.lives for player in team.players) + def _get_total_team_lives(self, team: Team) -> int: + return sum(player.lives for player in team.players) - def handlemessage(self, msg: Any) -> Any: + def handlemessage(self, msg: Any) -> Any: - if isinstance(msg, bs.PlayerDiedMessage): - # Augment standard behavior. - super().handlemessage(msg) - player: Player = msg.getplayer(Player) + if isinstance(msg, bs.PlayerDiedMessage): + # Augment standard behavior. + super().handlemessage(msg) + player: Player = msg.getplayer(Player) - player.lives -= 1 - if player.lives < 0: - player.lives = 0 + player.lives -= 1 + if player.lives < 0: + player.lives = 0 - # if we have any icons, update their state - for icon in player.icons: - icon.handle_player_died() + # if we have any icons, update their state + for icon in player.icons: + icon.handle_player_died() - # play big death sound on our last death - # or for every one in solo mode - if player.lives == 0: - SpazFactory.get().single_player_death_sound.play() + # play big death sound on our last death + # or for every one in solo mode + if player.lives == 0: + SpazFactory.get().single_player_death_sound.play() - # if we hit zero lives we're dead and the game might be over - if player.lives == 0 and not self.time_limit_only: - # If the whole team is now dead, mark their survival time. - if self._get_total_team_lives(player.team) == 0: - assert self._start_time is not None - player.team.survival_seconds = int(bs.time() - - self._start_time) - # we still have lives; yay! - else: - self.respawn_player(player) + # if we hit zero lives we're dead and the game might be over + if player.lives == 0 and not self.time_limit_only: + # If the whole team is now dead, mark their survival time. + if self._get_total_team_lives(player.team) == 0: + assert self._start_time is not None + player.team.survival_seconds = int(bs.time() - + self._start_time) + # we still have lives; yay! + else: + self.respawn_player(player) - bs.timer(0.1, self.check_end_game, repeat=True) + bs.timer(0.1, self.check_end_game, repeat=True) - else: - return super().handlemessage(msg) - return None + else: + return super().handlemessage(msg) + return None - def check_end_game(self) -> None: - if len(self._get_living_teams()) < 2: - bs.timer(0.5, self.end_game) + def check_end_game(self) -> None: + if len(self._get_living_teams()) < 2: + bs.timer(0.5, self.end_game) - def _get_living_teams(self) -> List[Team]: - return [ - team for team in self.teams - if len(team.players) > 0 and any(player.lives > 0 - for player in team.players) - ] + def _get_living_teams(self) -> List[Team]: + return [ + team for team in self.teams + if len(team.players) > 0 and any(player.lives > 0 + for player in team.players) + ] - def end_game(self) -> None: - if self.has_ended(): - return - results = bs.GameResults() - self._vs_text = None # Kill our 'vs' if its there. - for team in self.teams: - results.set_team_score(team, team.survival_seconds) - self.end(results=results) + def end_game(self) -> None: + if self.has_ended(): + return + results = bs.GameResults() + self._vs_text = None # Kill our 'vs' if its there. + for team in self.teams: + results.set_team_score(team, team.survival_seconds) + self.end(results=results) From 832458e8287ab2585f3ab18ee62cb754eeb0d66f Mon Sep 17 00:00:00 2001 From: SenjuZoro Date: Mon, 24 Jul 2023 10:34:31 +0000 Subject: [PATCH 30/60] [ci] apply-version-metadata --- plugins/minigames.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index 52773fa..2db4b01 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -674,4 +674,4 @@ "1.0.0": null } } -} +} \ No newline at end of file From e99617fd0e71e19402ed6674fae21ffccd5f05fd Mon Sep 17 00:00:00 2001 From: Rikko Date: Mon, 24 Jul 2023 18:52:41 +0530 Subject: [PATCH 31/60] Fix supersmash --- plugins/minigames.json | 4 ++-- plugins/minigames/{SuperSmash.py => supersmash.py} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename plugins/minigames/{SuperSmash.py => supersmash.py} (100%) diff --git a/plugins/minigames.json b/plugins/minigames.json index 2db4b01..a58c040 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -656,7 +656,7 @@ } }, "supersmash": { - "description": "SuperSmash", + "description": "Blow up your enemies off the map!", "external_url": "", "authors": [ { @@ -674,4 +674,4 @@ "1.0.0": null } } -} \ No newline at end of file +} diff --git a/plugins/minigames/SuperSmash.py b/plugins/minigames/supersmash.py similarity index 100% rename from plugins/minigames/SuperSmash.py rename to plugins/minigames/supersmash.py From 68e77f28d8661c4ab6598883e5914fea624521e5 Mon Sep 17 00:00:00 2001 From: rikkolovescats Date: Mon, 24 Jul 2023 13:23:42 +0000 Subject: [PATCH 32/60] [ci] apply-version-metadata --- plugins/minigames.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index a58c040..e33f963 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -674,4 +674,4 @@ "1.0.0": null } } -} +} \ No newline at end of file From 1ae512a65f6208ea32f043f3116d1199a067b88d Mon Sep 17 00:00:00 2001 From: Rikko Date: Mon, 24 Jul 2023 19:17:27 +0530 Subject: [PATCH 33/60] Fix JSON struct --- plugins/minigames.json | 113 +++++++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 54 deletions(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index e33f963..c394833 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -615,63 +615,68 @@ "md5sum": "f68395cc90dc8cddb166a23b2da81b7b" } } - } - }, - "ufo_fight": { - "description": "Fight the UFO boss!", - "external_url": "", - "authors": [ - { - "name": "Cross Joy", - "email": "cross.joy.official@gmail.com", - "discord": "Cross Joy#0721" + }, + "ufo_fight": { + "description": "Fight the UFO boss!", + "external_url": "", + "authors": [ + { + "name": "Cross Joy", + "email": "cross.joy.official@gmail.com", + "discord": "Cross Joy#0721" + } + ], + "versions": { + "1.0.0": { + "api_version": 7, + "commit_sha": "7219487", + "released_on": "15-05-2023", + "md5sum": "81617b130716996368b7d8f20f3a5154" + } } - ], - "versions": { - "1.0.0": { - "api_version": 7, - "commit_sha": "7219487", - "released_on": "15-05-2023", - "md5sum": "81617b130716996368b7d8f20f3a5154" + }, + "yeeting_party": { + "description": "Yeet your enemies out of the map!", + "external_url": "", + "authors": [ + { + "name": "Freaku", + "email": "", + "discord": "[Just] Freak#4999" + } + ], + "versions": { + "1.0.0": { + "api_version": 7, + "commit_sha": "7219487", + "released_on": "15-05-2023", + "md5sum": "197a377652ab0c3bfbe1ca07833924b4" + } } - } - }, - "yeeting_party": { - "description": "Yeet your enemies out of the map!", - "external_url": "", - "authors": [ - { - "name": "Freaku", - "email": "", - "discord": "[Just] Freak#4999" + }, + "supersmash": { + "description": "Blow up your enemies off the map!", + "external_url": "", + "authors": [ + { + "name": "Mrmaxmeier", + "email": "", + "discord": "" + }, + { + "name": "JoseAngel", + "email": "", + "discord": "joseang3l" + } + ], + "versions": { + "1.0.0": { + "api_version": 8, + "commit_sha": "68e77f2", + "released_on": "24-07-2023", + "md5sum": "1cbe5b3e85b5dfcee1eb322f33568fd4" + } } - ], - "versions": { - "1.0.0": { - "api_version": 7, - "commit_sha": "7219487", - "released_on": "15-05-2023", - "md5sum": "197a377652ab0c3bfbe1ca07833924b4" - } - } - }, - "supersmash": { - "description": "Blow up your enemies off the map!", - "external_url": "", - "authors": [ - { - "name": "Mrmaxmeier", - "email": "", - "discord": "" - }, - { - "name": "JoseAngel", - "email": "", - "discord": "joseang3l" - } - ], - "versions": { - "1.0.0": null } } } \ No newline at end of file From cf065bea67aec10c3ea4d7b45310778d8780e622 Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Mon, 24 Jul 2023 15:55:19 +0200 Subject: [PATCH 34/60] Handball minigame --- plugins/minigames/handball.py | 383 ++++++++++++++++++++++++++++++++++ 1 file changed, 383 insertions(+) create mode 100644 plugins/minigames/handball.py diff --git a/plugins/minigames/handball.py b/plugins/minigames/handball.py new file mode 100644 index 0000000..dfb439d --- /dev/null +++ b/plugins/minigames/handball.py @@ -0,0 +1,383 @@ +# Released under the MIT License. See LICENSE for details. +# +"""Hockey game and support classes.""" + +# ba_meta require api 8 +# (see https://ballistica.net/wiki/meta-tag-system) + +from __future__ import annotations + +from typing import TYPE_CHECKING + +import babase +import bauiv1 as bui +import bascenev1 as bs +from bascenev1lib.actor.playerspaz import PlayerSpaz +from bascenev1lib.actor.scoreboard import Scoreboard +from bascenev1lib.actor.powerupbox import PowerupBoxFactory +from bascenev1lib.gameutils import SharedObjects + +if TYPE_CHECKING: + from typing import Any, Sequence, Optional, Union + + +class PuckDiedMessage: + """Inform something that a puck has died.""" + + def __init__(self, puck: Puck): + self.puck = puck + + +class Puck(bs.Actor): + """A lovely giant hockey puck.""" + + def __init__(self, position: Sequence[float] = (0.0, 1.0, 0.0)): + super().__init__() + shared = SharedObjects.get() + activity = self.getactivity() + + # Spawn just above the provided point. + self._spawn_pos = (position[0], position[1] + 1.0, position[2]) + self.last_players_to_touch: dict[int, Player] = {} + self.scored = False + assert activity is not None + assert isinstance(activity, HockeyGame) + pmats = [shared.object_material, activity.puck_material] + self.node = bs.newnode('prop', + delegate=self, + attrs={ + 'mesh': activity.puck_mesh, + 'color_texture': activity.puck_tex, + 'body': 'sphere', + 'reflection': 'soft', + 'reflection_scale': [0.2], + 'shadow_size': 0.8, + 'is_area_of_interest': True, + 'position': self._spawn_pos, + 'materials': pmats + }) + bs.animate(self.node, 'mesh_scale', {0: 0, 0.2: 1.3, 0.26: 1}) + + def handlemessage(self, msg: Any) -> Any: + if isinstance(msg, bs.DieMessage): + assert self.node + self.node.delete() + activity = self._activity() + if activity and not msg.immediate: + activity.handlemessage(PuckDiedMessage(self)) + + # If we go out of bounds, move back to where we started. + elif isinstance(msg, bs.OutOfBoundsMessage): + assert self.node + self.node.position = self._spawn_pos + + elif isinstance(msg, bs.HitMessage): + assert self.node + assert msg.force_direction is not None + self.node.handlemessage( + 'impulse', msg.pos[0], msg.pos[1], msg.pos[2], msg.velocity[0], + msg.velocity[1], msg.velocity[2], 1.0 * msg.magnitude, + 1.0 * msg.velocity_magnitude, msg.radius, 0, + msg.force_direction[0], msg.force_direction[1], + msg.force_direction[2]) + + # If this hit came from a player, log them as the last to touch us. + s_player = msg.get_source_player(Player) + if s_player is not None: + activity = self._activity() + if activity: + if s_player in activity.players: + self.last_players_to_touch[s_player.team.id] = s_player + else: + super().handlemessage(msg) + + +class Player(bs.Player['Team']): + """Our player type for this game.""" + + +class Team(bs.Team[Player]): + """Our team type for this game.""" + + def __init__(self) -> None: + self.score = 0 + + +# ba_meta export bascenev1.GameActivity +class HockeyGame(bs.TeamGameActivity[Player, Team]): + """Ice hockey game.""" + + name = 'Handball' + description = 'Score some goals.' + available_settings = [ + bs.IntSetting( + 'Score to Win', + min_value=1, + default=1, + increment=1, + ), + bs.IntChoiceSetting( + 'Time Limit', + choices=[ + ('None', 0), + ('1 Minute', 60), + ('2 Minutes', 120), + ('5 Minutes', 300), + ('10 Minutes', 600), + ('20 Minutes', 1200), + ], + default=0, + ), + bs.FloatChoiceSetting( + 'Respawn Times', + choices=[ + ('Shorter', 0.25), + ('Short', 0.5), + ('Normal', 1.0), + ('Long', 2.0), + ('Longer', 4.0), + ], + default=1.0, + ), + bs.BoolSetting('Epic Mode', default=False), + + ] + default_music = bs.MusicType.HOCKEY + + @classmethod + def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool: + return issubclass(sessiontype, bs.DualTeamSession) + + @classmethod + def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]: + return bs.app.classic.getmaps('hockey') + + def __init__(self, settings: dict): + super().__init__(settings) + shared = SharedObjects.get() + self._scoreboard = Scoreboard() + self._cheer_sound = bs.getsound('cheer') + self._chant_sound = bs.getsound('crowdChant') + self._foghorn_sound = bs.getsound('foghorn') + self._swipsound = bs.getsound('swip') + self._whistle_sound = bs.getsound('refWhistle') + self.puck_mesh = bs.getmesh('bomb') + self.puck_tex = bs.gettexture('bonesColor') + self._puck_sound = bs.getsound('metalHit') + self._epic_mode = bool(settings['Epic Mode']) + self.slow_motion = self._epic_mode + self.default_music = (bs.MusicType.EPIC + if self._epic_mode else bs.MusicType.FOOTBALL) + self.puck_material = bs.Material() + self.puck_material.add_actions(actions=(('modify_part_collision', + 'friction', 0.5))) + self.puck_material.add_actions(conditions=('they_have_material', + shared.pickup_material), + actions=('modify_part_collision', + 'collide', False)) + self.puck_material = bs.Material() + self.puck_material.add_actions(actions=(('modify_part_collision', + 'friction', 0.5))) + self.puck_material.add_actions(conditions=('they_have_material', + shared.pickup_material), + actions=('modify_part_collision', + 'collide', True)) + self.puck_material.add_actions( + conditions=( + ('we_are_younger_than', 100), + 'and', + ('they_have_material', shared.object_material), + ), + actions=('modify_node_collision', 'collide', False), + ) + self.puck_material.add_actions(conditions=('they_have_material', + shared.footing_material), + actions=('impact_sound', + self._puck_sound, 0.2, 5)) + + # Keep track of which player last touched the puck + self.puck_material.add_actions( + conditions=('they_have_material', shared.player_material), + actions=(('call', 'at_connect', + self._handle_puck_player_collide), )) + + # We want the puck to kill powerups; not get stopped by them + self.puck_material.add_actions( + conditions=('they_have_material', + PowerupBoxFactory.get().powerup_material), + actions=(('modify_part_collision', 'physical', False), + ('message', 'their_node', 'at_connect', bs.DieMessage()))) + self._score_region_material = bs.Material() + self._score_region_material.add_actions( + conditions=('they_have_material', self.puck_material), + actions=(('modify_part_collision', 'collide', + True), ('modify_part_collision', 'physical', False), + ('call', 'at_connect', self._handle_score))) + self._puck_spawn_pos: Optional[Sequence[float]] = None + self._score_regions: Optional[list[bs.NodeActor]] = None + self._puck: Optional[Puck] = None + self._score_to_win = int(settings['Score to Win']) + self._time_limit = float(settings['Time Limit']) + + def get_instance_description(self) -> Union[str, Sequence]: + if self._score_to_win == 1: + return 'Score a goal.' + return 'Score ${ARG1} goals.', self._score_to_win + + def get_instance_description_short(self) -> Union[str, Sequence]: + if self._score_to_win == 1: + return 'score a goal' + return 'score ${ARG1} goals', self._score_to_win + + def on_begin(self) -> None: + super().on_begin() + + self.setup_standard_time_limit(self._time_limit) + self.setup_standard_powerup_drops() + self._puck_spawn_pos = self.map.get_flag_position(None) + self._spawn_puck() + + # Set up the two score regions. + defs = self.map.defs + self._score_regions = [] + self._score_regions.append( + bs.NodeActor( + bs.newnode('region', + attrs={ + 'position': defs.boxes['goal1'][0:3], + 'scale': defs.boxes['goal1'][6:9], + 'type': 'box', + 'materials': [self._score_region_material] + }))) + self._score_regions.append( + bs.NodeActor( + bs.newnode('region', + attrs={ + 'position': defs.boxes['goal2'][0:3], + 'scale': defs.boxes['goal2'][6:9], + 'type': 'box', + 'materials': [self._score_region_material] + }))) + self._update_scoreboard() + self._chant_sound.play() + + def on_team_join(self, team: Team) -> None: + self._update_scoreboard() + + def _handle_puck_player_collide(self) -> None: + collision = bs.getcollision() + try: + puck = collision.sourcenode.getdelegate(Puck, True) + player = collision.opposingnode.getdelegate(PlayerSpaz, + True).getplayer( + Player, True) + except bs.NotFoundError: + return + + puck.last_players_to_touch[player.team.id] = player + + def _kill_puck(self) -> None: + self._puck = None + + def _handle_score(self) -> None: + """A point has been scored.""" + + assert self._puck is not None + assert self._score_regions is not None + + # Our puck might stick around for a second or two + # we don't want it to be able to score again. + if self._puck.scored: + return + + region = bs.getcollision().sourcenode + index = 0 + for index, score_region in enumerate(self._score_regions): + if region == score_region.node: + break + + for team in self.teams: + if team.id == index: + scoring_team = team + team.score += 1 + + # Tell all players to celebrate. + for player in team.players: + if player.actor: + player.actor.handlemessage(bs.CelebrateMessage(2.0)) + + # If we've got the player from the scoring team that last + # touched us, give them points. + if (scoring_team.id in self._puck.last_players_to_touch + and self._puck.last_players_to_touch[scoring_team.id]): + self.stats.player_scored( + self._puck.last_players_to_touch[scoring_team.id], + 100, + big_message=True) + + # End game if we won. + if team.score >= self._score_to_win: + self.end_game() + + self._foghorn_sound.play() + self._cheer_sound.play() + + self._puck.scored = True + + # Kill the puck (it'll respawn itself shortly). + bs.timer(1.0, self._kill_puck) + + light = bs.newnode('light', + attrs={ + 'position': bs.getcollision().position, + 'height_attenuated': False, + 'color': (1, 0, 0) + }) + bs.animate(light, 'intensity', {0: 0, 0.5: 1, 1.0: 0}, loop=True) + bs.timer(1.0, light.delete) + + bs.cameraflash(duration=10.0) + self._update_scoreboard() + + def end_game(self) -> None: + results = bs.GameResults() + for team in self.teams: + results.set_team_score(team, team.score) + self.end(results=results) + + def _update_scoreboard(self) -> None: + winscore = self._score_to_win + for team in self.teams: + self._scoreboard.set_team_value(team, team.score, winscore) + + def handlemessage(self, msg: Any) -> Any: + + # Respawn dead players if they're still in the game. + if isinstance(msg, bs.PlayerDiedMessage): + # Augment standard behavior... + super().handlemessage(msg) + self.respawn_player(msg.getplayer(Player)) + + # Respawn dead pucks. + elif isinstance(msg, PuckDiedMessage): + if not self.has_ended(): + bs.timer(3.0, self._spawn_puck) + else: + super().handlemessage(msg) + + def _flash_puck_spawn(self) -> None: + light = bs.newnode('light', + attrs={ + 'position': self._puck_spawn_pos, + 'height_attenuated': False, + 'color': (1, 0, 0) + }) + bs.animate(light, 'intensity', {0.0: 0, 0.25: 1, 0.5: 0}, loop=True) + bs.timer(1.0, light.delete) + + def _spawn_puck(self) -> None: + self._swipsound.play() + self._whistle_sound.play() + self._flash_puck_spawn() + assert self._puck_spawn_pos is not None + self._puck = Puck(position=self._puck_spawn_pos) From 2309aab5b5cc61a01904ce5d17864319203ead31 Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Mon, 24 Jul 2023 15:58:02 +0200 Subject: [PATCH 35/60] Update minigames.json --- plugins/minigames.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index c394833..3c33d17 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -654,6 +654,20 @@ } } }, + "handball": { + "description": "Score some goals with handball", + "external_url": "", + "authors": [ + { + "name": "Unknown", + "email": "", + "discord": "" + } + ], + "versions": { + "1.0.0":null + } + }, "supersmash": { "description": "Blow up your enemies off the map!", "external_url": "", @@ -679,4 +693,4 @@ } } } -} \ No newline at end of file +} From 3ae4d768c9cf18c840d3c9a2ae25560205b9f308 Mon Sep 17 00:00:00 2001 From: SenjuZoro Date: Mon, 24 Jul 2023 13:59:30 +0000 Subject: [PATCH 36/60] [ci] apply-version-metadata --- plugins/minigames.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index 3c33d17..6a489c8 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -665,7 +665,12 @@ } ], "versions": { - "1.0.0":null + "1.0.0": { + "api_version": 8, + "commit_sha": "2309aab", + "released_on": "24-07-2023", + "md5sum": "01b85dc9ef1d464ab604387af09f05dc" + } } }, "supersmash": { @@ -693,4 +698,4 @@ } } } -} +} \ No newline at end of file From e5efd30159d835dc824a66e1a5e41dbc8b50ff5e Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Wed, 26 Jul 2023 20:52:27 +0200 Subject: [PATCH 37/60] arms race updated arms race updated to api 8 --- plugins/minigames/arms_race.py | 93 +++++++++++++++------------------- 1 file changed, 40 insertions(+), 53 deletions(-) diff --git a/plugins/minigames/arms_race.py b/plugins/minigames/arms_race.py index b7ea3f5..1ac367a 100644 --- a/plugins/minigames/arms_race.py +++ b/plugins/minigames/arms_race.py @@ -1,22 +1,26 @@ -# Ported by: Freaku / @[Just] Freak#4999 +#Ported by: Freaku / @[Just] Freak#4999 -# Join BCS: +#Join BCS: # https://discord.gg/ucyaesh -# ba_meta require api 7 + +# ba_meta require api 8 from __future__ import annotations from typing import TYPE_CHECKING -import ba -from bastd.actor.playerspaz import PlayerSpaz +import babase +import bauiv1 as bui +import bascenev1 as bs +from bascenev1lib.actor.playerspaz import PlayerSpaz if TYPE_CHECKING: from typing import Any, Type, List, Dict, Tuple, Union, Sequence, Optional + class State: def __init__(self, bomb=None, grab=False, punch=False, curse=False, required=False, final=False, name=''): self.bomb = bomb @@ -30,12 +34,11 @@ class State: self.next = None self.index = None - def apply(self, player, spaz): - + def apply(self, spaz): spaz.disconnect_controls_from_player() spaz.connect_controls_to_player(enable_punch=self.punch, - enable_bomb=self.bomb, - enable_pickup=self.grab) + enable_bomb=self.bomb, + enable_pickup=self.grab) if self.curse: spaz.curse_time = -1 spaz.curse() @@ -43,47 +46,33 @@ class State: spaz.bomb_type = self.bomb spaz.set_score_text(self.name) - def set_controls(): - player.actor.node.bomb_pressed = True - player.actor.on_bomb_release() - - release_input = (ba.InputType.PUNCH_RELEASE, ba.InputType.PICK_UP_RELEASE) - if not self.bomb is None: - for release in release_input: - player.assigninput( - release, - set_controls - ) - def get_setting(self): return (self.name) -states = [State(bomb='normal', name='Basic Bombs'), - State(bomb='ice', name='Frozen Bombs'), - State(bomb='sticky', name='Sticky Bombs'), - State(bomb='impact', name='Impact Bombs'), - State(grab=True, name='Grabbing only'), - State(punch=True, name='Punching only'), - State(curse=True, name='Cursed', final=True)] +states = [ State(bomb='normal', name='Basic Bombs'), + State(bomb='ice', name='Frozen Bombs'), + State(bomb='sticky', name='Sticky Bombs'), + State(bomb='impact', name='Impact Bombs'), + State(grab=True, name='Grabbing only'), + State(punch=True, name='Punching only'), + State(curse=True, name='Cursed', final=True) ] - -class Player(ba.Player['Team']): +class Player(bs.Player['Team']): """Our player type for this game.""" - def __init__(self): self.state = None -class Team(ba.Team[Player]): +class Team(bs.Team[Player]): """Our team type for this game.""" def __init__(self) -> None: self.score = 0 -# ba_meta export game -class ArmsRaceGame(ba.TeamGameActivity[Player, Team]): +# ba_meta export bascenev1.GameActivity +class ArmsRaceGame(bs.TeamGameActivity[Player, Team]): """A game type based on acquiring kills.""" name = 'Arms Race' @@ -94,9 +83,9 @@ class ArmsRaceGame(ba.TeamGameActivity[Player, Team]): @classmethod def get_available_settings( - cls, sessiontype: Type[ba.Session]) -> List[ba.Setting]: + cls, sessiontype: Type[bs.Session]) -> List[babase.Setting]: settings = [ - ba.IntChoiceSetting( + bs.IntChoiceSetting( 'Time Limit', choices=[ ('None', 0), @@ -108,7 +97,7 @@ class ArmsRaceGame(ba.TeamGameActivity[Player, Team]): ], default=0, ), - ba.FloatChoiceSetting( + bs.FloatChoiceSetting( 'Respawn Times', choices=[ ('Shorter', 0.25), @@ -119,21 +108,21 @@ class ArmsRaceGame(ba.TeamGameActivity[Player, Team]): ], default=1.0, ), - ba.BoolSetting('Epic Mode', default=False)] + bs.BoolSetting('Epic Mode', default=False)] for state in states: if not state.required: - settings.append(ba.BoolSetting(state.get_setting(), default=True)) + settings.append(bs.BoolSetting(state.get_setting(), default=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]: - return ba.getmaps('melee') + def get_supported_maps(cls, sessiontype: Type[bs.Session]) -> List[str]: + return bs.app.classic.getmaps('melee') def __init__(self, settings: dict): super().__init__(settings) @@ -142,14 +131,14 @@ class ArmsRaceGame(ba.TeamGameActivity[Player, Team]): if i < len(self.states) and not state.final: state.next = self.states[i + 1] state.index = i - self._dingsound = ba.getsound('dingSmall') + self._dingsound = bs.getsound('dingSmall') self._epic_mode = bool(settings['Epic Mode']) self._time_limit = float(settings['Time Limit']) # 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) + self.default_music = (bs.MusicType.EPIC if self._epic_mode else + bs.MusicType.TO_THE_DEATH) def get_instance_description(self) -> Union[str, Sequence]: return 'Upgrade your weapon by eliminating enemies.' @@ -168,12 +157,11 @@ class ArmsRaceGame(ba.TeamGameActivity[Player, Team]): self.spawn_player(player) # overriding the default character spawning.. - def spawn_player(self, player): if player.state is None: player.state = self.states[0] super().spawn_player(player) - player.state.apply(player, player.actor) + player.state.apply(player.actor) def isValidKill(self, m): if m.getkillerplayer(Player) is None: @@ -186,13 +174,12 @@ class ArmsRaceGame(ba.TeamGameActivity[Player, Team]): def handlemessage(self, msg: Any) -> Any: - if isinstance(msg, ba.PlayerDiedMessage): + if isinstance(msg, bs.PlayerDiedMessage): if self.isValidKill(msg): self.stats.player_scored(msg.getkillerplayer(Player), 10, kill=True) if not msg.getkillerplayer(Player).state.final: msg.getkillerplayer(Player).state = msg.getkillerplayer(Player).state.next - msg.getkillerplayer(Player).state.apply( - msg.getkillerplayer(Player), msg.getkillerplayer(Player).actor) + msg.getkillerplayer(Player).state.apply(msg.getkillerplayer(Player).actor) else: msg.getkillerplayer(Player).team.score += 1 self.end_game() @@ -203,7 +190,7 @@ class ArmsRaceGame(ba.TeamGameActivity[Player, Team]): return None 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) From 693eac617291472cde0f3392f3d895ba2305e2df Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Wed, 26 Jul 2023 20:53:38 +0200 Subject: [PATCH 38/60] Update minigames.json --- plugins/minigames.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index 6a489c8..06b1391 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -433,6 +433,7 @@ } ], "versions": { + "2.0.0":null, "1.1.0": { "api_version": 7, "commit_sha": "2e2540a", @@ -698,4 +699,4 @@ } } } -} \ No newline at end of file +} From e7a5df9aacaaa2193dd051219272772e77eed06e Mon Sep 17 00:00:00 2001 From: SenjuZoro Date: Wed, 26 Jul 2023 18:55:16 +0000 Subject: [PATCH 39/60] [ci] auto-format --- plugins/minigames/arms_race.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/plugins/minigames/arms_race.py b/plugins/minigames/arms_race.py index 1ac367a..6f7351b 100644 --- a/plugins/minigames/arms_race.py +++ b/plugins/minigames/arms_race.py @@ -1,10 +1,9 @@ -#Ported by: Freaku / @[Just] Freak#4999 +# Ported by: Freaku / @[Just] Freak#4999 -#Join BCS: +# Join BCS: # https://discord.gg/ucyaesh - # ba_meta require api 8 from __future__ import annotations @@ -20,7 +19,6 @@ if TYPE_CHECKING: from typing import Any, Type, List, Dict, Tuple, Union, Sequence, Optional - class State: def __init__(self, bomb=None, grab=False, punch=False, curse=False, required=False, final=False, name=''): self.bomb = bomb @@ -37,8 +35,8 @@ class State: def apply(self, spaz): spaz.disconnect_controls_from_player() spaz.connect_controls_to_player(enable_punch=self.punch, - enable_bomb=self.bomb, - enable_pickup=self.grab) + enable_bomb=self.bomb, + enable_pickup=self.grab) if self.curse: spaz.curse_time = -1 spaz.curse() @@ -50,16 +48,18 @@ class State: return (self.name) -states = [ State(bomb='normal', name='Basic Bombs'), - State(bomb='ice', name='Frozen Bombs'), - State(bomb='sticky', name='Sticky Bombs'), - State(bomb='impact', name='Impact Bombs'), - State(grab=True, name='Grabbing only'), - State(punch=True, name='Punching only'), - State(curse=True, name='Cursed', final=True) ] +states = [State(bomb='normal', name='Basic Bombs'), + State(bomb='ice', name='Frozen Bombs'), + State(bomb='sticky', name='Sticky Bombs'), + State(bomb='impact', name='Impact Bombs'), + State(grab=True, name='Grabbing only'), + State(punch=True, name='Punching only'), + State(curse=True, name='Cursed', final=True)] + class Player(bs.Player['Team']): """Our player type for this game.""" + def __init__(self): self.state = None From bbad78c1692e1cf1d15428e2a67167d45dd9dfb1 Mon Sep 17 00:00:00 2001 From: SenjuZoro Date: Wed, 26 Jul 2023 18:55:18 +0000 Subject: [PATCH 40/60] [ci] apply-version-metadata --- plugins/minigames.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index 06b1391..8d26d8c 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -433,7 +433,12 @@ } ], "versions": { - "2.0.0":null, + "2.0.0": { + "api_version": 8, + "commit_sha": "e7a5df9", + "released_on": "26-07-2023", + "md5sum": "641732ef5c8c97cd5482b8cd56126310" + }, "1.1.0": { "api_version": 7, "commit_sha": "2e2540a", @@ -699,4 +704,4 @@ } } } -} +} \ No newline at end of file From 651fc66aff25428b7282d7d284ffc19e42a09d8f Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Thu, 27 Jul 2023 12:46:41 +0200 Subject: [PATCH 41/60] New game mode Big Ball Works with latest api 8 --- plugins/minigames/big_ball.py | 517 ++++++++++++++++++++++++++++++++++ 1 file changed, 517 insertions(+) create mode 100644 plugins/minigames/big_ball.py diff --git a/plugins/minigames/big_ball.py b/plugins/minigames/big_ball.py new file mode 100644 index 0000000..ead6615 --- /dev/null +++ b/plugins/minigames/big_ball.py @@ -0,0 +1,517 @@ +#Made by MythB +#Ported by: MysteriousBoi + + + + + + +# ba_meta require api 8 +from __future__ import annotations +from typing import TYPE_CHECKING +import babase +import bauiv1 as bui +import bascenev1 as bs,random +from bascenev1lib.actor.playerspaz import PlayerSpaz +from bascenev1lib.actor.scoreboard import Scoreboard +from bascenev1lib.actor.powerupbox import PowerupBoxFactory +from bascenev1lib.gameutils import SharedObjects +from bascenev1lib.actor.flag import Flag +if TYPE_CHECKING: + from typing import Any, Sequence, Dict, Type, List, Optional, Union + + +class PuckDiedMessage: + """Inform something that a puck has died.""" + + def __init__(self, puck: Puck): + self.puck = puck + +#goalpost +class FlagKale(bs.Actor): + def __init__(self,position=(0,2.5,0),color=(1,1,1)): + super().__init__() + activity = self.getactivity() + shared = SharedObjects.get() + self.node = bs.newnode('flag', + attrs={'position':(position[0],position[1]+0.75,position[2]), + 'color_texture':activity._flagKaleTex, + 'color':color, + 'materials':[shared.object_material,activity._kaleMaterial], + }, + delegate=self) + + def handleMessage(self,m): + if isinstance(m,bs.DieMessage): + if self.node.exists(): + self.node.delete() + elif isinstance(m,bs.OutOfBoundsMessage): + self.handlemessage(bs.DieMessage()) + else: + super().handlemessage(msg) + + +class Puck(bs.Actor): + def __init__(self, position: Sequence[float] = (0.0, 1.0, 0.0)): + super().__init__() + shared = SharedObjects.get() + activity = self.getactivity() + + # Spawn just above the provided point. + self._spawn_pos = (position[0], position[1] + 1.0, position[2]) + self.last_players_to_touch: Dict[int, Player] = {} + self.scored = False + assert activity is not None + assert isinstance(activity, BBGame) + pmats = [shared.object_material, activity.puck_material] + self.node = bs.newnode('prop', + delegate=self, + attrs={ + 'mesh': activity._ballModel, + 'color_texture': activity._ballTex, + 'body': 'sphere', + 'reflection': 'soft', + 'reflection_scale': [0.2], + 'shadow_size': 0.8, + 'is_area_of_interest': True, + 'position': self._spawn_pos, + 'materials': pmats, + 'body_scale': 4, + 'mesh_scale': 1, + 'density': 0.02}) + bs.animate(self.node, 'mesh_scale', {0: 0, 0.2: 1.3, 0.26: 1}) + + def handlemessage(self, msg: Any) -> Any: + if isinstance(msg, bs.DieMessage): + assert self.node + self.node.delete() + activity = self._activity() + if activity and not msg.immediate: + activity.handlemessage(PuckDiedMessage(self)) + + # If we go out of bounds, move back to where we started. + elif isinstance(msg, bs.OutOfBoundsMessage): + assert self.node + self.node.position = self._spawn_pos + + elif isinstance(msg, bs.HitMessage): + assert self.node + assert msg.force_direction is not None + self.node.handlemessage( + 'impulse', msg.pos[0], msg.pos[1], msg.pos[2], msg.velocity[0], + msg.velocity[1], msg.velocity[2], 1.0 * msg.magnitude, + 1.0 * msg.velocity_magnitude, msg.radius, 0, + msg.force_direction[0], msg.force_direction[1], + msg.force_direction[2]) + + # If this hit came from a player, log them as the last to touch us. + s_player = msg.get_source_player(Player) + if s_player is not None: + activity = self._activity() + if activity: + if s_player in activity.players: + self.last_players_to_touch[s_player.team.id] = s_player + else: + super().handlemessage(msg) + +#for night mode: using a actor with large shadow and little mesh scale. Better then tint i think, players and objects more visible +class NightMod(bs.Actor): + def __init__(self,position=(0,0,0)): + super().__init__() + shared = SharedObjects.get() + activity = self.getactivity() + # spawn just above the provided point + self._spawnPos = (position[0],position[1],position[2]) + self.node = bs.newnode("prop", + attrs={'mesh': activity._nightModel, + 'color_texture': activity._nightTex, + 'body':'sphere', + 'reflection':'soft', + 'body_scale': 0.1, + 'mesh_scale':0.001, + 'density':0.010, + 'reflection_scale':[0.23], + 'shadow_size': 999999.0, + 'is_area_of_interest':True, + 'position':self._spawnPos, + 'materials': [activity._nightMaterial] + }, + delegate=self) + + def handlemssage(self,m): + super().handlemessage(m) + + +class Player(bs.Player['Team']): + """Our player type for this game.""" + + +class Team(bs.Team[Player]): + """Our team type for this game.""" + + def __init__(self) -> None: + self.score = 0 + + +# ba_meta export bascenev1.GameActivity +class BBGame(bs.TeamGameActivity[Player, Team]): + name = 'Big Ball' + description = 'Score some goals.\nFlags are goalposts.\nScored team players get boxing gloves,\nNon-scored team players getting shield (if Grant Powers on Score).\nYou can also set Night Mode!' + available_settings = [ + bs.IntSetting( + 'Score to Win', + min_value=1, + default=1, + increment=1, + ), + bs.IntChoiceSetting( + 'Time Limit', + choices=[ + ('None', 0), + ('1 Minute', 60), + ('2 Minutes', 120), + ('5 Minutes', 300), + ('10 Minutes', 600), + ('20 Minutes', 1200), + ], + default=0, + ), + bs.FloatChoiceSetting( + 'Respawn Times', + choices=[ + ('Shorter', 0.25), + ('Short', 0.5), + ('Normal', 1.0), + ('Long', 2.0), + ('Longer', 4.0), + ], + default=1.0, + ), + bs.BoolSetting('Epic Mode', True), + bs.BoolSetting('Night Mode', False), + bs.BoolSetting('Grant Powers on Score', False) + ] + default_music = bs.MusicType.HOCKEY + + @classmethod + def supports_session_type(cls, sessiontype: Type[bs.Session]) -> bool: + return issubclass(sessiontype, bs.DualTeamSession) + + @classmethod + def get_supported_maps(cls, sessiontype: Type[bs.Session]) -> List[str]: + return ['Football Stadium'] + + def __init__(self, settings: dict): + super().__init__(settings) + shared = SharedObjects.get() + self._scoreboard = Scoreboard() + self._cheer_sound = bs.getsound('cheer') + self._chant_sound = bs.getsound('crowdChant') + self._foghorn_sound = bs.getsound('foghorn') + self._swipsound = bs.getsound('swip') + self._whistle_sound = bs.getsound('refWhistle') + self._ballModel = bs.getmesh("shield") + self._ballTex = bs.gettexture("eggTex1") + self._ballSound = bs.getsound("impactMedium2") + self._flagKaleTex = bs.gettexture("star") + self._kaleSound = bs.getsound("metalHit") + self._nightModel = bs.getmesh("shield") + self._nightTex = bs.gettexture("black") + self._kaleMaterial = bs.Material() + #add friction to flags for standing our position (as far as) + self._kaleMaterial.add_actions(conditions=("they_have_material",shared.footing_material), + actions=( ("modify_part_collision","friction",9999.5))) + self._kaleMaterial.add_actions(conditions=( ("we_are_younger_than",1),'and', + ("they_have_material",shared.object_material)), + actions=( ("modify_part_collision","collide",False))) + self._kaleMaterial.add_actions(conditions=("they_have_material",shared.pickup_material), + actions=( ("modify_part_collision","collide",False))) + self._kaleMaterial.add_actions( + conditions=('they_have_material',shared.object_material), + actions=(('impact_sound',self._kaleSound,2,5))) + #we dont wanna hit the night so + self._nightMaterial = bs.Material() + self._nightMaterial.add_actions(conditions=(('they_have_material',shared.pickup_material),'or', + ('they_have_material',shared.attack_material)), + actions=(('modify_part_collision','collide',False))) + # we also dont want anything moving it + self._nightMaterial.add_actions( + conditions=(('they_have_material',shared.object_material),'or', + ('they_dont_have_material',shared.footing_material)), + actions=(('modify_part_collision','collide',False), + ('modify_part_collision','physical',False))) + self.puck_material = bs.Material() + self.puck_material.add_actions(actions=(('modify_part_collision', + 'friction', 0.5))) + self.puck_material.add_actions(conditions=('they_have_material', + shared.pickup_material), + actions=('modify_part_collision', + 'collide', False)) + self.puck_material.add_actions( + conditions=( + ('we_are_younger_than', 100), + 'and', + ('they_have_material', shared.object_material), + ), + actions=('modify_node_collision', 'collide', False), + ) + self.puck_material.add_actions(conditions=('they_have_material', + shared.footing_material), + actions=('impact_sound', + self._ballSound, 0.2, 5)) + + # Keep track of which player last touched the puck + self.puck_material.add_actions( + conditions=('they_have_material', shared.player_material), + actions=(('call', 'at_connect', + self._handle_puck_player_collide), )) + + # We want the puck to kill powerups; not get stopped by them + self.puck_material.add_actions( + conditions=('they_have_material', + PowerupBoxFactory.get().powerup_material), + actions=(('modify_part_collision', 'physical', False), + ('message', 'their_node', 'at_connect', bs.DieMessage()))) + self._score_region_material = bs.Material() + self._score_region_material.add_actions( + conditions=('they_have_material', self.puck_material), + actions=(('modify_part_collision', 'collide', + True), ('modify_part_collision', 'physical', False), + ('call', 'at_connect', self._handle_score))) + self._puck_spawn_pos: Optional[Sequence[float]] = None + self._score_regions: Optional[List[bs.NodeActor]] = None + self._puck: Optional[Puck] = None + self._score_to_win = int(settings['Score to Win']) + self._time_limit = float(settings['Time Limit']) + self._nm = bool(settings['Night Mode']) + self._grant_power = bool(settings['Grant Powers on Score']) + self._epic_mode = bool(settings['Epic Mode']) + # Base class overrides. + self.slow_motion = self._epic_mode + + def get_instance_description(self) -> Union[str, Sequence]: + if self._score_to_win == 1: + return 'Score a goal.' + return 'Score ${ARG1} goals.', self._score_to_win + + def get_instance_description_short(self) -> Union[str, Sequence]: + if self._score_to_win == 1: + return 'score a goal' + return 'score ${ARG1} goals', self._score_to_win + + def on_begin(self) -> None: + super().on_begin() + + self.setup_standard_time_limit(self._time_limit) + self.setup_standard_powerup_drops() + self._puck_spawn_pos = self.map.get_flag_position(None) + self._spawn_puck() + #for night mode we need night actor. And same goodies for nigh mode + if self._nm: self._nightSpawny(),self._flagKaleFlash() + + # Set up the two score regions. + defs = self.map.defs + self._score_regions = [] + self._score_regions.append( + bs.NodeActor( + bs.newnode('region', + attrs={ + 'position': (13.75, 0.85744967453, 0.1095578275), + 'scale': (1.05,1.1,3.8), + 'type': 'box', + 'materials': [self._score_region_material] + }))) + self._score_regions.append( + bs.NodeActor( + bs.newnode('region', + attrs={ + 'position': (-13.55, 0.85744967453, 0.1095578275), + 'scale': (1.05,1.1,3.8), + 'type': 'box', + 'materials': [self._score_region_material] + }))) + self._update_scoreboard() + self._chant_sound.play() + + def _nightSpawny(self): + self.MythBrk = NightMod(position=(0, 0.05744967453, 0)) + + #spawn some goodies on nightmode for pretty visuals + def _flagKaleFlash(self): + #flags positions + kale1 = (-12.45, 0.05744967453, -2.075) + kale2 = (-12.45, 0.05744967453, 2.075) + kale3 = (12.66, 0.03986567039, 2.075) + kale4 = (12.66, 0.03986567039, -2.075) + + flash = bs.newnode("light", + attrs={'position':kale1, + 'radius':0.15, + 'color':(1.0,1.0,0.7)}) + + flash = bs.newnode("light", + attrs={'position':kale2, + 'radius':0.15, + 'color':(1.0,1.0,0.7)}) + + flash = bs.newnode("light", + attrs={'position':kale3, + 'radius':0.15, + 'color':(0.7,1.0,1.0)}) + + flash = bs.newnode("light", + attrs={'position':kale4, + 'radius':0.15, + 'color':(0.7,1.0,1.0)}) + #flags positions + def _flagKalesSpawn(self): + for team in self.teams: + if team.id == 0: + _colorTeam0 = team.color + if team.id == 1: + _colorTeam1 = team.color + + self._MythB = FlagKale(position=(-12.45, 0.05744967453, -2.075),color=_colorTeam0) + self._MythB2 =FlagKale(position=(-12.45, 0.05744967453, 2.075),color=_colorTeam0) + self._MythB3 =FlagKale(position=(12.66, 0.03986567039, 2.075),color=_colorTeam1) + self._MythB4 =FlagKale(position=(12.66, 0.03986567039, -2.075),color=_colorTeam1) + + def on_team_join(self, team: Team) -> None: + self._update_scoreboard() + + def _handle_puck_player_collide(self) -> None: + collision = bs.getcollision() + try: + puck = collision.sourcenode.getdelegate(Puck, True) + player = collision.opposingnode.getdelegate(PlayerSpaz, + True).getplayer( + Player, True) + except bs.NotFoundError: + return + + puck.last_players_to_touch[player.team.id] = player + + def _kill_puck(self) -> None: + self._puck = None + + def _handle_score(self) -> None: + """A point has been scored.""" + + assert self._puck is not None + assert self._score_regions is not None + + # Our puck might stick around for a second or two + # we don't want it to be able to score again. + if self._puck.scored: + return + + region = bs.getcollision().sourcenode + index = 0 + for index in range(len(self._score_regions)): + if region == self._score_regions[index].node: + break + + for team in self.teams: + if team.id == index: + scoring_team = team + team.score += 1 + + # tell scored team players to celebrate and give them to boxing gloves + if self._grant_power: + for player in team.players: + try: player.actor.node.handlemessage(bs.PowerupMessage('punch')) + except: pass + + # Tell all players to celebrate. + for player in team.players: + if player.actor: + player.actor.handlemessage(bs.CelebrateMessage(2.0)) + + # If we've got the player from the scoring team that last + # touched us, give them points. + if (scoring_team.id in self._puck.last_players_to_touch + and self._puck.last_players_to_touch[scoring_team.id]): + self.stats.player_scored( + self._puck.last_players_to_touch[scoring_team.id], + 100, + big_message=True) + + # End game if we won. + if team.score >= self._score_to_win: + self.end_game() + else: + if self._grant_power: + for player in team.players: + try: player.actor.node.handlemessage(bs.PowerupMessage('shield')) + except: pass + + self._foghorn_sound.play() + self._cheer_sound.play() + + self._puck.scored = True + + # Kill the puck (it'll respawn itself shortly). + bs.timer(1.0, self._kill_puck) + + light = bs.newnode('light', + attrs={ + 'position': bs.getcollision().position, + 'height_attenuated': False, + 'color': (1, 0, 0) + }) + bs.animate(light, 'intensity', {0: 0, 0.5: 1, 1.0: 0}, loop=True) + bs.timer(1.0, light.delete) + + bs.cameraflash(duration=10.0) + self._update_scoreboard() + + def end_game(self) -> None: + results = bs.GameResults() + for team in self.teams: + results.set_team_score(team, team.score) + self.end(results=results) + + def _update_scoreboard(self) -> None: + winscore = self._score_to_win + for team in self.teams: + self._scoreboard.set_team_value(team, team.score, winscore) + + def handlemessage(self, msg: Any) -> Any: + + # Respawn dead players if they're still in the game. + if isinstance(msg, bs.PlayerDiedMessage): + # Augment standard behavior... + super().handlemessage(msg) + self.respawn_player(msg.getplayer(Player)) + + # Respawn dead pucks. + elif isinstance(msg, PuckDiedMessage): + if not self.has_ended(): + bs.timer(3.0, self._spawn_puck) + else: + super().handlemessage(msg) + + def _flash_puck_spawn(self) -> None: + light = bs.newnode('light', + attrs={ + 'position': self._puck_spawn_pos, + 'height_attenuated': False, + 'color': (1, 0, 0) + }) + bs.animate(light, 'intensity', {0.0: 0, 0.25: 1, 0.5: 0}, loop=True) + bs.timer(1.0, light.delete) + + def _spawn_puck(self) -> None: + self._swipsound.play() + self._whistle_sound.play() + self._flagKalesSpawn() + self._flash_puck_spawn() + assert self._puck_spawn_pos is not None + self._puck = Puck(position=self._puck_spawn_pos) + self._puck.light = bs.newnode('light', + owner=self._puck.node, + attrs={'intensity':0.3, + 'height_attenuated':False, + 'radius':0.2, + 'color': (0.9,0.2,0.9)}) + self._puck.node.connectattr('position',self._puck.light,'position') From 27bb489a1fd405deb025f57ff402b95b95e032a8 Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Thu, 27 Jul 2023 12:49:24 +0200 Subject: [PATCH 42/60] Update minigames.json --- plugins/minigames.json | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index 8d26d8c..6fcff11 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -660,6 +660,19 @@ } } }, + "big_ball": { + "description": "Score some goals with Big Ball on Football map", + "external_url": "", + "authors": [ + { + "name": "MythB", + "email": "", + "discord": "" + } + ], + "versions": { + "1.0.0":null + } "handball": { "description": "Score some goals with handball", "external_url": "", @@ -704,4 +717,4 @@ } } } -} \ No newline at end of file +} From 21821c0328fdcc561731f347eb32f72ad5eaee50 Mon Sep 17 00:00:00 2001 From: SenjuZoro Date: Thu, 27 Jul 2023 10:58:18 +0000 Subject: [PATCH 43/60] [ci] auto-format --- plugins/minigames/big_ball.py | 171 ++++++++++++++++++---------------- 1 file changed, 89 insertions(+), 82 deletions(-) diff --git a/plugins/minigames/big_ball.py b/plugins/minigames/big_ball.py index ead6615..9976722 100644 --- a/plugins/minigames/big_ball.py +++ b/plugins/minigames/big_ball.py @@ -1,9 +1,5 @@ -#Made by MythB -#Ported by: MysteriousBoi - - - - +# Made by MythB +# Ported by: MysteriousBoi # ba_meta require api 8 @@ -11,7 +7,8 @@ from __future__ import annotations from typing import TYPE_CHECKING import babase import bauiv1 as bui -import bascenev1 as bs,random +import bascenev1 as bs +import random from bascenev1lib.actor.playerspaz import PlayerSpaz from bascenev1lib.actor.scoreboard import Scoreboard from bascenev1lib.actor.powerupbox import PowerupBoxFactory @@ -27,25 +24,27 @@ class PuckDiedMessage: def __init__(self, puck: Puck): self.puck = puck -#goalpost +# goalpost + + class FlagKale(bs.Actor): - def __init__(self,position=(0,2.5,0),color=(1,1,1)): + def __init__(self, position=(0, 2.5, 0), color=(1, 1, 1)): super().__init__() activity = self.getactivity() shared = SharedObjects.get() self.node = bs.newnode('flag', - attrs={'position':(position[0],position[1]+0.75,position[2]), - 'color_texture':activity._flagKaleTex, - 'color':color, - 'materials':[shared.object_material,activity._kaleMaterial], - }, + attrs={'position': (position[0], position[1]+0.75, position[2]), + 'color_texture': activity._flagKaleTex, + 'color': color, + 'materials': [shared.object_material, activity._kaleMaterial], + }, delegate=self) - def handleMessage(self,m): - if isinstance(m,bs.DieMessage): + def handleMessage(self, m): + if isinstance(m, bs.DieMessage): if self.node.exists(): self.node.delete() - elif isinstance(m,bs.OutOfBoundsMessage): + elif isinstance(m, bs.OutOfBoundsMessage): self.handlemessage(bs.DieMessage()) else: super().handlemessage(msg) @@ -76,9 +75,9 @@ class Puck(bs.Actor): 'is_area_of_interest': True, 'position': self._spawn_pos, 'materials': pmats, - 'body_scale': 4, + 'body_scale': 4, 'mesh_scale': 1, - 'density': 0.02}) + 'density': 0.02}) bs.animate(self.node, 'mesh_scale', {0: 0, 0.2: 1.3, 0.26: 1}) def handlemessage(self, msg: Any) -> Any: @@ -114,31 +113,33 @@ class Puck(bs.Actor): else: super().handlemessage(msg) -#for night mode: using a actor with large shadow and little mesh scale. Better then tint i think, players and objects more visible +# for night mode: using a actor with large shadow and little mesh scale. Better then tint i think, players and objects more visible + + class NightMod(bs.Actor): - def __init__(self,position=(0,0,0)): + def __init__(self, position=(0, 0, 0)): super().__init__() shared = SharedObjects.get() activity = self.getactivity() # spawn just above the provided point - self._spawnPos = (position[0],position[1],position[2]) + self._spawnPos = (position[0], position[1], position[2]) self.node = bs.newnode("prop", attrs={'mesh': activity._nightModel, 'color_texture': activity._nightTex, - 'body':'sphere', - 'reflection':'soft', + 'body': 'sphere', + 'reflection': 'soft', 'body_scale': 0.1, - 'mesh_scale':0.001, - 'density':0.010, - 'reflection_scale':[0.23], + 'mesh_scale': 0.001, + 'density': 0.010, + 'reflection_scale': [0.23], 'shadow_size': 999999.0, - 'is_area_of_interest':True, - 'position':self._spawnPos, + 'is_area_of_interest': True, + 'position': self._spawnPos, 'materials': [activity._nightMaterial] }, delegate=self) - def handlemssage(self,m): + def handlemssage(self, m): super().handlemessage(m) @@ -218,28 +219,28 @@ class BBGame(bs.TeamGameActivity[Player, Team]): self._nightModel = bs.getmesh("shield") self._nightTex = bs.gettexture("black") self._kaleMaterial = bs.Material() - #add friction to flags for standing our position (as far as) - self._kaleMaterial.add_actions(conditions=("they_have_material",shared.footing_material), - actions=( ("modify_part_collision","friction",9999.5))) - self._kaleMaterial.add_actions(conditions=( ("we_are_younger_than",1),'and', - ("they_have_material",shared.object_material)), - actions=( ("modify_part_collision","collide",False))) - self._kaleMaterial.add_actions(conditions=("they_have_material",shared.pickup_material), - actions=( ("modify_part_collision","collide",False))) + # add friction to flags for standing our position (as far as) + self._kaleMaterial.add_actions(conditions=("they_have_material", shared.footing_material), + actions=(("modify_part_collision", "friction", 9999.5))) + self._kaleMaterial.add_actions(conditions=(("we_are_younger_than", 1), 'and', + ("they_have_material", shared.object_material)), + actions=(("modify_part_collision", "collide", False))) + self._kaleMaterial.add_actions(conditions=("they_have_material", shared.pickup_material), + actions=(("modify_part_collision", "collide", False))) self._kaleMaterial.add_actions( - conditions=('they_have_material',shared.object_material), - actions=(('impact_sound',self._kaleSound,2,5))) - #we dont wanna hit the night so + conditions=('they_have_material', shared.object_material), + actions=(('impact_sound', self._kaleSound, 2, 5))) + # we dont wanna hit the night so self._nightMaterial = bs.Material() - self._nightMaterial.add_actions(conditions=(('they_have_material',shared.pickup_material),'or', - ('they_have_material',shared.attack_material)), - actions=(('modify_part_collision','collide',False))) + self._nightMaterial.add_actions(conditions=(('they_have_material', shared.pickup_material), 'or', + ('they_have_material', shared.attack_material)), + actions=(('modify_part_collision', 'collide', False))) # we also dont want anything moving it self._nightMaterial.add_actions( - conditions=(('they_have_material',shared.object_material),'or', - ('they_dont_have_material',shared.footing_material)), - actions=(('modify_part_collision','collide',False), - ('modify_part_collision','physical',False))) + conditions=(('they_have_material', shared.object_material), 'or', + ('they_dont_have_material', shared.footing_material)), + actions=(('modify_part_collision', 'collide', False), + ('modify_part_collision', 'physical', False))) self.puck_material = bs.Material() self.puck_material.add_actions(actions=(('modify_part_collision', 'friction', 0.5))) @@ -306,8 +307,9 @@ class BBGame(bs.TeamGameActivity[Player, Team]): self.setup_standard_powerup_drops() self._puck_spawn_pos = self.map.get_flag_position(None) self._spawn_puck() - #for night mode we need night actor. And same goodies for nigh mode - if self._nm: self._nightSpawny(),self._flagKaleFlash() + # for night mode we need night actor. And same goodies for nigh mode + if self._nm: + self._nightSpawny(), self._flagKaleFlash() # Set up the two score regions. defs = self.map.defs @@ -317,7 +319,7 @@ class BBGame(bs.TeamGameActivity[Player, Team]): bs.newnode('region', attrs={ 'position': (13.75, 0.85744967453, 0.1095578275), - 'scale': (1.05,1.1,3.8), + 'scale': (1.05, 1.1, 3.8), 'type': 'box', 'materials': [self._score_region_material] }))) @@ -326,7 +328,7 @@ class BBGame(bs.TeamGameActivity[Player, Team]): bs.newnode('region', attrs={ 'position': (-13.55, 0.85744967453, 0.1095578275), - 'scale': (1.05,1.1,3.8), + 'scale': (1.05, 1.1, 3.8), 'type': 'box', 'materials': [self._score_region_material] }))) @@ -336,45 +338,46 @@ class BBGame(bs.TeamGameActivity[Player, Team]): def _nightSpawny(self): self.MythBrk = NightMod(position=(0, 0.05744967453, 0)) - #spawn some goodies on nightmode for pretty visuals + # spawn some goodies on nightmode for pretty visuals def _flagKaleFlash(self): - #flags positions + # flags positions kale1 = (-12.45, 0.05744967453, -2.075) kale2 = (-12.45, 0.05744967453, 2.075) kale3 = (12.66, 0.03986567039, 2.075) kale4 = (12.66, 0.03986567039, -2.075) flash = bs.newnode("light", - attrs={'position':kale1, - 'radius':0.15, - 'color':(1.0,1.0,0.7)}) + attrs={'position': kale1, + 'radius': 0.15, + 'color': (1.0, 1.0, 0.7)}) flash = bs.newnode("light", - attrs={'position':kale2, - 'radius':0.15, - 'color':(1.0,1.0,0.7)}) + attrs={'position': kale2, + 'radius': 0.15, + 'color': (1.0, 1.0, 0.7)}) flash = bs.newnode("light", - attrs={'position':kale3, - 'radius':0.15, - 'color':(0.7,1.0,1.0)}) + attrs={'position': kale3, + 'radius': 0.15, + 'color': (0.7, 1.0, 1.0)}) flash = bs.newnode("light", - attrs={'position':kale4, - 'radius':0.15, - 'color':(0.7,1.0,1.0)}) - #flags positions + attrs={'position': kale4, + 'radius': 0.15, + 'color': (0.7, 1.0, 1.0)}) + # flags positions + def _flagKalesSpawn(self): for team in self.teams: if team.id == 0: - _colorTeam0 = team.color + _colorTeam0 = team.color if team.id == 1: - _colorTeam1 = team.color + _colorTeam1 = team.color - self._MythB = FlagKale(position=(-12.45, 0.05744967453, -2.075),color=_colorTeam0) - self._MythB2 =FlagKale(position=(-12.45, 0.05744967453, 2.075),color=_colorTeam0) - self._MythB3 =FlagKale(position=(12.66, 0.03986567039, 2.075),color=_colorTeam1) - self._MythB4 =FlagKale(position=(12.66, 0.03986567039, -2.075),color=_colorTeam1) + self._MythB = FlagKale(position=(-12.45, 0.05744967453, -2.075), color=_colorTeam0) + self._MythB2 = FlagKale(position=(-12.45, 0.05744967453, 2.075), color=_colorTeam0) + self._MythB3 = FlagKale(position=(12.66, 0.03986567039, 2.075), color=_colorTeam1) + self._MythB4 = FlagKale(position=(12.66, 0.03986567039, -2.075), color=_colorTeam1) def on_team_join(self, team: Team) -> None: self._update_scoreboard() @@ -419,8 +422,10 @@ class BBGame(bs.TeamGameActivity[Player, Team]): # tell scored team players to celebrate and give them to boxing gloves if self._grant_power: for player in team.players: - try: player.actor.node.handlemessage(bs.PowerupMessage('punch')) - except: pass + try: + player.actor.node.handlemessage(bs.PowerupMessage('punch')) + except: + pass # Tell all players to celebrate. for player in team.players: @@ -442,8 +447,10 @@ class BBGame(bs.TeamGameActivity[Player, Team]): else: if self._grant_power: for player in team.players: - try: player.actor.node.handlemessage(bs.PowerupMessage('shield')) - except: pass + try: + player.actor.node.handlemessage(bs.PowerupMessage('shield')) + except: + pass self._foghorn_sound.play() self._cheer_sound.play() @@ -510,8 +517,8 @@ class BBGame(bs.TeamGameActivity[Player, Team]): self._puck = Puck(position=self._puck_spawn_pos) self._puck.light = bs.newnode('light', owner=self._puck.node, - attrs={'intensity':0.3, - 'height_attenuated':False, - 'radius':0.2, - 'color': (0.9,0.2,0.9)}) - self._puck.node.connectattr('position',self._puck.light,'position') + attrs={'intensity': 0.3, + 'height_attenuated': False, + 'radius': 0.2, + 'color': (0.9, 0.2, 0.9)}) + self._puck.node.connectattr('position', self._puck.light, 'position') From ca3221b0e61ac427546501e0e150c5af7b8d1d69 Mon Sep 17 00:00:00 2001 From: Rikko Date: Thu, 27 Jul 2023 20:28:51 +0530 Subject: [PATCH 44/60] Fix JSON struct --- plugins/minigames.json | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/minigames.json b/plugins/minigames.json index 6fcff11..6a2f0ef 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -673,6 +673,7 @@ "versions": { "1.0.0":null } + }, "handball": { "description": "Score some goals with handball", "external_url": "", From d3aa170d20580f01dce0e01af505b870f8437d31 Mon Sep 17 00:00:00 2001 From: rikkolovescats Date: Thu, 27 Jul 2023 15:03:13 +0000 Subject: [PATCH 45/60] [ci] apply-version-metadata --- plugins/minigames.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index 6a2f0ef..4c0872f 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -671,7 +671,12 @@ } ], "versions": { - "1.0.0":null + "1.0.0": { + "api_version": 8, + "commit_sha": "ca3221b", + "released_on": "27-07-2023", + "md5sum": "39c5b18efd5d5314f30c12fc0bec4931" + } } }, "handball": { @@ -718,4 +723,4 @@ } } } -} +} \ No newline at end of file From 7501794910f95a7b9ffe96f2e8fc69c78be8dad9 Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Thu, 27 Jul 2023 18:31:52 +0200 Subject: [PATCH 46/60] Super duel updated New game mode --> super duel --- plugins/minigames/super_duel.py | 598 ++++++++++++++++++++++++++++++++ 1 file changed, 598 insertions(+) create mode 100644 plugins/minigames/super_duel.py diff --git a/plugins/minigames/super_duel.py b/plugins/minigames/super_duel.py new file mode 100644 index 0000000..1610959 --- /dev/null +++ b/plugins/minigames/super_duel.py @@ -0,0 +1,598 @@ +"""New Duel / Created by: byANG3L""" + +# ba_meta require api 8 +# (see https://ballistica.net/wiki/meta-tag-system) + +from __future__ import annotations + +from typing import TYPE_CHECKING + +import babase +import bauiv1 as bui +import bascenev1 as bs +import random +from bascenev1lib.actor.playerspaz import PlayerSpaz +from bascenev1lib.actor.scoreboard import Scoreboard +from bascenev1lib.game.elimination import Icon + +if TYPE_CHECKING: + from typing import Any, Type, List, Dict, Tuple, Union, Sequence, Optional + + +class SuperSpaz(PlayerSpaz): + + def __init__(self, + player: bs.Player, + color: Sequence[float] = (1.0, 1.0, 1.0), + highlight: Sequence[float] = (0.5, 0.5, 0.5), + character: str = 'Spaz', + super_punch: bool = False, + powerups_expire: bool = True): + super().__init__(player=player, + color=color, + highlight=highlight, + character=character, + powerups_expire=powerups_expire) + self._super_punch = super_punch + + def handlemessage(self, msg: Any) -> Any: + from bascenev1lib.actor.spaz import PunchHitMessage + from bascenev1lib.actor.bomb import Blast + if isinstance(msg, PunchHitMessage): + super().handlemessage(msg) + node = bs.getcollision().opposingnode + if self._super_punch: + if node.getnodetype() == 'spaz': + if not node.frozen: + node.frozen = True + node.handlemessage(babase.FreezeMessage()) + bs.getsound('freeze').play() + bs.getsound('superPunch').play() + bs.getsound('punchStrong02').play() + Blast(position=node.position, + velocity=node.velocity, + blast_radius=0.0, + blast_type='normal').autoretain() + else: + return super().handlemessage(msg) + return None + + +class Player(bs.Player['Team']): + """Our player type for this game.""" + def __init__(self) -> None: + self.icons: List[Icon] = [] + self.in_game: bool = False + self.playervs1: bool = False + self.playervs2: bool = False + self.light: bool = False + + +class Team(bs.Team[Player]): + """Our team type for this game.""" + + def __init__(self) -> None: + self.score = 0 + + +lang = bs.app.lang.language +if lang == 'Spanish': + enable_powerups = 'Habilitar Potenciadores' + night_mode = 'Modo Noche' + fight_delay = 'Tiempo entre Pelea' + very_fast = 'Muy Rápido' + fast = 'Rápido' + normal = 'Normal' + slow = 'Lento' + very_slow = 'Muy Lento' + none = 'Ninguno' + super_punch = 'Super Golpe' + box_mode = 'Modo Caja' + boxing_gloves = 'Guantes de Boxeo' +else: + enable_powerups = 'Enable Powerups' + night_mode = 'Night Mode' + fight_delay = 'Fight Delay' + very_fast = 'Very Fast' + fast = 'Fast' + normal = 'Normal' + slow = 'Slow' + very_slow = 'Very Slow' + super_punch = 'Super Punch' + box_mode = 'Box Mode' + boxing_gloves = 'Boxing Gloves' + +# ba_meta export bascenev1.GameActivity +class NewDuelGame(bs.TeamGameActivity[Player, Team]): + """A game type based on acquiring kills.""" + + name = 'Duel' + 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[bs.Session]) -> List[babase.Setting]: + settings = [ + bs.IntSetting( + 'Kills to Win Per Player', + min_value=1, + default=5, + increment=1, + ), + bs.IntChoiceSetting( + 'Time Limit', + choices=[ + ('None', 0), + ('1 Minute', 60), + ('2 Minutes', 120), + ('5 Minutes', 300), + ('10 Minutes', 600), + ('20 Minutes', 1200), + ], + default=0, + ), + bs.BoolSetting(enable_powerups, default=False), + bs.BoolSetting(boxing_gloves, default=False), + bs.BoolSetting(night_mode, default=False), + bs.BoolSetting(super_punch, default=False), + bs.BoolSetting(box_mode, default=False), + bs.BoolSetting('Epic Mode', default=False), + bs.BoolSetting('Allow Negative Scores', default=False), + ] + return settings + + @classmethod + def supports_session_type(cls, sessiontype: Type[bs.Session]) -> bool: + return (issubclass(sessiontype, bs.FreeForAllSession)) + + @classmethod + def get_supported_maps(cls, sessiontype: Type[bs.Session]) -> List[str]: + return bs.app.classic.getmaps('melee') + + def __init__(self, settings: dict): + super().__init__(settings) + self._scoreboard = Scoreboard() + self._score_to_win: Optional[int] = None + self._dingsound = bs.getsound('dingSmall') + self._epic_mode = bool(settings['Epic Mode']) + self._kills_to_win_per_player = int( + settings['Kills to Win Per Player']) + self._enable_powerups = bool(settings[enable_powerups]) + self._night_mode = bool(settings[night_mode]) + self._fight_delay: float = 0 + self._time_limit = float(settings['Time Limit']) + self._allow_negative_scores = bool( + settings.get('Allow Negative Scores', False)) + self._super_punch = bool(settings[super_punch]) + self._box_mode = bool(settings[box_mode]) + self._boxing_gloves = bool(settings[boxing_gloves]) + self._vs_text: Optional[bs.Actor] = None + self.spawn_order: List[Player] = [] + self._players_vs_1: bool = False + self._players_vs_2: bool = False + self._first_countdown: bool = True + self._count_1 = bs.getsound('announceOne') + self._count_2 = bs.getsound('announceTwo') + self._count_3 = bs.getsound('announceThree') + self._boxing_bell = bs.getsound('boxingBell') + + # Base class overrides. + self.slow_motion = self._epic_mode + self.default_music = (bs.MusicType.EPIC if self._epic_mode else + bs.MusicType.TO_THE_DEATH) + + 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_player_join(self, player: Player) -> None: + self.spawn_order.append(player) + self._update_order() + + def on_player_leave(self, player: Player) -> None: + super().on_player_leave(player) + player.icons = [] + if player.playervs1: + player.playervs1 = False + self._players_vs_1 = False + player.in_game = False + elif player.playervs2: + player.playervs2 = False + self._players_vs_2 = False + player.in_game = False + if player in self.spawn_order: + self.spawn_order.remove(player) + bs.timer(0.2, self._update_order) + + def on_transition_in(self) -> None: + super().on_transition_in() + if self._night_mode: + gnode = bs.getactivity().globalsnode + gnode.tint = (0.3, 0.3, 0.3) + + def on_team_join(self, team: Team) -> None: + if self.has_begun(): + self._update_scoreboard() + + def on_begin(self) -> None: + super().on_begin() + self.setup_standard_time_limit(self._time_limit) + if self._enable_powerups: + self.setup_standard_powerup_drops() + self._vs_text = bs.NodeActor( + bs.newnode('text', + attrs={ + 'position': (0, 105), + 'h_attach': 'center', + 'h_align': 'center', + 'maxwidth': 200, + 'shadow': 0.5, + 'vr_depth': 390, + 'scale': 0.6, + 'v_attach': 'bottom', + 'color': (0.8, 0.8, 0.3, 1.0), + 'text': babase.Lstr(resource='vsText') + })) + + # 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() + bs.timer(1.0, self._update, repeat=True) + + def _update(self) -> None: + if len(self.players) == 1: + 'self.end_game()' + + + + def spawn_player(self, player: PlayerType) -> bs.Actor: + # pylint: disable=too-many-locals + # pylint: disable=cyclic-import + from babase import _math + from bascenev1._coopsession import CoopSession + from bascenev1lib.actor.spazfactory import SpazFactory + factory = SpazFactory.get() + name = player.getname() + color = player.color + highlight = player.highlight + + light_color = _math.normalized_color(color) + display_color = babase.safecolor(color, target_intensity=0.75) + spaz = SuperSpaz(color=color, + highlight=highlight, + character=player.character, + player=player, + super_punch=True if self._super_punch else False) + + player.actor = spaz + assert spaz.node + + # If this is co-op and we're on Courtyard or Runaround, add the + # material that allows us to collide with the player-walls. + # FIXME: Need to generalize this. + if isinstance(self.session, CoopSession) and self.map.getname() in [ + 'Courtyard', 'Tower D' + ]: + mat = self.map.preloaddata['collide_with_wall_material'] + assert isinstance(spaz.node.materials, tuple) + assert isinstance(spaz.node.roller_materials, tuple) + spaz.node.materials += (mat, ) + spaz.node.roller_materials += (mat, ) + + spaz.node.name = name + spaz.node.name_color = display_color + spaz.connect_controls_to_player() + + self._spawn_sound.play(1, position=spaz.node.position) + light = bs.newnode('light', attrs={'color': light_color}) + spaz.node.connectattr('position', light, 'position') + bs.animate(light, 'intensity', {0: 0, 0.25: 1, 0.5: 0}) + bs.timer(0.5, light.delete) + + pos1 = [self.map.get_start_position(0), 90] + pos2 = [self.map.get_start_position(1), 270] + pos3 = [] + + for x in self.players: + if x.is_alive(): + if x is player: continue + p = x.actor.node.position + if 0.0 not in (p[0], p[2]): + if p[0] <= 0: + pos3.append(pos2[0]) + else: pos3.append(pos1[0]) + + spaz.handlemessage(bs.StandMessage(pos1[0] if player.playervs1 else pos2[0], + pos1[1] if player.playervs1 else pos2[1])) + + if any(pos3): + spaz.handlemessage(bs.StandMessage(pos3[0])) + + if self._super_punch: + spaz._punch_power_scale = factory.punch_power_scale_gloves = 10 + spaz.equip_boxing_gloves() + lfx = bs.newnode( + 'light', + attrs={ + 'color': color, + 'radius': 0.3, + 'intensity': 0.3}) + def sp_fx(): + if not spaz.node: + lfx.delete() + return + bs.emitfx(position=spaz.node.position, + velocity=spaz.node.velocity, + count=5, + scale=0.5, + spread=0.5, + chunk_type='spark') + bs.emitfx(position=spaz.node.position, + velocity=spaz.node.velocity, + count=2, + scale=0.8, + spread=0.3, + chunk_type='spark') + if lfx: + spaz.node.connectattr('position', lfx, 'position') + bs.timer(0.1, sp_fx, repeat=True) + + if self._box_mode: + spaz.node.color_texture = bs.gettexture('tnt') + spaz.node.color_mask_texture = bs.gettexture('tnt') + spaz.node.color = (1, 1, 1) + spaz.node.highlight = (1, 1, 1) + spaz.node.head_mesh = None + spaz.node.torso_mesh = bs.getmesh('tnt') + spaz.node.style = 'cyborg' + + if self._boxing_gloves: + spaz.equip_boxing_gloves() + + return spaz + + def _update_spawn(self) -> None: + if self._players_vs_1 or self._players_vs_2: + for player in self.players: + if player.playervs1 or player.playervs2: + if not player.is_alive(): + self.spawn_player(player) + # player.actor.disconnect_controls_from_player() + + if self._night_mode: + if not player.light: + player.light = True + light = bs.newnode( + 'light', + owner=player.node, + attrs={ + 'radius': 0.3, + 'intensity': 0.6, + 'height_attenuated': False, + 'color': player.color + }) + player.node.connectattr( + 'position', light, 'position') + else: + player.actor.disconnect_controls_from_player() + + bs.timer(0.0, self._countdown) + # bs.timer(0.1, self._clear_all_objects) + + def _countdown(self) -> None: + self._first_countdown = False + if self._fight_delay == 0: + for player in self.players: + if player.playervs1 or player.playervs2: + if not player.is_alive(): + return + else: + player.actor.connect_controls_to_player() + else: + bs.timer(self._fight_delay, self.count3) + + def start(self) -> None: + self._count_text('FIGHT') + self._boxing_bell.play() + for player in self.players: + if player.playervs1 or player.playervs2: + if not player.is_alive(): + return + else: + player.actor.connect_controls_to_player() + + def count(self) -> None: + self._count_text('1') + self._count_1.play() + bs.timer(self._fight_delay, self.start) + + def count2(self) -> None: + self._count_text('2') + self._count_2.play() + bs.timer(self._fight_delay, self.count) + + def count3(self) -> None: + self._count_text('3') + self._count_3.play() + bs.timer(self._fight_delay, self.count2) + + def _count_text(self, num: str) -> None: + self.node = bs.newnode('text', + attrs={ + 'v_attach': 'center', + 'h_attach': 'center', + 'h_align': 'center', + 'color': (1, 1, 0.5, 1), + 'flatness': 0.5, + 'shadow': 0.5, + 'position': (0, 18), + 'text': num + }) + if self._fight_delay == 0.7: + bs.animate(self.node, 'scale', + {0: 0, 0.1: 3.9, 0.64: 4.3, 0.68: 0}) + elif self._fight_delay == 0.4: + bs.animate(self.node, 'scale', + {0: 0, 0.1: 3.9, 0.34: 4.3, 0.38: 0}) + else: + bs.animate(self.node, 'scale', + {0: 0, 0.1: 3.9, 0.92: 4.3, 0.96: 0}) + cmb = bs.newnode('combine', owner=self.node, attrs={'size': 4}) + cmb.connectattr('output', self.node, 'color') + bs.animate(cmb, 'input0', {0: 1.0, 0.15: 1.0}, loop=True) + bs.animate(cmb, 'input1', {0: 1.0, 0.15: 0.5}, loop=True) + bs.animate(cmb, 'input2', {0: 0.1, 0.15: 0.0}, loop=True) + cmb.input3 = 1.0 + bs.timer(self._fight_delay, self.node.delete) + + def _update_order(self) -> None: + for player in self.spawn_order: + assert isinstance(player, Player) + if not player.is_alive(): + if not self._players_vs_1: + self._players_vs_1 = True + player.playervs1 = True + player.in_game = True + self.spawn_order.remove(player) + self._update_spawn() + elif not self._players_vs_2: + self._players_vs_2 = True + player.playervs2 = True + player.in_game = True + self.spawn_order.remove(player) + self._update_spawn() + self._update_icons() + + def _update_icons(self) -> None: + # pylint: disable=too-many-branches + + for player in self.players: + player.icons = [] + + if player.in_game: + if player.playervs1: + xval = -60 + x_offs = -78 + elif player.playervs2: + xval = 60 + x_offs = 78 + player.icons.append( + Icon(player, + position=(xval, 40), + scale=1.0, + name_maxwidth=130, + name_scale=0.8, + flatness=0.0, + shadow=0.5, + show_death=True, + show_lives=False)) + else: + xval = 125 + xval2 = -125 + x_offs = 78 + for player in self.spawn_order: + player.icons.append( + Icon(player, + position=(xval, 25), + scale=0.5, + name_maxwidth=75, + name_scale=1.0, + flatness=1.0, + shadow=1.0, + show_death=False, + show_lives=False)) + xval += x_offs * 0.56 + player.icons.append( + Icon(player, + position=(xval2, 25), + scale=0.5, + name_maxwidth=75, + name_scale=1.0, + flatness=1.0, + shadow=1.0, + show_death=False, + show_lives=False)) + xval2 -= x_offs * 0.56 + + def handlemessage(self, msg: Any) -> Any: + + if isinstance(msg, bs.PlayerDiedMessage): + + # Augment standard behavior. + super().handlemessage(msg) + + player = msg.getplayer(Player) + + if player.playervs1: + player.playervs1 = False + self._players_vs_1 = False + player.in_game = False + self.spawn_order.append(player) + elif player.playervs2: + player.playervs2 = False + self._players_vs_2 = False + player.in_game = False + self.spawn_order.append(player) + bs.timer(0.2, self._update_order) + + 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, bs.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: + self._dingsound.play() + 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 + self._dingsound.play() + + # 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): + bs.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 = bs.GameResults() + for team in self.teams: + results.set_team_score(team, team.score) + self.end(results=results) \ No newline at end of file From bff7e1c89713ee9d0312bb8a2f03784d690dfda5 Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Thu, 27 Jul 2023 18:34:35 +0200 Subject: [PATCH 47/60] Update minigames.json --- plugins/minigames.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index 4c0872f..0df9b41 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -698,6 +698,20 @@ } } }, + "super_duel": { + "description": "Crush your enemy in a 1v1", + "external_url": "https://www.youtube.com/watch?v=hvRtiXR-oC0", + "authors": [ + { + "name": "JoseAng3l", + "email": "", + "discord": "joseang3l" + } + ], + "versions": { + "1.0.0":null + } + }, "supersmash": { "description": "Blow up your enemies off the map!", "external_url": "", @@ -723,4 +737,4 @@ } } } -} \ No newline at end of file +} From ab2678693d679d28ff721473bf3a1c80d487c3ca Mon Sep 17 00:00:00 2001 From: SenjuZoro Date: Thu, 27 Jul 2023 21:28:52 +0000 Subject: [PATCH 48/60] [ci] auto-format --- plugins/minigames/super_duel.py | 62 ++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/plugins/minigames/super_duel.py b/plugins/minigames/super_duel.py index 1610959..b6fc239 100644 --- a/plugins/minigames/super_duel.py +++ b/plugins/minigames/super_duel.py @@ -50,9 +50,9 @@ class SuperSpaz(PlayerSpaz): bs.getsound('superPunch').play() bs.getsound('punchStrong02').play() Blast(position=node.position, - velocity=node.velocity, - blast_radius=0.0, - blast_type='normal').autoretain() + velocity=node.velocity, + blast_radius=0.0, + blast_type='normal').autoretain() else: return super().handlemessage(msg) return None @@ -60,6 +60,7 @@ class SuperSpaz(PlayerSpaz): class Player(bs.Player['Team']): """Our player type for this game.""" + def __init__(self) -> None: self.icons: List[Icon] = [] self.in_game: bool = False @@ -103,6 +104,8 @@ else: boxing_gloves = 'Boxing Gloves' # ba_meta export bascenev1.GameActivity + + class NewDuelGame(bs.TeamGameActivity[Player, Team]): """A game type based on acquiring kills.""" @@ -225,19 +228,19 @@ class NewDuelGame(bs.TeamGameActivity[Player, Team]): if self._enable_powerups: self.setup_standard_powerup_drops() self._vs_text = bs.NodeActor( - bs.newnode('text', - attrs={ - 'position': (0, 105), - 'h_attach': 'center', - 'h_align': 'center', - 'maxwidth': 200, - 'shadow': 0.5, - 'vr_depth': 390, - 'scale': 0.6, - 'v_attach': 'bottom', - 'color': (0.8, 0.8, 0.3, 1.0), - 'text': babase.Lstr(resource='vsText') - })) + bs.newnode('text', + attrs={ + 'position': (0, 105), + 'h_attach': 'center', + 'h_align': 'center', + 'maxwidth': 200, + 'shadow': 0.5, + 'vr_depth': 390, + 'scale': 0.6, + 'v_attach': 'bottom', + 'color': (0.8, 0.8, 0.3, 1.0), + 'text': babase.Lstr(resource='vsText') + })) # Base kills needed to win on the size of the largest team. self._score_to_win = (self._kills_to_win_per_player * @@ -249,8 +252,6 @@ class NewDuelGame(bs.TeamGameActivity[Player, Team]): if len(self.players) == 1: 'self.end_game()' - - def spawn_player(self, player: PlayerType) -> bs.Actor: # pylint: disable=too-many-locals # pylint: disable=cyclic-import @@ -298,18 +299,20 @@ class NewDuelGame(bs.TeamGameActivity[Player, Team]): pos1 = [self.map.get_start_position(0), 90] pos2 = [self.map.get_start_position(1), 270] pos3 = [] - + for x in self.players: if x.is_alive(): - if x is player: continue + if x is player: + continue p = x.actor.node.position if 0.0 not in (p[0], p[2]): if p[0] <= 0: pos3.append(pos2[0]) - else: pos3.append(pos1[0]) - + else: + pos3.append(pos1[0]) + spaz.handlemessage(bs.StandMessage(pos1[0] if player.playervs1 else pos2[0], - pos1[1] if player.playervs1 else pos2[1])) + pos1[1] if player.playervs1 else pos2[1])) if any(pos3): spaz.handlemessage(bs.StandMessage(pos3[0])) @@ -323,6 +326,7 @@ class NewDuelGame(bs.TeamGameActivity[Player, Team]): 'color': color, 'radius': 0.3, 'intensity': 0.3}) + def sp_fx(): if not spaz.node: lfx.delete() @@ -364,7 +368,7 @@ class NewDuelGame(bs.TeamGameActivity[Player, Team]): if not player.is_alive(): self.spawn_player(player) # player.actor.disconnect_controls_from_player() - + if self._night_mode: if not player.light: player.light = True @@ -381,7 +385,7 @@ class NewDuelGame(bs.TeamGameActivity[Player, Team]): 'position', light, 'position') else: player.actor.disconnect_controls_from_player() - + bs.timer(0.0, self._countdown) # bs.timer(0.1, self._clear_all_objects) @@ -436,13 +440,13 @@ class NewDuelGame(bs.TeamGameActivity[Player, Team]): }) if self._fight_delay == 0.7: bs.animate(self.node, 'scale', - {0: 0, 0.1: 3.9, 0.64: 4.3, 0.68: 0}) + {0: 0, 0.1: 3.9, 0.64: 4.3, 0.68: 0}) elif self._fight_delay == 0.4: bs.animate(self.node, 'scale', - {0: 0, 0.1: 3.9, 0.34: 4.3, 0.38: 0}) + {0: 0, 0.1: 3.9, 0.34: 4.3, 0.38: 0}) else: bs.animate(self.node, 'scale', - {0: 0, 0.1: 3.9, 0.92: 4.3, 0.96: 0}) + {0: 0, 0.1: 3.9, 0.92: 4.3, 0.96: 0}) cmb = bs.newnode('combine', owner=self.node, attrs={'size': 4}) cmb.connectattr('output', self.node, 'color') bs.animate(cmb, 'input0', {0: 1.0, 0.15: 1.0}, loop=True) @@ -595,4 +599,4 @@ class NewDuelGame(bs.TeamGameActivity[Player, Team]): results = bs.GameResults() for team in self.teams: results.set_team_score(team, team.score) - self.end(results=results) \ No newline at end of file + self.end(results=results) From 4095f4894e70b79f37be60a087c4e8d8e161cd8b Mon Sep 17 00:00:00 2001 From: SenjuZoro Date: Thu, 27 Jul 2023 21:28:53 +0000 Subject: [PATCH 49/60] [ci] apply-version-metadata --- plugins/minigames.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index 0df9b41..b76c901 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -709,7 +709,12 @@ } ], "versions": { - "1.0.0":null + "1.0.0": { + "api_version": 8, + "commit_sha": "ab26786", + "released_on": "27-07-2023", + "md5sum": "d0c9c0472d7b145eadf535957a462fdf" + } } }, "supersmash": { @@ -737,4 +742,4 @@ } } } -} +} \ No newline at end of file From 5ea6a94de02396dd729a73a172e26620e5514e48 Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Fri, 28 Jul 2023 00:45:23 +0200 Subject: [PATCH 50/60] demolition war minigame updated updated to api 8 idk if i did it correctly in line 224 --- plugins/minigames/demolition_war.py | 121 ++++++++++++++-------------- 1 file changed, 62 insertions(+), 59 deletions(-) diff --git a/plugins/minigames/demolition_war.py b/plugins/minigames/demolition_war.py index 1c26433..87ffc11 100644 --- a/plugins/minigames/demolition_war.py +++ b/plugins/minigames/demolition_war.py @@ -1,5 +1,5 @@ -# ba_meta require api 7 +# ba_meta require api 8 """ DemolitionWar - BombFight on wooden floor flying in air. Author: Mr.Smoothy @@ -12,23 +12,26 @@ from __future__ import annotations from typing import TYPE_CHECKING -import ba -from bastd.game.elimination import EliminationGame, Player -from bastd.gameutils import SharedObjects -from bastd.actor.bomb import BombFactory +import babase +import bauiv1 as bui +import bascenev1 as bs +from bascenev1 import _map +from bascenev1lib.game.elimination import EliminationGame, Player +from bascenev1lib.gameutils import SharedObjects +from bascenev1lib.actor.bomb import BombFactory import random -from bastd.actor.playerspaz import PlayerSpaz +from bascenev1lib.actor.playerspaz import PlayerSpaz if TYPE_CHECKING: from typing import Any, Sequence -# ba_meta export game +# ba_meta export bascenev1.GameActivity class DemolitionWar(EliminationGame): name = 'DemolitionWar' description = 'Last remaining alive wins.' - scoreconfig = ba.ScoreConfig( - label='Survived', scoretype=ba.ScoreType.SECONDS, none_is_winner=True + scoreconfig = bs.ScoreConfig( + label='Survived', scoretype=bs.ScoreType.SECONDS, none_is_winner=True ) # Show messages when players die since it's meaningful here. announce_player_deaths = True @@ -37,17 +40,17 @@ class DemolitionWar(EliminationGame): @classmethod def get_available_settings( - cls, sessiontype: type[ba.Session] - ) -> list[ba.Setting]: + cls, sessiontype: type[bs.Session] + ) -> list[babase.Setting]: settings = [ - ba.IntSetting( + bs.IntSetting( 'Lives Per Player', default=1, min_value=1, max_value=10, increment=1, ), - ba.IntChoiceSetting( + bs.IntChoiceSetting( 'Time Limit', choices=[ ('None', 0), @@ -59,7 +62,7 @@ class DemolitionWar(EliminationGame): ], default=0, ), - ba.FloatChoiceSetting( + bs.FloatChoiceSetting( 'Respawn Times', choices=[ ('Shorter', 0.25), @@ -70,23 +73,23 @@ class DemolitionWar(EliminationGame): ], default=1.0, ), - ba.BoolSetting('Epic Mode', default=False), + bs.BoolSetting('Epic Mode', default=False), ] - if issubclass(sessiontype, ba.DualTeamSession): - settings.append(ba.BoolSetting('Solo Mode', default=False)) + if issubclass(sessiontype, bs.DualTeamSession): + settings.append(bs.BoolSetting('Solo Mode', default=False)) settings.append( - ba.BoolSetting('Balance Total Lives', default=False) + bs.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 + 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 ['Wooden Floor'] def __init__(self, settings: dict): @@ -95,7 +98,7 @@ class DemolitionWar(EliminationGame): self._solo_mode = False self._balance_total_lives = False - def spawn_player(self, player: Player) -> ba.Actor: + def spawn_player(self, player: Player) -> bs.Actor: p = [-6, -4.3, -2.6, -0.9, 0.8, 2.5, 4.2, 5.9] q = [-4, -2.3, -0.6, 1.1, 2.8, 4.5] @@ -118,23 +121,23 @@ class DemolitionWar(EliminationGame): self.map_extend() def on_blast(self): - node = ba.getcollision().sourcenode - ba.emitfx((node.position[0], 0.9, node.position[2]), + node = bs.getcollision().sourcenode + bs.emitfx((node.position[0], 0.9, node.position[2]), (0, 2, 0), 30, 1, spread=1, chunk_type='splinter') - ba.timer(0.1, ba.Call(node.delete)) + bs.timer(0.1, babase.Call(node.delete)) def map_extend(self): # TODO need to improve here , so we can increase size of map easily with settings p = [-6, -4.3, -2.6, -0.9, 0.8, 2.5, 4.2, 5.9] q = [-4, -2.3, -0.6, 1.1, 2.8, 4.5] factory = BombFactory.get() - self.ramp_bomb = ba.Material() + self.ramp_bomb = bs.Material() self.ramp_bomb.add_actions( conditions=('they_have_material', factory.bomb_material), actions=( ('modify_part_collision', 'collide', True), ('modify_part_collision', 'physical', True), - ('call', 'at_connect', ba.Call(self.on_blast)) + ('call', 'at_connect', babase.Call(self.on_blast)) )) self.ramps = [] for i in p: @@ -144,7 +147,7 @@ class DemolitionWar(EliminationGame): def create_ramp(self, x, z): shared = SharedObjects.get() - self._real_collied_material = ba.Material() + self._real_collied_material = bs.Material() self._real_collied_material.add_actions( actions=( @@ -152,32 +155,32 @@ class DemolitionWar(EliminationGame): ('modify_part_collision', 'physical', True) )) - self.mat = ba.Material() + self.mat = bs.Material() self.mat.add_actions( actions=(('modify_part_collision', 'physical', False), ('modify_part_collision', 'collide', False)) ) pos = (x, 0, z) - ud_1_r = ba.newnode('region', attrs={'position': pos, 'scale': (1.5, 1, 1.5), 'type': 'box', 'materials': [ + ud_1_r = bs.newnode('region', attrs={'position': pos, 'scale': (1.5, 1, 1.5), 'type': 'box', 'materials': [ shared.footing_material, self._real_collied_material, self.ramp_bomb]}) - node = ba.newnode('prop', + node = bs.newnode('prop', owner=ud_1_r, attrs={ - 'model': ba.getmodel('image1x1'), - 'light_model': ba.getmodel('powerupSimple'), + 'mesh': bs.getmesh('image1x1'), + 'light_mesh': bs.getmesh('powerupSimple'), 'position': (2, 7, 2), 'body': 'puck', 'shadow_size': 0.0, 'velocity': (0, 0, 0), - 'color_texture': ba.gettexture('tnt'), - 'model_scale': 1.5, + 'color_texture': bs.gettexture('tnt'), + 'mesh_scale': 1.5, 'reflection_scale': [1.5], 'materials': [self.mat, shared.object_material, shared.footing_material], 'density': 9000000000 }) - node.changerotation(1, 0, 0) - mnode = ba.newnode('math', + # node.changerotation(1, 0, 0) + mnode = bs.newnode('math', owner=ud_1_r, attrs={ 'input1': (0, 0.6, 0), @@ -218,7 +221,7 @@ class mapdefs: points['tnt1'] = (-0.08421587483, 0.9515026107, -0.7762602271) -class WoodenFloor(ba.Map): +class WoodenFloor(bs._map.Map): #ahdunno if this is correct way, change if u find better way """Stadium map for football games.""" defs = mapdefs defs.points['spawn1'] = (-12.03866341, 0.02275111462, 0.0) + (0.5, 1.0, 4.0) @@ -238,15 +241,15 @@ class WoodenFloor(ba.Map): def on_preload(cls) -> Any: data: dict[str, Any] = { - 'model_bg': ba.getmodel('doomShroomBG'), - 'bg_vr_fill_model': ba.getmodel('natureBackgroundVRFill'), - 'collide_model': ba.getcollidemodel('bridgitLevelCollide'), - 'tex': ba.gettexture('bridgitLevelColor'), - 'model_bg_tex': ba.gettexture('doomShroomBGColor'), - 'collide_bg': ba.getcollidemodel('natureBackgroundCollide'), - 'railing_collide_model': - (ba.getcollidemodel('bridgitLevelRailingCollide')), - 'bg_material': ba.Material() + 'mesh_bg': bs.getmesh('doomShroomBG'), + 'bg_vr_fill_mesh': bs.getmesh('natureBackgroundVRFill'), + 'collide_mesh': bs.getcollisionmesh('bridgitLevelCollide'), + 'tex': bs.gettexture('bridgitLevelColor'), + 'mesh_bg_tex': bs.gettexture('doomShroomBGColor'), + 'collide_bg': bs.getcollisionmesh('natureBackgroundCollide'), + 'railing_collide_mesh': + (bs.getcollisionmesh('bridgitLevelRailingCollide')), + 'bg_material': bs.Material() } data['bg_material'].add_actions(actions=('modify_part_collision', 'friction', 10.0)) @@ -255,23 +258,23 @@ class WoodenFloor(ba.Map): def __init__(self) -> None: super().__init__() shared = SharedObjects.get() - self.background = ba.newnode( + self.background = bs.newnode( 'terrain', attrs={ - 'model': self.preloaddata['model_bg'], + 'mesh': self.preloaddata['mesh_bg'], 'lighting': False, 'background': True, - 'color_texture': self.preloaddata['model_bg_tex'] + 'color_texture': self.preloaddata['mesh_bg_tex'] }) - self.vr = ba.newnode('terrain', + self.vr = bs.newnode('terrain', attrs={ - 'model': self.preloaddata['bg_vr_fill_model'], + 'mesh': self.preloaddata['bg_vr_fill_mesh'], 'lighting': False, 'vr_only': True, 'background': True, - 'color_texture': self.preloaddata['model_bg_tex'] + 'color_texture': self.preloaddata['mesh_bg_tex'] }) - gnode = ba.getactivity().globalsnode + gnode = bs.getactivity().globalsnode gnode.tint = (1.3, 1.2, 1.0) gnode.ambient_color = (1.3, 1.2, 1.0) gnode.vignette_outer = (0.57, 0.57, 0.57) @@ -280,7 +283,7 @@ class WoodenFloor(ba.Map): gnode.vr_near_clip = 0.5 def is_point_near_edge(self, - point: ba.Vec3, + point: babase.Vec3, running: bool = False) -> bool: box_position = self.defs.boxes['edge_box'][0:3] box_scale = self.defs.boxes['edge_box'][6:9] @@ -290,15 +293,15 @@ class WoodenFloor(ba.Map): def _handle_player_collide(self): try: - player = ba.getcollision().opposingnode.getdelegate( + player = bs.getcollision().opposingnode.getdelegate( PlayerSpaz, True) - except ba.NotFoundError: + except bs.NotFoundError: return if player.is_alive(): player.shatter(True) try: - ba._map.register_map(WoodenFloor) + bs._map.register_map(WoodenFloor) except: pass From 9a351a3263253426b7e4fe2a6ac71ed03933963f Mon Sep 17 00:00:00 2001 From: SenjuZoro Date: Thu, 27 Jul 2023 22:45:52 +0000 Subject: [PATCH 51/60] [ci] auto-format --- plugins/minigames/demolition_war.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/minigames/demolition_war.py b/plugins/minigames/demolition_war.py index 87ffc11..abafe06 100644 --- a/plugins/minigames/demolition_war.py +++ b/plugins/minigames/demolition_war.py @@ -15,7 +15,7 @@ from typing import TYPE_CHECKING import babase import bauiv1 as bui import bascenev1 as bs -from bascenev1 import _map +from bascenev1 import _map from bascenev1lib.game.elimination import EliminationGame, Player from bascenev1lib.gameutils import SharedObjects from bascenev1lib.actor.bomb import BombFactory @@ -221,7 +221,7 @@ class mapdefs: points['tnt1'] = (-0.08421587483, 0.9515026107, -0.7762602271) -class WoodenFloor(bs._map.Map): #ahdunno if this is correct way, change if u find better way +class WoodenFloor(bs._map.Map): # ahdunno if this is correct way, change if u find better way """Stadium map for football games.""" defs = mapdefs defs.points['spawn1'] = (-12.03866341, 0.02275111462, 0.0) + (0.5, 1.0, 4.0) From f54c993c5b02ed71b9b4e51248f002c85074121a Mon Sep 17 00:00:00 2001 From: SenjuZoro <69396975+SenjuZoro@users.noreply.github.com> Date: Fri, 28 Jul 2023 00:48:37 +0200 Subject: [PATCH 52/60] Update minigames.json --- plugins/minigames.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index b76c901..a30f433 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -328,6 +328,7 @@ } ], "versions": { + "2.0.0":null, "1.0.0": { "api_version": 7, "commit_sha": "2aa1e50", @@ -742,4 +743,4 @@ } } } -} \ No newline at end of file +} From 82cba4aae7b5ad63f6ace210256920187fa47675 Mon Sep 17 00:00:00 2001 From: SenjuZoro Date: Thu, 27 Jul 2023 22:49:04 +0000 Subject: [PATCH 53/60] [ci] apply-version-metadata --- plugins/minigames.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index a30f433..66a58ee 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -328,7 +328,12 @@ } ], "versions": { - "2.0.0":null, + "2.0.0": { + "api_version": 8, + "commit_sha": "f54c993", + "released_on": "27-07-2023", + "md5sum": "7699483f4c379db809676ac917943d3c" + }, "1.0.0": { "api_version": 7, "commit_sha": "2aa1e50", @@ -743,4 +748,4 @@ } } } -} +} \ No newline at end of file From cd29dacf98ffc1a36c1296410e4079bda30fff32 Mon Sep 17 00:00:00 2001 From: ! Freaku <92618708+Freaku17@users.noreply.github.com> Date: Fri, 28 Jul 2023 17:02:59 +0530 Subject: [PATCH 54/60] Update/Add my gamemodes for 1.7.20+ (API 8) --- plugins/minigames/arms_race.py | 29 +- plugins/minigames/frozen_one.py | 18 + plugins/minigames/icy_emits.py | 46 ++ plugins/minigames/memory_game.py | 827 ++++++++++++++--------------- plugins/minigames/musical_flags.py | 255 +++++---- plugins/minigames/volleyball.py | 488 +++++++++-------- 6 files changed, 890 insertions(+), 773 deletions(-) create mode 100644 plugins/minigames/frozen_one.py create mode 100644 plugins/minigames/icy_emits.py diff --git a/plugins/minigames/arms_race.py b/plugins/minigames/arms_race.py index 6f7351b..7710c2a 100644 --- a/plugins/minigames/arms_race.py +++ b/plugins/minigames/arms_race.py @@ -1,9 +1,10 @@ -# Ported by: Freaku / @[Just] Freak#4999 +# Ported by your friend: Freaku -# Join BCS: +#Join BCS: # https://discord.gg/ucyaesh + # ba_meta require api 8 from __future__ import annotations @@ -11,7 +12,6 @@ from __future__ import annotations from typing import TYPE_CHECKING import babase -import bauiv1 as bui import bascenev1 as bs from bascenev1lib.actor.playerspaz import PlayerSpaz @@ -19,6 +19,7 @@ if TYPE_CHECKING: from typing import Any, Type, List, Dict, Tuple, Union, Sequence, Optional + class State: def __init__(self, bomb=None, grab=False, punch=False, curse=False, required=False, final=False, name=''): self.bomb = bomb @@ -35,8 +36,8 @@ class State: def apply(self, spaz): spaz.disconnect_controls_from_player() spaz.connect_controls_to_player(enable_punch=self.punch, - enable_bomb=self.bomb, - enable_pickup=self.grab) + enable_bomb=self.bomb, + enable_pickup=self.grab) if self.curse: spaz.curse_time = -1 spaz.curse() @@ -48,18 +49,16 @@ class State: return (self.name) -states = [State(bomb='normal', name='Basic Bombs'), - State(bomb='ice', name='Frozen Bombs'), - State(bomb='sticky', name='Sticky Bombs'), - State(bomb='impact', name='Impact Bombs'), - State(grab=True, name='Grabbing only'), - State(punch=True, name='Punching only'), - State(curse=True, name='Cursed', final=True)] - +states = [ State(bomb='normal', name='Basic Bombs'), + State(bomb='ice', name='Frozen Bombs'), + State(bomb='sticky', name='Sticky Bombs'), + State(bomb='impact', name='Impact Bombs'), + State(grab=True, name='Grabbing only'), + State(punch=True, name='Punching only'), + State(curse=True, name='Cursed', final=True) ] class Player(bs.Player['Team']): """Our player type for this game.""" - def __init__(self): self.state = None @@ -193,4 +192,4 @@ class ArmsRaceGame(bs.TeamGameActivity[Player, Team]): 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 diff --git a/plugins/minigames/frozen_one.py b/plugins/minigames/frozen_one.py new file mode 100644 index 0000000..7bfbe65 --- /dev/null +++ b/plugins/minigames/frozen_one.py @@ -0,0 +1,18 @@ +# Ported by your friend: Freaku + + +import babase +import bascenev1 as bs +from bascenev1lib.game.chosenone import Player, ChosenOneGame + + +# ba_meta require api 8 +# ba_meta export bascenev1.GameActivity +class FrozenOneGame(ChosenOneGame): + name = 'Frozen One' + + def _set_chosen_one_player(self, player: Player) -> None: + super()._set_chosen_one_player(player) + if hasattr(player, 'actor'): + player.actor.frozen = True + player.actor.node.frozen = 1 \ No newline at end of file diff --git a/plugins/minigames/icy_emits.py b/plugins/minigames/icy_emits.py new file mode 100644 index 0000000..50a883c --- /dev/null +++ b/plugins/minigames/icy_emits.py @@ -0,0 +1,46 @@ +# Made by your friend: Freaku + + +import babase +import bascenev1 as bs, random +from bascenev1lib.actor.bomb import Bomb +from bascenev1lib.game.meteorshower import Player, MeteorShowerGame + + +# ba_meta require api 8 +# ba_meta export bascenev1.GameActivity +class IcyEmitsGame(MeteorShowerGame): + name = 'Icy Emits' + + @classmethod + def get_supported_maps(cls, sessiontype): + return ['Lake Frigid','Hockey Stadium'] + + def _drop_bomb_cluster(self) -> None: + delay = 0.0 + for _i in range(random.randrange(1, 3)): + # Drop them somewhere within our bounds with velocity pointing + # toward the opposite side. + pos = (-7.3 + 15.3 * random.random(), 5.3, + -5.5 + 2.1 * random.random()) + dropdir = (-1.0 if pos[0] > 0 else 1.0) + vel = (0,10,0) + bs.timer(delay, babase.Call(self._drop_bomb, pos, vel)) + delay += 0.1 + self._set_meteor_timer() + + def _drop_bomb(self, position, velocity): + random_xpositions = [-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10] + random_zpositions = [-5,-4.5,-4,-3.5,-3,-2.5,-2,-1.5,-1,-0.5,0,0.5,1,1.5,2,2.5,3,3.5,4,4.5,5] + bomb_position = (random.choice(random_xpositions), 0.2,random.choice(random_zpositions)) + Bomb(position=bomb_position, velocity=velocity, bomb_type = 'ice').autoretain() + + + + +# ba_meta export plugin +class byFreaku(babase.Plugin): + def __init__(self): + ## Campaign support ## + randomPic = ['lakeFrigidPreview','hockeyStadiumPreview'] + babase.app.classic.add_coop_practice_level(bs.Level(name='Icy Emits', displayname='${GAME}', gametype=IcyEmitsGame, settings={}, preview_texture_name=random.choice(randomPic))) \ No newline at end of file diff --git a/plugins/minigames/memory_game.py b/plugins/minigames/memory_game.py index c5c0204..a433eec 100644 --- a/plugins/minigames/memory_game.py +++ b/plugins/minigames/memory_game.py @@ -2,7 +2,7 @@ from __future__ import annotations ## Original creator: byANG3L ## -## Made by: Freaku / @[Just] Freak#4999 ## +## Made by: Freaku ## ## From: BSWorld Modpack (https://youtu.be/1TN56NLlShE) ## @@ -12,77 +12,70 @@ from __future__ import annotations # (& some improvements) + + + + # incase someone is wondering how is map floating. Check out # def spawnAllMap(self) -# ba_meta require api 7 + +# ba_meta require api 8 from typing import TYPE_CHECKING, overload -import _ba -import ba -import random -from bastd.gameutils import SharedObjects +import _babase, babase, random +import bascenev1 as bs +from bascenev1lib.gameutils import SharedObjects if TYPE_CHECKING: from typing import Any, Sequence, Optional, List, Dict, Type, Union, Any, Literal -class OnTimer(ba.Actor): - """Timer which counts but doesn't show on-screen""" + +class OnTimer(bs.Actor): + """Timer which counts but doesn't show on-screen""" def __init__(self) -> None: super().__init__() - self._starttime_ms: Optional[int] = None - self.node = ba.newnode('text', attrs={'v_attach': 'top', 'h_attach': 'center', 'h_align': 'center', 'color': ( - 1, 1, 0.5, 1), 'flatness': 0.5, 'shadow': 0.5, 'position': (0, -70), 'scale': 0, 'text': ''}) - self.inputnode = ba.newnode('timedisplay', attrs={ - 'timemin': 0, 'showsubseconds': True}) + self._starttime_ms: int | None = None + self.node = bs.newnode('text', attrs={ 'v_attach': 'top', 'h_attach': 'center', 'h_align': 'center', 'color': (1, 1, 0.5, 1), 'flatness': 0.5, 'shadow': 0.5, 'position': (0, -70), 'scale': 0, 'text': ''}) + self.inputnode = bs.newnode( + 'timedisplay', attrs={'timemin': 0, 'showsubseconds': True} + ) self.inputnode.connectattr('output', self.node, 'text') def start(self) -> None: - tval = ba.time(timeformat=ba.TimeFormat.MILLISECONDS) + """Start the timer.""" + tval = int(bs.time() * 1000.0) assert isinstance(tval, int) self._starttime_ms = tval self.inputnode.time1 = self._starttime_ms - ba.getactivity().globalsnode.connectattr('time', self.inputnode, 'time2') + bs.getactivity().globalsnode.connectattr( + 'time', self.inputnode, 'time2' + ) def has_started(self) -> bool: + """Return whether this timer has started yet.""" return self._starttime_ms is not None - def stop(self, - endtime: Union[int, float] = None, - timeformat: ba.TimeFormat = ba.TimeFormat.SECONDS) -> None: + def stop(self, endtime: int | float | None = None) -> None: + """End the timer. + + If 'endtime' is not None, it is used when calculating + the final display time; otherwise the current time is used. + """ if endtime is None: - endtime = ba.time(timeformat=ba.TimeFormat.MILLISECONDS) - timeformat = ba.TimeFormat.MILLISECONDS + endtime = bs.time() + if self._starttime_ms is None: - print('Warning: OnTimer.stop() called without start() first') + logging.warning( + 'OnScreenTimer.stop() called without first calling start()' + ) else: - endtime_ms: int - if timeformat is ba.TimeFormat.SECONDS: - endtime_ms = int(endtime * 1000) - elif timeformat is ba.TimeFormat.MILLISECONDS: - assert isinstance(endtime, int) - endtime_ms = endtime - else: - raise ValueError(f'invalid timeformat: {timeformat}') - + endtime_ms = int(endtime * 1000) self.inputnode.timemax = endtime_ms - self._starttime_ms - # Overloads so type checker knows our exact return type based in args. - @overload - def getstarttime(self, timeformat: Literal[ba.TimeFormat.SECONDS] = ba.TimeFormat.SECONDS) -> float: - ... - - @overload - def getstarttime(self, - timeformat: Literal[ba.TimeFormat.MILLISECONDS]) -> int: - ... - - def getstarttime( - self, - timeformat: ba.TimeFormat = ba.TimeFormat.SECONDS - ) -> Union[int, float]: - """Return the sim-time when start() was called. + def getstarttime(self) -> float: + """Return the scene-time when start() was called. Time will be returned in seconds if timeformat is SECONDS or milliseconds if it is MILLISECONDS. @@ -90,15 +83,11 @@ class OnTimer(ba.Actor): val_ms: Any if self._starttime_ms is None: print('WARNING: getstarttime() called on un-started timer') - val_ms = ba.time(timeformat=ba.TimeFormat.MILLISECONDS) + val_ms = int(bs.time() * 1000.0) else: val_ms = self._starttime_ms assert isinstance(val_ms, int) - if timeformat is ba.TimeFormat.SECONDS: - return 0.001 * val_ms - if timeformat is ba.TimeFormat.MILLISECONDS: - return val_ms - raise ValueError(f'invalid timeformat: {timeformat}') + return 0.001 * val_ms @property def starttime(self) -> float: @@ -107,12 +96,14 @@ class OnTimer(ba.Actor): def handlemessage(self, msg: Any) -> Any: # if we're asked to die, just kill our node/timer - if isinstance(msg, ba.DieMessage): + if isinstance(msg, bs.DieMessage): if self.node: self.node.delete() -class Player(ba.Player['Team']): + + +class Player(bs.Player['Team']): """Our player type for this game.""" def __init__(self) -> None: @@ -120,33 +111,32 @@ class Player(ba.Player['Team']): self.death_time: Optional[float] = None -class Team(ba.Team[Player]): +class Team(bs.Team[Player]): """Our team type for this game.""" -# ba_meta export game -class MGgame(ba.TeamGameActivity[Player, Team]): +# ba_meta export bascenev1.GameActivity +class MGgame(bs.TeamGameActivity[Player, Team]): name = 'Memory Game' description = 'Memories tiles and survive till the end!' - available_settings = [ba.BoolSetting( - 'Epic Mode', default=False), ba.BoolSetting('Enable Bottom Credits', True)] - scoreconfig = ba.ScoreConfig(label='Survived', scoretype=ba.ScoreType.MILLISECONDS, version='B') + available_settings = [bs.BoolSetting('Epic Mode', default=False), bs.BoolSetting('Enable Bottom Credits', True)] + scoreconfig = bs.ScoreConfig(label='Survived', scoretype=bs.ScoreType.MILLISECONDS, version='B') # Print messages when players die (since its meaningful in this game). announce_player_deaths = True # we're currently hard-coded for one map.. @classmethod - def get_supported_maps(cls, sessiontype: Type[ba.Session]) -> List[str]: + def get_supported_maps(cls, sessiontype: Type[bs.Session]) -> List[str]: return ['Sky Tiles'] # 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 supports_session_type(cls, sessiontype: Type[bs.Session]) -> bool: + return (issubclass(sessiontype, bs.DualTeamSession) + or issubclass(sessiontype, bs.FreeForAllSession) + or issubclass(sessiontype, babase.CoopSession)) def __init__(self, settings: dict): super().__init__(settings) @@ -157,14 +147,14 @@ class MGgame(ba.TeamGameActivity[Player, Team]): self.credit_text = bool(settings['Enable Bottom Credits']) # Some base class overrides: - self.default_music = (ba.MusicType.EPIC - if self._epic_mode else ba.MusicType.SURVIVAL) + self.default_music = (bs.MusicType.EPIC + if self._epic_mode else bs.MusicType.SURVIVAL) if self._epic_mode: self.slow_motion = True shared = SharedObjects.get() - self._collide_with_player = ba.Material() + self._collide_with_player=bs.Material() self._collide_with_player.add_actions(actions=(('modify_part_collision', 'collide', True))) - self.dont_collide = ba.Material() + self.dont_collide=bs.Material() self.dont_collide.add_actions(actions=(('modify_part_collision', 'collide', False))) self._levelStage = 0 @@ -172,100 +162,101 @@ class MGgame(ba.TeamGameActivity[Player, Team]): self._lastPlayerDeathTime = None self._spawnCenter = (-3.17358, 2.75764, -2.99124) - self._mapFGPModel = ba.getmodel('buttonSquareOpaque') - self._mapFGPDefaultTex = ba.gettexture('achievementOffYouGo') + self._mapFGPModel = bs.getmesh('buttonSquareOpaque') + self._mapFGPDefaultTex = bs.gettexture('achievementOffYouGo') - self._mapFGCurseTex = ba.gettexture('powerupCurse') - self._mapFGHealthTex = ba.gettexture('powerupHealth') - self._mapFGIceTex = ba.gettexture('powerupIceBombs') - self._mapFGImpactTex = ba.gettexture('powerupImpactBombs') - self._mapFGMinesTex = ba.gettexture('powerupLandMines') - self._mapFGPunchTex = ba.gettexture('powerupPunch') - self._mapFGShieldTex = ba.gettexture('powerupShield') - self._mapFGStickyTex = ba.gettexture('powerupStickyBombs') + self._mapFGCurseTex = bs.gettexture('powerupCurse') + self._mapFGHealthTex = bs.gettexture('powerupHealth') + self._mapFGIceTex = bs.gettexture('powerupIceBombs') + self._mapFGImpactTex = bs.gettexture('powerupImpactBombs') + self._mapFGMinesTex = bs.gettexture('powerupLandMines') + self._mapFGPunchTex = bs.gettexture('powerupPunch') + self._mapFGShieldTex = bs.gettexture('powerupShield') + self._mapFGStickyTex = bs.gettexture('powerupStickyBombs') - self._mapFGSpaz = ba.gettexture('neoSpazIcon') - self._mapFGZoe = ba.gettexture('zoeIcon') - self._mapFGSnake = ba.gettexture('ninjaIcon') - self._mapFGKronk = ba.gettexture('kronkIcon') - self._mapFGMel = ba.gettexture('melIcon') - self._mapFGJack = ba.gettexture('jackIcon') - self._mapFGSanta = ba.gettexture('santaIcon') - self._mapFGFrosty = ba.gettexture('frostyIcon') - self._mapFGBones = ba.gettexture('bonesIcon') - self._mapFGBernard = ba.gettexture('bearIcon') - self._mapFGPascal = ba.gettexture('penguinIcon') - self._mapFGAli = ba.gettexture('aliIcon') - self._mapFGRobot = ba.gettexture('cyborgIcon') - self._mapFGAgent = ba.gettexture('agentIcon') - self._mapFGGrumbledorf = ba.gettexture('wizardIcon') - self._mapFGPixel = ba.gettexture('pixieIcon') + self._mapFGSpaz = bs.gettexture('neoSpazIcon') + self._mapFGZoe = bs.gettexture('zoeIcon') + self._mapFGSnake = bs.gettexture('ninjaIcon') + self._mapFGKronk= bs.gettexture('kronkIcon') + self._mapFGMel = bs.gettexture('melIcon') + self._mapFGJack = bs.gettexture('jackIcon') + self._mapFGSanta = bs.gettexture('santaIcon') + self._mapFGFrosty = bs.gettexture('frostyIcon') + self._mapFGBones = bs.gettexture('bonesIcon') + self._mapFGBernard = bs.gettexture('bearIcon') + self._mapFGPascal = bs.gettexture('penguinIcon') + self._mapFGAli = bs.gettexture('aliIcon') + self._mapFGRobot = bs.gettexture('cyborgIcon') + self._mapFGAgent = bs.gettexture('agentIcon') + self._mapFGGrumbledorf = bs.gettexture('wizardIcon') + self._mapFGPixel = bs.gettexture('pixieIcon') - self._imageTextDefault = ba.gettexture('bg') - self._circleTex = ba.gettexture('circleShadow') + self._imageTextDefault = bs.gettexture('bg') + self._circleTex = bs.gettexture('circleShadow') - self._image = ba.newnode('image', - attrs={'texture': self._imageTextDefault, - 'position': (0, -100), - 'scale': (100, 100), - 'opacity': 0.0, - 'attach': 'topCenter'}) + self._image = bs.newnode('image', + attrs={'texture': self._imageTextDefault, + 'position':(0,-100), + 'scale':(100,100), + 'opacity': 0.0, + 'attach':'topCenter'}) - self._textCounter = ba.newnode('text', - attrs={'text': '10', - 'position': (0, -100), - 'scale': 2.3, - 'shadow': 1.0, - 'flatness': 1.0, - 'opacity': 0.0, - 'v_attach': 'top', - 'h_attach': 'center', - 'h_align': 'center', - 'v_align': 'center'}) + self._textCounter = bs.newnode('text', + attrs={'text': '10', + 'position': (0, -100), + 'scale': 2.3, + 'shadow': 1.0, + 'flatness': 1.0, + 'opacity': 0.0, + 'v_attach': 'top', + 'h_attach': 'center', + 'h_align': 'center', + 'v_align': 'center'}) - self._textLevel = ba.newnode('text', - attrs={'text': 'Level ' + str(self._levelStage), - 'position': (0, -28), - 'scale': 1.3, - 'shadow': 1.0, - 'flatness': 1.0, - 'color': (1.0, 0.0, 1.0), - 'opacity': 0.0, - 'v_attach': 'top', - 'h_attach': 'center', - 'h_align': 'center', - 'v_align': 'center'}) + self._textLevel = bs.newnode('text', + attrs={'text': 'Level ' + str(self._levelStage), + 'position': (0, -28), + 'scale': 1.3, + 'shadow': 1.0, + 'flatness': 1.0, + 'color': (1.0, 0.0, 1.0), + 'opacity': 0.0, + 'v_attach': 'top', + 'h_attach': 'center', + 'h_align': 'center', + 'v_align': 'center'}) + + self._imageCircle = bs.newnode('image', + attrs={'texture': self._circleTex, + 'position': (75, -75), + 'scale': (20,20), + 'color': (0.2, 0.2, 0.2), + 'opacity': 0.0, + 'attach': 'topCenter'}) + self._imageCircle2 = bs.newnode('image', + attrs={'texture': self._circleTex, + 'position': (75, -100), + 'scale': (20,20), + 'color': (0.2, 0.2, 0.2), + 'opacity': 0.0, + 'attach': 'topCenter'}) + self._imageCircle3 = bs.newnode('image', + attrs={'texture': self._circleTex, + 'position': (75, -125), + 'scale': (20,20), + 'color': (0.2, 0.2, 0.2), + 'opacity': 0.0, + 'attach': 'topCenter'}) - self._imageCircle = ba.newnode('image', - attrs={'texture': self._circleTex, - 'position': (75, -75), - 'scale': (20, 20), - 'color': (0.2, 0.2, 0.2), - 'opacity': 0.0, - 'attach': 'topCenter'}) - self._imageCircle2 = ba.newnode('image', - attrs={'texture': self._circleTex, - 'position': (75, -100), - 'scale': (20, 20), - 'color': (0.2, 0.2, 0.2), - 'opacity': 0.0, - 'attach': 'topCenter'}) - self._imageCircle3 = ba.newnode('image', - attrs={'texture': self._circleTex, - 'position': (75, -125), - 'scale': (20, 20), - 'color': (0.2, 0.2, 0.2), - 'opacity': 0.0, - 'attach': 'topCenter'}) def on_transition_in(self) -> None: super().on_transition_in() - self._bellLow = ba.getsound('bellLow') - self._bellMed = ba.getsound('bellMed') - self._bellHigh = ba.getsound('bellHigh') - self._tickSound = ba.getsound('tick') - self._tickFinal = ba.getsound('powerup01') - self._scoreSound = ba.getsound('score') + self._bellLow = bs.getsound('bellLow') + self._bellMed = bs.getsound('bellMed') + self._bellHigh = bs.getsound('bellHigh') + self._tickSound = bs.getsound('tick') + self._tickFinal = bs.getsound('powerup01') + self._scoreSound = bs.getsound('score') self._image.opacity = 1 self._textCounter.opacity = 1 @@ -282,8 +273,8 @@ class MGgame(ba.TeamGameActivity[Player, Team]): if self._levelStage == 1: timeStart = 6 - ba.timer(timeStart, self._randomPlatform) - ba.timer(timeStart, self.startCounter) + bs.timer(timeStart, self._randomPlatform) + bs.timer(timeStart, self.startCounter) def on_begin(self) -> None: super().on_begin() @@ -308,26 +299,25 @@ class MGgame(ba.TeamGameActivity[Player, Team]): self.coldel15 = True self.coldel16 = True if self.credit_text: - t = ba.newnode('text', - attrs={'text': "Made by Freaku\nOriginally for 1.4: byANG3L", # Disable 'Enable Bottom Credits' when making playlist, No need to edit this lovely... - 'scale': 0.7, - 'position': (0, 0), - 'shadow': 0.5, - 'flatness': 1.2, - 'color': (1, 1, 1), - 'h_align': 'center', - 'v_attach': 'bottom'}) - self.spawnAllMap() - self.flashHide() + t = bs.newnode('text', + attrs={ 'text':"Made by Freaku\nOriginally for 1.4: byANG3L", ## Disable 'Enable Bottom Credits' when making playlist, No need to edit this lovely... + 'scale':0.7, + 'position':(0,0), + 'shadow':0.5, + 'flatness':1.2, + 'color':(1, 1, 1), + 'h_align':'center', + 'v_attach':'bottom'}) + self.spawnAllMap() + self.flashHide() # Check for immediate end (if we've only got 1 player, etc). - ba.timer(5, self._check_end_game) - self._dingSound = ba.getsound('dingSmall') - self._dingSoundHigh = ba.getsound('dingSmallHigh') + bs.timer(5, self._check_end_game) + self._dingSound = bs.getsound('dingSmall') + self._dingSoundHigh = bs.getsound('dingSmallHigh') def startCounter(self): self._textCounter.text = '10' - def count9(): def count8(): def count7(): @@ -339,45 +329,45 @@ class MGgame(ba.TeamGameActivity[Player, Team]): def count1(): def countFinal(): self._textCounter.text = '' - ba.playsound(self._tickFinal) + self._tickFinal.play() self._stop() self._textCounter.text = '1' - ba.playsound(self._tickSound) - ba.timer(1, countFinal) + self._tickSound.play() + bs.timer(1, countFinal) self._textCounter.text = '2' - ba.playsound(self._tickSound) - ba.timer(1, count1) + self._tickSound.play() + bs.timer(1, count1) self._textCounter.text = '3' - ba.playsound(self._tickSound) - ba.timer(1, count2) + self._tickSound.play() + bs.timer(1, count2) self._textCounter.text = '4' - ba.playsound(self._tickSound) - ba.timer(1, count3) + self._tickSound.play() + bs.timer(1, count3) self._textCounter.text = '5' - ba.playsound(self._tickSound) - ba.timer(1, count4) + self._tickSound.play() + bs.timer(1, count4) self._textCounter.text = '6' - ba.playsound(self._tickSound) - ba.timer(1, count5) + self._tickSound.play() + bs.timer(1, count5) self._textCounter.text = '7' - ba.playsound(self._tickSound) - ba.timer(1, count6) + self._tickSound.play() + bs.timer(1, count6) self._textCounter.text = '8' - ba.playsound(self._tickSound) - ba.timer(1, count7) + self._tickSound.play() + bs.timer(1, count7) self._textCounter.text = '9' - ba.playsound(self._tickSound) - ba.timer(1, count8) - ba.timer(1, count9) + self._tickSound.play() + bs.timer(1, count8) + bs.timer(1, count9) def on_player_join(self, player: Player) -> None: # Don't allow joining after we start # (would enable leave/rejoin tomfoolery). if self.has_begun(): - ba.screenmessage( - ba.Lstr(resource='playerDelayedJoinText', + bs.broadcastmessage( + babase.Lstr(resource='playerDelayedJoinText', subs=[('${PLAYER}', player.getname(full=True))]), - color=(0, 1, 0), transient=True, clients=[player.sessionplayer.inputdevice.client_id]) + color=(0, 1, 0),transient=True,clients=[player.sessionplayer.inputdevice.client_id]) # For score purposes, mark them as having died right as the # game started. assert self._timer is not None @@ -393,184 +383,182 @@ class MGgame(ba.TeamGameActivity[Player, Team]): self._check_end_game() # overriding the default character spawning.. - def spawn_player(self, player: Player) -> ba.Actor: + def spawn_player(self, player: Player) -> bs.Actor: spaz = self.spawn_player_spaz(player) - pos = (self._spawnCenter[0] + random.uniform(-1.5, 2.5), - self._spawnCenter[1], self._spawnCenter[2] + random.uniform(-2.5, 1.5)) + pos = (self._spawnCenter[0] + random.uniform(-1.5, 2.5), self._spawnCenter[1], self._spawnCenter[2] + random.uniform(-2.5, 1.5)) spaz.connect_controls_to_player(enable_punch=False, enable_bomb=False, enable_pickup=False) - spaz.handlemessage(ba.StandMessage(pos)) + spaz.handlemessage(bs.StandMessage(pos)) return spaz def _randomSelect(self): if self._levelStage == 1: self._textureSelected = random.choice([self._mapFGMinesTex, - self._mapFGStickyTex]) + self._mapFGStickyTex]) self._image.texture = self._textureSelected elif self._levelStage == 2: self._textureSelected = random.choice([self._mapFGIceTex, - self._mapFGShieldTex]) + self._mapFGShieldTex]) self._image.texture = self._textureSelected - elif self._levelStage in [3, 4, 5]: + elif self._levelStage in [3,4,5]: self._textureSelected = random.choice([self._mapFGStickyTex, - self._mapFGIceTex, - self._mapFGImpactTex, - self._mapFGMinesTex]) + self._mapFGIceTex, + self._mapFGImpactTex, + self._mapFGMinesTex]) self._image.texture = self._textureSelected - elif self._levelStage in [6, 7, 8, 9]: + elif self._levelStage in [6,7,8,9]: self._textureSelected = random.choice([self._mapFGCurseTex, - self._mapFGHealthTex, - self._mapFGIceTex, - self._mapFGImpactTex, - self._mapFGMinesTex, - self._mapFGPunchTex, - self._mapFGShieldTex]) + self._mapFGHealthTex, + self._mapFGIceTex, + self._mapFGImpactTex, + self._mapFGMinesTex, + self._mapFGPunchTex, + self._mapFGShieldTex]) self._image.texture = self._textureSelected elif self._levelStage >= 10: self._textureSelected = random.choice([self._mapFGSpaz, - self._mapFGZoe, - self._mapFGSnake, - self._mapFGKronk, - self._mapFGMel, - self._mapFGJack, - self._mapFGSanta, - self._mapFGFrosty, - self._mapFGBones, - self._mapFGBernard, - self._mapFGPascal, - self._mapFGAli, - self._mapFGRobot, - self._mapFGAgent, - self._mapFGGrumbledorf, - self._mapFGPixel]) + self._mapFGZoe, + self._mapFGSnake, + self._mapFGKronk, + self._mapFGMel, + self._mapFGJack, + self._mapFGSanta, + self._mapFGFrosty, + self._mapFGBones, + self._mapFGBernard, + self._mapFGPascal, + self._mapFGAli, + self._mapFGRobot, + self._mapFGAgent, + self._mapFGGrumbledorf, + self._mapFGPixel]) self._image.texture = self._textureSelected return self._textureSelected def _stop(self): self._textureSelected = self._randomSelect() - def circle(): def circle2(): def circle3(): self._imageCircle3.color = (0.0, 1.0, 0.0) self._imageCircle3.opacity = 1.0 - ba.playsound(self._bellHigh) - ba.timer(0.2, self._doDelete) + self._bellHigh.play() + bs.timer(0.2, self._doDelete) self._imageCircle2.color = (1.0, 1.0, 0.0) self._imageCircle2.opacity = 1.0 - ba.playsound(self._bellMed) - ba.timer(1, circle3) + self._bellMed.play() + bs.timer(1, circle3) self._imageCircle.color = (1.0, 0.0, 0.0) self._imageCircle.opacity = 1.0 - ba.playsound(self._bellLow) - ba.timer(1, circle2) - ba.timer(1, circle) + self._bellLow.play() + bs.timer(1, circle2) + bs.timer(1, circle) def _randomPlatform(self): if self._levelStage == 1: - randomTexture = [self._mapFGMinesTex, - self._mapFGMinesTex, - self._mapFGMinesTex, - self._mapFGMinesTex, - self._mapFGMinesTex, - self._mapFGMinesTex, - self._mapFGMinesTex, - self._mapFGMinesTex, - self._mapFGStickyTex, - self._mapFGStickyTex, - self._mapFGStickyTex, - self._mapFGStickyTex, - self._mapFGStickyTex, - self._mapFGStickyTex, - self._mapFGStickyTex, - self._mapFGStickyTex] + randomTexture=[self._mapFGMinesTex, + self._mapFGMinesTex, + self._mapFGMinesTex, + self._mapFGMinesTex, + self._mapFGMinesTex, + self._mapFGMinesTex, + self._mapFGMinesTex, + self._mapFGMinesTex, + self._mapFGStickyTex, + self._mapFGStickyTex, + self._mapFGStickyTex, + self._mapFGStickyTex, + self._mapFGStickyTex, + self._mapFGStickyTex, + self._mapFGStickyTex, + self._mapFGStickyTex] elif self._levelStage == 2: - randomTexture = [self._mapFGIceTex, - self._mapFGIceTex, - self._mapFGIceTex, - self._mapFGIceTex, - self._mapFGIceTex, - self._mapFGIceTex, - self._mapFGIceTex, - self._mapFGIceTex, - self._mapFGShieldTex, - self._mapFGShieldTex, - self._mapFGShieldTex, - self._mapFGShieldTex, - self._mapFGShieldTex, - self._mapFGShieldTex, - self._mapFGShieldTex, - self._mapFGShieldTex] - elif self._levelStage in [3, 4, 5]: - randomTexture = [self._mapFGStickyTex, - self._mapFGStickyTex, - self._mapFGStickyTex, - self._mapFGStickyTex, - self._mapFGIceTex, - self._mapFGIceTex, - self._mapFGIceTex, - self._mapFGIceTex, - self._mapFGImpactTex, - self._mapFGImpactTex, - self._mapFGImpactTex, - self._mapFGImpactTex, - self._mapFGMinesTex, - self._mapFGMinesTex, - self._mapFGMinesTex, - self._mapFGMinesTex] - elif self._levelStage in [6, 7, 8, 9]: - randomTexture = [self._mapFGHealthTex, - self._mapFGShieldTex, - self._mapFGCurseTex, - self._mapFGCurseTex, - self._mapFGHealthTex, - self._mapFGHealthTex, - self._mapFGIceTex, - self._mapFGIceTex, - self._mapFGImpactTex, - self._mapFGImpactTex, - self._mapFGMinesTex, - self._mapFGMinesTex, - self._mapFGPunchTex, - self._mapFGPunchTex, - self._mapFGShieldTex, - self._mapFGShieldTex] + randomTexture=[self._mapFGIceTex, + self._mapFGIceTex, + self._mapFGIceTex, + self._mapFGIceTex, + self._mapFGIceTex, + self._mapFGIceTex, + self._mapFGIceTex, + self._mapFGIceTex, + self._mapFGShieldTex, + self._mapFGShieldTex, + self._mapFGShieldTex, + self._mapFGShieldTex, + self._mapFGShieldTex, + self._mapFGShieldTex, + self._mapFGShieldTex, + self._mapFGShieldTex] + elif self._levelStage in [3,4,5]: + randomTexture=[self._mapFGStickyTex, + self._mapFGStickyTex, + self._mapFGStickyTex, + self._mapFGStickyTex, + self._mapFGIceTex, + self._mapFGIceTex, + self._mapFGIceTex, + self._mapFGIceTex, + self._mapFGImpactTex, + self._mapFGImpactTex, + self._mapFGImpactTex, + self._mapFGImpactTex, + self._mapFGMinesTex, + self._mapFGMinesTex, + self._mapFGMinesTex, + self._mapFGMinesTex] + elif self._levelStage in [6,7,8,9]: + randomTexture=[self._mapFGHealthTex, + self._mapFGShieldTex, + self._mapFGCurseTex, + self._mapFGCurseTex, + self._mapFGHealthTex, + self._mapFGHealthTex, + self._mapFGIceTex, + self._mapFGIceTex, + self._mapFGImpactTex, + self._mapFGImpactTex, + self._mapFGMinesTex, + self._mapFGMinesTex, + self._mapFGPunchTex, + self._mapFGPunchTex, + self._mapFGShieldTex, + self._mapFGShieldTex] elif self._levelStage >= 10: - randomTexture = [self._mapFGSpaz, - self._mapFGZoe, - self._mapFGSnake, - self._mapFGKronk, - self._mapFGMel, - self._mapFGJack, - self._mapFGSanta, - self._mapFGFrosty, - self._mapFGBones, - self._mapFGBernard, - self._mapFGPascal, - self._mapFGAli, - self._mapFGRobot, - self._mapFGAgent, - self._mapFGGrumbledorf, - self._mapFGPixel] + randomTexture=[self._mapFGSpaz, + self._mapFGZoe, + self._mapFGSnake, + self._mapFGKronk, + self._mapFGMel, + self._mapFGJack, + self._mapFGSanta, + self._mapFGFrosty, + self._mapFGBones, + self._mapFGBernard, + self._mapFGPascal, + self._mapFGAli, + self._mapFGRobot, + self._mapFGAgent, + self._mapFGGrumbledorf, + self._mapFGPixel] (self.mapFGPTex, self.mapFGP2Tex, self.mapFGP3Tex, self.mapFGP4Tex, - self.mapFGP5Tex, self.mapFGP6Tex, - self.mapFGP7Tex, self.mapFGP8Tex, - self.mapFGP9Tex, self.mapFGP10Tex, - self.mapFGP11Tex, self.mapFGP12Tex, - self.mapFGP13Tex, self.mapFGP14Tex, - self.mapFGP15Tex, self.mapFGP16Tex) = ( - random.sample(randomTexture, 16)) + self.mapFGP5Tex, self.mapFGP6Tex, + self.mapFGP7Tex, self.mapFGP8Tex, + self.mapFGP9Tex,self.mapFGP10Tex, + self.mapFGP11Tex, self.mapFGP12Tex, + self.mapFGP13Tex, self.mapFGP14Tex, + self.mapFGP15Tex, self.mapFGP16Tex) = ( + random.sample(randomTexture, 16)) self._mixPlatform() def _mixPlatform(self): - ba.timer(1, self.flashShow) - ba.timer(3, self.flashHide) - ba.timer(4, self.flashShow) - ba.timer(6, self.flashHide) - ba.timer(7, self.flashShow) - ba.timer(9, self.flashHide) - ba.timer(13.2, self.flashShow) + bs.timer(1, self.flashShow) + bs.timer(3, self.flashHide) + bs.timer(4, self.flashShow) + bs.timer(6, self.flashHide) + bs.timer(7, self.flashShow) + bs.timer(9, self.flashHide) + bs.timer(13.2, self.flashShow) def flashHide(self): self.mapFGP.color_texture = self._mapFGPDefaultTex @@ -674,14 +662,14 @@ class MGgame(ba.TeamGameActivity[Player, Team]): self.mapFGP16col.delete() self.coldel16 = True - ba.timer(3.3, self._platformTexDefault) + bs.timer(3.3, self._platformTexDefault) def spawnAllMap(self): """ # Here's how it works: # First, create prop with a gravity scale of 0 - # Then use a in-game model which will suit it (For this one I didn't chose box, since it will look kinda weird) Right? - # Instead I used a 2d model (which is nothing but a button in menu) + # Then use a in-game mesh which will suit it (For this one I didn't chose box, since it will look kinda weird) Right? + # Instead I used a 2d mesh (which is nothing but a button in menu) # This prop SHOULD NOT collide with anything, since it has gravity_scale of 0 if it'll get weight it will fall down :(( # These are where we change those color-textures and is seen in-game @@ -696,131 +684,115 @@ class MGgame(ba.TeamGameActivity[Player, Team]): """ shared = SharedObjects.get() if self.coldel: - self.mapFGP = ba.newnode('prop', - attrs={'body': 'puck', 'position': (3, 2, -9), 'model': self._mapFGPModel, 'model_scale': 3.8, 'body_scale': 3.8, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP = bs.newnode('prop', + attrs={'body': 'puck', 'position': (4.5,2,-9), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGPTex = None - self.mapFGPcol = ba.newnode('region', attrs={'position': (3, 2, -9), 'scale': ( - 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGPcol = bs.newnode('region',attrs={'position': (4.5,2,-9),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) self.coldel = False if self.coldel2: - self.mapFGP2 = ba.newnode('prop', - attrs={'body': 'puck', 'position': (3, 2, -6), 'model': self._mapFGPModel, 'model_scale': 3.8, 'body_scale': 3.8, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP2 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (4.5,2,-6), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP2Tex = None - self.mapFGP2col = ba.newnode('region', attrs={'position': (3, 2, -6), 'scale': ( - 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP2col = bs.newnode('region',attrs={'position': (4.5,2,-6),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) self.coldel2 = False if self.coldel3: - self.mapFGP3 = ba.newnode('prop', - attrs={'body': 'puck', 'position': (3, 2, -3), 'model': self._mapFGPModel, 'model_scale': 3.8, 'body_scale': 3.8, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP3 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (4.5,2,-3), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP3Tex = None - self.mapFGP3col = ba.newnode('region', attrs={'position': (3, 2, -3), 'scale': ( - 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP3col = bs.newnode('region',attrs={'position': (4.5,2,-3),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) self.coldel3 = False if self.coldel4: - self.mapFGP4 = ba.newnode('prop', - attrs={'body': 'puck', 'position': (3, 2, 0), 'model': self._mapFGPModel, 'model_scale': 3.8, 'body_scale': 3.8, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP4 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (4.5,2,0), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP4Tex = None - self.mapFGP4col = ba.newnode('region', attrs={'position': (3, 2, 0), 'scale': ( - 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP4col = bs.newnode('region',attrs={'position': (4.5,2,0),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) self.coldel4 = False if self.coldel5: - self.mapFGP5 = ba.newnode('prop', - attrs={'body': 'puck', 'position': (0, 2, -9), 'model': self._mapFGPModel, 'model_scale': 3.8, 'body_scale': 3.8, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP5 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (1.5,2,-9), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP5Tex = None - self.mapFGP5col = ba.newnode('region', attrs={'position': (0, 2, -9), 'scale': ( - 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP5col = bs.newnode('region',attrs={'position': (1.5,2,-9),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) self.coldel5 = False if self.coldel6: - self.mapFGP6 = ba.newnode('prop', - attrs={'body': 'puck', 'position': (0, 2, -6), 'model': self._mapFGPModel, 'model_scale': 3.8, 'body_scale': 3.8, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP6 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (1.5,2,-6), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP6Tex = None - self.mapFGP6col = ba.newnode('region', attrs={'position': (0, 2, -6), 'scale': ( - 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP6col = bs.newnode('region',attrs={'position': (1.5,2,-6),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) self.coldel6 = False if self.coldel7: - self.mapFGP7 = ba.newnode('prop', - attrs={'body': 'puck', 'position': (0, 2, -3), 'model': self._mapFGPModel, 'model_scale': 3.8, 'body_scale': 3.8, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP7 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (1.5,2,-3), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP7Tex = None - self.mapFGP7col = ba.newnode('region', attrs={'position': (0, 2, -3), 'scale': ( - 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP7col = bs.newnode('region',attrs={'position': (1.5,2,-3),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) self.coldel7 = False if self.coldel8: - self.mapFGP8 = ba.newnode('prop', - attrs={'body': 'puck', 'position': (0, 2, 0), 'model': self._mapFGPModel, 'model_scale': 3.8, 'body_scale': 3.8, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP8 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (1.5,2,0), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP8Tex = None - self.mapFGP8col = ba.newnode('region', attrs={'position': (0, 2, 0), 'scale': ( - 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP8col = bs.newnode('region',attrs={'position': (1.5,2,0),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) self.coldel8 = False if self.coldel9: - self.mapFGP9 = ba.newnode('prop', - attrs={'body': 'puck', 'position': (-3, 2, -9), 'model': self._mapFGPModel, 'model_scale': 3.8, 'body_scale': 3.8, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP9 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (-1.5,2,-9), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP9Tex = None - self.mapFGP9col = ba.newnode('region', attrs={'position': (-3, 2, -9), 'scale': ( - 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP9col = bs.newnode('region',attrs={'position': (-1.5,2,-9),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) self.coldel9 = False if self.coldel10: - self.mapFGP10 = ba.newnode('prop', - attrs={'body': 'puck', 'position': (-3, 2, -6), 'model': self._mapFGPModel, 'model_scale': 3.8, 'body_scale': 3.8, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP10 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (-1.5,2,-6), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP10Tex = None - self.mapFGP10col = ba.newnode('region', attrs={'position': (-3, 2, -6), 'scale': ( - 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP10col = bs.newnode('region',attrs={'position': (-1.5,2,-6),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) self.coldel10 = False if self.coldel11: - self.mapFGP11 = ba.newnode('prop', - attrs={'body': 'puck', 'position': (-3, 2, -3), 'model': self._mapFGPModel, 'model_scale': 3.8, 'body_scale': 3.8, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP11 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (-1.5,2,-3), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP11Tex = None - self.mapFGP11col = ba.newnode('region', attrs={'position': (-3, 2, -3), 'scale': ( - 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP11col = bs.newnode('region',attrs={'position': (-1.5,2,-3),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) self.coldel11 = False if self.coldel12: - self.mapFGP12 = ba.newnode('prop', - attrs={'body': 'puck', 'position': (-3, 2, 0), 'model': self._mapFGPModel, 'model_scale': 3.8, 'body_scale': 3.8, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP12 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (-1.5,2,0), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP12Tex = None - self.mapFGP12col = ba.newnode('region', attrs={'position': (-3, 2, 0), 'scale': ( - 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP12col = bs.newnode('region',attrs={'position': (-1.5,2,0),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) self.coldel12 = False if self.coldel13: - self.mapFGP13 = ba.newnode('prop', - attrs={'body': 'puck', 'position': (-6, 2, -9), 'model': self._mapFGPModel, 'model_scale': 3.8, 'body_scale': 3.8, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP13 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (-4.5,2,-9), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP13Tex = None - self.mapFGP13col = ba.newnode('region', attrs={'position': (-6, 2, -9), 'scale': ( - 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP13col = bs.newnode('region',attrs={'position': (-4.5,2,-9),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) self.coldel13 = False if self.coldel14: - self.mapFGP14 = ba.newnode('prop', - attrs={'body': 'puck', 'position': (-6, 2, -6), 'model': self._mapFGPModel, 'model_scale': 3.8, 'body_scale': 3.8, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP14 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (-4.5,2,-6), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP14Tex = None - self.mapFGP14col = ba.newnode('region', attrs={'position': (-6, 2, -6), 'scale': ( - 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP14col = bs.newnode('region',attrs={'position': (-4.5,2,-6),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) self.coldel14 = False if self.coldel15: - self.mapFGP15 = ba.newnode('prop', - attrs={'body': 'puck', 'position': (-6, 2, -3), 'model': self._mapFGPModel, 'model_scale': 3.8, 'body_scale': 3.8, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP15 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (-4.5,2,-3), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP15Tex = None - self.mapFGP15col = ba.newnode('region', attrs={'position': (-6, 2, -3), 'scale': ( - 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP15col = bs.newnode('region',attrs={'position': (-4.5,2,-3),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) self.coldel15 = False if self.coldel16: - self.mapFGP16 = ba.newnode('prop', - attrs={'body': 'puck', 'position': (-6, 2, 0), 'model': self._mapFGPModel, 'model_scale': 3.8, 'body_scale': 3.8, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP16 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (-4.5,2,0), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP16Tex = None - self.mapFGP16col = ba.newnode('region', attrs={'position': (-6, 2, 0), 'scale': ( - 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP16col = bs.newnode('region',attrs={'position': (-4.5,2,0),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) self.coldel16 = False def _platformTexDefault(self): @@ -843,27 +815,27 @@ class MGgame(ba.TeamGameActivity[Player, Team]): timeStart = 6 else: timeStart = 2 - ba.playsound(self._scoreSound) - activity = _ba.get_foreground_host_activity() + self._scoreSound.play() + activity = bs.get_foreground_host_activity() for i in activity.players: try: - i.actor.node.handlemessage(ba.CelebrateMessage(2.0)) + i.actor.node.handlemessage(bs.CelebrateMessage(2.0)) except: pass - ba.timer(timeStart, self._randomPlatform) - ba.timer(timeStart, self.startCounter) + bs.timer(timeStart, self._randomPlatform) + bs.timer(timeStart, self.startCounter) self.spawnAllMap() self.flashHide() # Various high-level game events come through this method. def handlemessage(self, msg: Any) -> Any: - if isinstance(msg, ba.PlayerDiedMessage): + if isinstance(msg, bs.PlayerDiedMessage): # Augment standard behavior. super().handlemessage(msg) - curtime = ba.time() + curtime = bs.time() # Record the player's moment of death. # assert isinstance(msg.spaz.player @@ -873,15 +845,15 @@ class MGgame(ba.TeamGameActivity[Player, Team]): # (more accurate looking). # In teams/ffa, allow a one-second fudge-factor so we can # get more draws if players die basically at the same time. - if isinstance(self.session, ba.CoopSession): + if isinstance(self.session, bs.CoopSession): # Teams will still show up if we check now.. check in # the next cycle. - ba.pushcall(self._check_end_game) + babase.pushcall(self._check_end_game) # Also record this for a final setting of the clock. self._last_player_death_time = curtime else: - ba.timer(1.0, self._check_end_game) + bs.timer(1.0, self._check_end_game) else: # Default handler: return super().handlemessage(msg) @@ -897,15 +869,16 @@ class MGgame(ba.TeamGameActivity[Player, Team]): # In co-op, we go till everyone is dead.. otherwise we go # until one team remains. - if isinstance(self.session, ba.CoopSession): + if isinstance(self.session, bs.CoopSession): if living_team_count <= 0: self.end_game() else: if living_team_count <= 1: self.end_game() + def end_game(self) -> None: - cur_time = ba.time() + cur_time = bs.time() assert self._timer is not None start_time = self._timer.getstarttime() @@ -936,7 +909,7 @@ class MGgame(ba.TeamGameActivity[Player, Team]): # Ok now calc game results: set a score for each team and then tell # the game to end. - results = ba.GameResults() + results = bs.GameResults() # Remember that 'free-for-all' mode is simply a special form # of 'teams' mode where each player gets their own team, so we can @@ -956,16 +929,20 @@ class MGgame(ba.TeamGameActivity[Player, Team]): self.end(results=results) + + + + + + + class MGdefs(): points = {} boxes = {} - boxes['area_of_interest_bounds'] = ( - 0.3544110667, 4.493562578, -2.518391331) + (0.0, 0.0, 0.0) + (16.64754831, 8.06138989, 18.5029888) - boxes['map_bounds'] = (0.2608783669, 4.899663734, -3.543675157) + \ - (0.0, 0.0, 0.0) + (29.23565494, 14.19991443, 29.92689344) + boxes['area_of_interest_bounds'] = (0.3544110667, 4.493562578, -2.518391331) + (0.0, 0.0, 0.0) + (16.64754831, 8.06138989, 18.5029888) + boxes['map_bounds'] = (0.2608783669, 4.899663734, -3.543675157) + (0.0, 0.0, 0.0) + (29.23565494, 14.19991443, 29.92689344) - -class MGmap(ba.Map): +class MGmap(bs.Map): defs = MGdefs() name = 'Sky Tiles' @@ -981,23 +958,23 @@ class MGmap(ba.Map): @classmethod def on_preload(cls) -> Any: data: Dict[str, Any] = { - 'bgtex': ba.gettexture('menuBG'), - 'bgmodel': ba.getmodel('thePadBG') + 'bgtex': bs.gettexture('menuBG'), + 'bgmesh': bs.getmesh('thePadBG') } return data def __init__(self) -> None: super().__init__() shared = SharedObjects.get() - self.node = ba.newnode( + self.node = bs.newnode( 'terrain', attrs={ - 'model': self.preloaddata['bgmodel'], + 'mesh': self.preloaddata['bgmesh'], 'lighting': False, 'background': True, 'color_texture': self.preloaddata['bgtex'] }) - gnode = ba.getactivity().globalsnode + gnode = bs.getactivity().globalsnode gnode.tint = (1.3, 1.2, 1.0) gnode.ambient_color = (1.3, 1.2, 1.0) gnode.vignette_outer = (0.57, 0.57, 0.57) @@ -1006,12 +983,16 @@ class MGmap(ba.Map): gnode.vr_near_clip = 0.5 -ba._map.register_map(MGmap) + + + +bs._map.register_map(MGmap) + + # ba_meta export plugin -class byFreaku(ba.Plugin): +class byFreaku(babase.Plugin): def __init__(self): ## Campaign support ## - ba.app.add_coop_practice_level(ba.Level(name='Memory Game', displayname='${GAME}', gametype=MGgame, settings={ - }, preview_texture_name='achievementOffYouGo')) + babase.app.classic.add_coop_practice_level(bs.Level(name='Memory Game', displayname='${GAME}', gametype=MGgame, settings={}, preview_texture_name='achievementOffYouGo')) \ No newline at end of file diff --git a/plugins/minigames/musical_flags.py b/plugins/minigames/musical_flags.py index fbe9d2e..41828b3 100644 --- a/plugins/minigames/musical_flags.py +++ b/plugins/minigames/musical_flags.py @@ -1,100 +1,99 @@ -# Made by MattZ45986 on GitHub -# Ported by: Freaku / @[Just] Freak#4999 +## Made by MattZ45986 on GitHub +## Ported by your friend: Freaku -# Bug Fixes & Improvements as well... +#Bug Fixes & Improvements as well... -# Join BCS: +#Join BCS: # https://discord.gg/ucyaesh + + from __future__ import annotations from typing import TYPE_CHECKING -import _ba -import ba -import random -import 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', - attrs={'text': '', - 'position': (0, -38), - 'scale': 1, - 'shadow': 1.0, - 'flatness': 1.0, - 'color': (1.0, 0.0, 1.0), - 'opacity': 1, - 'v_attach': 'top', - 'h_attach': 'center', - 'h_align': 'center', - 'v_align': 'center'}) + self._textRound = bs.newnode('text', + attrs={'text': '', + 'position': (0, -38), + 'scale': 1, + 'shadow': 1.0, + 'flatness': 1.0, + 'color': (1.0, 0.0, 1.0), + 'opacity': 1, + 'v_attach': 'top', + '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' @@ -104,10 +103,10 @@ 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) + color=(0, 1, 0),transient=True) player.survived = False return self.spawn_player(player) @@ -115,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() @@ -124,74 +123,97 @@ class MFGame(ba.TeamGameActivity[Player, Team]): self.nodes = [] self.flags = [] self.spawned = [] - self.setup_standard_time_limit(self._time_limit) if self.credit_text: - t = ba.newnode('text', - attrs={'text': "Ported by Freaku\nMade by MattZ45986", # Disable 'Enable Bottom Credits' when making playlist, No need to edit this lovely... - 'scale': 0.7, - 'position': (0, 0), - 'shadow': 0.5, - 'flatness': 1.2, - 'color': (1, 1, 1), - 'h_align': 'center', - 'v_attach': 'bottom'}) + t = bs.newnode('text', + attrs={ 'text':"Ported by Freaku\nMade by MattZ45986", ## Disable 'Enable Bottom Credits' when making playlist, No need to edit this lovely... + 'scale':0.7, + 'position':(0,0), + 'shadow':0.5, + 'flatness':1.2, + 'color':(1, 1, 1), + 'h_align':'center', + 'v_attach':'bottom'}) 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: - if player.survived: - player.team.score += 1 + if player.survived: player.team.score += 1 self.roundNum += 1 self._textRound.text = 'Round ' + str(self.roundNum) self.flags = [] self.spawned = [] - angle = random.randint(0, 359) - c = 0 + 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: - if player.survived: - c += 1 + if player.survived: c+=1 spacing = 10 for player in self.players: player.done = False if player.survived: if not player.is_alive(): - self.spawn_player(player, (.5, 5, -4)) + self.spawn_player(player,(.5,5,-4)) self.spawned.append(player) - 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)] + 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): angle += spacing angle %= 360 - x = 6 * math.sin(math.degrees(angle)) - z = 6 * math.cos(math.degrees(angle)) - flag = Flag(position=(x+.5, 5, z-4), color=colors[i]).autoretain() + x=6 * math.sin(math.degrees(angle)) + z=6 * math.cos(math.degrees(angle)) + flag = Flag(position=(x+.5,5,z-4), color=colors[i]).autoretain() self.flags.append(flag) def killRound(self): self.numPickedUp = 0 for player in self.players: - if player.is_alive(): - player.actor.handlemessage(ba.DieMessage()) - for flag in self.flags: - flag.node.delete() - for light in self.nodes: - light.delete() + 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)) + 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(bs.StandMessage(pos)) return spaz def check_respawn(self, player): @@ -200,36 +222,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', - owner=None, - attrs={'color': msg.node.color, - 'position': (msg.node.position_center), - 'intensity': 1}) + 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())) - except: - pass - ba.timer(3.5, self.killRound) - ba.timer(3.55, self.makeRound) + 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 + bs.timer(3.5,self.killRound) + bs.timer(3.55,self.makeRound) else: return super().handlemessage(msg) return None @@ -238,15 +261,15 @@ class MFGame(ba.TeamGameActivity[Player, Team]): i = 0 for player in self.players: if player.survived: - i += 1 + i+=1 if i <= 1: 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 diff --git a/plugins/minigames/volleyball.py b/plugins/minigames/volleyball.py index d4aeacc..b255950 100644 --- a/plugins/minigames/volleyball.py +++ b/plugins/minigames/volleyball.py @@ -1,16 +1,22 @@ # Volley Ball (final) -# Made by your friend: Freaku / @[Just] Freak#4999 +# Made by your friend: Freaku + + # Join BCS: # https://discord.gg/ucyaesh + + # My GitHub: # https://github.com/Freaku17/BombSquad-Mods-byFreaku + + # CHANGELOG: """ ## 2021 @@ -28,30 +34,37 @@ ## 2022 - Code cleanup -- No longer requires a plugin - More accurate Goal positions """ -# ba_meta require api 7 + + + + + + + + +# ba_meta require api 8 from __future__ import annotations from typing import TYPE_CHECKING -import _ba -import ba -import random -from bastd.actor.playerspaz import PlayerSpaz -from bastd.actor.scoreboard import Scoreboard -from bastd.actor.powerupbox import PowerupBoxFactory -from bastd.actor.bomb import BombFactory -from bastd.gameutils import SharedObjects +import babase, random +import bascenev1 as bs +from bascenev1lib.actor.playerspaz import PlayerSpaz +from bascenev1lib.actor.scoreboard import Scoreboard +from bascenev1lib.actor.powerupbox import PowerupBoxFactory +from bascenev1lib.actor.bomb import BombFactory +from bascenev1lib.gameutils import SharedObjects if TYPE_CHECKING: from typing import Any, Sequence, Dict, Type, List, Optional, Union + class PuckDiedMessage: """Inform something that a puck has died.""" @@ -59,7 +72,7 @@ class PuckDiedMessage: self.puck = puck -class Puck(ba.Actor): +class Puck(bs.Actor): def __init__(self, position: Sequence[float] = (0.0, 1.0, 0.0)): super().__init__() shared = SharedObjects.get() @@ -72,30 +85,31 @@ class Puck(ba.Actor): assert activity is not None assert isinstance(activity, VolleyBallGame) pmats = [shared.object_material, activity.puck_material] - self.node = ba.newnode('prop', + self.node = bs.newnode('prop', delegate=self, attrs={ - 'model': activity.puck_model, + 'mesh': activity.puck_mesh, 'color_texture': activity.puck_tex, 'body': 'sphere', 'reflection': 'soft', 'reflection_scale': [0.2], 'shadow_size': 0.6, - 'model_scale': 0.4, + 'mesh_scale': 0.4, 'body_scale': 1.07, 'is_area_of_interest': True, 'position': self._spawn_pos, 'materials': pmats }) - + # Since it rolls on spawn, lets make gravity # to 0, and when another node (bomb/spaz) # touches it. It'll act back as our normie puck! - ba.animate(self.node, 'gravity_scale', {0: -0.1, 0.2: 1}, False) + bs.animate(self.node, 'gravity_scale', {0:-0.1, 0.2:1}, False) # When other node touches, it realises its new gravity_scale + def handlemessage(self, msg: Any) -> Any: - if isinstance(msg, ba.DieMessage): + if isinstance(msg, bs.DieMessage): assert self.node self.node.delete() activity = self._activity() @@ -103,11 +117,11 @@ class Puck(ba.Actor): activity.handlemessage(PuckDiedMessage(self)) # If we go out of bounds, move back to where we started. - elif isinstance(msg, ba.OutOfBoundsMessage): + elif isinstance(msg, bs.OutOfBoundsMessage): assert self.node self.node.position = self._spawn_pos - elif isinstance(msg, ba.HitMessage): + elif isinstance(msg, bs.HitMessage): assert self.node assert msg.force_direction is not None self.node.handlemessage( @@ -128,29 +142,28 @@ class Puck(ba.Actor): super().handlemessage(msg) -class Player(ba.Player['Team']): +class Player(bs.Player['Team']): """Our player type for this game.""" -class Team(ba.Team[Player]): +class Team(bs.Team[Player]): """Our team type for this game.""" - def __init__(self) -> None: self.score = 0 -# ba_meta export game -class VolleyBallGame(ba.TeamGameActivity[Player, Team]): +# ba_meta export bascenev1.GameActivity +class VolleyBallGame(bs.TeamGameActivity[Player, Team]): name = 'Volley Ball' description = 'Score some goals.\nby \ue048Freaku' available_settings = [ - ba.IntSetting( + bs.IntSetting( 'Score to Win', min_value=1, default=1, increment=1, ), - ba.IntChoiceSetting( + bs.IntChoiceSetting( 'Time Limit', choices=[ ('None', 0), @@ -162,7 +175,7 @@ class VolleyBallGame(ba.TeamGameActivity[Player, Team]): ], default=0, ), - ba.FloatChoiceSetting( + bs.FloatChoiceSetting( 'Respawn Times', choices=[ ('Shorter', 0.25), @@ -173,36 +186,36 @@ class VolleyBallGame(ba.TeamGameActivity[Player, Team]): ], default=1.0, ), - ba.BoolSetting('Epic Mode', True), - ba.BoolSetting('Night Mode', False), - ba.BoolSetting('Icy Floor', True), - ba.BoolSetting('Disable Punch', False), - ba.BoolSetting('Disable Bombs', False), - ba.BoolSetting('Enable Bottom Credits', True), + bs.BoolSetting('Epic Mode', True), + bs.BoolSetting('Night Mode', False), + bs.BoolSetting('Icy Floor', True), + bs.BoolSetting('Disable Punch', False), + bs.BoolSetting('Disable Bombs', False), + bs.BoolSetting('Enable Bottom Credits', True), ] - default_music = ba.MusicType.HOCKEY + default_music = bs.MusicType.HOCKEY @classmethod - def supports_session_type(cls, sessiontype: Type[ba.Session]) -> bool: - return issubclass(sessiontype, ba.DualTeamSession) + def supports_session_type(cls, sessiontype: Type[bs.Session]) -> bool: + return issubclass(sessiontype, bs.DualTeamSession) @classmethod - def get_supported_maps(cls, sessiontype: Type[ba.Session]) -> List[str]: + def get_supported_maps(cls, sessiontype: Type[bs.Session]) -> List[str]: return ['Open Field', 'Closed Arena'] def __init__(self, settings: dict): super().__init__(settings) shared = SharedObjects.get() self._scoreboard = Scoreboard() - self._cheer_sound = ba.getsound('cheer') - self._chant_sound = ba.getsound('crowdChant') - self._foghorn_sound = ba.getsound('foghorn') - self._swipsound = ba.getsound('swip') - self._whistle_sound = ba.getsound('refWhistle') - self.puck_model = ba.getmodel('shield') - self.puck_tex = ba.gettexture('gameCircleIcon') - self._puck_sound = ba.getsound('metalHit') - self.puck_material = ba.Material() + self._cheer_sound = bs.getsound('cheer') + self._chant_sound = bs.getsound('crowdChant') + self._foghorn_sound = bs.getsound('foghorn') + self._swipsound = bs.getsound('swip') + self._whistle_sound = bs.getsound('refWhistle') + self.puck_mesh = bs.getmesh('shield') + self.puck_tex = bs.gettexture('gameCircleIcon') + self._puck_sound = bs.getsound('metalHit') + self.puck_material = bs.Material() self.puck_material.add_actions(actions=(('modify_part_collision', 'friction', 0.5))) self.puck_material.add_actions(conditions=('they_have_material', @@ -233,21 +246,22 @@ class VolleyBallGame(ba.TeamGameActivity[Player, Team]): conditions=('they_have_material', PowerupBoxFactory.get().powerup_material), actions=(('modify_part_collision', 'physical', False), - ('message', 'their_node', 'at_connect', ba.DieMessage()))) - self._score_region_material = ba.Material() + ('message', 'their_node', 'at_connect', bs.DieMessage()))) + self._score_region_material = bs.Material() self._score_region_material.add_actions( conditions=('they_have_material', self.puck_material), actions=(('modify_part_collision', 'collide', True), ('modify_part_collision', 'physical', False), ('call', 'at_connect', self._handle_score))) - - self._wall_material = ba.Material() - self._fake_wall_material = ba.Material() + + + self._wall_material=bs.Material() + self._fake_wall_material=bs.Material() self._wall_material.add_actions( - + actions=( ('modify_part_collision', 'friction', 100000), - )) + )) self._wall_material.add_actions( conditions=('they_have_material', shared.pickup_material), actions=( @@ -256,13 +270,13 @@ class VolleyBallGame(ba.TeamGameActivity[Player, Team]): self._wall_material.add_actions( conditions=(('we_are_younger_than', 100), - 'and', - ('they_have_material', shared.object_material)), + 'and', + ('they_have_material',shared.object_material)), actions=( ('modify_part_collision', 'collide', False), )) self._wall_material.add_actions( - conditions=('they_have_material', shared.footing_material), + conditions=('they_have_material',shared.footing_material), actions=( ('modify_part_collision', 'friction', 9999.5), )) @@ -271,24 +285,25 @@ class VolleyBallGame(ba.TeamGameActivity[Player, Team]): actions=( ('modify_part_collision', 'collide', False), ('modify_part_collision', 'physical', False) - + )) self._fake_wall_material.add_actions( conditions=('they_have_material', shared.player_material), actions=( ('modify_part_collision', 'collide', True), ('modify_part_collision', 'physical', True) - + )) - self.blocks = [] + self.blocks=[] - self._net_wall_material = ba.Material() + + self._net_wall_material=bs.Material() self._net_wall_material.add_actions( conditions=('they_have_material', shared.player_material), actions=( ('modify_part_collision', 'collide', True), ('modify_part_collision', 'physical', True) - + )) self._net_wall_material.add_actions( @@ -306,10 +321,11 @@ class VolleyBallGame(ba.TeamGameActivity[Player, Team]): actions=( ('modify_part_collision', 'collide', True), )) - self.net_blocc = [] + self.net_blocc=[] + self._puck_spawn_pos: Optional[Sequence[float]] = None - self._score_regions: Optional[List[ba.NodeActor]] = None + self._score_regions: Optional[List[bs.NodeActor]] = None self._puck: Optional[Puck] = None self._score_to_win = int(settings['Score to Win']) self._punchie_ = bool(settings['Disable Punch']) @@ -321,8 +337,8 @@ class VolleyBallGame(ba.TeamGameActivity[Player, Team]): self._epic_mode = bool(settings['Epic Mode']) # 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) + self.default_music = (bs.MusicType.EPIC if self._epic_mode else + bs.MusicType.TO_THE_DEATH) def get_instance_description(self) -> Union[str, Sequence]: if self._score_to_win == 1: @@ -339,60 +355,58 @@ class VolleyBallGame(ba.TeamGameActivity[Player, Team]): self.setup_standard_time_limit(self._time_limit) if self._night_mode: - ba.getactivity().globalsnode.tint = (0.5, 0.7, 1) + bs.getactivity().globalsnode.tint = (0.5, 0.7, 1) self._puck_spawn_pos = self.map.get_flag_position(None) self._spawn_puck() # Set up the two score regions. self._score_regions = [] self._score_regions.append( - ba.NodeActor( - ba.newnode('region', + bs.NodeActor( + bs.newnode('region', attrs={ - 'position': (5.7, 0, -0.065), + 'position':(5.7, 0, -0.065), 'scale': (10.7, 0.001, 8), 'type': 'box', 'materials': [self._score_region_material] }))) self._score_regions.append( - ba.NodeActor( - ba.newnode('region', + bs.NodeActor( + bs.newnode('region', attrs={ - 'position': (-5.7, 0, -0.065), + 'position':(-5.7, 0, -0.065), 'scale': (10.7, 0.001, 8), 'type': 'box', 'materials': [self._score_region_material] }))) self._update_scoreboard() - ba.playsound(self._chant_sound) + self._chant_sound.play() if self.credit_text: - t = ba.newnode('text', - attrs={'text': "Created by Freaku\nVolleyBall", # Disable 'Enable Bottom Credits' when making playlist, No need to edit this lovely... - 'scale': 0.7, - 'position': (0, 0), - 'shadow': 0.5, - 'flatness': 1.2, - 'color': (1, 1, 1), - 'h_align': 'center', - 'v_attach': 'bottom'}) + t = bs.newnode('text', + attrs={ 'text':"Created by Freaku\nVolleyBall", ## Disable 'Enable Bottom Credits' when making playlist, No need to edit this lovely... + 'scale':0.7, + 'position':(0,0), + 'shadow':0.5, + 'flatness':1.2, + 'color':(1, 1, 1), + 'h_align':'center', + 'v_attach':'bottom'}) shared = SharedObjects.get() - self.blocks.append(ba.NodeActor(ba.newnode('region', attrs={'position': (0, 2.4, 0), 'scale': ( - 0.8, 6, 20), 'type': 'box', 'materials': (self._fake_wall_material, )}))) - - self.net_blocc.append(ba.NodeActor(ba.newnode('region', attrs={'position': (0, 0, 0), 'scale': ( - 0.6, 2.4, 20), 'type': 'box', 'materials': (self._net_wall_material, )}))) + self.blocks.append(bs.NodeActor(bs.newnode('region',attrs={'position': (0,2.4,0),'scale': (0.8,6,20),'type': 'box','materials': (self._fake_wall_material, )}))) + + self.net_blocc.append(bs.NodeActor(bs.newnode('region',attrs={'position': (0,0,0),'scale': (0.6,2.4,20),'type': 'box','materials': (self._net_wall_material, )}))) def on_team_join(self, team: Team) -> None: self._update_scoreboard() def _handle_puck_player_collide(self) -> None: - collision = ba.getcollision() + collision = bs.getcollision() try: puck = collision.sourcenode.getdelegate(Puck, True) player = collision.opposingnode.getdelegate(PlayerSpaz, True).getplayer( Player, True) - except ba.NotFoundError: + except bs.NotFoundError: return puck.last_players_to_touch[player.team.id] = player @@ -409,7 +423,7 @@ class VolleyBallGame(ba.TeamGameActivity[Player, Team]): if self._puck.scored: return - region = ba.getcollision().sourcenode + region = bs.getcollision().sourcenode index = 0 for index in range(len(self._score_regions)): if region == self._score_regions[index].node: @@ -420,18 +434,21 @@ class VolleyBallGame(ba.TeamGameActivity[Player, Team]): scoring_team = team team.score += 1 - # Change puck Spawn - if team.id == 0: # left side scored - self._puck_spawn_pos = (5, 0.42, 0) - elif team.id == 1: # right side scored - self._puck_spawn_pos = (-5, 0.42, 0) - else: # normally shouldn't occur - self._puck_spawn_pos = (0, 0.42, 0) - # Easy pizzy + + # Change puck Spawn + if team.id == 0: # left side scored + self._puck_spawn_pos= (5, 0.42, 0) + elif team.id == 1: # right side scored + self._puck_spawn_pos= (-5, 0.42, 0) + else: # normally shouldn't occur + self._puck_spawn_pos= (0, 0.42, 0) + # Easy pizzy + + for player in team.players: if player.actor: - player.actor.handlemessage(ba.CelebrateMessage(2.0)) + player.actor.handlemessage(bs.CelebrateMessage(2.0)) # If we've got the player from the scoring team that last # touched us, give them points. @@ -446,28 +463,28 @@ class VolleyBallGame(ba.TeamGameActivity[Player, Team]): if team.score >= self._score_to_win: self.end_game() - ba.playsound(self._foghorn_sound) - ba.playsound(self._cheer_sound) + self._foghorn_sound.play() + self._cheer_sound.play() self._puck.scored = True # Kill the puck (it'll respawn itself shortly). - ba.emitfx(position=ba.getcollision().position, count=int( - 6.0 + 7.0 * 12), scale=3, spread=0.5, chunk_type='spark') - ba.timer(0.7, self._kill_puck) + bs.emitfx(position= bs.getcollision().position, count=int(6.0 + 7.0 * 12), scale=3, spread=0.5, chunk_type='spark') + bs.timer(0.7, self._kill_puck) - ba.cameraflash(duration=7.0) + + bs.cameraflash(duration=7.0) self._update_scoreboard() 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) def on_transition_in(self) -> None: super().on_transition_in() - activity = ba.getactivity() + activity = bs.getactivity() if self._icy_flooor: activity.map.is_hockey = True @@ -477,7 +494,7 @@ class VolleyBallGame(ba.TeamGameActivity[Player, Team]): self._scoreboard.set_team_value(team, team.score, winscore) # overriding the default character spawning.. - def spawn_player(self, player: Player) -> ba.Actor: + def spawn_player(self, player: Player) -> bs.Actor: spaz = self.spawn_player_spaz(player) if self._bombies_: @@ -485,6 +502,7 @@ class VolleyBallGame(ba.TeamGameActivity[Player, Team]): spaz.bomb_count = 0 # Imagine not being able to swipe those colorful buttons ;( + if self._punchie_: spaz.connect_controls_to_player(enable_punch=False) @@ -493,7 +511,7 @@ class VolleyBallGame(ba.TeamGameActivity[Player, Team]): def handlemessage(self, msg: Any) -> Any: # Respawn dead players if they're still in the game. - if isinstance(msg, ba.PlayerDiedMessage): + if isinstance(msg, bs.PlayerDiedMessage): # Augment standard behavior... super().handlemessage(msg) self.respawn_player(msg.getplayer(Player)) @@ -501,44 +519,62 @@ class VolleyBallGame(ba.TeamGameActivity[Player, Team]): # Respawn dead pucks. elif isinstance(msg, PuckDiedMessage): if not self.has_ended(): - ba.timer(2.2, self._spawn_puck) + bs.timer(2.2, self._spawn_puck) else: super().handlemessage(msg) def _flash_puck_spawn(self) -> None: # Effect >>>>>> Flashly - ba.emitfx(position=self._puck_spawn_pos, count=int( - 6.0 + 7.0 * 12), scale=1.7, spread=0.4, chunk_type='spark') + bs.emitfx(position= self._puck_spawn_pos, count=int(6.0 + 7.0 * 12), scale=1.7, spread=0.4, chunk_type='spark') def _spawn_puck(self) -> None: - ba.playsound(self._swipsound) - ba.playsound(self._whistle_sound) + self._swipsound.play() + self._whistle_sound.play() self._flash_puck_spawn() assert self._puck_spawn_pos is not None self._puck = Puck(position=self._puck_spawn_pos) + + + + + + + + + + + + + + + + + + + + + class Pointzz: points, boxes = {}, {} points['spawn1'] = (-8.03866, 0.02275, 0.0) + (0.5, 0.05, 4.0) points['spawn2'] = (8.82311, 0.01092, 0.0) + (0.5, 0.05, 4.0) - boxes['area_of_interest_bounds'] = (0.0, 1.18575, 0.43262) + \ - (0, 0, 0) + (29.81803, 11.57249, 18.89134) + boxes['area_of_interest_bounds'] = (0.0, 1.18575, 0.43262) + (0, 0, 0) + (29.81803, 11.57249, 18.89134) boxes['map_bounds'] = (0.0, 1.185751251, 0.4326226188) + (0.0, 0.0, 0.0) + ( - 42.09506485, 22.81173179, 29.76723155) - + 42.09506485, 22.81173179, 29.76723155) class PointzzforH: points, boxes = {}, {} - boxes['area_of_interest_bounds'] = (0.0, 0.7956858119, 0.0) + \ - (0.0, 0.0, 0.0) + (30.80223883, 0.5961646365, 13.88431707) + boxes['area_of_interest_bounds'] = (0.0, 0.7956858119, 0.0) + (0.0, 0.0, 0.0) + (30.80223883, 0.5961646365, 13.88431707) boxes['map_bounds'] = (0.0, 0.7956858119, -0.4689020853) + (0.0, 0.0, 0.0) + ( - 35.16182389, 12.18696164, 21.52869693) + 35.16182389, 12.18696164, 21.52869693) points['spawn1'] = (-6.835352227, 0.02305323209, 0.0) + (1.0, 1.0, 3.0) points['spawn2'] = (6.857415055, 0.03938567998, 0.0) + (1.0, 1.0, 3.0) -class VolleyBallMap(ba.Map): + +class VolleyBallMap(bs.Map): defs = Pointzz() name = "Open Field" @@ -553,72 +589,72 @@ class VolleyBallMap(ba.Map): @classmethod def on_preload(cls) -> Any: data: Dict[str, Any] = { - 'model': ba.getmodel('footballStadium'), - 'vr_fill_model': ba.getmodel('footballStadiumVRFill'), - 'collide_model': ba.getcollidemodel('footballStadiumCollide'), - 'tex': ba.gettexture('footballStadium') + 'mesh': bs.getmesh('footballStadium'), + 'vr_fill_mesh': bs.getmesh('footballStadiumVRFill'), + 'collision_mesh': bs.getcollisionmesh('footballStadiumCollide'), + 'tex': bs.gettexture('footballStadium') } return data - + def __init__(self): super().__init__() shared = SharedObjects.get() x = -5 - while x < 5: - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (0, 0, x), - 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (0, .25, x), - 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (0, .5, x), - 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (0, .75, x), - 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (0, 1, x), - 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + while x<5: + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(0,0,x), + 'color':(1,1,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(0,.25,x), + 'color':(1,1,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(0,.5,x), + 'color':(1,1,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(0,.75,x), + 'color':(1,1,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(0,1,x), + 'color':(1,1,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) x = x + 0.5 y = -1 - while y > -11: - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (y, 0.01, 4), - 'color': (0, 0, 1), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (y, 0.01, -4), - 'color': (0, 0, 1), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (-y, 0.01, 4), - 'color': (1, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (-y, 0.01, -4), - 'color': (1, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - y -= 1 + while y>-11: + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(y,0.01,4), + 'color':(0,0,1),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(y,0.01,-4), + 'color':(0,0,1),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(-y,0.01,4), + 'color':(1,0,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(-y,0.01,-4), + 'color':(1,0,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + y-=1 z = 0 - while z < 5: - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (11, 0.01, z), - 'color': (1, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (11, 0.01, -z), - 'color': (1, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (-11, 0.01, z), - 'color': (0, 0, 1), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (-11, 0.01, -z), - 'color': (0, 0, 1), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - z += 1 + while z<5: + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(11,0.01,z), + 'color':(1,0,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(11,0.01,-z), + 'color':(1,0,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(-11,0.01,z), + 'color':(0,0,1),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(-11,0.01,-z), + 'color':(0,0,1),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + z+=1 - self.node = ba.newnode( + self.node = bs.newnode( 'terrain', delegate=self, attrs={ - 'model': self.preloaddata['model'], - 'collide_model': self.preloaddata['collide_model'], + 'mesh': self.preloaddata['mesh'], + 'collision_mesh': self.preloaddata['collision_mesh'], 'color_texture': self.preloaddata['tex'], 'materials': [shared.footing_material] }) - ba.newnode('terrain', + bs.newnode('terrain', attrs={ - 'model': self.preloaddata['vr_fill_model'], + 'mesh': self.preloaddata['vr_fill_mesh'], 'lighting': False, 'vr_only': True, 'background': True, 'color_texture': self.preloaddata['tex'] }) - gnode = ba.getactivity().globalsnode + gnode = bs.getactivity().globalsnode gnode.tint = (1.3, 1.2, 1.0) gnode.ambient_color = (1.3, 1.2, 1.0) gnode.vignette_outer = (0.57, 0.57, 0.57) @@ -627,7 +663,8 @@ class VolleyBallMap(ba.Map): gnode.vr_near_clip = 0.5 -class VolleyBallMapH(ba.Map): + +class VolleyBallMapH(bs.Map): defs = PointzzforH() name = 'Closed Arena' @@ -642,13 +679,13 @@ class VolleyBallMapH(ba.Map): @classmethod def on_preload(cls) -> Any: data: Dict[str, Any] = { - 'models': (ba.getmodel('hockeyStadiumOuter'), - ba.getmodel('hockeyStadiumInner')), - 'vr_fill_model': ba.getmodel('footballStadiumVRFill'), - 'collide_model': ba.getcollidemodel('hockeyStadiumCollide'), - 'tex': ba.gettexture('hockeyStadium'), + 'meshs': (bs.getmesh('hockeyStadiumOuter'), + bs.getmesh('hockeyStadiumInner')), + 'vr_fill_mesh': bs.getmesh('footballStadiumVRFill'), + 'collision_mesh': bs.getcollisionmesh('hockeyStadiumCollide'), + 'tex': bs.gettexture('hockeyStadium'), } - mat = ba.Material() + mat = bs.Material() mat.add_actions(actions=('modify_part_collision', 'friction', 0.01)) data['ice_material'] = mat return data @@ -657,84 +694,83 @@ class VolleyBallMapH(ba.Map): super().__init__() shared = SharedObjects.get() x = -5 - while x < 5: - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (0, 0, x), - 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (0, .25, x), - 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (0, .5, x), - 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (0, .75, x), - 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (0, 1, x), - 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + while x<5: + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(0,0,x), + 'color':(1,1,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(0,.25,x), + 'color':(1,1,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(0,.5,x), + 'color':(1,1,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(0,.75,x), + 'color':(1,1,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(0,1,x), + 'color':(1,1,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) x = x + 0.5 y = -1 - while y > -11: - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (y, 0.01, 4), - 'color': (0, 0, 1), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (y, 0.01, -4), - 'color': (0, 0, 1), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (-y, 0.01, 4), - 'color': (1, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (-y, 0.01, -4), - 'color': (1, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - y -= 1 + while y>-11: + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(y,0.01,4), + 'color':(0,0,1),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(y,0.01,-4), + 'color':(0,0,1),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(-y,0.01,4), + 'color':(1,0,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(-y,0.01,-4), + 'color':(1,0,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + y-=1 z = 0 - while z < 5: - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (11, 0.01, z), - 'color': (1, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (11, 0.01, -z), - 'color': (1, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (-11, 0.01, z), - 'color': (0, 0, 1), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - self.zone = ba.newnode('locator', attrs={'shape': 'circle', 'position': (-11, 0.01, -z), - 'color': (0, 0, 1), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) - z += 1 + while z<5: + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(11,0.01,z), + 'color':(1,0,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(11,0.01,-z), + 'color':(1,0,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(-11,0.01,z), + 'color':(0,0,1),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(-11,0.01,-z), + 'color':(0,0,1),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + z+=1 - self.node = ba.newnode('terrain', + self.node = bs.newnode('terrain', delegate=self, attrs={ - 'model': + 'mesh': None, - 'collide_model': - # we dont want Goalposts... - ba.getcollidemodel('footballStadiumCollide'), + 'collision_mesh': + bs.getcollisionmesh('footballStadiumCollide'), # we dont want Goalposts... 'color_texture': self.preloaddata['tex'], 'materials': [ shared.footing_material] }) - ba.newnode('terrain', + bs.newnode('terrain', attrs={ - 'model': self.preloaddata['vr_fill_model'], + 'mesh': self.preloaddata['vr_fill_mesh'], 'vr_only': True, 'lighting': False, 'background': True, }) mats = [shared.footing_material] - self.floor = ba.newnode('terrain', + self.floor = bs.newnode('terrain', attrs={ - 'model': self.preloaddata['models'][1], + 'mesh': self.preloaddata['meshs'][1], 'color_texture': self.preloaddata['tex'], 'opacity': 0.92, 'opacity_in_low_or_medium_quality': 1.0, 'materials': mats, - 'color': (0.4, 0.9, 0) + 'color': (0.4,0.9,0) }) - self.background = ba.newnode( + self.background = bs.newnode( 'terrain', attrs={ - 'model': ba.getmodel('natureBackground'), + 'mesh': bs.getmesh('natureBackground'), 'lighting': False, 'background': True, - 'color': (0.5, 0.30, 0.4) + 'color': (0.5,0.30,0.4) }) - gnode = ba.getactivity().globalsnode + gnode = bs.getactivity().globalsnode gnode.floor_reflection = True gnode.debris_friction = 0.3 gnode.debris_kill_height = -0.3 @@ -747,5 +783,19 @@ class VolleyBallMapH(ba.Map): #self.is_hockey = True -ba._map.register_map(VolleyBallMap) -ba._map.register_map(VolleyBallMapH) + + +bs._map.register_map(VolleyBallMap) +bs._map.register_map(VolleyBallMapH) + + +# ba_meta export plugin +class byFreaku(babase.Plugin): + def __init__(self): + # Reason of plugin: + # To register maps. + # + # Then why not include function here? + # On server upon first launch, plugins are not activated, + # (same can be case for user if disabled auto-enable plugins) + pass \ No newline at end of file From d6dc6c246a781d416b66d5880bfa49add23b8149 Mon Sep 17 00:00:00 2001 From: ! Freaku <92618708+Freaku17@users.noreply.github.com> Date: Fri, 28 Jul 2023 17:03:36 +0530 Subject: [PATCH 55/60] Update my utilities for 1.7.20+ (API 8) --- plugins/utilities/floater.py | 134 ++++++++++++++-------------- plugins/utilities/icons_keyboard.py | 80 +++++++++-------- plugins/utilities/unlock_TowerD.py | 13 +-- 3 files changed, 118 insertions(+), 109 deletions(-) diff --git a/plugins/utilities/floater.py b/plugins/utilities/floater.py index d57e593..c05b3a5 100644 --- a/plugins/utilities/floater.py +++ b/plugins/utilities/floater.py @@ -1,34 +1,35 @@ -# Ported by: Freaku / @[Just] Freak#4999 +# Ported by your friend: Freaku -# Join BCS: +#Join BCS: # https://discord.gg/ucyaesh -# My GitHub: +#My GitHub: # https://github.com/Freaku17/BombSquad-Mods-byFreaku -# ba_meta require api 7 + +# ba_meta require api 8 from __future__ import annotations from typing import TYPE_CHECKING -import _ba -import ba -import random -import math -from bastd.gameutils import SharedObjects -from bastd.actor.bomb import Bomb -from bastd.actor.popuptext import PopupText +import _babase, babase, random, math +import bauiv1 as bui +import bascenev1 as bs +from bascenev1lib.gameutils import SharedObjects +from bascenev1lib.actor.bomb import Bomb +from bascenev1lib.actor.popuptext import PopupText +from bauiv1lib.party import PartyWindow if TYPE_CHECKING: from typing import Optional -class Floater(ba.Actor): +class Floater(bs.Actor): def __init__(self, bounds): super().__init__() shared = SharedObjects.get() self.controlled = False self.source_player = None - self.floaterMaterial = ba.Material() + self.floaterMaterial = bs.Material() self.floaterMaterial.add_actions( conditions=('they_have_material', shared.player_material), @@ -48,21 +49,21 @@ class Floater(ba.Actor): self.py = "random.uniform(self.pos[1],self.pos[4])" self.pz = "random.uniform(self.pos[2],self.pos[5])" - self.node = ba.newnode( + self.node = bs.newnode( 'prop', delegate=self, owner=None, attrs={ 'position': (eval(self.px), eval(self.py), eval(self.pz)), - 'model': - ba.getmodel('landMine'), - 'light_model': - ba.getmodel('landMine'), + 'mesh': + bs.getmesh('landMine'), + 'light_mesh': + bs.getmesh('landMine'), 'body': 'landMine', 'body_scale': 3, - 'model_scale': + 'mesh_scale': 3.1, 'shadow_size': 0.25, @@ -71,21 +72,21 @@ class Floater(ba.Actor): 'gravity_scale': 0.0, 'color_texture': - ba.gettexture('achievementFlawlessVictory'), + bs.gettexture('achievementFlawlessVictory'), 'reflection': 'soft', 'reflection_scale': [0.25], 'materials': [shared.footing_material, self.floaterMaterial] }) - self.node2 = ba.newnode( + self.node2 = bs.newnode( 'prop', owner=self.node, attrs={ 'position': (0, 0, 0), 'body': 'sphere', - 'model': + 'mesh': None, 'color_texture': None, @@ -96,7 +97,7 @@ class Floater(ba.Actor): 'density': 999999, 'reflection_scale': [1.0], - 'model_scale': + 'mesh_scale': 1.0, 'gravity_scale': 0, @@ -109,8 +110,7 @@ class Floater(ba.Actor): }) self.node.connectattr('position', self.node2, 'position') - def pop(self): PopupText(text="Ported by \ue048Freaku", scale=1.3, position=( - self.node.position[0], self.node.position[1]-1, self.node.position[2]), color=(0, 1, 1)).autoretain() # Edit = YouNoob... + def pop(self): PopupText(text="Ported by \ue048Freaku", scale=1.3, position=(self.node.position[0],self.node.position[1]-1,self.node.position[2]), color=(0,1,1)).autoretain() def checkCanControl(self): if not self.node.exists(): @@ -172,7 +172,7 @@ class Floater(ba.Actor): if self.source_player is None: return if self.source_player.is_alive(): - ba.timer(1, self.checkPlayerDie) + bs.timer(1, self.checkPlayerDie) return else: self.dis() @@ -186,8 +186,7 @@ class Floater(ba.Actor): np = self.node.position except: np = (0, 0, 0) - self.b = Bomb(bomb_type=random.choice(['normal', 'ice', 'sticky', 'impact', 'land_mine', 'tnt']), - source_player=self.source_player, position=(np[0], np[1] - 1, np[2]), velocity=(0, -1, 0)).autoretain() + self.b = Bomb(bomb_type=random.choice(['normal', 'ice', 'sticky', 'impact', 'land_mine', 'tnt']), source_player=self.source_player, position=(np[0], np[1] - 1, np[2]), velocity=(0, -1, 0)).autoretain() if self.b.bomb_type in ['impact', 'land_mine']: self.b.arm() @@ -199,36 +198,36 @@ class Floater(ba.Actor): pn = self.node.position dist = self.distance(pn[0], pn[1], pn[2], px, py, pz) self.node.velocity = ((px - pn[0]) / dist, (py - pn[1]) / dist, (pz - pn[2]) / dist) - ba.timer(dist-1, ba.WeakCall(self.move), suppress_format_warning=True) + bs.timer(dist-1, bs.WeakCall(self.move)) #suppress_format_warning=True) def handlemessage(self, msg): - if isinstance(msg, ba.DieMessage): + if isinstance(msg, bs.DieMessage): self.node.delete() self.node2.delete() self.controlled = False - elif isinstance(msg, ba.OutOfBoundsMessage): - self.handlemessage(ba.DieMessage()) + elif isinstance(msg, bs.OutOfBoundsMessage): + self.handlemessage(bs.DieMessage()) else: super().handlemessage(msg) + + + + def assignFloInputs(clientID: int): - with ba.Context(_ba.get_foreground_host_activity()): - activity = ba.getactivity() + activity = bs.get_foreground_host_activity() + with activity.context: if not hasattr(activity, 'flo') or not activity.flo.node.exists(): - try: - activity.flo = Floater(activity.map.get_def_bound_box('map_bounds')) - except: - return # Perhaps using in main-menu/score-screen + try: activity.flo = Floater(activity.map.get_def_bound_box('map_bounds')) + except: return #Perhaps using in main-menu/score-screen floater = activity.flo if floater.controlled: - ba.screenmessage('Floater is already being controlled', - color=(1, 0, 0), transient=True, clients=[clientID]) + bs.broadcastmessage('Floater is already being controlled', color=(1, 0, 0), transient=True, clients=[clientID]) return - ba.screenmessage('You Gained Control Over The Floater!\n Press Bomb to Throw Bombs and Punch to leave!', clients=[ - clientID], transient=True, color=(0, 1, 1)) + bs.broadcastmessage('You Gained Control Over The Floater!\n Press Bomb to Throw Bombs and Punch to leave!', clients=[clientID], transient=True, color=(0, 1, 1)) - for i in _ba.get_foreground_host_activity().players: + for i in activity.players: if i.sessionplayer.inputdevice.client_id == clientID: def dis(i, floater): i.actor.node.invincible = False @@ -238,41 +237,42 @@ def assignFloInputs(clientID: int): ps = i.actor.node.position i.actor.node.invincible = True floater.node.position = (ps[0], ps[1] + 1.0, ps[2]) - ba.timer(1, floater.pop) - i.actor.node.hold_node = ba.Node(None) + bs.timer(1, floater.pop) + i.actor.node.hold_node = bs.Node(None) i.actor.node.hold_node = floater.node2 i.actor.connect_controls_to_player() i.actor.disconnect_controls_from_player() i.resetinput() floater.source_player = i floater.con() - i.assigninput(ba.InputType.PICK_UP_PRESS, floater.up) - i.assigninput(ba.InputType.PICK_UP_RELEASE, floater.upR) - i.assigninput(ba.InputType.JUMP_PRESS, floater.down) - i.assigninput(ba.InputType.BOMB_PRESS, floater.drop) - i.assigninput(ba.InputType.PUNCH_PRESS, ba.Call(dis, i, floater)) - i.assigninput(ba.InputType.UP_DOWN, floater.updown) - i.assigninput(ba.InputType.LEFT_RIGHT, floater.leftright) + i.assigninput(babase.InputType.PICK_UP_PRESS, floater.up) + i.assigninput(babase.InputType.PICK_UP_RELEASE, floater.upR) + i.assigninput(babase.InputType.JUMP_PRESS, floater.down) + i.assigninput(babase.InputType.BOMB_PRESS, floater.drop) + i.assigninput(babase.InputType.PUNCH_PRESS, babase.Call(dis, i, floater)) + i.assigninput(babase.InputType.UP_DOWN, floater.updown) + i.assigninput(babase.InputType.LEFT_RIGHT, floater.leftright) -old_fcm = _ba.chatmessage +# Display chat icon, but if user open/close gather it may disappear +bui.set_party_icon_always_visible(True) -def new_chat_message(msg: Union[str, ba.Lstr], clients: Sequence[int] = None, sender_override: str = None): - old_fcm(msg, clients, sender_override) - if msg == '/floater': - try: - assignFloInputs(-1) - except: - pass +old_piv = bui.set_party_icon_always_visible +def new_piv(*args, **kwargs): + # Do not let chat icon go away + old_piv(True) +bui.set_party_icon_always_visible = new_piv -_ba.chatmessage = new_chat_message -if not _ba.is_party_icon_visible(): - _ba.set_party_icon_always_visible(True) +old_fcm = bs.chatmessage +def new_chat_message(*args, **kwargs): + old_fcm(*args, **kwargs) + if args[0] == '/floater': + try: assignFloInputs(-1) + except: pass +bs.chatmessage = new_chat_message # ba_meta export plugin - - -class byFreaku(ba.Plugin): - def __init__(self): pass +class byFreaku(babase.Plugin): + def __init__(self): pass \ No newline at end of file diff --git a/plugins/utilities/icons_keyboard.py b/plugins/utilities/icons_keyboard.py index 3033bd4..bbb48ab 100644 --- a/plugins/utilities/icons_keyboard.py +++ b/plugins/utilities/icons_keyboard.py @@ -1,4 +1,4 @@ -# Made by: Freaku / @[Just] Freak#4999 +# Made by your friend: Freaku # • Icon Keyboard • # Make your chats look even more cooler! @@ -6,51 +6,59 @@ # Double tap the space to change between keyboards... -# ba_meta require api 7 + + +# ba_meta require api 8 from __future__ import annotations from typing import TYPE_CHECKING -import ba -from _ba import charstr as uwu +import babase +import bascenev1 as bs +from babase import charstr as uwu if TYPE_CHECKING: - from typing import Any, Optional, Dict, List, Tuple, Type, Iterable + from typing import Any, Optional, Dict, List, Tuple,Type, Iterable + + + + + # ba_meta export keyboard -class IconKeyboard_byFreaku(ba.Keyboard): +class IconKeyboard_byFreaku(babase.Keyboard): """Keyboard go brrrrrrr""" name = 'Icons by \ue048Freaku' - chars = [(uwu(ba.SpecialChar.TICKET), - uwu(ba.SpecialChar.CROWN), - uwu(ba.SpecialChar.DRAGON), - uwu(ba.SpecialChar.SKULL), - uwu(ba.SpecialChar.HEART), - uwu(ba.SpecialChar.FEDORA), - uwu(ba.SpecialChar.HAL), - uwu(ba.SpecialChar.YIN_YANG), - uwu(ba.SpecialChar.EYE_BALL), - uwu(ba.SpecialChar.HELMET), - uwu(ba.SpecialChar.OUYA_BUTTON_U)), - (uwu(ba.SpecialChar.MUSHROOM), - uwu(ba.SpecialChar.NINJA_STAR), - uwu(ba.SpecialChar.VIKING_HELMET), - uwu(ba.SpecialChar.MOON), - uwu(ba.SpecialChar.SPIDER), - uwu(ba.SpecialChar.FIREBALL), - uwu(ba.SpecialChar.MIKIROG), - uwu(ba.SpecialChar.OUYA_BUTTON_O), - uwu(ba.SpecialChar.LOCAL_ACCOUNT), - uwu(ba.SpecialChar.LOGO)), - (uwu(ba.SpecialChar.TICKET), - uwu(ba.SpecialChar.FLAG_INDIA), - uwu(ba.SpecialChar.OCULUS_LOGO), - uwu(ba.SpecialChar.STEAM_LOGO), - uwu(ba.SpecialChar.NVIDIA_LOGO), - uwu(ba.SpecialChar.GAME_CENTER_LOGO), - uwu(ba.SpecialChar.GOOGLE_PLAY_GAMES_LOGO), - uwu(ba.SpecialChar.ALIBABA_LOGO))] + chars = [(uwu(babase.SpecialChar.TICKET), + uwu(babase.SpecialChar.CROWN), + uwu(babase.SpecialChar.DRAGON), + uwu(babase.SpecialChar.SKULL), + uwu(babase.SpecialChar.HEART), + uwu(babase.SpecialChar.FEDORA), + uwu(babase.SpecialChar.HAL), + uwu(babase.SpecialChar.YIN_YANG), + uwu(babase.SpecialChar.EYE_BALL), + uwu(babase.SpecialChar.HELMET), + uwu(babase.SpecialChar.OUYA_BUTTON_U)), + (uwu(babase.SpecialChar.MUSHROOM), + uwu(babase.SpecialChar.NINJA_STAR), + uwu(babase.SpecialChar.VIKING_HELMET), + uwu(babase.SpecialChar.MOON), + uwu(babase.SpecialChar.SPIDER), + uwu(babase.SpecialChar.FIREBALL), + uwu(babase.SpecialChar.MIKIROG), + uwu(babase.SpecialChar.OUYA_BUTTON_O), + uwu(babase.SpecialChar.LOCAL_ACCOUNT), + uwu(babase.SpecialChar.LOGO)), + (uwu(babase.SpecialChar.TICKET), + uwu(babase.SpecialChar.FLAG_INDIA), + uwu(babase.SpecialChar.OCULUS_LOGO), + uwu(babase.SpecialChar.STEAM_LOGO), + uwu(babase.SpecialChar.NVIDIA_LOGO), + uwu(babase.SpecialChar.GAME_CENTER_LOGO), + uwu(babase.SpecialChar.GOOGLE_PLAY_GAMES_LOGO), + uwu(babase.SpecialChar.EXPLODINARY_LOGO))] nums = [] - pages: Dict[str, Tuple[str, ...]] = {} + pages: Dict[str, Tuple[str, ...]] = {} \ No newline at end of file diff --git a/plugins/utilities/unlock_TowerD.py b/plugins/utilities/unlock_TowerD.py index e6d29b4..6a219f1 100644 --- a/plugins/utilities/unlock_TowerD.py +++ b/plugins/utilities/unlock_TowerD.py @@ -1,8 +1,9 @@ -# By Freaku / @[Just] Freak#4999 +# Made by your friend: Freaku -import ba -from bastd.maps import TowerD +import babase +import bascenev1 as bs +from bascenev1lib.maps import TowerD @classmethod @@ -11,8 +12,8 @@ def new_play_types(cls): return ['melee', 'keep_away', 'team_flag', 'king_of_the_hill'] -# ba_meta require api 7 +# ba_meta require api 8 # ba_meta export plugin -class byFreaku(ba.Plugin): +class byFreaku(babase.Plugin): def on_app_running(self): - TowerD.get_play_types = new_play_types + TowerD.get_play_types = new_play_types \ No newline at end of file From 3f65846527694f6f9b3508cd12ceb4648e6d5fe8 Mon Sep 17 00:00:00 2001 From: ! Freaku <92618708+Freaku17@users.noreply.github.com> Date: Fri, 28 Jul 2023 17:04:23 +0530 Subject: [PATCH 56/60] Update JSON files --- plugins/minigames.json | 56 ++++++++++++++++++++++++++---------------- plugins/utilities.json | 12 ++++----- 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index 66a58ee..c7e2d6d 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -28,6 +28,32 @@ } } }, + "icy_emits": { + "description": "Survice from icy bombs emitting through cold platform. Playable in teams/ffa/co-op", + "external_url": "", + "authors": [ + { + "name": "Freaku", + "email": "" + } + ], + "versions": { + "1.0.0": null + } + }, + "frozen_one": { + "description": "Survive until the timer runs out", + "external_url": "", + "authors": [ + { + "name": "Freaku", + "email": "" + } + ], + "versions": { + "1.0.0": null + } + }, "simon_says": { "description": "You better do what Simon says", "external_url": "", @@ -198,11 +224,11 @@ "authors": [ { "name": "Freaku", - "email": "", - "discord": "[Just] Freak#4999" + "email": "" } ], "versions": { + "2.0.0": null, "1.1.0": { "api_version": 7, "commit_sha": "0bc9522", @@ -217,11 +243,11 @@ "authors": [ { "name": "Freaku", - "email": "", - "discord": "[Just] Freak#4999" + "email": "" } ], "versions": { + "2.0.0": null, "1.0.0": { "api_version": 7, "commit_sha": "858030b", @@ -236,11 +262,11 @@ "authors": [ { "name": "Freaku", - "email": "", - "discord": "[Just] Freak#4999" + "email": "" } ], "versions": { + "2.0.0": null, "1.0.0": { "api_version": 7, "commit_sha": "858030b", @@ -429,22 +455,11 @@ }, { "name": "Freaku", - "email": "", - "discord": "[Just] Freak#4999" - }, - { - "name": "LoupGarou", - "email": "LoupGarou5418@outlook.com", - "discord": "ʟօʊքɢǟʀօʊ#3063" + "email": "" } ], "versions": { - "2.0.0": { - "api_version": 8, - "commit_sha": "e7a5df9", - "released_on": "26-07-2023", - "md5sum": "641732ef5c8c97cd5482b8cd56126310" - }, + "2.0.0": null, "1.1.0": { "api_version": 7, "commit_sha": "2e2540a", @@ -653,8 +668,7 @@ "authors": [ { "name": "Freaku", - "email": "", - "discord": "[Just] Freak#4999" + "email": "" } ], "versions": { diff --git a/plugins/utilities.json b/plugins/utilities.json index ceb32a8..20d0f71 100644 --- a/plugins/utilities.json +++ b/plugins/utilities.json @@ -292,11 +292,11 @@ "authors": [ { "name": "Freaku", - "email": "", - "discord": "[Just] Freak#4999" + "email": "" } ], "versions": { + "2.0.0": null, "1.0.0": { "api_version": 7, "commit_sha": "6beb8ddf", @@ -311,11 +311,11 @@ "authors": [ { "name": "Freaku", - "email": "", - "discord": "[Just] Freak#4999" + "email": "" } ], "versions": { + "2.0.0": null, "1.1.0": { "api_version": 7, "commit_sha": "383f774", @@ -504,11 +504,11 @@ "authors": [ { "name": "Freaku", - "email": "", - "discord": "[Just] Freak#4999" + "email": "" } ], "versions": { + "2.0.0": null, "1.0.0": { "api_version": 7, "commit_sha": "b581d90", From 7dcf3c711e859dbe7ada70685e7bf82deb9ab9d7 Mon Sep 17 00:00:00 2001 From: Freaku17 Date: Fri, 28 Jul 2023 11:37:09 +0000 Subject: [PATCH 57/60] [ci] auto-format --- plugins/minigames/arms_race.py | 26 +- plugins/minigames/frozen_one.py | 2 +- plugins/minigames/icy_emits.py | 24 +- plugins/minigames/memory_game.py | 507 ++++++++++++++-------------- plugins/minigames/musical_flags.py | 156 +++++---- plugins/minigames/volleyball.py | 281 +++++++-------- plugins/utilities/floater.py | 52 ++- plugins/utilities/icons_keyboard.py | 67 ++-- plugins/utilities/unlock_TowerD.py | 2 +- 9 files changed, 553 insertions(+), 564 deletions(-) diff --git a/plugins/minigames/arms_race.py b/plugins/minigames/arms_race.py index 7710c2a..475811a 100644 --- a/plugins/minigames/arms_race.py +++ b/plugins/minigames/arms_race.py @@ -1,10 +1,9 @@ # Ported by your friend: Freaku -#Join BCS: +# Join BCS: # https://discord.gg/ucyaesh - # ba_meta require api 8 from __future__ import annotations @@ -19,7 +18,6 @@ if TYPE_CHECKING: from typing import Any, Type, List, Dict, Tuple, Union, Sequence, Optional - class State: def __init__(self, bomb=None, grab=False, punch=False, curse=False, required=False, final=False, name=''): self.bomb = bomb @@ -36,8 +34,8 @@ class State: def apply(self, spaz): spaz.disconnect_controls_from_player() spaz.connect_controls_to_player(enable_punch=self.punch, - enable_bomb=self.bomb, - enable_pickup=self.grab) + enable_bomb=self.bomb, + enable_pickup=self.grab) if self.curse: spaz.curse_time = -1 spaz.curse() @@ -49,16 +47,18 @@ class State: return (self.name) -states = [ State(bomb='normal', name='Basic Bombs'), - State(bomb='ice', name='Frozen Bombs'), - State(bomb='sticky', name='Sticky Bombs'), - State(bomb='impact', name='Impact Bombs'), - State(grab=True, name='Grabbing only'), - State(punch=True, name='Punching only'), - State(curse=True, name='Cursed', final=True) ] +states = [State(bomb='normal', name='Basic Bombs'), + State(bomb='ice', name='Frozen Bombs'), + State(bomb='sticky', name='Sticky Bombs'), + State(bomb='impact', name='Impact Bombs'), + State(grab=True, name='Grabbing only'), + State(punch=True, name='Punching only'), + State(curse=True, name='Cursed', final=True)] + class Player(bs.Player['Team']): """Our player type for this game.""" + def __init__(self): self.state = None @@ -192,4 +192,4 @@ class ArmsRaceGame(bs.TeamGameActivity[Player, Team]): results = bs.GameResults() for team in self.teams: results.set_team_score(team, team.score) - self.end(results=results) \ No newline at end of file + self.end(results=results) diff --git a/plugins/minigames/frozen_one.py b/plugins/minigames/frozen_one.py index 7bfbe65..9b0c9ba 100644 --- a/plugins/minigames/frozen_one.py +++ b/plugins/minigames/frozen_one.py @@ -15,4 +15,4 @@ class FrozenOneGame(ChosenOneGame): super()._set_chosen_one_player(player) if hasattr(player, 'actor'): player.actor.frozen = True - player.actor.node.frozen = 1 \ No newline at end of file + player.actor.node.frozen = 1 diff --git a/plugins/minigames/icy_emits.py b/plugins/minigames/icy_emits.py index 50a883c..f5467e3 100644 --- a/plugins/minigames/icy_emits.py +++ b/plugins/minigames/icy_emits.py @@ -2,7 +2,8 @@ import babase -import bascenev1 as bs, random +import bascenev1 as bs +import random from bascenev1lib.actor.bomb import Bomb from bascenev1lib.game.meteorshower import Player, MeteorShowerGame @@ -14,7 +15,7 @@ class IcyEmitsGame(MeteorShowerGame): @classmethod def get_supported_maps(cls, sessiontype): - return ['Lake Frigid','Hockey Stadium'] + return ['Lake Frigid', 'Hockey Stadium'] def _drop_bomb_cluster(self) -> None: delay = 0.0 @@ -24,23 +25,24 @@ class IcyEmitsGame(MeteorShowerGame): pos = (-7.3 + 15.3 * random.random(), 5.3, -5.5 + 2.1 * random.random()) dropdir = (-1.0 if pos[0] > 0 else 1.0) - vel = (0,10,0) + vel = (0, 10, 0) bs.timer(delay, babase.Call(self._drop_bomb, pos, vel)) delay += 0.1 self._set_meteor_timer() def _drop_bomb(self, position, velocity): - random_xpositions = [-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10] - random_zpositions = [-5,-4.5,-4,-3.5,-3,-2.5,-2,-1.5,-1,-0.5,0,0.5,1,1.5,2,2.5,3,3.5,4,4.5,5] - bomb_position = (random.choice(random_xpositions), 0.2,random.choice(random_zpositions)) - Bomb(position=bomb_position, velocity=velocity, bomb_type = 'ice').autoretain() - - + random_xpositions = [-10, -9, -8, -7, -6, -5, - + 4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + random_zpositions = [-5, -4.5, -4, -3.5, -3, -2.5, -2, - + 1.5, -1, -0.5, 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5] + bomb_position = (random.choice(random_xpositions), 0.2, random.choice(random_zpositions)) + Bomb(position=bomb_position, velocity=velocity, bomb_type='ice').autoretain() # ba_meta export plugin class byFreaku(babase.Plugin): def __init__(self): ## Campaign support ## - randomPic = ['lakeFrigidPreview','hockeyStadiumPreview'] - babase.app.classic.add_coop_practice_level(bs.Level(name='Icy Emits', displayname='${GAME}', gametype=IcyEmitsGame, settings={}, preview_texture_name=random.choice(randomPic))) \ No newline at end of file + randomPic = ['lakeFrigidPreview', 'hockeyStadiumPreview'] + babase.app.classic.add_coop_practice_level(bs.Level( + name='Icy Emits', displayname='${GAME}', gametype=IcyEmitsGame, settings={}, preview_texture_name=random.choice(randomPic))) diff --git a/plugins/minigames/memory_game.py b/plugins/minigames/memory_game.py index a433eec..5ab2502 100644 --- a/plugins/minigames/memory_game.py +++ b/plugins/minigames/memory_game.py @@ -12,32 +12,29 @@ from __future__ import annotations # (& some improvements) - - - - # incase someone is wondering how is map floating. Check out # def spawnAllMap(self) - # ba_meta require api 8 from typing import TYPE_CHECKING, overload -import _babase, babase, random +import _babase +import babase +import random import bascenev1 as bs from bascenev1lib.gameutils import SharedObjects if TYPE_CHECKING: from typing import Any, Sequence, Optional, List, Dict, Type, Union, Any, Literal - - class OnTimer(bs.Actor): """Timer which counts but doesn't show on-screen""" + def __init__(self) -> None: super().__init__() self._starttime_ms: int | None = None - self.node = bs.newnode('text', attrs={ 'v_attach': 'top', 'h_attach': 'center', 'h_align': 'center', 'color': (1, 1, 0.5, 1), 'flatness': 0.5, 'shadow': 0.5, 'position': (0, -70), 'scale': 0, 'text': ''}) + self.node = bs.newnode('text', attrs={'v_attach': 'top', 'h_attach': 'center', 'h_align': 'center', 'color': ( + 1, 1, 0.5, 1), 'flatness': 0.5, 'shadow': 0.5, 'position': (0, -70), 'scale': 0, 'text': ''}) self.inputnode = bs.newnode( 'timedisplay', attrs={'timemin': 0, 'showsubseconds': True} ) @@ -101,8 +98,6 @@ class OnTimer(bs.Actor): self.node.delete() - - class Player(bs.Player['Team']): """Our player type for this game.""" @@ -120,7 +115,8 @@ class MGgame(bs.TeamGameActivity[Player, Team]): name = 'Memory Game' description = 'Memories tiles and survive till the end!' - available_settings = [bs.BoolSetting('Epic Mode', default=False), bs.BoolSetting('Enable Bottom Credits', True)] + available_settings = [bs.BoolSetting( + 'Epic Mode', default=False), bs.BoolSetting('Enable Bottom Credits', True)] scoreconfig = bs.ScoreConfig(label='Survived', scoretype=bs.ScoreType.MILLISECONDS, version='B') # Print messages when players die (since its meaningful in this game). @@ -152,9 +148,9 @@ class MGgame(bs.TeamGameActivity[Player, Team]): if self._epic_mode: self.slow_motion = True shared = SharedObjects.get() - self._collide_with_player=bs.Material() + self._collide_with_player = bs.Material() self._collide_with_player.add_actions(actions=(('modify_part_collision', 'collide', True))) - self.dont_collide=bs.Material() + self.dont_collide = bs.Material() self.dont_collide.add_actions(actions=(('modify_part_collision', 'collide', False))) self._levelStage = 0 @@ -177,7 +173,7 @@ class MGgame(bs.TeamGameActivity[Player, Team]): self._mapFGSpaz = bs.gettexture('neoSpazIcon') self._mapFGZoe = bs.gettexture('zoeIcon') self._mapFGSnake = bs.gettexture('ninjaIcon') - self._mapFGKronk= bs.gettexture('kronkIcon') + self._mapFGKronk = bs.gettexture('kronkIcon') self._mapFGMel = bs.gettexture('melIcon') self._mapFGJack = bs.gettexture('jackIcon') self._mapFGSanta = bs.gettexture('santaIcon') @@ -195,59 +191,58 @@ class MGgame(bs.TeamGameActivity[Player, Team]): self._circleTex = bs.gettexture('circleShadow') self._image = bs.newnode('image', - attrs={'texture': self._imageTextDefault, - 'position':(0,-100), - 'scale':(100,100), - 'opacity': 0.0, - 'attach':'topCenter'}) + attrs={'texture': self._imageTextDefault, + 'position': (0, -100), + 'scale': (100, 100), + 'opacity': 0.0, + 'attach': 'topCenter'}) self._textCounter = bs.newnode('text', - attrs={'text': '10', - 'position': (0, -100), - 'scale': 2.3, - 'shadow': 1.0, - 'flatness': 1.0, - 'opacity': 0.0, - 'v_attach': 'top', - 'h_attach': 'center', - 'h_align': 'center', - 'v_align': 'center'}) + attrs={'text': '10', + 'position': (0, -100), + 'scale': 2.3, + 'shadow': 1.0, + 'flatness': 1.0, + 'opacity': 0.0, + 'v_attach': 'top', + 'h_attach': 'center', + 'h_align': 'center', + 'v_align': 'center'}) self._textLevel = bs.newnode('text', - attrs={'text': 'Level ' + str(self._levelStage), - 'position': (0, -28), - 'scale': 1.3, - 'shadow': 1.0, - 'flatness': 1.0, - 'color': (1.0, 0.0, 1.0), - 'opacity': 0.0, - 'v_attach': 'top', - 'h_attach': 'center', - 'h_align': 'center', - 'v_align': 'center'}) + attrs={'text': 'Level ' + str(self._levelStage), + 'position': (0, -28), + 'scale': 1.3, + 'shadow': 1.0, + 'flatness': 1.0, + 'color': (1.0, 0.0, 1.0), + 'opacity': 0.0, + 'v_attach': 'top', + 'h_attach': 'center', + 'h_align': 'center', + 'v_align': 'center'}) self._imageCircle = bs.newnode('image', - attrs={'texture': self._circleTex, - 'position': (75, -75), - 'scale': (20,20), - 'color': (0.2, 0.2, 0.2), - 'opacity': 0.0, - 'attach': 'topCenter'}) + attrs={'texture': self._circleTex, + 'position': (75, -75), + 'scale': (20, 20), + 'color': (0.2, 0.2, 0.2), + 'opacity': 0.0, + 'attach': 'topCenter'}) self._imageCircle2 = bs.newnode('image', - attrs={'texture': self._circleTex, - 'position': (75, -100), - 'scale': (20,20), - 'color': (0.2, 0.2, 0.2), - 'opacity': 0.0, - 'attach': 'topCenter'}) + attrs={'texture': self._circleTex, + 'position': (75, -100), + 'scale': (20, 20), + 'color': (0.2, 0.2, 0.2), + 'opacity': 0.0, + 'attach': 'topCenter'}) self._imageCircle3 = bs.newnode('image', - attrs={'texture': self._circleTex, - 'position': (75, -125), - 'scale': (20,20), - 'color': (0.2, 0.2, 0.2), - 'opacity': 0.0, - 'attach': 'topCenter'}) - + attrs={'texture': self._circleTex, + 'position': (75, -125), + 'scale': (20, 20), + 'color': (0.2, 0.2, 0.2), + 'opacity': 0.0, + 'attach': 'topCenter'}) def on_transition_in(self) -> None: super().on_transition_in() @@ -300,14 +295,14 @@ class MGgame(bs.TeamGameActivity[Player, Team]): self.coldel16 = True if self.credit_text: t = bs.newnode('text', - attrs={ 'text':"Made by Freaku\nOriginally for 1.4: byANG3L", ## Disable 'Enable Bottom Credits' when making playlist, No need to edit this lovely... - 'scale':0.7, - 'position':(0,0), - 'shadow':0.5, - 'flatness':1.2, - 'color':(1, 1, 1), - 'h_align':'center', - 'v_attach':'bottom'}) + attrs={'text': "Made by Freaku\nOriginally for 1.4: byANG3L", # Disable 'Enable Bottom Credits' when making playlist, No need to edit this lovely... + 'scale': 0.7, + 'position': (0, 0), + 'shadow': 0.5, + 'flatness': 1.2, + 'color': (1, 1, 1), + 'h_align': 'center', + 'v_attach': 'bottom'}) self.spawnAllMap() self.flashHide() @@ -318,6 +313,7 @@ class MGgame(bs.TeamGameActivity[Player, Team]): def startCounter(self): self._textCounter.text = '10' + def count9(): def count8(): def count7(): @@ -366,8 +362,8 @@ class MGgame(bs.TeamGameActivity[Player, Team]): if self.has_begun(): bs.broadcastmessage( babase.Lstr(resource='playerDelayedJoinText', - subs=[('${PLAYER}', player.getname(full=True))]), - color=(0, 1, 0),transient=True,clients=[player.sessionplayer.inputdevice.client_id]) + subs=[('${PLAYER}', player.getname(full=True))]), + color=(0, 1, 0), transient=True, clients=[player.sessionplayer.inputdevice.client_id]) # For score purposes, mark them as having died right as the # game started. assert self._timer is not None @@ -385,7 +381,8 @@ class MGgame(bs.TeamGameActivity[Player, Team]): # overriding the default character spawning.. def spawn_player(self, player: Player) -> bs.Actor: spaz = self.spawn_player_spaz(player) - pos = (self._spawnCenter[0] + random.uniform(-1.5, 2.5), self._spawnCenter[1], self._spawnCenter[2] + random.uniform(-2.5, 1.5)) + pos = (self._spawnCenter[0] + random.uniform(-1.5, 2.5), + self._spawnCenter[1], self._spawnCenter[2] + random.uniform(-2.5, 1.5)) spaz.connect_controls_to_player(enable_punch=False, enable_bomb=False, enable_pickup=False) spaz.handlemessage(bs.StandMessage(pos)) return spaz @@ -393,49 +390,50 @@ class MGgame(bs.TeamGameActivity[Player, Team]): def _randomSelect(self): if self._levelStage == 1: self._textureSelected = random.choice([self._mapFGMinesTex, - self._mapFGStickyTex]) + self._mapFGStickyTex]) self._image.texture = self._textureSelected elif self._levelStage == 2: self._textureSelected = random.choice([self._mapFGIceTex, - self._mapFGShieldTex]) + self._mapFGShieldTex]) self._image.texture = self._textureSelected - elif self._levelStage in [3,4,5]: + elif self._levelStage in [3, 4, 5]: self._textureSelected = random.choice([self._mapFGStickyTex, - self._mapFGIceTex, - self._mapFGImpactTex, - self._mapFGMinesTex]) + self._mapFGIceTex, + self._mapFGImpactTex, + self._mapFGMinesTex]) self._image.texture = self._textureSelected - elif self._levelStage in [6,7,8,9]: + elif self._levelStage in [6, 7, 8, 9]: self._textureSelected = random.choice([self._mapFGCurseTex, - self._mapFGHealthTex, - self._mapFGIceTex, - self._mapFGImpactTex, - self._mapFGMinesTex, - self._mapFGPunchTex, - self._mapFGShieldTex]) + self._mapFGHealthTex, + self._mapFGIceTex, + self._mapFGImpactTex, + self._mapFGMinesTex, + self._mapFGPunchTex, + self._mapFGShieldTex]) self._image.texture = self._textureSelected elif self._levelStage >= 10: self._textureSelected = random.choice([self._mapFGSpaz, - self._mapFGZoe, - self._mapFGSnake, - self._mapFGKronk, - self._mapFGMel, - self._mapFGJack, - self._mapFGSanta, - self._mapFGFrosty, - self._mapFGBones, - self._mapFGBernard, - self._mapFGPascal, - self._mapFGAli, - self._mapFGRobot, - self._mapFGAgent, - self._mapFGGrumbledorf, - self._mapFGPixel]) + self._mapFGZoe, + self._mapFGSnake, + self._mapFGKronk, + self._mapFGMel, + self._mapFGJack, + self._mapFGSanta, + self._mapFGFrosty, + self._mapFGBones, + self._mapFGBernard, + self._mapFGPascal, + self._mapFGAli, + self._mapFGRobot, + self._mapFGAgent, + self._mapFGGrumbledorf, + self._mapFGPixel]) self._image.texture = self._textureSelected return self._textureSelected def _stop(self): self._textureSelected = self._randomSelect() + def circle(): def circle2(): def circle3(): @@ -455,100 +453,100 @@ class MGgame(bs.TeamGameActivity[Player, Team]): def _randomPlatform(self): if self._levelStage == 1: - randomTexture=[self._mapFGMinesTex, - self._mapFGMinesTex, - self._mapFGMinesTex, - self._mapFGMinesTex, - self._mapFGMinesTex, - self._mapFGMinesTex, - self._mapFGMinesTex, - self._mapFGMinesTex, - self._mapFGStickyTex, - self._mapFGStickyTex, - self._mapFGStickyTex, - self._mapFGStickyTex, - self._mapFGStickyTex, - self._mapFGStickyTex, - self._mapFGStickyTex, - self._mapFGStickyTex] + randomTexture = [self._mapFGMinesTex, + self._mapFGMinesTex, + self._mapFGMinesTex, + self._mapFGMinesTex, + self._mapFGMinesTex, + self._mapFGMinesTex, + self._mapFGMinesTex, + self._mapFGMinesTex, + self._mapFGStickyTex, + self._mapFGStickyTex, + self._mapFGStickyTex, + self._mapFGStickyTex, + self._mapFGStickyTex, + self._mapFGStickyTex, + self._mapFGStickyTex, + self._mapFGStickyTex] elif self._levelStage == 2: - randomTexture=[self._mapFGIceTex, - self._mapFGIceTex, - self._mapFGIceTex, - self._mapFGIceTex, - self._mapFGIceTex, - self._mapFGIceTex, - self._mapFGIceTex, - self._mapFGIceTex, - self._mapFGShieldTex, - self._mapFGShieldTex, - self._mapFGShieldTex, - self._mapFGShieldTex, - self._mapFGShieldTex, - self._mapFGShieldTex, - self._mapFGShieldTex, - self._mapFGShieldTex] - elif self._levelStage in [3,4,5]: - randomTexture=[self._mapFGStickyTex, - self._mapFGStickyTex, - self._mapFGStickyTex, - self._mapFGStickyTex, - self._mapFGIceTex, - self._mapFGIceTex, - self._mapFGIceTex, - self._mapFGIceTex, - self._mapFGImpactTex, - self._mapFGImpactTex, - self._mapFGImpactTex, - self._mapFGImpactTex, - self._mapFGMinesTex, - self._mapFGMinesTex, - self._mapFGMinesTex, - self._mapFGMinesTex] - elif self._levelStage in [6,7,8,9]: - randomTexture=[self._mapFGHealthTex, - self._mapFGShieldTex, - self._mapFGCurseTex, - self._mapFGCurseTex, - self._mapFGHealthTex, - self._mapFGHealthTex, - self._mapFGIceTex, - self._mapFGIceTex, - self._mapFGImpactTex, - self._mapFGImpactTex, - self._mapFGMinesTex, - self._mapFGMinesTex, - self._mapFGPunchTex, - self._mapFGPunchTex, - self._mapFGShieldTex, - self._mapFGShieldTex] + randomTexture = [self._mapFGIceTex, + self._mapFGIceTex, + self._mapFGIceTex, + self._mapFGIceTex, + self._mapFGIceTex, + self._mapFGIceTex, + self._mapFGIceTex, + self._mapFGIceTex, + self._mapFGShieldTex, + self._mapFGShieldTex, + self._mapFGShieldTex, + self._mapFGShieldTex, + self._mapFGShieldTex, + self._mapFGShieldTex, + self._mapFGShieldTex, + self._mapFGShieldTex] + elif self._levelStage in [3, 4, 5]: + randomTexture = [self._mapFGStickyTex, + self._mapFGStickyTex, + self._mapFGStickyTex, + self._mapFGStickyTex, + self._mapFGIceTex, + self._mapFGIceTex, + self._mapFGIceTex, + self._mapFGIceTex, + self._mapFGImpactTex, + self._mapFGImpactTex, + self._mapFGImpactTex, + self._mapFGImpactTex, + self._mapFGMinesTex, + self._mapFGMinesTex, + self._mapFGMinesTex, + self._mapFGMinesTex] + elif self._levelStage in [6, 7, 8, 9]: + randomTexture = [self._mapFGHealthTex, + self._mapFGShieldTex, + self._mapFGCurseTex, + self._mapFGCurseTex, + self._mapFGHealthTex, + self._mapFGHealthTex, + self._mapFGIceTex, + self._mapFGIceTex, + self._mapFGImpactTex, + self._mapFGImpactTex, + self._mapFGMinesTex, + self._mapFGMinesTex, + self._mapFGPunchTex, + self._mapFGPunchTex, + self._mapFGShieldTex, + self._mapFGShieldTex] elif self._levelStage >= 10: - randomTexture=[self._mapFGSpaz, - self._mapFGZoe, - self._mapFGSnake, - self._mapFGKronk, - self._mapFGMel, - self._mapFGJack, - self._mapFGSanta, - self._mapFGFrosty, - self._mapFGBones, - self._mapFGBernard, - self._mapFGPascal, - self._mapFGAli, - self._mapFGRobot, - self._mapFGAgent, - self._mapFGGrumbledorf, - self._mapFGPixel] + randomTexture = [self._mapFGSpaz, + self._mapFGZoe, + self._mapFGSnake, + self._mapFGKronk, + self._mapFGMel, + self._mapFGJack, + self._mapFGSanta, + self._mapFGFrosty, + self._mapFGBones, + self._mapFGBernard, + self._mapFGPascal, + self._mapFGAli, + self._mapFGRobot, + self._mapFGAgent, + self._mapFGGrumbledorf, + self._mapFGPixel] (self.mapFGPTex, self.mapFGP2Tex, self.mapFGP3Tex, self.mapFGP4Tex, - self.mapFGP5Tex, self.mapFGP6Tex, - self.mapFGP7Tex, self.mapFGP8Tex, - self.mapFGP9Tex,self.mapFGP10Tex, - self.mapFGP11Tex, self.mapFGP12Tex, - self.mapFGP13Tex, self.mapFGP14Tex, - self.mapFGP15Tex, self.mapFGP16Tex) = ( - random.sample(randomTexture, 16)) + self.mapFGP5Tex, self.mapFGP6Tex, + self.mapFGP7Tex, self.mapFGP8Tex, + self.mapFGP9Tex, self.mapFGP10Tex, + self.mapFGP11Tex, self.mapFGP12Tex, + self.mapFGP13Tex, self.mapFGP14Tex, + self.mapFGP15Tex, self.mapFGP16Tex) = ( + random.sample(randomTexture, 16)) self._mixPlatform() def _mixPlatform(self): @@ -685,114 +683,130 @@ class MGgame(bs.TeamGameActivity[Player, Team]): shared = SharedObjects.get() if self.coldel: self.mapFGP = bs.newnode('prop', - attrs={'body': 'puck', 'position': (4.5,2,-9), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + attrs={'body': 'puck', 'position': (4.5, 2, -9), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGPTex = None - self.mapFGPcol = bs.newnode('region',attrs={'position': (4.5,2,-9),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGPcol = bs.newnode('region', attrs={'position': (4.5, 2, -9), 'scale': ( + 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) self.coldel = False if self.coldel2: - self.mapFGP2 = bs.newnode('prop', - attrs={'body': 'puck', 'position': (4.5,2,-6), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP2 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (4.5, 2, -6), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP2Tex = None - self.mapFGP2col = bs.newnode('region',attrs={'position': (4.5,2,-6),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP2col = bs.newnode('region', attrs={'position': (4.5, 2, -6), 'scale': ( + 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) self.coldel2 = False if self.coldel3: - self.mapFGP3 = bs.newnode('prop', - attrs={'body': 'puck', 'position': (4.5,2,-3), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP3 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (4.5, 2, -3), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP3Tex = None - self.mapFGP3col = bs.newnode('region',attrs={'position': (4.5,2,-3),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP3col = bs.newnode('region', attrs={'position': (4.5, 2, -3), 'scale': ( + 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) self.coldel3 = False if self.coldel4: - self.mapFGP4 = bs.newnode('prop', - attrs={'body': 'puck', 'position': (4.5,2,0), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP4 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (4.5, 2, 0), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP4Tex = None - self.mapFGP4col = bs.newnode('region',attrs={'position': (4.5,2,0),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP4col = bs.newnode('region', attrs={'position': (4.5, 2, 0), 'scale': ( + 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) self.coldel4 = False if self.coldel5: - self.mapFGP5 = bs.newnode('prop', - attrs={'body': 'puck', 'position': (1.5,2,-9), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP5 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (1.5, 2, -9), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP5Tex = None - self.mapFGP5col = bs.newnode('region',attrs={'position': (1.5,2,-9),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP5col = bs.newnode('region', attrs={'position': (1.5, 2, -9), 'scale': ( + 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) self.coldel5 = False if self.coldel6: - self.mapFGP6 = bs.newnode('prop', - attrs={'body': 'puck', 'position': (1.5,2,-6), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP6 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (1.5, 2, -6), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP6Tex = None - self.mapFGP6col = bs.newnode('region',attrs={'position': (1.5,2,-6),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP6col = bs.newnode('region', attrs={'position': (1.5, 2, -6), 'scale': ( + 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) self.coldel6 = False if self.coldel7: - self.mapFGP7 = bs.newnode('prop', - attrs={'body': 'puck', 'position': (1.5,2,-3), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP7 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (1.5, 2, -3), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP7Tex = None - self.mapFGP7col = bs.newnode('region',attrs={'position': (1.5,2,-3),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP7col = bs.newnode('region', attrs={'position': (1.5, 2, -3), 'scale': ( + 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) self.coldel7 = False if self.coldel8: - self.mapFGP8 = bs.newnode('prop', - attrs={'body': 'puck', 'position': (1.5,2,0), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP8 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (1.5, 2, 0), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP8Tex = None - self.mapFGP8col = bs.newnode('region',attrs={'position': (1.5,2,0),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP8col = bs.newnode('region', attrs={'position': (1.5, 2, 0), 'scale': ( + 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) self.coldel8 = False if self.coldel9: - self.mapFGP9 = bs.newnode('prop', - attrs={'body': 'puck', 'position': (-1.5,2,-9), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP9 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (-1.5, 2, -9), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP9Tex = None - self.mapFGP9col = bs.newnode('region',attrs={'position': (-1.5,2,-9),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP9col = bs.newnode('region', attrs={'position': (-1.5, 2, -9), 'scale': ( + 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) self.coldel9 = False if self.coldel10: - self.mapFGP10 = bs.newnode('prop', - attrs={'body': 'puck', 'position': (-1.5,2,-6), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP10 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (-1.5, 2, -6), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP10Tex = None - self.mapFGP10col = bs.newnode('region',attrs={'position': (-1.5,2,-6),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP10col = bs.newnode('region', attrs={'position': (-1.5, 2, -6), 'scale': ( + 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) self.coldel10 = False if self.coldel11: - self.mapFGP11 = bs.newnode('prop', - attrs={'body': 'puck', 'position': (-1.5,2,-3), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP11 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (-1.5, 2, -3), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP11Tex = None - self.mapFGP11col = bs.newnode('region',attrs={'position': (-1.5,2,-3),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP11col = bs.newnode('region', attrs={'position': (-1.5, 2, -3), 'scale': ( + 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) self.coldel11 = False if self.coldel12: - self.mapFGP12 = bs.newnode('prop', - attrs={'body': 'puck', 'position': (-1.5,2,0), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP12 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (-1.5, 2, 0), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP12Tex = None - self.mapFGP12col = bs.newnode('region',attrs={'position': (-1.5,2,0),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP12col = bs.newnode('region', attrs={'position': (-1.5, 2, 0), 'scale': ( + 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) self.coldel12 = False if self.coldel13: - self.mapFGP13 = bs.newnode('prop', - attrs={'body': 'puck', 'position': (-4.5,2,-9), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP13 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (-4.5, 2, -9), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP13Tex = None - self.mapFGP13col = bs.newnode('region',attrs={'position': (-4.5,2,-9),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP13col = bs.newnode('region', attrs={'position': (-4.5, 2, -9), 'scale': ( + 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) self.coldel13 = False if self.coldel14: - self.mapFGP14 = bs.newnode('prop', - attrs={'body': 'puck', 'position': (-4.5,2,-6), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP14 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (-4.5, 2, -6), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP14Tex = None - self.mapFGP14col = bs.newnode('region',attrs={'position': (-4.5,2,-6),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP14col = bs.newnode('region', attrs={'position': (-4.5, 2, -6), 'scale': ( + 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) self.coldel14 = False if self.coldel15: - self.mapFGP15 = bs.newnode('prop', - attrs={'body': 'puck', 'position': (-4.5,2,-3), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP15 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (-4.5, 2, -3), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP15Tex = None - self.mapFGP15col = bs.newnode('region',attrs={'position': (-4.5,2,-3),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP15col = bs.newnode('region', attrs={'position': (-4.5, 2, -3), 'scale': ( + 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) self.coldel15 = False if self.coldel16: - self.mapFGP16 = bs.newnode('prop', - attrs={'body': 'puck', 'position': (-4.5,2,0), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale':0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) + self.mapFGP16 = bs.newnode('prop', + attrs={'body': 'puck', 'position': (-4.5, 2, 0), 'mesh': self._mapFGPModel, 'mesh_scale': 3.73, 'body_scale': 3.73, 'shadow_size': 0.5, 'gravity_scale': 0.0, 'color_texture': self._mapFGPDefaultTex, 'reflection': 'soft', 'reflection_scale': [1.0], 'is_area_of_interest': True, 'materials': [self.dont_collide]}) self.mapFGP16Tex = None - self.mapFGP16col = bs.newnode('region',attrs={'position': (-4.5,2,0),'scale': (3.5,0.1,3.5),'type': 'box','materials': (self._collide_with_player, shared.footing_material)}) + self.mapFGP16col = bs.newnode('region', attrs={'position': (-4.5, 2, 0), 'scale': ( + 3.5, 0.1, 3.5), 'type': 'box', 'materials': (self._collide_with_player, shared.footing_material)}) self.coldel16 = False def _platformTexDefault(self): @@ -876,7 +890,6 @@ class MGgame(bs.TeamGameActivity[Player, Team]): if living_team_count <= 1: self.end_game() - def end_game(self) -> None: cur_time = bs.time() assert self._timer is not None @@ -929,18 +942,14 @@ class MGgame(bs.TeamGameActivity[Player, Team]): self.end(results=results) - - - - - - - class MGdefs(): points = {} boxes = {} - boxes['area_of_interest_bounds'] = (0.3544110667, 4.493562578, -2.518391331) + (0.0, 0.0, 0.0) + (16.64754831, 8.06138989, 18.5029888) - boxes['map_bounds'] = (0.2608783669, 4.899663734, -3.543675157) + (0.0, 0.0, 0.0) + (29.23565494, 14.19991443, 29.92689344) + boxes['area_of_interest_bounds'] = ( + 0.3544110667, 4.493562578, -2.518391331) + (0.0, 0.0, 0.0) + (16.64754831, 8.06138989, 18.5029888) + boxes['map_bounds'] = (0.2608783669, 4.899663734, -3.543675157) + \ + (0.0, 0.0, 0.0) + (29.23565494, 14.19991443, 29.92689344) + class MGmap(bs.Map): defs = MGdefs() @@ -983,16 +992,12 @@ class MGmap(bs.Map): gnode.vr_near_clip = 0.5 - - - bs._map.register_map(MGmap) - - # ba_meta export plugin class byFreaku(babase.Plugin): def __init__(self): ## Campaign support ## - babase.app.classic.add_coop_practice_level(bs.Level(name='Memory Game', displayname='${GAME}', gametype=MGgame, settings={}, preview_texture_name='achievementOffYouGo')) \ No newline at end of file + babase.app.classic.add_coop_practice_level(bs.Level( + name='Memory Game', displayname='${GAME}', gametype=MGgame, settings={}, preview_texture_name='achievementOffYouGo')) diff --git a/plugins/minigames/musical_flags.py b/plugins/minigames/musical_flags.py index 41828b3..7934c10 100644 --- a/plugins/minigames/musical_flags.py +++ b/plugins/minigames/musical_flags.py @@ -1,31 +1,31 @@ -## Made by MattZ45986 on GitHub -## Ported by your friend: Freaku +# Made by MattZ45986 on GitHub +# Ported by your friend: Freaku -#Bug Fixes & Improvements as well... +# Bug Fixes & Improvements as well... -#Join BCS: +# Join BCS: # https://discord.gg/ucyaesh - - from __future__ import annotations from typing import TYPE_CHECKING -import _babase, random, math +import _babase +import random +import math import bascenev1 as bs -from bascenev1lib.actor.flag import Flag,FlagPickedUpMessage +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(bs.Player['Team']): def __init__(self) -> None: self.done: bool = False self.survived: bool = True + class Team(bs.Team[Player]): def __init__(self) -> None: self.score = 0 @@ -73,23 +73,23 @@ class MFGame(bs.TeamGameActivity[Player, Team]): self.is_run = bool(settings['Enable Running']) self._textRound = bs.newnode('text', - attrs={'text': '', - 'position': (0, -38), - 'scale': 1, - 'shadow': 1.0, - 'flatness': 1.0, - 'color': (1.0, 0.0, 1.0), - 'opacity': 1, - 'v_attach': 'top', - 'h_attach': 'center', - 'h_align': 'center', - 'v_align': 'center'}) + attrs={'text': '', + 'position': (0, -38), + 'scale': 1, + 'shadow': 1.0, + 'flatness': 1.0, + 'color': (1.0, 0.0, 1.0), + 'opacity': 1, + 'v_attach': 'top', + '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)}) + 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 @@ -106,7 +106,7 @@ class MFGame(bs.TeamGameActivity[Player, Team]): bs.broadcastmessage( bs.Lstr(resource='playerDelayedJoinText', subs=[('${PLAYER}', player.getname(full=True))]), - color=(0, 1, 0),transient=True) + color=(0, 1, 0), transient=True) player.survived = False return self.spawn_player(player) @@ -125,14 +125,14 @@ class MFGame(bs.TeamGameActivity[Player, Team]): self.spawned = [] if self.credit_text: t = bs.newnode('text', - attrs={ 'text':"Ported by Freaku\nMade by MattZ45986", ## Disable 'Enable Bottom Credits' when making playlist, No need to edit this lovely... - 'scale':0.7, - 'position':(0,0), - 'shadow':0.5, - 'flatness':1.2, - 'color':(1, 1, 1), - 'h_align':'center', - 'v_attach':'bottom'}) + attrs={'text': "Ported by Freaku\nMade by MattZ45986", # Disable 'Enable Bottom Credits' when making playlist, No need to edit this lovely... + 'scale': 0.7, + 'position': (0, 0), + 'shadow': 0.5, + 'flatness': 1.2, + 'color': (1, 1, 1), + 'h_align': 'center', + 'v_attach': 'bottom'}) self.makeRound() self._textRound.text = 'Round ' + str(self.roundNum) bs.timer(3, self.checkEnd) @@ -147,14 +147,15 @@ class MFGame(bs.TeamGameActivity[Player, Team]): 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) + 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: @@ -163,7 +164,8 @@ class MFGame(bs.TeamGameActivity[Player, Team]): def makeRound(self): for player in self.players: - if player.survived: player.team.score += 1 + if player.survived: + player.team.score += 1 self.roundNum += 1 self._textRound.text = 'Round ' + str(self.roundNum) self.flags = [] @@ -171,48 +173,57 @@ class MFGame(bs.TeamGameActivity[Player, Team]): 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 + angle = random.randint(0, 359) + c = 0 for player in self.players: - if player.survived: c+=1 + if player.survived: + c += 1 spacing = 10 for player in self.players: player.done = False if player.survived: if not player.is_alive(): - self.spawn_player(player,(.5,5,-4)) + self.spawn_player(player, (.5, 5, -4)) self.spawned.append(player) - 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)] - + 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))) - + 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): angle += spacing angle %= 360 - x=6 * math.sin(math.degrees(angle)) - z=6 * math.cos(math.degrees(angle)) - flag = Flag(position=(x+.5,5,z-4), color=colors[i]).autoretain() + x = 6 * math.sin(math.degrees(angle)) + z = 6 * math.cos(math.degrees(angle)) + flag = Flag(position=(x+.5, 5, z-4), color=colors[i]).autoretain() self.flags.append(flag) def killRound(self): self.numPickedUp = 0 for player in self.players: - if player.is_alive(): player.actor.handlemessage(bs.DieMessage()) - for flag in self.flags: flag.node.delete() - for light in self.nodes: light.delete() + 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)) -> bs.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) + 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(bs.StandMessage(pos)) return spaz @@ -231,10 +242,10 @@ class MFGame(bs.TeamGameActivity[Player, Team]): self.numPickedUp += 1 msg.node.getdelegate(PlayerSpaz, True).getplayer(Player, True).done = True l = bs.newnode('light', - owner=None, - attrs={'color':msg.node.color, - 'position':(msg.node.position_center), - 'intensity':1}) + owner=None, + attrs={'color': msg.node.color, + 'position': (msg.node.position_center), + 'intensity': 1}) self.nodes.append(l) msg.flag.handlemessage(bs.DieMessage()) msg.node.handlemessage(bs.DieMessage()) @@ -247,12 +258,13 @@ class MFGame(bs.TeamGameActivity[Player, Team]): try: player.survived = False 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 - bs.timer(3.5,self.killRound) - bs.timer(3.55,self.makeRound) + 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 + bs.timer(3.5, self.killRound) + bs.timer(3.55, self.makeRound) else: return super().handlemessage(msg) return None @@ -261,7 +273,7 @@ class MFGame(bs.TeamGameActivity[Player, Team]): i = 0 for player in self.players: if player.survived: - i+=1 + i += 1 if i <= 1: for player in self.players: if player.survived: @@ -272,4 +284,4 @@ class MFGame(bs.TeamGameActivity[Player, Team]): results = bs.GameResults() for team in self.teams: results.set_team_score(team, team.score) - self.end(results=results) \ No newline at end of file + self.end(results=results) diff --git a/plugins/minigames/volleyball.py b/plugins/minigames/volleyball.py index b255950..df4c19a 100644 --- a/plugins/minigames/volleyball.py +++ b/plugins/minigames/volleyball.py @@ -3,20 +3,14 @@ # Made by your friend: Freaku - - # Join BCS: # https://discord.gg/ucyaesh - - # My GitHub: # https://github.com/Freaku17/BombSquad-Mods-byFreaku - - # CHANGELOG: """ ## 2021 @@ -38,21 +32,14 @@ """ - - - - - - - - # ba_meta require api 8 from __future__ import annotations from typing import TYPE_CHECKING -import babase, random +import babase +import random import bascenev1 as bs from bascenev1lib.actor.playerspaz import PlayerSpaz from bascenev1lib.actor.scoreboard import Scoreboard @@ -64,7 +51,6 @@ if TYPE_CHECKING: from typing import Any, Sequence, Dict, Type, List, Optional, Union - class PuckDiedMessage: """Inform something that a puck has died.""" @@ -100,14 +86,13 @@ class Puck(bs.Actor): 'position': self._spawn_pos, 'materials': pmats }) - + # Since it rolls on spawn, lets make gravity # to 0, and when another node (bomb/spaz) # touches it. It'll act back as our normie puck! - bs.animate(self.node, 'gravity_scale', {0:-0.1, 0.2:1}, False) + bs.animate(self.node, 'gravity_scale', {0: -0.1, 0.2: 1}, False) # When other node touches, it realises its new gravity_scale - def handlemessage(self, msg: Any) -> Any: if isinstance(msg, bs.DieMessage): assert self.node @@ -148,6 +133,7 @@ class Player(bs.Player['Team']): class Team(bs.Team[Player]): """Our team type for this game.""" + def __init__(self) -> None: self.score = 0 @@ -253,15 +239,14 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): actions=(('modify_part_collision', 'collide', True), ('modify_part_collision', 'physical', False), ('call', 'at_connect', self._handle_score))) - - - self._wall_material=bs.Material() - self._fake_wall_material=bs.Material() + + self._wall_material = bs.Material() + self._fake_wall_material = bs.Material() self._wall_material.add_actions( - + actions=( ('modify_part_collision', 'friction', 100000), - )) + )) self._wall_material.add_actions( conditions=('they_have_material', shared.pickup_material), actions=( @@ -270,13 +255,13 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): self._wall_material.add_actions( conditions=(('we_are_younger_than', 100), - 'and', - ('they_have_material',shared.object_material)), + 'and', + ('they_have_material', shared.object_material)), actions=( ('modify_part_collision', 'collide', False), )) self._wall_material.add_actions( - conditions=('they_have_material',shared.footing_material), + conditions=('they_have_material', shared.footing_material), actions=( ('modify_part_collision', 'friction', 9999.5), )) @@ -285,25 +270,24 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): actions=( ('modify_part_collision', 'collide', False), ('modify_part_collision', 'physical', False) - + )) self._fake_wall_material.add_actions( conditions=('they_have_material', shared.player_material), actions=( ('modify_part_collision', 'collide', True), ('modify_part_collision', 'physical', True) - + )) - self.blocks=[] + self.blocks = [] - - self._net_wall_material=bs.Material() + self._net_wall_material = bs.Material() self._net_wall_material.add_actions( conditions=('they_have_material', shared.player_material), actions=( ('modify_part_collision', 'collide', True), ('modify_part_collision', 'physical', True) - + )) self._net_wall_material.add_actions( @@ -321,8 +305,7 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): actions=( ('modify_part_collision', 'collide', True), )) - self.net_blocc=[] - + self.net_blocc = [] self._puck_spawn_pos: Optional[Sequence[float]] = None self._score_regions: Optional[List[bs.NodeActor]] = None @@ -365,7 +348,7 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): bs.NodeActor( bs.newnode('region', attrs={ - 'position':(5.7, 0, -0.065), + 'position': (5.7, 0, -0.065), 'scale': (10.7, 0.001, 8), 'type': 'box', 'materials': [self._score_region_material] @@ -374,7 +357,7 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): bs.NodeActor( bs.newnode('region', attrs={ - 'position':(-5.7, 0, -0.065), + 'position': (-5.7, 0, -0.065), 'scale': (10.7, 0.001, 8), 'type': 'box', 'materials': [self._score_region_material] @@ -383,18 +366,20 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): self._chant_sound.play() if self.credit_text: t = bs.newnode('text', - attrs={ 'text':"Created by Freaku\nVolleyBall", ## Disable 'Enable Bottom Credits' when making playlist, No need to edit this lovely... - 'scale':0.7, - 'position':(0,0), - 'shadow':0.5, - 'flatness':1.2, - 'color':(1, 1, 1), - 'h_align':'center', - 'v_attach':'bottom'}) + attrs={'text': "Created by Freaku\nVolleyBall", # Disable 'Enable Bottom Credits' when making playlist, No need to edit this lovely... + 'scale': 0.7, + 'position': (0, 0), + 'shadow': 0.5, + 'flatness': 1.2, + 'color': (1, 1, 1), + 'h_align': 'center', + 'v_attach': 'bottom'}) shared = SharedObjects.get() - self.blocks.append(bs.NodeActor(bs.newnode('region',attrs={'position': (0,2.4,0),'scale': (0.8,6,20),'type': 'box','materials': (self._fake_wall_material, )}))) - - self.net_blocc.append(bs.NodeActor(bs.newnode('region',attrs={'position': (0,0,0),'scale': (0.6,2.4,20),'type': 'box','materials': (self._net_wall_material, )}))) + self.blocks.append(bs.NodeActor(bs.newnode('region', attrs={'position': (0, 2.4, 0), 'scale': ( + 0.8, 6, 20), 'type': 'box', 'materials': (self._fake_wall_material, )}))) + + self.net_blocc.append(bs.NodeActor(bs.newnode('region', attrs={'position': (0, 0, 0), 'scale': ( + 0.6, 2.4, 20), 'type': 'box', 'materials': (self._net_wall_material, )}))) def on_team_join(self, team: Team) -> None: self._update_scoreboard() @@ -434,18 +419,15 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): scoring_team = team team.score += 1 - - # Change puck Spawn - if team.id == 0: # left side scored - self._puck_spawn_pos= (5, 0.42, 0) - elif team.id == 1: # right side scored - self._puck_spawn_pos= (-5, 0.42, 0) - else: # normally shouldn't occur - self._puck_spawn_pos= (0, 0.42, 0) + if team.id == 0: # left side scored + self._puck_spawn_pos = (5, 0.42, 0) + elif team.id == 1: # right side scored + self._puck_spawn_pos = (-5, 0.42, 0) + else: # normally shouldn't occur + self._puck_spawn_pos = (0, 0.42, 0) # Easy pizzy - - + for player in team.players: if player.actor: player.actor.handlemessage(bs.CelebrateMessage(2.0)) @@ -469,10 +451,10 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): self._puck.scored = True # Kill the puck (it'll respawn itself shortly). - bs.emitfx(position= bs.getcollision().position, count=int(6.0 + 7.0 * 12), scale=3, spread=0.5, chunk_type='spark') + bs.emitfx(position=bs.getcollision().position, count=int( + 6.0 + 7.0 * 12), scale=3, spread=0.5, chunk_type='spark') bs.timer(0.7, self._kill_puck) - bs.cameraflash(duration=7.0) self._update_scoreboard() @@ -502,7 +484,6 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): spaz.bomb_count = 0 # Imagine not being able to swipe those colorful buttons ;( - if self._punchie_: spaz.connect_controls_to_player(enable_punch=False) @@ -525,7 +506,8 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): def _flash_puck_spawn(self) -> None: # Effect >>>>>> Flashly - bs.emitfx(position= self._puck_spawn_pos, count=int(6.0 + 7.0 * 12), scale=1.7, spread=0.4, chunk_type='spark') + bs.emitfx(position=self._puck_spawn_pos, count=int( + 6.0 + 7.0 * 12), scale=1.7, spread=0.4, chunk_type='spark') def _spawn_puck(self) -> None: self._swipsound.play() @@ -535,45 +517,26 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): self._puck = Puck(position=self._puck_spawn_pos) - - - - - - - - - - - - - - - - - - - - - class Pointzz: points, boxes = {}, {} points['spawn1'] = (-8.03866, 0.02275, 0.0) + (0.5, 0.05, 4.0) points['spawn2'] = (8.82311, 0.01092, 0.0) + (0.5, 0.05, 4.0) - boxes['area_of_interest_bounds'] = (0.0, 1.18575, 0.43262) + (0, 0, 0) + (29.81803, 11.57249, 18.89134) + boxes['area_of_interest_bounds'] = (0.0, 1.18575, 0.43262) + \ + (0, 0, 0) + (29.81803, 11.57249, 18.89134) boxes['map_bounds'] = (0.0, 1.185751251, 0.4326226188) + (0.0, 0.0, 0.0) + ( - 42.09506485, 22.81173179, 29.76723155) + 42.09506485, 22.81173179, 29.76723155) + class PointzzforH: points, boxes = {}, {} - boxes['area_of_interest_bounds'] = (0.0, 0.7956858119, 0.0) + (0.0, 0.0, 0.0) + (30.80223883, 0.5961646365, 13.88431707) + boxes['area_of_interest_bounds'] = (0.0, 0.7956858119, 0.0) + \ + (0.0, 0.0, 0.0) + (30.80223883, 0.5961646365, 13.88431707) boxes['map_bounds'] = (0.0, 0.7956858119, -0.4689020853) + (0.0, 0.0, 0.0) + ( - 35.16182389, 12.18696164, 21.52869693) + 35.16182389, 12.18696164, 21.52869693) points['spawn1'] = (-6.835352227, 0.02305323209, 0.0) + (1.0, 1.0, 3.0) points['spawn2'] = (6.857415055, 0.03938567998, 0.0) + (1.0, 1.0, 3.0) - class VolleyBallMap(bs.Map): defs = Pointzz() name = "Open Field" @@ -595,47 +558,47 @@ class VolleyBallMap(bs.Map): 'tex': bs.gettexture('footballStadium') } return data - + def __init__(self): super().__init__() shared = SharedObjects.get() x = -5 - while x<5: - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(0,0,x), - 'color':(1,1,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(0,.25,x), - 'color':(1,1,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(0,.5,x), - 'color':(1,1,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(0,.75,x), - 'color':(1,1,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(0,1,x), - 'color':(1,1,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + while x < 5: + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (0, 0, x), + 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (0, .25, x), + 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (0, .5, x), + 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (0, .75, x), + 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (0, 1, x), + 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) x = x + 0.5 y = -1 - while y>-11: - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(y,0.01,4), - 'color':(0,0,1),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(y,0.01,-4), - 'color':(0,0,1),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(-y,0.01,4), - 'color':(1,0,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(-y,0.01,-4), - 'color':(1,0,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - y-=1 + while y > -11: + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (y, 0.01, 4), + 'color': (0, 0, 1), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (y, 0.01, -4), + 'color': (0, 0, 1), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (-y, 0.01, 4), + 'color': (1, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (-y, 0.01, -4), + 'color': (1, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + y -= 1 z = 0 - while z<5: - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(11,0.01,z), - 'color':(1,0,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(11,0.01,-z), - 'color':(1,0,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(-11,0.01,z), - 'color':(0,0,1),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(-11,0.01,-z), - 'color':(0,0,1),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - z+=1 + while z < 5: + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (11, 0.01, z), + 'color': (1, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (11, 0.01, -z), + 'color': (1, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (-11, 0.01, z), + 'color': (0, 0, 1), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (-11, 0.01, -z), + 'color': (0, 0, 1), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + z += 1 self.node = bs.newnode( 'terrain', @@ -663,7 +626,6 @@ class VolleyBallMap(bs.Map): gnode.vr_near_clip = 0.5 - class VolleyBallMapH(bs.Map): defs = PointzzforH() name = 'Closed Arena' @@ -680,7 +642,7 @@ class VolleyBallMapH(bs.Map): def on_preload(cls) -> Any: data: Dict[str, Any] = { 'meshs': (bs.getmesh('hockeyStadiumOuter'), - bs.getmesh('hockeyStadiumInner')), + bs.getmesh('hockeyStadiumInner')), 'vr_fill_mesh': bs.getmesh('footballStadiumVRFill'), 'collision_mesh': bs.getcollisionmesh('hockeyStadiumCollide'), 'tex': bs.gettexture('hockeyStadium'), @@ -694,42 +656,42 @@ class VolleyBallMapH(bs.Map): super().__init__() shared = SharedObjects.get() x = -5 - while x<5: - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(0,0,x), - 'color':(1,1,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(0,.25,x), - 'color':(1,1,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(0,.5,x), - 'color':(1,1,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(0,.75,x), - 'color':(1,1,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(0,1,x), - 'color':(1,1,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) + while x < 5: + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (0, 0, x), + 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (0, .25, x), + 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (0, .5, x), + 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (0, .75, x), + 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (0, 1, x), + 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) x = x + 0.5 y = -1 - while y>-11: - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(y,0.01,4), - 'color':(0,0,1),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(y,0.01,-4), - 'color':(0,0,1),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(-y,0.01,4), - 'color':(1,0,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(-y,0.01,-4), - 'color':(1,0,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - y-=1 + while y > -11: + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (y, 0.01, 4), + 'color': (0, 0, 1), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (y, 0.01, -4), + 'color': (0, 0, 1), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (-y, 0.01, 4), + 'color': (1, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (-y, 0.01, -4), + 'color': (1, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + y -= 1 z = 0 - while z<5: - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(11,0.01,z), - 'color':(1,0,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(11,0.01,-z), - 'color':(1,0,0),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(-11,0.01,z), - 'color':(0,0,1),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - self.zone = bs.newnode('locator',attrs={'shape':'circle','position':(-11,0.01,-z), - 'color':(0,0,1),'opacity':1,'draw_beauty':True,'additive':False,'size':[0.40]}) - z+=1 + while z < 5: + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (11, 0.01, z), + 'color': (1, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (11, 0.01, -z), + 'color': (1, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (-11, 0.01, z), + 'color': (0, 0, 1), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + self.zone = bs.newnode('locator', attrs={'shape': 'circle', 'position': (-11, 0.01, -z), + 'color': (0, 0, 1), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': [0.40]}) + z += 1 self.node = bs.newnode('terrain', delegate=self, @@ -737,7 +699,8 @@ class VolleyBallMapH(bs.Map): 'mesh': None, 'collision_mesh': - bs.getcollisionmesh('footballStadiumCollide'), # we dont want Goalposts... + # we dont want Goalposts... + bs.getcollisionmesh('footballStadiumCollide'), 'color_texture': self.preloaddata['tex'], 'materials': [ @@ -758,7 +721,7 @@ class VolleyBallMapH(bs.Map): 'opacity': 0.92, 'opacity_in_low_or_medium_quality': 1.0, 'materials': mats, - 'color': (0.4,0.9,0) + 'color': (0.4, 0.9, 0) }) self.background = bs.newnode( @@ -767,7 +730,7 @@ class VolleyBallMapH(bs.Map): 'mesh': bs.getmesh('natureBackground'), 'lighting': False, 'background': True, - 'color': (0.5,0.30,0.4) + 'color': (0.5, 0.30, 0.4) }) gnode = bs.getactivity().globalsnode @@ -783,8 +746,6 @@ class VolleyBallMapH(bs.Map): #self.is_hockey = True - - bs._map.register_map(VolleyBallMap) bs._map.register_map(VolleyBallMapH) @@ -798,4 +759,4 @@ class byFreaku(babase.Plugin): # Then why not include function here? # On server upon first launch, plugins are not activated, # (same can be case for user if disabled auto-enable plugins) - pass \ No newline at end of file + pass diff --git a/plugins/utilities/floater.py b/plugins/utilities/floater.py index c05b3a5..28e943e 100644 --- a/plugins/utilities/floater.py +++ b/plugins/utilities/floater.py @@ -1,18 +1,20 @@ # Ported by your friend: Freaku -#Join BCS: +# Join BCS: # https://discord.gg/ucyaesh -#My GitHub: +# My GitHub: # https://github.com/Freaku17/BombSquad-Mods-byFreaku - # ba_meta require api 8 from __future__ import annotations from typing import TYPE_CHECKING -import _babase, babase, random, math +import _babase +import babase +import random +import math import bauiv1 as bui import bascenev1 as bs from bascenev1lib.gameutils import SharedObjects @@ -110,7 +112,8 @@ class Floater(bs.Actor): }) self.node.connectattr('position', self.node2, 'position') - def pop(self): PopupText(text="Ported by \ue048Freaku", scale=1.3, position=(self.node.position[0],self.node.position[1]-1,self.node.position[2]), color=(0,1,1)).autoretain() + def pop(self): PopupText(text="Ported by \ue048Freaku", scale=1.3, position=( + self.node.position[0], self.node.position[1]-1, self.node.position[2]), color=(0, 1, 1)).autoretain() def checkCanControl(self): if not self.node.exists(): @@ -186,7 +189,8 @@ class Floater(bs.Actor): np = self.node.position except: np = (0, 0, 0) - self.b = Bomb(bomb_type=random.choice(['normal', 'ice', 'sticky', 'impact', 'land_mine', 'tnt']), source_player=self.source_player, position=(np[0], np[1] - 1, np[2]), velocity=(0, -1, 0)).autoretain() + self.b = Bomb(bomb_type=random.choice(['normal', 'ice', 'sticky', 'impact', 'land_mine', 'tnt']), + source_player=self.source_player, position=(np[0], np[1] - 1, np[2]), velocity=(0, -1, 0)).autoretain() if self.b.bomb_type in ['impact', 'land_mine']: self.b.arm() @@ -198,7 +202,7 @@ class Floater(bs.Actor): pn = self.node.position dist = self.distance(pn[0], pn[1], pn[2], px, py, pz) self.node.velocity = ((px - pn[0]) / dist, (py - pn[1]) / dist, (pz - pn[2]) / dist) - bs.timer(dist-1, bs.WeakCall(self.move)) #suppress_format_warning=True) + bs.timer(dist-1, bs.WeakCall(self.move)) # suppress_format_warning=True) def handlemessage(self, msg): if isinstance(msg, bs.DieMessage): @@ -211,21 +215,21 @@ class Floater(bs.Actor): super().handlemessage(msg) - - - - def assignFloInputs(clientID: int): activity = bs.get_foreground_host_activity() with activity.context: if not hasattr(activity, 'flo') or not activity.flo.node.exists(): - try: activity.flo = Floater(activity.map.get_def_bound_box('map_bounds')) - except: return #Perhaps using in main-menu/score-screen + try: + activity.flo = Floater(activity.map.get_def_bound_box('map_bounds')) + except: + return # Perhaps using in main-menu/score-screen floater = activity.flo if floater.controlled: - bs.broadcastmessage('Floater is already being controlled', color=(1, 0, 0), transient=True, clients=[clientID]) + bs.broadcastmessage('Floater is already being controlled', + color=(1, 0, 0), transient=True, clients=[clientID]) return - bs.broadcastmessage('You Gained Control Over The Floater!\n Press Bomb to Throw Bombs and Punch to leave!', clients=[clientID], transient=True, color=(0, 1, 1)) + bs.broadcastmessage('You Gained Control Over The Floater!\n Press Bomb to Throw Bombs and Punch to leave!', clients=[ + clientID], transient=True, color=(0, 1, 1)) for i in activity.players: if i.sessionplayer.inputdevice.client_id == clientID: @@ -259,20 +263,32 @@ bui.set_party_icon_always_visible(True) old_piv = bui.set_party_icon_always_visible + + def new_piv(*args, **kwargs): # Do not let chat icon go away old_piv(True) + + bui.set_party_icon_always_visible = new_piv old_fcm = bs.chatmessage + + def new_chat_message(*args, **kwargs): old_fcm(*args, **kwargs) if args[0] == '/floater': - try: assignFloInputs(-1) - except: pass + try: + assignFloInputs(-1) + except: + pass + + bs.chatmessage = new_chat_message # ba_meta export plugin + + class byFreaku(babase.Plugin): - def __init__(self): pass \ No newline at end of file + def __init__(self): pass diff --git a/plugins/utilities/icons_keyboard.py b/plugins/utilities/icons_keyboard.py index bbb48ab..7447660 100644 --- a/plugins/utilities/icons_keyboard.py +++ b/plugins/utilities/icons_keyboard.py @@ -6,8 +6,6 @@ # Double tap the space to change between keyboards... - - # ba_meta require api 8 from __future__ import annotations @@ -19,12 +17,7 @@ import bascenev1 as bs from babase import charstr as uwu if TYPE_CHECKING: - from typing import Any, Optional, Dict, List, Tuple,Type, Iterable - - - - - + from typing import Any, Optional, Dict, List, Tuple, Type, Iterable # ba_meta export keyboard @@ -32,33 +25,33 @@ class IconKeyboard_byFreaku(babase.Keyboard): """Keyboard go brrrrrrr""" name = 'Icons by \ue048Freaku' chars = [(uwu(babase.SpecialChar.TICKET), - uwu(babase.SpecialChar.CROWN), - uwu(babase.SpecialChar.DRAGON), - uwu(babase.SpecialChar.SKULL), - uwu(babase.SpecialChar.HEART), - uwu(babase.SpecialChar.FEDORA), - uwu(babase.SpecialChar.HAL), - uwu(babase.SpecialChar.YIN_YANG), - uwu(babase.SpecialChar.EYE_BALL), - uwu(babase.SpecialChar.HELMET), - uwu(babase.SpecialChar.OUYA_BUTTON_U)), - (uwu(babase.SpecialChar.MUSHROOM), - uwu(babase.SpecialChar.NINJA_STAR), - uwu(babase.SpecialChar.VIKING_HELMET), - uwu(babase.SpecialChar.MOON), - uwu(babase.SpecialChar.SPIDER), - uwu(babase.SpecialChar.FIREBALL), - uwu(babase.SpecialChar.MIKIROG), - uwu(babase.SpecialChar.OUYA_BUTTON_O), - uwu(babase.SpecialChar.LOCAL_ACCOUNT), - uwu(babase.SpecialChar.LOGO)), - (uwu(babase.SpecialChar.TICKET), - uwu(babase.SpecialChar.FLAG_INDIA), - uwu(babase.SpecialChar.OCULUS_LOGO), - uwu(babase.SpecialChar.STEAM_LOGO), - uwu(babase.SpecialChar.NVIDIA_LOGO), - uwu(babase.SpecialChar.GAME_CENTER_LOGO), - uwu(babase.SpecialChar.GOOGLE_PLAY_GAMES_LOGO), - uwu(babase.SpecialChar.EXPLODINARY_LOGO))] + uwu(babase.SpecialChar.CROWN), + uwu(babase.SpecialChar.DRAGON), + uwu(babase.SpecialChar.SKULL), + uwu(babase.SpecialChar.HEART), + uwu(babase.SpecialChar.FEDORA), + uwu(babase.SpecialChar.HAL), + uwu(babase.SpecialChar.YIN_YANG), + uwu(babase.SpecialChar.EYE_BALL), + uwu(babase.SpecialChar.HELMET), + uwu(babase.SpecialChar.OUYA_BUTTON_U)), + (uwu(babase.SpecialChar.MUSHROOM), + uwu(babase.SpecialChar.NINJA_STAR), + uwu(babase.SpecialChar.VIKING_HELMET), + uwu(babase.SpecialChar.MOON), + uwu(babase.SpecialChar.SPIDER), + uwu(babase.SpecialChar.FIREBALL), + uwu(babase.SpecialChar.MIKIROG), + uwu(babase.SpecialChar.OUYA_BUTTON_O), + uwu(babase.SpecialChar.LOCAL_ACCOUNT), + uwu(babase.SpecialChar.LOGO)), + (uwu(babase.SpecialChar.TICKET), + uwu(babase.SpecialChar.FLAG_INDIA), + uwu(babase.SpecialChar.OCULUS_LOGO), + uwu(babase.SpecialChar.STEAM_LOGO), + uwu(babase.SpecialChar.NVIDIA_LOGO), + uwu(babase.SpecialChar.GAME_CENTER_LOGO), + uwu(babase.SpecialChar.GOOGLE_PLAY_GAMES_LOGO), + uwu(babase.SpecialChar.EXPLODINARY_LOGO))] nums = [] - pages: Dict[str, Tuple[str, ...]] = {} \ No newline at end of file + pages: Dict[str, Tuple[str, ...]] = {} diff --git a/plugins/utilities/unlock_TowerD.py b/plugins/utilities/unlock_TowerD.py index 6a219f1..172e8c0 100644 --- a/plugins/utilities/unlock_TowerD.py +++ b/plugins/utilities/unlock_TowerD.py @@ -16,4 +16,4 @@ def new_play_types(cls): # ba_meta export plugin class byFreaku(babase.Plugin): def on_app_running(self): - TowerD.get_play_types = new_play_types \ No newline at end of file + TowerD.get_play_types = new_play_types From fd23e65ed35c6c50b8da84019d30c29de395b5e4 Mon Sep 17 00:00:00 2001 From: Freaku17 Date: Fri, 28 Jul 2023 11:37:11 +0000 Subject: [PATCH 58/60] [ci] apply-version-metadata --- plugins/minigames.json | 42 ++++++++++++++++++++++++++++++++++++------ plugins/utilities.json | 21 ++++++++++++++++++--- 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index c7e2d6d..f9e721d 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -38,7 +38,12 @@ } ], "versions": { - "1.0.0": null + "1.0.0": { + "api_version": 8, + "commit_sha": "7dcf3c7", + "released_on": "28-07-2023", + "md5sum": "cedc448a3d625065d586445e115fcd1f" + } } }, "frozen_one": { @@ -51,7 +56,12 @@ } ], "versions": { - "1.0.0": null + "1.0.0": { + "api_version": 8, + "commit_sha": "7dcf3c7", + "released_on": "28-07-2023", + "md5sum": "529c8b9c9a450317d5aa75e8eab47497" + } } }, "simon_says": { @@ -228,7 +238,12 @@ } ], "versions": { - "2.0.0": null, + "2.0.0": { + "api_version": 8, + "commit_sha": "7dcf3c7", + "released_on": "28-07-2023", + "md5sum": "2c457b80b5a35adf0cad1436af4ab3fe" + }, "1.1.0": { "api_version": 7, "commit_sha": "0bc9522", @@ -247,7 +262,12 @@ } ], "versions": { - "2.0.0": null, + "2.0.0": { + "api_version": 8, + "commit_sha": "7dcf3c7", + "released_on": "28-07-2023", + "md5sum": "49ae645a5afc390ead44d7219b388c78" + }, "1.0.0": { "api_version": 7, "commit_sha": "858030b", @@ -266,7 +286,12 @@ } ], "versions": { - "2.0.0": null, + "2.0.0": { + "api_version": 8, + "commit_sha": "7dcf3c7", + "released_on": "28-07-2023", + "md5sum": "4cb6510f9f3ce151720a53a957986864" + }, "1.0.0": { "api_version": 7, "commit_sha": "858030b", @@ -459,7 +484,12 @@ } ], "versions": { - "2.0.0": null, + "2.0.0": { + "api_version": 8, + "commit_sha": "7dcf3c7", + "released_on": "28-07-2023", + "md5sum": "22b51a147524d84fbc249e61f21ae424" + }, "1.1.0": { "api_version": 7, "commit_sha": "2e2540a", diff --git a/plugins/utilities.json b/plugins/utilities.json index 20d0f71..7efc87e 100644 --- a/plugins/utilities.json +++ b/plugins/utilities.json @@ -296,7 +296,12 @@ } ], "versions": { - "2.0.0": null, + "2.0.0": { + "api_version": 8, + "commit_sha": "7dcf3c7", + "released_on": "28-07-2023", + "md5sum": "31df84f027c98e86336a420aa509e47f" + }, "1.0.0": { "api_version": 7, "commit_sha": "6beb8ddf", @@ -315,7 +320,12 @@ } ], "versions": { - "2.0.0": null, + "2.0.0": { + "api_version": 8, + "commit_sha": "7dcf3c7", + "released_on": "28-07-2023", + "md5sum": "ef2dbcac9190a61753e2c3c0f8afc22c" + }, "1.1.0": { "api_version": 7, "commit_sha": "383f774", @@ -508,7 +518,12 @@ } ], "versions": { - "2.0.0": null, + "2.0.0": { + "api_version": 8, + "commit_sha": "7dcf3c7", + "released_on": "28-07-2023", + "md5sum": "8a63ad58d24e2b61bb63645f74d876e8" + }, "1.0.0": { "api_version": 7, "commit_sha": "b581d90", From 48f930209cede3257ac637e77948ba128137da0c Mon Sep 17 00:00:00 2001 From: ! Freaku <92618708+Freaku17@users.noreply.github.com> Date: Fri, 28 Jul 2023 17:10:17 +0530 Subject: [PATCH 59/60] Fix JSON files --- plugins/minigames.json | 63 ++++++++++++++---------------------------- plugins/utilities.json | 30 ++++++-------------- 2 files changed, 29 insertions(+), 64 deletions(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index f9e721d..5239401 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -34,16 +34,12 @@ "authors": [ { "name": "Freaku", - "email": "" + "email": "", + "discord": "" } ], "versions": { - "1.0.0": { - "api_version": 8, - "commit_sha": "7dcf3c7", - "released_on": "28-07-2023", - "md5sum": "cedc448a3d625065d586445e115fcd1f" - } + "1.0.0": null } }, "frozen_one": { @@ -52,16 +48,12 @@ "authors": [ { "name": "Freaku", - "email": "" + "email": "", + "discord": "" } ], "versions": { - "1.0.0": { - "api_version": 8, - "commit_sha": "7dcf3c7", - "released_on": "28-07-2023", - "md5sum": "529c8b9c9a450317d5aa75e8eab47497" - } + "1.0.0": null } }, "simon_says": { @@ -234,16 +226,12 @@ "authors": [ { "name": "Freaku", - "email": "" + "email": "", + "discord": "" } ], "versions": { - "2.0.0": { - "api_version": 8, - "commit_sha": "7dcf3c7", - "released_on": "28-07-2023", - "md5sum": "2c457b80b5a35adf0cad1436af4ab3fe" - }, + "2.0.0": null, "1.1.0": { "api_version": 7, "commit_sha": "0bc9522", @@ -258,16 +246,12 @@ "authors": [ { "name": "Freaku", - "email": "" + "email": "", + "discord": "" } ], "versions": { - "2.0.0": { - "api_version": 8, - "commit_sha": "7dcf3c7", - "released_on": "28-07-2023", - "md5sum": "49ae645a5afc390ead44d7219b388c78" - }, + "2.0.0": null, "1.0.0": { "api_version": 7, "commit_sha": "858030b", @@ -282,16 +266,12 @@ "authors": [ { "name": "Freaku", - "email": "" + "email": "", + "discord": "" } ], "versions": { - "2.0.0": { - "api_version": 8, - "commit_sha": "7dcf3c7", - "released_on": "28-07-2023", - "md5sum": "4cb6510f9f3ce151720a53a957986864" - }, + "2.0.0": null, "1.0.0": { "api_version": 7, "commit_sha": "858030b", @@ -480,16 +460,12 @@ }, { "name": "Freaku", - "email": "" + "email": "", + "discord": "" } ], "versions": { - "2.0.0": { - "api_version": 8, - "commit_sha": "7dcf3c7", - "released_on": "28-07-2023", - "md5sum": "22b51a147524d84fbc249e61f21ae424" - }, + "2.0.0": null, "1.1.0": { "api_version": 7, "commit_sha": "2e2540a", @@ -698,7 +674,8 @@ "authors": [ { "name": "Freaku", - "email": "" + "email": "", + "discord": "" } ], "versions": { diff --git a/plugins/utilities.json b/plugins/utilities.json index 7efc87e..cc95bfd 100644 --- a/plugins/utilities.json +++ b/plugins/utilities.json @@ -292,16 +292,12 @@ "authors": [ { "name": "Freaku", - "email": "" + "email": "", + "discord": "" } ], "versions": { - "2.0.0": { - "api_version": 8, - "commit_sha": "7dcf3c7", - "released_on": "28-07-2023", - "md5sum": "31df84f027c98e86336a420aa509e47f" - }, + "2.0.0": null, "1.0.0": { "api_version": 7, "commit_sha": "6beb8ddf", @@ -316,16 +312,12 @@ "authors": [ { "name": "Freaku", - "email": "" + "email": "", + "discord": "" } ], "versions": { - "2.0.0": { - "api_version": 8, - "commit_sha": "7dcf3c7", - "released_on": "28-07-2023", - "md5sum": "ef2dbcac9190a61753e2c3c0f8afc22c" - }, + "2.0.0": null, "1.1.0": { "api_version": 7, "commit_sha": "383f774", @@ -514,16 +506,12 @@ "authors": [ { "name": "Freaku", - "email": "" + "email": "", + "discord": "" } ], "versions": { - "2.0.0": { - "api_version": 8, - "commit_sha": "7dcf3c7", - "released_on": "28-07-2023", - "md5sum": "8a63ad58d24e2b61bb63645f74d876e8" - }, + "2.0.0": null, "1.0.0": { "api_version": 7, "commit_sha": "b581d90", From 35193f80c5e0cbe9616ba5df75d13e8df63f7086 Mon Sep 17 00:00:00 2001 From: Freaku17 Date: Fri, 28 Jul 2023 11:40:47 +0000 Subject: [PATCH 60/60] [ci] apply-version-metadata --- plugins/minigames.json | 42 ++++++++++++++++++++++++++++++++++++------ plugins/utilities.json | 21 ++++++++++++++++++--- 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/plugins/minigames.json b/plugins/minigames.json index 5239401..8d698fe 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -39,7 +39,12 @@ } ], "versions": { - "1.0.0": null + "1.0.0": { + "api_version": 8, + "commit_sha": "48f9302", + "released_on": "28-07-2023", + "md5sum": "cedc448a3d625065d586445e115fcd1f" + } } }, "frozen_one": { @@ -53,7 +58,12 @@ } ], "versions": { - "1.0.0": null + "1.0.0": { + "api_version": 8, + "commit_sha": "48f9302", + "released_on": "28-07-2023", + "md5sum": "529c8b9c9a450317d5aa75e8eab47497" + } } }, "simon_says": { @@ -231,7 +241,12 @@ } ], "versions": { - "2.0.0": null, + "2.0.0": { + "api_version": 8, + "commit_sha": "48f9302", + "released_on": "28-07-2023", + "md5sum": "2c457b80b5a35adf0cad1436af4ab3fe" + }, "1.1.0": { "api_version": 7, "commit_sha": "0bc9522", @@ -251,7 +266,12 @@ } ], "versions": { - "2.0.0": null, + "2.0.0": { + "api_version": 8, + "commit_sha": "48f9302", + "released_on": "28-07-2023", + "md5sum": "49ae645a5afc390ead44d7219b388c78" + }, "1.0.0": { "api_version": 7, "commit_sha": "858030b", @@ -271,7 +291,12 @@ } ], "versions": { - "2.0.0": null, + "2.0.0": { + "api_version": 8, + "commit_sha": "48f9302", + "released_on": "28-07-2023", + "md5sum": "4cb6510f9f3ce151720a53a957986864" + }, "1.0.0": { "api_version": 7, "commit_sha": "858030b", @@ -465,7 +490,12 @@ } ], "versions": { - "2.0.0": null, + "2.0.0": { + "api_version": 8, + "commit_sha": "48f9302", + "released_on": "28-07-2023", + "md5sum": "22b51a147524d84fbc249e61f21ae424" + }, "1.1.0": { "api_version": 7, "commit_sha": "2e2540a", diff --git a/plugins/utilities.json b/plugins/utilities.json index cc95bfd..0aabefb 100644 --- a/plugins/utilities.json +++ b/plugins/utilities.json @@ -297,7 +297,12 @@ } ], "versions": { - "2.0.0": null, + "2.0.0": { + "api_version": 8, + "commit_sha": "48f9302", + "released_on": "28-07-2023", + "md5sum": "31df84f027c98e86336a420aa509e47f" + }, "1.0.0": { "api_version": 7, "commit_sha": "6beb8ddf", @@ -317,7 +322,12 @@ } ], "versions": { - "2.0.0": null, + "2.0.0": { + "api_version": 8, + "commit_sha": "48f9302", + "released_on": "28-07-2023", + "md5sum": "ef2dbcac9190a61753e2c3c0f8afc22c" + }, "1.1.0": { "api_version": 7, "commit_sha": "383f774", @@ -511,7 +521,12 @@ } ], "versions": { - "2.0.0": null, + "2.0.0": { + "api_version": 8, + "commit_sha": "48f9302", + "released_on": "28-07-2023", + "md5sum": "8a63ad58d24e2b61bb63645f74d876e8" + }, "1.0.0": { "api_version": 7, "commit_sha": "b581d90",