Fix some Shaaloani/S9 pathing issues
authorLiza Carvelli <liza@carvel.li>
Fri, 20 Sep 2024 14:05:39 +0000 (16:05 +0200)
committerLiza Carvelli <liza@carvel.li>
Fri, 20 Sep 2024 14:05:39 +0000 (16:05 +0200)
QuestPaths/7.x - Dawntrail/Aether Currents/Shaaloani/5140_When the Bill Comes Due.json
QuestPaths/7.x - Dawntrail/MSQ/D-Shaaloani-HeritageFound1/4920_No Time for Tears.json
QuestPaths/7.x - Dawntrail/MSQ/E-SolutionNine-HeritageFound2/4932_Embracing Oblivion.json
QuestPaths/7.x - Dawntrail/MSQ/E-SolutionNine-HeritageFound2/4935_Her People, Her Family.json
QuestPaths/7.x - Dawntrail/MSQ/E-SolutionNine-HeritageFound2/4936_Scales of Blue.json
Questionable/Controller/Steps/Shared/AethernetShortcut.cs
Questionable/Controller/Steps/Shared/AetheryteShortcut.cs
Questionable/QuestionablePlugin.cs

index 912043e1885317712f0e8400941c29a12ba409b2..11ce3cd754ca50ca540ef4ded920ea0ea2353cdc 100644 (file)
@@ -59,7 +59,8 @@
           },
           "TerritoryId": 1190,
           "InteractionType": "WalkTo",
-          "$": "Shaaloani Hhusatahwi Saloon Stairs (top)"
+          "$": "Shaaloani Hhusatahwi Saloon Stairs (top)",
+          "Mount": true
         },
         {
           "Position": {
index 86985831010849939961be64c734c7eba85ab841..ff3a50003978b50832fb7b2aee8007d088b25af6 100644 (file)
     {
       "Sequence": 3,
       "Steps": [
+        {
+          "Position": {
+            "X": -163.63573,
+            "Y": 45.171337,
+            "Z": 12.003954
+          },
+          "TerritoryId": 1185,
+          "InteractionType": "WalkTo"
+        },
         {
           "DataId": 1047026,
           "Position": {
index 0bdf93e887e13ea279c3fb8ec0e3dd95b63ee33a..c7d817876829582138e18aa2cf5ff84306956511 100644 (file)
@@ -55,7 +55,8 @@
             "Z": 0.6866455
           },
           "TerritoryId": 1171,
-          "InteractionType": "Interact"
+          "InteractionType": "Interact",
+          "DelaySecondsAtStart": 3
         }
       ]
     },
index 9de8ecaee618cbf8597cf0d2b782bdca862d633b..033c17298ff6d56501c79454eaafd2b56f929a72 100644 (file)
             "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,
index b80cade47a6f27ff9eb5dc16214bfbac1199a6b5..831ad35602fcdb7dd563b62a88d14e422d24e265 100644 (file)
@@ -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
         }
       ]
     },
index bb39bd8154b826e5df7f3958b699d712b41d10f9..a1a066f0840702e878ff38a5b757828473c069f0 100644 (file)
@@ -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<ITask> 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);
index c059df46f3943034359e403495e876f5d5cf6869..7f2a8fd0304422b3a7068f19e71b12a14fbca11a 100644 (file)
@@ -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<ITask> 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<MoveAwayFromAetheryte>
+    {
+        private static readonly Dictionary<EAetheryteLocation, List<Vector3>> 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();
+    }
 }
index 47b5cb96c1d5dbcf35213270dc4fada6ee142581..acee9943690a5a77ded647677b790cf8933a0b67 100644 (file)
@@ -129,7 +129,8 @@ public sealed class QuestionablePlugin : IDalamudPlugin
     private static void AddTaskFactories(ServiceCollection serviceCollection)
     {
         // individual tasks
-        serviceCollection.AddTaskExecutor<MoveToLandingLocation.Task, MoveToLandingLocation.MoveToLandingLocationExecutor>();
+        serviceCollection
+            .AddTaskExecutor<MoveToLandingLocation.Task, MoveToLandingLocation.MoveToLandingLocationExecutor>();
         serviceCollection.AddTaskExecutor<DoGather.Task, DoGather.GatherExecutor>();
         serviceCollection.AddTaskExecutor<DoGatherCollectable.Task, DoGatherCollectable.GatherCollectableExecutor>();
         serviceCollection.AddTaskExecutor<SwitchClassJob.Task, SwitchClassJob.SwitchClassJobExecutor>();
@@ -138,13 +139,16 @@ public sealed class QuestionablePlugin : IDalamudPlugin
 
         // task factories
         serviceCollection
-            .AddTaskFactoryAndExecutor<StepDisabled.SkipRemainingTasks, StepDisabled.Factory, StepDisabled.SkipDisabledStepsExecutor>();
+            .AddTaskFactoryAndExecutor<StepDisabled.SkipRemainingTasks, StepDisabled.Factory,
+                StepDisabled.SkipDisabledStepsExecutor>();
         serviceCollection.AddTaskFactory<EquipRecommended.BeforeDutyOrInstance>();
         serviceCollection.AddTaskFactoryAndExecutor<Gather.GatheringTask, Gather.Factory, Gather.StartGathering>();
         serviceCollection.AddTaskExecutor<Gather.SkipMarker, Gather.DoSkip>();
         serviceCollection
             .AddTaskFactoryAndExecutor<AetheryteShortcut.Task, AetheryteShortcut.Factory,
                 AetheryteShortcut.UseAetheryteShortcut>();
+        serviceCollection
+            .AddTaskExecutor<AetheryteShortcut.MoveAwayFromAetheryte, AetheryteShortcut.MoveAwayFromAetheryteExecutor>();
         serviceCollection
             .AddTaskFactoryAndExecutor<SkipCondition.SkipTask, SkipCondition.Factory, SkipCondition.CheckSkip>();
         serviceCollection
@@ -156,7 +160,8 @@ public sealed class QuestionablePlugin : IDalamudPlugin
         serviceCollection.AddTaskExecutor<MoveTo.WaitForNearDataId, MoveTo.WaitForNearDataIdExecutor>();
         serviceCollection.AddTaskExecutor<MoveTo.LandTask, MoveTo.LandExecutor>();
 
-        serviceCollection.AddTaskFactoryAndExecutor<NextQuest.SetQuestTask, NextQuest.Factory, NextQuest.NextQuestExecutor>();
+        serviceCollection
+            .AddTaskFactoryAndExecutor<NextQuest.SetQuestTask, NextQuest.Factory, NextQuest.NextQuestExecutor>();
         serviceCollection
             .AddTaskFactoryAndExecutor<AetherCurrent.Attune, AetherCurrent.Factory, AetherCurrent.DoAttune>();
         serviceCollection
@@ -189,7 +194,8 @@ public sealed class QuestionablePlugin : IDalamudPlugin
                 TurnInDelivery.SatisfactionSupplyTurnIn>();
 
         serviceCollection.AddTaskFactory<InitiateLeve.Factory>();
-        serviceCollection.AddTaskExecutor<InitiateLeve.SkipInitiateIfActive, InitiateLeve.SkipInitiateIfActiveExecutor>();
+        serviceCollection
+            .AddTaskExecutor<InitiateLeve.SkipInitiateIfActive, InitiateLeve.SkipInitiateIfActiveExecutor>();
         serviceCollection.AddTaskExecutor<InitiateLeve.OpenJournal, InitiateLeve.OpenJournalExecutor>();
         serviceCollection.AddTaskExecutor<InitiateLeve.Initiate, InitiateLeve.InitiateExecutor>();
         serviceCollection.AddTaskExecutor<InitiateLeve.SelectDifficulty, InitiateLeve.SelectDifficultyExecutor>();