diff --git a/HighRollerClassic/Configuration.cs b/HighRollerClassic/Configuration.cs index 26ca079..0ba2f08 100644 --- a/HighRollerClassic/Configuration.cs +++ b/HighRollerClassic/Configuration.cs @@ -8,7 +8,7 @@ namespace HighRollerClassic; public class Configuration : IPluginConfiguration { public PlayerManager Players { get; set; } = new(); - public SettingsStructure.Settings Settings { get; set; } = new(null); + public SettingsStructure.Settings? Settings { get; set; } // is nullable if settings are not yet created public int Version { get; set; } = 0; diff --git a/HighRollerClassic/SettingsStructure/RollsCollection.cs b/HighRollerClassic/SettingsStructure/RollsCollection.cs index 025db11..ea46ce7 100644 --- a/HighRollerClassic/SettingsStructure/RollsCollection.cs +++ b/HighRollerClassic/SettingsStructure/RollsCollection.cs @@ -7,39 +7,16 @@ 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 - } + public List Rolls { get; private set; } = new(); /// /// Validates given roll /// /// The roll we wish to validate - /// Returns - private bool ValidateRoll(SettingsRoll newRoll) + /// Returns message TODO + private string? ValidateRoll(SettingsRoll newRoll) { - var inputValid = newRoll.IsValid; + if (!newRoll.IsValid) return "Invalid roll configuration input"; // existing values must not exist anywhere else var mpExists = Rolls.Exists(p => p != newRoll && p.Roll.Value == newRoll.Roll.Value); @@ -50,22 +27,22 @@ public class RollsCollection colourExists = Rolls.Exists(p => p != newRoll && p.Colour.Value == newRoll.Colour.Value); } - var fullNotExists = !mpExists && !rollExists && !colourExists; - - return inputValid && fullNotExists; + var hasDuplicate = mpExists && rollExists && colourExists; + return hasDuplicate ? "The roll configuration is not unique!" : null; } /// /// Does quick iteration to see if rolls are valid /// - /// true if all rolls are valid - public bool ValidateAll() + /// string if there is an error + public (bool valid, string? message) ValidateAll() { foreach (var roll in Rolls) { - if (!roll.IsValid) return false; + var val = ValidateRoll(roll); + if (ValidateRoll(roll) != null) return (false, val); } - return true; + return (true, null); } } diff --git a/HighRollerClassic/SettingsStructure/Settings.cs b/HighRollerClassic/SettingsStructure/Settings.cs index 1788a6d..6cb5094 100644 --- a/HighRollerClassic/SettingsStructure/Settings.cs +++ b/HighRollerClassic/SettingsStructure/Settings.cs @@ -26,11 +26,9 @@ public class Settings(Configuration? configuration) // TODO IMPLEMENT 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(); + public readonly RollsCollection Rolls = new(); // todo might get fucky wucky if maxbet is not yet defined - public bool IsValid => MaxBet.IsValid && Step.IsValid && RollsCollection.ValidateAll(); - public bool Set => IsValid && RollsCollection.Size > 0 && Macros.Count > 0; + public bool IsValid => MaxBet.IsValid && Step.IsValid && Rolls.ValidateAll().valid; + public bool Set => IsValid && Rolls.Rolls.Count > 0 && Macros.Count > 0; } diff --git a/HighRollerClassic/SettingsStructure/TrackedValue.cs b/HighRollerClassic/SettingsStructure/TrackedValue.cs index d6d3fe4..72a2669 100644 --- a/HighRollerClassic/SettingsStructure/TrackedValue.cs +++ b/HighRollerClassic/SettingsStructure/TrackedValue.cs @@ -11,23 +11,20 @@ namespace HighRollerClassic.SettingsStructure; /// Its value public class TrackedValue(SettingValueType type, Configuration? configuration, uint? valueInit) { - // TODO FIX!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - private uint? _value = valueInit; - /// /// The main value /// public uint? Value { - get => _value; + get; set { + if (value == field) return; + IsValid = CheckValid(value); - _value = value; + field = value; } - } - - public ref uint? ValueRef => ref _value; + } = valueInit; /// /// Tracks validity of the value @@ -63,7 +60,7 @@ public class TrackedValue(SettingValueType type, Configuration? configuration, u // if max bet is not set allow the user to set whichever they want // it will get invalidated as soon as maxbet is set anyway - /* TODO if any of setting is considered INVALID + /* TODO if any of setting is considered INVALID DO NOT USER USE THE APPLICATION */ return true; diff --git a/HighRollerClassic/Windows/GambaWindow.cs b/HighRollerClassic/Windows/GambaWindow.cs index 4181d1c..77fb030 100644 --- a/HighRollerClassic/Windows/GambaWindow.cs +++ b/HighRollerClassic/Windows/GambaWindow.cs @@ -11,7 +11,6 @@ public class GambaWindow : Window, IDisposable private readonly Configuration configuration; private readonly string name; - // todo remove state as the window will only be opened by us calling it with parameters window id private readonly Player? player; private readonly Plugin plugin; diff --git a/HighRollerClassic/Windows/SettingsWindow.cs b/HighRollerClassic/Windows/SettingsWindow.cs index 0de3bb0..d97e1e8 100644 --- a/HighRollerClassic/Windows/SettingsWindow.cs +++ b/HighRollerClassic/Windows/SettingsWindow.cs @@ -1,6 +1,8 @@ using System; +using System.Collections.Generic; using System.Numerics; using Dalamud.Bindings.ImGui; +using Dalamud.Interface; using Dalamud.Interface.Components; using Dalamud.Interface.Windowing; using HighRollerClassic.DataStructures; @@ -22,12 +24,7 @@ public class SettingsWindow : Window, IDisposable private readonly Vector4 red = new(1, 0, 0, 1f); private readonly Vector4 yellow = new(249 / 255f, 180 / 255f, 45 / 255f, 1); - private SettingsStructure.Settings settings; - - /// - /// Tracks new roll - /// - private SettingsRoll? newRoll; + private Settings settings; public SettingsWindow(Plugin plugin) : base("Settings##HRC") { @@ -37,7 +34,10 @@ public class SettingsWindow : Window, IDisposable SizeCondition = ImGuiCond.Always; configuration = plugin.Configuration; - settings = new SettingsStructure.Settings(configuration); + + // todo settings from config can be null + // todo if null create new, if not copy existing + settings = new Settings(configuration); } public void Dispose() { } @@ -47,37 +47,30 @@ public class SettingsWindow : Window, IDisposable public override void Draw() { // todo set up multiplier, roll, color, etc - // todo add button for rolls if (ImGui.CollapsingHeader("Rolls##settings")) { - ImGui.BeginDisabled(newRoll != null); - if (ImGui.Button("Add roll") && newRoll == null) + if (ImGui.Button("Add roll")) { - newRoll = new SettingsRoll(null, null, null); - // todo display shit - - // todo make it display actual error - ImGui.SameLine(); - if (!newRoll.IsValid) ImGui.Text("ERROR"); + settings.Rolls.Rolls.Add(new SettingsRoll(null, null, null)); } - ImGui.EndDisabled(); - // todo display new roll - foreach (var roll in settings.RollsCollection.Rolls) + for (uint i = 0; i < settings.Rolls.Rolls.Count; i++) { - // todo here we put existing rolls + DisplayRollSetting(i, settings.Rolls.Rolls[(int)i]); } + + // todo reorder by multiplier/roll } if (ImGui.CollapsingHeader("General##settings")) { - var maxbetValid = LabelTextInput("max_bet_label", "Max bet", "max_bet_text", ref settings.MaxBet); + LabelTextInput("max_bet_label", "Max bet", "max_bet_text", settings.MaxBet); ImGui.Spacing(); - var stepValid = LabelTextInput("step_label", "Step", "step_input", ref settings.Step.ValueRef); + LabelTextInput("step_label", "Step", "step_input", settings.Step); ImGui.Spacing(); ImGui.Checkbox("Developer options", ref settings.devOptions); @@ -88,11 +81,9 @@ public class SettingsWindow : Window, IDisposable // todo add developer settings - like the ability to have every character have HRC open } - var inputValidation = ValidateInput(); - ImGui.Spacing(); - - ImGui.BeginDisabled(!inputValidation.valid); + var validation = settings.Rolls.ValidateAll(); + ImGui.BeginDisabled(validation != null); if (ImGui.Button("Save")) { @@ -105,8 +96,8 @@ public class SettingsWindow : Window, IDisposable ImGui.EndDisabled(); ImGui.SameLine(); - if (!inputValidation.valid && ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)) - ImGui.SetTooltip(inputValidation.message); + if (validation != null && ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)) + ImGui.SetTooltip(validation); if (ImGui.Button("Reset")) settings = configuration.Settings; } @@ -145,11 +136,20 @@ public class SettingsWindow : Window, IDisposable /// how much user rolls /// colours the rolls in main window, depending on their value /// tracks which roll we're setting so input fields don't have the same ids - private (bool? valid, bool change) DisplayRollSetting( - ref uint multiplier, ref uint roll, ref Vector4 colour, ref uint id, ref TrackedValue original) + private void DisplayRollSetting(uint id, SettingsRoll rollConfig) { + uint multiplier = rollConfig.Multiplier.Value ?? 0; ImGui.SetNextItemWidth(RollInputWidth); - ImGui.InputUInt($"##multiplier{id}", ref multiplier); + if (ImGui.InputUInt($"##multiplier{id}", ref multiplier)) + { + // todo edge case if we change but don't get good value + /* possible solutions + 1. do int + 2. do string textbox + 3. make a fucky check if the new value = old value and in that case don't send it in + */ + rollConfig.Multiplier.Value = multiplier; + } ImGui.SameLine(); @@ -160,21 +160,22 @@ public class SettingsWindow : Window, IDisposable ImGui.InputUInt($"##roll{id}", ref roll); ImGui.SameLine(); + var colourVal = rollConfig.Colour.Value.HasValue + ? ColorHelpers.RgbaUintToVector4(rollConfig.Colour.Value.Value) + : new Vector4(0, 0, 0, 1); var newColour = ImGuiComponents.ColorPickerWithPalette( - (int)id, "placeholder", colour); + (int)id, "placeholder", colourVal); + // TODO if colour is black (0,0,0) set it to null ImGui.SameLine(); if (ImGui.Button("-")) { // signals to the colour to remove this roll setting - return null; + settings.Rolls.Rolls.Remove(rollConfig); } // TODO verify input // we need to verify if data inputted is "good" - - var valid = ValidateRollSetting(); - var change = } @@ -186,7 +187,7 @@ public class SettingsWindow : Window, IDisposable /// id of the input field /// the original value in configuration to compare it to private void LabelTextInput( - string labelId, string labelText, string inputId, ref TrackedValue original) + string labelId, string labelText, string inputId, TrackedValue original) { ImGui.LabelText($"###{labelId}", $"{labelText}: "); ImGui.SameLine(XOffset, Spacing); @@ -204,36 +205,8 @@ public class SettingsWindow : Window, IDisposable } if (original.IsValid) return; - // todo test ImGui.SameLine(); // todo alert that appears when field doesn't match the configuration ImGui.Text("ERROR"); } - - /// - /// Validates input values for Max bet and Step - /// - /// - private (bool valid, string message) ValidateInput() - { - var valid = true; - var message = string.Empty; - - if (!maxBetFormatValid || !stepFormatValid) SetError("Input fields have invalid data", ref message, ref valid); - - if (settings.MaxBet > MaxAllowedGil) - SetError("Entered bet amount exceeds maximum possible bet", ref message, ref valid); - - if (settings.Step > configuration.Settings.MaxBet || settings.MaxBet < configuration.Settings.MaxBet) - SetError("Step change must not exceed current maximum bet", ref message, ref valid); - - return (valid, message); - } - - private static void SetError(string errMsg, ref string message, ref bool valid) - { - if (!valid) message += "\n"; - message += errMsg; - valid = false; - } }