using System; using System.Collections.Generic; using Dalamud.Game.ClientState.Conditions; using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.Game; using Questionable.Data; using Questionable.Functions; using Questionable.Model; using Questionable.Model.Questing; namespace Questionable.Controller.Steps.Shared; internal static class RedeemRewardItems { internal sealed class Factory(QuestData questData) : ITaskFactory { public unsafe IEnumerable CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step) { if (step.InteractionType != EInteractionType.AcceptQuest) { return Array.Empty(); } List list = new List(); InventoryManager* ptr = InventoryManager.Instance(); if (ptr == null) { return list; } foreach (ItemReward redeemableItem in questData.RedeemableItems) { if (ptr->GetInventoryItemCount(redeemableItem.ItemId, isHq: false, checkEquipped: true, checkArmory: true, 0) > 0 && !redeemableItem.IsUnlocked()) { list.Add(new Task(redeemableItem)); } } return list; } } internal sealed record Task(ItemReward ItemReward) : ITask { public override string ToString() { return "TryRedeem(" + ItemReward.Name + ")"; } } internal sealed class Executor(GameFunctions gameFunctions, ICondition condition) : TaskExecutor() { private static readonly TimeSpan MinimumCastTime = TimeSpan.FromSeconds(4L); private DateTime _continueAt; protected override bool Start() { if (condition[ConditionFlag.Mounted]) { return false; } TimeSpan timeSpan = base.Task.ItemReward.CastTime; if (timeSpan < MinimumCastTime) { timeSpan = MinimumCastTime; } _continueAt = DateTime.Now.Add(timeSpan).AddSeconds(3.0); return gameFunctions.UseItem(base.Task.ItemReward.ItemId); } public override ETaskResult Update() { if (condition[ConditionFlag.Casting]) { return ETaskResult.StillRunning; } if (!(DateTime.Now <= _continueAt)) { return ETaskResult.TaskComplete; } return ETaskResult.StillRunning; } public override bool ShouldInterruptOnDamage() { return true; } } }