Automatically close job bar tutorials + Lv49 novice guide

This commit is contained in:
Liza 2025-01-24 19:53:20 +01:00
parent 7731dd0658
commit d85b204c79
Signed by: liza
GPG Key ID: 2C41B84815CF6445
3 changed files with 80 additions and 2 deletions

View File

@ -3,6 +3,7 @@ using Dalamud.Game.Addon.Lifecycle;
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;
@ -11,17 +12,45 @@ internal sealed class HelpUiController : IDisposable
{
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)
@ -36,7 +65,7 @@ internal sealed class HelpUiController : IDisposable
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;
@ -58,10 +87,38 @@ internal sealed class HelpUiController : IDisposable
}
}
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;
}
}

View File

@ -28,6 +28,7 @@ internal abstract class MiniTaskController<T> : IDisposable
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)
@ -39,6 +40,7 @@ internal abstract class MiniTaskController<T> : IDisposable
_condition = condition;
_actionCanceledText = dataManager.GetString<LogMessage>(1314, x => x.Text)!;
_cantExecuteDueToStatusText = dataManager.GetString<LogMessage>(7728, x => x.Text)!;
_interruptHandler.Interrupted += HandleInterruption;
}
@ -183,6 +185,19 @@ internal abstract class MiniTaskController<T> : IDisposable
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);
@ -204,6 +219,8 @@ internal abstract class MiniTaskController<T> : IDisposable
!_condition[ConditionFlag.InFlight] &&
_taskQueue.CurrentTaskExecutor?.ShouldInterruptOnDamage() == true)
InterruptQueueWithCombat();
else if (GameFunctions.GameStringEquals(_cantExecuteDueToStatusText, message.TextValue))
InterruptWithoutCombat();
}
}

View File

@ -111,9 +111,13 @@ internal sealed class QuestController : MiniTaskController<QuestController>, IDi
_logger.LogInformation("Setting automation type to {NewAutomationType} (previous: {OldAutomationType})",
value, _automationType);
_automationType = value;
AutomationTypeChanged?.Invoke(this, value);
}
}
public delegate void AutomationTypeChangedEventHandler(object sender, EAutomationType e);
public event AutomationTypeChangedEventHandler? AutomationTypeChanged;
public (QuestProgress Progress, ECurrentQuestType Type)? CurrentQuestDetails
{
get