diff --git a/HighRollerClassic/DataStructures/Settings.cs b/HighRollerClassic/DataStructures/Settings.cs
index dd96d7d..86b8b7a 100644
--- a/HighRollerClassic/DataStructures/Settings.cs
+++ b/HighRollerClassic/DataStructures/Settings.cs
@@ -5,17 +5,17 @@ namespace HighRollerClassic.DataStructures;
public struct Settings
{
///
- /// Contains data about each multiplier, roll, etc.
+ /// Contains data bout each multiplier, roll, etc.
///
- private List rolls;
-
+ public List rolls;
+
///
- /// Maximum bet that will be allowed to set
+ /// Maximum bet that will be allowed to set
///
- private uint maxBet;
-
+ public uint maxBet;
+
///
- /// How much the bet will change when user adjusts their bet via +/- keys
+ /// How much the bet will change when user adjusts their bet via +/- keys
///
- private uint step;
+ public uint step;
}
diff --git a/HighRollerClassic/Player.cs b/HighRollerClassic/Player.cs
index ec705b0..460ea2b 100644
--- a/HighRollerClassic/Player.cs
+++ b/HighRollerClassic/Player.cs
@@ -7,8 +7,6 @@ public class Player(MenuTargetDefault target)
{
private Roll rolls = new();
public int Bank { get; private set; } = 0;
- public string Name { get; private set; } = target.TargetName;
- // todo maybe remove it and tie it to dalamud's api to get accurate character name once per session
public ulong ContentId { get; private set; } = target.TargetContentId;
}
diff --git a/HighRollerClassic/PlayerManager.cs b/HighRollerClassic/PlayerManager.cs
index 6108d4b..3839ab3 100644
--- a/HighRollerClassic/PlayerManager.cs
+++ b/HighRollerClassic/PlayerManager.cs
@@ -1,5 +1,4 @@
using System.Collections.Generic;
-using System.Linq;
using Dalamud.Game.Gui.ContextMenu;
namespace HighRollerClassic;
@@ -8,13 +7,15 @@ public class PlayerManager
{
private List Players { get; set; } = [];
- public Player GetPlayer(MenuTargetDefault target)
+ public Player? GetOrCreatePlayer(MenuTargetDefault? target)
{
- foreach (var player in Players)
- if (player.ContentId == target.TargetContentId)
- return player;
+ if (target is null) return null;
- Players.Add(new Player(target));
- return Players.Last();
+ var player = Players.Find(p => p.ContentId == target.TargetContentId);
+ if (player is not null) return player;
+
+ player = new Player(target);
+ Players.Add(player);
+ return player;
}
}
diff --git a/HighRollerClassic/Plugin.cs b/HighRollerClassic/Plugin.cs
index 3939e24..ce78a92 100644
--- a/HighRollerClassic/Plugin.cs
+++ b/HighRollerClassic/Plugin.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.Command;
using Dalamud.Game.Gui.ContextMenu;
@@ -7,40 +8,37 @@ using Dalamud.IoC;
using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using HighRollerClassic.Windows;
+using Lumina.Data.Parsing.Layer;
namespace HighRollerClassic;
public sealed class Plugin : IDalamudPlugin
{
private const string CommandName = "/hrc";
- private readonly PluginState state = new();
-
- public readonly WindowSystem WindowSystem = new("HighRollerClassic");
+ private readonly WindowSystem windowSystem = new("HighRollerClassic");
+ private readonly List gambaWindows = [];
public Plugin()
{
Configuration = PluginInterface.GetPluginConfig() as Configuration ?? new Configuration();
SettingsWindow = new SettingsWindow(this);
- MainWindow = new MainWindow(this, state);
-
- WindowSystem.AddWindow(SettingsWindow);
- WindowSystem.AddWindow(MainWindow);
+ windowSystem.AddWindow(SettingsWindow);
CommandManager.AddHandler(CommandName, new CommandInfo(OnCommand)
{
- HelpMessage = "Opens the High Roller Classic window"
+ HelpMessage = "Opens the HRC Settings"
});
// Tell the UI system that we want our windows to be drawn through the window system
- PluginInterface.UiBuilder.Draw += WindowSystem.Draw;
+ PluginInterface.UiBuilder.Draw += windowSystem.Draw;
// This adds a button to the plugin installer entry of this plugin which allows
// toggling the display status of the configuration ui
- PluginInterface.UiBuilder.OpenConfigUi += ToggleConfigUi;
+ PluginInterface.UiBuilder.OpenConfigUi += ToggleSettingsUi;
// Adds another button doing the same but for the main ui of the plugin
- PluginInterface.UiBuilder.OpenMainUi += ToggleMainUi;
+ // PluginInterface.UiBuilder.OpenMainUi += ToggleMainUi;
// Add a simple message to the log with level set to information
// Use /xllog to open the log window in-game
@@ -77,19 +75,21 @@ public sealed class Plugin : IDalamudPlugin
public Configuration Configuration { get; init; }
private SettingsWindow SettingsWindow { get; init; }
- private MainWindow MainWindow { get; init; }
+ private List Windows { get; init; }
public void Dispose()
{
// Unregister all actions to not leak anything during disposal of plugin
- PluginInterface.UiBuilder.Draw -= WindowSystem.Draw;
- PluginInterface.UiBuilder.OpenConfigUi -= ToggleConfigUi;
- PluginInterface.UiBuilder.OpenMainUi -= ToggleMainUi;
+ PluginInterface.UiBuilder.Draw -= windowSystem.Draw;
+ PluginInterface.UiBuilder.OpenConfigUi -= ToggleSettingsUi;
- WindowSystem.RemoveAllWindows();
+ windowSystem.RemoveAllWindows();
SettingsWindow.Dispose();
- MainWindow.Dispose();
+ foreach (var window in gambaWindows)
+ {
+ window.Dispose();
+ }
CommandManager.RemoveHandler(CommandName);
@@ -99,17 +99,12 @@ public sealed class Plugin : IDalamudPlugin
private void OnCommand(string command, string args)
{
// In response to the slash command, toggle the display status of our main ui
- MainWindow.Toggle();
- }
-
- public void ToggleConfigUi()
- {
SettingsWindow.Toggle();
}
- public void ToggleMainUi()
+ public void ToggleSettingsUi()
{
- MainWindow.Toggle();
+ SettingsWindow.Toggle();
}
public bool PlayerIsLoaded()
@@ -121,12 +116,12 @@ public sealed class Plugin : IDalamudPlugin
{
if (args.MenuType == ContextMenuType.Inventory) return;
- // get character's (persistent) id
var target = (MenuTargetDefault)args.Target;
- if (target.TargetObject is not IPlayerCharacter)
+ // target must be a player that is not self
+ if (target.TargetObject is not IPlayerCharacter || target.TargetContentId == PlayerState.ContentId)
{
- Log.Debug("Not a player, returning");
+ Log.Debug("Not a foreign player");
return;
}
@@ -141,11 +136,28 @@ public sealed class Plugin : IDalamudPlugin
private Action ContextMenuPlayerGameStart(MenuTargetDefault target)
{
- return args =>
+ return _ =>
{
- Log.Debug($"Starting match with {target.TargetName}");
- state.Target = target;
- MainWindow.Toggle();
+ Log.Debug($"Starting gamba with {target.TargetName}");
+ CreateGambaWindow(target);
};
}
+
+ private void CreateGambaWindow(MenuTargetDefault target)
+ {
+ var existingWindow = gambaWindows.Find(p => p.WindowName.Contains(target.TargetContentId.ToString()));
+ if (existingWindow is { IsOpen: false })
+ {
+ existingWindow.Toggle();
+ return;
+ }
+
+ var window = new GambaWindow(this, target)
+ {
+ IsOpen = true,
+ };
+
+ gambaWindows.Add(window);
+ windowSystem.AddWindow(window);
+ }
}
diff --git a/HighRollerClassic/PluginState.cs b/HighRollerClassic/PluginState.cs
deleted file mode 100644
index deb2ffe..0000000
--- a/HighRollerClassic/PluginState.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using Dalamud.Game.Gui.ContextMenu;
-
-namespace HighRollerClassic;
-
-public sealed class PluginState
-{
- /// tracks selected target as we pass it to the window
- public MenuTargetDefault? Target { get; set; }
-}
diff --git a/HighRollerClassic/Windows/MainWindow.cs b/HighRollerClassic/Windows/GambaWindow.cs
similarity index 67%
rename from HighRollerClassic/Windows/MainWindow.cs
rename to HighRollerClassic/Windows/GambaWindow.cs
index 024c31e..7159be2 100644
--- a/HighRollerClassic/Windows/MainWindow.cs
+++ b/HighRollerClassic/Windows/GambaWindow.cs
@@ -1,18 +1,22 @@
using System;
using System.Numerics;
using Dalamud.Bindings.ImGui;
+using Dalamud.Game.Gui.ContextMenu;
using Dalamud.Interface.Windowing;
namespace HighRollerClassic.Windows;
-public class MainWindow : Window, IDisposable
+public class GambaWindow : Window, IDisposable
{
private readonly Configuration configuration;
- private readonly Plugin plugin;
- private readonly PluginState state;
- public MainWindow(Plugin plugin, PluginState state)
- : base($"High Roller Classic###{state.Target?.TargetName ?? "null"}",
+ // 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;
+ private string name;
+
+ public GambaWindow(Plugin plugin, MenuTargetDefault target)
+ : base($"High Roller Classic###{target.TargetContentId}",
ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse)
{
SizeConstraints = new WindowSizeConstraints
@@ -23,7 +27,9 @@ public class MainWindow : Window, IDisposable
this.plugin = plugin;
configuration = this.plugin.Configuration;
- this.state = state;
+
+ player = configuration.players.GetOrCreatePlayer(target);
+ name = target.TargetName;
}
public void Dispose() { }
@@ -42,19 +48,16 @@ public class MainWindow : Window, IDisposable
roll settings
message/macro settings
*/
- // TODO create player project and clear the existing shared state
+ // todo if player is null, then allow user to set user by clicking on them manually
- if (state.Target == null)
+ if (player == null)
{
ImGui.Text(
"No target selected, please open HRC by right clicking the player and choosing the 'High Roller Classic' option");
return;
}
- var player = configuration.players.GetPlayer(state.Target);
- state.Target = null;
-
- ImGui.Text($"Player: {player}");
+ ImGui.Text($"Player: {name}");
ImGui.Spacing();
ImGui.Text($"Bank balance: {player.Bank} gil");
diff --git a/HighRollerClassic/Windows/SettingsWindow.cs b/HighRollerClassic/Windows/SettingsWindow.cs
index 6383032..40dc503 100644
--- a/HighRollerClassic/Windows/SettingsWindow.cs
+++ b/HighRollerClassic/Windows/SettingsWindow.cs
@@ -9,6 +9,14 @@ namespace HighRollerClassic.Windows;
public class SettingsWindow : Window, IDisposable
{
private readonly Configuration configuration;
+ private Settings settings;
+
+ private const int XOffset = 80;
+ private const int Spacing = 5;
+ private const int InputWidth = 105;
+ private const int InputMaxLen = 11;
+
+ private const uint MaxPossibleBet = 999_999_999;
// We give this window a constant ID using ###.
// This allows for labels to be dynamic, like "{FPS Counter}fps###XYZ counter window",
@@ -18,10 +26,11 @@ public class SettingsWindow : Window, IDisposable
Flags = ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoScrollbar |
ImGuiWindowFlags.NoScrollWithMouse;
- Size = new Vector2(232, 90);
+ Size = new Vector2(500, 300);
SizeCondition = ImGuiCond.Always;
configuration = plugin.Configuration;
+ settings = configuration.settings;
}
public void Dispose() { }
@@ -30,13 +39,58 @@ public class SettingsWindow : Window, IDisposable
public override void Draw()
{
- Settings settings;
-
// todo set up multiplier, roll, color, etc
// todo add button for rolls
- // todo setup max bet, change
+ ImGui.LabelText("###max_bet_label", "Max bet: ");
+ ImGui.SameLine(XOffset, Spacing);
+ ImGui.SetNextItemWidth(InputWidth);
+
+ // TODO maybe throw it in a function because we have 2 fields behaving the same except for variables and label
+ var betBuf = settings.maxBet.ToString("N0");
+ if (ImGui.InputText("###max_bet_text", ref betBuf, InputMaxLen))
+ {
+ var num = betBuf.Replace(",", string.Empty).Replace(".", string.Empty);
+ if (uint.TryParse(num, out var parsedValue)) settings.maxBet = parsedValue;
+ }
- // todo save button which will copy our settings to configuration and invoke .Save() to save configuration to disk
+ ImGui.Spacing();
+
+ ImGui.LabelText("###step_label", "Step: ");
+ ImGui.SameLine(XOffset, Spacing);
+ ImGui.SetNextItemWidth(InputWidth);
+
+ var stepBuf = settings.step.ToString("N0");
+ if (ImGui.InputText("###step_input", ref stepBuf, InputMaxLen))
+ {
+ var num = stepBuf.Replace(",", string.Empty).Replace(".", string.Empty);
+ if (uint.TryParse(num, out var parsedValue)) settings.step = parsedValue;
+ }
+
+ ImGui.Spacing();
+
+ // todo validation step?
+ var invalidInput = !ValidateInput();
+
+ ImGui.BeginDisabled(invalidInput);
+ if (ImGui.Button("Save"))
+ {
+ configuration.settings = settings;
+ configuration.Save();
+ }
+ ImGui.EndDisabled();
+ }
+
+ ///
+ /// Validates inputs for Max bet and Step
+ ///
+ ///
+ private bool ValidateInput()
+ {
+ // TODO add explanation why input validation failed
+ if (settings.maxBet > MaxPossibleBet) return false;
+ if (settings.step > configuration.settings.maxBet) return false;
+
+ return true;
}
}