diff --git a/GatheringPathRenderer/Windows/EditorWindow.cs b/GatheringPathRenderer/Windows/EditorWindow.cs index 5da1bf04c..55f9a5c20 100644 --- a/GatheringPathRenderer/Windows/EditorWindow.cs +++ b/GatheringPathRenderer/Windows/EditorWindow.cs @@ -66,7 +66,7 @@ internal sealed class EditorWindow : Window _target = _targetManager.Target; var gatheringLocations = _plugin.GetLocationsInTerritory(_clientState.TerritoryType); - var location = gatheringLocations.SelectMany(context => + var location = gatheringLocations.ToList().SelectMany(context => context.Root.Groups.SelectMany(group => group.Nodes.SelectMany(node => node.Locations .Select(location => diff --git a/Questionable/Controller/GatheringController.cs b/Questionable/Controller/GatheringController.cs index 52541c091..f97a9b37e 100644 --- a/Questionable/Controller/GatheringController.cs +++ b/Questionable/Controller/GatheringController.cs @@ -167,7 +167,7 @@ internal sealed unsafe class GatheringController : MiniTaskController GetRemainingTaskNames() { - if (_taskQueue.CurrentTaskExecutor?.CurrentTask is {} currentTask) + if (_taskQueue.CurrentTaskExecutor?.CurrentTask is { } currentTask) return [currentTask.ToString() ?? "?", .. base.GetRemainingTaskNames()]; else return base.GetRemainingTaskNames(); diff --git a/Questionable/Controller/Steps/Gathering/MoveToLandingLocation.cs b/Questionable/Controller/Steps/Gathering/MoveToLandingLocation.cs index 048bd2080..14552c213 100644 --- a/Questionable/Controller/Steps/Gathering/MoveToLandingLocation.cs +++ b/Questionable/Controller/Steps/Gathering/MoveToLandingLocation.cs @@ -8,6 +8,7 @@ using Questionable.Controller.Steps.Shared; using Questionable.Functions; using Questionable.Model; using Questionable.Model.Gathering; +using Questionable.Model.Questing; namespace Questionable.Controller.Steps.Gathering; @@ -50,7 +51,8 @@ internal static class MoveToLandingLocation bool fly = Task.FlyBetweenNodes && gameFunctions.IsFlyingUnlocked(Task.TerritoryId); _moveTask = new MoveTo.MoveTask(Task.TerritoryId, target, null, 0.25f, - DataId: Task.GatheringNode.DataId, Fly: fly, IgnoreDistanceToObject: true); + DataId: Task.GatheringNode.DataId, Fly: fly, IgnoreDistanceToObject: true, + InteractionType: EInteractionType.Gather); return moveExecutor.Start(_moveTask); } diff --git a/Questionable/Controller/Steps/Interactions/UseItem.cs b/Questionable/Controller/Steps/Interactions/UseItem.cs index ccdb998d0..e0753758e 100644 --- a/Questionable/Controller/Steps/Interactions/UseItem.cs +++ b/Questionable/Controller/Steps/Interactions/UseItem.cs @@ -62,7 +62,8 @@ internal static class UseItem nextPosition != null ? Mount.EMountIf.AwayFromPosition : Mount.EMountIf.Always, nextPosition), new MoveTo.MoveTask(140, new(-408.92343f, 23.167036f, -351.16223f), null, 0.25f, - DataId: null, DisableNavmesh: true, Sprint: false, Fly: false) + DataId: null, DisableNavmesh: true, Sprint: false, Fly: false, + InteractionType: EInteractionType.WalkTo) ]; } @@ -105,7 +106,8 @@ internal static class UseItem yield return new AetheryteShortcut.Task(null, null, EAetheryteLocation.Limsa, territoryId); yield return new AethernetShortcut.Task(EAetheryteLocation.Limsa, EAetheryteLocation.LimsaArcanist); yield return new WaitAtEnd.WaitDelay(); - yield return new MoveTo.MoveTask(territoryId, destination, DataId: npcId, Sprint: false); + yield return new MoveTo.MoveTask(territoryId, destination, DataId: npcId, Sprint: false, + InteractionType: EInteractionType.WalkTo); yield return new Interact.Task(npcId, null, EInteractionType.None, true); } } diff --git a/Questionable/Controller/Steps/Shared/MoveTo.cs b/Questionable/Controller/Steps/Shared/MoveTo.cs index 2f7a8ea34..92aa6d073 100644 --- a/Questionable/Controller/Steps/Shared/MoveTo.cs +++ b/Questionable/Controller/Steps/Shared/MoveTo.cs @@ -36,7 +36,7 @@ internal static class MoveTo { if (step.Position != null) { - return CreateMountTasks(quest.Id, step, step.Position.Value); + return CreateMoveTasks(step, step.Position.Value); } else if (step is { DataId: not null, StopDistance: not null }) { @@ -44,17 +44,17 @@ internal static class MoveTo } else if (step is { InteractionType: EInteractionType.AttuneAetheryte, Aetheryte: not null }) { - return CreateMountTasks(quest.Id, step, aetheryteData.Locations[step.Aetheryte.Value]); + return CreateMoveTasks(step, aetheryteData.Locations[step.Aetheryte.Value]); } else if (step is { InteractionType: EInteractionType.AttuneAethernetShard, AethernetShard: not null }) { - return CreateMountTasks(quest.Id, step, aetheryteData.Locations[step.AethernetShard.Value]); + return CreateMoveTasks(step, aetheryteData.Locations[step.AethernetShard.Value]); } return []; } - public IEnumerable CreateMountTasks(ElementId questId, QuestStep step, Vector3 destination) + private IEnumerable CreateMoveTasks(QuestStep step, Vector3 destination) { if (step.InteractionType == EInteractionType.Jump && step.JumpDestination != null && (clientState.LocalPlayer!.Position - step.JumpDestination.Position).Length() <= @@ -71,13 +71,9 @@ internal static class MoveTo { yield return new WaitCondition.Task(() => movementController.IsNavmeshReady, "Wait(navmesh ready)"); + } - yield return new MoveTask(step, destination); - } - else - { - yield return new MoveTask(step, destination); - } + yield return new MoveTask(step, destination); if (step is { Fly: true, Land: true }) yield return new LandTask(); @@ -94,7 +90,7 @@ internal static class MoveTo private readonly Mount.MountExecutor _mountExecutor; private readonly Mount.UnmountExecutor _unmountExecutor; - private Action _startAction = null!; + private Action? _startAction; private Vector3 _destination; private bool _canRestart; private ITaskExecutor? _nestedExecutor; @@ -115,13 +111,10 @@ internal static class MoveTo _mountExecutor = mountExecutor; _unmountExecutor = unmountExecutor; _cannotExecuteAtThisTime = dataManager.GetString(579, x => x.Text)!; - } - private void Initialize() + private void PrepareMovementIfNeeded() { - _destination = Task.Destination; - if (!_gameFunctions.IsFlyingUnlocked(Task.TerritoryId)) { Task = Task with { Fly = false, Land = false }; @@ -147,18 +140,22 @@ internal static class MoveTo ignoreDistanceToObject: Task.IgnoreDistanceToObject, land: Task.Land); } - - _canRestart = Task.RestartNavigation; } protected override bool Start() { - Initialize(); + _canRestart = Task.RestartNavigation; + _destination = Task.Destination; + float stopDistance = Task.StopDistance ?? QuestStep.DefaultStopDistance; Vector3? position = _clientState.LocalPlayer?.Position; float actualDistance = position == null ? float.MaxValue : Vector3.Distance(position.Value, _destination); + bool requiresMovement = actualDistance > stopDistance; + if (requiresMovement) + PrepareMovementIfNeeded(); + // might be able to make this optional if (Task.Mount == true) { var mountTask = new Mount.MountTask(Task.TerritoryId, Mount.EMountIf.Always); @@ -207,13 +204,21 @@ internal static class MoveTo if (_nestedExecutor.Update() == ETaskResult.TaskComplete) { _nestedExecutor = null; - - _logger.LogInformation("Moving to {Destination}", _destination.ToString("G", CultureInfo.InvariantCulture)); - _startAction(); + if (_startAction != null) + { + _logger.LogInformation("Moving to {Destination}", + _destination.ToString("G", CultureInfo.InvariantCulture)); + _startAction(); + } + else + return ETaskResult.TaskComplete; } return ETaskResult.StillRunning; } + if (_startAction == null) + return ETaskResult.TaskComplete; + if (_movementController.IsPathfinding || _movementController.IsPathRunning) return ETaskResult.StillRunning; @@ -268,7 +273,8 @@ internal static class MoveTo bool Fly = false, bool Land = false, bool IgnoreDistanceToObject = false, - bool RestartNavigation = true) : ITask + bool RestartNavigation = true, + EInteractionType InteractionType = EInteractionType.None) : ITask { public MoveTask(QuestStep step, Vector3 destination) : this(step.TerritoryId, @@ -281,7 +287,8 @@ internal static class MoveTo step.Fly == true, step.Land == true, step.IgnoreDistanceToObject == true, - step.RestartNavigationIfCancelled != false) + step.RestartNavigationIfCancelled != false, + step.InteractionType) { }