using System; using System.Runtime.CompilerServices; using FFXIVClientStructs.FFXIV.Client.Game; namespace Questionable.Controller.Steps; internal sealed class InteractionProgressContext { private bool _firstUpdateDone; public bool CheckSequence { get; private set; } public int CurrentSequence { get; private set; } private InteractionProgressContext(bool checkSequence, int currentSequence) { CheckSequence = checkSequence; CurrentSequence = currentSequence; } public unsafe static InteractionProgressContext Create(bool checkSequence) { if (!checkSequence) { ActionManager.Instance()->CastTimeElapsed = ActionManager.Instance()->CastTimeTotal; } return new InteractionProgressContext(checkSequence, ActionManager.Instance()->LastUsedActionSequence); } private unsafe static (bool, InteractionProgressContext?) FromActionUseInternal(Func func) { int lastUsedActionSequence = ActionManager.Instance()->LastUsedActionSequence; if (!func()) { return (false, null); } int lastUsedActionSequence2 = ActionManager.Instance()->LastUsedActionSequence; if (lastUsedActionSequence == lastUsedActionSequence2) { return (true, null); } return (true, Create(checkSequence: true)); } public static InteractionProgressContext? FromActionUse(Func func) { return FromActionUseInternal(func).Item2; } public static InteractionProgressContext? FromActionUseOrDefault(Func func) { (bool, InteractionProgressContext) tuple = FromActionUseInternal(func); if (!tuple.Item1) { return null; } return tuple.Item2 ?? Create(checkSequence: false); } public unsafe void Update() { if (!_firstUpdateDone) { int lastUsedActionSequence = ActionManager.Instance()->LastUsedActionSequence; if (!CheckSequence && lastUsedActionSequence > CurrentSequence) { CheckSequence = true; CurrentSequence = lastUsedActionSequence; } _firstUpdateDone = true; } } public unsafe bool WasSuccessful() { if (CheckSequence && (CurrentSequence != ActionManager.Instance()->LastUsedActionSequence || CurrentSequence != ActionManager.Instance()->LastHandledActionSequence)) { return false; } if (ActionManager.Instance()->CastTimeElapsed > 0f) { return Math.Abs(ActionManager.Instance()->CastTimeElapsed - ActionManager.Instance()->CastTimeTotal) < 0.001f; } return false; } public unsafe bool WasInterrupted() { if (CheckSequence && CurrentSequence == ActionManager.Instance()->LastHandledActionSequence && CurrentSequence == ActionManager.Instance()->LastUsedActionSequence) { return false; } if (ActionManager.Instance()->CastTimeElapsed == 0f) { return ActionManager.Instance()->CastTimeTotal > 0f; } return false; } public override string ToString() { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(12, 3); defaultInterpolatedStringHandler.AppendLiteral("IPCtx("); defaultInterpolatedStringHandler.AppendFormatted(CheckSequence ? ((object)CurrentSequence) : "-"); defaultInterpolatedStringHandler.AppendLiteral(" - "); defaultInterpolatedStringHandler.AppendFormatted(WasSuccessful()); defaultInterpolatedStringHandler.AppendLiteral(", "); defaultInterpolatedStringHandler.AppendFormatted(WasInterrupted()); defaultInterpolatedStringHandler.AppendLiteral(")"); return defaultInterpolatedStringHandler.ToStringAndClear(); } }