diff --git a/README.md b/README.md
index f499a31..c1cf690 100644
--- a/README.md
+++ b/README.md
@@ -36,7 +36,7 @@
```
3. Enable **Avatar Switcher** when loading your save.
-4. Press **'** (apostrophe/quote) to open Avatar Switcher. The binding can be changed in the in-game controls menu.
+4. Press **Alt+Shift+A** to open Avatar Switcher. The binding can be changed in the in-game controls menu.
Do not extract the mod ZIP into the mods folder.
@@ -53,7 +53,7 @@ Do not extract the mod ZIP into the mods folder.
### Applying an appearance
-1. Press the mapped **Open Avatar Switcher** control.
+1. Press the mapped **Open Avatar Switcher** control (**Alt+Shift+A** by default).
2. Select a category.
3. Select a saved appearance.
4. Choose **Apply**.
diff --git a/modDesc.xml b/modDesc.xml
index e6b5e4d..b3f5ef1 100644
--- a/modDesc.xml
+++ b/modDesc.xml
@@ -23,14 +23,14 @@ Features:
- Store presets in the Avatar Switcher mod settings folder
Default control:
-' opens Avatar Switcher. The key binding can be changed in the in-game controls menu.
+Alt+Shift+A opens Avatar Switcher. The key binding can be changed in the in-game controls menu.
How to use:
1. Open the wardrobe and configure the player appearance.
2. Select "Save to AvatarSwitcher".
3. Enter a unique Preset ID and an optional Display Name.
4. Select an existing category or enter a new category, then select Save.
-5. Press ' to open Avatar Switcher.
+5. Press Alt+Shift+A to open Avatar Switcher.
6. Select a category and appearance, then select Apply.
Deleting a preset does not change the appearance currently being used.
@@ -38,31 +38,31 @@ Deleting a preset does not change the appearance currently being used.
This mod is designed for single-player use and does not support multiplayer.
]]>
+
@@ -114,12 +115,12 @@ Ce mod est conçu pour le mode solo et ne prend pas en charge le multijoueur.
-
+
-
+
diff --git a/scripts/AS_GuiLifecycle.lua b/scripts/AS_GuiLifecycle.lua
new file mode 100644
index 0000000..68bedbc
--- /dev/null
+++ b/scripts/AS_GuiLifecycle.lua
@@ -0,0 +1,94 @@
+-- FS25_AvatarSwitcher
+-- ModVersion: 1.0.0.0
+-- File: AS_GuiLifecycle.lua
+-- BuildTag: 20260825.1
+-- Centralises custom GUI profile loading so profile names are registered only
+-- once per game process, regardless of which Avatar Switcher dialog opens first.
+
+AvatarSwitcher = AvatarSwitcher or {}
+
+-- Do not reset this in deleteMap(). GIANTS keeps GUI profiles registered for the
+-- lifetime of the process, so loading another save must not register them again.
+AvatarSwitcher.guiProfilesLoaded = AvatarSwitcher.guiProfilesLoaded == true
+
+function AvatarSwitcher:ensureGuiProfilesLoaded()
+ if self.guiProfilesLoaded == true then
+ return true
+ end
+
+ if g_gui == nil or g_gui.loadProfiles == nil then
+ if self.warn ~= nil then
+ self:warn("[GUI] Cannot load Avatar Switcher GUI profiles: g_gui.loadProfiles unavailable")
+ end
+ return false
+ end
+
+ local filename = self.modDirectory .. "gui/guiProfiles.xml"
+ local ok, err = pcall(g_gui.loadProfiles, g_gui, filename)
+ if not ok then
+ if self.error ~= nil then
+ self:error("[GUI] Failed to load GUI profiles: " .. tostring(err))
+ else
+ print("[FS25_AvatarSwitcher/GUI] Failed to load GUI profiles: " .. tostring(err))
+ end
+ return false
+ end
+
+ self.guiProfilesLoaded = true
+ if self.debug ~= nil then
+ self:debug("[GUI] Loaded custom GUI profiles once: " .. tostring(filename))
+ end
+ return true
+end
+
+-- AS_Dialog.lua and AS_SaveDialog.lua historically loaded guiProfiles.xml inside
+-- their open routines. Replacing the two open routines here keeps their dialog
+-- behaviour unchanged while routing profile registration through the shared guard.
+
+function AvatarSwitcher:openDialog()
+ self:initialize()
+ if g_gui == nil then
+ self:warn("[Dialog] g_gui is not available")
+ return false
+ end
+
+ if self.guiDialog ~= nil then
+ return true
+ end
+
+ if not self:ensureGuiProfilesLoaded() then
+ return false
+ end
+
+ local dlgFrame = AvatarSwitcherDialog.new(g_i18n)
+ g_gui:loadGui(self.modDirectory .. "gui/AS_Dialog.xml", "AvatarSwitcherDialog", dlgFrame)
+ self.guiDialog = g_gui:showDialog("AvatarSwitcherDialog")
+
+ if self.HUD ~= nil then
+ self.HUD.visible = self.guiDialog ~= nil
+ end
+
+ return self.guiDialog ~= nil
+end
+
+function AvatarSwitcher:openWardrobeSaveDialog()
+ self:initialize()
+ if g_gui == nil then
+ self:warn("[WardrobeSaveDialog] g_gui is not available")
+ return false
+ end
+
+ if self.wardrobeSaveDialog ~= nil then
+ return true
+ end
+
+ if not self:ensureGuiProfilesLoaded() then
+ return false
+ end
+
+ local dlgFrame = AvatarSwitcherSaveDialog.new(g_i18n)
+ g_gui:loadGui(self.modDirectory .. "gui/AS_SaveDialog.xml", "AvatarSwitcherSaveDialog", dlgFrame)
+ self.wardrobeSaveDialog = g_gui:showDialog("AvatarSwitcherSaveDialog")
+
+ return self.wardrobeSaveDialog ~= nil
+end