From 7c718cf4a345bfc05deda459756779025942040f Mon Sep 17 00:00:00 2001 From: Loup <90267658+Loup-Garou911XD@users.noreply.github.com> Date: Mon, 1 Jun 2026 08:21:09 +0530 Subject: [PATCH] Revert "Volley Punch" This reverts commit f6c0fd5fbe5f491fa365cc34d1a3117e562b400c. --- plugins/minigames.json | 19 - plugins/minigames/volley_punch.py | 1293 ----------------------------- 2 files changed, 1312 deletions(-) delete mode 100644 plugins/minigames/volley_punch.py diff --git a/plugins/minigames.json b/plugins/minigames.json index 9ba5818a..969670f2 100644 --- a/plugins/minigames.json +++ b/plugins/minigames.json @@ -1663,25 +1663,6 @@ "md5sum": "33e6b93420cf6115e992aca534d76bfd" } } - }, - "volley_punch": { - "description": "Have fun with your friends in this new volley game !", - "external_url": "https://github.com/Scriptz1/Learn.py-Installer/blob/main/volleypunch.py", - "authors": [ - { - "name": "Learn.py", - "email": "phillipians36@gmail.com", - "discord": "Learning .py" - } - ], - "versions": { - "1.0.0": { - "api_version": 9, - "commit_sha": "576a9c0", - "released_on": "01-06-2026", - "md5sum": "be998b599896ed0e8dd5f2545fae6173" - } - } } } } \ No newline at end of file diff --git a/plugins/minigames/volley_punch.py b/plugins/minigames/volley_punch.py deleted file mode 100644 index c19e2694..00000000 --- a/plugins/minigames/volley_punch.py +++ /dev/null @@ -1,1293 +0,0 @@ -# VolleyPunch ? ig i'll name it like that - -# Made by Learn.py -# but this was def inspired by some freaky guy - - -# ba_meta require api 9 - -from __future__ import annotations - -from typing import TYPE_CHECKING - -import babase -import _babase -import math -import random -import bascenev1 as bs -import bauiv1 as bui -import math -import time -import babase -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 - - -plugman = dict( - plugin_name="volley_punch", - description="Have fun with your friends in this new volley game !", - external_url="https://github.com/Scriptz1/Learn.py-Installer/blob/main/volleypunch.py", - authors=[ - {"name": "Learn.py", "email": "phillipians36@gmail.com", "discord": "Learning .py"}, - ], - version="1.0.0", -) - - -class PuckDiedMessage: - """Inform something that a puck has died.""" - - def __init__(self, puck: Puck): - self.puck = puck - - -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.05, position[2]) - self.last_players_to_touch: Dict[int, Player] = {} - self.scored = False - - self.touches = 0 - assert activity is not None - assert isinstance(activity, VolleyBallGame) - pmats = [shared.object_material, activity.puck_material] - - # so this is the volleyball we gonna mesh with today - 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.3, - 'mesh_scale': activity.ball_size, - 'body_scale': 1.07, - 'gravity_scale': 1, - 'is_area_of_interest': True, - 'position': self._spawn_pos, - 'materials': pmats - }) - - 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. - # copied that stuff from hockey game ngl - 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 VolleyBallGame(bs.TeamGameActivity[Player, Team]): - name = 'VolleyPunch' - description = 'Punch the Volleyball !' - available_settings = [ - bs.IntSetting( - 'Score to Win', - 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.FloatSetting( - 'Ball size (m)', - min_value=0.15, - default=0.25, - max_value=0.35, - increment=0.05, - ), - bs.FloatChoiceSetting( - 'Ball Average Speed', - choices=[ - ('Slower', 0.9899), - ('Normal', 1.0), - ], - default=1.0, - ), - bs.BoolSetting('Epic Mode', False), - bs.BoolSetting('Enable Credits', True), - ] - 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.one_sound = bs.getsound('announceOne') - self.two_sound = bs.getsound('announceTwo') - self.three_sound = bs.getsound('announceThree') # unused.. yet - self._swipsound = bs.getsound('swip') - self._whistle_sound = bs.getsound('refWhistle') - self.puck_mesh = bs.getmesh('shield') - self.puck_tex = bs.gettexture('ouyaUButton') - self._puck_sound = bs.getsound('metalHit') - self.puck_material = bs.Material() - self.puck_material.add_actions(actions=(('modify_part_collision', - 'friction', 4))) - 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), - ('modify_part_collision', 'physical', False))) - - # 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._fake_wall_material = bs.Material() # i'll fix this. trust - - self._net_wall_material = bs.Material() - self._net_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_material.add_actions( - conditions=('they_have_material', shared.object_material), - actions=( - ('modify_part_collision', 'collide', True), - ('modify_part_collision', 'physical', True), - ('modify_part_collision', - 'friction', -10), - ('call', 'at_connect', self.slow_down))) - - 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.credit_text = bool(settings['Enable Credits']) # i did the freaku credit thing - self._epic_mode = bool(settings['Epic Mode']) - - # the ball is too fast for the players and the map is soo huge its a good poc - brostos - self.ball_size = float(settings['Ball size (m)']) - self.ball_speed = float(settings['Ball Average Speed']) - - # 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.s: list = [] - self.w: list = [] - self.n: list = [] - self.last_interaction_time = -9999 - self.smashed = -9999 - self.interactions_timer = None - self.curve = True - self.difficulty = 0.5 - self.smasher = None - self.commentary_text = None - self._text_task = None # Référence pour annuler l'animation en cours - self._clear_timer = None # Référence pour le timer de disparition - self.touches_indicator = None - self.guide = None - self.curving = False - - 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._puck_spawn_pos = (-4, 1, 0) if random.random() < 0.5 else (4, 1, 0) - self._spawn_puck() - - # Set up the two score regions. - self._score_regions = [] - self.commentary_text = bs.newnode( - 'text', - attrs=dict( - text='', - scale=0.012, - position=(0, 3.1, -5.8), - in_world=True, - flatness=1, - shadow=0, - color=(1, 1, 1, 0.5), - h_align='center', - v_align='top', - h_attach='center', - v_attach='top', - )) - self.touches_indicator = bs.newnode( - 'text', - attrs=dict( - text='', - scale=0.025, - position=(0, 3, -5.8), - in_world=True, - flatness=1, - shadow=0, - color=(1, 1, 1, 0.5), - h_align='center', - v_align='top', - h_attach='center', - v_attach='top', - )) - self.guide = bs.newnode( - 'text', - attrs=dict( - text='PUNCH TO TAP THE BALL \nPICKUP TO CUFF \nBOMB TO GLIDE / DIVE \nJUMP UNDER A MID AIR BALL WITH THE BAR FILLED TO SMASH \nTHE ULT BAR FILLS AS YOU PLAY', - scale=0.005, - position=(0, 2.7, -5.8), - in_world=True, - flatness=1, - shadow=0, - color=(1, 1, 1, 0.5), - h_align='center', - v_align='top', - h_attach='center', - v_attach='top', - )) - bs.animate_array(self.guide, 'color', 4, {0: (1, 1, 1, 0.5), 1: ( - 1, 1, 1, 1), 2: (1, 1, 1, 0.5)}, loop=True) - self.interactions_timer = bs.Timer( - 1 / 120, self.interactions, repeat=True) # time, function, repeat - self._score_regions.append( - bs.NodeActor( - bs.newnode('region', - attrs={ - 'position': (9, 0, 0), - 'scale': (17.3, 0.002, 12), - 'type': 'box', - 'materials': [self._score_region_material] - }))) - self._score_regions.append( - bs.NodeActor( - bs.newnode('region', - attrs={ - 'position': (-9, 0, 0), - 'scale': (17.3, 0.002, 20), - 'type': 'box', - 'materials': [self._score_region_material] - }))) - self._update_scoreboard() - self._chant_sound.play() - if self.credit_text: - t = bs.newnode('text', - attrs={'text': "Created by Learn.py", - 'scale': 0.7, - 'position': (0, 0), - 'shadow': 0.5, - 'flatness': 1.2, - 'color': (1, 1, 1), - 'h_align': 'center', - 'v_attach': 'bottom'}) - - # Create the net and regions. - mat = bs.Material() # spam this whenever u want a material THEN add some properties - mat.add_actions(actions=('modify_part_collision', - 'collide', False)) - net = bs.newnode( - 'prop', - attrs={ - 'body': 'puck', - 'body_scale': 0, - 'position': (0, 0, 0), - 'mesh_scale': 1, - 'mesh': bs.getmesh('volleyball_net'), - 'color_texture': bs.gettexture('black'), - 'reflection': 'soft', - 'reflection_scale': [1.5], - 'sticky': False, - 'shadow_size': 0.2, - 'gravity_scale': 0, - 'materials': [mat], - }, - ) - - self.s.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.w.append(bs.NodeActor(bs.newnode('region', attrs={'position': (0, 0, 0), 'scale': ( - 0.6, 10, 20), 'type': 'box', 'materials': (self._net_wall_material, )}))) - self.n.append(bs.NodeActor(bs.newnode('region', attrs={'position': (0, 0, 0), 'scale': ( - 0.6, 2.75, 20), 'type': 'box', 'materials': (self._net_material, )}))) - self.n.append(bs.NodeActor(bs.newnode('region', attrs={'position': (0, 0, -5.9), 'scale': ( - 20, 20, 0.8), 'type': 'box', 'materials': (self._net_wall_material, self._net_material)}))) - self.n.append(bs.NodeActor(bs.newnode('region', attrs={'position': (0, 0, 5.9), 'scale': ( - 20, 20, 0.8), 'type': 'box', 'materials': (self._net_wall_material, self._net_material)}))) - - def slow_down(self): - if not self._puck: - return - puck_node = self._puck.node - mult = 0.88 - v = puck_node.velocity - puck_node.velocity = (v[0] * mult, v[1] * mult, v[2] * mult) - - def write(self, text, color): - """types""" - if hasattr(self, '_timers'): - for t in self._timers: - t = None - self._timers = [] - - if not text: - return - - self.commentary_text.color = color - total_chars = len(text) - - interval = 0.9 / max(total_chars, 1) - - for i in range(1, total_chars + 1): - def show(index=i): - if self.commentary_text.exists(): - self.commentary_text.text = text[:index] - - self._timers.append(bs.Timer(interval * i, show, repeat=False)) - - def start_clear(): - for i in range(total_chars, -1, -1): - def hide(index=i): - if self.commentary_text.exists(): - self.commentary_text.text = text[:index] - - self._timers.append( - bs.Timer(0.9 + 3.0 + (0.015 * (total_chars - i)), hide, repeat=False)) - - start_clear() - - def vignette(self, final_color, longer): - """Aesthetic reasons.""" - glb = bs.getactivity().globalsnode - base_color = (0.57, 0.57, 0.57) - bs.animate_array(glb, 'vignette_outer', 3, {0: base_color, 0.1: ( - final_color[0] / 1.2, final_color[1] / 1.2, final_color[2] / 1.2), (1 if longer else 0.5): base_color}) - - def interactions(self): - """Some personalized stuff and my deepest secrets. - I don't know why, but I feel SoK may like this.""" - if self._puck is None: - return - - vel = self._puck.node.velocity - # apply the mult - self._puck.node.velocity = ( - vel[0], - vel[1] * self.ball_speed, - vel[2] - ) - - green = bs.gettexture('ouyaOButton') - yellow = bs.gettexture('ouyaYButton') - red = bs.gettexture('ouyaAButton') - blue = bs.gettexture('ouyaUButton') - - # If it passes the middle.. green. - puck_node = self._puck.node - pos = puck_node.position - x_diff = abs(pos[0]) - - if x_diff < 0.25 or self.curve: - puck_node.color_texture = blue - self._puck.touches = 0 - - if pos[1] < 2.6 and (bs.time() - self.last_interaction_time > 0.5): - mult = 0.935 - v = puck_node.velocity - puck_node.velocity = (v[0] * mult, v[1] * mult, v[2] * mult) - - self.save_text = random.choice([ - "dived to the rescue!", - "kept the ball alive!", - "flew in to save the day!", - "is too fast for the floor!", - "bounced it back just in time!", - "kept the dream alive!", - "barely missed the ground!", - "saved the rally!", - "made a clutch save!", - "refused to let it drop!", - "pulled a superman save!", - "made a desperate save!", - "proved the floor is not an option!", - "landed a miracle touch!", - "saved the point!", - "pulled off a heroic dive!", - "stretched to the limit!", - "barely kept it up!", - "showed reflexes of a cat!", - "denied the floor!", - "made a clutch save!", - "is staying in the game!", - "pulled an epic recovery!", - "reacted in the nick of time!", - "won't let the ball drop!", - "is pure hustle!", - "made an impossible save!", - "is defying gravity!", - "made sure the ground stays empty!", - "saved it!", - "pulled off last-second magic!", - "is floating to save it!", - "is too clutch to fail!", - "got the ball back in the air!", - "is denying the dirt!", - "saved it by a hair!", - "is fighting for every ball!", - "is pure energy!", - "never gives up!", - "keeps it in play!", - "saved it barely!", - "kept the floor clean!", - "is pure determination!", - "pulled a miraculous save!", - "denied the game over!", - "is still alive!", - "is keeping the rally going!", - "made an out-of-reach save!", - "made a ninja-like save!", - "bounced back from trouble!"]) - self.hit_text = random.choice([ - "sent it over!", - "cleared the net!", - "powered it across!", - "nailed a deep shot!", - "bounced it into their zone!", - "launched an attack!", - "sent a rocket over!", - "is dominating the net!", - "found the open spot!", - "placed it perfectly!", - "smashed it back!", - "is applying the pressure!", - "sent them scrambling!", - "over the net it goes!", - "hit a beauty!", - "is controlling the court!", - "forced a tough return!", - "keeps the pressure high!", - "landed a sweet strike!", - "sent it deep!", - "is playing aggressively!", - "hit a laser beam!", - "made a solid connection!", - "is taking charge!", - "sent a tricky shot over!", - "is firing back!", - "put it right on target!", - "sent the ball flying!", - "beat the defense!", - "is crushing it!", - "nailed that serve return!", - "showed off some power!", - "sent a high arc over!", - "is making moves!", - "kept them on their toes!", - "delivered a powerful hit!", - "is pushing the pace!", - "found the gap!", - "sent a curveball over!", - "is looking sharp!", - "hit it with precision!", - "made them work for it!", - "is owning the net!", - "sent a heavy strike!", - "is dictating the play!", - "put it out of reach!", - "landed the perfect hit!", - "is on fire!", - "sent a swift strike!", - "is forcing errors!" - ]) - self.control_text = random.choice([ - "is showing off sweet control!", - "has the ball on a string!", - "handles it with grace!", - "shows off some nice touch!", - "keeps it close and tight!", - "is demonstrating perfect poise!", - "has ice in their veins!", - "is keeping it under control!", - "shows a velvet touch!", - "is masterfully handling the ball!", - "keeps the ball glued to them!", - "is displaying total composure!", - "makes it look so easy!", - "is controlling the pace!", - "shows off pure finesse!", - "has the ball perfectly placed!", - "is staying cool under pressure!", - "has incredible ball handling!", - "is maneuvering with ease!", - "keeps the ball within reach!", - "shows off some fancy footwork!", - "is keeping the ball calm!", - "has the softest touch!", - "is dictating the rhythm!", - "keeps it balanced and steady!", - "is showing high-level control!", - "has the situation handled!", - "is playing with surgical precision!", - "keeps the ball in their zone!", - "shows off expert handling!", - "is keeping it smooth!", - "has the ball right where they want it!", - "demonstrates a gentle touch!", - "is keeping the game slow!", - "shows off calm concentration!", - "has everything under control!", - "is moving with grace!", - "keeps the ball softly hovering!", - "shows off true talent!", - "is maintaining perfect flow!", - "has a magical touch!", - "is playing it smart!", - "keeps the ball very close!", - "shows off professional control!", - "is handling the pressure well!", - "has a very steady hand!", - "is keeping it precise!", - "shows off masterful technique!", - "is keeping the ball in check!", - "has the perfect feel for it!" - ]) - if self.touches_indicator is not None and self.touches_indicator.exists(): - self.touches_indicator.position = (self._puck.node.position[0], self._puck.node.position[1] + 0.35, - self._puck.node.position[2]) - else: - self.touches_indicator = bs.newnode( - 'text', - attrs=dict( - text='', - scale=0.025, - position=(0, 3, -5.8), - in_world=True, - flatness=1, - shadow=0, - color=(1, 1, 1, 0.5), - h_align='center', - v_align='top', - h_attach='center', - v_attach='top', - )) - - everything = bs.getnodes() - everyone = [] - closest_distance = 9999 - closest_player = None - - # i won't explain what "curve" is... look by yourself - if not self.curve and not self._puck.scored: - if bs.time() < self.smashed: - random_pos = (random.uniform( - 0.1, 0.7) + self._puck.node.position[0], self._puck.node.position[1], random.uniform(0.1, 0.7) + self._puck.node.position[2]) - e = bs.newnode( - 'explosion', - attrs={ - 'position': random_pos, - 'color': self.smasher.color, - 'radius': random.uniform(0.1, 0.7), - 'big': False, - } - ) - bs.timer(1, e.delete) - self.smasher.getdelegate(object).percentage /= 1.1 - else: - ball_tex = self._puck.node.color_texture - - texture_to_name = { - green: 'green', - yellow: 'yellow', - red: 'red', - blue: 'blue' - } - - colors = { - 'green': (0.6, 1, 0.6), - 'yellow': (1, 0.3, 0), - 'red': (1, 0, 0), - 'blue': (0.6, 0.6, 1) - } - - color_name = texture_to_name.get(ball_tex) - color = colors.get(color_name) - - e = bs.newnode( - 'explosion', - attrs={ - 'position': self._puck.node.position, - 'color': color, - 'radius': 0.1, - 'big': False, - } - ) - indicator_color = (*color, 0.5) - bs.timer(1, e.delete) - self.touches_indicator.color = indicator_color - self.touches_indicator.text = str(3 - self._puck.touches) - - for human in everything: # doesn't make much sense, but I hope u understand I want players nodes. - if human.getnodetype() == "spaz": - everyone.append(human) - - for player_node in everyone: - if not player_node.exists(): # why wouldn't u exist at first - continue - - # not wanting to do that Euclidean thingy - distance = math.dist(player_node.position, self._puck.node.position) - player_node.hold_node = None - player_node.getdelegate(object).impact_scale = 0 - if distance < closest_distance: - closest_player = player_node # him, the closest one - closest_distance = distance # his distance with the volleyball - - good: bool = (self._puck.touches < 3 and - bs.time() - self.last_interaction_time > 0.4 and - not self._puck.scored) - # bs.time() is the current bombsquad time :) bs for bombsquad. - - delegate = closest_player.getdelegate(object) - now = bs.time() - can_jump = (delegate.last_jump_time_ms > - delegate._jump_cooldown and closest_player.position[1] < 1) - - if closest_player.jump_pressed and can_jump: - ppos = closest_player.position - delegate.last_jump_time_ms = int(bs.time() * 1000) - closest_player.handlemessage( - 'kick_back', - ppos[0], - ppos[1], - ppos[2], - 0, - 1, - 0, - 50, # small force - ) - - punched = now < delegate.punched - pickup = now < delegate.pickup - bombed = now < delegate.bombed - curved = now < delegate.curved - - # SO if broski is the nearest AND broski is near enough... - if closest_player and closest_distance < 4 and good: - player = spaz = delegate - ball = self._puck.node # ball node - you = closest_player.position # already a node - in_air = (you[1] > 0.8) - # Ball goes where you look but always tries to go to the other side. (tell me if u guys want it to go totally where you're looking at) - if closest_distance < (1.35 if not in_air else 1.6) and (closest_player.punch_pressed or punched): - self.difficulty += 0.6 / 75 - e = bs.newnode( - 'explosion', - attrs={ - 'position': self._puck.node.position, - 'color': closest_player.color, - 'radius': 0.8, - 'big': False, - } - ) - bs.timer(1, e.delete) - self.last_interaction_time = bs.time() - self._puck.touches += 1 - self.curve = False - if self._puck.touches == 2: - spaz.percentage = min(spaz.percentage + 8, 100) - ball.color_texture = yellow - self.two_sound.play() - elif self._puck.touches == 3: - spaz.percentage = min(spaz.percentage + 12, 100) - ball.color_texture = red - self.one_sound.play() - else: - ball.color_texture = green - # This is for the sound, you probably didn't know that! - bs.getsound("impactHard").play() - - sight = (bs.Vec3(you) - bs.Vec3(closest_player.position_forward) - ).normalized() * (12 if delegate.percentage < 95 else 30) # Sight factor - speed = 6 if delegate.percentage < 95 else 20 # bar full - - if curved: - start_pos = ball.position - end_pos = (sight[0] * 2, -1, -sight[2]) - duration = 1.1 - fps = 144 - total_steps = int(duration * fps) - curved_time = bs.time() + 0.15 - self.curving = True - - z_offset = -4.0 if sight[0] < 0 else 4.0 - - def move_to_point(step): - if not ball.exists(): - return - if ball.position[1] < 1 and bs.time() > curved_time: - return - if not self.curving: - return - - t = step / total_steps - - x = start_pos[0] + (end_pos[0] - start_pos[0]) * t - y = start_pos[1] + (end_pos[1] - start_pos[1]) * t - z = start_pos[2] + (end_pos[2] - start_pos[2]) * t - - y += math.sin(t * math.pi) * 3.0 - - # Ajout de la courbe latérale - z += math.sin(t * math.pi) * z_offset - - # --- LIMITE SUR L'AXE Z --- - # On force z à rester entre -5 et 5 - z = max(-5.0, min(5.0, z)) - # -------------------------- - - ball.position = (x, y, z) - - if step < total_steps: - bs.timer(1 / fps, lambda: move_to_point(step + 1)) - - move_to_point(0) - else: - # normal - self.curving = False - if in_air and delegate.percentage > 95: - if closest_player.position[0] < 0: - vel = (12 * 1.6, 0, sight[2]) * speed - else: - vel = (-12 * 1.6, 0, sight[2]) * speed - else: - if closest_player.position[0] < 0: - vel = (4.8 * 1.6, 0, sight[2]) * speed - else: - vel = (-4.8 * 1.6, 0, sight[2]) * speed - - # smth - dist_from_middle = math.dist(you, (0, 2, 0)) - height = (max(dist_from_middle * 2.75, 7) * 0.8) - if in_air and delegate.percentage > 95: - height = -4 * 2 / dist_from_middle - - ball.velocity = (vel[0], height, vel[2]) - if in_air and delegate.percentage > 95: - audio = random.choice(['explosion01', 'explosion02', - 'explosion03', 'explosion04', 'explosion05']) - bs.getsound(audio).play() - self.smashed = bs.time() + 1 - self.smasher = closest_player - self.vignette(closest_player.color, False) - delegate.on_punch_press() - delegate.on_punch_release() - self.write( - f'{player.name.upper()} SMASHED THE BALL !' if random.random() < 0.5 else f'{player.name} hit the ball with all his might !', closest_player.color) - else: - self.write( - f'{player.name} {self.hit_text}', closest_player.color) - - # prettiness here - ppos = you - f = (bs.Vec3(ball.position) - bs.Vec3(you)).normalized() - closest_player.handlemessage( - 'kick_back', - ppos[0], - ppos[1], - ppos[2], - f[0], - f[1], - f[2], - 400, # small force - ) - # Ball goes straight up in the air. idk what it is called. - if closest_distance < 1.35 and (closest_player.pickup_pressed or pickup): - self.write( - f'{player.name} {self.control_text}', closest_player.color) - y_diff = abs(self._puck.node.position[1] - closest_player.position[1]) - - if y_diff < 1: - self.difficulty += 0.6 / 75 - self.last_interaction_time = bs.time() - self.curve = False - - self._puck.touches += 1 - - ball = self._puck.node - if self._puck.touches == 2: - spaz.percentage = min(spaz.percentage + 4, 100) - ball.color_texture = yellow - self.two_sound.play() - elif self._puck.touches == 3: - spaz.percentage = min(spaz.percentage + 6, 100) - ball.color_texture = red - self.one_sound.play() - else: - ball.color_texture = green - - closest_player.handlemessage('celebrate', 400) - bs.getsound("impactMedium").play() - e = bs.newnode( - 'explosion', - attrs={ - 'position': self._puck.node.position, - 'color': closest_player.color, - 'radius': 0.5, - 'big': True, - } - ) - bs.timer(1, e.delete) - - direction = (bs.Vec3(you) - - bs.Vec3(closest_player.position_forward)).normalized() - ball.velocity = (-you[0] * 0.04, 12.8, direction[2] * 0.1) - if closest_player.bomb_pressed and not delegate.gliding or bombed and not delegate.gliding: # gliding.. variant coming soon - self.write( - f'{player.name} {self.save_text}', closest_player.color) - delegate.gliding = True - ppos = you - f = (bs.Vec3(ball.position) - bs.Vec3(you)).normalized() - distance = math.dist(ball.position, you) - closest_player.handlemessage( - 'kick_back', - ppos[0], - ppos[1], - ppos[2], - f[0], - 0, - f[2], - 1000 - (500/distance), # tiny force - ) - closest_player.handlemessage('knockout', 100) - print(1) - spaz.pickup = now + 0.8 - - bs.getsound("impactHard").play(volume=0.5) - e = bs.newnode( - 'explosion', - attrs={ - 'position': you, - 'color': (0, 0.3, 0.5), - 'radius': 1.1, - 'big': False, - } - ) - bs.timer(1, e.delete) - bs.timer(0.6, lambda: setattr(delegate, 'gliding', False)) - - # variant soon - - 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 - self.curve = True - - def _handle_score(self) -> None: - 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 - # to not be getting a corrupted score. - if self._puck.scored: - return - E = bs.newnode( - 'explosion', - attrs={ - 'position': self._puck.node.position, - 'color': (0, 0, 0), - 'radius': .1, - 'big': True, - } - ) - bs.timer(1, E.delete) - bs.animate(self.touches_indicator, 'scale', {0: 0, 2.65: 0, 3: 0.025}) - self.touches_indicator.text = '0' - if self.smashed > 0: - self._puck.node.sticky = True - self.smashed = -9999 - - 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: - team.score += 1 - - # Puck Spawn - if team.id == 0: # left side scored - self._puck_spawn_pos = (5, 0.7, 0) - elif team.id == 1: # right side scored - self._puck_spawn_pos = (-5, 0.7, 0) - else: # what the heck - self._puck_spawn_pos = (0, 0.7, 0) - - for player in team.players: - if player.actor: - player.actor.handlemessage(bs.CelebrateMessage(2.0)) # yay we scored - player.actor.percentage = min(player.actor.percentage + 15, 100) - # dont mind this ;( - scorch = bs.newnode( - 'scorch', - attrs={ - 'position': self._puck.node.position, - 'size': 1.4, - 'color': player.actor.node.color, - 'big': True, - }, - ) - bs.animate(scorch, 'presence', {3.000: 1, 7.000: 0}) - bs.timer(7, scorch.delete) - self.vignette(player.actor.node.color, longer=True) - - # End game if we won. - if team.score >= self._score_to_win: - self.end_game() - - self._cheer_sound.play() - - self._puck.scored = True - - # Kill the puck (it'll respawn itself shortly). - # Animation ! 0 sec = 0.25 of size in our case - bs.animate(self._puck.node, 'mesh_scale', {0: 0.25, 0.4: 0}) - bs.timer(0.7, self._kill_puck) - - bs.cameraflash(duration=7.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.interactions_timer = None - self.end(results=results) - - def on_transition_in(self) -> None: - super().on_transition_in() - - 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) -> bs.Actor: - spaz = self.spawn_player_spaz(player) - spaz.bomb_count = 0 # No bombs for yall bahaha - # Now we want to make that your punches are useless too - # But we will need the button to work so let's put the damage to 0 and some custom stuff - spaz._punch_power_scale = 0 - spaz.impact_scale = 0 - spaz.check_timer = 0 - - spaz.pickup = 0 - spaz.punched = 0 - spaz.bombed = 0 - spaz.curved = 0 - - spaz.can_curve = False - - spaz.last_angle = 0 - spaz.total_rotation = 0.0 - spaz.rotation_direction = 0 # 0: neutre, 1: clockwise, -1: not clockwise - - spaz.gliding = False - spaz.smashed = False - spaz.percentage = 0 - spaz._jump_cooldown = 2000 - spaz.name = spaz.node.name - spaz.bar = bs.newnode( - 'shield', - owner=spaz.node, - attrs={ - 'position': spaz.node.position, - 'radius': .01, - 'color': (0, 0, 0), - } - ) - spaz.node.connectattr('position', spaz.bar, 'position') - spaz.bar.always_show_health_bar = True - spaz.node.name = '' # bahaha but you'll sspazuseful - - def check(): - if spaz.node.exists(): - # Controls part - now = bs.time() - - if spaz.node.punch_pressed: - spaz.punched = now + 0.25 - elif spaz.node.pickup_pressed: - spaz.pickup = now + 0.40 - elif spaz.node.bomb_pressed: - spaz.bombed = now + 0.20 - elif spaz.node.jump_pressed and spaz.percentage > 95: - spaz.punched = now + 0.50 - - if spaz.percentage > 95: - spaz.node.name = 'SMASH' - else: - spaz.node.name = '' - - spaz.bar.hurt = min(1.0 - float(spaz.percentage) / 100, 1) - - # Curved ball part - - pos = spaz.node.position - fwd = spaz.node.position_forward - - dx = fwd[0] - pos[0] - dz = fwd[2] - pos[2] - - length = math.sqrt(dx * dx + dz * dz) - if length > 0.0001: - dx /= length - dz /= length - - spaz.angle = math.degrees(math.atan2(-dx, -dz)) # trust - - # checks if u turn ! Not in the game yet ! - def check_270_rotation(): - now = bs.time() - current_angle = spaz.angle - - delta = current_angle - spaz.last_angle - if delta > 180: - delta -= 360 - if delta < -180: - delta += 360 - - current_dir = 1 if delta > 0 else -1 - - if spaz.rotation_direction != 0 and current_dir != spaz.rotation_direction: - spaz.total_rotation = 0 - - spaz.rotation_direction = current_dir - - spaz.total_rotation += abs(delta) - - if spaz.total_rotation >= 250: - spaz.curved = now + 0.40 - spaz.total_rotation = 0 - - spaz.last_angle = current_angle - - spaz.check_timer1 = bs.Timer(1/30, check, repeat=True) - # spaz.check_timer2 = bs.Timer(1/30, check_270_rotation, repeat=True) - - # spaz.node.hold_node = spaz.node ... nevermind - - # By the way when you have a node but want his player just do - # player = node.getdelegate(object) - # i dont know why you'll need it but here it is - - return spaz - - def handlemessage(self, msg: Any) -> Any: - - # Respawn dead players if they're still in the game. - # Because if we don't.. they won't like our 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(2, self._spawn_puck) # 2 secs to breathe bahahaha - else: - super().handlemessage(msg) - - def _spawn_puck(self) -> None: - self._swipsound.play() - self._whistle_sound.play() - assert self._puck_spawn_pos is not None - self._puck = Puck(position=self._puck_spawn_pos) - self.timer = bs.Timer(1 / 144, self.lock_it, repeat=True) # 144 ?.. yes - - def lock_it(self): - if self._puck is None: - return - if self.curve: - self._puck.node.position = self._puck_spawn_pos - else: - self._puck.node.shadow_size = min(self._puck.node.position[1] * 0.3, 2) - - -# ba_meta export babase.Plugin -class justlearn(babase.Plugin): - def __init__(self): - self.installer = ModInstaller() - self.installer.run_full_install() - - -class ModInstaller: - def __init__(self) -> None: - self.python_user = _babase.env()["python_directory_user"] - self.files = self.python_user + '/VolleyBallMap/' - self.app_dir = _babase.env()["python_directory_app"] + '/' - self.data_dir = self.app_dir + '../' - self.meshes_dir = self.data_dir + 'meshes/' - self.platform = _babase.app.classic.platform - - def run_full_install(self) -> None: - import os - import urllib.request - import shutil - import babase - - target_path = os.path.join(self.files, 'volleyball_net.bob') - destination_path = os.path.join(self.meshes_dir, 'volleyball_net.bob') - - if os.path.exists(destination_path): - return - - def _do_install(): - try: - if not os.path.exists(self.files): - os.makedirs(self.files) - - url = "https://raw.githubusercontent.com/Scriptz1/Learn.py-Installer/main/volleyball_net.bob" - urllib.request.urlretrieve(url, target_path) - shutil.copy(target_path, destination_path) - - bui.screenmessage("Installation worked !", color=(0, 1, 0.3)) - bui.getsound('ding').play() - - except Exception as e: - print(f"DEBUG ERROR: {e}") - bui.screenmessage("Installation Failed!", color=(1, 0, 0)) - bui.getsound('kronk2').play() - - bs.apptimer(2.5, _do_install)