From ea6f7b80345fdafd6d012fdc9d5818eeeeed2ec8 Mon Sep 17 00:00:00 2001 From: Freaku17 <92618708+Freaku17@users.noreply.github.com> Date: Sun, 6 Feb 2022 11:54:52 +0530 Subject: [PATCH] Add files via upload --- Gamemodes/IcyEmits16.py | 282 +++++++++++++ Gamemodes/VolleyBall.py | 866 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1148 insertions(+) create mode 100644 Gamemodes/IcyEmits16.py create mode 100644 Gamemodes/VolleyBall.py diff --git a/Gamemodes/IcyEmits16.py b/Gamemodes/IcyEmits16.py new file mode 100644 index 0000000..6f34601 --- /dev/null +++ b/Gamemodes/IcyEmits16.py @@ -0,0 +1,282 @@ +#Icy Emits 1.6 +#Made by your friend: @[Just] Freak#4999 / Freaku + +"""Defines dodging icybombs mini-game which spawns below your feet""" + +# ba_meta require api 6 + +from __future__ import annotations + +import random +from typing import TYPE_CHECKING + +import ba +from bastd.actor.bomb import Bomb +from bastd.actor.onscreentimer import OnScreenTimer + +if TYPE_CHECKING: + from typing import Any, Sequence, Optional, List, Dict, Type, Type + +## MoreMinigames.py support ## +randomPic = ['lakeFrigidPreview','hockeyStadiumPreview'] + +def ba_get_api_version(): + return 6 + +def ba_get_levels(): + return [ba._level.Level( + 'Icy Emits',gametype=IcyEmitsGame, + settings={}, + preview_texture_name = random.choice(randomPic))] +## MoreMinigames.py support ## + +class Player(ba.Player['Team']): + """Our player type for this game.""" + + def __init__(self) -> None: + super().__init__() + self.death_time: Optional[float] = None + +class Team(ba.Team[Player]): + """Our team type for this game.""" + + +# ba_meta export game +class IcyEmitsGame(ba.TeamGameActivity[Player, Team]): + """Minigame involving dodging icy bombs""" + + name = 'Icy Emits' + description = 'Beware of the cold platform' + available_settings = [ba.BoolSetting('Epic Mode', default=False)] + scoreconfig = ba.ScoreConfig(label='Survived', + scoretype=ba.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]: + return ['Lake Frigid','Hockey Stadium'] + + # 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 __init__(self, settings: dict): + super().__init__(settings) + + self._epic_mode = settings.get('Epic Mode', False) + self._last_player_death_time: Optional[float] = None + self._meteor_time = 2.0 + self._timer: Optional[OnScreenTimer] = None + + # Some base class overrides: + self.default_music = (ba.MusicType.EPIC + if self._epic_mode else ba.MusicType.SURVIVAL) + if self._epic_mode: + self.slow_motion = True + + def on_begin(self) -> None: + super().on_begin() + + # Drop a wave every few seconds.. and every so often drop the time + # between waves ..lets have things increase faster if we have fewer + # players. + delay = 5.0 if len(self.players) > 2 else 2.5 + if self._epic_mode: + delay *= 0.25 + ba.timer(delay, self._decrement_meteor_time, repeat=True) + + # Kick off the first wave in a few seconds. + delay = 3.0 + if self._epic_mode: + delay *= 0.25 + ba.timer(delay, self._set_meteor_timer) + + self._timer = OnScreenTimer() + self._timer.start() + + # Check for immediate end (if we've only got 1 player, etc). + ba.timer(5.0, self._check_end_game) + + 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', + subs=[('${PLAYER}', player.getname(full=True))]), + color=(0, 1, 0), + ) + # For score purposes, mark them as having died right as the + # game started. + assert self._timer is not None + player.death_time = self._timer.getstarttime() + return + self.spawn_player(player) + + def on_player_leave(self, player: Player) -> None: + # Augment default behavior. + super().on_player_leave(player) + + # A departing player may trigger game-over. + self._check_end_game() + + # overriding the default character spawning.. + def spawn_player(self, player: Player) -> ba.Actor: + spaz = self.spawn_player_spaz(player) + + # Let's reconnect this player's controls to this + # spaz but *without* the ability to attack or pick stuff up. + spaz.connect_controls_to_player(enable_punch=False, + enable_bomb=False, + enable_pickup=False) + + # Also lets have them make some noise when they die. + spaz.play_big_death_sound = True + return spaz + + # Various high-level game events come through this method. + def handlemessage(self, msg: Any) -> Any: + if isinstance(msg, ba.PlayerDiedMessage): + + # Augment standard behavior. + super().handlemessage(msg) + + curtime = ba.time() + + # Record the player's moment of death. + # assert isinstance(msg.spaz.player + msg.getplayer(Player).death_time = curtime + + # In co-op mode, end the game the instant everyone dies + # (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): + # Teams will still show up if we check now.. check in + # the next cycle. + ba.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) + + else: + # Default handler: + return super().handlemessage(msg) + return None + + def _check_end_game(self) -> None: + living_team_count = 0 + for team in self.teams: + for player in team.players: + if player.is_alive(): + living_team_count += 2 + break + + # In co-op, we go till everyone is dead.. otherwise we go + # until one team remains. + if isinstance(self.session, ba.CoopSession): + if living_team_count <= 0: + self.end_game() + else: + if living_team_count <= 1: + self.end_game() + + def _set_meteor_timer(self) -> None: + ba.timer((1.0 + 0.2 * random.random()) * self._meteor_time, + self._drop_bomb_cluster) + + def _drop_bomb_cluster(self) -> None: + + # Random note: code like this is a handy way to plot out extents + # and debug things. + loc_test = False + if loc_test: + ba.newnode('locator', attrs={'position': (8, 6, -5.5)}) + ba.newnode('locator', attrs={'position': (8, 6, -2.3)}) + ba.newnode('locator', attrs={'position': (-7.3, 6, -5.5)}) + ba.newnode('locator', attrs={'position': (-7.3, 6, -2.3)}) + + # Drop several bombs in series. + 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) + ba.timer(delay, ba.Call(self._drop_bomb, pos, vel)) + delay += 0.1 + self._set_meteor_timer() + + def _drop_bomb(self, position: Sequence[float], + velocity: Sequence[float]) -> None: + 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() + + + def _decrement_meteor_time(self) -> None: + self._meteor_time = max(0.01, self._meteor_time * 0.9) + + def end_game(self) -> None: + cur_time = ba.time() + assert self._timer is not None + start_time = self._timer.getstarttime() + + # Mark death-time as now for any still-living players + # and award players points for how long they lasted. + # (these per-player scores are only meaningful in team-games) + for team in self.teams: + for player in team.players: + survived = False + + # Throw an extra fudge factor in so teams that + # didn't die come out ahead of teams that did. + if player.death_time is None: + survived = True + player.death_time = cur_time + 1 + + # Award a per-player score depending on how many seconds + # they lasted (per-player scores only affect teams mode; + # everywhere else just looks at the per-team score). + score = int(player.death_time - self._timer.getstarttime()) + if survived: + score += 50 # A bit extra for survivors. + self.stats.player_scored(player, score, screenmessage=False) + + # Stop updating our time text, and set the final time to match + # exactly when our last guy died. + self._timer.stop(endtime=self._last_player_death_time) + + # Ok now calc game results: set a score for each team and then tell + # the game to end. + results = ba.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. + for team in self.teams: + + # Set the team score to the max time survived by any player on + # that team. + longest_life = 0.0 + for player in team.players: + assert player.death_time is not None + longest_life = max(longest_life, + player.death_time - start_time) + + # Submit the score value in milliseconds. + results.set_team_score(team, int(1000.0 * longest_life)) + + self.end(results=results) diff --git a/Gamemodes/VolleyBall.py b/Gamemodes/VolleyBall.py new file mode 100644 index 0000000..9cdfd70 --- /dev/null +++ b/Gamemodes/VolleyBall.py @@ -0,0 +1,866 @@ +from __future__ import annotations + +#Volley Ball (updated) +#Made for 1.6 by your friend: @[Just] Freak#4999 / Freaku + +"""Defines Volley Ball mini-game""" + + + + +## This thing was originally made for 1.4 by someone (but had errors/bugs/missing features) so I edited/ported to 1.6/added all useful features :D +## I suggest to join this discord servers: +## https://discord.gg/ucyaesh +## https://discord.gg/NCvfPG2N9A + + +## Made on Android with the help of Terminal.py +## https://github.com/Freaku17/BombSquad-Mods-byFreaku/blob/main/Utilities/Terminal.py + + +## MY (Freak's) comments are double-tagged btw ## + +## UPDATED: +""" +- Fixed Puck's mass/size/positions/texture/effects +- Fixed Goal positions +- Better center wall +- Added 1 more map +- Added more customisable options +- Map lights locators are now looped (thus reducing the size of the file and lengthy work...) +- Merged map & minigame in one file +- Puck spawns according to scored team (if right team scored, ball will spawn on left side) +- Also puck now spawns in airrr +- Server support added :) +- Fixed **LOTS** of errors/bugs +""" + + + + + + + + + + +# ba_meta require api 6 + +from typing import TYPE_CHECKING + +import bastd, _ba, ba, random +from bastd.actor.playerspaz import PlayerSpaz +from bastd.actor.scoreboard import Scoreboard +from bastd.actor.powerupbox import PowerupBoxFactory +from bastd.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.""" + + def __init__(self, puck: Puck): + self.puck = puck + + +class Puck(ba.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.8, position[2]) + self.last_players_to_touch: Dict[int, Player] = {} + self.scored = False + assert activity is not None + assert isinstance(activity, VolleyBallGame) + pmats = [shared.object_material, activity.puck_material] + self.node = ba.newnode('prop', + delegate=self, + attrs={ + 'model': activity.puck_model, + 'color_texture': activity.puck_tex, + 'body': 'sphere', + 'reflection': 'soft', + 'reflection_scale': [0.2], + 'shadow_size': 0.6, + 'model_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, 2:1}, False) + ## When other node touches, it realises its new gravity_scale + ## Jugad for now... + + + + + def handlemessage(self, msg: Any) -> Any: + if isinstance(msg, ba.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, ba.OutOfBoundsMessage): + assert self.node + self.node.position = self._spawn_pos + + elif isinstance(msg, ba.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(ba.Player['Team']): + """Our player type for this game.""" + + +class Team(ba.Team[Player]): + """Our team type for this game.""" + + def __init__(self) -> None: + self.score = 0 + + +# ba_meta export game +class VolleyBallGame(ba.TeamGameActivity[Player, Team]): + """Volley Ball game.""" + + name = 'Volley Ball' + description = 'Score some goals.\nbyFREAK' + available_settings = [ + ba.IntSetting( + 'Score to Win', + min_value=1, + default=1, + increment=1, + ), + ba.IntChoiceSetting( + 'Time Limit', + choices=[ + ('None', 0), + ('1 Minute', 60), + ('2 Minutes', 120), + ('5 Minutes', 300), + ('10 Minutes', 600), + ('20 Minutes', 1200), + ], + default=0, + ), + ba.FloatChoiceSetting( + 'Respawn Times', + choices=[ + ('Shorter', 0.25), + ('Short', 0.5), + ('Normal', 1.0), + ('Long', 2.0), + ('Longer', 4.0), + ], + default=1.0, + ), + ba.BoolSetting('Epic Mode', 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), + ] + default_music = ba.MusicType.HOCKEY + + @classmethod + def supports_session_type(cls, sessiontype: Type[ba.Session]) -> bool: + return issubclass(sessiontype, ba.DualTeamSession) + + @classmethod + def get_supported_maps(cls, sessiontype: Type[ba.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.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', ba.DieMessage()))) + self._score_region_material = ba.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.add_actions( + + actions=( + ('modify_part_collision', 'friction', 100000), + )) + self._wall_material.add_actions( + conditions=('they_have_material', shared.pickup_material), + actions=( + ('modify_part_collision', 'collide', False), + )) + + self._wall_material.add_actions( + conditions=(('we_are_younger_than', 100), + '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), + actions=( + ('modify_part_collision', 'friction', 9999.5), + )) + self._wall_material.add_actions( + conditions=('they_have_material', bastd.actor.bomb.BombFactory.get().blast_material), + 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._net_wall_material=ba.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( + conditions=('they_have_material', shared.object_material), + actions=( + ('modify_part_collision', 'collide', True), + )) + self._net_wall_material.add_actions( + conditions=('they_have_material', self.puck_material), + actions=( + ('modify_part_collision', 'collide', True), + )) + self._net_wall_material.add_actions( + conditions=('we_are_older_than', 1), + actions=( + ('modify_part_collision', 'collide', True), + )) + self.net_blocc=[] + + + self._puck_spawn_pos: Optional[Sequence[float]] = None + self._score_regions: Optional[List[ba.NodeActor]] = None + self._puck: Optional[Puck] = None + self._score_to_win = int(settings['Score to Win']) + self._punchie_ = bool(settings['Disable Punch']) + self._night_mode = bool(settings['Night Mode']) + self._bombies_ = bool(settings['Disable Bombs']) + self._time_limit = float(settings['Time Limit']) + self._icy_flooor = bool(settings['Icy Floor']) + self.credit_text = bool(settings['Enable Bottom Credits']) + 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) + + 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) + if self._night_mode: + ba.getactivity().globalsnode.tint = (0.5, 0.7, 1) + else: + pass + 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( + ba.NodeActor( + ba.newnode('region', + attrs={ + 'position':(5,0,0), + 'scale': defs.boxes['goal1'], + 'type': 'box', + 'materials': [self._score_region_material] + }))) + self._score_regions.append( + ba.NodeActor( + ba.newnode('region', + attrs={ + 'position':(-5,0,0), + 'scale': defs.boxes['goal2'], + 'type': 'box', + 'materials': [self._score_region_material] + }))) + self._update_scoreboard() + ba.playsound(self._chant_sound) + import base64 + exec(base64.b64decode("aWYgc2VsZi5jcmVkaXRfdGV4dDoKICAgICMjIFBlb3BsZSBzdGVhbGVkIGNyZWRpdHMgc28gdGhhdHMgd2h5IEkgZW5jb2RlZCB0aGlzLi4uCiAgICAjIyBFdmVuIHRobyB0aGVyZSBpcyBhIG9wdGlvbiwgdGhleSBjaGFuZ2VkIGNyZWF0ZWQgYnkKICAgICMjIGxpa2Ugd3RmIGlzIHRoaWVyIHByb2JsZW0/PwogICAgCiAgICAjIyBBbnl3YXlzIGhhdmUgYSBnb29kIGRheSEKICAgIHQgPSBiYS5uZXdub2RlKCd0ZXh0JywKICAgICAgICAgICAgICAgYXR0cnM9eyAndGV4dCc6IkNyZWF0ZWQgYnkg7oCgRlJFw4JLL+6BiEZyZWFrdVxuVm9sbGV5QmFsbCAxLjYiLCAjIyBEaXNhYmxlICdFbmFibGUgQm90dG9tIENyZWRpdHMnIHdoZW4gbWFraW5nIHBsYXlsaXN0LCBObyBuZWVkIHRvIGVkaXQgdGhpcyBsb3ZlbHkuLi4KICAgICAgICAnc2NhbGUnOjAuNywKICAgICAgICAncG9zaXRpb24nOigwLDApLCAjTGV0cyBob3BlIGhlIHVzZXMgVFYgYm9yZGVyIG9mIHNldHRpbmdzPkdyYXBoaWNzCiAgICAgICAgJ3NoYWRvdyc6MC41LAogICAgICAgICdmbGF0bmVzcyc6MS4yLAogICAgICAgICdjb2xvcic6KDEsIDEsIDEpLAogICAgICAgICdoX2FsaWduJzonY2VudGVyJywKICAgICAgICAndl9hdHRhY2gnOidib3R0b20nfSk=").decode('UTF-8')) + shared = SharedObjects.get() + self.blocks.append(ba.NodeActor(ba.newnode('region',attrs={'position': (0,2.4,0),'scale': (1,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, )}))) + + def on_team_join(self, team: Team) -> None: + self._update_scoreboard() + + def _handle_puck_player_collide(self) -> None: + collision = ba.getcollision() + try: + puck = collision.sourcenode.getdelegate(Puck, True) + player = collision.opposingnode.getdelegate(PlayerSpaz, + True).getplayer( + Player, True) + except ba.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 = ba.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 + + + + ## Spawn puck on opponent's Area + if team.id == 0: # left side scored + self._puck_spawn_pos= (5, -0.3, 0) + elif team.id == 1: # right side scored + self._puck_spawn_pos= (-5, -0.3, 0) + else: # incase, this dude is oversmart and using 3+ teams... + self._puck_spawn_pos= (0, 0.2, 0) + ## Easy pizzy + + + for player in team.players: + if player.actor: + player.actor.handlemessage(ba.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() + + ba.playsound(self._foghorn_sound) + ba.playsound(self._cheer_sound) + + 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) + + + ba.cameraflash(duration=7.0) + self._update_scoreboard() + + def end_game(self) -> None: + results = ba.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() + if self._icy_flooor: + activity.map.is_hockey = True + else: + return + + def _update_scoreboard(self) -> None: + winscore = self._score_to_win + for team in self.teams: + self._scoreboard.set_team_value(team, team.score, winscore) + + # overriding the default character spawning.. + def spawn_player(self, player: Player) -> ba.Actor: + spaz = self.spawn_player_spaz(player) + + if self._bombies_: + ## We wantthe button to work, justno bombs... + spaz.bomb_count = 0 + ## Imagine not being able to swipe those colorful buttons ;( + + + if self._punchie_: + spaz.connect_controls_to_player(enable_punch=False) + + return spaz + + def handlemessage(self, msg: Any) -> Any: + + # Respawn dead players if they're still in the game. + if isinstance(msg, ba.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(): + ba.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') + + def _spawn_puck(self) -> None: + ba.playsound(self._swipsound) + ba.playsound(self._whistle_sound) + self._flash_puck_spawn() + assert self._puck_spawn_pos is not None + self._puck = Puck(position=self._puck_spawn_pos) + + +## Can be done: +# Add a return timer and reset it when ball goes from one area to other (i.e Left/Right) To avoid people camping with the Ball in thier own area... + + + + + + + + + + + + + + + + + + +####### DONT DIE READING THIS ######### + +## The reason I made maps differently (instead of keeping it in minigame only) was to avoid getting some jittery starts... ## + + + +a=0.0 +class Pointzz: + points, boxes = {}, {} + points['ffa_spawn1'] = (-0.08016, 0.02275, -4.37367) + (8.89506, 0.05, 0.44435) + points['ffa_spawn2'] = (-0.08016, 0.02275, 4.07629) + (8.89506, 0.05, 0.44435) + points['flag1'] = (-10.72073, 0.06537, 0.14648) + points['flag2'] = (10.7587, 0.04779, 0.14648) + points['flag_default'] = (-0.10014, 0.0418, 0.10956) + points['powerup_spawn1'] = (500000000.41468, 50000.9515, -500000.03791) + points['powerup_spawn2'] = (-500000.5554, 500000.9515, -500000.03791) + points['powerup_spawn3'] = (500000.41468, 50000.9515, 5000.14822) + points['powerup_spawn4'] = (-50000.73727, 50000.9515, 500.14822) + 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['tnt1'] = (-0.10387, 0.41333, 0.42947) + (0, 0, 0) + (22.48296, 1.29024, 8.99025) + boxes['goal1'] = (10,0.001,8) + boxes['goal2'] = (10,0.001,8) + boxes['map_bounds'] = (0.0, 1.185751251, 0.4326226188) + (0.0, 0.0, 0.0) + ( + 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) + points['ffa_spawn1'] = (-0.001925625146, 0.02305323209, + -3.81971842) + (7.828121539, 1.0, 0.1588021252) + points['ffa_spawn2'] = (-0.001925625146, 0.02305323209, + 3.560115735) + (7.828121539, 1.0, 0.05859841271) + points['flag1'] = (-11.21689747, 0.09527878981, -0.07659307272) + points['flag2'] = (11.08204909, 0.04119542459, -0.07659307272) + points['flag_default'] = (-0.01690735171, 0.06139940044, -0.07659307272) + boxes['goal1'] = (10,0.001,8) + boxes['goal2'] = (10,0.001,8) + boxes['map_bounds'] = (0.0, 0.7956858119, -0.4689020853) + (0.0, 0.0, 0.0) + ( + 35.16182389, 12.18696164, 21.52869693) + points['powerup_spawn1'] = (-3.654355317, 1.080990833, -4.765886164) + points['powerup_spawn2'] = (-3.654355317, 1.080990833, 4.599802158) + points['powerup_spawn3'] = (2.881071011, 1.080990833, -4.765886164) + points['powerup_spawn4'] = (2.881071011, 1.080990833, 4.599802158) + 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) + points['tnt1'] = (-0.05791962398, 1.080990833, -4.765886164) + +class VolleyBallMap(ba.Map): + from VolleyBall import Pointzz as defs + name = "Open Field" + + @classmethod + def get_play_types(cls) -> List[str]: + """Return valid play types for this map.""" + return [] + + @classmethod + def get_preview_texture_name(cls) -> str: + return 'footballStadiumPreview' + + @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') + } + 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]}) + 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 + + + + 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 + + + + self.node = ba.newnode( + 'terrain', + delegate=self, + attrs={ + 'model': self.preloaddata['model'], + 'collide_model': self.preloaddata['collide_model'], + 'color_texture': self.preloaddata['tex'], + 'materials': [shared.footing_material] + }) + ba.newnode('terrain', + attrs={ + 'model': self.preloaddata['vr_fill_model'], + 'lighting': False, + 'vr_only': True, + 'background': True, + 'color_texture': self.preloaddata['tex'] + }) + gnode = ba.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) + gnode.vignette_inner = (0.9, 0.9, 0.9) + gnode.vr_camera_offset = (0, -0.8, -1.1) + gnode.vr_near_clip = 0.5 + + def is_point_near_edge(self, + point: ba.Vec3, + running: bool = False) -> bool: + box_position = self.defs.boxes['edge_box'][0:3] + box_scale = self.defs.boxes['edge_box'][6:9] + xpos = (point.x - box_position[0]) / box_scale[0] + zpos = (point.z - box_position[2]) / box_scale[2] + return xpos < -0.5 or xpos > 0.5 or zpos < -0.5 or zpos > 0.5 + +class VolleyBallMapH(ba.Map): + """Stadium map used for ice hockey games.""" + + from VolleyBall import PointzzforH as defs + name = 'Closed Arena' + + @classmethod + def get_play_types(cls) -> List[str]: + """Return valid play types for this map.""" + return [] + + @classmethod + def get_preview_texture_name(cls) -> str: + return 'hockeyStadiumPreview' + + @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'), + } + mat = ba.Material() + mat.add_actions(actions=('modify_part_collision', 'friction', 0.01)) + data['ice_material'] = mat + return data + + def __init__(self) -> None: + 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]}) + 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 + + + + 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 + + + + self.node = ba.newnode('terrain', + delegate=self, + attrs={ + 'model': + None, + 'collide_model': + ba.getcollidemodel('footballStadiumCollide'), ## we dont want Goalposts... + 'color_texture': + self.preloaddata['tex'], + 'materials': [ + shared.footing_material] + }) + ba.newnode('terrain', + attrs={ + 'model': self.preloaddata['vr_fill_model'], + 'vr_only': True, + 'lighting': False, + 'background': True, + }) + mats = [shared.footing_material] + self.floor = ba.newnode('terrain', + attrs={ + 'model': self.preloaddata['models'][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) + }) + + self.background = ba.newnode( + 'terrain', + attrs={ + 'model': ba.getmodel('natureBackground'), + 'lighting': False, + 'background': True, + 'color': (0.5,0.30,0.4) + }) + + gnode = ba.getactivity().globalsnode + gnode.floor_reflection = True + gnode.debris_friction = 0.3 + gnode.debris_kill_height = -0.3 + gnode.tint = (1.2, 1.3, 1.33) + gnode.ambient_color = (1.15, 1.25, 1.6) + gnode.vignette_outer = (0.66, 0.67, 0.73) + gnode.vignette_inner = (0.93, 0.93, 0.95) + gnode.vr_camera_offset = (0, -0.8, -1.1) + gnode.vr_near_clip = 0.5 + #self.is_hockey = True + + +## Plugin only for our dirty map UwU ## + +# ba_meta export plugin +class byFreaku(ba.Plugin): + def on_app_launch(self): + ba._map.register_map(VolleyBallMap) + ba._map.register_map(VolleyBallMapH)