using Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Component.GUI;
+using LLib.GameUI;
using Microsoft.Extensions.Logging;
namespace Questionable.Controller.GameUi;
{
private readonly QuestController _questController;
private readonly IAddonLifecycle _addonLifecycle;
+ private readonly IGameGui _gameGui;
private readonly ILogger<HelpUiController> _logger;
- public HelpUiController(QuestController questController, IAddonLifecycle addonLifecycle, ILogger<HelpUiController> logger)
+ public HelpUiController(
+ QuestController questController,
+ IAddonLifecycle addonLifecycle,
+ IGameGui gameGui,
+ ILogger<HelpUiController> logger)
{
_questController = questController;
_addonLifecycle = addonLifecycle;
+ _gameGui = gameGui;
_logger = logger;
+ _questController.AutomationTypeChanged += CloseHelpWindowsWhenStartingQuests;
+
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "AkatsukiNote", UnendingCodexPostSetup);
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "ContentsTutorial", ContentsTutorialPostSetup);
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "MultipleHelpWindow", MultipleHelpWindowPostSetup);
+ _addonLifecycle.RegisterListener(AddonEvent.PostSetup, "JobHudNotice", JobHudNoticePostSetup);
+ _addonLifecycle.RegisterListener(AddonEvent.PostSetup, "Guide", GuidePostSetup);
+ }
+
+ private unsafe void CloseHelpWindowsWhenStartingQuests(object sender, QuestController.EAutomationType e)
+ {
+ if (e is QuestController.EAutomationType.Manual)
+ return;
+
+ if (_gameGui.TryGetAddonByName("Guide", out AtkUnitBase* addonGuide))
+ {
+ _logger.LogInformation("Guide window is open");
+ GuidePostSetup(addonGuide);
+ }
+
+ if (_gameGui.TryGetAddonByName("JobHudNotice", out AtkUnitBase* addonJobHudNotice))
+ {
+ _logger.LogInformation("JobHudNotice window is open");
+ JobHudNoticePostSetup(addonJobHudNotice);
+ }
}
private unsafe void UnendingCodexPostSetup(AddonEvent type, AddonArgs args)
private unsafe void ContentsTutorialPostSetup(AddonEvent type, AddonArgs args)
{
- if (_questController.StartedQuest?.Quest.Id.Value == 245)
+ if (_questController.StartedQuest?.Quest.Id.Value is 245 or 3872)
{
_logger.LogInformation("Closing ContentsTutorial");
AtkUnitBase* addon = (AtkUnitBase*)args.Addon;
}
}
+ private unsafe void JobHudNoticePostSetup(AddonEvent type, AddonArgs args)
+ {
+ if (_questController.IsRunning || _questController.AutomationType != QuestController.EAutomationType.Manual)
+ JobHudNoticePostSetup((AtkUnitBase*)args.Addon);
+ }
+
+ private unsafe void JobHudNoticePostSetup(AtkUnitBase* addon)
+ {
+ _logger.LogInformation("Clicking the JobHudNotice window to open the relevant Guide page");
+ addon->FireCallbackInt(0);
+ }
+
+ private unsafe void GuidePostSetup(AddonEvent type, AddonArgs args)
+ {
+ if (_questController.IsRunning || _questController.AutomationType != QuestController.EAutomationType.Manual)
+ GuidePostSetup((AtkUnitBase*)args.Addon);
+ }
+
+ private unsafe void GuidePostSetup(AtkUnitBase* addon)
+ {
+ _logger.LogInformation("Closing Guide window");
+ addon->FireCallbackInt(-1);
+ }
+
public void Dispose()
{
+ _addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "Guide", GuidePostSetup);
+ _addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "JobHudNotice", JobHudNoticePostSetup);
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "MultipleHelpWindow", MultipleHelpWindowPostSetup);
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "ContentsTutorial", ContentsTutorialPostSetup);
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "AkatsukiNote", UnendingCodexPostSetup);
+
+ _questController.AutomationTypeChanged -= CloseHelpWindowsWhenStartingQuests;
}
}
private readonly ILogger<T> _logger;
private readonly string _actionCanceledText;
+ private readonly string _cantExecuteDueToStatusText;
protected MiniTaskController(IChatGui chatGui, ICondition condition, IServiceProvider serviceProvider,
InterruptHandler interruptHandler, IDataManager dataManager, ILogger<T> logger)
_condition = condition;
_actionCanceledText = dataManager.GetString<LogMessage>(1314, x => x.Text)!;
+ _cantExecuteDueToStatusText = dataManager.GetString<LogMessage>(7728, x => x.Text)!;
_interruptHandler.Interrupted += HandleInterruption;
}
else
_taskQueue.InterruptWith([new WaitAtEnd.WaitDelay()]);
+ LogTasksAfterInterruption();
+ }
+
+ private void InterruptWithoutCombat()
+ {
+ _logger.LogWarning("Interrupted, attempting to redo previous tasks (not in combat)");
+ _taskQueue.InterruptWith([new WaitAtEnd.WaitDelay()]);
+
+ LogTasksAfterInterruption();
+ }
+
+ private void LogTasksAfterInterruption()
+ {
_logger.LogInformation("Remaining tasks after interruption:");
foreach (ITask task in _taskQueue.RemainingTasks)
_logger.LogInformation("- {TaskName}", task);
!_condition[ConditionFlag.InFlight] &&
_taskQueue.CurrentTaskExecutor?.ShouldInterruptOnDamage() == true)
InterruptQueueWithCombat();
+ else if (GameFunctions.GameStringEquals(_cantExecuteDueToStatusText, message.TextValue))
+ InterruptWithoutCombat();
}
}