Add notification settings for when manual interactions are required
This commit is contained in:
parent
eb81c74930
commit
f42540bd66
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -4,3 +4,6 @@
|
|||||||
[submodule "vendor/ECommons"]
|
[submodule "vendor/ECommons"]
|
||||||
path = vendor/ECommons
|
path = vendor/ECommons
|
||||||
url = https://github.com/NightmareXIV/ECommons.git
|
url = https://github.com/NightmareXIV/ECommons.git
|
||||||
|
[submodule "vendor/NotificationMasterAPI"]
|
||||||
|
path = vendor/NotificationMasterAPI
|
||||||
|
url = https://github.com/NightmareXIV/NotificationMasterAPI.git
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>3.12</Version>
|
<Version>3.13</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -26,6 +26,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||||||
Directory.Build.targets = Directory.Build.targets
|
Directory.Build.targets = Directory.Build.targets
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "vendor", "vendor", "{8F5EC9D5-4CE7-433B-BB3A-782500E84DDB}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NotificationMasterAPI", "vendor\NotificationMasterAPI\NotificationMasterAPI\NotificationMasterAPI.csproj", "{9BD494ED-22F2-487B-BCE1-435399A8720E}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|x64 = Debug|x64
|
Debug|x64 = Debug|x64
|
||||||
@ -68,8 +72,16 @@ Global
|
|||||||
{A12D7B4B-8E6E-4DCF-A41A-12F62E9FF94B}.Debug|x64.Build.0 = Debug|x64
|
{A12D7B4B-8E6E-4DCF-A41A-12F62E9FF94B}.Debug|x64.Build.0 = Debug|x64
|
||||||
{A12D7B4B-8E6E-4DCF-A41A-12F62E9FF94B}.Release|x64.ActiveCfg = Release|x64
|
{A12D7B4B-8E6E-4DCF-A41A-12F62E9FF94B}.Release|x64.ActiveCfg = Release|x64
|
||||||
{A12D7B4B-8E6E-4DCF-A41A-12F62E9FF94B}.Release|x64.Build.0 = Release|x64
|
{A12D7B4B-8E6E-4DCF-A41A-12F62E9FF94B}.Release|x64.Build.0 = Release|x64
|
||||||
|
{9BD494ED-22F2-487B-BCE1-435399A8720E}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{9BD494ED-22F2-487B-BCE1-435399A8720E}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{9BD494ED-22F2-487B-BCE1-435399A8720E}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{9BD494ED-22F2-487B-BCE1-435399A8720E}.Release|x64.Build.0 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
GlobalSection(NestedProjects) = preSolution
|
||||||
|
{A12D7B4B-8E6E-4DCF-A41A-12F62E9FF94B} = {8F5EC9D5-4CE7-433B-BB3A-782500E84DDB}
|
||||||
|
{9BD494ED-22F2-487B-BCE1-435399A8720E} = {8F5EC9D5-4CE7-433B-BB3A-782500E84DDB}
|
||||||
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Dalamud.Configuration;
|
using Dalamud.Configuration;
|
||||||
|
using Dalamud.Game.Text;
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||||
using LLib.ImGui;
|
using LLib.ImGui;
|
||||||
|
|
||||||
@ -8,9 +9,10 @@ internal sealed class Configuration : IPluginConfiguration
|
|||||||
{
|
{
|
||||||
public const int PluginSetupVersion = 1;
|
public const int PluginSetupVersion = 1;
|
||||||
|
|
||||||
public int Version { get; set; } = 1;
|
public int Version { get; set; } =1 ;
|
||||||
public int PluginSetupCompleteVersion { get; set; }
|
public int PluginSetupCompleteVersion { get; set; }
|
||||||
public GeneralConfiguration General { get; } = new();
|
public GeneralConfiguration General { get; } = new();
|
||||||
|
public NotificationConfiguration Notifications { get; } = new();
|
||||||
public AdvancedConfiguration Advanced { get; } = new();
|
public AdvancedConfiguration Advanced { get; } = new();
|
||||||
public WindowConfig DebugWindowConfig { get; } = new();
|
public WindowConfig DebugWindowConfig { get; } = new();
|
||||||
public WindowConfig ConfigWindowConfig { get; } = new();
|
public WindowConfig ConfigWindowConfig { get; } = new();
|
||||||
@ -30,6 +32,14 @@ internal sealed class Configuration : IPluginConfiguration
|
|||||||
public bool ConfigureTextAdvance { get; set; } = true;
|
public bool ConfigureTextAdvance { get; set; } = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal sealed class NotificationConfiguration
|
||||||
|
{
|
||||||
|
public bool Enabled { get; set; } = true;
|
||||||
|
public XivChatType ChatType { get; set; } = XivChatType.Debug;
|
||||||
|
public bool ShowTrayMessage { get; set; }
|
||||||
|
public bool FlashTaskbar { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
internal sealed class AdvancedConfiguration
|
internal sealed class AdvancedConfiguration
|
||||||
{
|
{
|
||||||
public bool DebugOverlay { get; set; }
|
public bool DebugOverlay { get; set; }
|
||||||
|
84
Questionable/Controller/Steps/Common/SendNotification.cs
Normal file
84
Questionable/Controller/Steps/Common/SendNotification.cs
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
using Dalamud.Game.Text;
|
||||||
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
|
using Dalamud.Plugin.Services;
|
||||||
|
using Questionable.External;
|
||||||
|
using Questionable.Model.Questing;
|
||||||
|
|
||||||
|
namespace Questionable.Controller.Steps.Common;
|
||||||
|
|
||||||
|
internal static class SendNotification
|
||||||
|
{
|
||||||
|
internal sealed record Task(EInteractionType InteractionType, string? Comment) : ITask
|
||||||
|
{
|
||||||
|
public override string ToString() => "SendNotification";
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed class Executor(
|
||||||
|
NotificationMasterIpc notificationMasterIpc,
|
||||||
|
IChatGui chatGui,
|
||||||
|
Configuration configuration) : TaskExecutor<Task>
|
||||||
|
{
|
||||||
|
protected override bool Start()
|
||||||
|
{
|
||||||
|
if (!configuration.Notifications.Enabled)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
string text = Task.InteractionType switch
|
||||||
|
{
|
||||||
|
EInteractionType.Duty => "Duty",
|
||||||
|
EInteractionType.SinglePlayerDuty => "Single player duty",
|
||||||
|
EInteractionType.Instruction or EInteractionType.WaitForManualProgress or EInteractionType.Snipe =>
|
||||||
|
"Manual interaction required",
|
||||||
|
_ => $"{Task.InteractionType}",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(Task.Comment))
|
||||||
|
text += $" - {Task.Comment}";
|
||||||
|
|
||||||
|
if (configuration.Notifications.ChatType != XivChatType.None)
|
||||||
|
{
|
||||||
|
var message = configuration.Notifications.ChatType switch
|
||||||
|
{
|
||||||
|
XivChatType.Say
|
||||||
|
or XivChatType.Shout
|
||||||
|
or XivChatType.TellOutgoing
|
||||||
|
or XivChatType.TellIncoming
|
||||||
|
or XivChatType.Party
|
||||||
|
or XivChatType.Alliance
|
||||||
|
or (>= XivChatType.Ls1 and <= XivChatType.Ls8)
|
||||||
|
or XivChatType.FreeCompany
|
||||||
|
or XivChatType.NoviceNetwork
|
||||||
|
or XivChatType.Yell
|
||||||
|
or XivChatType.CrossParty
|
||||||
|
or XivChatType.PvPTeam
|
||||||
|
or XivChatType.CrossLinkShell1
|
||||||
|
or XivChatType.NPCDialogue
|
||||||
|
or XivChatType.NPCDialogueAnnouncements
|
||||||
|
or (>= XivChatType.CrossLinkShell2 and <= XivChatType.CrossLinkShell8)
|
||||||
|
=> new XivChatEntry
|
||||||
|
{
|
||||||
|
Message = text,
|
||||||
|
Type = configuration.Notifications.ChatType,
|
||||||
|
Name = new SeStringBuilder()
|
||||||
|
.AddUiForeground(CommandHandler.MessageTag, CommandHandler.TagColor)
|
||||||
|
.Build(),
|
||||||
|
},
|
||||||
|
_ => new XivChatEntry
|
||||||
|
{
|
||||||
|
Message = new SeStringBuilder()
|
||||||
|
.AddUiForeground($"[{CommandHandler.MessageTag}] ", CommandHandler.TagColor)
|
||||||
|
.Append(text)
|
||||||
|
.Build(),
|
||||||
|
Type = configuration.Notifications.ChatType,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
chatGui.Print(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
notificationMasterIpc.Notify(text);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ETaskResult Update() => ETaskResult.TaskComplete;
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@ using System.Numerics;
|
|||||||
using Dalamud.Game.ClientState.Conditions;
|
using Dalamud.Game.ClientState.Conditions;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using Questionable.Controller.Steps.Common;
|
using Questionable.Controller.Steps.Common;
|
||||||
|
using Questionable.Controller.Steps.Interactions;
|
||||||
using Questionable.Controller.Utils;
|
using Questionable.Controller.Utils;
|
||||||
using Questionable.Data;
|
using Questionable.Data;
|
||||||
using Questionable.Functions;
|
using Questionable.Functions;
|
||||||
@ -19,7 +20,8 @@ internal static class WaitAtEnd
|
|||||||
internal sealed class Factory(
|
internal sealed class Factory(
|
||||||
IClientState clientState,
|
IClientState clientState,
|
||||||
ICondition condition,
|
ICondition condition,
|
||||||
TerritoryData territoryData)
|
TerritoryData territoryData,
|
||||||
|
Configuration configuration)
|
||||||
: ITaskFactory
|
: ITaskFactory
|
||||||
{
|
{
|
||||||
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
|
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
|
||||||
@ -47,12 +49,28 @@ internal static class WaitAtEnd
|
|||||||
|
|
||||||
case EInteractionType.WaitForManualProgress:
|
case EInteractionType.WaitForManualProgress:
|
||||||
case EInteractionType.Instruction:
|
case EInteractionType.Instruction:
|
||||||
case EInteractionType.Snipe:
|
|
||||||
return [new WaitNextStepOrSequence()];
|
return [new WaitNextStepOrSequence()];
|
||||||
|
|
||||||
|
case EInteractionType.Snipe:
|
||||||
|
if (configuration.General.AutomaticallyCompleteSnipeTasks)
|
||||||
|
return [new WaitNextStepOrSequence()];
|
||||||
|
else
|
||||||
|
return [
|
||||||
|
new SendNotification.Task(step.InteractionType, step.Comment),
|
||||||
|
new WaitNextStepOrSequence()
|
||||||
|
];
|
||||||
|
|
||||||
case EInteractionType.Duty:
|
case EInteractionType.Duty:
|
||||||
|
return [
|
||||||
|
new SendNotification.Task(step.InteractionType, step.ContentFinderConditionId.HasValue ? territoryData.GetContentFinderConditionName(step.ContentFinderConditionId.Value) : step.Comment),
|
||||||
|
new EndAutomation(),
|
||||||
|
];
|
||||||
|
|
||||||
case EInteractionType.SinglePlayerDuty:
|
case EInteractionType.SinglePlayerDuty:
|
||||||
return [new EndAutomation()];
|
return [
|
||||||
|
new SendNotification.Task(step.InteractionType, quest.Info.Name),
|
||||||
|
new EndAutomation()
|
||||||
|
];
|
||||||
|
|
||||||
case EInteractionType.WalkTo:
|
case EInteractionType.WalkTo:
|
||||||
case EInteractionType.Jump:
|
case EInteractionType.Jump:
|
||||||
|
@ -14,6 +14,7 @@ internal sealed class TerritoryData
|
|||||||
private readonly ImmutableHashSet<ushort> _territoriesWithMount;
|
private readonly ImmutableHashSet<ushort> _territoriesWithMount;
|
||||||
private readonly ImmutableDictionary<ushort, uint> _dutyTerritories;
|
private readonly ImmutableDictionary<ushort, uint> _dutyTerritories;
|
||||||
private readonly ImmutableDictionary<ushort, string> _instanceNames;
|
private readonly ImmutableDictionary<ushort, string> _instanceNames;
|
||||||
|
private readonly ImmutableDictionary<uint, string> _contentFinderConditionNames;
|
||||||
|
|
||||||
public TerritoryData(IDataManager dataManager)
|
public TerritoryData(IDataManager dataManager)
|
||||||
{
|
{
|
||||||
@ -40,6 +41,10 @@ internal sealed class TerritoryData
|
|||||||
_instanceNames = dataManager.GetExcelSheet<ContentFinderCondition>()!
|
_instanceNames = dataManager.GetExcelSheet<ContentFinderCondition>()!
|
||||||
.Where(x => x.RowId > 0 && x.Content != 0 && x.ContentLinkType == 1 && x.ContentType.Row != 6)
|
.Where(x => x.RowId > 0 && x.Content != 0 && x.ContentLinkType == 1 && x.ContentType.Row != 6)
|
||||||
.ToImmutableDictionary(x => x.Content, x => x.Name.ToString());
|
.ToImmutableDictionary(x => x.Content, x => x.Name.ToString());
|
||||||
|
|
||||||
|
_contentFinderConditionNames = dataManager.GetExcelSheet<ContentFinderCondition>()!
|
||||||
|
.Where(x => x.RowId > 0 && x.Content != 0 && x.ContentLinkType == 1 && x.ContentType.Row != 6)
|
||||||
|
.ToImmutableDictionary(x => x.RowId, x => x.Name.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public string? GetName(ushort territoryId) => _territoryNames.GetValueOrDefault(territoryId);
|
public string? GetName(ushort territoryId) => _territoryNames.GetValueOrDefault(territoryId);
|
||||||
@ -61,4 +66,6 @@ internal sealed class TerritoryData
|
|||||||
_dutyTerritories.TryGetValue(territoryId, out uint contentType) && contentType == 7;
|
_dutyTerritories.TryGetValue(territoryId, out uint contentType) && contentType == 7;
|
||||||
|
|
||||||
public string? GetInstanceName(ushort instanceId) => _instanceNames.GetValueOrDefault(instanceId);
|
public string? GetInstanceName(ushort instanceId) => _instanceNames.GetValueOrDefault(instanceId);
|
||||||
|
|
||||||
|
public string? GetContentFinderConditionName(uint cfcId) => _contentFinderConditionNames.GetValueOrDefault(cfcId);
|
||||||
}
|
}
|
||||||
|
24
Questionable/External/NotificationMasterIpc.cs
vendored
Normal file
24
Questionable/External/NotificationMasterIpc.cs
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using Dalamud.Plugin;
|
||||||
|
using NotificationMasterAPI;
|
||||||
|
|
||||||
|
namespace Questionable.External;
|
||||||
|
|
||||||
|
internal sealed class NotificationMasterIpc(IDalamudPluginInterface pluginInterface, Configuration configuration)
|
||||||
|
{
|
||||||
|
private readonly NotificationMasterApi _api = new(pluginInterface);
|
||||||
|
|
||||||
|
public bool Enabled => _api.IsIPCReady();
|
||||||
|
|
||||||
|
public void Notify(string message)
|
||||||
|
{
|
||||||
|
var config = configuration.Notifications;
|
||||||
|
if (!config.Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (config.ShowTrayMessage)
|
||||||
|
_api.DisplayTrayNotification("Questionable", message);
|
||||||
|
|
||||||
|
if (config.FlashTaskbar)
|
||||||
|
_api.FlashTaskbarIcon();
|
||||||
|
}
|
||||||
|
}
|
@ -21,5 +21,6 @@
|
|||||||
<ProjectReference Include="..\LLib\LLib.csproj"/>
|
<ProjectReference Include="..\LLib\LLib.csproj"/>
|
||||||
<ProjectReference Include="..\Questionable.Model\Questionable.Model.csproj"/>
|
<ProjectReference Include="..\Questionable.Model\Questionable.Model.csproj"/>
|
||||||
<ProjectReference Include="..\QuestPaths\QuestPaths.csproj"/>
|
<ProjectReference Include="..\QuestPaths\QuestPaths.csproj"/>
|
||||||
|
<ProjectReference Include="..\vendor\NotificationMasterAPI\NotificationMasterAPI\NotificationMasterAPI.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -127,6 +127,7 @@ public sealed class QuestionablePlugin : IDalamudPlugin
|
|||||||
serviceCollection.AddSingleton<ArtisanIpc>();
|
serviceCollection.AddSingleton<ArtisanIpc>();
|
||||||
serviceCollection.AddSingleton<QuestionableIpc>();
|
serviceCollection.AddSingleton<QuestionableIpc>();
|
||||||
serviceCollection.AddSingleton<TextAdvanceIpc>();
|
serviceCollection.AddSingleton<TextAdvanceIpc>();
|
||||||
|
serviceCollection.AddSingleton<NotificationMasterIpc>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddTaskFactories(ServiceCollection serviceCollection)
|
private static void AddTaskFactories(ServiceCollection serviceCollection)
|
||||||
@ -205,6 +206,7 @@ public sealed class QuestionablePlugin : IDalamudPlugin
|
|||||||
serviceCollection.AddTaskExecutor<InitiateLeve.Initiate, InitiateLeve.InitiateExecutor>();
|
serviceCollection.AddTaskExecutor<InitiateLeve.Initiate, InitiateLeve.InitiateExecutor>();
|
||||||
serviceCollection.AddTaskExecutor<InitiateLeve.SelectDifficulty, InitiateLeve.SelectDifficultyExecutor>();
|
serviceCollection.AddTaskExecutor<InitiateLeve.SelectDifficulty, InitiateLeve.SelectDifficultyExecutor>();
|
||||||
|
|
||||||
|
serviceCollection.AddTaskExecutor<SendNotification.Task, SendNotification.Executor>();
|
||||||
serviceCollection.AddTaskExecutor<WaitCondition.Task, WaitCondition.WaitConditionExecutor>();
|
serviceCollection.AddTaskExecutor<WaitCondition.Task, WaitCondition.WaitConditionExecutor>();
|
||||||
serviceCollection.AddTaskFactory<WaitAtEnd.Factory>();
|
serviceCollection.AddTaskFactory<WaitAtEnd.Factory>();
|
||||||
serviceCollection.AddTaskExecutor<WaitAtEnd.WaitDelay, WaitAtEnd.WaitDelayExecutor>();
|
serviceCollection.AddTaskExecutor<WaitAtEnd.WaitDelay, WaitAtEnd.WaitDelayExecutor>();
|
||||||
|
@ -1,12 +1,17 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Dalamud.Game.Text;
|
||||||
using Dalamud.Interface.Colors;
|
using Dalamud.Interface.Colors;
|
||||||
|
using Dalamud.Interface.Components;
|
||||||
|
using Dalamud.Interface.Utility.Raii;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
|
using Dalamud.Utility;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using LLib.ImGui;
|
using LLib.ImGui;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.GeneratedSheets;
|
||||||
|
using Questionable.External;
|
||||||
using GrandCompany = FFXIVClientStructs.FFXIV.Client.UI.Agent.GrandCompany;
|
using GrandCompany = FFXIVClientStructs.FFXIV.Client.UI.Agent.GrandCompany;
|
||||||
|
|
||||||
namespace Questionable.Windows;
|
namespace Questionable.Windows;
|
||||||
@ -14,6 +19,7 @@ namespace Questionable.Windows;
|
|||||||
internal sealed class ConfigWindow : LWindow, IPersistableWindowConfig
|
internal sealed class ConfigWindow : LWindow, IPersistableWindowConfig
|
||||||
{
|
{
|
||||||
private readonly IDalamudPluginInterface _pluginInterface;
|
private readonly IDalamudPluginInterface _pluginInterface;
|
||||||
|
private readonly NotificationMasterIpc _notificationMasterIpc;
|
||||||
private readonly Configuration _configuration;
|
private readonly Configuration _configuration;
|
||||||
|
|
||||||
private readonly uint[] _mountIds;
|
private readonly uint[] _mountIds;
|
||||||
@ -23,10 +29,11 @@ internal sealed class ConfigWindow : LWindow, IPersistableWindowConfig
|
|||||||
["None (manually pick quest)", "Maelstrom", "Twin Adder", "Immortal Flames"];
|
["None (manually pick quest)", "Maelstrom", "Twin Adder", "Immortal Flames"];
|
||||||
|
|
||||||
[SuppressMessage("Performance", "CA1861", Justification = "One time initialization")]
|
[SuppressMessage("Performance", "CA1861", Justification = "One time initialization")]
|
||||||
public ConfigWindow(IDalamudPluginInterface pluginInterface, Configuration configuration, IDataManager dataManager)
|
public ConfigWindow(IDalamudPluginInterface pluginInterface, NotificationMasterIpc notificationMasterIpc, Configuration configuration, IDataManager dataManager)
|
||||||
: base("Config - Questionable###QuestionableConfig", ImGuiWindowFlags.AlwaysAutoResize)
|
: base("Config - Questionable###QuestionableConfig", ImGuiWindowFlags.AlwaysAutoResize)
|
||||||
{
|
{
|
||||||
_pluginInterface = pluginInterface;
|
_pluginInterface = pluginInterface;
|
||||||
|
_notificationMasterIpc = notificationMasterIpc;
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
|
|
||||||
var mounts = dataManager.GetExcelSheet<Mount>()!
|
var mounts = dataManager.GetExcelSheet<Mount>()!
|
||||||
@ -43,109 +50,174 @@ internal sealed class ConfigWindow : LWindow, IPersistableWindowConfig
|
|||||||
|
|
||||||
public override void Draw()
|
public override void Draw()
|
||||||
{
|
{
|
||||||
if (ImGui.BeginTabBar("QuestionableConfigTabs"))
|
using var tabBar = ImRaii.TabBar("QuestionableConfigTabs");
|
||||||
|
if (!tabBar)
|
||||||
|
return;
|
||||||
|
|
||||||
|
DrawGeneralTab();
|
||||||
|
DrawNotificationsTab();
|
||||||
|
DrawAdvancedTab();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawGeneralTab()
|
||||||
|
{
|
||||||
|
using var tab = ImRaii.TabItem("General");
|
||||||
|
if (!tab)
|
||||||
|
return;
|
||||||
|
int selectedMount = Array.FindIndex(_mountIds, x => x == _configuration.General.MountId);
|
||||||
|
if (selectedMount == -1)
|
||||||
{
|
{
|
||||||
if (ImGui.BeginTabItem("General"))
|
selectedMount = 0;
|
||||||
|
_configuration.General.MountId = _mountIds[selectedMount];
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.Combo("Preferred Mount", ref selectedMount, _mountNames, _mountNames.Length))
|
||||||
|
{
|
||||||
|
_configuration.General.MountId = _mountIds[selectedMount];
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
int grandCompany = (int)_configuration.General.GrandCompany;
|
||||||
|
if (ImGui.Combo("Preferred Grand Company", ref grandCompany, _grandCompanyNames,
|
||||||
|
_grandCompanyNames.Length))
|
||||||
|
{
|
||||||
|
_configuration.General.GrandCompany = (GrandCompany)grandCompany;
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hideInAllInstances = _configuration.General.HideInAllInstances;
|
||||||
|
if (ImGui.Checkbox("Hide quest window in all instanced duties", ref hideInAllInstances))
|
||||||
|
{
|
||||||
|
_configuration.General.HideInAllInstances = hideInAllInstances;
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool useEscToCancelQuesting = _configuration.General.UseEscToCancelQuesting;
|
||||||
|
if (ImGui.Checkbox("Use ESC to cancel questing/movement", ref useEscToCancelQuesting))
|
||||||
|
{
|
||||||
|
_configuration.General.UseEscToCancelQuesting = useEscToCancelQuesting;
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool showIncompleteSeasonalEvents = _configuration.General.ShowIncompleteSeasonalEvents;
|
||||||
|
if (ImGui.Checkbox("Show details for incomplete seasonal events", ref showIncompleteSeasonalEvents))
|
||||||
|
{
|
||||||
|
_configuration.General.ShowIncompleteSeasonalEvents = showIncompleteSeasonalEvents;
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool configureTextAdvance = _configuration.General.ConfigureTextAdvance;
|
||||||
|
if (ImGui.Checkbox("Automatically configure TextAdvance with the recommended settings",
|
||||||
|
ref configureTextAdvance))
|
||||||
|
{
|
||||||
|
_configuration.General.ConfigureTextAdvance = configureTextAdvance;
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.CollapsingHeader("Cheats"))
|
||||||
|
{
|
||||||
|
ImGui.TextColored(ImGuiColors.DalamudRed,
|
||||||
|
"This setting will be removed in a future version, and will be\navailable through TextAdvance instead.");
|
||||||
|
bool automaticallyCompleteSnipeTasks = _configuration.General.AutomaticallyCompleteSnipeTasks;
|
||||||
|
if (ImGui.Checkbox("Automatically complete snipe tasks", ref automaticallyCompleteSnipeTasks))
|
||||||
{
|
{
|
||||||
int selectedMount = Array.FindIndex(_mountIds, x => x == _configuration.General.MountId);
|
_configuration.General.AutomaticallyCompleteSnipeTasks = automaticallyCompleteSnipeTasks;
|
||||||
if (selectedMount == -1)
|
Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawNotificationsTab()
|
||||||
|
{
|
||||||
|
using var tab = ImRaii.TabItem("Notifications");
|
||||||
|
if (!tab)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool enabled = _configuration.Notifications.Enabled;
|
||||||
|
if (ImGui.Checkbox("Enable notifications when manual interaction is required", ref enabled))
|
||||||
|
{
|
||||||
|
_configuration.Notifications.Enabled = enabled;
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
using (ImRaii.Disabled(!_configuration.Notifications.Enabled))
|
||||||
|
{
|
||||||
|
using (ImRaii.PushIndent())
|
||||||
|
{
|
||||||
|
var xivChatTypes = Enum.GetValues<XivChatType>()
|
||||||
|
.Where(x => x != XivChatType.StandardEmote)
|
||||||
|
.ToArray();
|
||||||
|
var selectedChatType = Array.IndexOf(xivChatTypes, _configuration.Notifications.ChatType);
|
||||||
|
string[] chatTypeNames = xivChatTypes
|
||||||
|
.Select(t => t.GetAttribute<XivChatTypeInfoAttribute>()?.FancyName ?? t.ToString())
|
||||||
|
.ToArray();
|
||||||
|
if (ImGui.Combo("Chat channel", ref selectedChatType, chatTypeNames,
|
||||||
|
chatTypeNames.Length))
|
||||||
{
|
{
|
||||||
selectedMount = 0;
|
_configuration.Notifications.ChatType = xivChatTypes[selectedChatType];
|
||||||
_configuration.General.MountId = _mountIds[selectedMount];
|
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui.Combo("Preferred Mount", ref selectedMount, _mountNames, _mountNames.Length))
|
ImGui.Separator();
|
||||||
|
ImGui.Text("NotificationMaster settings");
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGuiComponents.HelpMarker("Requires the plugin 'NotificationMaster' to be installed.");
|
||||||
|
using (ImRaii.Disabled(!_notificationMasterIpc.Enabled))
|
||||||
{
|
{
|
||||||
_configuration.General.MountId = _mountIds[selectedMount];
|
bool showTrayMessage = _configuration.Notifications.ShowTrayMessage;
|
||||||
Save();
|
if (ImGui.Checkbox("Show tray notification", ref showTrayMessage))
|
||||||
}
|
|
||||||
|
|
||||||
int grandCompany = (int)_configuration.General.GrandCompany;
|
|
||||||
if (ImGui.Combo("Preferred Grand Company", ref grandCompany, _grandCompanyNames,
|
|
||||||
_grandCompanyNames.Length))
|
|
||||||
{
|
|
||||||
_configuration.General.GrandCompany = (GrandCompany)grandCompany;
|
|
||||||
Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hideInAllInstances = _configuration.General.HideInAllInstances;
|
|
||||||
if (ImGui.Checkbox("Hide quest window in all instanced duties", ref hideInAllInstances))
|
|
||||||
{
|
|
||||||
_configuration.General.HideInAllInstances = hideInAllInstances;
|
|
||||||
Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool useEscToCancelQuesting = _configuration.General.UseEscToCancelQuesting;
|
|
||||||
if (ImGui.Checkbox("Use ESC to cancel questing/movement", ref useEscToCancelQuesting))
|
|
||||||
{
|
|
||||||
_configuration.General.UseEscToCancelQuesting = useEscToCancelQuesting;
|
|
||||||
Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool showIncompleteSeasonalEvents = _configuration.General.ShowIncompleteSeasonalEvents;
|
|
||||||
if (ImGui.Checkbox("Show details for incomplete seasonal events", ref showIncompleteSeasonalEvents))
|
|
||||||
{
|
|
||||||
_configuration.General.ShowIncompleteSeasonalEvents = showIncompleteSeasonalEvents;
|
|
||||||
Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool configureTextAdvance = _configuration.General.ConfigureTextAdvance;
|
|
||||||
if (ImGui.Checkbox("Automatically configure TextAdvance with the recommended settings", ref configureTextAdvance))
|
|
||||||
{
|
|
||||||
_configuration.General.ConfigureTextAdvance = configureTextAdvance;
|
|
||||||
Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui.CollapsingHeader("Cheats"))
|
|
||||||
{
|
|
||||||
ImGui.TextColored(ImGuiColors.DalamudRed, "This setting will be removed in a future version, and will be\navailable through TextAdvance instead.");
|
|
||||||
bool automaticallyCompleteSnipeTasks = _configuration.General.AutomaticallyCompleteSnipeTasks;
|
|
||||||
if (ImGui.Checkbox("Automatically complete snipe tasks", ref automaticallyCompleteSnipeTasks))
|
|
||||||
{
|
{
|
||||||
_configuration.General.AutomaticallyCompleteSnipeTasks = automaticallyCompleteSnipeTasks;
|
_configuration.Notifications.ShowTrayMessage = showTrayMessage;
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool flashTaskbar = _configuration.Notifications.FlashTaskbar;
|
||||||
|
if (ImGui.Checkbox("Flash taskbar icon", ref flashTaskbar))
|
||||||
|
{
|
||||||
|
_configuration.Notifications.FlashTaskbar = flashTaskbar;
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.EndTabItem();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui.BeginTabItem("Advanced"))
|
|
||||||
{
|
|
||||||
ImGui.TextColored(ImGuiColors.DalamudRed,
|
|
||||||
"Enabling any option here may cause unexpected behavior. Use at your own risk.");
|
|
||||||
|
|
||||||
ImGui.Separator();
|
|
||||||
|
|
||||||
bool debugOverlay = _configuration.Advanced.DebugOverlay;
|
|
||||||
if (ImGui.Checkbox("Enable debug overlay", ref debugOverlay))
|
|
||||||
{
|
|
||||||
_configuration.Advanced.DebugOverlay = debugOverlay;
|
|
||||||
Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool neverFly = _configuration.Advanced.NeverFly;
|
|
||||||
if (ImGui.Checkbox("Disable flying (even if unlocked for the zone)", ref neverFly))
|
|
||||||
{
|
|
||||||
_configuration.Advanced.NeverFly = neverFly;
|
|
||||||
Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool additionalStatusInformation = _configuration.Advanced.AdditionalStatusInformation;
|
|
||||||
if (ImGui.Checkbox("Draw additional status information", ref additionalStatusInformation))
|
|
||||||
{
|
|
||||||
_configuration.Advanced.AdditionalStatusInformation = additionalStatusInformation;
|
|
||||||
Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndTabItem();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndTabBar();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DrawAdvancedTab()
|
||||||
|
{
|
||||||
|
using var tab = ImRaii.TabItem("Advanced");
|
||||||
|
if (!tab)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ImGui.TextColored(ImGuiColors.DalamudRed,
|
||||||
|
"Enabling any option here may cause unexpected behavior. Use at your own risk.");
|
||||||
|
|
||||||
|
ImGui.Separator();
|
||||||
|
|
||||||
|
bool debugOverlay = _configuration.Advanced.DebugOverlay;
|
||||||
|
if (ImGui.Checkbox("Enable debug overlay", ref debugOverlay))
|
||||||
|
{
|
||||||
|
_configuration.Advanced.DebugOverlay = debugOverlay;
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool neverFly = _configuration.Advanced.NeverFly;
|
||||||
|
if (ImGui.Checkbox("Disable flying (even if unlocked for the zone)", ref neverFly))
|
||||||
|
{
|
||||||
|
_configuration.Advanced.NeverFly = neverFly;
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool additionalStatusInformation = _configuration.Advanced.AdditionalStatusInformation;
|
||||||
|
if (ImGui.Checkbox("Draw additional status information", ref additionalStatusInformation))
|
||||||
|
{
|
||||||
|
_configuration.Advanced.AdditionalStatusInformation = additionalStatusInformation;
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndTabItem();
|
||||||
|
}
|
||||||
|
|
||||||
private void Save() => _pluginInterface.SavePluginConfig(_configuration);
|
private void Save() => _pluginInterface.SavePluginConfig(_configuration);
|
||||||
|
|
||||||
public void SaveWindowConfig() => Save();
|
public void SaveWindowConfig() => Save();
|
||||||
|
@ -44,6 +44,12 @@ internal sealed class OneTimeSetupWindow : LWindow, IDisposable
|
|||||||
during quests, including being interrupted by mobs.
|
during quests, including being interrupted by mobs.
|
||||||
""",
|
""",
|
||||||
new Uri("https://github.com/FFXIV-CombatReborn/RotationSolverReborn")),
|
new Uri("https://github.com/FFXIV-CombatReborn/RotationSolverReborn")),
|
||||||
|
new("NotificationMaster",
|
||||||
|
"""
|
||||||
|
Sends a configurable out-of-game notification if a quest
|
||||||
|
requires manual actions.
|
||||||
|
""",
|
||||||
|
new Uri("https://github.com/NightmareXIV/NotificationMaster")),
|
||||||
];
|
];
|
||||||
|
|
||||||
private readonly Configuration _configuration;
|
private readonly Configuration _configuration;
|
||||||
@ -109,6 +115,7 @@ internal sealed class OneTimeSetupWindow : LWindow, IDisposable
|
|||||||
{
|
{
|
||||||
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Check, "Finish Setup"))
|
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Check, "Finish Setup"))
|
||||||
{
|
{
|
||||||
|
_logger.LogInformation("Marking setup as complete");
|
||||||
_configuration.MarkPluginSetupComplete();
|
_configuration.MarkPluginSetupComplete();
|
||||||
_pluginInterface.SavePluginConfig(_configuration);
|
_pluginInterface.SavePluginConfig(_configuration);
|
||||||
IsOpen = false;
|
IsOpen = false;
|
||||||
@ -128,6 +135,7 @@ internal sealed class OneTimeSetupWindow : LWindow, IDisposable
|
|||||||
|
|
||||||
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Times, "Close window & don't enable Questionable"))
|
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Times, "Close window & don't enable Questionable"))
|
||||||
{
|
{
|
||||||
|
_logger.LogWarning("Closing window without all required plugins installed");
|
||||||
IsOpen = false;
|
IsOpen = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,7 @@
|
|||||||
"gatheringpaths": {
|
"gatheringpaths": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Questionable.Model": "[3.10.0, )"
|
"Questionable.Model": "[3.12.0, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"llib": {
|
"llib": {
|
||||||
@ -183,6 +183,9 @@
|
|||||||
"DalamudPackager": "[2.1.13, )"
|
"DalamudPackager": "[2.1.13, )"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"notificationmasterapi": {
|
||||||
|
"type": "Project"
|
||||||
|
},
|
||||||
"questionable.model": {
|
"questionable.model": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -192,7 +195,7 @@
|
|||||||
"questpaths": {
|
"questpaths": {
|
||||||
"type": "Project",
|
"type": "Project",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Questionable.Model": "[3.10.0, )"
|
"Questionable.Model": "[3.12.0, )"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1
vendor/NotificationMasterAPI
vendored
Submodule
1
vendor/NotificationMasterAPI
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 05b1ba788d5cb940ed8e82599eb88778c9cecdb0
|
Loading…
Reference in New Issue
Block a user