using System; 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; internal sealed class HelpUiController : IDisposable { private readonly QuestController _questController; private readonly IAddonLifecycle _addonLifecycle; private readonly IGameGui _gameGui; private readonly IFramework _framework; private readonly ILogger _logger; public HelpUiController(QuestController questController, IAddonLifecycle addonLifecycle, IGameGui gameGui, IFramework framework, ILogger logger) { _questController = questController; _addonLifecycle = addonLifecycle; _gameGui = gameGui; _framework = framework; _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); _addonLifecycle.RegisterListener(AddonEvent.PostSetup, "EventTutorial", EventTutorialPostSetup); } private unsafe void CloseHelpWindowsWhenStartingQuests(object sender, QuestController.EAutomationType e) { if (e != QuestController.EAutomationType.Manual) { if (_gameGui.TryGetAddonByName("Guide", out var addonPtr)) { _logger.LogInformation("Guide window is open"); GuidePostSetup(addonPtr); } if (_gameGui.TryGetAddonByName("EventTutorial", out var addonPtr2)) { _logger.LogInformation("EventTutorial window is open"); EventTutorialPostSetup(addonPtr2); } if (_gameGui.TryGetAddonByName("ContentsTutorial", out var addonPtr3)) { _logger.LogInformation("ContentsTutorial window is open"); ContentsTutorialPostSetup(addonPtr3); } if (_gameGui.TryGetAddonByName("JobHudNotice", out var addonPtr4)) { _logger.LogInformation("JobHudNotice window is open"); JobHudNoticePostSetup(addonPtr4); } } } private unsafe void UnendingCodexPostSetup(AddonEvent type, AddonArgs args) { if (_questController.StartedQuest?.Quest.Id.Value == 4526) { _logger.LogInformation("Closing Unending Codex"); AtkUnitBase* address = (AtkUnitBase*)args.Addon.Address; address->FireCallbackInt(-2); } } private unsafe void ContentsTutorialPostSetup(AddonEvent type, AddonArgs args) { bool flag; switch (_questController.StartedQuest?.Quest.Id.Value) { case 245: case 3872: case 5253: flag = true; break; default: flag = false; break; } if (flag) { ContentsTutorialPostSetup((AtkUnitBase*)args.Addon.Address); } } private unsafe void ContentsTutorialPostSetup(AtkUnitBase* addon) { _logger.LogInformation("Closing ContentsTutorial"); addon->FireCallbackInt(13); } private unsafe void MultipleHelpWindowPostSetup(AddonEvent type, AddonArgs args) { if (_questController.StartedQuest?.Quest.Id.Value == 245) { _logger.LogInformation("Closing MultipleHelpWindow"); AtkUnitBase* address = (AtkUnitBase*)args.Addon.Address; address->FireCallbackInt(-2); address->FireCallbackInt(-1); } } private unsafe void JobHudNoticePostSetup(AddonEvent type, AddonArgs args) { if (_questController.IsRunning || _questController.AutomationType != QuestController.EAutomationType.Manual) { JobHudNoticePostSetup((AtkUnitBase*)args.Addon.Address); } } 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.Address); } } private unsafe void GuidePostSetup(AtkUnitBase* addon) { _logger.LogInformation("Closing Guide window"); addon->FireCallbackInt(-1); } private unsafe void EventTutorialPostSetup(AddonEvent type, AddonArgs args) { if (!_questController.IsRunning && _questController.AutomationType == QuestController.EAutomationType.Manual) { return; } _framework.RunOnTick(delegate { if (_gameGui.TryGetAddonByName("EventTutorial", out var addonPtr)) { EventTutorialPostSetup(addonPtr); } }); } private unsafe void EventTutorialPostSetup(AtkUnitBase* addon) { _logger.LogInformation("Closing EventTutorial window"); addon->FireCallbackInt(-1); } public void Dispose() { _addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "EventTutorial", EventTutorialPostSetup); _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; } }