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 long _nextActionAt; protected override bool Start() { logger.LogDebug("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 (Environment.TickCount64 < _nextActionAt) { return ETaskResult.StillRunning; } foreach (FateActionTarget target in base.Task.Targets) { IGameObject gameObject = gameFunctions.FindObjectByDataId(target.DataId, null, warnIfMissing: false); if (gameObject != null && gameObject.IsTargetable) { bool flag = gameFunctions.UseAction(gameObject, target.Action); _nextActionAt = (flag ? (Environment.TickCount64 + 2500) : (Environment.TickCount64 + 500)); return ETaskResult.StillRunning; } } _nextActionAt = Environment.TickCount64 + 250; return ETaskResult.StillRunning; } public override bool ShouldInterruptOnDamage() { return false; } } }