diff --git a/plugins/minigames/volley_punch.py b/plugins/minigames/volley_punch.py index 8c8b0c8..c19e269 100644 --- a/plugins/minigames/volley_punch.py +++ b/plugins/minigames/volley_punch.py @@ -10,8 +10,10 @@ from __future__ import annotations from typing import TYPE_CHECKING -import babase, _babase -import math, random +import babase +import _babase +import math +import random import bascenev1 as bs import bauiv1 as bui import math @@ -28,7 +30,7 @@ if TYPE_CHECKING: plugman = dict( - plugin_name="VolleyPunch", + 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=[ @@ -37,6 +39,7 @@ plugman = dict( version="1.0.0", ) + class PuckDiedMessage: """Inform something that a puck has died.""" @@ -78,9 +81,6 @@ class Puck(bs.Actor): 'materials': pmats }) - - - def handlemessage(self, msg: Any) -> Any: if isinstance(msg, bs.DieMessage): assert self.node @@ -197,7 +197,7 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): 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.three_sound = bs.getsound('announceThree') # unused.. yet self._swipsound = bs.getsound('swip') self._whistle_sound = bs.getsound('refWhistle') self.puck_mesh = bs.getmesh('shield') @@ -243,7 +243,7 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): True), ('modify_part_collision', 'physical', False), ('call', 'at_connect', self._handle_score))) - self._fake_wall_material = bs.Material() #i'll fix this. trust + self._fake_wall_material = bs.Material() # i'll fix this. trust self._net_wall_material = bs.Material() self._net_material = bs.Material() @@ -263,30 +263,25 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): '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.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.s: list = [] + self.w: list = [] + self.n: list = [] self.last_interaction_time = -9999 self.smashed = -9999 self.interactions_timer = None @@ -314,58 +309,60 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): 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._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', - )) + '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', - )) + '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 + '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', @@ -397,16 +394,16 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): '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 + # 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)) + 'collide', False)) net = bs.newnode( 'prop', attrs={ 'body': 'puck', 'body_scale': 0, - 'position': (0,0,0), + 'position': (0, 0, 0), 'mesh_scale': 1, 'mesh': bs.getmesh('volleyball_net'), 'color_texture': bs.gettexture('black'), @@ -419,7 +416,6 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): }, ) - 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, )}))) @@ -428,9 +424,9 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): 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 )}))) + 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 )}))) + 20, 20, 0.8), 'type': 'box', 'materials': (self._net_wall_material, self._net_material)}))) def slow_down(self): if not self._puck: @@ -468,15 +464,17 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): 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)) + 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}) + 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. @@ -686,8 +684,6 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): v_attach='top', )) - - everything = bs.getnodes() everyone = [] closest_distance = 9999 @@ -696,7 +692,8 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): # 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]) + 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={ @@ -742,31 +739,31 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): 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. + 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 + if not player_node.exists(): # why wouldn't u exist at first continue - - distance = math.dist(player_node.position, self._puck.node.position) # not wanting to do that Euclidean thingy + # 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 + 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) + 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) + 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 @@ -782,19 +779,19 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): 50, # small force ) - punched = now < delegate.punched pickup = now < delegate.pickup bombed = now < delegate.bombed curved = now < delegate.curved - - if closest_player and closest_distance < 4 and good: # SO if broski is the nearest AND broski is near enough... + # 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) - if closest_distance < (1.35 if not in_air else 1.6) and (closest_player.punch_pressed or punched): # 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) + # 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', @@ -819,38 +816,78 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): self.one_sound.play() else: ball.color_texture = green - bs.getsound("impactHard").play() # This is for the sound, you probably didn't know that! + # 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 - 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 + z_offset = -4.0 if sight[0] < 0 else 4.0 - # 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 + 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: - if closest_player.position[0] < 0: - vel = (4.8 * 1.6, 0, sight[2]) * speed + # 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: - vel = (-4.8 * 1.6, 0, sight[2]) * speed + 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 = 3.5 - vel = (vel[0] * 1.5, height, vel[2]) - if in_air and delegate.percentage > 95: - height = -4 * 2 / dist_from_middle + # 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]) + ball.velocity = (vel[0], height, vel[2]) if in_air and delegate.percentage > 95: - audio = random.choice(['explosion01','explosion02','explosion03','explosion04','explosion05']) + audio = random.choice(['explosion01', 'explosion02', + 'explosion03', 'explosion04', 'explosion05']) bs.getsound(audio).play() self.smashed = bs.time() + 1 self.smasher = closest_player @@ -863,7 +900,7 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): self.write( f'{player.name} {self.hit_text}', closest_player.color) - #prettiness here + # prettiness here ppos = you f = (bs.Vec3(ball.position) - bs.Vec3(you)).normalized() closest_player.handlemessage( @@ -876,7 +913,8 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): f[2], 400, # small force ) - if closest_distance < 1.35 and (closest_player.pickup_pressed or pickup): # Ball goes straight up in the air. idk what it is called. + # 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]) @@ -886,7 +924,6 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): self.last_interaction_time = bs.time() self.curve = False - self._puck.touches += 1 ball = self._puck.node @@ -914,9 +951,10 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): ) bs.timer(1, e.delete) - direction = (bs.Vec3(you) - bs.Vec3(closest_player.position_forward)).normalized() + 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 + 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 @@ -952,12 +990,6 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): # variant soon - - - - - - def on_team_join(self, team: Team) -> None: self._update_scoreboard() @@ -990,7 +1022,7 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): 'explosion', attrs={ 'position': self._puck.node.position, - 'color': (0,0,0), + 'color': (0, 0, 0), 'radius': .1, 'big': True, } @@ -1022,7 +1054,7 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): for player in team.players: if player.actor: - player.actor.handlemessage(bs.CelebrateMessage(2.0)) # yay we scored + 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( @@ -1047,7 +1079,8 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): self._puck.scored = True # Kill the puck (it'll respawn itself shortly). - bs.animate(self._puck.node, 'mesh_scale', {0: 0.25, 0.4 : 0}) # Animation ! 0 sec = 0.25 of size in our case + # 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) @@ -1071,7 +1104,7 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): # 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 + 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 @@ -1085,10 +1118,9 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): spaz.can_curve = False - spaz.last_angle = 0 spaz.total_rotation = 0.0 - spaz.rotation_direction = 0 + spaz.rotation_direction = 0 # 0: neutre, 1: clockwise, -1: not clockwise spaz.gliding = False spaz.smashed = False @@ -1106,7 +1138,7 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): ) spaz.node.connectattr('position', spaz.bar, 'position') spaz.bar.always_show_health_bar = True - spaz.node.name = '' # bahaha but you'll sspazuseful + spaz.node.name = '' # bahaha but you'll sspazuseful def check(): if spaz.node.exists(): @@ -1127,7 +1159,6 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): else: spaz.node.name = '' - spaz.bar.hurt = min(1.0 - float(spaz.percentage) / 100, 1) # Curved ball part @@ -1143,12 +1174,42 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): dx /= length dz /= length - spaz.angle = math.degrees(math.atan2(-dx, -dz)) # trust + 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 @@ -1164,17 +1225,17 @@ class VolleyBallGame(bs.TeamGameActivity[Player, Team]): # Respawn dead pucks. elif isinstance(msg, PuckDiedMessage): if not self.has_ended(): - bs.timer(2, self._spawn_puck) + 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) + self.timer = bs.Timer(1 / 144, self.lock_it, repeat=True) # 144 ?.. yes + def lock_it(self): if self._puck is None: return @@ -1229,5 +1290,4 @@ class ModInstaller: bui.screenmessage("Installation Failed!", color=(1, 0, 0)) bui.getsound('kronk2').play() - bs.apptimer(2.5, _do_install)