using System; using System.Collections.Generic; using System.Linq; using Dalamud.Game.ClientState.Objects.Types; using Microsoft.Extensions.Logging; using Questionable.Controller.Steps.Common; using Questionable.Functions; using Questionable.Model; using Questionable.Model.Questing; namespace Questionable.Controller.Steps.Interactions; internal static class FateAction { internal sealed class Factory : ITaskFactory { public IEnumerable CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step) { if (step.InteractionType != EInteractionType.FateAction) { return Array.Empty(); } if (step.FateActionTargets.Count == 0) { throw new InvalidOperationException("FateAction step requires FateActionTargets"); } return new global::_003C_003Ez__ReadOnlyArray(new ITask[2] { new Mount.UnmountTask(), new UseOnTargets(step.FateActionTargets) }); } } internal sealed record UseOnTargets(IList Targets) : ITask { public bool ShouldRedoOnInterrupt() { return true; } public override string ToString() { return $"FateAction({Targets.Count} targets)"; } } internal sealed class UseOnTargetsExecutor(GameFunctions gameFunctions, ILogger logger) : TaskExecutor() { private DateTime _nextActionAt = DateTime.MinValue; protected override bool Start() { logger.LogInformation("Starting FateAction: {Count} targets [{Targets}]", base.Task.Targets.Count, string.Join(", ", base.Task.Targets.Select((FateActionTarget t) => $"{t.DataId}→{t.Action}"))); return true; } public override ETaskResult Update() { if (DateTime.Now < _nextActionAt) { return ETaskResult.StillRunning; } foreach (FateActionTarget target in base.Task.Targets) { IGameObject gameObject = gameFunctions.FindObjectByDataId(target.DataId); if (gameObject != null && gameObject.IsTargetable) { bool flag = gameFunctions.UseAction(gameObject, target.Action); _nextActionAt = (flag ? DateTime.Now.AddSeconds(2.5) : DateTime.Now.AddSeconds(0.5)); return ETaskResult.StillRunning; } } _nextActionAt = DateTime.Now.AddSeconds(0.25); return ETaskResult.StillRunning; } public override bool ShouldInterruptOnDamage() { return false; } } }