2025-04-09 23:27:43 +02:00
|
|
|
"""
|
|
|
|
|
Vanilla Wiggle Dance by SoK
|
|
|
|
|
Pizza Tower dance ported to BombSquad.
|
|
|
|
|
Originally made for Explodinary Rebombed.
|
|
|
|
|
|
|
|
|
|
Wiggling left and right makes your character play music, wave arms and emit cool sparks :D
|
|
|
|
|
For much cooler version of this plugin, check out BSE Rebombed Modpack! (not released yet)
|
|
|
|
|
Version 1.0
|
|
|
|
|
|
|
|
|
|
If you want to use this plugin in your own work, please let me know on Discord (sok05).
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
from typing import override
|
|
|
|
|
import random
|
|
|
|
|
import math
|
|
|
|
|
import bascenev1 as bs
|
|
|
|
|
import babase
|
|
|
|
|
|
|
|
|
|
# ba_meta require api 9
|
|
|
|
|
|
2025-06-24 00:55:09 +05:30
|
|
|
# ba_meta export babase.Plugin
|
2025-04-09 23:27:43 +02:00
|
|
|
class WiggleDance(babase.Plugin):
|
|
|
|
|
def add_dance_mechanic_to_spaz(spaz_class):
|
|
|
|
|
"""Add dance mechanic to the Spaz class"""
|
|
|
|
|
|
|
|
|
|
# Store the original on_move_left_right method
|
|
|
|
|
original_on_move_left_right = spaz_class.on_move_left_right
|
|
|
|
|
|
|
|
|
|
# Override the on_move_left_right method
|
|
|
|
|
def new_on_move_left_right(self, value: float) -> None:
|
|
|
|
|
"""Called to set the left/right joystick amount on this spaz"""
|
|
|
|
|
# Call the original method first
|
|
|
|
|
original_on_move_left_right(self, value)
|
|
|
|
|
|
|
|
|
|
# Check for wiggling
|
|
|
|
|
if not hasattr(self, '_last_wiggle_value'):
|
|
|
|
|
self._last_wiggle_value = 0
|
|
|
|
|
self._wiggle_count = 0
|
|
|
|
|
self._wiggle_timer = None
|
|
|
|
|
self._dance_timer = None
|
|
|
|
|
self._dance_visual_timer = None
|
|
|
|
|
self._dance_sound_node = None
|
|
|
|
|
self.dancing = False
|
|
|
|
|
self._last_dance_arm = 'left'
|
|
|
|
|
|
|
|
|
|
# Detect significant change in direction (wiggle)
|
|
|
|
|
if abs(value) > 0.5:
|
|
|
|
|
# Add a wiggle
|
|
|
|
|
self._wiggle_count += 1
|
|
|
|
|
|
|
|
|
|
# Remove the existing timer
|
|
|
|
|
if self._wiggle_timer:
|
|
|
|
|
self._wiggle_timer = None
|
|
|
|
|
|
|
|
|
|
# Start a new timer
|
|
|
|
|
self._wiggle_timer = bs.Timer(0.18, bs.WeakCall(self._reset_wiggle_count))
|
|
|
|
|
|
|
|
|
|
# Check if we've been wiggling enough to start dancing
|
|
|
|
|
if self._wiggle_count > 8 and not self.dancing:
|
|
|
|
|
self._start_dancing()
|
|
|
|
|
|
|
|
|
|
# Update last wiggle value
|
|
|
|
|
self._last_wiggle_value = value
|
|
|
|
|
|
|
|
|
|
# Add new methods to the class
|
|
|
|
|
def _reset_wiggle_count(self):
|
|
|
|
|
"""Reset wiggle count if timer expires"""
|
|
|
|
|
if self.node and self.is_alive():
|
|
|
|
|
self._wiggle_count = 0
|
|
|
|
|
self._wiggle_timer = None
|
|
|
|
|
|
|
|
|
|
# If we were dancing, stop dancing
|
|
|
|
|
if self.dancing:
|
|
|
|
|
self._stop_dancing()
|
|
|
|
|
|
|
|
|
|
def _start_dancing(self):
|
|
|
|
|
"""Start the dance sequence"""
|
|
|
|
|
if not self.node or not self.is_alive():
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
self.dancing = True
|
|
|
|
|
|
|
|
|
|
# Play sound
|
|
|
|
|
bs.getsound('orchestraHit4').play(volume=0.35)
|
|
|
|
|
|
|
|
|
|
# Create dance sound node
|
|
|
|
|
# We gotta keep track if another Spaz is playing music currently
|
|
|
|
|
# in our activity. We don't want multiple musics cuz.. annoying, man
|
|
|
|
|
activity = bs.getactivity()
|
|
|
|
|
if not hasattr(activity, 'music_spazzes'):
|
|
|
|
|
activity.music_spazzes = 0
|
|
|
|
|
if not self._dance_sound_node and activity.music_spazzes < 1:
|
|
|
|
|
self._dance_sound_node = bs.newnode(
|
|
|
|
|
'sound',
|
|
|
|
|
owner=self.node,
|
|
|
|
|
attrs={'sound': bs.getsound('victoryMusic'), 'volume': 0.2, 'loop': True},
|
|
|
|
|
)
|
|
|
|
|
self.node.connectattr('position', self._dance_sound_node, 'position')
|
|
|
|
|
|
|
|
|
|
# And add our Spaz as a music one for our activity
|
|
|
|
|
activity.music_spazzes += 1
|
|
|
|
|
|
|
|
|
|
# Start visual dance timer
|
|
|
|
|
if not self._dance_visual_timer:
|
2025-04-09 21:30:15 +00:00
|
|
|
self._dance_visual_timer = bs.Timer(
|
|
|
|
|
0.5, bs.WeakCall(self._dance_visual), repeat=True)
|
2025-04-09 23:27:43 +02:00
|
|
|
|
|
|
|
|
def _dance_visual(self):
|
|
|
|
|
"""Create visual dance effects"""
|
|
|
|
|
if not self.node or not self.is_alive() or not self.dancing:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# Emit sparks
|
|
|
|
|
bs.emitfx(
|
|
|
|
|
position=self.node.position,
|
|
|
|
|
velocity=(random.uniform(-1, 1), 2, random.uniform(-1, 1)),
|
|
|
|
|
count=random.randint(5, 10),
|
|
|
|
|
scale=random.uniform(0.7, 1.1),
|
|
|
|
|
spread=0.2,
|
|
|
|
|
chunk_type='spark'
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# Wave arms
|
|
|
|
|
if self._last_dance_arm == 'left':
|
|
|
|
|
self.node.handlemessage('celebrate_r', 50)
|
|
|
|
|
self._last_dance_arm = 'right'
|
|
|
|
|
else:
|
|
|
|
|
self.node.handlemessage('celebrate', 50)
|
|
|
|
|
self._last_dance_arm = 'left'
|
|
|
|
|
|
|
|
|
|
def _stop_dancing(self):
|
|
|
|
|
"""Stop the dance sequence"""
|
|
|
|
|
self.dancing = False
|
|
|
|
|
|
|
|
|
|
# Clean up timers
|
|
|
|
|
if self._dance_visual_timer:
|
|
|
|
|
self._dance_visual_timer = None
|
|
|
|
|
|
|
|
|
|
# Clean up sound
|
|
|
|
|
if self._dance_sound_node:
|
|
|
|
|
self._dance_sound_node.delete()
|
|
|
|
|
self._dance_sound_node = None
|
|
|
|
|
|
|
|
|
|
activity = bs.getactivity()
|
|
|
|
|
|
|
|
|
|
# And remove our Spaz as a music one for our activity
|
|
|
|
|
activity.music_spazzes -= 1
|
|
|
|
|
|
|
|
|
|
# Add methods to the class
|
|
|
|
|
spaz_class.on_move_left_right = new_on_move_left_right
|
|
|
|
|
spaz_class._reset_wiggle_count = _reset_wiggle_count
|
|
|
|
|
spaz_class._start_dancing = _start_dancing
|
|
|
|
|
spaz_class._dance_visual = _dance_visual
|
|
|
|
|
spaz_class._stop_dancing = _stop_dancing
|
|
|
|
|
|
|
|
|
|
# Add cleanup
|
|
|
|
|
original_on_expire = spaz_class.on_expire
|
|
|
|
|
|
|
|
|
|
def new_on_expire(self):
|
|
|
|
|
"""Clean up dance resources when expiring"""
|
|
|
|
|
if hasattr(self, 'dancing') and self.dancing:
|
|
|
|
|
self._stop_dancing()
|
|
|
|
|
original_on_expire(self)
|
|
|
|
|
|
|
|
|
|
spaz_class.on_expire = new_on_expire
|
|
|
|
|
|
|
|
|
|
return spaz_class
|
|
|
|
|
|
|
|
|
|
# Apply the dance mechanic to the Spaz class
|
|
|
|
|
from bascenev1lib.actor.spaz import Spaz
|
2025-04-09 21:30:15 +00:00
|
|
|
Spaz = add_dance_mechanic_to_spaz(Spaz)
|