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

87 lines
2.1 KiB
C#

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<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
{
if (step.InteractionType != EInteractionType.AcceptQuest)
{
return Array.Empty<ITask>();
}
List<ITask> list = new List<ITask>();
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<Task>()
{
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;
}
}
}