From cf308fc118fbcc3fd83c7ad8bb10d71bb712068d Mon Sep 17 00:00:00 2001 From: Diorik Date: Tue, 4 Feb 2025 01:54:34 -0600 Subject: [PATCH 1/3] Prevent repeating random design Cache the last selected random design and prevent it from being chosen again. --- Glamourer/Designs/Special/RandomDesignGenerator.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Glamourer/Designs/Special/RandomDesignGenerator.cs b/Glamourer/Designs/Special/RandomDesignGenerator.cs index 7ed4452..1bee8ad 100644 --- a/Glamourer/Designs/Special/RandomDesignGenerator.cs +++ b/Glamourer/Designs/Special/RandomDesignGenerator.cs @@ -5,15 +5,20 @@ namespace Glamourer.Designs.Special; public class RandomDesignGenerator(DesignStorage designs, DesignFileSystem fileSystem) : IService { private readonly Random _rng = new(); + private Design? _lastDesign = null; public Design? Design(IReadOnlyList localDesigns) { if (localDesigns.Count == 0) return null; + if (_lastDesign != null && localDesigns.Count > 1) + localDesigns = localDesigns.Where(d => d != _lastDesign).ToList(); + var idx = _rng.Next(0, localDesigns.Count); Glamourer.Log.Verbose($"[Random Design] Chose design {idx + 1} out of {localDesigns.Count}: {localDesigns[idx].Incognito}."); - return localDesigns[idx]; + _lastDesign = localDesigns[idx]; + return _lastDesign; } public Design? Design() From 67fd65d366133ba0569ce9a3a70760e8f43fec5a Mon Sep 17 00:00:00 2001 From: Diorik Date: Thu, 6 Feb 2025 12:49:23 -0600 Subject: [PATCH 2/3] Make PreventRandomc figurable, clean up logic Will no longer hold design reference or make redundant copy of list --- Glamourer/Configuration.cs | 1 + .../Designs/Special/RandomDesignGenerator.cs | 17 +++++++++-------- Glamourer/Gui/Tabs/SettingsTab/SettingsTab.cs | 3 +++ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Glamourer/Configuration.cs b/Glamourer/Configuration.cs index 4b59191..5f838a8 100644 --- a/Glamourer/Configuration.cs +++ b/Glamourer/Configuration.cs @@ -67,6 +67,7 @@ public class Configuration : IPluginConfiguration, ISavable public bool UseTemporarySettings { get; set; } = true; public bool AllowDoubleClickToApply { get; set; } = false; public bool RespectManualOnAutomationUpdate { get; set; } = false; + public bool PreventRandomRepeats { get; set; } = false; public DefaultDesignSettings DefaultDesignSettings { get; set; } = new(); diff --git a/Glamourer/Designs/Special/RandomDesignGenerator.cs b/Glamourer/Designs/Special/RandomDesignGenerator.cs index 1bee8ad..3ff353b 100644 --- a/Glamourer/Designs/Special/RandomDesignGenerator.cs +++ b/Glamourer/Designs/Special/RandomDesignGenerator.cs @@ -1,24 +1,25 @@ -using OtterGui.Services; +using OtterGui; +using OtterGui.Services; namespace Glamourer.Designs.Special; -public class RandomDesignGenerator(DesignStorage designs, DesignFileSystem fileSystem) : IService +public class RandomDesignGenerator(DesignStorage designs, DesignFileSystem fileSystem, Configuration config) : IService { private readonly Random _rng = new(); - private Design? _lastDesign = null; + private Guid? _lastDesignID = null; - public Design? Design(IReadOnlyList localDesigns) + public Design? Design(IList localDesigns) { if (localDesigns.Count == 0) return null; - if (_lastDesign != null && localDesigns.Count > 1) - localDesigns = localDesigns.Where(d => d != _lastDesign).ToList(); + if (config.PreventRandomRepeats && _lastDesignID != null && localDesigns.Count > 1 && localDesigns.FindFirst(d => d.Identifier == _lastDesignID, out var found)) + localDesigns.Remove(found); var idx = _rng.Next(0, localDesigns.Count); Glamourer.Log.Verbose($"[Random Design] Chose design {idx + 1} out of {localDesigns.Count}: {localDesigns[idx].Incognito}."); - _lastDesign = localDesigns[idx]; - return _lastDesign; + _lastDesignID = localDesigns[idx].Identifier; + return localDesigns[idx]; } public Design? Design() diff --git a/Glamourer/Gui/Tabs/SettingsTab/SettingsTab.cs b/Glamourer/Gui/Tabs/SettingsTab/SettingsTab.cs index ab40a48..2b9548f 100644 --- a/Glamourer/Gui/Tabs/SettingsTab/SettingsTab.cs +++ b/Glamourer/Gui/Tabs/SettingsTab/SettingsTab.cs @@ -109,6 +109,9 @@ public class SettingsTab( Checkbox("Use Temporary Mod Settings", "Apply all settings as temporary settings so they will be reset when Glamourer or the game shut down.", config.UseTemporarySettings, v => config.UseTemporarySettings = v); + Checkbox("Prevent Random Design Repeats", + "When using random designs, prevent the same design from being chosen twice in a row.", + config.PreventRandomRepeats, v => config.PreventRandomRepeats = v); ImGui.NewLine(); } From 5ca151b675e3f9484dac8ff06236a48f045895db Mon Sep 17 00:00:00 2001 From: Diorik Date: Thu, 6 Feb 2025 13:29:47 -0600 Subject: [PATCH 3/3] PreventRandom use WeakReference, reroll rand instead of changing list --- .../Designs/Special/RandomDesignGenerator.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Glamourer/Designs/Special/RandomDesignGenerator.cs b/Glamourer/Designs/Special/RandomDesignGenerator.cs index 3ff353b..b34a8ba 100644 --- a/Glamourer/Designs/Special/RandomDesignGenerator.cs +++ b/Glamourer/Designs/Special/RandomDesignGenerator.cs @@ -6,19 +6,20 @@ namespace Glamourer.Designs.Special; public class RandomDesignGenerator(DesignStorage designs, DesignFileSystem fileSystem, Configuration config) : IService { private readonly Random _rng = new(); - private Guid? _lastDesignID = null; + private WeakReference _lastDesign = new(null, false); - public Design? Design(IList localDesigns) + public Design? Design(IReadOnlyList localDesigns) { if (localDesigns.Count == 0) return null; - if (config.PreventRandomRepeats && _lastDesignID != null && localDesigns.Count > 1 && localDesigns.FindFirst(d => d.Identifier == _lastDesignID, out var found)) - localDesigns.Remove(found); - - var idx = _rng.Next(0, localDesigns.Count); + int idx; + do + idx = _rng.Next(0, localDesigns.Count); + while (config.PreventRandomRepeats && localDesigns.Count > 1 && _lastDesign.TryGetTarget(out var lastDesign) && lastDesign == localDesigns[idx]); + Glamourer.Log.Verbose($"[Random Design] Chose design {idx + 1} out of {localDesigns.Count}: {localDesigns[idx].Incognito}."); - _lastDesignID = localDesigns[idx].Identifier; + _lastDesign.SetTarget(localDesigns[idx]); return localDesigns[idx]; }