bombsquad-plugin-manager/plugins/utilities/disco_light.py
2022-12-14 20:51:18 +08:00

271 lines
8.2 KiB
Python

"""Disco Light Mod: V1.0
Made by Cross Joy"""
# If anyone who wanna help me on giving suggestion/ fix bugs/ creating PR,
# Can visit my github https://github.com/CrossJoy/Bombsquad-Modding
# You can contact me through discord:
# My Discord Id: Cross Joy#0721
# My BS Discord Server: https://discord.gg/JyBY6haARJ
# ----------------------------------------------------------------------------
# Add disco light into the game, so you can
# play with your friends under the colorful light. :)
# type '/disco' in your chat box to activate or
# type '/disco off' to deactivate the disco light.
# Coop and multiplayer compatible.
# Work on any 1.7 ver.
# Note:
# The plugin commands only works on the host with the plugin activated.
# Other clients/players can't use the commands.
# ----------------------------------------------------------------------------
# ba_meta require api 7
from __future__ import annotations
from typing import TYPE_CHECKING
import ba
import _ba
from ba import _gameutils
import random
from ba import animate
if TYPE_CHECKING:
from typing import Sequence, Union
# Check game ver.
def is_game_version_lower_than(version):
"""
Returns a boolean value indicating whether the current game
version is lower than the passed version. Useful for addressing
any breaking changes within game versions.
"""
game_version = tuple(map(int, ba.app.version.split(".")))
version = tuple(map(int, version.split(".")))
return game_version < version
if is_game_version_lower_than("1.7.7"):
ba_internal = _ba
else:
ba_internal = ba.internal
# Activate disco light.
def start():
activity = _ba.get_foreground_host_activity()
with ba.Context(activity):
partyLight(True)
rainbow(activity)
# Deactivate disco light.
def stop():
activity = _ba.get_foreground_host_activity()
with ba.Context(activity):
partyLight(False)
stop_rainbow(activity)
# Create and animate colorful spotlight.
def partyLight(switch=True):
from ba._nodeactor import NodeActor
x_spread = 10
y_spread = 5
positions = [[-x_spread, -y_spread], [0, -y_spread], [0, y_spread],
[x_spread, -y_spread], [x_spread, y_spread],
[-x_spread, y_spread]]
times = [0, 2700, 1000, 1800, 500, 1400]
# Store this on the current activity, so we only have one at a time.
activity = _ba.getactivity()
activity.camera_flash_data = [] # type: ignore
for i in range(6):
r = random.choice([0.5, 1])
g = random.choice([0.5, 1])
b = random.choice([0.5, 1])
light = NodeActor(
_ba.newnode('light',
attrs={
'position': (positions[i][0], 0, positions[i][1]),
'radius': 1.0,
'lights_volumes': False,
'height_attenuated': False,
'color': (r, g, b)
}))
sval = 1.87
iscale = 1.3
tcombine = _ba.newnode('combine',
owner=light.node,
attrs={
'size': 3,
'input0': positions[i][0],
'input1': 0,
'input2': positions[i][1]
})
assert light.node
tcombine.connectattr('output', light.node, 'position')
xval = positions[i][0]
yval = positions[i][1]
spd = 1.0 + random.random()
spd2 = 1.0 + random.random()
animate(tcombine,
'input0', {
0.0: xval + 0,
0.069 * spd: xval + 10.0,
0.143 * spd: xval - 10.0,
0.201 * spd: xval + 0
},
loop=True)
animate(tcombine,
'input2', {
0.0: yval + 0,
0.15 * spd2: yval + 10.0,
0.287 * spd2: yval - 10.0,
0.398 * spd2: yval + 0
},
loop=True)
animate(light.node,
'intensity', {
0.0: 0,
0.02 * sval: 0,
0.05 * sval: 0.8 * iscale,
0.08 * sval: 0,
0.1 * sval: 0
},
loop=True,
offset=times[i])
if not switch:
_ba.timer(0.1,
light.node.delete)
activity.camera_flash_data.append(light) # type: ignore
# Create RGB tint.
def rainbow(self) -> None:
"""Create RGB tint."""
c_existing = self.globalsnode.tint
cnode = _ba.newnode('combine',
attrs={
'input0': c_existing[0],
'input1': c_existing[1],
'input2': c_existing[2],
'size': 3
})
_gameutils.animate(cnode, 'input0',
{0.0: 1.0, 1.0: 1.0, 2.0: 1.0, 3.0: 1.0,
4.0: 0.2, 5.0: 0.1, 6.0: 0.5,
7.0: 1.0}, loop=True)
_gameutils.animate(cnode, 'input1',
{0.0: 0.2, 1.0: 0.2, 2.0: 0.5, 3.0: 1.0,
4.0: 1.0, 5.0: 0.1, 6.0: 0.3,
7.0: 0.2}, loop=True)
_gameutils.animate(cnode, 'input2',
{0.0: 0.2, 1.0: 0.2, 2.0: 0.0, 3.0: 0.0,
4.0: 0.2, 5.0: 1.0, 6.0: 1.0,
7.0: 0.2}, loop=True)
cnode.connectattr('output', self.globalsnode, 'tint')
# Revert to the original map tint.
def stop_rainbow(self):
"""Revert to the original map tint."""
c_existing = self.globalsnode.tint
map_name = self.map.getname()
tint = check_map_tint(map_name)
cnode = _ba.newnode('combine',
attrs={
'input0': c_existing[0],
'input1': c_existing[1],
'input2': c_existing[2],
'size': 3
})
_gameutils.animate(cnode, 'input0', {0: c_existing[0], 1.0: tint[0]})
_gameutils.animate(cnode, 'input1', {0: c_existing[1], 1.0: tint[1]})
_gameutils.animate(cnode, 'input2', {0: c_existing[2], 1.0: tint[2]})
cnode.connectattr('output', self.globalsnode, 'tint')
# Check map name
def check_map_tint(map_name):
if map_name in 'Hockey Stadium':
tint = (1.2, 1.3, 1.33)
elif map_name in 'Football Stadium':
tint = (1.3, 1.2, 1.0)
elif map_name in 'Bridgit':
tint = (1.1, 1.2, 1.3)
elif map_name in 'Big G':
tint = (1.1, 1.2, 1.3)
elif map_name in 'Roundabout':
tint = (1.0, 1.05, 1.1)
elif map_name in 'Monkey Face':
tint = (1.1, 1.2, 1.2)
elif map_name in 'Zigzag':
tint = (1.0, 1.15, 1.15)
elif map_name in 'The Pad':
tint = (1.1, 1.1, 1.0)
elif map_name in 'Lake Frigid':
tint = (0.8, 0.9, 1.3)
elif map_name in 'Crag Castle':
tint = (1.15, 1.05, 0.75)
elif map_name in 'Tower D':
tint = (1.15, 1.11, 1.03)
elif map_name in 'Happy Thoughts':
tint = (1.3, 1.23, 1.0)
elif map_name in 'Step Right Up':
tint = (1.2, 1.1, 1.0)
elif map_name in 'Doom Shroom':
tint = (0.82, 1.10, 1.15)
elif map_name in 'Courtyard':
tint = (1.2, 1.17, 1.1)
elif map_name in 'Rampage':
tint = (1.2, 1.1, 0.97)
elif map_name in 'Tip Top':
tint = (0.8, 0.9, 1.3)
else:
tint = (1, 1, 1)
return tint
# Get the original game codes.
old_fcm = ba_internal.chatmessage
# New chat func to add some commands to activate/deactivate the disco light.
def new_chat_message(msg: Union[str, ba.Lstr], clients: Sequence[int] = None,
sender_override: str = None):
old_fcm(msg, clients, sender_override)
if msg == '/disco':
start()
if msg == '/disco off':
stop()
# Replace new chat func to the original game codes.
ba_internal.chatmessage = new_chat_message
if not ba_internal.is_party_icon_visible():
ba_internal.set_party_icon_always_visible(True)
# ba_meta export plugin
class ByCrossJoy(ba.Plugin):
def __init__(self): pass