diff --git a/.idea/ballisticakit.iml b/.idea/ballisticakit.iml
index 45327b93..4c2844c3 100644
--- a/.idea/ballisticakit.iml
+++ b/.idea/ballisticakit.iml
@@ -74,4 +74,4 @@
-
\ No newline at end of file
+
diff --git a/.idea/misc.xml b/.idea/misc.xml
index e94ce45b..7326dccb 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -10,4 +10,4 @@
-
\ No newline at end of file
+
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 6aacc6ad..8fccc544 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -41,9 +41,9 @@
- Modder
### Era0S
+- Community Suggestions Implementer
- Bug Fixer
- Modder
-- Added a feature
### VinniTR
- Fixes
diff --git a/src/assets/.asset_manifest_public.json b/src/assets/.asset_manifest_public.json
index 4ff9c920..55998cf7 100644
--- a/src/assets/.asset_manifest_public.json
+++ b/src/assets/.asset_manifest_public.json
@@ -370,6 +370,7 @@
"ba_data/python/bauiv1lib/__pycache__/continues.cpython-311.opt-1.pyc",
"ba_data/python/bauiv1lib/__pycache__/creditslist.cpython-311.opt-1.pyc",
"ba_data/python/bauiv1lib/__pycache__/debug.cpython-311.opt-1.pyc",
+ "ba_data/python/bauiv1lib/__pycache__/discord.cpython-311.opt-1.pyc",
"ba_data/python/bauiv1lib/__pycache__/feedback.cpython-311.opt-1.pyc",
"ba_data/python/bauiv1lib/__pycache__/fileselector.cpython-311.opt-1.pyc",
"ba_data/python/bauiv1lib/__pycache__/getcurrency.cpython-311.opt-1.pyc",
@@ -430,6 +431,7 @@
"ba_data/python/bauiv1lib/coop/tournamentbutton.py",
"ba_data/python/bauiv1lib/creditslist.py",
"ba_data/python/bauiv1lib/debug.py",
+ "ba_data/python/bauiv1lib/discord.py",
"ba_data/python/bauiv1lib/feedback.py",
"ba_data/python/bauiv1lib/fileselector.py",
"ba_data/python/bauiv1lib/gather/__init__.py",
diff --git a/src/assets/ba_data/python/bascenev1lib/actor/spaz.py b/src/assets/ba_data/python/bascenev1lib/actor/spaz.py
index e38be539..71a31a4c 100644
--- a/src/assets/ba_data/python/bascenev1lib/actor/spaz.py
+++ b/src/assets/ba_data/python/bascenev1lib/actor/spaz.py
@@ -624,7 +624,7 @@ class Spaz(bs.Actor):
1000.0 * (tval + self.curse_time)
)
self._curse_timer = bs.Timer(
- 5.0, bs.WeakCall(self.curse_explode)
+ 5.0, bs.WeakCall(self.handlemessage, CurseExplodeMessage())
)
def equip_boxing_gloves(self) -> None:
diff --git a/src/assets/ba_data/python/bauiv1lib/discord.py b/src/assets/ba_data/python/bauiv1lib/discord.py
new file mode 100644
index 00000000..22060d8c
--- /dev/null
+++ b/src/assets/ba_data/python/bauiv1lib/discord.py
@@ -0,0 +1,129 @@
+# Released under the MIT License. See LICENSE for details.
+#
+"""UI functionality for the Discord window."""
+
+from __future__ import annotations
+
+import bauiv1 as bui
+
+
+class DiscordWindow(bui.Window):
+ """Window for joining the Discord."""
+
+ def __init__(
+ self,
+ transition: str = 'in_right',
+ origin_widget: bui.Widget | None = None,
+ ):
+ if bui.app.classic is None:
+ raise RuntimeError('This requires classic support.')
+
+ app = bui.app
+ assert app.classic is not None
+
+ # If they provided an origin-widget, scale up from that.
+ scale_origin: tuple[float, float] | None
+ if origin_widget is not None:
+ self._transition_out = 'out_scale'
+ scale_origin = origin_widget.get_screen_space_center()
+ transition = 'in_scale'
+ else:
+ self._transition_out = 'out_right'
+ scale_origin = None
+
+ uiscale = bui.app.ui_v1.uiscale
+ self._width = 800
+ x_inset = 100 if uiscale is bui.UIScale.SMALL else 0
+ self._height = 320
+ top_extra = 10 if uiscale is bui.UIScale.SMALL else 0
+ super().__init__(
+ root_widget=bui.containerwidget(
+ size=(self._width, self._height + top_extra),
+ transition=transition,
+ toolbar_visibility='menu_minimal',
+ scale_origin_stack_offset=scale_origin,
+ scale=(
+ 1.6
+ if uiscale is bui.UIScale.SMALL
+ else 1.3
+ if uiscale is bui.UIScale.MEDIUM
+ else 1.0
+ ),
+ stack_offset=(0, 5) if uiscale is bui.UIScale.SMALL else (0, 0),
+ )
+ )
+
+ if app.ui_v1.use_toolbars and uiscale is bui.UIScale.SMALL:
+ bui.containerwidget(
+ edit=self._root_widget, on_cancel_call=self._do_back
+ )
+ self._back_button = None
+ else:
+ self._back_button = bui.buttonwidget(
+ parent=self._root_widget,
+ position=(53 + x_inset, self._height - 60),
+ size=(140, 60),
+ scale=0.8,
+ autoselect=True,
+ label=bui.Lstr(resource='backText'),
+ button_type='back',
+ on_activate_call=self._do_back,
+ )
+ bui.containerwidget(
+ edit=self._root_widget, cancel_button=self._back_button
+ )
+
+ self._title_text = bui.textwidget(
+ parent=self._root_widget,
+ position=(0, self._height - 52),
+ size=(self._width, 25),
+ text='Discord',
+ color=app.ui_v1.title_color,
+ h_align='center',
+ v_align='top',
+ )
+
+ min_size = min(self._width - 25, self._height - 25)
+ bui.imagewidget(
+ parent=self._root_widget,
+ position=(40, -15),
+ size=(min_size, min_size),
+ texture=bui.gettexture('discordPreview'),
+ )
+
+ bui.textwidget(
+ parent=self._root_widget,
+ position=(self._width / 2 - 60, self._height - 100),
+ text='We have our own Discord server where you can:\n- Find new'
+ ' friends and people to play with\n- Participate in Office'
+ ' Hours/Coffee with Eric\n- Share mods, plugins, art, and'
+ ' memes\n- Report bugs and make feature suggestions\n'
+ '- Troubleshoot issues',
+ maxwidth=(self._width - 10) / 2,
+ color=(1, 1, 1, 1),
+ h_align='left',
+ v_align='top',
+ )
+
+ bui.buttonwidget(
+ parent=self._root_widget,
+ position=(self._width / 2 - 30, 20),
+ size=(self._width / 2 - 60, 60),
+ autoselect=True,
+ label='Join The Discord',
+ text_scale=1.0,
+ on_activate_call=bui.Call(
+ bui.open_url, 'https://ballistica.net/discord'
+ ),
+ )
+
+ if self._back_button is not None:
+ bui.buttonwidget(
+ edit=self._back_button,
+ button_type='backSmall',
+ size=(60, 60),
+ label=bui.charstr(bui.SpecialChar.BACK),
+ )
+
+ def _do_back(self) -> None:
+ bui.containerwidget(edit=self._root_widget, transition='out_scale')
diff --git a/src/assets/ba_data/python/bauiv1lib/gather/abouttab.py b/src/assets/ba_data/python/bauiv1lib/gather/abouttab.py
index 66c3f480..67d02bcd 100644
--- a/src/assets/ba_data/python/bauiv1lib/gather/abouttab.py
+++ b/src/assets/ba_data/python/bauiv1lib/gather/abouttab.py
@@ -80,15 +80,12 @@ class AboutGatherTab(GatherTab):
bui.textwidget(
parent=self._container,
- position=(
- region_width * 0.5,
- c_height_2 * (0.58 if include_invite else 0.5),
- ),
+ position=(region_width * 0.5, c_height_2 * 0.58),
color=(0.6, 1.0, 0.6),
scale=msc_scale,
size=(0, 0),
maxwidth=region_width * 0.9,
- max_height=c_height_2 * (0.7 if include_invite else 0.9),
+ max_height=c_height_2 * 0.7,
h_align='center',
v_align='center',
text=message,
@@ -97,7 +94,7 @@ class AboutGatherTab(GatherTab):
if include_invite:
bui.textwidget(
parent=self._container,
- position=(region_width * 0.57, 35),
+ position=(region_width * 0.57, 85),
color=(0, 1, 0),
scale=0.6,
size=(0, 0),
@@ -112,7 +109,7 @@ class AboutGatherTab(GatherTab):
)
bui.buttonwidget(
parent=self._container,
- position=(region_width * 0.59, 10),
+ position=(region_width * 0.59, 60),
size=(230, 50),
color=(0.54, 0.42, 0.56),
textcolor=(0, 1, 0),
@@ -124,6 +121,32 @@ class AboutGatherTab(GatherTab):
on_activate_call=bui.WeakCall(self._invite_to_try_press),
up_widget=tab_button,
)
+
+ bui.textwidget(
+ parent=self._container,
+ position=(region_width * 0.57, 15 if include_invite else 75),
+ color=(0.6, 0.6, 1),
+ scale=0.6,
+ size=(0, 0),
+ maxwidth=region_width * 0.5,
+ h_align='right',
+ v_align='center',
+ flatness=1.0,
+ text='Want to look for new people to play with?\nJoin our Discord'
+ ' and find new friends!',
+ )
+ bui.buttonwidget(
+ parent=self._container,
+ position=(region_width * 0.59, -10 if include_invite else 50),
+ size=(230, 50),
+ color=(0.54, 0.42, 0.56),
+ textcolor=(0.6, 0.6, 1),
+ label='Join The Discord',
+ autoselect=True,
+ on_activate_call=bui.WeakCall(self._join_the_discord_press),
+ up_widget=tab_button,
+ )
+
return self._container
def _invite_to_try_press(self) -> None:
@@ -137,3 +160,10 @@ class AboutGatherTab(GatherTab):
show_sign_in_prompt()
return
handle_app_invites_press()
+
+ def _join_the_discord_press(self) -> None:
+ # pylint: disable=cyclic-import
+ from bauiv1lib.discord import DiscordWindow
+
+ assert bui.app.classic is not None
+ DiscordWindow().get_root_widget()