using System; using Dalamud.Game.ClientState.Objects.Types; using Dalamud.Plugin; using Dalamud.Plugin.Ipc; using Dalamud.Plugin.Ipc.Exceptions; using Microsoft.Extensions.Logging; using Questionable.Controller.Steps; namespace Questionable.Controller.CombatModules; internal sealed class WrathComboModule : ICombatModule, IDisposable { public enum ESetResult { Okay = 0, OkayWorking = 1, IpcDisabled = 10, InvalidLease = 11, BlacklistedLease = 12, Duplicate = 13, PlayerNotAvailable = 14, InvalidConfiguration = 15, InvalidValue = 16 } public enum AutoRotationConfigOption { InCombatOnly, DPSRotationMode, HealerRotationMode, FATEPriority, QuestPriority, SingleTargetHPP, AoETargetHPP, SingleTargetRegenHPP, ManageKardia, AutoRez, AutoRezDPSJobs, AutoCleanse, IncludeNPCs, OnlyAttackInCombat, OrbwalkerIntegration, AutoRezOutOfParty, DPSAoETargets, SingleTargetExcogHPP } public enum HealerRotationMode { Manual, Highest_Current, Lowest_Current } private const string CallbackPrefix = "Questionable$Wrath"; private readonly ILogger _logger; private readonly Configuration _configuration; private readonly ICallGateSubscriber _test; private readonly ICallGateSubscriber _registerForLeaseWithCallback; private readonly ICallGateSubscriber _releaseControl; private readonly ICallGateSubscriber _setAutoRotationState; private readonly ICallGateSubscriber _setAutoRotationConfigState; private readonly ICallGateSubscriber _setCurrentJobAutoRotationReady; private readonly ICallGateProvider _callback; private Guid? _lease; public WrathComboModule(ILogger logger, Configuration configuration, IDalamudPluginInterface pluginInterface) { _logger = logger; _configuration = configuration; _test = pluginInterface.GetIpcSubscriber("WrathCombo.Test"); _registerForLeaseWithCallback = pluginInterface.GetIpcSubscriber("WrathCombo.RegisterForLeaseWithCallback"); _releaseControl = pluginInterface.GetIpcSubscriber("WrathCombo.ReleaseControl"); _setAutoRotationState = pluginInterface.GetIpcSubscriber("WrathCombo.SetAutoRotationState"); _setAutoRotationConfigState = pluginInterface.GetIpcSubscriber("WrathCombo.SetAutoRotationConfigState"); _setCurrentJobAutoRotationReady = pluginInterface.GetIpcSubscriber("WrathCombo.SetCurrentJobAutoRotationReady"); _callback = pluginInterface.GetIpcProvider("Questionable$Wrath.WrathComboCallback"); _callback.RegisterAction(Callback); } public bool CanHandleFight(CombatController.CombatData combatData) { if (_configuration.General.CombatModule != Configuration.ECombatModule.WrathCombo) { return false; } try { _test.InvokeAction(); return true; } catch (IpcError) { return false; } } public bool Start(CombatController.CombatData combatData) { try { _lease = _registerForLeaseWithCallback.InvokeFunc("Questionable", "Questionable", "Questionable$Wrath"); if (_lease.HasValue) { _logger.LogDebug("Wrath combo lease: {Lease}", _lease.Value); if (!_setAutoRotationState.InvokeFunc(_lease.Value, arg2: true).IsSuccess()) { _logger.LogError("Unable to set autorotation state"); Stop(); return false; } if (!_setCurrentJobAutoRotationReady.InvokeFunc(_lease.Value).IsSuccess()) { _logger.LogError("Unable to set current job for autorotation"); Stop(); return false; } ESetResult eSetResult = _setAutoRotationConfigState.InvokeFunc(_lease.Value, AutoRotationConfigOption.HealerRotationMode, HealerRotationMode.Lowest_Current); if (!eSetResult.IsSuccess()) { _logger.LogError("Unable to configure healing priority for autorotation: {Result}", eSetResult); } return true; } _logger.LogError("Wrath combo did not return a lease"); return false; } catch (IpcError exception) { _logger.LogError(exception, "Unable to use wrath combo for combat"); return false; } } public bool Stop() { try { if (_lease.HasValue) { _releaseControl.InvokeAction(_lease.Value); _lease = null; } return true; } catch (IpcError exception) { _logger.LogWarning(exception, "Could not turn off wrath combo"); return false; } } public void Update(IGameObject nextTarget) { if (!_lease.HasValue) { throw new TaskException("Wrath Combo Lease is cancelled"); } } public bool CanAttack(IBattleNpc target) { return true; } private void Callback(int reason, string additionalInfo) { _logger.LogWarning("WrathCombo callback: {Reason} ({Info})", reason, additionalInfo); _lease = null; } public void Dispose() { Stop(); _callback.UnregisterAction(); } }