diff --git a/.gitmodules b/.gitmodules index 0bc08a36..832da345 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "vendor/ECommons"] path = vendor/ECommons url = https://github.com/NightmareXIV/ECommons.git +[submodule "vendor/NotificationMasterAPI"] + path = vendor/NotificationMasterAPI + url = https://github.com/NightmareXIV/NotificationMasterAPI.git diff --git a/Directory.Build.targets b/Directory.Build.targets index 9b59f0ef..1d114280 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -1,5 +1,5 @@ - 3.12 + 3.13 diff --git a/Questionable.sln b/Questionable.sln index ad259b03..df898789 100644 --- a/Questionable.sln +++ b/Questionable.sln @@ -26,6 +26,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Directory.Build.targets = Directory.Build.targets EndProjectSection 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 GlobalSection(SolutionConfigurationPlatforms) = preSolution 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}.Release|x64.ActiveCfg = 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 GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE 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 diff --git a/Questionable/Configuration.cs b/Questionable/Configuration.cs index fb96ce35..238e4a51 100644 --- a/Questionable/Configuration.cs +++ b/Questionable/Configuration.cs @@ -1,4 +1,5 @@ using Dalamud.Configuration; +using Dalamud.Game.Text; using FFXIVClientStructs.FFXIV.Client.UI.Agent; using LLib.ImGui; @@ -8,9 +9,10 @@ internal sealed class Configuration : IPluginConfiguration { public const int PluginSetupVersion = 1; - 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(); public AdvancedConfiguration Advanced { get; } = new(); public WindowConfig DebugWindowConfig { get; } = new(); public WindowConfig ConfigWindowConfig { get; } = new(); @@ -30,6 +32,14 @@ internal sealed class Configuration : IPluginConfiguration 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 { public bool DebugOverlay { get; set; } diff --git a/Questionable/Controller/Steps/Common/SendNotification.cs b/Questionable/Controller/Steps/Common/SendNotification.cs new file mode 100644 index 00000000..76b8a810 --- /dev/null +++ b/Questionable/Controller/Steps/Common/SendNotification.cs @@ -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 + { + 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; + } +} diff --git a/Questionable/Controller/Steps/Shared/WaitAtEnd.cs b/Questionable/Controller/Steps/Shared/WaitAtEnd.cs index d64c009b..84d2e1ca 100644 --- a/Questionable/Controller/Steps/Shared/WaitAtEnd.cs +++ b/Questionable/Controller/Steps/Shared/WaitAtEnd.cs @@ -6,6 +6,7 @@ using System.Numerics; using Dalamud.Game.ClientState.Conditions; using Dalamud.Plugin.Services; using Questionable.Controller.Steps.Common; +using Questionable.Controller.Steps.Interactions; using Questionable.Controller.Utils; using Questionable.Data; using Questionable.Functions; @@ -19,7 +20,8 @@ internal static class WaitAtEnd internal sealed class Factory( IClientState clientState, ICondition condition, - TerritoryData territoryData) + TerritoryData territoryData, + Configuration configuration) : ITaskFactory { public IEnumerable CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step) @@ -47,12 +49,28 @@ internal static class WaitAtEnd case EInteractionType.WaitForManualProgress: case EInteractionType.Instruction: - case EInteractionType.Snipe: 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: + return [ + new SendNotification.Task(step.InteractionType, step.ContentFinderConditionId.HasValue ? territoryData.GetContentFinderConditionName(step.ContentFinderConditionId.Value) : step.Comment), + new EndAutomation(), + ]; + case EInteractionType.SinglePlayerDuty: - return [new EndAutomation()]; + return [ + new SendNotification.Task(step.InteractionType, quest.Info.Name), + new EndAutomation() + ]; case EInteractionType.WalkTo: case EInteractionType.Jump: diff --git a/Questionable/Data/TerritoryData.cs b/Questionable/Data/TerritoryData.cs index 0b20d9a9..e2d471c3 100644 --- a/Questionable/Data/TerritoryData.cs +++ b/Questionable/Data/TerritoryData.cs @@ -14,6 +14,7 @@ internal sealed class TerritoryData private readonly ImmutableHashSet _territoriesWithMount; private readonly ImmutableDictionary _dutyTerritories; private readonly ImmutableDictionary _instanceNames; + private readonly ImmutableDictionary _contentFinderConditionNames; public TerritoryData(IDataManager dataManager) { @@ -40,6 +41,10 @@ internal sealed class TerritoryData _instanceNames = dataManager.GetExcelSheet()! .Where(x => x.RowId > 0 && x.Content != 0 && x.ContentLinkType == 1 && x.ContentType.Row != 6) .ToImmutableDictionary(x => x.Content, x => x.Name.ToString()); + + _contentFinderConditionNames = dataManager.GetExcelSheet()! + .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); @@ -61,4 +66,6 @@ internal sealed class TerritoryData _dutyTerritories.TryGetValue(territoryId, out uint contentType) && contentType == 7; public string? GetInstanceName(ushort instanceId) => _instanceNames.GetValueOrDefault(instanceId); + + public string? GetContentFinderConditionName(uint cfcId) => _contentFinderConditionNames.GetValueOrDefault(cfcId); } diff --git a/Questionable/External/NotificationMasterIpc.cs b/Questionable/External/NotificationMasterIpc.cs new file mode 100644 index 00000000..7a528c6f --- /dev/null +++ b/Questionable/External/NotificationMasterIpc.cs @@ -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(); + } +} diff --git a/Questionable/Questionable.csproj b/Questionable/Questionable.csproj index 8d1a3c89..64df5619 100644 --- a/Questionable/Questionable.csproj +++ b/Questionable/Questionable.csproj @@ -21,5 +21,6 @@ + diff --git a/Questionable/QuestionablePlugin.cs b/Questionable/QuestionablePlugin.cs index 5e8dc11d..b97158c6 100644 --- a/Questionable/QuestionablePlugin.cs +++ b/Questionable/QuestionablePlugin.cs @@ -127,6 +127,7 @@ public sealed class QuestionablePlugin : IDalamudPlugin serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); + serviceCollection.AddSingleton(); } private static void AddTaskFactories(ServiceCollection serviceCollection) @@ -205,6 +206,7 @@ public sealed class QuestionablePlugin : IDalamudPlugin serviceCollection.AddTaskExecutor(); serviceCollection.AddTaskExecutor(); + serviceCollection.AddTaskExecutor(); serviceCollection.AddTaskExecutor(); serviceCollection.AddTaskFactory(); serviceCollection.AddTaskExecutor(); diff --git a/Questionable/Windows/ConfigWindow.cs b/Questionable/Windows/ConfigWindow.cs index 0416943f..7bcd7681 100644 --- a/Questionable/Windows/ConfigWindow.cs +++ b/Questionable/Windows/ConfigWindow.cs @@ -1,12 +1,17 @@ using System; using System.Diagnostics.CodeAnalysis; using System.Linq; +using Dalamud.Game.Text; using Dalamud.Interface.Colors; +using Dalamud.Interface.Components; +using Dalamud.Interface.Utility.Raii; using Dalamud.Plugin; using Dalamud.Plugin.Services; +using Dalamud.Utility; using ImGuiNET; using LLib.ImGui; using Lumina.Excel.GeneratedSheets; +using Questionable.External; using GrandCompany = FFXIVClientStructs.FFXIV.Client.UI.Agent.GrandCompany; namespace Questionable.Windows; @@ -14,6 +19,7 @@ namespace Questionable.Windows; internal sealed class ConfigWindow : LWindow, IPersistableWindowConfig { private readonly IDalamudPluginInterface _pluginInterface; + private readonly NotificationMasterIpc _notificationMasterIpc; private readonly Configuration _configuration; private readonly uint[] _mountIds; @@ -23,10 +29,11 @@ internal sealed class ConfigWindow : LWindow, IPersistableWindowConfig ["None (manually pick quest)", "Maelstrom", "Twin Adder", "Immortal Flames"]; [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) { _pluginInterface = pluginInterface; + _notificationMasterIpc = notificationMasterIpc; _configuration = configuration; var mounts = dataManager.GetExcelSheet()! @@ -43,109 +50,174 @@ internal sealed class ConfigWindow : LWindow, IPersistableWindowConfig 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); - if (selectedMount == -1) + _configuration.General.AutomaticallyCompleteSnipeTasks = automaticallyCompleteSnipeTasks; + 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() + .Where(x => x != XivChatType.StandardEmote) + .ToArray(); + var selectedChatType = Array.IndexOf(xivChatTypes, _configuration.Notifications.ChatType); + string[] chatTypeNames = xivChatTypes + .Select(t => t.GetAttribute()?.FancyName ?? t.ToString()) + .ToArray(); + if (ImGui.Combo("Chat channel", ref selectedChatType, chatTypeNames, + chatTypeNames.Length)) { - selectedMount = 0; - _configuration.General.MountId = _mountIds[selectedMount]; + _configuration.Notifications.ChatType = xivChatTypes[selectedChatType]; 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]; - 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)) + bool showTrayMessage = _configuration.Notifications.ShowTrayMessage; + if (ImGui.Checkbox("Show tray notification", ref showTrayMessage)) { - _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(); } } - - 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); public void SaveWindowConfig() => Save(); diff --git a/Questionable/Windows/OneTimeSetupWindow.cs b/Questionable/Windows/OneTimeSetupWindow.cs index 6026bafe..2ec22702 100644 --- a/Questionable/Windows/OneTimeSetupWindow.cs +++ b/Questionable/Windows/OneTimeSetupWindow.cs @@ -44,6 +44,12 @@ internal sealed class OneTimeSetupWindow : LWindow, IDisposable during quests, including being interrupted by mobs. """, 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; @@ -109,6 +115,7 @@ internal sealed class OneTimeSetupWindow : LWindow, IDisposable { if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Check, "Finish Setup")) { + _logger.LogInformation("Marking setup as complete"); _configuration.MarkPluginSetupComplete(); _pluginInterface.SavePluginConfig(_configuration); IsOpen = false; @@ -128,6 +135,7 @@ internal sealed class OneTimeSetupWindow : LWindow, IDisposable if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Times, "Close window & don't enable Questionable")) { + _logger.LogWarning("Closing window without all required plugins installed"); IsOpen = false; } } diff --git a/Questionable/packages.lock.json b/Questionable/packages.lock.json index 07f5b16f..eb9b1d2c 100644 --- a/Questionable/packages.lock.json +++ b/Questionable/packages.lock.json @@ -174,7 +174,7 @@ "gatheringpaths": { "type": "Project", "dependencies": { - "Questionable.Model": "[3.10.0, )" + "Questionable.Model": "[3.12.0, )" } }, "llib": { @@ -183,6 +183,9 @@ "DalamudPackager": "[2.1.13, )" } }, + "notificationmasterapi": { + "type": "Project" + }, "questionable.model": { "type": "Project", "dependencies": { @@ -192,7 +195,7 @@ "questpaths": { "type": "Project", "dependencies": { - "Questionable.Model": "[3.10.0, )" + "Questionable.Model": "[3.12.0, )" } } } diff --git a/vendor/NotificationMasterAPI b/vendor/NotificationMasterAPI new file mode 160000 index 00000000..05b1ba78 --- /dev/null +++ b/vendor/NotificationMasterAPI @@ -0,0 +1 @@ +Subproject commit 05b1ba788d5cb940ed8e82599eb88778c9cecdb0