diff --git a/QuestPaths/7.x - Dawntrail/Aether Currents/Shaaloani/5140_When the Bill Comes Due.json b/QuestPaths/7.x - Dawntrail/Aether Currents/Shaaloani/5140_When the Bill Comes Due.json index 912043e18..11ce3cd75 100644 --- a/QuestPaths/7.x - Dawntrail/Aether Currents/Shaaloani/5140_When the Bill Comes Due.json +++ b/QuestPaths/7.x - Dawntrail/Aether Currents/Shaaloani/5140_When the Bill Comes Due.json @@ -59,7 +59,8 @@ }, "TerritoryId": 1190, "InteractionType": "WalkTo", - "$": "Shaaloani Hhusatahwi Saloon Stairs (top)" + "$": "Shaaloani Hhusatahwi Saloon Stairs (top)", + "Mount": true }, { "Position": { diff --git a/QuestPaths/7.x - Dawntrail/MSQ/D-Shaaloani-HeritageFound1/4920_No Time for Tears.json b/QuestPaths/7.x - Dawntrail/MSQ/D-Shaaloani-HeritageFound1/4920_No Time for Tears.json index 869858310..ff3a50003 100644 --- a/QuestPaths/7.x - Dawntrail/MSQ/D-Shaaloani-HeritageFound1/4920_No Time for Tears.json +++ b/QuestPaths/7.x - Dawntrail/MSQ/D-Shaaloani-HeritageFound1/4920_No Time for Tears.json @@ -137,6 +137,15 @@ { "Sequence": 3, "Steps": [ + { + "Position": { + "X": -163.63573, + "Y": 45.171337, + "Z": 12.003954 + }, + "TerritoryId": 1185, + "InteractionType": "WalkTo" + }, { "DataId": 1047026, "Position": { diff --git a/QuestPaths/7.x - Dawntrail/MSQ/E-SolutionNine-HeritageFound2/4932_Embracing Oblivion.json b/QuestPaths/7.x - Dawntrail/MSQ/E-SolutionNine-HeritageFound2/4932_Embracing Oblivion.json index 0bdf93e88..c7d817876 100644 --- a/QuestPaths/7.x - Dawntrail/MSQ/E-SolutionNine-HeritageFound2/4932_Embracing Oblivion.json +++ b/QuestPaths/7.x - Dawntrail/MSQ/E-SolutionNine-HeritageFound2/4932_Embracing Oblivion.json @@ -55,7 +55,8 @@ "Z": 0.6866455 }, "TerritoryId": 1171, - "InteractionType": "Interact" + "InteractionType": "Interact", + "DelaySecondsAtStart": 3 } ] }, diff --git a/QuestPaths/7.x - Dawntrail/MSQ/E-SolutionNine-HeritageFound2/4935_Her People, Her Family.json b/QuestPaths/7.x - Dawntrail/MSQ/E-SolutionNine-HeritageFound2/4935_Her People, Her Family.json index 9de8ecaee..033c17298 100644 --- a/QuestPaths/7.x - Dawntrail/MSQ/E-SolutionNine-HeritageFound2/4935_Her People, Her Family.json +++ b/QuestPaths/7.x - Dawntrail/MSQ/E-SolutionNine-HeritageFound2/4935_Her People, Her Family.json @@ -44,12 +44,14 @@ "Z": -117.162285 }, "TerritoryId": 1186, - "InteractionType": "WalkTo" + "InteractionType": "WalkTo", + "RestartNavigationIfCancelled": false }, { "TerritoryId": 1186, "InteractionType": "AttuneAethernetShard", - "AethernetShard": "[Solution Nine] Resolution" + "AethernetShard": "[Solution Nine] Resolution", + "DelaySecondsAtStart": 2 }, { "DataId": 1048073, diff --git a/QuestPaths/7.x - Dawntrail/MSQ/E-SolutionNine-HeritageFound2/4936_Scales of Blue.json b/QuestPaths/7.x - Dawntrail/MSQ/E-SolutionNine-HeritageFound2/4936_Scales of Blue.json index b80cade47..831ad3560 100644 --- a/QuestPaths/7.x - Dawntrail/MSQ/E-SolutionNine-HeritageFound2/4936_Scales of Blue.json +++ b/QuestPaths/7.x - Dawntrail/MSQ/E-SolutionNine-HeritageFound2/4936_Scales of Blue.json @@ -27,7 +27,8 @@ "Z": 5.1162424 }, "TerritoryId": 1186, - "InteractionType": "WalkTo" + "InteractionType": "WalkTo", + "RestartNavigationIfCancelled": false }, { "DataId": 1048172, @@ -37,7 +38,8 @@ "Z": 9.201172 }, "TerritoryId": 1186, - "InteractionType": "Interact" + "InteractionType": "Interact", + "DelaySecondsAtStart": 2 } ] }, diff --git a/Questionable/Controller/Steps/Shared/AethernetShortcut.cs b/Questionable/Controller/Steps/Shared/AethernetShortcut.cs index bb39bd815..a1a066f08 100644 --- a/Questionable/Controller/Steps/Shared/AethernetShortcut.cs +++ b/Questionable/Controller/Steps/Shared/AethernetShortcut.cs @@ -19,7 +19,11 @@ namespace Questionable.Controller.Steps.Shared; internal static class AethernetShortcut { - internal sealed class Factory(MovementController movementController) + internal sealed class Factory( + MovementController movementController, + AetheryteData aetheryteData, + TerritoryData territoryData, + IClientState clientState) : ITaskFactory { public IEnumerable CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step) @@ -31,6 +35,14 @@ internal static class AethernetShortcut "Wait(navmesh ready)"); yield return new Task(step.AethernetShortcut.From, step.AethernetShortcut.To, step.SkipConditions?.AethernetShortcutIf ?? new()); + + if (AetheryteShortcut.MoveAwayFromAetheryteExecutor.AppliesTo(step.AethernetShortcut.To)) + { + yield return new WaitCondition.Task( + () => clientState.TerritoryType == aetheryteData.TerritoryIds[step.AethernetShortcut.To], + $"Wait(territory: {territoryData.GetNameAndId(aetheryteData.TerritoryIds[step.AethernetShortcut.To])})"); + yield return new AetheryteShortcut.MoveAwayFromAetheryte(step.AethernetShortcut.To); + } } } @@ -142,7 +154,7 @@ internal static class AethernetShortcut new(0, 8.442986f, -9), ]; - Vector3 closestPoint = nearbyPoints.MinBy(x => (playerPosition - x).Length()); + Vector3 closestPoint = nearbyPoints.MinBy(x => Vector3.Distance(playerPosition, x)); _moving = true; movementController.NavigateTo(EMovementType.Quest, (uint)Task.From, closestPoint, false, true, 0.25f); diff --git a/Questionable/Controller/Steps/Shared/AetheryteShortcut.cs b/Questionable/Controller/Steps/Shared/AetheryteShortcut.cs index c059df46f..7f2a8fd03 100644 --- a/Questionable/Controller/Steps/Shared/AetheryteShortcut.cs +++ b/Questionable/Controller/Steps/Shared/AetheryteShortcut.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Numerics; using Dalamud.Plugin.Services; using Microsoft.Extensions.Logging; +using Questionable.Controller.Steps.Common; using Questionable.Controller.Utils; using Questionable.Data; using Questionable.Functions; @@ -15,7 +17,8 @@ namespace Questionable.Controller.Steps.Shared; internal static class AetheryteShortcut { - internal sealed class Factory(AetheryteData aetheryteData) : ITaskFactory + internal sealed class Factory(AetheryteData aetheryteData, TerritoryData territoryData, IClientState clientState) + : ITaskFactory { public IEnumerable CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step) { @@ -25,6 +28,15 @@ internal static class AetheryteShortcut yield return new Task(step, quest.Id, step.AetheryteShortcut.Value, aetheryteData.TerritoryIds[step.AetheryteShortcut.Value]); yield return new WaitAtEnd.WaitDelay(TimeSpan.FromSeconds(0.5)); + + if (MoveAwayFromAetheryteExecutor.AppliesTo(step.AetheryteShortcut.Value) && + step.AethernetShortcut?.From != step.AetheryteShortcut.Value) + { + yield return new WaitCondition.Task( + () => clientState.TerritoryType == aetheryteData.TerritoryIds[step.AetheryteShortcut.Value], + $"Wait(territory: {territoryData.GetNameAndId(aetheryteData.TerritoryIds[step.AetheryteShortcut.Value])})"); + yield return new MoveAwayFromAetheryte(step.AetheryteShortcut.Value); + } } } @@ -206,4 +218,47 @@ internal static class AetheryteShortcut } } } + + internal sealed record MoveAwayFromAetheryte(EAetheryteLocation TargetAetheryte) : ITask + { + public override string ToString() => $"MoveAway({TargetAetheryte})"; + } + + internal sealed class MoveAwayFromAetheryteExecutor( + MoveTo.MoveExecutor moveExecutor, + AetheryteData aetheryteData, + IClientState clientState) : TaskExecutor + { + private static readonly Dictionary> AetherytesToMoveFrom = new() + { + { + EAetheryteLocation.SolutionNine, + [ + new(0f, 8.8f, 15.5f), + new(0f, 8.8f, -15.5f), + new(15.5f, 8.8f, 0f), + new(-15.5f, 8.8f, 0f) + ] + } + }; + + public static bool AppliesTo(EAetheryteLocation location) => AetherytesToMoveFrom.ContainsKey(location); + + protected override bool Start() + { + // only relevant if we're actually near the s9 aetheryte at the end + Vector3 playerPosition = clientState.LocalPlayer!.Position; + if (aetheryteData.CalculateDistance(playerPosition, clientState.TerritoryType, Task.TargetAetheryte) >= 20) + return false; + + Vector3 closestPoint = AetherytesToMoveFrom[Task.TargetAetheryte] + .MinBy(x => Vector3.Distance(x, playerPosition)); + MoveTo.MoveTask task = new MoveTo.MoveTask(aetheryteData.TerritoryIds[Task.TargetAetheryte], + closestPoint, Mount: false, StopDistance: 0.25f, DisableNavmesh: true, + InteractionType: EInteractionType.None, RestartNavigation: false); + return moveExecutor.Start(task); + } + + public override ETaskResult Update() => moveExecutor.Update(); + } } diff --git a/Questionable/QuestionablePlugin.cs b/Questionable/QuestionablePlugin.cs index 47b5cb96c..acee99436 100644 --- a/Questionable/QuestionablePlugin.cs +++ b/Questionable/QuestionablePlugin.cs @@ -129,7 +129,8 @@ public sealed class QuestionablePlugin : IDalamudPlugin private static void AddTaskFactories(ServiceCollection serviceCollection) { // individual tasks - serviceCollection.AddTaskExecutor(); + serviceCollection + .AddTaskExecutor(); serviceCollection.AddTaskExecutor(); serviceCollection.AddTaskExecutor(); serviceCollection.AddTaskExecutor(); @@ -138,13 +139,16 @@ public sealed class QuestionablePlugin : IDalamudPlugin // task factories serviceCollection - .AddTaskFactoryAndExecutor(); + .AddTaskFactoryAndExecutor(); serviceCollection.AddTaskFactory(); serviceCollection.AddTaskFactoryAndExecutor(); serviceCollection.AddTaskExecutor(); serviceCollection .AddTaskFactoryAndExecutor(); + serviceCollection + .AddTaskExecutor(); serviceCollection .AddTaskFactoryAndExecutor(); serviceCollection @@ -156,7 +160,8 @@ public sealed class QuestionablePlugin : IDalamudPlugin serviceCollection.AddTaskExecutor(); serviceCollection.AddTaskExecutor(); - serviceCollection.AddTaskFactoryAndExecutor(); + serviceCollection + .AddTaskFactoryAndExecutor(); serviceCollection .AddTaskFactoryAndExecutor(); serviceCollection @@ -189,7 +194,8 @@ public sealed class QuestionablePlugin : IDalamudPlugin TurnInDelivery.SatisfactionSupplyTurnIn>(); serviceCollection.AddTaskFactory(); - serviceCollection.AddTaskExecutor(); + serviceCollection + .AddTaskExecutor(); serviceCollection.AddTaskExecutor(); serviceCollection.AddTaskExecutor(); serviceCollection.AddTaskExecutor();