Update practice_tools.py

Update to ver 2.2
This commit is contained in:
Cross Joy 2024-02-14 18:43:00 +08:00 committed by GitHub
parent 3f6bead9e2
commit 5bce0885d8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,4 +1,4 @@
"""Practice Tools Mod: V2.1 """Practice Tools Mod: V2.2
Made by Cross Joy""" Made by Cross Joy"""
# If anyone who want to help me on giving suggestion/ fix bugs/ creating PR, # 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 # 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 # V2.2 update
# - Updated to API 8 (1.7.20+) # - 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. # Powerful and comprehensive tools for practice purpose.
@ -72,7 +59,8 @@ import bascenev1lib
import bauiv1 as bui import bauiv1 as bui
from bauiv1lib import mainmenu from bauiv1lib import mainmenu
from babase import app, Plugin 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.spaz import Spaz
from bascenev1lib.actor import spawner from bascenev1lib.actor import spawner
from bascenev1lib.actor.spazbot import (SpazBotSet, SpazBot, BrawlerBot, from bascenev1lib.actor.spazbot import (SpazBotSet, SpazBot, BrawlerBot,
@ -94,47 +82,35 @@ from bauiv1lib.tabs import TabRow
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any, Sequence, Callable, Optional 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: class ConfigLoader:
if babase.app.config.get("bombRadiusVisual") is None: def __init__(self):
babase.app.config["bombRadiusVisual"] = False self.config_data = {
else: "Practice Tab": False,
babase.app.config.get("bombRadiusVisual") "bombCountdown": False,
except: "bombRadiusVisual": False,
babase.app.config["bombRadiusVisual"] = False "stopBots": False,
"immortalDummy": False,
"powerupsExpire": False,
"invincible": False
}
self.config_names = ["Practice Tab", "bombCountdown",
"bombRadiusVisual", "stopBots",
"immortalDummy", "powerupsExpire", "invincible"]
def load_configs(self):
for config_name in self.config_names:
try: try:
if babase.app.config.get("stopBots") is None: existing_config = babase.app.config.get(config_name)
babase.app.config["stopBots"] = False if existing_config is None:
babase.app.config[config_name] = self.config_data[
config_name]
else: else:
babase.app.config.get("stopBots") babase.app.config.get(config_name)
except: except:
babase.app.config["stopBots"] = False babase.app.config[config_name] = self.config_data[config_name]
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
class PartyWindow(bui.Window): class PartyWindow(bui.Window):
@ -174,7 +150,7 @@ def redefine_class(original_cls: object, cls: object) -> None:
def main(plugin: Plugin) -> None: def main(plugin: Plugin) -> None:
print(f'Plugins Tools v{plugin.__version__}') print(f'Practice Tools v{plugin.__version__}')
app.practice_tool = plugin app.practice_tool = plugin
redefine_class(OriginalPartyWindow, PartyWindow) redefine_class(OriginalPartyWindow, PartyWindow)
@ -185,10 +161,9 @@ class NewMainMenuWindow(mainmenu.MainMenuWindow):
# Display chat icon, but if user open/close gather it may disappear # Display chat icon, but if user open/close gather it may disappear
bui.set_party_icon_always_visible(True) bui.set_party_icon_always_visible(True)
# ba_meta require api 8 # ba_meta require api 8
# ba_meta export plugin # ba_meta export plugin
class Practice(Plugin): class Practice(Plugin):
__version__ = version __version__ = version
@ -202,8 +177,11 @@ class Practice(Plugin):
raise RuntimeError( raise RuntimeError(
'sad') 'sad')
mainmenu.MainMenuWindow = NewMainMenuWindow mainmenu.MainMenuWindow = NewMainMenuWindow
config_loader = ConfigLoader()
config_loader.load_configs()
return main(self) return main(self)
def new_bomb_init(func): def new_bomb_init(func):
def setting(*args, **kwargs): def setting(*args, **kwargs):
func(*args, **kwargs) func(*args, **kwargs)
@ -290,18 +268,16 @@ class Practice(Plugin):
return setting return setting
bascenev1lib.actor.bomb.Bomb.__init__ = new_bomb_init( bascenev1lib.actor.bomb.Bomb.__init__ = new_bomb_init(
bascenev1lib.actor.bomb.Bomb.__init__) bascenev1lib.actor.bomb.Bomb.__init__)
Spaz._pm2_spz_old = Spaz.__init__ def _init_spaz_(func):
def wrapper(*args, **kwargs):
func(*args, **kwargs)
def _init_spaz_(self, *args, **kwargs): args[0].bot_radius = bs.newnode('locator',
self._pm2_spz_old(*args, **kwargs) owner=args[0].node,
self.bot_radius = bs.newnode('locator',
owner=self.node,
# Remove itself when the bomb node dies.
attrs={ attrs={
'shape': 'circle', 'shape': 'circle',
'color': (0, 0, 1), 'color': (0, 0, 1),
@ -309,29 +285,26 @@ def _init_spaz_(self, *args, **kwargs):
'draw_beauty': False, 'draw_beauty': False,
'additive': False 'additive': False
}) })
self.node.connectattr('position', args[0].node.connectattr('position',
self.bot_radius, args[0].bot_radius,
'position') 'position')
self.radius_visualizer_circle = bs.newnode( args[0].radius_visualizer_circle = bs.newnode(
'locator', 'locator',
owner=self.node, owner=args[0].node,
# Remove itself when the bomb node dies.
attrs={ attrs={
'shape': 'circleOutline', 'shape': 'circleOutline',
'size': [(self.hitpoints_max - self.hitpoints) * 0.0048], 'size': [(args[0].hitpoints_max - args[0].hitpoints) * 0.0048],
# Here's that bomb's blast radius value again!
'color': (0, 1, 1), 'color': (0, 1, 1),
'draw_beauty': False, 'draw_beauty': False,
'additive': True 'additive': True
}) })
self.node.connectattr('position', self.radius_visualizer_circle, args[0].node.connectattr('position', args[0].radius_visualizer_circle,
'position') 'position')
self.curse_visualizer = bs.newnode('locator', args[0].curse_visualizer = bs.newnode('locator',
owner=self.node, owner=args[0].node,
# Remove itself when the bomb node dies.
attrs={ attrs={
'shape': 'circle', 'shape': 'circle',
'color': (1, 0, 0), 'color': (1, 0, 0),
@ -340,30 +313,27 @@ def _init_spaz_(self, *args, **kwargs):
'draw_beauty': False, 'draw_beauty': False,
'additive': False 'additive': False
}) })
self.node.connectattr('position', self.curse_visualizer, args[0].node.connectattr('position', args[0].curse_visualizer,
'position') 'position')
self.curse_visualizer_circle = bs.newnode( args[0].curse_visualizer_circle = bs.newnode(
'locator', 'locator',
owner=self.node, owner=args[0].node,
# Remove itself when the bomb node dies.
attrs={ attrs={
'shape': 'circleOutline', 'shape': 'circleOutline',
'size': [3 * 2.0], 'size': [3 * 2.0],
# Here's that bomb's blast radius value again!
'color': ( 'color': (
1, 1, 0), 1, 1, 0),
'opacity': 0.0, 'opacity': 0.0,
'draw_beauty': False, 'draw_beauty': False,
'additive': True 'additive': True
}) })
self.node.connectattr('position', args[0].node.connectattr('position',
self.curse_visualizer_circle, args[0].curse_visualizer_circle,
'position') 'position')
self.curse_visualizer_fatal = bs.newnode('locator', args[0].curse_visualizer_fatal = bs.newnode('locator',
owner=self.node, owner=args[0].node,
# Remove itself when the bomb node dies.
attrs={ attrs={
'shape': 'circle', 'shape': 'circle',
'color': ( 'color': (
@ -373,8 +343,8 @@ def _init_spaz_(self, *args, **kwargs):
'draw_beauty': False, 'draw_beauty': False,
'additive': False 'additive': False
}) })
self.node.connectattr('position', args[0].node.connectattr('position',
self.curse_visualizer_fatal, args[0].curse_visualizer_fatal,
'position') 'position')
def invincible() -> None: def invincible() -> None:
@ -390,18 +360,19 @@ def _init_spaz_(self, *args, **kwargs):
bs.timer(1.001, bs.Call(invincible)) bs.timer(1.001, bs.Call(invincible))
return wrapper
Spaz.__init__ = _init_spaz_
Spaz.super_curse = Spaz.curse
def new_cursed(self): Spaz.__init__ = _init_spaz_(Spaz.__init__)
if self.node.invincible:
def new_cursed(func):
def wrapper(*args, **kwargs):
if args[0].node.invincible:
return return
self.super_curse() func(*args, **kwargs)
if babase.app.config.get("bombRadiusVisual"): if babase.app.config.get("bombRadiusVisual"):
bs.animate_array(self.curse_visualizer, 'size', 1, { bs.animate_array(args[0].curse_visualizer, 'size', 1, {
0.0: [0.0], 0.0: [0.0],
0.2: [3 * 2.2], 0.2: [3 * 2.2],
0.5: [3 * 2.0], 0.5: [3 * 2.0],
@ -410,14 +381,14 @@ def new_cursed(self):
}) })
bs.animate( bs.animate(
self.curse_visualizer_circle, 'opacity', { args[0].curse_visualizer_circle, 'opacity', {
0: 0.0, 0: 0.0,
0.4: 0.1, 0.4: 0.1,
5.0: 0.1, 5.0: 0.1,
5.1: 0.0, 5.1: 0.0,
}) })
bs.animate_array(self.curse_visualizer_fatal, 'size', 1, { bs.animate_array(args[0].curse_visualizer_fatal, 'size', 1, {
0.0: [0.0], 0.0: [0.0],
0.2: [2.2], 0.2: [2.2],
0.5: [2.0], 0.5: [2.0],
@ -425,91 +396,134 @@ def new_cursed(self):
5.1: [0.0], 5.1: [0.0],
}) })
return wrapper
Spaz.curse = new_cursed
Spaz.super_handlemessage = Spaz.handlemessage
def bot_handlemessage(self, msg: Any): Spaz.curse = new_cursed(Spaz.curse)
if isinstance(msg, bs.PowerupMessage):
if msg.poweruptype == 'health':
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 babase.app.config.get("bombRadiusVisual"):
if self._cursed: if args[0]._cursed:
bs.animate_array(self.curse_visualizer, 'size', 1, { bs.animate_array(args[0].curse_visualizer, 'size', 1, {
0.0: [3 * 2.0], 0.0: [3 * 2.0],
0.2: [0.0], 0.2: [0.0],
}) })
bs.animate( bs.animate(
self.curse_visualizer_circle, 'opacity', { args[0].curse_visualizer_circle, 'opacity', {
0.0: 0.1, 0.0: 0.1,
0.2: 0.0, 0.2: 0.0,
}) })
bs.animate_array(self.curse_visualizer_fatal, 'size', 1, { bs.animate_array(args[0].curse_visualizer_fatal, 'size',
1,
{
0.0: [2.0], 0.0: [2.0],
0.2: [0.0], 0.2: [0.0],
}) })
bs.animate_array(self.bot_radius, 'size', 1, { bs.animate_array(args[0].bot_radius, 'size', 1, {
0.0: [0], 0.0: [0],
0.25: [0] 0.25: [0]
}) })
bs.animate(self.bot_radius, 'opacity', { bs.animate(args[0].bot_radius, 'opacity', {
0.0: 0.00, 0.0: 0.00,
0.25: 0.0 0.25: 0.0
}) })
bs.animate_array(self.radius_visualizer_circle, 'size', 1, { bs.animate_array(args[0].radius_visualizer_circle, 'size',
1, {
0.0: [0], 0.0: [0],
0.25: [0] 0.25: [0]
}) })
bs.animate( bs.animate(
self.radius_visualizer_circle, 'opacity', { args[0].radius_visualizer_circle, 'opacity', {
0.0: 0.00, 0.0: 0.00,
0.25: 0.0 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)
self.super_handlemessage(msg) elif args[1].poweruptype == 'impact_bombs':
args[0].bomb_type = 'impact'
tex = args[0]._get_bomb_type_tex()
args[0]._flash_billboard(tex)
if isinstance(msg, bs.HitMessage): elif args[1].poweruptype == 'sticky_bombs':
if self.hitpoints <= 0: args[0].bomb_type = 'sticky'
bs.animate(self.bot_radius, 'opacity', { 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 0.0: 0.00
}) })
bs.animate( bs.animate(
self.radius_visualizer_circle, 'opacity', { args[0].radius_visualizer_circle, 'opacity', {
0.0: 0.00 0.0: 0.00
}) })
elif babase.app.config.get('bombRadiusVisual'): elif babase.app.config.get('bombRadiusVisual'):
bs.animate_array(self.bot_radius, 'size', 1, { bs.animate_array(args[0].bot_radius, 'size', 1, {
0.0: [(self.hitpoints_max - self.hitpoints) * 0.0045], 0.0: [(args[0].hitpoints_max - args[0].hitpoints) * 0.0045],
0.25: [(self.hitpoints_max - self.hitpoints) * 0.0045] 0.25: [(args[0].hitpoints_max - args[0].hitpoints) * 0.0045]
}) })
bs.animate(self.bot_radius, 'opacity', { bs.animate(args[0].bot_radius, 'opacity', {
0.0: 0.00, 0.0: 0.00,
0.25: 0.05 0.25: 0.05
}) })
bs.animate_array(self.radius_visualizer_circle, 'size', 1, { bs.animate_array(args[0].radius_visualizer_circle, 'size', 1, {
0.0: [(self.hitpoints_max - self.hitpoints) * 0.0045], 0.0: [(args[0].hitpoints_max - args[0].hitpoints) * 0.0045],
0.25: [(self.hitpoints_max - self.hitpoints) * 0.0045] 0.25: [(args[0].hitpoints_max - args[0].hitpoints) * 0.0045]
}) })
bs.animate( bs.animate(
self.radius_visualizer_circle, 'opacity', { args[0].radius_visualizer_circle, 'opacity', {
0.0: 0.00, 0.0: 0.00,
0.25: 0.1 0.25: 0.1
}) })
return wrapper
Spaz.handlemessage = bot_handlemessage
Spaz.handlemessage = bot_handlemessage(Spaz.handlemessage)
def count_bomb(*args, count, color): def count_bomb(*args, count, color):
if args[0].node.exists():
text = bs.newnode('math', owner=args[0].node, text = bs.newnode('math', owner=args[0].node,
attrs={'input1': (0, 0.7, 0), attrs={'input1': (0, 0.7, 0),
'operation': 'add'}) 'operation': 'add'})
@ -1211,8 +1225,9 @@ class PowerUpPracticeTab(PracticeTab):
'shield', 'sticky_bombs']) 'shield', 'sticky_bombs'])
self._icon_index = self.load_settings() self._icon_index = self.load_settings()
self.setting_name = (['Bomb Countdown', 'Bomb Radius Visualizer']) self.setting_name = (
self.config = (['bombCountdown', 'bombRadiusVisual']) ['Bomb Countdown', 'Bomb Radius Visualizer', 'Powerups Expire'])
self.config = (['bombCountdown', 'bombRadiusVisual', 'powerupsExpire'])
def on_activate( def on_activate(
self, self,
@ -1238,7 +1253,7 @@ class PowerUpPracticeTab(PracticeTab):
self._sub_width = self._scroll_width self._sub_width = self._scroll_width
self._sub_height = 200 self._sub_height = 200
self.container_h = 450 self.container_h = 550
power_height = self.container_h - 50 power_height = self.container_h - 50
self._subcontainer = bui.containerwidget( self._subcontainer = bui.containerwidget(
@ -1426,6 +1441,11 @@ class PowerUpPracticeTab(PracticeTab):
babase.app.config["bombRadiusVisual"] = True babase.app.config["bombRadiusVisual"] = True
else: else:
babase.app.config["bombRadiusVisual"] = False 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): def load_settings(self):
try: try: