using System; using System.Collections.Generic; using System.Threading; using Dalamud.Game.ClientState.Conditions; using Dalamud.Game.ClientState.Objects.SubKinds; using Dalamud.Plugin.Services; namespace QuestionableCompanion.Services; public class StepsOfFaithHandler : IDisposable { private readonly ICondition condition; private readonly IPluginLog log; private readonly IClientState clientState; private readonly ICommandManager commandManager; private readonly IFramework framework; private readonly Configuration config; private bool isActive; private readonly Dictionary characterHandledStatus = new Dictionary(); private const uint StepsOfFaithQuestId = 4591u; public bool IsActive => isActive; public bool IsStepsOfFaithQuest(uint questId) { return questId == 4591; } public StepsOfFaithHandler(ICondition condition, IPluginLog log, IClientState clientState, ICommandManager commandManager, IFramework framework, Configuration config) { this.condition = condition; this.log = log; this.clientState = clientState; this.commandManager = commandManager; this.framework = framework; this.config = config; log.Information("[StepsOfFaith] Handler initialized"); } public bool ShouldActivate(uint questId, bool isInSoloDuty) { if (!config.EnableAutoDutyUnsynced) { return false; } if (isActive) { return false; } if (questId != 4591) { return false; } if (!isInSoloDuty) { return false; } string characterName = GetCurrentCharacterName(); if (string.IsNullOrEmpty(characterName)) { return false; } if (characterHandledStatus.GetValueOrDefault(characterName, defaultValue: false)) { return false; } return true; } public void Execute(string characterName) { isActive = true; if (!string.IsNullOrEmpty(characterName)) { characterHandledStatus[characterName] = true; log.Information("[StepsOfFaith] Marked " + characterName + " as handled"); } log.Information("[StepsOfFaith] ========================================"); log.Information("[StepsOfFaith] === STEPS OF FAITH HANDLER ACTIVATED ==="); log.Information("[StepsOfFaith] ========================================"); try { log.Information("[StepsOfFaith] Waiting for conditions to clear..."); DateTime startTime = DateTime.Now; TimeSpan maxWaitTime = TimeSpan.FromSeconds(6000L); while (DateTime.Now - startTime < maxWaitTime) { bool hasCondition29 = condition[ConditionFlag.Occupied]; bool hasCondition63 = condition[ConditionFlag.SufferingStatusAffliction63]; if (!hasCondition29 && !hasCondition63) { log.Information("[StepsOfFaith] Conditions cleared!"); break; } if ((DateTime.Now - startTime).TotalSeconds % 5.0 < 0.1) { log.Information($"[StepsOfFaith] Waiting... (29: {hasCondition29}, 63: {hasCondition63})"); } Thread.Sleep(200); } log.Information("[StepsOfFaith] Waiting 25s for stabilization..."); Thread.Sleep(25000); log.Information("[StepsOfFaith] Disabling Bossmod Rotation..."); framework.RunOnFrameworkThread(delegate { commandManager.ProcessCommand("/vbm ar disable"); }); log.Information("[StepsOfFaith] Moving to target position..."); framework.RunOnFrameworkThread(delegate { commandManager.ProcessCommand("/vnav moveto 2.8788917064667 0.0 293.36273193359"); }); log.Information("[StepsOfFaith] Enabling combat commands..."); framework.RunOnFrameworkThread(delegate { commandManager.ProcessCommand("/rsr auto"); Thread.Sleep(100); commandManager.ProcessCommand("/vbmai on"); Thread.Sleep(100); commandManager.ProcessCommand("/bmrai on"); }); log.Information("[StepsOfFaith] === HANDLER COMPLETE ==="); } catch (Exception ex) { log.Error("[StepsOfFaith] Error: " + ex.Message); } finally { isActive = false; } } public void Reset() { isActive = false; log.Information("[StepsOfFaith] Active state reset (character completion status preserved)"); } private string GetCurrentCharacterName() { try { IPlayerCharacter player = clientState.LocalPlayer; if (player != null) { return $"{player.Name}@{player.HomeWorld.Value.Name}"; } } catch (Exception ex) { log.Error("[StepsOfFaith] Failed to get character name: " + ex.Message); } return string.Empty; } public void Dispose() { } }