mirror of
https://github.com/bombsquad-community/plugin-manager.git
synced 2025-10-08 14:54:36 +00:00
commit
7c4ffaf2e2
4 changed files with 660 additions and 585 deletions
|
|
@ -826,7 +826,7 @@
|
|||
}
|
||||
},
|
||||
"disco_light": {
|
||||
"description": "Add disco light into the game.",
|
||||
"description": "Add disco light into the game. Do '/disco' to turn on and '/disco off' to turn off",
|
||||
"external_url": "",
|
||||
"authors": [
|
||||
{
|
||||
|
|
@ -836,6 +836,12 @@
|
|||
}
|
||||
],
|
||||
"versions": {
|
||||
"2.1.0": {
|
||||
"api_version": 8,
|
||||
"commit_sha": "41046ae",
|
||||
"released_on": "14-02-2024",
|
||||
"md5sum": "bfffb346d61958c02015dde0b1520ca3"
|
||||
},
|
||||
"1.0.1": {
|
||||
"api_version": 8,
|
||||
"commit_sha": "2b5c9ee",
|
||||
|
|
@ -851,7 +857,7 @@
|
|||
}
|
||||
},
|
||||
"practice_tools": {
|
||||
"description": "Powerful and comprehensive tools for practice purpose. Practice tabs can be access through party window.",
|
||||
"description": "Powerful and comprehensive tools for practice purposes. Practice tabs can be accessed through party window.",
|
||||
"external_url": "https://www.youtube.com/watch?v=7BeCcIYSXd0&t=113s&ab_channel=BOMBsquadlife",
|
||||
"authors": [
|
||||
{
|
||||
|
|
@ -861,6 +867,12 @@
|
|||
}
|
||||
],
|
||||
"versions": {
|
||||
"2.2.0": {
|
||||
"api_version": 8,
|
||||
"commit_sha": "41046ae",
|
||||
"released_on": "14-02-2024",
|
||||
"md5sum": "b02de60a80039b092ef4d826b3d61cc1"
|
||||
},
|
||||
"2.1.1": {
|
||||
"api_version": 8,
|
||||
"commit_sha": "5422dd6",
|
||||
|
|
@ -905,6 +917,25 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"health_indicator": {
|
||||
"description": "Add a simple health indicator on every player and bot.",
|
||||
"external_url": "",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Cross Joy",
|
||||
"email": "cross.joy.official@gmail.com",
|
||||
"discord": "crossjoy"
|
||||
}
|
||||
],
|
||||
"versions": {
|
||||
"1.2.0": {
|
||||
"api_version": 8,
|
||||
"commit_sha": "41046ae",
|
||||
"released_on": "14-02-2024",
|
||||
"md5sum": "e16123cf550f433c70e53b8ec41a4e46"
|
||||
}
|
||||
}
|
||||
},
|
||||
"autorun": {
|
||||
"description": "Run without holding any buttons. Made for beginners or players on mobile. Keeps your character maneuverable. Start running as usual to override.",
|
||||
"external_url": "",
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
# Porting to api 8 made easier by baport.(https://github.com/bombsquad-community/baport)
|
||||
"""Disco Light Mod: V1.0
|
||||
"""Disco Light Mod: V2.1
|
||||
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: crossjoy
|
||||
# My Discord Id: Cross Joy#0721
|
||||
# My BS Discord Server: https://discord.gg/JyBY6haARJ
|
||||
|
||||
|
||||
|
|
@ -19,11 +18,16 @@ Made by Cross Joy"""
|
|||
|
||||
|
||||
# Coop and multiplayer compatible.
|
||||
# Work on any 1.7 ver.
|
||||
# Work on any 1.7.20+ ver.
|
||||
|
||||
# Note:
|
||||
# The plugin commands only works on the host with the plugin activated.
|
||||
# Other clients/players can't use the commands.
|
||||
|
||||
# v2.1
|
||||
# - Enhance compatibility with other mods
|
||||
# - Tint change when /disco off will be more dynamic.
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ba_meta require api 8
|
||||
|
|
@ -33,255 +37,196 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from baenv import TARGET_BALLISTICA_BUILD as build_number
|
||||
from bauiv1lib import mainmenu
|
||||
import bascenev1 as bs
|
||||
import babase
|
||||
import bauiv1 as bui
|
||||
import bascenev1 as bs
|
||||
import _babase
|
||||
from bascenev1 import _gameutils, animate
|
||||
from bascenev1 import _gameutils
|
||||
import random
|
||||
|
||||
from bascenev1 import animate
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Sequence, Union
|
||||
|
||||
# Check game ver.
|
||||
|
||||
class DiscoLight:
|
||||
|
||||
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, babase.app.version if build_number <
|
||||
21282 else babase.app.env.split(".")))
|
||||
version = tuple(map(int, version.split(".")))
|
||||
return game_version < version
|
||||
def __init__(self):
|
||||
activity = bs.get_foreground_host_activity()
|
||||
self.globalnodes = activity.globalsnode.tint
|
||||
|
||||
# Activate disco light.
|
||||
def start(self):
|
||||
activity = bs.get_foreground_host_activity()
|
||||
with activity.context:
|
||||
self.partyLight(True)
|
||||
self.rainbow(activity)
|
||||
|
||||
# if is_game_version_lower_than("1.7.7"):
|
||||
# ba_internal = _ba
|
||||
# else:
|
||||
# ba_internal = babase.internal
|
||||
# Deactivate disco light.
|
||||
def stop(self):
|
||||
activity = bs.get_foreground_host_activity()
|
||||
with activity.context:
|
||||
self.partyLight(False)
|
||||
self.stop_rainbow(activity)
|
||||
|
||||
# Create and animate colorful spotlight.
|
||||
def partyLight(self, switch=True):
|
||||
from bascenev1._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]
|
||||
|
||||
# Activate disco light.
|
||||
def start():
|
||||
activity = bs.get_foreground_host_activity()
|
||||
# Store this on the current activity, so we only have one at a time.
|
||||
activity = bs.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(
|
||||
bs.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 = bs.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:
|
||||
bs.timer(0.1,
|
||||
light.node.delete)
|
||||
activity.camera_flash_data.append(light) # type: ignore
|
||||
|
||||
with activity.context:
|
||||
partyLight(True)
|
||||
rainbow(activity)
|
||||
# Create RGB tint.
|
||||
def rainbow(self, activity) -> None:
|
||||
"""Create RGB tint."""
|
||||
|
||||
cnode = bs.newnode('combine',
|
||||
attrs={
|
||||
'input0': self.globalnodes[0],
|
||||
'input1': self.globalnodes[1],
|
||||
'input2': self.globalnodes[2],
|
||||
'size': 3
|
||||
})
|
||||
|
||||
# Deactivate disco light.
|
||||
def stop():
|
||||
activity = bs.get_foreground_host_activity()
|
||||
_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)
|
||||
|
||||
with activity.context:
|
||||
partyLight(False)
|
||||
stop_rainbow(activity)
|
||||
_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)
|
||||
|
||||
# Create and animate colorful spotlight.
|
||||
def partyLight(switch=True):
|
||||
from bascenev1._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]
|
||||
cnode.connectattr('output', activity.globalsnode, 'tint')
|
||||
|
||||
# Store this on the current activity, so we only have one at a time.
|
||||
activity = bs.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(
|
||||
bs.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 = bs.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:
|
||||
bs.timer(0.1,
|
||||
light.node.delete)
|
||||
activity.camera_flash_data.append(light) # type: ignore
|
||||
# Revert to the original map tint.
|
||||
def stop_rainbow(self, activity):
|
||||
"""Revert to the original map tint."""
|
||||
c_existing = activity.globalsnode.tint
|
||||
# map_name = activity.map.getname()
|
||||
tint = self.globalnodes
|
||||
|
||||
cnode = bs.newnode('combine',
|
||||
attrs={
|
||||
'input0': c_existing[0],
|
||||
'input1': c_existing[1],
|
||||
'input2': c_existing[2],
|
||||
'size': 3
|
||||
})
|
||||
|
||||
# Create RGB tint.
|
||||
def rainbow(self) -> None:
|
||||
"""Create RGB tint."""
|
||||
c_existing = self.globalsnode.tint
|
||||
cnode = bs.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]})
|
||||
|
||||
_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."""
|
||||
try:
|
||||
c_existing = self.globalsnode.tint
|
||||
map_name = self.map.getname()
|
||||
tint = check_map_tint(map_name)
|
||||
except:
|
||||
tint = (1, 1, 1)
|
||||
|
||||
cnode = bs.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 = bs.chatmessage
|
||||
cnode.connectattr('output', activity.globalsnode, 'tint')
|
||||
|
||||
|
||||
# New chat func to add some commands to activate/deactivate the disco light.
|
||||
def new_chat_message(msg: Union[str, babase.Lstr], clients: Sequence[int] = None,
|
||||
sender_override: str = None):
|
||||
old_fcm(msg, clients, sender_override)
|
||||
if msg == '/disco':
|
||||
start()
|
||||
if msg == '/disco off':
|
||||
stop()
|
||||
def new_chat_message(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
func(*args, **kwargs)
|
||||
activity = bs.get_foreground_host_activity()
|
||||
with activity.context:
|
||||
try:
|
||||
if not activity.disco_light:
|
||||
activity.disco_light = DiscoLight()
|
||||
except:
|
||||
activity.disco_light = DiscoLight()
|
||||
if args[0] == '/disco':
|
||||
activity.disco_light.start()
|
||||
elif args[0] == '/disco off':
|
||||
activity.disco_light.stop()
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
class NewMainMenuWindow(mainmenu.MainMenuWindow):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
# Display chat icon, but if user open/close gather it may disappear
|
||||
def new_begin(func):
|
||||
"""Runs when game is began."""
|
||||
|
||||
def wrapper(*args, **kwargs):
|
||||
func(*args, **kwargs)
|
||||
bui.set_party_icon_always_visible(True)
|
||||
|
||||
|
||||
# Replace new chat func to the original game codes.
|
||||
bs.chatmessage = new_chat_message
|
||||
return wrapper
|
||||
|
||||
|
||||
# ba_meta export plugin
|
||||
class ByCrossJoy(babase.Plugin):
|
||||
def on_app_running(self):
|
||||
mainmenu.MainMenuWindow = NewMainMenuWindow
|
||||
def __init__(self):
|
||||
# Replace new chat func to the original game codes.
|
||||
bs.chatmessage = new_chat_message(bs.chatmessage)
|
||||
bs._activity.Activity.on_begin = new_begin(
|
||||
bs._activity.Activity.on_begin)
|
||||
|
|
|
|||
79
plugins/utilities/health_indicator.py
Normal file
79
plugins/utilities/health_indicator.py
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
"""Health Indicator mod v1.2
|
||||
Made by Cross Joy
|
||||
For 1.7.20+"""
|
||||
|
||||
# ----------------------
|
||||
# v1.2 update
|
||||
# Enhance compatibility with other mods.
|
||||
# Fixed the health is not displaying accurately.
|
||||
# ----------------------
|
||||
|
||||
# You can contact me through discord:
|
||||
# My Discord Id: Cross Joy#0721
|
||||
# My BS Discord Server: https://discord.gg/JyBY6haARJ
|
||||
|
||||
# Add a simple health indicator on every player and bot.
|
||||
|
||||
# ba_meta require api 8
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import babase
|
||||
import bascenev1lib.actor.spaz
|
||||
from bascenev1lib.actor.spaz import Spaz
|
||||
import bascenev1 as bs
|
||||
import bascenev1lib
|
||||
|
||||
|
||||
def new_init_spaz_(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
func(*args, **kwargs)
|
||||
m = bs.newnode('math',
|
||||
owner=args[0].node,
|
||||
attrs={'input1': (0, 0.7, 0),
|
||||
'operation': 'add'})
|
||||
args[0].node.connectattr('position', m, 'input2')
|
||||
args[0]._hitpoint_text = bs.newnode(
|
||||
'text',
|
||||
owner=args[0].node,
|
||||
attrs={'text': "\ue047" + str(args[0].hitpoints),
|
||||
'in_world': True,
|
||||
'shadow': 1.0,
|
||||
'flatness': 1.0,
|
||||
'color': (1, 1, 1),
|
||||
'scale': 0.0,
|
||||
'h_align': 'center'})
|
||||
m.connectattr('output', args[0]._hitpoint_text, 'position')
|
||||
bs.animate(args[0]._hitpoint_text, 'scale', {0: 0.0, 1.0: 0.01})
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def new_handlemessage_spaz_(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
def update_hitpoint_text(spaz):
|
||||
spaz._hitpoint_text.text = "\ue047" + str(spaz.hitpoints)
|
||||
r = spaz.hitpoints / 1000
|
||||
spaz._hitpoint_text.color = (1, r, r, 1)
|
||||
|
||||
func(*args, **kwargs)
|
||||
if isinstance(args[1], bs.PowerupMessage):
|
||||
if args[1].poweruptype == 'health':
|
||||
update_hitpoint_text(args[0])
|
||||
if isinstance(
|
||||
args[1], bs.HitMessage) or isinstance(
|
||||
args[1], bs.ImpactDamageMessage):
|
||||
update_hitpoint_text(args[0])
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
# ba_meta export plugin
|
||||
class ByCrossJoy(babase.Plugin):
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def on_app_running(self) -> None:
|
||||
Spaz.__init__ = new_init_spaz_(Spaz.__init__)
|
||||
Spaz.handlemessage = new_handlemessage_spaz_(Spaz.handlemessage)
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
"""Practice Tools Mod: V2.1
|
||||
"""Practice Tools Mod: V2.2
|
||||
Made by Cross Joy"""
|
||||
|
||||
# If anyone who want to help me on giving suggestion/ fix bugs/ creating PR,
|
||||
|
|
@ -12,25 +12,12 @@ Made by Cross Joy"""
|
|||
# Support link: https://www.buymeacoffee.com/CrossJoy
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# V2.1 update
|
||||
# - Fix bug where the ui stuck if opened on server side.
|
||||
# - Fix a bug to set party icon to always visible for newer bombsquad version.
|
||||
|
||||
# V2.0 update
|
||||
# - Updated to API 8 (1.7.20+)
|
||||
# V2.2 update
|
||||
# - Enhance computability with other mods.
|
||||
# - Added setting for permanent powerups.
|
||||
# - Codes Optimization.
|
||||
|
||||
# V1.2 update
|
||||
# - Added New Bot: Bomber Lite and Brawler Lite.
|
||||
# - Added New Setting: Epic Mode Toggle.
|
||||
# - Added immunity to curse if invincible.
|
||||
# - Fixed Power Up mini billboard will not removed after debuff.
|
||||
# - Fixed Power Up landmine count will not removed after debuff.
|
||||
# - Fixed the config (Bot Picker, Count, Radius and Power Up Picker) will set to default when exit the practice tab.
|
||||
|
||||
# V1.1 update
|
||||
# - Fixed Charger Bot Pro bot spawn with shield.
|
||||
# - Fixed selecting Bruiser bot is not working.
|
||||
# - Added screen message when pressing spawn/clear/debuff button.
|
||||
# ----------------------------------------------------------------------------
|
||||
# Powerful and comprehensive tools for practice purpose.
|
||||
|
||||
|
|
@ -72,7 +59,8 @@ import bascenev1lib
|
|||
import bauiv1 as bui
|
||||
from bauiv1lib import mainmenu
|
||||
from babase import app, Plugin
|
||||
from bascenev1lib.actor.powerupbox import PowerupBox
|
||||
from bascenev1lib.actor.powerupbox import PowerupBox, PowerupBoxFactory
|
||||
from bascenev1lib.actor.bomb import Bomb
|
||||
from bascenev1lib.actor.spaz import Spaz
|
||||
from bascenev1lib.actor import spawner
|
||||
from bascenev1lib.actor.spazbot import (SpazBotSet, SpazBot, BrawlerBot,
|
||||
|
|
@ -94,47 +82,35 @@ from bauiv1lib.tabs import TabRow
|
|||
if TYPE_CHECKING:
|
||||
from typing import Any, Sequence, Callable, Optional
|
||||
|
||||
version = '2.1'
|
||||
version = '2.2'
|
||||
|
||||
try:
|
||||
if babase.app.config.get("bombCountdown") is None:
|
||||
babase.app.config["bombCountdown"] = False
|
||||
else:
|
||||
babase.app.config.get("bombCountdown")
|
||||
except:
|
||||
babase.app.config["bombCountdown"] = False
|
||||
|
||||
try:
|
||||
if babase.app.config.get("bombRadiusVisual") is None:
|
||||
babase.app.config["bombRadiusVisual"] = False
|
||||
else:
|
||||
babase.app.config.get("bombRadiusVisual")
|
||||
except:
|
||||
babase.app.config["bombRadiusVisual"] = False
|
||||
class ConfigLoader:
|
||||
def __init__(self):
|
||||
self.config_data = {
|
||||
"Practice Tab": False,
|
||||
"bombCountdown": False,
|
||||
"bombRadiusVisual": False,
|
||||
"stopBots": False,
|
||||
"immortalDummy": False,
|
||||
"powerupsExpire": False,
|
||||
"invincible": False
|
||||
}
|
||||
self.config_names = ["Practice Tab", "bombCountdown",
|
||||
"bombRadiusVisual", "stopBots",
|
||||
"immortalDummy", "powerupsExpire", "invincible"]
|
||||
|
||||
try:
|
||||
if babase.app.config.get("stopBots") is None:
|
||||
babase.app.config["stopBots"] = False
|
||||
else:
|
||||
babase.app.config.get("stopBots")
|
||||
except:
|
||||
babase.app.config["stopBots"] = False
|
||||
|
||||
try:
|
||||
if babase.app.config.get("immortalDummy") is None:
|
||||
babase.app.config["immortalDummy"] = False
|
||||
else:
|
||||
babase.app.config.get("immortalDummy")
|
||||
except:
|
||||
babase.app.config["immortalDummy"] = False
|
||||
|
||||
try:
|
||||
if babase.app.config.get("invincible") is None:
|
||||
babase.app.config["invincible"] = False
|
||||
else:
|
||||
babase.app.config.get("invincible")
|
||||
except:
|
||||
babase.app.config["invincible"] = False
|
||||
def load_configs(self):
|
||||
for config_name in self.config_names:
|
||||
try:
|
||||
existing_config = babase.app.config.get(config_name)
|
||||
if existing_config is None:
|
||||
babase.app.config[config_name] = self.config_data[
|
||||
config_name]
|
||||
else:
|
||||
babase.app.config.get(config_name)
|
||||
except:
|
||||
babase.app.config[config_name] = self.config_data[config_name]
|
||||
|
||||
|
||||
class PartyWindow(bui.Window):
|
||||
|
|
@ -174,7 +150,7 @@ def redefine_class(original_cls: object, cls: object) -> None:
|
|||
|
||||
|
||||
def main(plugin: Plugin) -> None:
|
||||
print(f'Plugins Tools v{plugin.__version__}')
|
||||
print(f'Practice Tools v{plugin.__version__}')
|
||||
app.practice_tool = plugin
|
||||
redefine_class(OriginalPartyWindow, PartyWindow)
|
||||
|
||||
|
|
@ -185,10 +161,9 @@ class NewMainMenuWindow(mainmenu.MainMenuWindow):
|
|||
# Display chat icon, but if user open/close gather it may disappear
|
||||
bui.set_party_icon_always_visible(True)
|
||||
|
||||
|
||||
# ba_meta require api 8
|
||||
# ba_meta export plugin
|
||||
|
||||
|
||||
class Practice(Plugin):
|
||||
__version__ = version
|
||||
|
||||
|
|
@ -202,334 +177,373 @@ class Practice(Plugin):
|
|||
raise RuntimeError(
|
||||
'sad')
|
||||
mainmenu.MainMenuWindow = NewMainMenuWindow
|
||||
config_loader = ConfigLoader()
|
||||
config_loader.load_configs()
|
||||
return main(self)
|
||||
|
||||
def new_bomb_init(func):
|
||||
def setting(*args, **kwargs):
|
||||
func(*args, **kwargs)
|
||||
|
||||
bomb_type = args[0].bomb_type
|
||||
fuse_bomb = ('land_mine', 'tnt', 'impact')
|
||||
def new_bomb_init(func):
|
||||
def setting(*args, **kwargs):
|
||||
func(*args, **kwargs)
|
||||
|
||||
if babase.app.config.get("bombRadiusVisual"):
|
||||
args[0].radius_visualizer = bs.newnode('locator',
|
||||
owner=args[0].node,
|
||||
# Remove itself when the bomb node dies.
|
||||
attrs={
|
||||
'shape': 'circle',
|
||||
'color': (1, 0, 0),
|
||||
'opacity': 0.05,
|
||||
'draw_beauty': False,
|
||||
'additive': False
|
||||
})
|
||||
args[0].node.connectattr('position', args[0].radius_visualizer,
|
||||
'position')
|
||||
bomb_type = args[0].bomb_type
|
||||
fuse_bomb = ('land_mine', 'tnt', 'impact')
|
||||
|
||||
bs.animate_array(args[0].radius_visualizer, 'size', 1, {
|
||||
0.0: [0.0],
|
||||
0.2: [args[0].blast_radius * 2.2],
|
||||
0.25: [args[0].blast_radius * 2.0]
|
||||
})
|
||||
if babase.app.config.get("bombRadiusVisual"):
|
||||
args[0].radius_visualizer = bs.newnode('locator',
|
||||
owner=args[0].node,
|
||||
# Remove itself when the bomb node dies.
|
||||
attrs={
|
||||
'shape': 'circle',
|
||||
'color': (1, 0, 0),
|
||||
'opacity': 0.05,
|
||||
'draw_beauty': False,
|
||||
'additive': False
|
||||
})
|
||||
args[0].node.connectattr('position', args[0].radius_visualizer,
|
||||
'position')
|
||||
|
||||
args[0].radius_visualizer_circle = bs.newnode(
|
||||
'locator',
|
||||
owner=args[
|
||||
0].node,
|
||||
# Remove itself when the bomb node dies.
|
||||
attrs={
|
||||
'shape': 'circleOutline',
|
||||
'size': [
|
||||
args[
|
||||
0].blast_radius * 2.0],
|
||||
# Here's that bomb's blast radius value again!
|
||||
'color': (
|
||||
1, 1, 0),
|
||||
'draw_beauty': False,
|
||||
'additive': True
|
||||
})
|
||||
args[0].node.connectattr('position',
|
||||
args[0].radius_visualizer_circle,
|
||||
'position')
|
||||
|
||||
bs.animate(
|
||||
args[0].radius_visualizer_circle, 'opacity', {
|
||||
0: 0.0,
|
||||
0.4: 0.1
|
||||
})
|
||||
|
||||
if bomb_type == 'tnt':
|
||||
args[0].fatal = bs.newnode('locator',
|
||||
owner=args[0].node,
|
||||
# Remove itself when the bomb node dies.
|
||||
attrs={
|
||||
'shape': 'circle',
|
||||
'color': (
|
||||
0.7, 0, 0),
|
||||
'opacity': 0.10,
|
||||
'draw_beauty': False,
|
||||
'additive': False
|
||||
})
|
||||
args[0].node.connectattr('position',
|
||||
args[0].fatal,
|
||||
'position')
|
||||
|
||||
bs.animate_array(args[0].fatal, 'size', 1, {
|
||||
0.0: [0.0],
|
||||
0.2: [args[0].blast_radius * 2.2 * 0.7],
|
||||
0.25: [args[0].blast_radius * 2.0 * 0.7]
|
||||
})
|
||||
|
||||
if babase.app.config.get(
|
||||
"bombCountdown") and bomb_type not in fuse_bomb:
|
||||
color = (1.0, 1.0, 0.0)
|
||||
count_bomb(*args, count='3', color=color)
|
||||
color = (1.0, 0.5, 0.0)
|
||||
bs.timer(1, bs.Call(count_bomb, *args, count='2', color=color))
|
||||
color = (1.0, 0.15, 0.15)
|
||||
bs.timer(2, bs.Call(count_bomb, *args, count='1', color=color))
|
||||
|
||||
return setting
|
||||
|
||||
bascenev1lib.actor.bomb.Bomb.__init__ = new_bomb_init(
|
||||
bascenev1lib.actor.bomb.Bomb.__init__)
|
||||
|
||||
|
||||
Spaz._pm2_spz_old = Spaz.__init__
|
||||
|
||||
|
||||
def _init_spaz_(self, *args, **kwargs):
|
||||
self._pm2_spz_old(*args, **kwargs)
|
||||
self.bot_radius = bs.newnode('locator',
|
||||
owner=self.node,
|
||||
# Remove itself when the bomb node dies.
|
||||
attrs={
|
||||
'shape': 'circle',
|
||||
'color': (0, 0, 1),
|
||||
'opacity': 0.0,
|
||||
'draw_beauty': False,
|
||||
'additive': False
|
||||
})
|
||||
self.node.connectattr('position',
|
||||
self.bot_radius,
|
||||
'position')
|
||||
|
||||
self.radius_visualizer_circle = bs.newnode(
|
||||
'locator',
|
||||
owner=self.node,
|
||||
# Remove itself when the bomb node dies.
|
||||
attrs={
|
||||
'shape': 'circleOutline',
|
||||
'size': [(self.hitpoints_max - self.hitpoints) * 0.0048],
|
||||
# Here's that bomb's blast radius value again!
|
||||
'color': (0, 1, 1),
|
||||
'draw_beauty': False,
|
||||
'additive': True
|
||||
})
|
||||
|
||||
self.node.connectattr('position', self.radius_visualizer_circle,
|
||||
'position')
|
||||
|
||||
self.curse_visualizer = bs.newnode('locator',
|
||||
owner=self.node,
|
||||
# Remove itself when the bomb node dies.
|
||||
attrs={
|
||||
'shape': 'circle',
|
||||
'color': (1, 0, 0),
|
||||
'size': (0.0, 0.0, 0.0),
|
||||
'opacity': 0.05,
|
||||
'draw_beauty': False,
|
||||
'additive': False
|
||||
})
|
||||
self.node.connectattr('position', self.curse_visualizer,
|
||||
'position')
|
||||
|
||||
self.curse_visualizer_circle = bs.newnode(
|
||||
'locator',
|
||||
owner=self.node,
|
||||
# Remove itself when the bomb node dies.
|
||||
attrs={
|
||||
'shape': 'circleOutline',
|
||||
'size': [3 * 2.0],
|
||||
# Here's that bomb's blast radius value again!
|
||||
'color': (
|
||||
1, 1, 0),
|
||||
'opacity': 0.0,
|
||||
'draw_beauty': False,
|
||||
'additive': True
|
||||
})
|
||||
self.node.connectattr('position',
|
||||
self.curse_visualizer_circle,
|
||||
'position')
|
||||
|
||||
self.curse_visualizer_fatal = bs.newnode('locator',
|
||||
owner=self.node,
|
||||
# Remove itself when the bomb node dies.
|
||||
attrs={
|
||||
'shape': 'circle',
|
||||
'color': (
|
||||
0.7, 0, 0),
|
||||
'size': (0.0, 0.0, 0.0),
|
||||
'opacity': 0.10,
|
||||
'draw_beauty': False,
|
||||
'additive': False
|
||||
})
|
||||
self.node.connectattr('position',
|
||||
self.curse_visualizer_fatal,
|
||||
'position')
|
||||
|
||||
def invincible() -> None:
|
||||
for i in bs.get_foreground_host_activity().players:
|
||||
try:
|
||||
if i.node:
|
||||
if babase.app.config.get("invincible"):
|
||||
i.actor.node.invincible = True
|
||||
else:
|
||||
i.actor.node.invincible = False
|
||||
except:
|
||||
pass
|
||||
|
||||
bs.timer(1.001, bs.Call(invincible))
|
||||
|
||||
|
||||
Spaz.__init__ = _init_spaz_
|
||||
|
||||
Spaz.super_curse = Spaz.curse
|
||||
|
||||
|
||||
def new_cursed(self):
|
||||
if self.node.invincible:
|
||||
return
|
||||
self.super_curse()
|
||||
if babase.app.config.get("bombRadiusVisual"):
|
||||
bs.animate_array(self.curse_visualizer, 'size', 1, {
|
||||
0.0: [0.0],
|
||||
0.2: [3 * 2.2],
|
||||
0.5: [3 * 2.0],
|
||||
5.0: [3 * 2.0],
|
||||
5.1: [0.0],
|
||||
})
|
||||
|
||||
bs.animate(
|
||||
self.curse_visualizer_circle, 'opacity', {
|
||||
0: 0.0,
|
||||
0.4: 0.1,
|
||||
5.0: 0.1,
|
||||
5.1: 0.0,
|
||||
bs.animate_array(args[0].radius_visualizer, 'size', 1, {
|
||||
0.0: [0.0],
|
||||
0.2: [args[0].blast_radius * 2.2],
|
||||
0.25: [args[0].blast_radius * 2.0]
|
||||
})
|
||||
|
||||
bs.animate_array(self.curse_visualizer_fatal, 'size', 1, {
|
||||
0.0: [0.0],
|
||||
0.2: [2.2],
|
||||
0.5: [2.0],
|
||||
5.0: [2.0],
|
||||
5.1: [0.0],
|
||||
})
|
||||
args[0].radius_visualizer_circle = bs.newnode(
|
||||
'locator',
|
||||
owner=args[
|
||||
0].node,
|
||||
# Remove itself when the bomb node dies.
|
||||
attrs={
|
||||
'shape': 'circleOutline',
|
||||
'size': [
|
||||
args[
|
||||
0].blast_radius * 2.0],
|
||||
# Here's that bomb's blast radius value again!
|
||||
'color': (
|
||||
1, 1, 0),
|
||||
'draw_beauty': False,
|
||||
'additive': True
|
||||
})
|
||||
args[0].node.connectattr('position',
|
||||
args[0].radius_visualizer_circle,
|
||||
'position')
|
||||
|
||||
bs.animate(
|
||||
args[0].radius_visualizer_circle, 'opacity', {
|
||||
0: 0.0,
|
||||
0.4: 0.1
|
||||
})
|
||||
|
||||
if bomb_type == 'tnt':
|
||||
args[0].fatal = bs.newnode('locator',
|
||||
owner=args[0].node,
|
||||
# Remove itself when the bomb node dies.
|
||||
attrs={
|
||||
'shape': 'circle',
|
||||
'color': (
|
||||
0.7, 0, 0),
|
||||
'opacity': 0.10,
|
||||
'draw_beauty': False,
|
||||
'additive': False
|
||||
})
|
||||
args[0].node.connectattr('position',
|
||||
args[0].fatal,
|
||||
'position')
|
||||
|
||||
bs.animate_array(args[0].fatal, 'size', 1, {
|
||||
0.0: [0.0],
|
||||
0.2: [args[0].blast_radius * 2.2 * 0.7],
|
||||
0.25: [args[0].blast_radius * 2.0 * 0.7]
|
||||
})
|
||||
|
||||
if babase.app.config.get(
|
||||
"bombCountdown") and bomb_type not in fuse_bomb:
|
||||
color = (1.0, 1.0, 0.0)
|
||||
count_bomb(*args, count='3', color=color)
|
||||
color = (1.0, 0.5, 0.0)
|
||||
bs.timer(1, bs.Call(count_bomb, *args, count='2', color=color))
|
||||
color = (1.0, 0.15, 0.15)
|
||||
bs.timer(2, bs.Call(count_bomb, *args, count='1', color=color))
|
||||
|
||||
return setting
|
||||
|
||||
|
||||
Spaz.curse = new_cursed
|
||||
|
||||
Spaz.super_handlemessage = Spaz.handlemessage
|
||||
bascenev1lib.actor.bomb.Bomb.__init__ = new_bomb_init(
|
||||
bascenev1lib.actor.bomb.Bomb.__init__)
|
||||
|
||||
|
||||
def bot_handlemessage(self, msg: Any):
|
||||
if isinstance(msg, bs.PowerupMessage):
|
||||
if msg.poweruptype == 'health':
|
||||
if babase.app.config.get("bombRadiusVisual"):
|
||||
if self._cursed:
|
||||
bs.animate_array(self.curse_visualizer, 'size', 1, {
|
||||
0.0: [3 * 2.0],
|
||||
0.2: [0.0],
|
||||
})
|
||||
def _init_spaz_(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
func(*args, **kwargs)
|
||||
args[0].bot_radius = bs.newnode('locator',
|
||||
owner=args[0].node,
|
||||
attrs={
|
||||
'shape': 'circle',
|
||||
'color': (0, 0, 1),
|
||||
'opacity': 0.0,
|
||||
'draw_beauty': False,
|
||||
'additive': False
|
||||
})
|
||||
args[0].node.connectattr('position',
|
||||
args[0].bot_radius,
|
||||
'position')
|
||||
|
||||
bs.animate(
|
||||
self.curse_visualizer_circle, 'opacity', {
|
||||
0.0: 0.1,
|
||||
0.2: 0.0,
|
||||
args[0].radius_visualizer_circle = bs.newnode(
|
||||
'locator',
|
||||
owner=args[0].node,
|
||||
attrs={
|
||||
'shape': 'circleOutline',
|
||||
'size': [(args[0].hitpoints_max - args[0].hitpoints) * 0.0048],
|
||||
'color': (0, 1, 1),
|
||||
'draw_beauty': False,
|
||||
'additive': True
|
||||
})
|
||||
|
||||
args[0].node.connectattr('position', args[0].radius_visualizer_circle,
|
||||
'position')
|
||||
|
||||
args[0].curse_visualizer = bs.newnode('locator',
|
||||
owner=args[0].node,
|
||||
attrs={
|
||||
'shape': 'circle',
|
||||
'color': (1, 0, 0),
|
||||
'size': (0.0, 0.0, 0.0),
|
||||
'opacity': 0.05,
|
||||
'draw_beauty': False,
|
||||
'additive': False
|
||||
})
|
||||
args[0].node.connectattr('position', args[0].curse_visualizer,
|
||||
'position')
|
||||
|
||||
args[0].curse_visualizer_circle = bs.newnode(
|
||||
'locator',
|
||||
owner=args[0].node,
|
||||
attrs={
|
||||
'shape': 'circleOutline',
|
||||
'size': [3 * 2.0],
|
||||
'color': (
|
||||
1, 1, 0),
|
||||
'opacity': 0.0,
|
||||
'draw_beauty': False,
|
||||
'additive': True
|
||||
})
|
||||
args[0].node.connectattr('position',
|
||||
args[0].curse_visualizer_circle,
|
||||
'position')
|
||||
|
||||
args[0].curse_visualizer_fatal = bs.newnode('locator',
|
||||
owner=args[0].node,
|
||||
attrs={
|
||||
'shape': 'circle',
|
||||
'color': (
|
||||
0.7, 0, 0),
|
||||
'size': (0.0, 0.0, 0.0),
|
||||
'opacity': 0.10,
|
||||
'draw_beauty': False,
|
||||
'additive': False
|
||||
})
|
||||
args[0].node.connectattr('position',
|
||||
args[0].curse_visualizer_fatal,
|
||||
'position')
|
||||
|
||||
def invincible() -> None:
|
||||
for i in bs.get_foreground_host_activity().players:
|
||||
try:
|
||||
if i.node:
|
||||
if babase.app.config.get("invincible"):
|
||||
i.actor.node.invincible = True
|
||||
else:
|
||||
i.actor.node.invincible = False
|
||||
except:
|
||||
pass
|
||||
|
||||
bs.timer(1.001, bs.Call(invincible))
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
Spaz.__init__ = _init_spaz_(Spaz.__init__)
|
||||
|
||||
|
||||
def new_cursed(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
if args[0].node.invincible:
|
||||
return
|
||||
func(*args, **kwargs)
|
||||
if babase.app.config.get("bombRadiusVisual"):
|
||||
bs.animate_array(args[0].curse_visualizer, 'size', 1, {
|
||||
0.0: [0.0],
|
||||
0.2: [3 * 2.2],
|
||||
0.5: [3 * 2.0],
|
||||
5.0: [3 * 2.0],
|
||||
5.1: [0.0],
|
||||
})
|
||||
|
||||
bs.animate(
|
||||
args[0].curse_visualizer_circle, 'opacity', {
|
||||
0: 0.0,
|
||||
0.4: 0.1,
|
||||
5.0: 0.1,
|
||||
5.1: 0.0,
|
||||
})
|
||||
|
||||
bs.animate_array(args[0].curse_visualizer_fatal, 'size', 1, {
|
||||
0.0: [0.0],
|
||||
0.2: [2.2],
|
||||
0.5: [2.0],
|
||||
5.0: [2.0],
|
||||
5.1: [0.0],
|
||||
})
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
Spaz.curse = new_cursed(Spaz.curse)
|
||||
|
||||
|
||||
def bot_handlemessage(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
|
||||
if isinstance(args[1], bs.PowerupMessage):
|
||||
if args[1].poweruptype == 'health':
|
||||
if babase.app.config.get("bombRadiusVisual"):
|
||||
if args[0]._cursed:
|
||||
bs.animate_array(args[0].curse_visualizer, 'size', 1, {
|
||||
0.0: [3 * 2.0],
|
||||
0.2: [0.0],
|
||||
})
|
||||
|
||||
bs.animate_array(self.curse_visualizer_fatal, 'size', 1, {
|
||||
0.0: [2.0],
|
||||
0.2: [0.0],
|
||||
bs.animate(
|
||||
args[0].curse_visualizer_circle, 'opacity', {
|
||||
0.0: 0.1,
|
||||
0.2: 0.0,
|
||||
})
|
||||
|
||||
bs.animate_array(args[0].curse_visualizer_fatal, 'size',
|
||||
1,
|
||||
{
|
||||
0.0: [2.0],
|
||||
0.2: [0.0],
|
||||
})
|
||||
|
||||
bs.animate_array(args[0].bot_radius, 'size', 1, {
|
||||
0.0: [0],
|
||||
0.25: [0]
|
||||
})
|
||||
|
||||
bs.animate_array(self.bot_radius, 'size', 1, {
|
||||
0.0: [0],
|
||||
0.25: [0]
|
||||
})
|
||||
bs.animate(self.bot_radius, 'opacity', {
|
||||
0.0: 0.00,
|
||||
0.25: 0.0
|
||||
})
|
||||
|
||||
bs.animate_array(self.radius_visualizer_circle, 'size', 1, {
|
||||
0.0: [0],
|
||||
0.25: [0]
|
||||
})
|
||||
|
||||
bs.animate(
|
||||
self.radius_visualizer_circle, 'opacity', {
|
||||
bs.animate(args[0].bot_radius, 'opacity', {
|
||||
0.0: 0.00,
|
||||
0.25: 0.0
|
||||
})
|
||||
|
||||
self.super_handlemessage(msg)
|
||||
bs.animate_array(args[0].radius_visualizer_circle, 'size',
|
||||
1, {
|
||||
0.0: [0],
|
||||
0.25: [0]
|
||||
})
|
||||
|
||||
if isinstance(msg, bs.HitMessage):
|
||||
if self.hitpoints <= 0:
|
||||
bs.animate(self.bot_radius, 'opacity', {
|
||||
0.0: 0.00
|
||||
})
|
||||
bs.animate(
|
||||
self.radius_visualizer_circle, 'opacity', {
|
||||
bs.animate(
|
||||
args[0].radius_visualizer_circle, 'opacity', {
|
||||
0.0: 0.00,
|
||||
0.25: 0.0
|
||||
})
|
||||
if not (babase.app.config.get("powerupsExpire") and
|
||||
args[0].powerups_expire):
|
||||
if args[1].poweruptype == 'triple_bombs':
|
||||
tex = PowerupBoxFactory.get().tex_bomb
|
||||
args[0]._flash_billboard(tex)
|
||||
args[0].set_bomb_count(3)
|
||||
|
||||
elif args[1].poweruptype == 'impact_bombs':
|
||||
args[0].bomb_type = 'impact'
|
||||
tex = args[0]._get_bomb_type_tex()
|
||||
args[0]._flash_billboard(tex)
|
||||
|
||||
elif args[1].poweruptype == 'sticky_bombs':
|
||||
args[0].bomb_type = 'sticky'
|
||||
tex = args[0]._get_bomb_type_tex()
|
||||
args[0]._flash_billboard(tex)
|
||||
|
||||
elif args[1].poweruptype == 'punch':
|
||||
tex = PowerupBoxFactory.get().tex_punch
|
||||
args[0]._flash_billboard(tex)
|
||||
args[0].equip_boxing_gloves()
|
||||
|
||||
elif args[1].poweruptype == 'ice_bombs':
|
||||
args[0].bomb_type = 'ice'
|
||||
tex = args[0]._get_bomb_type_tex()
|
||||
args[0]._flash_billboard(tex)
|
||||
|
||||
if args[1].poweruptype in ['triple_bombs', 'impact_bombs',
|
||||
'sticky_bombs', 'punch',
|
||||
'ice_bombs']:
|
||||
args[0].node.handlemessage('flash')
|
||||
if args[1].sourcenode:
|
||||
args[1].sourcenode.handlemessage(
|
||||
bs.PowerupAcceptMessage())
|
||||
return True
|
||||
|
||||
func(*args, **kwargs)
|
||||
|
||||
if isinstance(args[1], bs.HitMessage):
|
||||
if args[0].hitpoints <= 0:
|
||||
bs.animate(args[0].bot_radius, 'opacity', {
|
||||
0.0: 0.00
|
||||
})
|
||||
elif babase.app.config.get('bombRadiusVisual'):
|
||||
bs.animate(
|
||||
args[0].radius_visualizer_circle, 'opacity', {
|
||||
0.0: 0.00
|
||||
})
|
||||
elif babase.app.config.get('bombRadiusVisual'):
|
||||
|
||||
bs.animate_array(self.bot_radius, 'size', 1, {
|
||||
0.0: [(self.hitpoints_max - self.hitpoints) * 0.0045],
|
||||
0.25: [(self.hitpoints_max - self.hitpoints) * 0.0045]
|
||||
})
|
||||
bs.animate(self.bot_radius, 'opacity', {
|
||||
0.0: 0.00,
|
||||
0.25: 0.05
|
||||
})
|
||||
|
||||
bs.animate_array(self.radius_visualizer_circle, 'size', 1, {
|
||||
0.0: [(self.hitpoints_max - self.hitpoints) * 0.0045],
|
||||
0.25: [(self.hitpoints_max - self.hitpoints) * 0.0045]
|
||||
})
|
||||
|
||||
bs.animate(
|
||||
self.radius_visualizer_circle, 'opacity', {
|
||||
bs.animate_array(args[0].bot_radius, 'size', 1, {
|
||||
0.0: [(args[0].hitpoints_max - args[0].hitpoints) * 0.0045],
|
||||
0.25: [(args[0].hitpoints_max - args[0].hitpoints) * 0.0045]
|
||||
})
|
||||
bs.animate(args[0].bot_radius, 'opacity', {
|
||||
0.0: 0.00,
|
||||
0.25: 0.1
|
||||
0.25: 0.05
|
||||
})
|
||||
|
||||
bs.animate_array(args[0].radius_visualizer_circle, 'size', 1, {
|
||||
0.0: [(args[0].hitpoints_max - args[0].hitpoints) * 0.0045],
|
||||
0.25: [(args[0].hitpoints_max - args[0].hitpoints) * 0.0045]
|
||||
})
|
||||
|
||||
Spaz.handlemessage = bot_handlemessage
|
||||
bs.animate(
|
||||
args[0].radius_visualizer_circle, 'opacity', {
|
||||
0.0: 0.00,
|
||||
0.25: 0.1
|
||||
})
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
Spaz.handlemessage = bot_handlemessage(Spaz.handlemessage)
|
||||
|
||||
|
||||
def count_bomb(*args, count, color):
|
||||
text = bs.newnode('math', owner=args[0].node,
|
||||
attrs={'input1': (0, 0.7, 0),
|
||||
'operation': 'add'})
|
||||
args[0].node.connectattr('position', text, 'input2')
|
||||
args[0].spaztext = bs.newnode('text',
|
||||
owner=args[0].node,
|
||||
attrs={
|
||||
'text': count,
|
||||
'in_world': True,
|
||||
'color': color,
|
||||
'shadow': 1.0,
|
||||
'flatness': 1.0,
|
||||
'scale': 0.012,
|
||||
'h_align': 'center',
|
||||
})
|
||||
if args[0].node.exists():
|
||||
text = bs.newnode('math', owner=args[0].node,
|
||||
attrs={'input1': (0, 0.7, 0),
|
||||
'operation': 'add'})
|
||||
args[0].node.connectattr('position', text, 'input2')
|
||||
args[0].spaztext = bs.newnode('text',
|
||||
owner=args[0].node,
|
||||
attrs={
|
||||
'text': count,
|
||||
'in_world': True,
|
||||
'color': color,
|
||||
'shadow': 1.0,
|
||||
'flatness': 1.0,
|
||||
'scale': 0.012,
|
||||
'h_align': 'center',
|
||||
})
|
||||
|
||||
args[0].node.connectattr('position', args[0].spaztext,
|
||||
'position')
|
||||
bs.animate(args[0].spaztext, 'scale',
|
||||
{0: 0, 0.3: 0.03, 0.5: 0.025, 0.8: 0.025, 1.0: 0.0})
|
||||
args[0].node.connectattr('position', args[0].spaztext,
|
||||
'position')
|
||||
bs.animate(args[0].spaztext, 'scale',
|
||||
{0: 0, 0.3: 0.03, 0.5: 0.025, 0.8: 0.025, 1.0: 0.0})
|
||||
|
||||
|
||||
def doTestButton(self):
|
||||
|
|
@ -1211,8 +1225,9 @@ class PowerUpPracticeTab(PracticeTab):
|
|||
'shield', 'sticky_bombs'])
|
||||
self._icon_index = self.load_settings()
|
||||
|
||||
self.setting_name = (['Bomb Countdown', 'Bomb Radius Visualizer'])
|
||||
self.config = (['bombCountdown', 'bombRadiusVisual'])
|
||||
self.setting_name = (
|
||||
['Bomb Countdown', 'Bomb Radius Visualizer', 'Powerups Expire'])
|
||||
self.config = (['bombCountdown', 'bombRadiusVisual', 'powerupsExpire'])
|
||||
|
||||
def on_activate(
|
||||
self,
|
||||
|
|
@ -1238,7 +1253,7 @@ class PowerUpPracticeTab(PracticeTab):
|
|||
self._sub_width = self._scroll_width
|
||||
self._sub_height = 200
|
||||
|
||||
self.container_h = 450
|
||||
self.container_h = 550
|
||||
power_height = self.container_h - 50
|
||||
|
||||
self._subcontainer = bui.containerwidget(
|
||||
|
|
@ -1426,6 +1441,11 @@ class PowerUpPracticeTab(PracticeTab):
|
|||
babase.app.config["bombRadiusVisual"] = True
|
||||
else:
|
||||
babase.app.config["bombRadiusVisual"] = False
|
||||
elif setting == 2:
|
||||
if value:
|
||||
babase.app.config["powerupsExpire"] = True
|
||||
else:
|
||||
babase.app.config["powerupsExpire"] = False
|
||||
|
||||
def load_settings(self):
|
||||
try:
|
||||
|
|
@ -2204,9 +2224,9 @@ class InfoWindow(popup.PopupWindow):
|
|||
text = ('Practice Tools Mod\n'
|
||||
'Made By Cross Joy\n'
|
||||
'version v' + version + '\n'
|
||||
'\n'
|
||||
'Thx to\n'
|
||||
'Mikirog for the Bomb radius visualizer mod.\n'
|
||||
'\n'
|
||||
'Thx to\n'
|
||||
'Mikirog for the Bomb radius visualizer mod.\n'
|
||||
)
|
||||
|
||||
lines = text.splitlines()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue