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