using System.Collections.Generic; using System.Linq; using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Component.GUI; using LLib.GameUI; using Microsoft.Extensions.Logging; using Questionable.Controller.Steps.Shared; using Questionable.Data; using Questionable.Functions; using Questionable.Model; using Questionable.Model.Common; using Questionable.Model.Questing; namespace Questionable.Controller.Steps; internal static class QuestCleanUp { internal sealed class CheckAlliedSocietyMount(GameFunctions gameFunctions, AetheryteData aetheryteData, AlliedSocietyData alliedSocietyData, ILogger logger) : SimpleTaskFactory() { public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step) { if (sequence.Sequence == 0) { return null; } ushort? mountId = gameFunctions.GetMountId(); if (mountId.HasValue) { ushort valueOrDefault = mountId.GetValueOrDefault(); if (alliedSocietyData.Mounts.TryGetValue(valueOrDefault, out AlliedSocietyMountConfiguration mountConfiguration)) { logger.LogInformation("We are on a known allied society mount with id = {MountId}", valueOrDefault); EAetheryteLocation eAetheryteLocation = step.AetheryteShortcut ?? mountConfiguration.ClosestAetheryte; AetheryteShortcut.Task result = new AetheryteShortcut.Task(null, quest.Id, eAetheryteLocation, aetheryteData.TerritoryIds[eAetheryteLocation]); if (sequence.Sequence == byte.MaxValue) { logger.LogInformation("Mount can't be used to finish quest, teleporting to {Aetheryte}", mountConfiguration.ClosestAetheryte); return result; } if (!quest.AllSteps().Any<(QuestSequence, int, QuestStep)>(delegate((QuestSequence Sequence, int StepId, QuestStep Step) x) { EAction? action = x.Step.Action; if (action.HasValue) { EAction valueOrDefault2 = action.GetValueOrDefault(); if (valueOrDefault2.RequiresMount()) { return true; } } return x.Step.InteractionType == EInteractionType.Combat && x.Step.KillEnemyDataIds.Contains(8593u); })) { logger.LogInformation("Quest doesn't use any mount actions, teleporting to {Aetheryte}", mountConfiguration.ClosestAetheryte); return result; } if (!(from x in quest.AllSequences() where x.Sequence > 0 && x.Sequence < sequence.Sequence select x).SelectMany((QuestSequence x) => x.Steps).ToList().Any((QuestStep x) => x.DataId.HasValue && mountConfiguration.IssuerDataIds.Contains(x.DataId.Value))) { logger.LogInformation("Haven't talked to mount NPC for this allied society quest; {Aetheryte}", mountConfiguration.ClosestAetheryte); return result; } } } return null; } } internal sealed class CloseGatheringAddonFactory(IGameGui gameGui) : ITaskFactory { public IEnumerable CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step) { if (IsAddonOpen("GatheringMasterpiece")) { yield return new CloseGatheringAddonTask("GatheringMasterpiece"); } if (IsAddonOpen("Gathering")) { yield return new CloseGatheringAddonTask("Gathering"); } } private unsafe bool IsAddonOpen(string name) { if (gameGui.TryGetAddonByName(name, out var addonPtr)) { return addonPtr->IsVisible; } return false; } } internal sealed record CloseGatheringAddonTask(string AddonName) : ITask { public override string ToString() { return "CloseAddon(" + AddonName + ")"; } } internal sealed class DoCloseAddon(IGameGui gameGui) : TaskExecutor() { protected unsafe override bool Start() { if (gameGui.TryGetAddonByName(base.Task.AddonName, out var addonPtr)) { addonPtr->FireCallbackInt(-1); return true; } return false; } public override ETaskResult Update() { return ETaskResult.TaskComplete; } public override bool ShouldInterruptOnDamage() { return false; } } }