Add config option to switch between VBM/RSR
This commit is contained in:
parent
471cc563f4
commit
118a5948a5
@ -7,9 +7,9 @@ namespace Questionable;
|
||||
|
||||
internal sealed class Configuration : IPluginConfiguration
|
||||
{
|
||||
public const int PluginSetupVersion = 2;
|
||||
public const int PluginSetupVersion = 3;
|
||||
|
||||
public int Version { get; set; } =1 ;
|
||||
public int Version { get; set; } = 1;
|
||||
public int PluginSetupCompleteVersion { get; set; }
|
||||
public GeneralConfiguration General { get; } = new();
|
||||
public NotificationConfiguration Notifications { get; } = new();
|
||||
@ -23,6 +23,7 @@ internal sealed class Configuration : IPluginConfiguration
|
||||
|
||||
internal sealed class GeneralConfiguration
|
||||
{
|
||||
public ECombatModule CombatModule { get; set; } = ECombatModule.BossMod;
|
||||
public uint MountId { get; set; } = 71;
|
||||
public GrandCompany GrandCompany { get; set; } = GrandCompany.None;
|
||||
public bool HideInAllInstances { get; set; } = true;
|
||||
@ -45,4 +46,11 @@ internal sealed class Configuration : IPluginConfiguration
|
||||
public bool NeverFly { get; set; }
|
||||
public bool AdditionalStatusInformation { get; set; }
|
||||
}
|
||||
|
||||
internal enum ECombatModule
|
||||
{
|
||||
None,
|
||||
BossMod,
|
||||
RotationSolverReborn,
|
||||
}
|
||||
}
|
||||
|
@ -12,22 +12,44 @@ using System.Numerics;
|
||||
|
||||
namespace Questionable.Controller.CombatModules;
|
||||
|
||||
internal sealed class BossModModule(ILogger<BossModModule> logger, MovementController movementController, IClientState clientState, IDalamudPluginInterface pluginInterface) : ICombatModule, IDisposable
|
||||
internal sealed class BossModModule : ICombatModule, IDisposable
|
||||
{
|
||||
private const string Name = "BossMod";
|
||||
private readonly ILogger<BossModModule> _logger = logger;
|
||||
private readonly MovementController _movementController = movementController;
|
||||
private readonly IClientState _clientState = clientState;
|
||||
private readonly ICallGateSubscriber<string, string?> _getPreset = pluginInterface.GetIpcSubscriber<string, string?>($"{Name}.Presets.Get");
|
||||
private readonly ICallGateSubscriber<string, bool, bool> _createPreset = pluginInterface.GetIpcSubscriber<string, bool, bool>($"{Name}.Presets.Create");
|
||||
private readonly ICallGateSubscriber<string, bool> _setPreset = pluginInterface.GetIpcSubscriber<string, bool>($"{Name}.Presets.SetActive");
|
||||
private readonly ICallGateSubscriber<bool> _clearPreset = pluginInterface.GetIpcSubscriber<bool>($"{Name}.Presets.ClearActive");
|
||||
private readonly ILogger<BossModModule> _logger;
|
||||
private readonly MovementController _movementController;
|
||||
private readonly IClientState _clientState;
|
||||
private readonly Configuration _configuration;
|
||||
private readonly ICallGateSubscriber<string, string?> _getPreset;
|
||||
private readonly ICallGateSubscriber<string, bool, bool> _createPreset;
|
||||
private readonly ICallGateSubscriber<string, bool> _setPreset;
|
||||
private readonly ICallGateSubscriber<bool> _clearPreset;
|
||||
|
||||
private static Stream Preset => typeof(BossModModule).Assembly.GetManifestResourceStream("Questionable.Controller.CombatModules.BossModPreset")!;
|
||||
private DateTime _lastDistanceCheck = DateTime.MinValue;
|
||||
|
||||
public BossModModule(
|
||||
ILogger<BossModModule> logger,
|
||||
MovementController movementController,
|
||||
IClientState clientState,
|
||||
IDalamudPluginInterface pluginInterface,
|
||||
Configuration configuration)
|
||||
{
|
||||
_logger = logger;
|
||||
_movementController = movementController;
|
||||
_clientState = clientState;
|
||||
_configuration = configuration;
|
||||
|
||||
_getPreset = pluginInterface.GetIpcSubscriber<string, string?>($"{Name}.Presets.Get");
|
||||
_createPreset = pluginInterface.GetIpcSubscriber<string, bool, bool>($"{Name}.Presets.Create");
|
||||
_setPreset = pluginInterface.GetIpcSubscriber<string, bool>($"{Name}.Presets.SetActive");
|
||||
_clearPreset = pluginInterface.GetIpcSubscriber<bool>($"{Name}.Presets.ClearActive");
|
||||
}
|
||||
|
||||
public bool CanHandleFight(CombatController.CombatData combatData)
|
||||
{
|
||||
if (_configuration.General.CombatModule != Configuration.ECombatModule.BossMod)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
return _getPreset.HasFunction;
|
||||
|
@ -16,17 +16,19 @@ internal sealed class RotationSolverRebornModule : ICombatModule, IDisposable
|
||||
private readonly ILogger<RotationSolverRebornModule> _logger;
|
||||
private readonly MovementController _movementController;
|
||||
private readonly IClientState _clientState;
|
||||
private readonly Configuration _configuration;
|
||||
private readonly ICallGateSubscriber<string, object> _test;
|
||||
private readonly ICallGateSubscriber<StateCommandType, object> _changeOperationMode;
|
||||
|
||||
private DateTime _lastDistanceCheck = DateTime.MinValue;
|
||||
|
||||
public RotationSolverRebornModule(ILogger<RotationSolverRebornModule> logger, MovementController movementController,
|
||||
IClientState clientState, IDalamudPluginInterface pluginInterface)
|
||||
IClientState clientState, IDalamudPluginInterface pluginInterface, Configuration configuration)
|
||||
{
|
||||
_logger = logger;
|
||||
_movementController = movementController;
|
||||
_clientState = clientState;
|
||||
_configuration = configuration;
|
||||
_test = pluginInterface.GetIpcSubscriber<string, object>("RotationSolverReborn.Test");
|
||||
_changeOperationMode =
|
||||
pluginInterface.GetIpcSubscriber<StateCommandType, object>("RotationSolverReborn.ChangeOperatingMode");
|
||||
@ -34,6 +36,9 @@ internal sealed class RotationSolverRebornModule : ICombatModule, IDisposable
|
||||
|
||||
public bool CanHandleFight(CombatController.CombatData combatData)
|
||||
{
|
||||
if (_configuration.General.CombatModule != Configuration.ECombatModule.RotationSolverReborn)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
_test.InvokeAction("Validate RSR is callable from Questionable");
|
||||
|
@ -26,6 +26,7 @@ internal sealed class ConfigWindow : LWindow, IPersistableWindowConfig
|
||||
private readonly uint[] _mountIds;
|
||||
private readonly string[] _mountNames;
|
||||
|
||||
private readonly string[] _combatModuleNames = ["None", "Boss Mod (VBM)", "Rotation Solver Reborn"];
|
||||
private readonly string[] _grandCompanyNames =
|
||||
["None (manually pick quest)", "Maelstrom", "Twin Adder", "Immortal Flames"];
|
||||
|
||||
@ -65,6 +66,14 @@ internal sealed class ConfigWindow : LWindow, IPersistableWindowConfig
|
||||
using var tab = ImRaii.TabItem("General");
|
||||
if (!tab)
|
||||
return;
|
||||
|
||||
int selectedCombatModule = (int)_configuration.General.CombatModule;
|
||||
if (ImGui.Combo("Preferred Combat Module", ref selectedCombatModule, _combatModuleNames, _combatModuleNames.Length))
|
||||
{
|
||||
_configuration.General.CombatModule = (Configuration.ECombatModule)selectedCombatModule;
|
||||
Save();
|
||||
}
|
||||
|
||||
int selectedMount = Array.FindIndex(_mountIds, x => x == _configuration.General.MountId);
|
||||
if (selectedMount == -1)
|
||||
{
|
||||
|
@ -44,6 +44,27 @@ internal sealed class OneTimeSetupWindow : LWindow
|
||||
new Uri("https://github.com/NightmareXIV/MyDalamudPlugins/raw/main/pluginmaster.json")),
|
||||
];
|
||||
|
||||
private static readonly IReadOnlyDictionary<Configuration.ECombatModule, PluginInfo> CombatPlugins = new Dictionary<Configuration.ECombatModule, PluginInfo>
|
||||
{
|
||||
{
|
||||
Configuration.ECombatModule.BossMod,
|
||||
new("Boss Mod (VBM)",
|
||||
"BossMod",
|
||||
string.Empty,
|
||||
new Uri("https://github.com/awgil/ffxiv_bossmod"),
|
||||
new Uri("https://puni.sh/api/repository/veyn"))
|
||||
},
|
||||
{
|
||||
Configuration.ECombatModule.RotationSolverReborn,
|
||||
new("Rotation Solver Reborn",
|
||||
"RotationSolver",
|
||||
string.Empty,
|
||||
new Uri("https://github.com/FFXIV-CombatReborn/RotationSolverReborn"),
|
||||
new Uri(
|
||||
"https://raw.githubusercontent.com/FFXIV-CombatReborn/CombatRebornRepo/main/pluginmaster.json"))
|
||||
},
|
||||
}.AsReadOnly();
|
||||
|
||||
private readonly IReadOnlyList<PluginInfo> _recommendedPlugins;
|
||||
|
||||
private readonly Configuration _configuration;
|
||||
@ -60,18 +81,8 @@ internal sealed class OneTimeSetupWindow : LWindow
|
||||
_pluginInterface = pluginInterface;
|
||||
_uiUtils = uiUtils;
|
||||
_logger = logger;
|
||||
|
||||
_recommendedPlugins =
|
||||
[
|
||||
new("Rotation Solver Reborn",
|
||||
"RotationSolver",
|
||||
"""
|
||||
Automatically handles most combat interactions you encounter
|
||||
during quests, including being interrupted by mobs.
|
||||
""",
|
||||
new Uri("https://github.com/FFXIV-CombatReborn/RotationSolverReborn"),
|
||||
new Uri(
|
||||
"https://raw.githubusercontent.com/FFXIV-CombatReborn/CombatRebornRepo/main/pluginmaster.json")),
|
||||
new PluginInfo("CBT (formerly known as Automaton)",
|
||||
"Automaton",
|
||||
"""
|
||||
@ -120,6 +131,25 @@ internal sealed class OneTimeSetupWindow : LWindow
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
|
||||
ImGui.Text("Questionable supports multiple rotation/combat plugins, please pick the one\nyou want to use:");
|
||||
|
||||
using (ImRaii.PushIndent())
|
||||
{
|
||||
if (ImGui.RadioButton("No rotation/combat plugin (combat must be done manually)",
|
||||
_configuration.General.CombatModule == Configuration.ECombatModule.None))
|
||||
{
|
||||
_configuration.General.CombatModule = Configuration.ECombatModule.None;
|
||||
_pluginInterface.SavePluginConfig(_configuration);
|
||||
}
|
||||
|
||||
DrawCombatPlugin(Configuration.ECombatModule.BossMod, checklistPadding);
|
||||
DrawCombatPlugin(Configuration.ECombatModule.RotationSolverReborn, checklistPadding);
|
||||
}
|
||||
|
||||
ImGui.Spacing();
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
|
||||
ImGui.Text("The following plugins are recommended, but not required:");
|
||||
using (ImRaii.PushIndent())
|
||||
{
|
||||
@ -164,13 +194,52 @@ internal sealed class OneTimeSetupWindow : LWindow
|
||||
|
||||
private bool DrawPlugin(PluginInfo plugin, float checklistPadding)
|
||||
{
|
||||
bool isInstalled = IsPluginInstalled(plugin);
|
||||
using (ImRaii.PushId("plugin_" + plugin.DisplayName))
|
||||
{
|
||||
bool isInstalled = IsPluginInstalled(plugin);
|
||||
_uiUtils.ChecklistItem(plugin.DisplayName, isInstalled);
|
||||
|
||||
DrawPluginDetails(plugin, checklistPadding, isInstalled);
|
||||
return isInstalled;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawCombatPlugin(Configuration.ECombatModule combatModule, float checklistPadding)
|
||||
{
|
||||
ImGui.Spacing();
|
||||
|
||||
PluginInfo plugin = CombatPlugins[combatModule];
|
||||
using (ImRaii.PushId("plugin_" + plugin.DisplayName))
|
||||
{
|
||||
bool isInstalled = IsPluginInstalled(plugin);
|
||||
if (ImGui.RadioButton(plugin.DisplayName, _configuration.General.CombatModule == combatModule))
|
||||
{
|
||||
_configuration.General.CombatModule = combatModule;
|
||||
_pluginInterface.SavePluginConfig(_configuration);
|
||||
}
|
||||
|
||||
ImGui.SameLine(0);
|
||||
using (_pluginInterface.UiBuilder.IconFontFixedWidthHandle.Push())
|
||||
{
|
||||
var iconColor = isInstalled ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed;
|
||||
var icon = isInstalled ? FontAwesomeIcon.Check : FontAwesomeIcon.Times;
|
||||
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextColored(iconColor, icon.ToIconString());
|
||||
}
|
||||
|
||||
|
||||
DrawPluginDetails(plugin, checklistPadding, isInstalled);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawPluginDetails(PluginInfo plugin, float checklistPadding, bool isInstalled)
|
||||
{
|
||||
using (ImRaii.PushIndent(checklistPadding))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(plugin.Details))
|
||||
ImGui.TextUnformatted(plugin.Details);
|
||||
|
||||
if (plugin.DetailsToCheck != null)
|
||||
{
|
||||
foreach (var detail in plugin.DetailsToCheck)
|
||||
@ -196,9 +265,6 @@ internal sealed class OneTimeSetupWindow : LWindow
|
||||
}
|
||||
}
|
||||
|
||||
return isInstalled;
|
||||
}
|
||||
|
||||
private bool IsPluginInstalled(PluginInfo pluginInfo)
|
||||
{
|
||||
return _pluginInterface.InstalledPlugins.Any(x => x.InternalName == pluginInfo.InternalName && x.IsLoaded);
|
||||
|
@ -44,7 +44,8 @@ internal sealed class QuestWindow : LWindow, IPersistableWindowConfig
|
||||
QuickAccessButtonsComponent quickAccessButtonsComponent,
|
||||
RemainingTasksComponent remainingTasksComponent,
|
||||
IFramework framework,
|
||||
InteractionUiController interactionUiController)
|
||||
InteractionUiController interactionUiController,
|
||||
ConfigWindow configWindow)
|
||||
: base($"Questionable v{PluginVersion.ToString(2)}###Questionable",
|
||||
ImGuiWindowFlags.AlwaysAutoResize)
|
||||
{
|
||||
@ -67,7 +68,7 @@ internal sealed class QuestWindow : LWindow, IPersistableWindowConfig
|
||||
#endif
|
||||
SizeConstraints = new WindowSizeConstraints
|
||||
{
|
||||
MinimumSize = new Vector2(230, 30),
|
||||
MinimumSize = new Vector2(240, 30),
|
||||
MaximumSize = default
|
||||
};
|
||||
RespectCloseHotkey = false;
|
||||
@ -87,6 +88,20 @@ internal sealed class QuestWindow : LWindow, IPersistableWindowConfig
|
||||
};
|
||||
TitleBarButtons.Insert(0, _minimizeButton);
|
||||
|
||||
TitleBarButtons.Add(new TitleBarButton
|
||||
{
|
||||
Icon = FontAwesomeIcon.Cog,
|
||||
IconOffset = new Vector2(1.5f, 1),
|
||||
Click = _ => configWindow.IsOpen = true,
|
||||
Priority = int.MinValue,
|
||||
ShowTooltip = () =>
|
||||
{
|
||||
ImGui.BeginTooltip();
|
||||
ImGui.Text("Open Configuration");
|
||||
ImGui.EndTooltip();
|
||||
}
|
||||
});
|
||||
|
||||
_activeQuestComponent.Reload += OnReload;
|
||||
_quickAccessButtonsComponent.Reload += OnReload;
|
||||
}
|
||||
|
@ -55,8 +55,7 @@ internal sealed class UiUtils
|
||||
|
||||
public bool ChecklistItem(string text, Vector4 color, FontAwesomeIcon icon, float extraPadding = 0)
|
||||
{
|
||||
// ReSharper disable once UnusedVariable
|
||||
using (var font = _pluginInterface.UiBuilder.IconFontFixedWidthHandle.Push())
|
||||
using (_pluginInterface.UiBuilder.IconFontFixedWidthHandle.Push())
|
||||
{
|
||||
ImGui.TextColored(color, icon.ToIconString());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user