diff --git a/QuestPathGenerator/QuestSourceGenerator.cs b/QuestPathGenerator/QuestSourceGenerator.cs index aa68436b1..616ad2f5d 100644 --- a/QuestPathGenerator/QuestSourceGenerator.cs +++ b/QuestPathGenerator/QuestSourceGenerator.cs @@ -297,6 +297,9 @@ public class QuestSourceGenerator : ISourceGenerator Assignment(nameof(QuestStep.TargetTerritoryId), step.TargetTerritoryId, emptyStep.TargetTerritoryId) .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.DelaySecondsAtStart), step.DelaySecondsAtStart, + emptyStep.DelaySecondsAtStart) + .AsSyntaxNodeOrToken(), Assignment(nameof(QuestStep.Disabled), step.Disabled, emptyStep.Disabled) .AsSyntaxNodeOrToken(), Assignment(nameof(QuestStep.DisableNavmesh), step.DisableNavmesh, diff --git a/QuestPaths/Endwalker/AetherCurrents/Thavnair/4203_Alchemist or Dancer.json b/QuestPaths/Endwalker/AetherCurrents/Thavnair/4203_Alchemist or Dancer.json index 17fc03509..a86ce80c7 100644 --- a/QuestPaths/Endwalker/AetherCurrents/Thavnair/4203_Alchemist or Dancer.json +++ b/QuestPaths/Endwalker/AetherCurrents/Thavnair/4203_Alchemist or Dancer.json @@ -68,7 +68,7 @@ null, null, null, - 32 + -32 ] }, { diff --git a/QuestPaths/Endwalker/MSQ/A-Thavnair1-Labyrinthos1/4361_A Labyrinthine Descent.json b/QuestPaths/Endwalker/MSQ/A-Thavnair1-Labyrinthos1/4361_A Labyrinthine Descent.json index f32f1c1a6..ffcbebb54 100644 --- a/QuestPaths/Endwalker/MSQ/A-Thavnair1-Labyrinthos1/4361_A Labyrinthine Descent.json +++ b/QuestPaths/Endwalker/MSQ/A-Thavnair1-Labyrinthos1/4361_A Labyrinthine Descent.json @@ -105,7 +105,8 @@ "Z": -209.40958 }, "TerritoryId": 962, - "InteractionType": "Interact" + "InteractionType": "WalkTo", + "Comment": "Should auto-trigger the next step once Alisaie is here" } ] }, diff --git a/QuestPaths/Endwalker/MSQ/A-Thavnair1-Labyrinthos1/4362_Glorified Ratcatcher.json b/QuestPaths/Endwalker/MSQ/A-Thavnair1-Labyrinthos1/4362_Glorified Ratcatcher.json index 6348c2308..2d3973d31 100644 --- a/QuestPaths/Endwalker/MSQ/A-Thavnair1-Labyrinthos1/4362_Glorified Ratcatcher.json +++ b/QuestPaths/Endwalker/MSQ/A-Thavnair1-Labyrinthos1/4362_Glorified Ratcatcher.json @@ -127,6 +127,15 @@ "InteractionType": "AttuneAetherCurrent", "AetherCurrentId": 2818314 }, + { + "Position": { + "X": 280.38452, + "Y": 216.34708, + "Z": -823.3921 + }, + "TerritoryId": 956, + "InteractionType": "WalkTo" + }, { "DataId": 1038701, "Position": { @@ -136,7 +145,8 @@ }, "TerritoryId": 956, "InteractionType": "UseItem", - "ItemId": 2003129 + "ItemId": 2003129, + "Mount": false } ] }, diff --git a/QuestPaths/Endwalker/MSQ/B-Garlemald/4384_Tracks in the Snow.json b/QuestPaths/Endwalker/MSQ/B-Garlemald/4384_Tracks in the Snow.json index ce1c7980c..1972e4bac 100644 --- a/QuestPaths/Endwalker/MSQ/B-Garlemald/4384_Tracks in the Snow.json +++ b/QuestPaths/Endwalker/MSQ/B-Garlemald/4384_Tracks in the Snow.json @@ -152,6 +152,149 @@ { "Sequence": 6, "Steps": [ + { + "DataId": 1038845, + "Position": { + "X": 156.66682, + "Y": -18.078814, + "Z": 361.58972 + }, + "TerritoryId": 958, + "InteractionType": "WaitForNpcAtPosition", + "NpcWaitDistance": 5, + "StopDistance": 100, + "Mount": false, + "Sprint": false + }, + { + "Position": { + "X": 204.82344, + "Y": -19.113703, + "Z": 373.52936 + }, + "TerritoryId": 958, + "InteractionType": "WalkTo", + "Mount": false, + "Sprint": false, + "DelaySecondsAtStart": 1 + }, + { + "DataId": 1038845, + "Position": { + "X": 232.28406, + "Y": -16.777779, + "Z": 339.1168 + }, + "TerritoryId": 958, + "InteractionType": "WaitForNpcAtPosition", + "NpcWaitDistance": 5, + "StopDistance": 100, + "Mount": false, + "Sprint": false + }, + { + "Position": { + "X": 272.79572, + "Y": -13.174152, + "Z": 317.53406 + }, + "TerritoryId": 958, + "InteractionType": "WalkTo", + "Mount": false, + "Sprint": false, + "DelaySecondsAtStart": 8 + }, + { + "DataId": 1038845, + "Position": { + "X": 287.9112, + "Y": -11.811615, + "Z": 292.6589 + }, + "TerritoryId": 958, + "InteractionType": "WaitForNpcAtPosition", + "NpcWaitDistance": 5, + "StopDistance": 100, + "Mount": false, + "Sprint": false + }, + { + "Position": { + "X": 323.9364, + "Y": -10.539692, + "Z": 254.19264 + }, + "TerritoryId": 958, + "InteractionType": "WalkTo", + "Mount": false, + "Sprint": false + }, + { + "DataId": 1038845, + "Position": { + "X": 354.5913, + "Y": -5.5008125, + "Z": 245.22939 + }, + "TerritoryId": 958, + "InteractionType": "WaitForNpcAtPosition", + "NpcWaitDistance": 5, + "StopDistance": 100, + "Mount": false, + "Sprint": false + }, + { + "Position": { + "X": 354.71964, + "Y": -2.2201555, + "Z": 233.99152 + }, + "TerritoryId": 958, + "InteractionType": "WalkTo", + "Mount": false, + "Sprint": false + }, + { + "DataId": 1038845, + "Position": { + "X": 382.75116, + "Y": 2.7549856, + "Z": 226.49387 + }, + "TerritoryId": 958, + "InteractionType": "WaitForNpcAtPosition", + "NpcWaitDistance": 5, + "StopDistance": 40, + "Mount": false, + "Sprint": false + }, + { + "DataId": 1038845, + "Position": { + "X": 408.44272, + "Y": 4.965298, + "Z": 208.22794 + }, + "TerritoryId": 958, + "InteractionType": "WalkTo", + "StopDistance": 45, + "Mount": false, + "Sprint": false + }, + { + "DataId": 1038845, + "Position": { + "X": 426.39246, + "Y": 5.348692, + "Z": 194.86263 + }, + "TerritoryId": 958, + "InteractionType": "WaitForNpcAtPosition", + "NpcWaitDistance": 5, + "StopDistance": 100, + "Mount": false, + "Sprint": false + }, { "DataId": 1038846, "Position": { @@ -160,7 +303,8 @@ "Z": 159.10571 }, "TerritoryId": 958, - "InteractionType": "WalkTo" + "InteractionType": "WalkTo", + "Mount": false } ] }, diff --git a/QuestPaths/quest-v1.json b/QuestPaths/quest-v1.json index e019e2f75..80c082a9f 100644 --- a/QuestPaths/quest-v1.json +++ b/QuestPaths/quest-v1.json @@ -387,6 +387,13 @@ "minItems": 6, "maxItems": 6 }, + "DelaySecondsAtStart": { + "description": "Time to wait before starting", + "type": [ + "number", + "null" + ] + }, "Comment": { "type": "string" } diff --git a/Questionable.Model/V1/QuestStep.cs b/Questionable.Model/V1/QuestStep.cs index d265df6da..936f7aae3 100644 --- a/Questionable.Model/V1/QuestStep.cs +++ b/Questionable.Model/V1/QuestStep.cs @@ -20,6 +20,7 @@ public sealed class QuestStep public float? NpcWaitDistance { get; set; } public ushort TerritoryId { get; set; } public ushort? TargetTerritoryId { get; set; } + public float? DelaySecondsAtStart { get; set; } public bool Disabled { get; set; } public bool DisableNavmesh { get; set; } diff --git a/Questionable/Controller/Steps/BaseFactory/WaitAtStart.cs b/Questionable/Controller/Steps/BaseFactory/WaitAtStart.cs new file mode 100644 index 000000000..5da57f6b4 --- /dev/null +++ b/Questionable/Controller/Steps/BaseFactory/WaitAtStart.cs @@ -0,0 +1,35 @@ +using System; +using Microsoft.Extensions.DependencyInjection; +using Questionable.Controller.Steps.BaseTasks; +using Questionable.Model; +using Questionable.Model.V1; + +namespace Questionable.Controller.Steps.BaseFactory; + +internal static class WaitAtStart +{ + internal sealed class Factory(IServiceProvider serviceProvider) : ITaskFactory + { + public ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step) + { + if (step.DelaySecondsAtStart == null) + return null; + + return serviceProvider.GetRequiredService() + .With(TimeSpan.FromSeconds(step.DelaySecondsAtStart.Value)); + } + } + + internal sealed class WaitDelay : AbstractDelayedTask + { + public ITask With(TimeSpan delay) + { + Delay = delay; + return this; + } + + protected override bool StartInternal() => true; + + public override string ToString() => $"Wait[S](seconds: {Delay.TotalSeconds})"; + } +} diff --git a/Questionable/Controller/Steps/BaseTasks/AbstractDelayedTask.cs b/Questionable/Controller/Steps/BaseTasks/AbstractDelayedTask.cs index b43ee953e..ed1e8506c 100644 --- a/Questionable/Controller/Steps/BaseTasks/AbstractDelayedTask.cs +++ b/Questionable/Controller/Steps/BaseTasks/AbstractDelayedTask.cs @@ -4,7 +4,6 @@ namespace Questionable.Controller.Steps.BaseTasks; internal abstract class AbstractDelayedTask : ITask { - protected readonly TimeSpan Delay; private DateTime _continueAt; protected AbstractDelayedTask(TimeSpan delay) @@ -12,6 +11,8 @@ internal abstract class AbstractDelayedTask : ITask Delay = delay; } + protected TimeSpan Delay { get; set; } + protected AbstractDelayedTask() : this(TimeSpan.FromSeconds(5)) {