qstbak/Questionable/Questionable.Controller.Steps/QuestCleanUp.cs
2025-10-09 07:47:19 +10:00

124 lines
3.9 KiB
C#

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<CheckAlliedSocietyMount> 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<ITask> 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<AtkUnitBase>(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<CloseGatheringAddonTask>()
{
protected unsafe override bool Start()
{
if (gameGui.TryGetAddonByName<AtkUnitBase>(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;
}
}
}