From 8c9c3b3d94c61bd2b50a2cd572dae637645e7593 Mon Sep 17 00:00:00 2001 From: Marto Date: Sat, 3 Jan 2026 13:10:26 +0100 Subject: [PATCH] Major settings overhaul --- HighRollerClassic/Configuration.cs | 4 +- HighRollerClassic/DataStructures/Misc.cs | 16 --- HighRollerClassic/DataStructures/Settings.cs | 73 ------------ .../DataStructures/SettingsRoll.cs | 45 -------- .../DataStructures/TrackedValue.cs | 95 --------------- .../{DataStructures => Macro}/MacroType.cs | 0 .../{DataStructures => Macro}/MessageMacro.cs | 0 HighRollerClassic/{ => Player}/Player.cs | 0 .../{ => Player}/PlayerManager.cs | 0 .../{DataStructures => Player}/RollHistory.cs | 0 .../SettingsStructure/RollsCollection.cs | 71 ++++++++++++ .../SettingValueType.cs | 0 .../SettingsStructure/Settings.cs | 55 +++++++++ .../SettingsStructure/SettingsRoll.cs | 35 ++++++ .../SettingsStructure/TrackedValue.cs | 66 +++++++++++ HighRollerClassic/Windows/GambaWindow.cs | 5 +- HighRollerClassic/Windows/SettingsWindow.cs | 108 +++++++++--------- 17 files changed, 284 insertions(+), 289 deletions(-) delete mode 100644 HighRollerClassic/DataStructures/Misc.cs delete mode 100644 HighRollerClassic/DataStructures/Settings.cs delete mode 100644 HighRollerClassic/DataStructures/SettingsRoll.cs delete mode 100644 HighRollerClassic/DataStructures/TrackedValue.cs rename HighRollerClassic/{DataStructures => Macro}/MacroType.cs (100%) rename HighRollerClassic/{DataStructures => Macro}/MessageMacro.cs (100%) rename HighRollerClassic/{ => Player}/Player.cs (100%) rename HighRollerClassic/{ => Player}/PlayerManager.cs (100%) rename HighRollerClassic/{DataStructures => Player}/RollHistory.cs (100%) create mode 100644 HighRollerClassic/SettingsStructure/RollsCollection.cs rename HighRollerClassic/{DataStructures => SettingsStructure}/SettingValueType.cs (100%) create mode 100644 HighRollerClassic/SettingsStructure/Settings.cs create mode 100644 HighRollerClassic/SettingsStructure/SettingsRoll.cs create mode 100644 HighRollerClassic/SettingsStructure/TrackedValue.cs diff --git a/HighRollerClassic/Configuration.cs b/HighRollerClassic/Configuration.cs index 9e2f712..26ca079 100644 --- a/HighRollerClassic/Configuration.cs +++ b/HighRollerClassic/Configuration.cs @@ -7,8 +7,8 @@ namespace HighRollerClassic; [Serializable] public class Configuration : IPluginConfiguration { - public PlayerManager Players { get; set; }= new(); - public Settings Settings { get; set; } = new(); + public PlayerManager Players { get; set; } = new(); + public SettingsStructure.Settings Settings { get; set; } = new(null); public int Version { get; set; } = 0; diff --git a/HighRollerClassic/DataStructures/Misc.cs b/HighRollerClassic/DataStructures/Misc.cs deleted file mode 100644 index 8f83fe8..0000000 --- a/HighRollerClassic/DataStructures/Misc.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace HighRollerClassic.DataStructures; - -public static class Misc -{ - /// - /// Appends message if error par is true - /// - /// it will write the message if it's true - /// the message we wish to write - /// reference to the message - public static void AppendMessage(bool error, string errorMessage, ref string? message) - { - if (!error) return; - message = message == null ? errorMessage : $"\n{errorMessage}"; - } -} diff --git a/HighRollerClassic/DataStructures/Settings.cs b/HighRollerClassic/DataStructures/Settings.cs deleted file mode 100644 index eee9372..0000000 --- a/HighRollerClassic/DataStructures/Settings.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System.Collections.Generic; - -namespace HighRollerClassic.DataStructures; - -public class Settings -{ - /// - /// Whether developer options should be visible in the settings - /// - public bool devOptions = false; - - /// - /// Maximum bet that will be allowed to set - /// - public uint? MaxBet { get; set; } = null; - - /// - /// How much the bet will change when user adjusts their bet via +/- keys - /// - public uint? Step { get; set; } = null; - - /// - /// Contains messages such as announcements etc. - /// - public List Macros { get; private set; } = new(); - - /// - /// Contains data about each multiplier, roll, etc. - /// - public List Rolls { get; private set; } = new(); - // todo we'll make this a new class because we have 3 roll methods already 'polluting' this class - - /// - /// Adds roll - /// - /// The roll 'collection' we wish to add - /// returns error message if validations fails, null if it's successfully added - public string? AddRoll(SettingsRoll newRoll) - { - var individualValidation = ValidateIndividual(newRoll); - if (individualValidation != null) return individualValidation; - - var fullValidation = ValidateRoll(newRoll); - if (fullValidation != null) return fullValidation; - - Rolls.Add(newRoll); - return null; - } - - public void RemoveRoll(SettingsRoll roll) - { - Rolls.Remove(roll); - } - - /// - /// Validates new roll - /// - /// The roll we wish to add - /// Returns error message if validation fails, otherwise null string - private string? ValidateRoll(SettingsRoll newRoll) - { - string? message = null; - - var rollExists = Rolls.Exists(p => p.Roll == newRoll.Roll); - Misc.AppendMessage(rollExists, "The roll already exists", ref message); - var multiplierExists = Rolls.Exists(p => p.Multiplier == newRoll.Multiplier); - Misc.AppendMessage(multiplierExists, "This multiplier already exists", ref message); - var colourExists = Rolls.Exists(p => p.Colour == newRoll.Colour); - Misc.AppendMessage(colourExists, "This colour already exists", ref message); - - return message; - } -} diff --git a/HighRollerClassic/DataStructures/SettingsRoll.cs b/HighRollerClassic/DataStructures/SettingsRoll.cs deleted file mode 100644 index 819eff0..0000000 --- a/HighRollerClassic/DataStructures/SettingsRoll.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Numerics; - -namespace HighRollerClassic.DataStructures; - -/// -/// Stores individual 'Roll' setting (multiplier, roll, colour) -/// -/// the amount gil will get multiplied if roll interval is reached -/// the amount that will manipulate multiplier, usually acquired by a player running /random -/// each roll can be colour coded for better visibility -public record SettingsRoll(uint? Multiplier, uint? Roll, Vector4? Colour) -{ - private const uint MinRollInterval = 1; - private const uint MaxRollInterval = 999; - - /// - /// Roll multiplier - /// - public uint? Multiplier { get; set; } = Multiplier; - - /// - /// Roll itself - /// - public uint? Roll - { - get; - set - { - if (value is < MinRollInterval or > MaxRollInterval) - { - field = null; - return; - } - - field = value; - } - } = Roll; - - /// - /// Colour that will be used to highlight roll in history - /// - public Vector4? Colour { get; set; } = Colour; - - public bool ValidInput => Multiplier.HasValue && Roll.HasValue; -} diff --git a/HighRollerClassic/DataStructures/TrackedValue.cs b/HighRollerClassic/DataStructures/TrackedValue.cs deleted file mode 100644 index 89f7fc7..0000000 --- a/HighRollerClassic/DataStructures/TrackedValue.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using System.Diagnostics; -using System.Numerics; -using FFXIVClientStructs.FFXIV.Component.GUI; - -namespace HighRollerClassic.DataStructures; - -/// -/// Tracks value and its validity and changes -/// -public class TrackedValue -{ - private SettingValueType type; - private Configuration configuration; - - private uint? Value { get; - set - { - SetValue(value); - field = value; - } - } - private Vector4? colourValue { get; set; } - - public bool IsValid { get; private set; } - public bool HasChanged { get; private set; } - - private const uint MinRoll = 1; - private const uint MaxRoll = 999; - private const uint MaxGil = 999_999_999; - - private bool multiplierValid => Value is not null; - private bool rollValid => Value is >= MinRoll and <= MaxRoll; - private bool maxBetValid => Value is <= MaxGil; - private bool stepValid => CheckStepValid(); - - public TrackedValue(uint? value, SettingValueType type, Configuration configuration) - { - Initialise(type, configuration); - Value = value; - } - - public TrackedValue(Vector4? value, SettingValueType type, Configuration configuration) - { - Initialise(type, configuration); - colourValue = value; - } - - private void Initialise(SettingValueType type, Configuration configuration) - { - this.type = type; - this.configuration = configuration; - } - - private bool CheckStepValid() - { - return Value <= configuration.Settings.MaxBet; - } - - private void SetValue(uint? value) - { - bool? valid = null; - bool? change = null; - - switch (type) - { - case SettingValueType.Multiplier: - valid = multiplierValid; - break; - case SettingValueType.Roll: - valid = rollValid; - break; - case SettingValueType.Colour: - valid = true; - break; - case SettingValueType.MaxBet: - valid = maxBetValid; - change = value == configuration.Settings.MaxBet; - break; - case SettingValueType.Step: - valid = stepValid; - change = value == configuration.Settings.Step; - break; - } - - if (valid.HasValue) IsValid = valid.Value; - if (change.HasValue) HasChanged = change.Value; - } - - private void SetColourValue(Vector4? value) - { - IsValid = true; // colour will always be valid because we set it from colour picker - HasChanged = true; // todo we have to check - } -} diff --git a/HighRollerClassic/DataStructures/MacroType.cs b/HighRollerClassic/Macro/MacroType.cs similarity index 100% rename from HighRollerClassic/DataStructures/MacroType.cs rename to HighRollerClassic/Macro/MacroType.cs diff --git a/HighRollerClassic/DataStructures/MessageMacro.cs b/HighRollerClassic/Macro/MessageMacro.cs similarity index 100% rename from HighRollerClassic/DataStructures/MessageMacro.cs rename to HighRollerClassic/Macro/MessageMacro.cs diff --git a/HighRollerClassic/Player.cs b/HighRollerClassic/Player/Player.cs similarity index 100% rename from HighRollerClassic/Player.cs rename to HighRollerClassic/Player/Player.cs diff --git a/HighRollerClassic/PlayerManager.cs b/HighRollerClassic/Player/PlayerManager.cs similarity index 100% rename from HighRollerClassic/PlayerManager.cs rename to HighRollerClassic/Player/PlayerManager.cs diff --git a/HighRollerClassic/DataStructures/RollHistory.cs b/HighRollerClassic/Player/RollHistory.cs similarity index 100% rename from HighRollerClassic/DataStructures/RollHistory.cs rename to HighRollerClassic/Player/RollHistory.cs diff --git a/HighRollerClassic/SettingsStructure/RollsCollection.cs b/HighRollerClassic/SettingsStructure/RollsCollection.cs new file mode 100644 index 0000000..025db11 --- /dev/null +++ b/HighRollerClassic/SettingsStructure/RollsCollection.cs @@ -0,0 +1,71 @@ +using System.Collections.Generic; + +namespace HighRollerClassic.SettingsStructure; + +public class RollsCollection +{ + /// + /// Contains data about each multiplier, roll, etc. + /// + public List Rolls { get; set; } = new(); + + public int Size => Rolls.Count; + + /// + /// Adds roll + /// + /// The roll 'collection' we wish to add + /// returns error message if validations fails, null if it's successfully added + public bool AddRoll(SettingsRoll newRoll) + { + if (!ValidateRoll(newRoll)) return false; + + Rolls.Add(newRoll); + return true; + + // todo add that specific roll message + } + + public void RemoveRoll(SettingsRoll roll) + { + Rolls.Remove(roll); + // todo remove that specific roll macromessage + } + + /// + /// Validates given roll + /// + /// The roll we wish to validate + /// Returns + private bool ValidateRoll(SettingsRoll newRoll) + { + var inputValid = newRoll.IsValid; + + // existing values must not exist anywhere else + var mpExists = Rolls.Exists(p => p != newRoll && p.Roll.Value == newRoll.Roll.Value); + var rollExists = Rolls.Exists(p => p != newRoll && p.Roll.Value == newRoll.Roll.Value); + var colourExists = false; + if (newRoll.Colour.Value.HasValue) + { + colourExists = Rolls.Exists(p => p != newRoll && p.Colour.Value == newRoll.Colour.Value); + } + + var fullNotExists = !mpExists && !rollExists && !colourExists; + + return inputValid && fullNotExists; + } + + /// + /// Does quick iteration to see if rolls are valid + /// + /// true if all rolls are valid + public bool ValidateAll() + { + foreach (var roll in Rolls) + { + if (!roll.IsValid) return false; + } + + return true; + } +} diff --git a/HighRollerClassic/DataStructures/SettingValueType.cs b/HighRollerClassic/SettingsStructure/SettingValueType.cs similarity index 100% rename from HighRollerClassic/DataStructures/SettingValueType.cs rename to HighRollerClassic/SettingsStructure/SettingValueType.cs diff --git a/HighRollerClassic/SettingsStructure/Settings.cs b/HighRollerClassic/SettingsStructure/Settings.cs new file mode 100644 index 0000000..d59ed1e --- /dev/null +++ b/HighRollerClassic/SettingsStructure/Settings.cs @@ -0,0 +1,55 @@ +using System.Collections.Generic; +using HighRollerClassic.DataStructures; + +namespace HighRollerClassic.SettingsStructure; + +public class Settings(Configuration? configuration) +{ + /// + /// Whether developer options should be visible in the settings + /// + public bool devOptions = false; + + /// + /// Maximum bet that will be allowed to set + /// + public TrackedValue MaxBet { get; set; } = new(SettingValueType.MaxBet, null); + + /// + /// How much the bet will change when user adjusts their bet via +/- keys + /// + public uint? Step { get; set; } + + /// + /// Contains messages such as announcements etc. + /// + public List Macros { get; private set; } = new(); + + // todo we'll make this a new class because we have 3 roll methods already 'polluting' this class + + public readonly RollsCollection RollsCollection = new(); + + // todo might get fucky wucky if maxbet is not yet defined + public bool IsValid => MaxBet.IsValid && StepValid() && RollsCollection.ValidateAll(); + public bool Set => IsValid && RollsCollection.Size > 0 && Macros.Count > 0; + + private bool StepValid() + { + uint maxBet; + + if (configuration is { Settings.MaxBet.IsValid: true }) + { + maxBet = configuration.Settings.MaxBet.Value!.Value; //IsValid guarantees validity + } + else if (MaxBet.IsValid) + { + maxBet = MaxBet.Value!.Value; // IsValid + } + else + { + maxBet = 0; + } + + return Step <= maxBet; + } +} diff --git a/HighRollerClassic/SettingsStructure/SettingsRoll.cs b/HighRollerClassic/SettingsStructure/SettingsRoll.cs new file mode 100644 index 0000000..c84a56e --- /dev/null +++ b/HighRollerClassic/SettingsStructure/SettingsRoll.cs @@ -0,0 +1,35 @@ +using System.Numerics; +using Dalamud.Interface; +using HighRollerClassic.DataStructures; + +namespace HighRollerClassic.SettingsStructure; + +/// +/// Stores individual 'Roll' setting (multiplier, roll, colour) +/// +/// Roll multiplier +/// Actual roll value +/// Actual colour (can be null) +public class SettingsRoll(uint? multiplier, uint? roll, Vector4? colour) +{ + /// + /// Roll multiplier + /// + public TrackedValue Multiplier { get; set; } = new(SettingValueType.Multiplier, multiplier); + + /// + /// Roll itself + /// + public TrackedValue Roll { get; set; } = new(SettingValueType.Roll, roll); + + /// + /// Colour that will be used to highlight roll in history + /// + public TrackedValue Colour { get; set; } = + new(SettingValueType.Colour, colour.HasValue ? ColorHelpers.RgbaVector4ToUint(colour.Value) : null); + + /// + /// Returns true if all properties in record are valid + /// + public bool IsValid => Multiplier.IsValid && Roll.IsValid && Colour.IsValid; +} diff --git a/HighRollerClassic/SettingsStructure/TrackedValue.cs b/HighRollerClassic/SettingsStructure/TrackedValue.cs new file mode 100644 index 0000000..56c36cd --- /dev/null +++ b/HighRollerClassic/SettingsStructure/TrackedValue.cs @@ -0,0 +1,66 @@ +using System; +using HighRollerClassic.DataStructures; + +namespace HighRollerClassic.SettingsStructure; + +/// +/// Tracks value and its validity +/// +/// Type of the value +/// Its value +public class TrackedValue(SettingValueType type, uint? value) +{ + /// + /// The main value + /// + public uint? Value + { + get; + set + { + IsValid = CheckValid(value); + field = value; + } + } = value; + + /// + /// Tracks validity of the value + /// + public bool IsValid { get; private set; } + + /// + /// Minimum rng roll (/random) + /// + private const uint MinRoll = 1; + + /// + /// Maximum rng roll (/random) + /// + private const uint MaxRoll = 999; + + /// + /// Maximum possible gil in-game + /// + private const uint MaxGil = 999_999_999; + + private readonly Func multiplierValid = v => v is not null; + private readonly Func rollValid = v => v is >= MinRoll and <= MaxRoll; + private readonly Func maxBetValid = v => v is <= MaxGil; + + /// + /// Checks if the value is valid + /// + /// + private bool CheckValid(uint? value) + { + return type switch + { + SettingValueType.Multiplier => multiplierValid(value), + SettingValueType.Roll => rollValid(value), + SettingValueType.Colour => true, + SettingValueType.MaxBet => maxBetValid(value), + // step will get checked upstream to prevent passing configuration to every tracked value + _ => false, + }; + } +} diff --git a/HighRollerClassic/Windows/GambaWindow.cs b/HighRollerClassic/Windows/GambaWindow.cs index 10a0b24..4181d1c 100644 --- a/HighRollerClassic/Windows/GambaWindow.cs +++ b/HighRollerClassic/Windows/GambaWindow.cs @@ -32,9 +32,6 @@ public class GambaWindow : Window, IDisposable name = target.TargetName; } - private bool SettingsSet => configuration.Settings is - { MaxBet: not null, Step: not null, Rolls.Count: > 0, Macros.Count: > 0 }; - public void Dispose() { } public override void Draw() @@ -45,7 +42,7 @@ public class GambaWindow : Window, IDisposable return; } - if (!SettingsSet) + if (!configuration.Settings.Set) { ImGui.Text("Please set up settings"); return; diff --git a/HighRollerClassic/Windows/SettingsWindow.cs b/HighRollerClassic/Windows/SettingsWindow.cs index 19f0d1e..5040347 100644 --- a/HighRollerClassic/Windows/SettingsWindow.cs +++ b/HighRollerClassic/Windows/SettingsWindow.cs @@ -4,6 +4,7 @@ using Dalamud.Bindings.ImGui; using Dalamud.Interface.Components; using Dalamud.Interface.Windowing; using HighRollerClassic.DataStructures; +using HighRollerClassic.SettingsStructure; namespace HighRollerClassic.Windows; @@ -13,20 +14,20 @@ public class SettingsWindow : Window, IDisposable private const int Spacing = 5; private const int InputWidth = 105; private const int InputMaxLen = 11; + private const uint RollInputWidth = 50; - private const uint RollSettingInputWidth = 50; - - private const uint MaxAllowedGil = 999_999_999; private readonly Configuration configuration; - private readonly Vector4 red = new(1, 0, 0, 1f); // colours + private readonly Vector4 red = new(1, 0, 0, 1f); private readonly Vector4 yellow = new(249 / 255f, 180 / 255f, 45 / 255f, 1); - private SettingsRoll? newRoll; + private SettingsStructure.Settings settings; - private Settings settings; - private bool stepFormatValid = true; + /// + /// Tracks new roll + /// + private SettingsRoll? newRoll; public SettingsWindow(Plugin plugin) : base("Settings##HRC") { @@ -36,7 +37,7 @@ public class SettingsWindow : Window, IDisposable SizeCondition = ImGuiCond.Always; configuration = plugin.Configuration; - settings = new Settings(); + settings = new SettingsStructure.Settings(configuration); } public void Dispose() { } @@ -45,46 +46,30 @@ public class SettingsWindow : Window, IDisposable public override void Draw() { - // todo integrate for every field - var drawList = ImGui.GetWindowDrawList(); - - var center = ImGui.GetCursorScreenPos(); - const uint radius = 10; - - var circleColor = ImGui.GetColorU32(yellow); - var borderColor = ImGui.GetColorU32(red); - var textColor = ImGui.GetColorU32(red); - - drawList.AddCircleFilled(center + new Vector2(radius, radius), radius, circleColor); - drawList.AddCircle(center + new Vector2(radius, radius), radius, borderColor, 0, 2.5f); - - const string text = "!"; - var textSize = ImGui.CalcTextSize(text); - var textPos = center + new Vector2( - radius - (textSize.X * 0.5f), - radius - (textSize.Y * 0.5f) - ); - - drawList.AddText(textPos, textColor, text); - - ImGui.Dummy(new Vector2(radius * 2f, radius * 2f)); // todo set up multiplier, roll, color, etc // todo add button for rolls - if (ImGui.CollapsingHeader("Rolls##settings")) { - if (ImGui.Button("Add roll") && TempRoll) + ImGui.BeginDisabled(newRoll != null); + if (ImGui.Button("Add roll") && newRoll == null) { - // TODO no new rolls must be there - newRoll = new SettingsRoll(); + newRoll = new SettingsRoll(null, null, null); + // todo display shit + + // todo make it display actual error + ImGui.SameLine(); + if (!newRoll.IsValid) ImGui.Text("ERROR"); + } + ImGui.EndDisabled(); + + // todo display new roll + + foreach (var roll in settings.RollsCollection.Rolls) + { + // todo here we put existing rolls } - // todo here we put new rolls - // foreach (var roll in settings.rolls) - // { - // // todo here we put existing rolls - // } } if (ImGui.CollapsingHeader("General##settings")) @@ -128,6 +113,33 @@ public class SettingsWindow : Window, IDisposable if (ImGui.Button("Reset")) settings = configuration.Settings; } + private void DrawError() + { + // todo integrate for every field + var drawList = ImGui.GetWindowDrawList(); + + var center = ImGui.GetCursorScreenPos(); + const uint radius = 10; + + var circleColor = ImGui.GetColorU32(yellow); + var borderColor = ImGui.GetColorU32(red); + var textColor = ImGui.GetColorU32(red); + + drawList.AddCircleFilled(center + new Vector2(radius, radius), radius, circleColor); + drawList.AddCircle(center + new Vector2(radius, radius), radius, borderColor, 0, 2.5f); + + const string text = "!"; + var textSize = ImGui.CalcTextSize(text); + var textPos = center + new Vector2( + radius - (textSize.X * 0.5f), + radius - (textSize.Y * 0.5f) + ); + + drawList.AddText(textPos, textColor, text); + + ImGui.Dummy(new Vector2(radius * 2f, radius * 2f)); + } + /// /// Returns false if the roll is to be removed /// @@ -138,7 +150,7 @@ public class SettingsWindow : Window, IDisposable private (bool? valid, bool change) DisplayRollSetting( ref uint multiplier, ref uint roll, ref Vector4 colour, ref uint id, ref) { - ImGui.SetNextItemWidth(RollSettingInputWidth); + ImGui.SetNextItemWidth(RollInputWidth); ImGui.InputUInt($"##multiplier{id}", ref multiplier); ImGui.SameLine(); @@ -146,7 +158,7 @@ public class SettingsWindow : Window, IDisposable ImGui.Text("x"); ImGui.SameLine(); - ImGui.SetNextItemWidth(RollSettingInputWidth); + ImGui.SetNextItemWidth(RollInputWidth); ImGui.InputUInt($"##roll{id}", ref roll); ImGui.SameLine(); @@ -167,18 +179,6 @@ public class SettingsWindow : Window, IDisposable var change = } - private bool ValidateRollSetting() - { - // multiplier must not already exist - - // roll must be between 1 and 999 - - // roll must not already exist - - // colour must not exist already - - return true; - } /// /// Returns true if valid, false if invalid or null if validity has no changed