additional settings changes

This commit is contained in:
2025-12-27 17:54:54 +01:00
parent e186db6fb0
commit 81a4bb4bc4
7 changed files with 133 additions and 74 deletions

View File

@@ -5,17 +5,17 @@ namespace HighRollerClassic.DataStructures;
public struct Settings public struct Settings
{ {
/// <summary> /// <summary>
/// Contains data about each multiplier, roll, etc. /// Contains data bout each multiplier, roll, etc.
/// </summary> /// </summary>
private List<SettingsRolls> rolls; public List<SettingsRolls> rolls;
/// <summary> /// <summary>
/// Maximum bet that will be allowed to set /// Maximum bet that will be allowed to set
/// </summary> /// </summary>
private uint maxBet; public uint maxBet;
/// <summary> /// <summary>
/// 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
/// </summary> /// </summary>
private uint step; public uint step;
} }

View File

@@ -7,8 +7,6 @@ public class Player(MenuTargetDefault target)
{ {
private Roll rolls = new(); private Roll rolls = new();
public int Bank { get; private set; } = 0; 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; public ulong ContentId { get; private set; } = target.TargetContentId;
} }

View File

@@ -1,5 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Dalamud.Game.Gui.ContextMenu; using Dalamud.Game.Gui.ContextMenu;
namespace HighRollerClassic; namespace HighRollerClassic;
@@ -8,13 +7,15 @@ public class PlayerManager
{ {
private List<Player> Players { get; set; } = []; private List<Player> Players { get; set; } = [];
public Player GetPlayer(MenuTargetDefault target) public Player? GetOrCreatePlayer(MenuTargetDefault? target)
{ {
foreach (var player in Players) if (target is null) return null;
if (player.ContentId == target.TargetContentId)
return player;
Players.Add(new Player(target)); var player = Players.Find(p => p.ContentId == target.TargetContentId);
return Players.Last(); if (player is not null) return player;
player = new Player(target);
Players.Add(player);
return player;
} }
} }

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using Dalamud.Game.ClientState.Objects.SubKinds; using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.Command; using Dalamud.Game.Command;
using Dalamud.Game.Gui.ContextMenu; using Dalamud.Game.Gui.ContextMenu;
@@ -7,40 +8,37 @@ using Dalamud.IoC;
using Dalamud.Plugin; using Dalamud.Plugin;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using HighRollerClassic.Windows; using HighRollerClassic.Windows;
using Lumina.Data.Parsing.Layer;
namespace HighRollerClassic; namespace HighRollerClassic;
public sealed class Plugin : IDalamudPlugin public sealed class Plugin : IDalamudPlugin
{ {
private const string CommandName = "/hrc"; private const string CommandName = "/hrc";
private readonly PluginState state = new(); private readonly WindowSystem windowSystem = new("HighRollerClassic");
private readonly List<GambaWindow> gambaWindows = [];
public readonly WindowSystem WindowSystem = new("HighRollerClassic");
public Plugin() public Plugin()
{ {
Configuration = PluginInterface.GetPluginConfig() as Configuration ?? new Configuration(); Configuration = PluginInterface.GetPluginConfig() as Configuration ?? new Configuration();
SettingsWindow = new SettingsWindow(this); SettingsWindow = new SettingsWindow(this);
MainWindow = new MainWindow(this, state); windowSystem.AddWindow(SettingsWindow);
WindowSystem.AddWindow(SettingsWindow);
WindowSystem.AddWindow(MainWindow);
CommandManager.AddHandler(CommandName, new CommandInfo(OnCommand) 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 // 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 // This adds a button to the plugin installer entry of this plugin which allows
// toggling the display status of the configuration ui // 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 // 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 // Add a simple message to the log with level set to information
// Use /xllog to open the log window in-game // Use /xllog to open the log window in-game
@@ -77,19 +75,21 @@ public sealed class Plugin : IDalamudPlugin
public Configuration Configuration { get; init; } public Configuration Configuration { get; init; }
private SettingsWindow SettingsWindow { get; init; } private SettingsWindow SettingsWindow { get; init; }
private MainWindow MainWindow { get; init; } private List<GambaWindow> Windows { get; init; }
public void Dispose() public void Dispose()
{ {
// Unregister all actions to not leak anything during disposal of plugin // Unregister all actions to not leak anything during disposal of plugin
PluginInterface.UiBuilder.Draw -= WindowSystem.Draw; PluginInterface.UiBuilder.Draw -= windowSystem.Draw;
PluginInterface.UiBuilder.OpenConfigUi -= ToggleConfigUi; PluginInterface.UiBuilder.OpenConfigUi -= ToggleSettingsUi;
PluginInterface.UiBuilder.OpenMainUi -= ToggleMainUi;
WindowSystem.RemoveAllWindows(); windowSystem.RemoveAllWindows();
SettingsWindow.Dispose(); SettingsWindow.Dispose();
MainWindow.Dispose(); foreach (var window in gambaWindows)
{
window.Dispose();
}
CommandManager.RemoveHandler(CommandName); CommandManager.RemoveHandler(CommandName);
@@ -99,17 +99,12 @@ public sealed class Plugin : IDalamudPlugin
private void OnCommand(string command, string args) private void OnCommand(string command, string args)
{ {
// In response to the slash command, toggle the display status of our main ui // In response to the slash command, toggle the display status of our main ui
MainWindow.Toggle();
}
public void ToggleConfigUi()
{
SettingsWindow.Toggle(); SettingsWindow.Toggle();
} }
public void ToggleMainUi() public void ToggleSettingsUi()
{ {
MainWindow.Toggle(); SettingsWindow.Toggle();
} }
public bool PlayerIsLoaded() public bool PlayerIsLoaded()
@@ -121,12 +116,12 @@ public sealed class Plugin : IDalamudPlugin
{ {
if (args.MenuType == ContextMenuType.Inventory) return; if (args.MenuType == ContextMenuType.Inventory) return;
// get character's (persistent) id
var target = (MenuTargetDefault)args.Target; 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; return;
} }
@@ -141,11 +136,28 @@ public sealed class Plugin : IDalamudPlugin
private Action<IMenuItemClickedArgs> ContextMenuPlayerGameStart(MenuTargetDefault target) private Action<IMenuItemClickedArgs> ContextMenuPlayerGameStart(MenuTargetDefault target)
{ {
return args => return _ =>
{ {
Log.Debug($"Starting match with {target.TargetName}"); Log.Debug($"Starting gamba with {target.TargetName}");
state.Target = target; CreateGambaWindow(target);
MainWindow.Toggle();
}; };
} }
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);
}
} }

View File

@@ -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; }
}

View File

@@ -1,18 +1,22 @@
using System; using System;
using System.Numerics; using System.Numerics;
using Dalamud.Bindings.ImGui; using Dalamud.Bindings.ImGui;
using Dalamud.Game.Gui.ContextMenu;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
namespace HighRollerClassic.Windows; namespace HighRollerClassic.Windows;
public class MainWindow : Window, IDisposable public class GambaWindow : Window, IDisposable
{ {
private readonly Configuration configuration; private readonly Configuration configuration;
private readonly Plugin plugin;
private readonly PluginState state;
public MainWindow(Plugin plugin, PluginState state) // todo remove state as the window will only be opened by us calling it with parameters window id
: base($"High Roller Classic###{state.Target?.TargetName ?? "null"}", 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) ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse)
{ {
SizeConstraints = new WindowSizeConstraints SizeConstraints = new WindowSizeConstraints
@@ -23,7 +27,9 @@ public class MainWindow : Window, IDisposable
this.plugin = plugin; this.plugin = plugin;
configuration = this.plugin.Configuration; configuration = this.plugin.Configuration;
this.state = state;
player = configuration.players.GetOrCreatePlayer(target);
name = target.TargetName;
} }
public void Dispose() { } public void Dispose() { }
@@ -42,19 +48,16 @@ public class MainWindow : Window, IDisposable
roll settings roll settings
message/macro 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( ImGui.Text(
"No target selected, please open HRC by right clicking the player and choosing the 'High Roller Classic' option"); "No target selected, please open HRC by right clicking the player and choosing the 'High Roller Classic' option");
return; return;
} }
var player = configuration.players.GetPlayer(state.Target); ImGui.Text($"Player: {name}");
state.Target = null;
ImGui.Text($"Player: {player}");
ImGui.Spacing(); ImGui.Spacing();
ImGui.Text($"Bank balance: {player.Bank} gil"); ImGui.Text($"Bank balance: {player.Bank} gil");

View File

@@ -9,6 +9,14 @@ namespace HighRollerClassic.Windows;
public class SettingsWindow : Window, IDisposable public class SettingsWindow : Window, IDisposable
{ {
private readonly Configuration configuration; 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 ###. // We give this window a constant ID using ###.
// This allows for labels to be dynamic, like "{FPS Counter}fps###XYZ counter window", // 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 | Flags = ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoScrollbar |
ImGuiWindowFlags.NoScrollWithMouse; ImGuiWindowFlags.NoScrollWithMouse;
Size = new Vector2(232, 90); Size = new Vector2(500, 300);
SizeCondition = ImGuiCond.Always; SizeCondition = ImGuiCond.Always;
configuration = plugin.Configuration; configuration = plugin.Configuration;
settings = configuration.settings;
} }
public void Dispose() { } public void Dispose() { }
@@ -30,13 +39,58 @@ public class SettingsWindow : Window, IDisposable
public override void Draw() public override void Draw()
{ {
Settings settings;
// todo set up multiplier, roll, color, etc // todo set up multiplier, roll, color, etc
// todo add button for rolls // 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();
}
/// <summary>
/// Validates inputs for Max bet and Step
/// </summary>
/// <exception cref="NotImplementedException"></exception>
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;
} }
} }