diff --git a/AutoDuty/AutoDuty.cs b/AutoDuty/AutoDuty.cs index 58c2f560..e2f95352 100644 --- a/AutoDuty/AutoDuty.cs +++ b/AutoDuty/AutoDuty.cs @@ -31,7 +31,6 @@ using ECommons.ExcelServices; using FFXIVClientStructs.FFXIV.Client.UI.Agent; using Dalamud.IoC; -using FFXIVClientStructs.FFXIV.Component.GUI; using System.Diagnostics; using Lumina.Excel.GeneratedSheets; using Dalamud.Game.ClientState.Conditions; @@ -91,12 +90,6 @@ internal Stage Stage case Stage.Action: ActionInvoke(); break; - case Stage.Dead: - OnDeath(); - break; - case Stage.Revived: - OnRevive(); - break; case Stage.Condition: Action = $"ConditionChange"; SchedulerHelper.ScheduleAction("ConditionChangeStageReadingPath", () => _stage = Stage.Reading_Path, () => !Svc.Condition[ConditionFlag.BetweenAreas] && !Svc.Condition[ConditionFlag.BetweenAreas51] && !Svc.Condition[ConditionFlag.Jumping61]); @@ -419,6 +412,23 @@ private void ClientState_TerritoryChanged(ushort t) private void Condition_ConditionChange(ConditionFlag flag, bool value) { if (Stage == Stage.Stopped) return; + + if (flag == ConditionFlag.Unconscious) + { + if (value && (Stage != Stage.Dead || DeathHelper.DeathState != PlayerLifeState.Dead)) + { + Svc.Log.Debug($"We Died, Setting Stage to Dead"); + DeathHelper.DeathState = PlayerLifeState.Dead; + Stage = Stage.Dead; + } + else if (!value && (Stage != Stage.Revived || DeathHelper.DeathState != PlayerLifeState.Revived)) + { + Svc.Log.Debug($"We Revived, Setting Stage to Revived"); + DeathHelper.DeathState = PlayerLifeState.Revived; + Stage = Stage.Revived; + } + return; + } //Svc.Log.Debug($"{flag} : {value}"); if (Stage != Stage.Dead && Stage != Stage.Revived && !_recentlyWatchedCutscene && !Conditions.IsWatchingCutscene && flag != ConditionFlag.WatchingCutscene && flag != ConditionFlag.WatchingCutscene78 && flag != ConditionFlag.OccupiedInCutSceneEvent && Stage != Stage.Action && value && States.HasFlag(PluginState.Navigating) && (flag == ConditionFlag.BetweenAreas || flag == ConditionFlag.BetweenAreas51 || flag == ConditionFlag.Jumping61)) { @@ -880,8 +890,10 @@ internal void SetGeneralSettings(bool on) } } - internal void SetRotationPluginSettings(bool on) + internal void SetRotationPluginSettings(bool on, bool ignoreConfig = false) { + if (!Configuration.AutoManageRotationPluginState && !ignoreConfig) return; + if (ReflectionHelper.RotationSolver_Reflection.RotationSolverEnabled) { if (on) @@ -983,51 +995,6 @@ internal void BMRoleChecks() ConfigTab.FollowName = ObjectHelper.GetPartyMemberFromRole($"{Configuration.FollowRoleEnum}")?.Name.ExtractText() ?? ""; } - private unsafe void OnDeath() - { - if ((Configuration.DutyModeEnum == DutyMode.Regular || Configuration.DutyModeEnum == DutyMode.Trial || Configuration.DutyModeEnum == DutyMode.Raid) && !Configuration.Unsynced) - return; - - StopForCombat = true; - SkipTreasureCoffer = true; - if (VNavmesh_IPCSubscriber.Path_IsRunning()) - VNavmesh_IPCSubscriber.Path_Stop(); - if (TaskManager.IsBusy) - TaskManager.Abort(); - if (Configuration.DutyModeEnum == DutyMode.Regular || Configuration.DutyModeEnum == DutyMode.Trial || Configuration.DutyModeEnum == DutyMode.Raid) - { - TaskManager.Enqueue(() => GenericHelpers.TryGetAddonByName("SelectYesno", out AtkUnitBase* addonSelectYesno) && GenericHelpers.IsAddonReady(addonSelectYesno)); - TaskManager.Enqueue(() => AddonHelper.ClickSelectYesno()); - } - } - - private unsafe void OnRevive() - { - if ((Configuration.DutyModeEnum == DutyMode.Regular || Configuration.DutyModeEnum == DutyMode.Trial || Configuration.DutyModeEnum == DutyMode.Raid) && !Configuration.Unsynced) - return; - - TaskManager.DelayNext(5000); - TaskManager.Enqueue(() => !ObjectHelper.PlayerIsCasting); - TaskManager.Enqueue(() => BossMod_IPCSubscriber.Presets_ClearActive()); - IGameObject? gameObject = ObjectHelper.GetObjectByDataId(2000700); - if (gameObject == null || !gameObject.IsTargetable) - { - TaskManager.Enqueue(() => { Stage = Stage.Reading_Path; } ); - return; - } - - var oldindex = Indexer; - Indexer = FindWaypoint(); - TaskManager.Enqueue(() => MovementHelper.Move(gameObject, 0.25f, 2)); - TaskManager.Enqueue(() => !ObjectHelper.PlayerIsCasting); - TaskManager.Enqueue(() => ObjectHelper.InteractWithObjectUntilAddon(gameObject, "SelectYesno"), int.MaxValue); - TaskManager.Enqueue(() => AddonHelper.ClickSelectYesno(), int.MaxValue); - TaskManager.Enqueue(() => !ObjectHelper.IsValid, 500); - TaskManager.Enqueue(() => ObjectHelper.IsValid); - TaskManager.Enqueue(() => { if (Indexer == 0) Indexer = FindWaypoint(); }); - TaskManager.Enqueue(() => Stage = Stage.Reading_Path); - } - private unsafe void ActionInvoke() { if (!TaskManager.IsBusy && !_action.IsNullOrEmpty()) @@ -1060,67 +1027,6 @@ private unsafe void ActionInvoke() } } - private int FindWaypoint() - { - if (Indexer == 0) - { - //Svc.Log.Info($"Finding Closest Waypoint {ListBoxPOSText.Count}"); - float closestWaypointDistance = float.MaxValue; - int closestWaypointIndex = -1; - float currentDistance = 0; - - for (int i = 0; i < ListBoxPOSText.Count; i++) - { - string node = ListBoxPOSText[i]; - - if (node.Contains("Boss|") && node.Replace("Boss|", "").All(c => char.IsDigit(c) || c == ',' || c == ' ' || c == '-' || c == '.')) - { - currentDistance = ObjectHelper.GetDistanceToPlayer(new Vector3(float.Parse(ListBoxPOSText[Indexer].Replace("Boss|", "").Split(',')[0], System.Globalization.CultureInfo.InvariantCulture), float.Parse(ListBoxPOSText[Indexer].Replace("Boss|", "").Split(',')[1], System.Globalization.CultureInfo.InvariantCulture), float.Parse(ListBoxPOSText[Indexer].Replace("Boss|", "").Split(',')[2], System.Globalization.CultureInfo.InvariantCulture))); - - if (currentDistance < closestWaypointDistance) - { - closestWaypointDistance = currentDistance; - closestWaypointIndex = i; - } - } - else if (node.All(c => char.IsDigit(c) || c == ',' || c == ' ' || c == '-' || c == '.')) - { - currentDistance = ObjectHelper.GetDistanceToPlayer(new Vector3(float.Parse(ListBoxPOSText[Indexer].Split(',')[0], System.Globalization.CultureInfo.InvariantCulture), float.Parse(ListBoxPOSText[Indexer].Split(',')[1], System.Globalization.CultureInfo.InvariantCulture), float.Parse(ListBoxPOSText[Indexer].Split(',')[2], System.Globalization.CultureInfo.InvariantCulture))); - //Svc.Log.Info($"cd: {currentDistance}"); - if (currentDistance < closestWaypointDistance) - { - closestWaypointDistance = ObjectHelper.GetDistanceToPlayer(new Vector3(float.Parse(ListBoxPOSText[Indexer].Split(',')[0], System.Globalization.CultureInfo.InvariantCulture), float.Parse(ListBoxPOSText[Indexer].Split(',')[1], System.Globalization.CultureInfo.InvariantCulture), float.Parse(ListBoxPOSText[Indexer].Split(',')[2], System.Globalization.CultureInfo.InvariantCulture))); - closestWaypointIndex = i; - } - } - } - //Svc.Log.Info($"Closest Waypoint was {closestWaypointIndex}"); - return closestWaypointIndex + 1; - } - - if (Indexer != -1) - { - bool revivalFound = ContentPathsManager.DictionaryPaths[CurrentTerritoryType].Paths[CurrentPath].RevivalFound; - - //Svc.Log.Info("Finding Last Boss"); - for (int i = Indexer; i >= 0; i--) - { - if (revivalFound) - { - if (ListBoxPOSText[i].Contains("Revival|") && i != Indexer) - return i; - } - else - { - if (ListBoxPOSText[i].Contains("Boss|") && i != Indexer) - return i + 1; - } - } - } - - return 0; - } - private void GetJobAndLevelingCheck() { Job curJob = Player.Object.GetJob(); @@ -1179,12 +1085,6 @@ public void Framework_Update(IFramework framework) if (States.HasFlag(PluginState.Navigating) && Configuration.LootTreasure && (!Configuration.LootBossTreasureOnly || (_action == "Boss" && Stage == Stage.Action)) && (treasureCofferGameObject = ObjectHelper.GetObjectsByObjectKind(ObjectKind.Treasure)?.FirstOrDefault(x => ObjectHelper.GetDistanceToPlayer(x) < 2)) != null) ObjectHelper.InteractWithObject(treasureCofferGameObject, false); - if (Stage != Stage.Dead && States.HasFlag(PluginState.Navigating) && Player.Object.CurrentHp == 0) - Stage = Stage.Dead; - - if (Stage == Stage.Dead && States.HasFlag(PluginState.Navigating) && Player.Object.CurrentHp > 0) - Stage = Stage.Revived; - if (Indexer >= ListBoxPOSText.Count && ListBoxPOSText.Count > 0 && States.HasFlag(PluginState.Navigating)) DoneNavigating(); @@ -1566,7 +1466,8 @@ private void StopAndResetALL() ExitDutyHelper.Stop(); if (AutoEquipHelper.State == ActionState.Running) AutoEquipHelper.Stop(); - + if (DeathHelper.DeathState == PlayerLifeState.Revived) + DeathHelper.Stop(); Action = ""; } diff --git a/AutoDuty/Data/Enums.cs b/AutoDuty/Data/Enums.cs index b5416d0f..fc385f22 100644 --- a/AutoDuty/Data/Enums.cs +++ b/AutoDuty/Data/Enums.cs @@ -181,5 +181,12 @@ public enum TrustRole : byte Tank = 2, AllRounder = 3 } + + public enum PlayerLifeState + { + Alive = 0, + Dead = 1, + Revived = 2 + } } } diff --git a/AutoDuty/Helpers/DeathHelper.cs b/AutoDuty/Helpers/DeathHelper.cs new file mode 100644 index 00000000..f2bc1a12 --- /dev/null +++ b/AutoDuty/Helpers/DeathHelper.cs @@ -0,0 +1,188 @@ +using AutoDuty.IPC; +using Dalamud.Game.ClientState.Objects.Types; +using Dalamud.Plugin.Services; +using ECommons; +using ECommons.DalamudServices; +using ECommons.Throttlers; +using FFXIVClientStructs.FFXIV.Client.Game; +using FFXIVClientStructs.FFXIV.Component.GUI; +using System; +using System.Linq; +using System.Numerics; + +namespace AutoDuty.Helpers +{ + internal static class DeathHelper + { + private static PlayerLifeState _deathState = PlayerLifeState.Alive; + internal static PlayerLifeState DeathState + { + get => _deathState; + set + { + if (AutoDuty.Plugin.Configuration.DutyModeEnum.EqualsAny(DutyMode.Regular, DutyMode.Trial, DutyMode.Raid) && !AutoDuty.Plugin.Configuration.Unsynced) + return; + else if (value == PlayerLifeState.Dead) + { + Svc.Log.Debug("DeathHelper - Player is Dead changing state to Dead"); + OnDeath(); + } + else if (value == PlayerLifeState.Revived) + { + Svc.Log.Debug("DeathHelper - Player is Revived changing state to Revived"); + _oldIndex = AutoDuty.Plugin.Indexer; + BossMod_IPCSubscriber.Presets_ClearActive(); + _findShortcutStartTime = Environment.TickCount; + FindShortcut(); + } + _deathState = value; + } + } + + private static unsafe void OnDeath() + { + if (AutoDuty.Plugin.Configuration.DutyModeEnum.EqualsAny(DutyMode.Regular, DutyMode.Trial, DutyMode.Raid) && !AutoDuty.Plugin.Configuration.Unsynced) + return; + + AutoDuty.Plugin.StopForCombat = true; + AutoDuty.Plugin.SkipTreasureCoffer = true; + + if (VNavmesh_IPCSubscriber.Path_IsRunning()) + VNavmesh_IPCSubscriber.Path_Stop(); + + if (AutoDuty.Plugin.TaskManager.IsBusy) + AutoDuty.Plugin.TaskManager.Abort(); + + if (AutoDuty.Plugin.Configuration.DutyModeEnum.EqualsAny(DutyMode.Regular, DutyMode.Trial, DutyMode.Raid)) + { + if (GenericHelpers.TryGetAddonByName("SelectYesno", out AtkUnitBase* addonSelectYesno) && GenericHelpers.IsAddonReady(addonSelectYesno)) + AddonHelper.ClickSelectYesno(); + else + SchedulerHelper.ScheduleAction("OnDeath", OnDeath, 500); + } + } + + private static int _oldIndex = 0; + private static IGameObject? _gameObject => ObjectHelper.GetObjectByDataId(2000700); + private static int _findShortcutStartTime = 0; + + private static int FindWaypoint() + { + if (AutoDuty.Plugin.Indexer == 0) + { + //Svc.Log.Info($"Finding Closest Waypoint {ListBoxPOSText.Count}"); + float closestWaypointDistance = float.MaxValue; + int closestWaypointIndex = -1; + float currentDistance = 0; + + for (int i = 0; i < AutoDuty.Plugin.ListBoxPOSText.Count; i++) + { + string node = AutoDuty.Plugin.ListBoxPOSText[i]; + + if (node.Contains("Boss|") && node.Replace("Boss|", "").All(c => char.IsDigit(c) || c == ',' || c == ' ' || c == '-' || c == '.')) + { + currentDistance = ObjectHelper.GetDistanceToPlayer(new Vector3(float.Parse(AutoDuty.Plugin.ListBoxPOSText[AutoDuty.Plugin.Indexer].Replace("Boss|", "").Split(',')[0], System.Globalization.CultureInfo.InvariantCulture), float.Parse(AutoDuty.Plugin.ListBoxPOSText[AutoDuty.Plugin.Indexer].Replace("Boss|", "").Split(',')[1], System.Globalization.CultureInfo.InvariantCulture), float.Parse(AutoDuty.Plugin.ListBoxPOSText[AutoDuty.Plugin.Indexer].Replace("Boss|", "").Split(',')[2], System.Globalization.CultureInfo.InvariantCulture))); + + if (currentDistance < closestWaypointDistance) + { + closestWaypointDistance = currentDistance; + closestWaypointIndex = i; + } + } + else if (node.All(c => char.IsDigit(c) || c == ',' || c == ' ' || c == '-' || c == '.')) + { + currentDistance = ObjectHelper.GetDistanceToPlayer(new Vector3(float.Parse(AutoDuty.Plugin.ListBoxPOSText[AutoDuty.Plugin.Indexer].Split(',')[0], System.Globalization.CultureInfo.InvariantCulture), float.Parse(AutoDuty.Plugin.ListBoxPOSText[AutoDuty.Plugin.Indexer].Split(',')[1], System.Globalization.CultureInfo.InvariantCulture), float.Parse(AutoDuty.Plugin.ListBoxPOSText[AutoDuty.Plugin.Indexer].Split(',')[2], System.Globalization.CultureInfo.InvariantCulture))); + //Svc.Log.Info($"cd: {currentDistance}"); + if (currentDistance < closestWaypointDistance) + { + closestWaypointDistance = ObjectHelper.GetDistanceToPlayer(new Vector3(float.Parse(AutoDuty.Plugin.ListBoxPOSText[AutoDuty.Plugin.Indexer].Split(',')[0], System.Globalization.CultureInfo.InvariantCulture), float.Parse(AutoDuty.Plugin.ListBoxPOSText[AutoDuty.Plugin.Indexer].Split(',')[1], System.Globalization.CultureInfo.InvariantCulture), float.Parse(AutoDuty.Plugin.ListBoxPOSText[AutoDuty.Plugin.Indexer].Split(',')[2], System.Globalization.CultureInfo.InvariantCulture))); + closestWaypointIndex = i; + } + } + } + //Svc.Log.Info($"Closest Waypoint was {closestWaypointIndex}"); + return closestWaypointIndex + 1; + } + + if (AutoDuty.Plugin.Indexer != -1) + { + bool revivalFound = ContentPathsManager.DictionaryPaths[AutoDuty.Plugin.CurrentTerritoryType].Paths[AutoDuty.Plugin.CurrentPath].RevivalFound; + + //Svc.Log.Info("Finding Last Boss"); + for (int i = AutoDuty.Plugin.Indexer; i >= 0; i--) + { + if (revivalFound) + { + if (AutoDuty.Plugin.ListBoxPOSText[i].Contains("Revival|") && i != AutoDuty.Plugin.Indexer) + return i; + } + else + { + if (AutoDuty.Plugin.ListBoxPOSText[i].Contains("Boss|") && i != AutoDuty.Plugin.Indexer) + return i + 1; + } + } + } + + return 0; + } + + private static void FindShortcut() + { + if (_gameObject == null && Environment.TickCount <= (_findShortcutStartTime + 5000)) + { + Svc.Log.Debug($"OnRevive: Searching for shortcut"); + SchedulerHelper.ScheduleAction("FindShortcut", FindShortcut, 500); + return; + } + + if (_gameObject == null || !_gameObject!.IsTargetable) + { + Svc.Log.Debug($"OnRevive: Couldn't find shortcut"); + Stop(); + return; + } + + Svc.Log.Debug("OnRevive: Found shortcut"); + Svc.Framework.Update += OnRevive; + } + + internal static void Stop() + { + Svc.Framework.Update -= OnRevive; + if (VNavmesh_IPCSubscriber.Path_IsRunning()) + VNavmesh_IPCSubscriber.Path_Stop(); + AutoDuty.Plugin.Stage = Stage.Reading_Path; + Svc.Log.Debug("DeathHelper - Player is Alive, and we are done with Revived Actions, changing state to Alive"); + _deathState = PlayerLifeState.Alive; + } + + private static unsafe void OnRevive(IFramework _) + { + if (!EzThrottler.Throttle("OnRevive", 500) || (!ObjectHelper.IsReady && !Conditions.IsOccupiedInQuestEvent) || ObjectHelper.PlayerIsCasting) return; + + if (_gameObject == null || !_gameObject.IsTargetable) + { + Svc.Log.Debug("OnRevive: Done"); + if (AutoDuty.Plugin.Indexer == 0) AutoDuty.Plugin.Indexer = FindWaypoint(); + Stop(); + return; + } + + if (_oldIndex == AutoDuty.Plugin.Indexer) + AutoDuty.Plugin.Indexer = FindWaypoint(); + + if (ObjectHelper.GetDistanceToPlayer(_gameObject) > 2) + { + MovementHelper.Move(_gameObject, 0.25f, 2); + Svc.Log.Debug($"OnRevive: Moving to {_gameObject.Name} at: {_gameObject.Position} which is {ObjectHelper.GetDistanceToPlayer(_gameObject)} away"); + } + else + { + Svc.Log.Debug($"OnRevive: Interacting with {_gameObject.Name} until SelectYesno Addon appears, and ClickingYes"); + ObjectHelper.InteractWithObjectUntilAddon(_gameObject, "SelectYesno"); + AddonHelper.ClickSelectYesno(); + } + } + } +} diff --git a/AutoDuty/Helpers/TrustHelper.cs b/AutoDuty/Helpers/TrustHelper.cs index a7c7d9ce..0f3bcb12 100644 --- a/AutoDuty/Helpers/TrustHelper.cs +++ b/AutoDuty/Helpers/TrustHelper.cs @@ -239,7 +239,7 @@ internal static unsafe void GetLevelsUpdate(IFramework framework) { if (EzThrottler.Throttle("OpenDawn", 5000)) { - Svc.Log.Debug("TrustHelper Helper - Opening Dawn"); + Svc.Log.Debug("TrustHelper - Opening Dawn"); AgentModule.Instance()->GetAgentByInternalId(AgentId.Dawn)->Show(); } return; @@ -249,19 +249,19 @@ internal static unsafe void GetLevelsUpdate(IFramework framework) if (addonDawn->AtkValues[225].UInt < (_getLevelsContent!.ExVersion - 2)) { - Svc.Log.Debug($"TrustHelper Helper - You do not have expansion: {_getLevelsContent.ExVersion} unlocked stopping"); + Svc.Log.Debug($"TrustHelper - You do not have expansion: {_getLevelsContent.ExVersion} unlocked stopping"); Stop(); return; } if (addonDawn->AtkValues[226].UInt != (_getLevelsContent!.ExVersion - 3)) { - Svc.Log.Debug($"TrustHelper Helper - Opening Expansion: {_getLevelsContent.ExVersion}"); + Svc.Log.Debug($"TrustHelper - Opening Expansion: {_getLevelsContent.ExVersion}"); AddonHelper.FireCallBack(addonDawn, true, 20, (_getLevelsContent!.ExVersion - 3)); } else if (addonDawn->AtkValues[151].UInt != _getLevelsContent.DawnIndex) { - Svc.Log.Debug($"TrustHelper Helper - Clicking: {_getLevelsContent.EnglishName} at index: {_getLevelsContent.DawnIndex}"); + Svc.Log.Debug($"TrustHelper - Clicking: {_getLevelsContent.EnglishName} at index: {_getLevelsContent.DawnIndex}"); AddonHelper.FireCallBack(addonDawn, true, 15, _getLevelsContent.DawnIndex); } else diff --git a/AutoDuty/Managers/ActionsManager.cs b/AutoDuty/Managers/ActionsManager.cs index 260c944d..bc59fce4 100644 --- a/AutoDuty/Managers/ActionsManager.cs +++ b/AutoDuty/Managers/ActionsManager.cs @@ -144,14 +144,14 @@ public void Rotation(string sts) _autoManageRotationPluginState = true; AutoDuty.Plugin.Configuration.AutoManageRotationPluginState = false; } - AutoDuty.Plugin.SetRotationPluginSettings(false); + AutoDuty.Plugin.SetRotationPluginSettings(false, true); } else if (sts.Equals("on", StringComparison.InvariantCultureIgnoreCase)) { if (_autoManageRotationPluginState) AutoDuty.Plugin.Configuration.AutoManageRotationPluginState = true; - AutoDuty.Plugin.SetRotationPluginSettings(true); + AutoDuty.Plugin.SetRotationPluginSettings(true, true); } }