diff --git a/.efrocachemap b/.efrocachemap
index b2a4ef26..f9326672 100644
--- a/.efrocachemap
+++ b/.efrocachemap
@@ -429,12 +429,12 @@
"assets/build/ba_data/data/languages/czech.json": "https://files.ballistica.net/cache/ba1/4e/8c/72ddb584856a15dfb11df95f9283",
"assets/build/ba_data/data/languages/danish.json": "https://files.ballistica.net/cache/ba1/6a/fa/fcf4a804beaff927b0f12c179eaa",
"assets/build/ba_data/data/languages/dutch.json": "https://files.ballistica.net/cache/ba1/68/93/da8e9874f41a786edf52ba4ccaad",
- "assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/ad/85/3caf0c981389e46835862248386a",
+ "assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/15/9d/5199b6a053922c2f9cc0f705e113",
"assets/build/ba_data/data/languages/esperanto.json": "https://files.ballistica.net/cache/ba1/ac/f5/c0922a99e40dfc9f5e026d43b533",
"assets/build/ba_data/data/languages/filipino.json": "https://files.ballistica.net/cache/ba1/dc/50/c109f475599608a7e8fdacea667c",
"assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/4f/4d/b259b145a69db1d34052281bb3bb",
"assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/cb/7b/b881356f22e5f8293a5e4b8976ae",
- "assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/ee/fa/6eb38e7d4cfd13702c66d37b9723",
+ "assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/09/c3/029c8d6357aa2dc5a3ac3560265a",
"assets/build/ba_data/data/languages/greek.json": "https://files.ballistica.net/cache/ba1/8a/82/392f2a4e0e6e5a5e367f19e49538",
"assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/2e/d1/b506ddf3d27af7be1ae6159531a3",
"assets/build/ba_data/data/languages/hungarian.json": "https://files.ballistica.net/cache/ba1/b2/81/53c8cd7617d649403e539c3a6171",
diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml
index 5f3cb01c..41368e39 100644
--- a/.idea/dictionaries/ericf.xml
+++ b/.idea/dictionaries/ericf.xml
@@ -1922,6 +1922,7 @@
plistname
plpt
plst
+ pluginsettings
plugkey
plugkeys
pluglist
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b84d61d2..10f4103d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,7 @@
### 1.7.19 (build 20993, api 7, 2023-01-17)
+- Fixes an issue where repeated curses could use incorrect countdown times (Thanks EraOSBeta!).
+- Last manual party connect port is now saved. Previously, it always assumed the port to be 43210 (Thanks ritiek!).
+- Added a plugin-settings window under the plugins UI for enabling/disabling, and setting whether plugins are auto-enabled (Thanks vishal332008!).
### 1.7.18 (build 20989, api 7, 2023-01-16)
- Reworked some low level asynchronous messaging functionality in efro.message and efro.rpc. Previously these were a little *too* asynchronous which could lead to messages being received in a different order than they were sent, which is not desirable.
diff --git a/assets/src/ba_data/python/ba/_plugin.py b/assets/src/ba_data/python/ba/_plugin.py
index 2aad94b1..5a89dcf9 100644
--- a/assets/src/ba_data/python/ba/_plugin.py
+++ b/assets/src/ba_data/python/ba/_plugin.py
@@ -22,6 +22,9 @@ class PluginSubsystem:
Access the single shared instance of this class at `ba.app.plugins`.
"""
+ AUTO_ENABLE_NEW_PLUGINS_CONFIG_KEY = 'Auto Enable New Plugins'
+ AUTO_ENABLE_NEW_PLUGINS_DEFAULT = True
+
def __init__(self) -> None:
self.potential_plugins: list[ba.PotentialPlugin] = []
self.active_plugins: dict[str, ba.Plugin] = {}
@@ -48,7 +51,13 @@ class PluginSubsystem:
available=True,
)
)
- if _ba.app.config['Auto Enable New Plugins'] is True:
+ if (
+ _ba.app.config.get(
+ self.AUTO_ENABLE_NEW_PLUGINS_CONFIG_KEY,
+ self.AUTO_ENABLE_NEW_PLUGINS_DEFAULT,
+ )
+ is True
+ ):
if class_path not in plugstates:
# Go ahead and enable new plugins by default, but we'll
# inform the user that they need to restart to pick them up.
diff --git a/assets/src/ba_data/python/bastd/ui/settings/pluginsettings.py b/assets/src/ba_data/python/bastd/ui/settings/pluginsettings.py
index 72d0c0fd..5e7d2196 100644
--- a/assets/src/ba_data/python/bastd/ui/settings/pluginsettings.py
+++ b/assets/src/ba_data/python/bastd/ui/settings/pluginsettings.py
@@ -1,166 +1,169 @@
-# Released under the MIT License. See LICENSE for details.
-#
-"""Plugin Settings UI."""
-
-from __future__ import annotations
-
-from typing import TYPE_CHECKING
-
-import ba
-
-if TYPE_CHECKING:
- pass
-
-
-class PluginSettingsWindow(ba.Window):
- """Plugin Settings Window"""
-
- def __init__(self, transition: str = 'in_right'):
-
- scale_origin: tuple[float, float] | None
- self._transition_out = 'out_right'
- scale_origin = None
-
- uiscale = ba.app.ui.uiscale
- width = 470.0 if uiscale is ba.UIScale.SMALL else 470.0
- height = (
- 365.0
- if uiscale is ba.UIScale.SMALL
- else 300.0
- if uiscale is ba.UIScale.MEDIUM
- else 370.0
- )
- top_extra = 10 if uiscale is ba.UIScale.SMALL else 0
-
- super().__init__(
- root_widget=ba.containerwidget(
- size=(width, height + top_extra),
- transition=transition,
- toolbar_visibility='menu_minimal',
- scale_origin_stack_offset=scale_origin,
- scale=(
- 2.06
- if uiscale is ba.UIScale.SMALL
- else 1.4
- if uiscale is ba.UIScale.MEDIUM
- else 1.0
- ),
- stack_offset=(0, -25)
- if uiscale is ba.UIScale.SMALL
- else (0, 0),
- )
- )
-
- self._back_button = ba.buttonwidget(
- parent=self._root_widget,
- position=(53, height - 60),
- size=(60, 60),
- scale=0.8,
- autoselect=True,
- label=ba.charstr(ba.SpecialChar.BACK),
- button_type='backSmall',
- on_activate_call=self._do_back,
- )
- ba.containerwidget(
- edit=self._root_widget, cancel_button=self._back_button
- )
-
- self._title_text = ba.textwidget(
- parent=self._root_widget,
- position=(0, height - 52),
- size=(width, 25),
- text=ba.Lstr(resource='pluginSettingsText'),
- color=ba.app.ui.title_color,
- h_align='center',
- v_align='top',
- )
-
- self._y_position = 170 if uiscale is ba.UIScale.MEDIUM else 205
- self._enable_plugins_button = ba.buttonwidget(
- parent=self._root_widget,
- position=(65, self._y_position),
- size=(350, 60),
- autoselect=True,
- label=ba.Lstr(resource='pluginsEnableAllText'),
- text_scale=1.0,
- on_activate_call=self._enable_all_plugins,
- )
-
- self._y_position -= 70
- self._disable_plugins_button = ba.buttonwidget(
- parent=self._root_widget,
- position=(65, self._y_position),
- size=(350, 60),
- autoselect=True,
- label=ba.Lstr(resource='pluginsDisableAllText'),
- text_scale=1.0,
- on_activate_call=self._disable_all_plugins,
- )
-
- self._y_position -= 70
- self._enable_new_plugins_check_box = ba.checkboxwidget(
- parent=self._root_widget,
- position=(65, self._y_position),
- size=(350, 60),
- value=ba.app.config['Auto Enable New Plugins'],
- text=ba.Lstr(resource='AutoEnableNewPluginsText'),
- scale=1.0,
- maxwidth=430,
- on_value_change_call=self._update_value,
- )
-
- ba.widget(
- edit=self._back_button, down_widget=self._enable_plugins_button
- )
-
- ba.widget(
- edit=self._disable_plugins_button,
- left_widget=self._disable_plugins_button,
- )
-
- ba.widget(
- edit=self._enable_new_plugins_check_box,
- left_widget=self._enable_new_plugins_check_box,
- right_widget=self._enable_new_plugins_check_box,
- down_widget=self._enable_new_plugins_check_box,
- )
-
- def _enable_all_plugins(self) -> None:
- cfg = ba.app.config
- plugs = cfg['Plugins']
- for plug in plugs:
- plugs[plug]['enabled'] = True
- cfg.apply_and_commit()
-
- ba.screenmessage(
- ba.Lstr(resource='settingsWindowAdvanced.mustRestartText'),
- color=(1.0, 0.5, 0.0),
- )
-
- def _disable_all_plugins(self) -> None:
- cfg = ba.app.config
- plugs = cfg['Plugins']
- for plug in plugs:
- plugs[plug]['enabled'] = False
- cfg.apply_and_commit()
-
- ba.screenmessage(
- ba.Lstr(resource='settingsWindowAdvanced.mustRestartText'),
- color=(1.0, 0.5, 0.0),
- )
-
- def _update_value(self, val: bool) -> None:
- cfg = ba.app.config
- cfg['Auto Enable New Plugins'] = val
- cfg.apply_and_commit()
-
- def _do_back(self) -> None:
- # pylint: disable=cyclic-import
- from bastd.ui.settings.plugins import PluginWindow
-
- ba.containerwidget(
- edit=self._root_widget, transition=self._transition_out
- )
- ba.app.ui.set_main_menu_window(
- PluginWindow(transition='in_left').get_root_widget()
- )
+# Released under the MIT License. See LICENSE for details.
+#
+"""Plugin Settings UI."""
+
+from __future__ import annotations
+
+from typing import TYPE_CHECKING
+
+import ba
+
+if TYPE_CHECKING:
+ pass
+
+
+class PluginSettingsWindow(ba.Window):
+ """Plugin Settings Window"""
+
+ def __init__(self, transition: str = 'in_right'):
+
+ scale_origin: tuple[float, float] | None
+ self._transition_out = 'out_right'
+ scale_origin = None
+
+ uiscale = ba.app.ui.uiscale
+ width = 470.0 if uiscale is ba.UIScale.SMALL else 470.0
+ height = (
+ 365.0
+ if uiscale is ba.UIScale.SMALL
+ else 300.0
+ if uiscale is ba.UIScale.MEDIUM
+ else 370.0
+ )
+ top_extra = 10 if uiscale is ba.UIScale.SMALL else 0
+
+ super().__init__(
+ root_widget=ba.containerwidget(
+ size=(width, height + top_extra),
+ transition=transition,
+ toolbar_visibility='menu_minimal',
+ scale_origin_stack_offset=scale_origin,
+ scale=(
+ 2.06
+ if uiscale is ba.UIScale.SMALL
+ else 1.4
+ if uiscale is ba.UIScale.MEDIUM
+ else 1.0
+ ),
+ stack_offset=(0, -25)
+ if uiscale is ba.UIScale.SMALL
+ else (0, 0),
+ )
+ )
+
+ self._back_button = ba.buttonwidget(
+ parent=self._root_widget,
+ position=(53, height - 60),
+ size=(60, 60),
+ scale=0.8,
+ autoselect=True,
+ label=ba.charstr(ba.SpecialChar.BACK),
+ button_type='backSmall',
+ on_activate_call=self._do_back,
+ )
+ ba.containerwidget(
+ edit=self._root_widget, cancel_button=self._back_button
+ )
+
+ self._title_text = ba.textwidget(
+ parent=self._root_widget,
+ position=(0, height - 52),
+ size=(width, 25),
+ text=ba.Lstr(resource='pluginSettingsText'),
+ color=ba.app.ui.title_color,
+ h_align='center',
+ v_align='top',
+ )
+
+ self._y_position = 170 if uiscale is ba.UIScale.MEDIUM else 205
+ self._enable_plugins_button = ba.buttonwidget(
+ parent=self._root_widget,
+ position=(65, self._y_position),
+ size=(350, 60),
+ autoselect=True,
+ label=ba.Lstr(resource='pluginsEnableAllText'),
+ text_scale=1.0,
+ on_activate_call=self._enable_all_plugins,
+ )
+
+ self._y_position -= 70
+ self._disable_plugins_button = ba.buttonwidget(
+ parent=self._root_widget,
+ position=(65, self._y_position),
+ size=(350, 60),
+ autoselect=True,
+ label=ba.Lstr(resource='pluginsDisableAllText'),
+ text_scale=1.0,
+ on_activate_call=self._disable_all_plugins,
+ )
+
+ self._y_position -= 70
+ self._enable_new_plugins_check_box = ba.checkboxwidget(
+ parent=self._root_widget,
+ position=(65, self._y_position),
+ size=(350, 60),
+ value=ba.app.config.get(
+ ba.app.plugins.AUTO_ENABLE_NEW_PLUGINS_CONFIG_KEY,
+ ba.app.plugins.AUTO_ENABLE_NEW_PLUGINS_DEFAULT,
+ ),
+ text=ba.Lstr(resource='pluginsAutoEnableNewText'),
+ scale=1.0,
+ maxwidth=430,
+ on_value_change_call=self._update_value,
+ )
+
+ ba.widget(
+ edit=self._back_button, down_widget=self._enable_plugins_button
+ )
+
+ ba.widget(
+ edit=self._disable_plugins_button,
+ left_widget=self._disable_plugins_button,
+ )
+
+ ba.widget(
+ edit=self._enable_new_plugins_check_box,
+ left_widget=self._enable_new_plugins_check_box,
+ right_widget=self._enable_new_plugins_check_box,
+ down_widget=self._enable_new_plugins_check_box,
+ )
+
+ def _enable_all_plugins(self) -> None:
+ cfg = ba.app.config
+ plugs: dict[str, dict] = cfg.setdefault('Plugins', {})
+ for plug in plugs.values():
+ plug['enabled'] = True
+ cfg.apply_and_commit()
+
+ ba.screenmessage(
+ ba.Lstr(resource='settingsWindowAdvanced.mustRestartText'),
+ color=(1.0, 0.5, 0.0),
+ )
+
+ def _disable_all_plugins(self) -> None:
+ cfg = ba.app.config
+ plugs: dict[str, dict] = cfg.setdefault('Plugins', {})
+ for plug in plugs.values():
+ plug['enabled'] = False
+ cfg.apply_and_commit()
+
+ ba.screenmessage(
+ ba.Lstr(resource='settingsWindowAdvanced.mustRestartText'),
+ color=(1.0, 0.5, 0.0),
+ )
+
+ def _update_value(self, val: bool) -> None:
+ cfg = ba.app.config
+ cfg[ba.app.plugins.AUTO_ENABLE_NEW_PLUGINS_CONFIG_KEY] = val
+ cfg.apply_and_commit()
+
+ def _do_back(self) -> None:
+ # pylint: disable=cyclic-import
+ from bastd.ui.settings.plugins import PluginWindow
+
+ ba.containerwidget(
+ edit=self._root_widget, transition=self._transition_out
+ )
+ ba.app.ui.set_main_menu_window(
+ PluginWindow(transition='in_left').get_root_widget()
+ )
diff --git a/ballisticacore-cmake/.idea/dictionaries/ericf.xml b/ballisticacore-cmake/.idea/dictionaries/ericf.xml
index 21191a9c..562edbcf 100644
--- a/ballisticacore-cmake/.idea/dictionaries/ericf.xml
+++ b/ballisticacore-cmake/.idea/dictionaries/ericf.xml
@@ -1030,6 +1030,7 @@
playpause
playsound
plen
+ pluginsettings
plugnames
pname
podcast