Update gathering from 'RequiredGatheredItems' to a dedicated InteractionType; updated...
authorLiza Carvelli <liza@carvel.li>
Mon, 16 Sep 2024 18:22:12 +0000 (20:22 +0200)
committerLiza Carvelli <liza@carvel.li>
Mon, 16 Sep 2024 18:22:12 +0000 (20:22 +0200)
93 files changed:
QuestPathGenerator/RoslynElements/QuestStepExtensions.cs
QuestPaths/2.x - A Realm Reborn/Class Quests/MIN/599_My First Pickaxe.json
QuestPaths/2.x - A Realm Reborn/Class Quests/MIN/600_Know Thy Land.json
QuestPaths/3.x - Heavensward/Custom Deliveries/Zhloe/S1_Zhloe Aliapoh.json
QuestPaths/4.x - Stormblood/Class Quests/BTN/2622_Walking for Walker's.json
QuestPaths/4.x - Stormblood/Class Quests/BTN/2623_The White Death.json
QuestPaths/4.x - Stormblood/Class Quests/BTN/2624_Edgyth's Winning Streak.json
QuestPaths/4.x - Stormblood/Custom Deliveries/Adkiragh/S4_Adkiragh.json
QuestPaths/4.x - Stormblood/Custom Deliveries/Kurenai/S3_Kurenai.json
QuestPaths/4.x - Stormblood/Custom Deliveries/M'naago/S2_M'naago.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Dailies/3806_A Tool's Errand.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Dailies/3807_Where the Sun Don't Shine.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Dailies/3808_A Touch of Home.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Dailies/3809_Mother's Recipe.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Dailies/3810_Power to the Vegetables.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Dailies/3811_Rational Thinking.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Dailies/3812_Making Scents.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Dailies/3814_Prayers and Poison.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Dailies/3815_Salve Our Souls.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Dailies/3816_Rings of Pattern.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Dailies/3817_You Dirty Rats.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Dailies/3818_If It's Broke, Fix It.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Dailies/3820_The Qitari Book of Records.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Dailies/3821_Meat and Greet.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Dailies/3822_I Have Never Exploded.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Dailies/3824_Rock 'n Ronka.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Dailies/3825_There's No Clean Like Qhoterl Clean.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Dailies/3827_Her Splendid Materials.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Dailies/3828_Splendid Eats.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Dailies/3830_Safety Is No Accident.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Dailies/3831_One Fish, Two Fish, Bread Fish, Stew Fish.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Dailies/3832_Serpent's Will Be Done.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Dailies/3833_Qhoterl's Chronicles.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Story/3794_The Stewards of Note.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Qitari/Story/3795_Wisdom of the Night.json
QuestPaths/5.x - Shadowbringers/Custom Deliveries/Kai-Shirr/S5_Kai-Shirr.json
QuestPaths/6.x - Endwalker/Allied Societies/Omicrons/Dailies/4607_Signs of the Past.json
QuestPaths/6.x - Endwalker/Allied Societies/Omicrons/Dailies/4609_Well Below Standard.json
QuestPaths/6.x - Endwalker/Allied Societies/Omicrons/Dailies/4611_Grounds for Improvement.json
QuestPaths/6.x - Endwalker/Allied Societies/Omicrons/Dailies/4612_A Fertile Blend.json
QuestPaths/6.x - Endwalker/Allied Societies/Omicrons/Dailies/4614_The Robot and the Sea.json
QuestPaths/6.x - Endwalker/Allied Societies/Omicrons/Dailies/4615_Using Their Heads.json
QuestPaths/6.x - Endwalker/Allied Societies/Omicrons/Dailies/4617_I'll Fish It Myself.json
QuestPaths/6.x - Endwalker/Allied Societies/Omicrons/Dailies/4620_A Taste of the Sea.json
QuestPaths/6.x - Endwalker/Allied Societies/Omicrons/Dailies/4622_Ea Epicurious.json
QuestPaths/6.x - Endwalker/Allied Societies/Omicrons/Dailies/4623_I, Omicron.json
QuestPaths/6.x - Endwalker/Allied Societies/Omicrons/Dailies/4625_Corporeal Hand to Proverbial Mouth.json
QuestPaths/6.x - Endwalker/Allied Societies/Omicrons/Dailies/4626_Mush for Miw Miisv.json
QuestPaths/6.x - Endwalker/Allied Societies/Omicrons/Dailies/4627_Corporeal Comforts.json
QuestPaths/6.x - Endwalker/Allied Societies/Omicrons/Dailies/4629_A Light in the Dark.json
QuestPaths/6.x - Endwalker/Allied Societies/Omicrons/Dailies/4630_Reclaiming the Taste of Home.json
QuestPaths/6.x - Endwalker/Allied Societies/Omicrons/Dailies/4631_Not Forgotten.json
QuestPaths/6.x - Endwalker/Allied Societies/Omicrons/Dailies/4632_Checking for Cavities.json
QuestPaths/6.x - Endwalker/Allied Societies/Omicrons/Dailies/4634_The Lost World.json
QuestPaths/6.x - Endwalker/Allied Societies/Omicrons/Story/4601_The Café at the End of the Universe.json
QuestPaths/6.x - Endwalker/Allied Societies/Omicrons/Story/4602_Longing So for All the Fish.json
QuestPaths/6.x - Endwalker/Allied Societies/Omicrons/Story/4603_And Another Question.json
QuestPaths/6.x - Endwalker/Allied Societies/Omicrons/Story/4604_The Restaurateur's Guide to the Dragonstar.json
QuestPaths/6.x - Endwalker/Allied Societies/Omicrons/Story/4605_Mostly Heartless.json
QuestPaths/6.x - Endwalker/Custom Deliveries/Ameliance/S8_Ameliance.json
QuestPaths/6.x - Endwalker/Custom Deliveries/Anden/S9_Anden.json
QuestPaths/6.x - Endwalker/Custom Deliveries/Margrat/S10_Margrat.json
QuestPaths/6.x - Endwalker/Custom Deliveries/Studium/MIN, BTN/4154_Cooking Up a Culture.json
QuestPaths/6.x - Endwalker/Custom Deliveries/Studium/MIN, BTN/4155_The Culture of Ceruleum.json
QuestPaths/6.x - Endwalker/Custom Deliveries/Studium/MIN, BTN/4156_The Culture of Carrots.json
QuestPaths/6.x - Endwalker/Custom Deliveries/Studium/MIN, BTN/4157_Hinageshi in Hingashi.json
QuestPaths/6.x - Endwalker/Custom Deliveries/Studium/MIN, BTN/4158_The Culture of the Past.json
QuestPaths/6.x - Endwalker/Custom Deliveries/Studium/MIN, BTN/4159_The Culture of Love.json
QuestPaths/7.x - Dawntrail/Custom Deliveries/Wachumeqimeqi/MIN, BTN/4990_Test of Talents.json
QuestPaths/7.x - Dawntrail/Custom Deliveries/Wachumeqimeqi/MIN, BTN/4991_A Discerning Eye.json
QuestPaths/7.x - Dawntrail/Custom Deliveries/Wachumeqimeqi/MIN, BTN/4992_As Nature Intends.json
QuestPaths/7.x - Dawntrail/Custom Deliveries/Wachumeqimeqi/MIN, BTN/4993_The Cycle of Life.json
QuestPaths/7.x - Dawntrail/Custom Deliveries/Wachumeqimeqi/MIN, BTN/4994_Digging Up the Truth.json
QuestPaths/7.x - Dawntrail/Custom Deliveries/Wachumeqimeqi/MIN, BTN/4995_Wellspring of Tears.json
QuestPaths/7.x - Dawntrail/Leves/BTN/L1770_All Stars.json
QuestPaths/7.x - Dawntrail/Leves/BTN/L1779_New Start for the Cinderfield.json
QuestPaths/7.x - Dawntrail/Leves/MIN/L1785_Old and Bubbly.json
QuestPaths/7.x - Dawntrail/Leves/MIN/L1794_Vestiges of War.json
QuestPaths/quest-v1.json
Questionable.Model/Questing/Converter/InteractionTypeConverter.cs
Questionable.Model/Questing/EInteractionType.cs
Questionable.Model/Questing/QuestStep.cs
Questionable/Controller/ContextMenuController.cs
Questionable/Controller/GameUi/InteractionUiController.cs
Questionable/Controller/GatheringController.cs
Questionable/Controller/MiniTaskController.cs
Questionable/Controller/Steps/Gathering/MoveToLandingLocation.cs
Questionable/Controller/Steps/Interactions/Interact.cs
Questionable/Controller/Steps/Interactions/UseItem.cs
Questionable/Controller/Steps/Shared/Gather.cs [new file with mode: 0644]
Questionable/Controller/Steps/Shared/GatheringRequiredItems.cs [deleted file]
Questionable/Controller/Steps/Shared/MoveTo.cs
Questionable/QuestionablePlugin.cs

index e5b8eabb9e27875b15163fc9f8e71ec666cecac1..6aca708aea96edafea4d79871840385a21518cc5 100644 (file)
@@ -118,8 +118,8 @@ internal static class QuestStepExtensions
                             AssignmentList(nameof(QuestStep.RequiredQuestVariables),
                                     step.RequiredQuestVariables)
                                 .AsSyntaxNodeOrToken(),
-                            AssignmentList(nameof(QuestStep.RequiredGatheredItems),
-                                step.RequiredGatheredItems),
+                            AssignmentList(nameof(QuestStep.ItemsToGather),
+                                step.ItemsToGather),
                             AssignmentList(nameof(QuestStep.CompletionQuestVariablesFlags),
                                     step.CompletionQuestVariablesFlags)
                                 .AsSyntaxNodeOrToken(),
index 07dd8fbf14e1d4742b098c273c3b812ee6e9f239..feff763bdf10f5bd8036c5b0d52264ce2276ac16 100644 (file)
     {
       "Sequence": 255,
       "Steps": [
+        {
+          "TerritoryId": 131,
+          "InteractionType": "Gather",
+          "ItemsToGather": [
+            {
+              "ItemId": 5106,
+              "ItemCount": 10
+            }
+          ]
+        },
         {
           "DataId": 1002298,
           "Position": {
                 131
               ]
             }
-          },
-          "RequiredGatheredItems": [
-            {
-              "ItemId": 5106,
-              "ItemCount": 10
-            }
-          ]
+          }
         }
       ]
     }
index 50ff25c8c016862d305d034bde78cce92806e4b4..4d15185fd79f781e15b12fb8aecd9c77a709fc21 100644 (file)
     {
       "Sequence": 255,
       "Steps": [
+        {
+          "TerritoryId": 131,
+          "InteractionType": "Gather",
+          "ItemsToGather": [
+            {
+              "ItemId": 5432,
+              "ItemCount": 10
+            }
+          ]
+        },
         {
           "DataId": 1002298,
           "Position": {
                 131
               ]
             }
-          },
-          "RequiredGatheredItems": [
-            {
-              "ItemId": 5432,
-              "ItemCount": 10
-            }
-          ]
+          }
         }
       ]
     }
index c2154923aaed120dbce7d7de3ef1e51b91493a06..1422190e154bc638110712912de5925e3465605e 100644 (file)
@@ -5,6 +5,11 @@
     {
       "Sequence": 0,
       "Steps": [
+        {
+          "TerritoryId": 478,
+          "InteractionType": "Gather",
+          "ItemsToGather": []
+        },
         {
           "Position": {
             "X": -71.31451,
@@ -13,7 +18,6 @@
           },
           "TerritoryId": 478,
           "InteractionType": "WalkTo",
-          "RequiredGatheredItems": [],
           "AetheryteShortcut": "Idyllshire"
         },
         {
index c59687c6cab61bcf1729748ab25217503ac2bca4..185e382541bd774bc3b42109f4884a73df3b8a56 100644 (file)
     {
       "Sequence": 255,
       "Steps": [
+        {
+          "TerritoryId": 478,
+          "InteractionType": "Gather",
+          "ItemsToGather": [
+            {
+              "ItemId": 17946,
+              "ItemCount": 20
+            }
+          ]
+        },
         {
           "DataId": 1021349,
           "Position": {
             "[Idyllshire] Aetheryte Plaza",
             "[Idyllshire] West Idyllshire"
           ],
-          "RequiredGatheredItems": [
-            {
-              "ItemId": 17946,
-              "ItemCount": 20
-            }
-          ],
           "NextQuestId": 2623
         }
       ]
index fcc2e5f8137fa8a5a4151c4a27ee2aa104fc6fb4..b2ef3384392d4187d02d4a99439e477259f6dc2f 100644 (file)
     {
       "Sequence": 6,
       "Steps": [
+        {
+          "TerritoryId": 478,
+          "InteractionType": "Gather",
+          "ItemsToGather": [
+            {
+              "ItemId": 17947,
+              "ItemCount": 20
+            }
+          ]
+        },
         {
           "DataId": 1017106,
           "Position": {
           },
           "TerritoryId": 478,
           "InteractionType": "Interact",
-          "AetheryteShortcut": "Idyllshire",
-          "RequiredGatheredItems": [
-            {
-              "ItemId": 17947,
-              "ItemCount": 20
-            }
-          ]
+          "AetheryteShortcut": "Idyllshire"
         }
       ]
     },
index b682928e725aa0eaf757e4cec7e73076c91a62b4..5fc30c903ea678bfddca5eecff6a3f444439e936 100644 (file)
     {
       "Sequence": 255,
       "Steps": [
+        {
+          "TerritoryId": 478,
+          "InteractionType": "Gather",
+          "ItemsToGather": [
+            {
+              "ItemId": 17948,
+              "ItemCount": 5
+            }
+          ]
+        },
         {
           "DataId": 1021349,
           "Position": {
             "[Idyllshire] Aetheryte Plaza",
             "[Idyllshire] West Idyllshire"
           ],
-          "Comment": "Eorzean Time: 4:00-5:59 AM/PM",
-          "RequiredGatheredItems": [
-            {
-              "ItemId": 17948,
-              "ItemCount": 5
-            }
-          ]
+          "Comment": "Eorzean Time: 4:00-5:59 AM/PM"
         }
       ]
     }
index 3912cfc6d6b7dfeb5e27919b98c27c1cdc45e701..99762b5b2662f1b380ddefd99a9a878323b80d4f 100644 (file)
@@ -5,6 +5,11 @@
     {
       "Sequence": 0,
       "Steps": [
+        {
+          "TerritoryId": 478,
+          "InteractionType": "Gather",
+          "ItemsToGather": []
+        },
         {
           "DataId": 1018393,
           "Position": {
@@ -14,7 +19,6 @@
           },
           "TerritoryId": 478,
           "InteractionType": "Interact",
-          "RequiredGatheredItems": [],
           "AetheryteShortcut": "Idyllshire",
           "DialogueChoices": [
             {
index 3fef30bea71c37e36291f0b15322164200e274f9..9b1f82dc3a1307a5b421cf7ed7b672f5059410e3 100644 (file)
@@ -5,6 +5,11 @@
     {
       "Sequence": 0,
       "Steps": [
+        {
+          "TerritoryId": 613,
+          "InteractionType": "Gather",
+          "ItemsToGather": []
+        },
         {
           "DataId": 1025878,
           "Position": {
@@ -14,7 +19,6 @@
           },
           "TerritoryId": 613,
           "InteractionType": "Interact",
-          "RequiredGatheredItems": [],
           "AetheryteShortcut": "Ruby Sea - Tamamizu",
           "DialogueChoices": [
             {
index 1908b500c67926de5ea127ab9ab6adcdcb3eb605..ba9858d8733877b1c97fe122dc0514ef0f4ff031 100644 (file)
@@ -5,6 +5,11 @@
     {
       "Sequence": 0,
       "Steps": [
+        {
+          "TerritoryId": 635,
+          "InteractionType": "Gather",
+          "ItemsToGather": []
+        },
         {
           "DataId": 1020337,
           "Position": {
@@ -14,7 +19,6 @@
           },
           "TerritoryId": 635,
           "InteractionType": "Interact",
-          "RequiredGatheredItems": [],
           "AetheryteShortcut": "Rhalgr's Reach",
           "AethernetShortcut": [
             "[Rhalgr's Reach] Aetheryte Plaza",
index d9625d0dfcb40d64cf4898037e23d4081a4309f9..3a11c275ac6cc15cc4e6eadb3de40e7f8468489a 100644 (file)
       "Sequence": 255,
       "Steps": [
         {
-          "Position": {
-            "X": 788.1569,
-            "Y": -45.82557,
-            "Z": -212.9306
-          },
           "TerritoryId": 817,
-          "InteractionType": "WalkTo",
-          "AetheryteShortcut": "Rak'tika - Fanow",
-          "Fly": true,
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 29517,
             }
           ]
         },
+        {
+          "Position": {
+            "X": 788.1569,
+            "Y": -45.82557,
+            "Z": -212.9306
+          },
+          "TerritoryId": 817,
+          "InteractionType": "WalkTo",
+          "AetheryteShortcut": "Rak'tika - Fanow",
+          "Fly": true
+        },
         {
           "DataId": 1032643,
           "Position": {
index 45b2176d810e8fed74342574aead4df2f268da99..194836db333c6f782b164547efecc105d6e73a76 100644 (file)
       "Sequence": 255,
       "Steps": [
         {
-          "Position": {
-            "X": 788.1569,
-            "Y": -45.82557,
-            "Z": -212.9306
-          },
           "TerritoryId": 817,
-          "InteractionType": "WalkTo",
-          "Fly": true,
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 29518,
             }
           ]
         },
+        {
+          "Position": {
+            "X": 788.1569,
+            "Y": -45.82557,
+            "Z": -212.9306
+          },
+          "TerritoryId": 817,
+          "InteractionType": "WalkTo",
+          "Fly": true
+        },
         {
           "DataId": 1032643,
           "Position": {
index 5f67cc1dc1583ca5a809e22eadd11afdd5dcb2a2..5fa818a8889bad19c231ac6fc1350f7273c5d2a5 100644 (file)
       "Sequence": 255,
       "Steps": [
         {
-          "Position": {
-            "X": 788.1569,
-            "Y": -45.82557,
-            "Z": -212.9306
-          },
           "TerritoryId": 817,
-          "InteractionType": "WalkTo",
-          "AetheryteShortcut": "Rak'tika - Fanow",
-          "Fly": true,
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 29519,
             }
           ]
         },
+        {
+          "Position": {
+            "X": 788.1569,
+            "Y": -45.82557,
+            "Z": -212.9306
+          },
+          "TerritoryId": 817,
+          "InteractionType": "WalkTo",
+          "AetheryteShortcut": "Rak'tika - Fanow",
+          "Fly": true
+        },
         {
           "DataId": 1032643,
           "Position": {
index 158b910043a5c25f6092a0e6e01fe235377f8b39..e0e1def3c801bf9f316ec9680008896218f4d2c8 100644 (file)
       "Sequence": 255,
       "Steps": [
         {
-          "Position": {
-            "X": 788.1569,
-            "Y": -45.82557,
-            "Z": -212.9306
-          },
           "TerritoryId": 817,
-          "InteractionType": "WalkTo",
-          "AetheryteShortcut": "Rak'tika - Fanow",
-          "Fly": true,
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 29520,
             }
           ]
         },
+        {
+          "Position": {
+            "X": 788.1569,
+            "Y": -45.82557,
+            "Z": -212.9306
+          },
+          "TerritoryId": 817,
+          "InteractionType": "WalkTo",
+          "AetheryteShortcut": "Rak'tika - Fanow",
+          "Fly": true
+        },
         {
           "DataId": 1032643,
           "Position": {
index d88da9c814a795d985e44e46cdd830e51ba490ed..ed0114e46e522b6d514a1c4e5a7df6f839c2ab97 100644 (file)
@@ -88,9 +88,7 @@
           "TerritoryId": 817,
           "InteractionType": "WalkTo",
           "AetheryteShortcut": "Rak'tika - Fanow",
-          "Fly": true,
-          "RequiredGatheredItems": [
-          ]
+          "Fly": true
         },
         {
           "DataId": 1032643,
index e81c302dbd15f3b111dae3f0a4d375213e9ba297..1e420bdfafc20027f88c81850d64fad11ed15bf2 100644 (file)
       "Sequence": 255,
       "Steps": [
         {
-          "Position": {
-            "X": 788.1569,
-            "Y": -45.82557,
-            "Z": -212.9306
-          },
           "TerritoryId": 817,
-          "InteractionType": "WalkTo",
-          "AetheryteShortcut": "Rak'tika - Fanow",
-          "Fly": true,
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 29521,
             }
           ]
         },
+        {
+          "Position": {
+            "X": 788.1569,
+            "Y": -45.82557,
+            "Z": -212.9306
+          },
+          "TerritoryId": 817,
+          "InteractionType": "WalkTo",
+          "AetheryteShortcut": "Rak'tika - Fanow",
+          "Fly": true
+        },
         {
           "DataId": 1032643,
           "Position": {
index 86de8b47286ef41f884c342846ee26da6fa389c9..6b0ac90418152034013c6da28e9d2b6535e99763 100644 (file)
       "Sequence": 255,
       "Steps": [
         {
-          "Position": {
-            "X": 788.1569,
-            "Y": -45.82557,
-            "Z": -212.9306
-          },
           "TerritoryId": 817,
-          "InteractionType": "WalkTo",
-          "AetheryteShortcut": "Rak'tika - Fanow",
-          "Fly": true,
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 29522,
             }
           ]
         },
+        {
+          "Position": {
+            "X": 788.1569,
+            "Y": -45.82557,
+            "Z": -212.9306
+          },
+          "TerritoryId": 817,
+          "InteractionType": "WalkTo",
+          "AetheryteShortcut": "Rak'tika - Fanow",
+          "Fly": true
+        },
         {
           "DataId": 1032643,
           "Position": {
index 23a2829e9b7ee8e649ebb9947982e0d58175c11f..6fa2638b184e29ecb869e40f69bc44aa7ac51e80 100644 (file)
       "Sequence": 255,
       "Steps": [
         {
-          "Position": {
-            "X": 788.1569,
-            "Y": -45.82557,
-            "Z": -212.9306
-          },
           "TerritoryId": 817,
-          "InteractionType": "WalkTo",
-          "AetheryteShortcut": "Rak'tika - Fanow",
-          "Fly": true,
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 29523,
             }
           ]
         },
+        {
+          "Position": {
+            "X": 788.1569,
+            "Y": -45.82557,
+            "Z": -212.9306
+          },
+          "TerritoryId": 817,
+          "InteractionType": "WalkTo",
+          "AetheryteShortcut": "Rak'tika - Fanow",
+          "Fly": true
+        },
         {
           "DataId": 1032643,
           "Position": {
index 3fda4f2d701d9e5f1fc41ca194575cafdaa3cbb0..1a63219d3dd6890b0c70aab2fd96e073aa99ba49 100644 (file)
       "Sequence": 255,
       "Steps": [
         {
-          "Position": {
-            "X": 788.1569,
-            "Y": -45.82557,
-            "Z": -212.9306
-          },
           "TerritoryId": 817,
-          "InteractionType": "WalkTo",
-          "AetheryteShortcut": "Rak'tika - Fanow",
-          "Fly": true,
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 29524,
             }
           ]
         },
+        {
+          "Position": {
+            "X": 788.1569,
+            "Y": -45.82557,
+            "Z": -212.9306
+          },
+          "TerritoryId": 817,
+          "InteractionType": "WalkTo",
+          "AetheryteShortcut": "Rak'tika - Fanow",
+          "Fly": true
+        },
         {
           "DataId": 1032643,
           "Position": {
index 76b7a64a55b3e843f24a89bf46eeb6735da85982..bdbb16961e528b1f121b4fefb767030e3785c695 100644 (file)
@@ -30,9 +30,7 @@
           "TerritoryId": 817,
           "InteractionType": "WalkTo",
           "AetheryteShortcut": "Rak'tika - Fanow",
-          "Fly": true,
-          "RequiredGatheredItems": [
-          ]
+          "Fly": true
         },
         {
           "DataId": 1032643,
index 76b7a64a55b3e843f24a89bf46eeb6735da85982..bdbb16961e528b1f121b4fefb767030e3785c695 100644 (file)
@@ -30,9 +30,7 @@
           "TerritoryId": 817,
           "InteractionType": "WalkTo",
           "AetheryteShortcut": "Rak'tika - Fanow",
-          "Fly": true,
-          "RequiredGatheredItems": [
-          ]
+          "Fly": true
         },
         {
           "DataId": 1032643,
index 76b7a64a55b3e843f24a89bf46eeb6735da85982..bdbb16961e528b1f121b4fefb767030e3785c695 100644 (file)
@@ -30,9 +30,7 @@
           "TerritoryId": 817,
           "InteractionType": "WalkTo",
           "AetheryteShortcut": "Rak'tika - Fanow",
-          "Fly": true,
-          "RequiredGatheredItems": [
-          ]
+          "Fly": true
         },
         {
           "DataId": 1032643,
index 9282be6561507d77b75d3e0355be060b46aecc7e..204ea239f38faf58d29e26b4d4686903a2743d15 100644 (file)
       "Sequence": 255,
       "Steps": [
         {
-          "Position": {
-            "X": 788.1569,
-            "Y": -45.82557,
-            "Z": -212.9306
-          },
           "TerritoryId": 817,
-          "InteractionType": "WalkTo",
-          "AetheryteShortcut": "Rak'tika - Fanow",
-          "Fly": true,
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 29528,
             }
           ]
         },
+        {
+          "Position": {
+            "X": 788.1569,
+            "Y": -45.82557,
+            "Z": -212.9306
+          },
+          "TerritoryId": 817,
+          "InteractionType": "WalkTo",
+          "AetheryteShortcut": "Rak'tika - Fanow",
+          "Fly": true
+        },
         {
           "DataId": 1032643,
           "Position": {
index 3d5f7dcbf65fa1c944fbc41fe746a229c49b65d0..ffa6ff83cdc9d87144d20c4442025bd0a80a08bb 100644 (file)
       "Sequence": 255,
       "Steps": [
         {
-          "Position": {
-            "X": 788.1569,
-            "Y": -45.82557,
-            "Z": -212.9306
-          },
           "TerritoryId": 817,
-          "InteractionType": "WalkTo",
-          "AetheryteShortcut": "Rak'tika - Fanow",
-          "Fly": true,
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 29529,
             }
           ]
         },
+        {
+          "Position": {
+            "X": 788.1569,
+            "Y": -45.82557,
+            "Z": -212.9306
+          },
+          "TerritoryId": 817,
+          "InteractionType": "WalkTo",
+          "AetheryteShortcut": "Rak'tika - Fanow",
+          "Fly": true
+        },
         {
           "DataId": 1032643,
           "Position": {
index 49588dea441d925dfebaca40733adf5ebf2da68b..dec082cdef163a2828a44b25e6767613547d762a 100644 (file)
       "Sequence": 255,
       "Steps": [
         {
-          "Position": {
-            "X": 788.1569,
-            "Y": -45.82557,
-            "Z": -212.9306
-          },
           "TerritoryId": 817,
-          "InteractionType": "WalkTo",
-          "AetheryteShortcut": "Rak'tika - Fanow",
-          "Fly": true,
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 29530,
             }
           ]
         },
+        {
+          "Position": {
+            "X": 788.1569,
+            "Y": -45.82557,
+            "Z": -212.9306
+          },
+          "TerritoryId": 817,
+          "InteractionType": "WalkTo",
+          "AetheryteShortcut": "Rak'tika - Fanow",
+          "Fly": true
+        },
         {
           "DataId": 1032643,
           "Position": {
index 76b7a64a55b3e843f24a89bf46eeb6735da85982..bdbb16961e528b1f121b4fefb767030e3785c695 100644 (file)
@@ -30,9 +30,7 @@
           "TerritoryId": 817,
           "InteractionType": "WalkTo",
           "AetheryteShortcut": "Rak'tika - Fanow",
-          "Fly": true,
-          "RequiredGatheredItems": [
-          ]
+          "Fly": true
         },
         {
           "DataId": 1032643,
index 76b7a64a55b3e843f24a89bf46eeb6735da85982..bdbb16961e528b1f121b4fefb767030e3785c695 100644 (file)
@@ -30,9 +30,7 @@
           "TerritoryId": 817,
           "InteractionType": "WalkTo",
           "AetheryteShortcut": "Rak'tika - Fanow",
-          "Fly": true,
-          "RequiredGatheredItems": [
-          ]
+          "Fly": true
         },
         {
           "DataId": 1032643,
index 0ae024dc0e92c70830ae1f839feedd2aba116462..6b71e791e8ed668f5b27be2cfd46d67aa05388d5 100644 (file)
       "Sequence": 255,
       "Steps": [
         {
-          "Position": {
-            "X": 788.1569,
-            "Y": -45.82557,
-            "Z": -212.9306
-          },
           "TerritoryId": 817,
-          "InteractionType": "WalkTo",
-          "AetheryteShortcut": "Rak'tika - Fanow",
-          "Fly": true,
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 29533,
             }
           ]
         },
+        {
+          "Position": {
+            "X": 788.1569,
+            "Y": -45.82557,
+            "Z": -212.9306
+          },
+          "TerritoryId": 817,
+          "InteractionType": "WalkTo",
+          "AetheryteShortcut": "Rak'tika - Fanow",
+          "Fly": true
+        },
         {
           "DataId": 1032643,
           "Position": {
index ce85c188a93c498cd529d4d2ccc0f9144e2eff61..9442335fa117587c8d41ec3fca721f43b79c48cd 100644 (file)
       "Sequence": 255,
       "Steps": [
         {
-          "Position": {
-            "X": 788.1569,
-            "Y": -45.82557,
-            "Z": -212.9306
-          },
           "TerritoryId": 817,
-          "InteractionType": "WalkTo",
-          "AetheryteShortcut": "Rak'tika - Fanow",
-          "Fly": true,
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 29534,
             }
           ]
         },
+        {
+          "Position": {
+            "X": 788.1569,
+            "Y": -45.82557,
+            "Z": -212.9306
+          },
+          "TerritoryId": 817,
+          "InteractionType": "WalkTo",
+          "AetheryteShortcut": "Rak'tika - Fanow",
+          "Fly": true
+        },
         {
           "DataId": 1032643,
           "Position": {
index deded4f53ebc198788068fcf09cf8aaaec7c161f..8f3976ed99d8eb5be992821d2e32961dfa1eb426 100644 (file)
       "Sequence": 255,
       "Steps": [
         {
-          "Position": {
-            "X": 788.1569,
-            "Y": -45.82557,
-            "Z": -212.9306
-          },
           "TerritoryId": 817,
-          "InteractionType": "WalkTo",
-          "AetheryteShortcut": "Rak'tika - Fanow",
-          "Fly": true,
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 29535,
             }
           ]
         },
+        {
+          "Position": {
+            "X": 788.1569,
+            "Y": -45.82557,
+            "Z": -212.9306
+          },
+          "TerritoryId": 817,
+          "InteractionType": "WalkTo",
+          "AetheryteShortcut": "Rak'tika - Fanow",
+          "Fly": true
+        },
         {
           "DataId": 1032643,
           "Position": {
index 17c44e90221c1e53ea7e62bcfe6cc44e870db949..f2761f621eb863e451c66014dcb48c08de833fa3 100644 (file)
       "Sequence": 255,
       "Steps": [
         {
-          "Position": {
-            "X": 788.1569,
-            "Y": -45.82557,
-            "Z": -212.9306
-          },
           "TerritoryId": 817,
-          "InteractionType": "WalkTo",
-          "AetheryteShortcut": "Rak'tika - Fanow",
-          "Fly": true,
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 29536,
             }
           ]
         },
+        {
+          "Position": {
+            "X": 788.1569,
+            "Y": -45.82557,
+            "Z": -212.9306
+          },
+          "TerritoryId": 817,
+          "InteractionType": "WalkTo",
+          "AetheryteShortcut": "Rak'tika - Fanow",
+          "Fly": true
+        },
         {
           "DataId": 1032643,
           "Position": {
index 76b7a64a55b3e843f24a89bf46eeb6735da85982..bdbb16961e528b1f121b4fefb767030e3785c695 100644 (file)
@@ -30,9 +30,7 @@
           "TerritoryId": 817,
           "InteractionType": "WalkTo",
           "AetheryteShortcut": "Rak'tika - Fanow",
-          "Fly": true,
-          "RequiredGatheredItems": [
-          ]
+          "Fly": true
         },
         {
           "DataId": 1032643,
index 76b7a64a55b3e843f24a89bf46eeb6735da85982..bdbb16961e528b1f121b4fefb767030e3785c695 100644 (file)
@@ -30,9 +30,7 @@
           "TerritoryId": 817,
           "InteractionType": "WalkTo",
           "AetheryteShortcut": "Rak'tika - Fanow",
-          "Fly": true,
-          "RequiredGatheredItems": [
-          ]
+          "Fly": true
         },
         {
           "DataId": 1032643,
index e13c4ad32e20fe9c0e3451d1986f7ee33c563824..9a9e070ffe1d355553b080225c9b10d185c1b3bc 100644 (file)
     {
       "Sequence": 255,
       "Steps": [
+        {
+          "TerritoryId": 817,
+          "InteractionType": "Gather",
+          "ItemsToGather": [
+            {
+              "ItemId": 29512,
+              "ItemCount": 1
+            }
+          ]
+        },
         {
           "DataId": 1032724,
           "Position": {
           },
           "TerritoryId": 817,
           "InteractionType": "CompleteQuest",
-          "Fly": true,
-          "RequiredGatheredItems": [
-            {
-              "ItemId": 29512,
-              "ItemCount": 1
-            }
-          ]
+          "Fly": true
         }
       ]
     }
index 1b2c8f550dff5191b9d98c98f723fa884d922b8c..84db90fd8c9348209be7f53b954024583eb21672 100644 (file)
       "Sequence": 2,
       "Steps": [
         {
-          "DataId": 1032734,
-          "Position": {
-            "X": 802.6703,
-            "Y": -45.915627,
-            "Z": -214.70972
-          },
           "TerritoryId": 817,
-          "InteractionType": "Interact",
-          "AetheryteShortcut": "Rak'tika - Fanow",
-          "Fly": true,
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 29513,
               "ItemCount": 1
             }
           ]
+        },
+        {
+          "DataId": 1032734,
+          "Position": {
+            "X": 802.6703,
+            "Y": -45.915627,
+            "Z": -214.70972
+          },
+          "TerritoryId": 817,
+          "InteractionType": "Interact",
+          "AetheryteShortcut": "Rak'tika - Fanow",
+          "Fly": true
         }
       ]
     },
index 325c08cd26a909e170885aeef652ae76c7e9afa1..007020533594758de25b578abb4a1d9965dbdaed 100644 (file)
@@ -5,6 +5,11 @@
     {
       "Sequence": 0,
       "Steps": [
+        {
+          "TerritoryId": 820,
+          "InteractionType": "Gather",
+          "ItemsToGather": []
+        },
         {
           "DataId": 1031801,
           "Position": {
@@ -14,7 +19,6 @@
           },
           "TerritoryId": 820,
           "InteractionType": "Interact",
-          "RequiredGatheredItems": [],
           "AetheryteShortcut": "Eulmore",
           "DialogueChoices": [
             {
index e53d9af14e542f866119319138b71d89fca3705a..e70487a8a332650d01c2beae91c479c15eefb042 100644 (file)
@@ -22,8 +22,8 @@
       "Steps": [
         {
           "TerritoryId": 960,
-          "InteractionType": "None",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 38281,
index 8f588d7613ceb53deefb3be30a3508cfe2628625..c50c4a58173b34228699cac92ef1d064f6d7890f 100644 (file)
       "Sequence": 255,
       "Steps": [
         {
-          "DataId": 2013072,
-          "Position": {
-            "X": 456.65674,
-            "Y": 438.04077,
-            "Z": 310.2312
-          },
           "TerritoryId": 960,
-          "InteractionType": "Interact",
-          "TargetTerritoryId": 960,
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 38282,
               "ItemId": 38306,
               "ItemCount": 3
             }
-          ],
-          "AetheryteShortcut": "Ultima Thule - Base Omicron"
+          ]
+        },
+        {
+          "DataId": 2013072,
+          "Position": {
+            "X": 456.65674,
+            "Y": 438.04077,
+            "Z": 310.2312
+          },
+          "TerritoryId": 960,
+          "InteractionType": "Interact",
+          "AetheryteShortcut": "Ultima Thule - Base Omicron",
+          "TargetTerritoryId": 960
         },
         {
           "DataId": 1043417,
index 47d61f1494511283bb2511e14b94cc6acd362bed..9cdb099ad6e4c6032182c5010aaa45953b4ac344 100644 (file)
@@ -33,8 +33,8 @@
         },
         {
           "TerritoryId": 1073,
-          "InteractionType": "None",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 38284,
index 298df76d63408a85b675e1cefadad37283156661..0635180f2c05ce7e2520bb1bc4263282adbed19e 100644 (file)
       "Sequence": 255,
       "Steps": [
         {
-          "DataId": 2013072,
-          "Position": {
-            "X": 456.65674,
-            "Y": 438.04077,
-            "Z": 310.2312
-          },
           "TerritoryId": 960,
-          "InteractionType": "Interact",
-          "TargetTerritoryId": 960,
-          "AetheryteShortcut": "Ultima Thule - Base Omicron",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 38283,
             }
           ]
         },
+        {
+          "DataId": 2013072,
+          "Position": {
+            "X": 456.65674,
+            "Y": 438.04077,
+            "Z": 310.2312
+          },
+          "TerritoryId": 960,
+          "InteractionType": "Interact",
+          "TargetTerritoryId": 960,
+          "AetheryteShortcut": "Ultima Thule - Base Omicron"
+        },
         {
           "DataId": 1043417,
           "Position": {
index 70ae5932a76b3e371271eb133cd56f77057d310a..71875e688c49ab41cc466eb17d8c40e463680e6e 100644 (file)
@@ -33,8 +33,8 @@
         },
         {
           "TerritoryId": 1073,
-          "InteractionType": "None",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 38285,
index 88f3b658d4f583c474a31302d962f6cdefd93186..dece67eb02db7d95b18e8bf07086abdf3e3a5b34 100644 (file)
@@ -22,8 +22,8 @@
       "Steps": [
         {
           "TerritoryId": 960,
-          "InteractionType": "None",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 38286,
index 30a6cf2fc9b6d38e8cf81bb17dfbfc0e961417b9..513129c61eaff6a5ea2b61d49c05069ed7aadde7 100644 (file)
@@ -34,8 +34,8 @@
         },
         {
           "TerritoryId": 1073,
-          "InteractionType": "None",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 38287,
index e06131edeeaf1225825c0001ca0fb61a5782989d..9432896100f1d7a9eaf33adfba7b0c891eae111a 100644 (file)
       "Sequence": 2,
       "Steps": [
         {
-          "DataId": 1044059,
-          "Position": {
-            "X": -15.304871,
-            "Y": 494.9991,
-            "Z": -68.16211
-          },
           "TerritoryId": 1073,
-          "InteractionType": "Interact",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 38289,
               "ItemCount": 3
             }
           ]
+        },
+        {
+          "DataId": 1044059,
+          "Position": {
+            "X": -15.304871,
+            "Y": 494.9991,
+            "Z": -68.16211
+          },
+          "TerritoryId": 1073,
+          "InteractionType": "Interact"
         }
       ]
     },
index afa62fdd628efdedab9d34fc33a595d713a66c58..9662a58c67af03cd1ab9aaf3826ad3a97a2958e8 100644 (file)
       "Sequence": 1,
       "Steps": [
         {
-          "DataId": 1044064,
-          "Position": {
-            "X": 86.503296,
-            "Y": 269.08234,
-            "Z": -515.0683
-          },
           "TerritoryId": 960,
-          "InteractionType": "Interact",
-          "AetheryteShortcut": "Ultima Thule - Abode of the Ea",
-          "Fly": true,
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 38290,
               "ItemCount": 3
             }
           ]
+        },
+        {
+          "DataId": 1044064,
+          "Position": {
+            "X": 86.503296,
+            "Y": 269.08234,
+            "Z": -515.0683
+          },
+          "TerritoryId": 960,
+          "InteractionType": "Interact",
+          "AetheryteShortcut": "Ultima Thule - Abode of the Ea",
+          "Fly": true
         }
       ]
     },
index ee54956335dddd30c23607ac0ebf05c46f1f6941..6d818a499e5028a2160a08e57250a71d52b3f5d1 100644 (file)
@@ -34,8 +34,8 @@
         },
         {
           "TerritoryId": 1073,
-          "InteractionType": "None",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 38291,
index 6e64ff1c77ef86c76cceb741b82691ae90e3b57d..b1fc3e924fa6a209f2c28cc9017ae4ec0b1684c9 100644 (file)
@@ -33,8 +33,8 @@
         },
         {
           "TerritoryId": 1073,
-          "InteractionType": "None",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 38292,
index 940950de8ed07e564233fb3ea883974cb8fed6c6..1faf24167496b262ee7ed0415e550f2c3fe59a04 100644 (file)
@@ -33,8 +33,8 @@
         },
         {
           "TerritoryId": 1073,
-          "InteractionType": "None",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 38293,
index 1c319fcac740cec8683d78d3bddd7d3dd49c3fe1..f8be57eca1206c4cbe0f3e23d102b0b0c61566a7 100644 (file)
       "Sequence": 1,
       "Steps": [
         {
-          "DataId": 1044071,
-          "Position": {
-            "X": 46.066895,
-            "Y": 268.99976,
-            "Z": -584.77155
-          },
           "TerritoryId": 960,
-          "InteractionType": "Interact",
-          "AetheryteShortcut": "Ultima Thule - Abode of the Ea",
-          "Fly": true,
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 38294,
               "ItemCount": 3
             }
           ]
+        },
+        {
+          "DataId": 1044071,
+          "Position": {
+            "X": 46.066895,
+            "Y": 268.99976,
+            "Z": -584.77155
+          },
+          "TerritoryId": 960,
+          "InteractionType": "Interact",
+          "AetheryteShortcut": "Ultima Thule - Abode of the Ea",
+          "Fly": true
         }
       ]
     },
index f1d2760b422c573ecf95130bff85d20dec179576..9ba18a23c3cfd3d0e74480473e931d0a2cd4be7e 100644 (file)
       "Sequence": 1,
       "Steps": [
         {
-          "DataId": 1044074,
-          "Position": {
-            "X": -585.90063,
-            "Y": 75.22713,
-            "Z": 256.67188
-          },
           "TerritoryId": 960,
-          "InteractionType": "Interact",
-          "AetheryteShortcut": "Ultima Thule - Reah Tahra",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 38295,
               "ItemCount": 3
             }
           ]
+        },
+        {
+          "DataId": 1044074,
+          "Position": {
+            "X": -585.90063,
+            "Y": 75.22713,
+            "Z": 256.67188
+          },
+          "TerritoryId": 960,
+          "InteractionType": "Interact",
+          "AetheryteShortcut": "Ultima Thule - Reah Tahra"
         }
       ]
     },
index 91ba26b490c419e9b48cd4583b84594bb2b1e0e2..6e075fa897268b77386cb6c05d341e843cdedb07 100644 (file)
       "Sequence": 2,
       "Steps": [
         {
-          "DataId": 1044075,
-          "Position": {
-            "X": -64.4389,
-            "Y": 493.32922,
-            "Z": -4.409851
-          },
           "TerritoryId": 1073,
-          "InteractionType": "Interact",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 38296,
               "ItemCount": 3
             }
           ]
+        },
+        {
+          "DataId": 1044075,
+          "Position": {
+            "X": -64.4389,
+            "Y": 493.32922,
+            "Z": -4.409851
+          },
+          "TerritoryId": 1073,
+          "InteractionType": "Interact"
         }
       ]
     },
index f68b76f5f78bd7bd80e73c28e651a655e55364a6..f3eca7450d4afb7a983ad3343e184ece37e47f6d 100644 (file)
       "Sequence": 1,
       "Steps": [
         {
-          "DataId": 1044076,
-          "Position": {
-            "X": -499.96188,
-            "Y": 77.00467,
-            "Z": 241.07727
-          },
-          "StopDistance": 9,
           "TerritoryId": 960,
-          "InteractionType": "Interact",
-          "AetheryteShortcut": "Ultima Thule - Reah Tahra",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 38297,
               "ItemCount": 3
             }
           ]
+        },
+        {
+          "DataId": 1044076,
+          "Position": {
+            "X": -499.96188,
+            "Y": 77.00467,
+            "Z": 241.07727
+          },
+          "StopDistance": 9,
+          "TerritoryId": 960,
+          "InteractionType": "Interact",
+          "AetheryteShortcut": "Ultima Thule - Reah Tahra"
         }
       ]
     },
index fdec020c4ffbe4dbaae62c0486da3511a61f633c..bf7202517bf3adcebd6a4f7099e576eba7da778d 100644 (file)
       "Sequence": 1,
       "Steps": [
         {
-          "DataId": 1044081,
-          "Position": {
-            "X": -503.99023,
-            "Y": 74.16917,
-            "Z": 261.82947
-          },
           "TerritoryId": 960,
-          "InteractionType": "Interact",
+          "InteractionType": "Gather",
           "AetheryteShortcut": "Ultima Thule - Reah Tahra",
-          "RequiredGatheredItems": [
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 38299,
               "ItemCount": 3
             }
           ]
+        },
+        {
+          "DataId": 1044081,
+          "Position": {
+            "X": -503.99023,
+            "Y": 74.16917,
+            "Z": 261.82947
+          },
+          "TerritoryId": 960,
+          "InteractionType": "Interact"
         }
       ]
     },
index 7825c3cb2375169c252e6796d9d32fe73e8e8bd7..89f6b44c10320790bd9bca3cae10cf6700516078 100644 (file)
@@ -33,8 +33,8 @@
         },
         {
           "TerritoryId": 1073,
-          "InteractionType": "None",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 38298,
index 34b28d3d4a5c3a8d5e31937414b39bcfe0cab0b3..d1eb587c3f47d061178d5460f6eb76639ec4bcdc 100644 (file)
     {
       "Sequence": 4,
       "Steps": [
+        {
+          "TerritoryId": 960,
+          "InteractionType": "Gather",
+          "ItemsToGather": [
+            {
+              "QuestAcceptedAsClass": "Miner",
+              "ItemId": 38276,
+              "ItemCount": 3
+            },
+            {
+              "QuestAcceptedAsClass": "Botanist",
+              "ItemId": 38300,
+              "ItemCount": 3
+            }
+          ]
+        },
         {
           "DataId": 2013072,
           "Position": {
               "Prompt": "TEXT_BANOMI001_04601_Q5_000_000",
               "Yes": true
             }
-          ],
-          "RequiredGatheredItems": [
-            {
-              "QuestAcceptedAsClass": "Miner",
-              "ItemId": 38276,
-              "ItemCount": 3
-            },
-            {
-              "QuestAcceptedAsClass": "Botanist",
-              "ItemId": 38300,
-              "ItemCount": 3
-            }
           ]
         },
         {
index af25f7e6103557cc58d5830e665e549535b047b5..ffafc60f83a2b74c56a9dd74b0f7d1c0b48168a9 100644 (file)
       "Steps": [
         {
           "TerritoryId": 960,
-          "InteractionType": "None",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 38277,
index 7d90748459f14fca92d93eb69942a4629654a577..9170a9ed57057fc6a89571941852b5ce6122b6b9 100644 (file)
       "Steps": [
         {
           "TerritoryId": 960,
-          "InteractionType": "None",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 38278,
index 795964570bf87a1f29279dc2afdd96e54067438e..0cdbce560846d64f868bb17fdc2e2e633c486b51 100644 (file)
@@ -91,8 +91,8 @@
       "Steps": [
         {
           "TerritoryId": 398,
-          "InteractionType": "None",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 38279,
index 0fc6c53a460e934bbdd0448b845d48a2f6ff46b0..32571b616fcb4bfb5b5036192463d859e1d4f4ee 100644 (file)
       "Steps": [
         {
           "TerritoryId": 1073,
-          "InteractionType": "None",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "QuestAcceptedAsClass": "Miner",
               "ItemId": 38280,
index 36229edda3f19a63c62168c0ab8877684f287aa8..9cd56890f18fdb2f972663330e26558cab29edcc 100644 (file)
@@ -5,6 +5,11 @@
     {
       "Sequence": 0,
       "Steps": [
+        {
+          "TerritoryId": 962,
+          "InteractionType": "Gather",
+          "ItemsToGather": []
+        },
         {
           "DataId": 1042241,
           "Position": {
@@ -14,7 +19,6 @@
           },
           "TerritoryId": 962,
           "InteractionType": "Interact",
-          "RequiredGatheredItems": [],
           "AetheryteShortcut": "Old Sharlayan",
           "AethernetShortcut": [
             "[Old Sharlayan] Aetheryte Plaza",
index 1ac3ad73d44f8483c52f3d9db830fdb47051764a..b36972b05dd31a78e7132b90edbc2bf798f022f8 100644 (file)
@@ -5,6 +5,11 @@
     {
       "Sequence": 0,
       "Steps": [
+        {
+          "TerritoryId": 816,
+          "InteractionType": "Gather",
+          "ItemsToGather": []
+        },
         {
           "DataId": 1044547,
           "Position": {
@@ -14,7 +19,6 @@
           },
           "TerritoryId": 816,
           "InteractionType": "Interact",
-          "RequiredGatheredItems": [],
           "AetheryteShortcut": "Il Mheg - Lydha Lran",
           "Fly": true,
           "DialogueChoices": [
index 1d5507af07f3b580a34ca58630ed246adde4d976..e4d27b17c9a8f1108376edf02de3c25372e055fa 100644 (file)
@@ -5,6 +5,11 @@
     {
       "Sequence": 0,
       "Steps": [
+        {
+          "TerritoryId": 956,
+          "InteractionType": "Gather",
+          "ItemsToGather": []
+        },
         {
           "Position": {
             "X": -44.066154,
@@ -14,7 +19,6 @@
           "TerritoryId": 956,
           "InteractionType": "WalkTo",
           "AetheryteShortcut": "Labyrinthos - Sharlayan Hamlet",
-          "RequiredGatheredItems": [],
           "Fly": true
         },
         {
index 3072030357ba6a4ccf461ff3ed951159350994d8..8139e0c24c148df2ccd65c030487b1de27f0bd19 100644 (file)
     {
       "Sequence": 255,
       "Steps": [
+        {
+          "TerritoryId": 962,
+          "InteractionType": "Gather",
+          "ItemsToGather": [
+            {
+              "ItemId": 35600,
+              "ItemCount": 6,
+              "Collectability": 600
+            }
+          ]
+        },
         {
           "DataId": 1038501,
           "Position": {
             "[Old Sharlayan] Aetheryte Plaza",
             "[Old Sharlayan] The Studium"
           ],
-          "RequiredGatheredItems": [
-            {
-              "ItemId": 35600,
-              "ItemCount": 6,
-              "Collectability": 600
-            }
-          ],
           "NextQuestId": 4155
         }
       ]
index ca598552f85020bbdf854e6a1aed91171d8cc468..9e231382b4564265ac478f09763bf9116716d19a 100644 (file)
     {
       "Sequence": 255,
       "Steps": [
+        {
+          "TerritoryId": 962,
+          "InteractionType": "Gather",
+          "ItemsToGather": [
+            {
+              "ItemId": 35601,
+              "ItemCount": 6,
+              "Collectability": 600
+            }
+          ]
+        },
         {
           "DataId": 1038501,
           "Position": {
             "[Old Sharlayan] Aetheryte Plaza",
             "[Old Sharlayan] The Studium"
           ],
-          "RequiredGatheredItems": [
-            {
-              "ItemId": 35601,
-              "ItemCount": 6,
-              "Collectability": 600
-            }
-          ],
           "NextQuestId": 4156
         }
       ]
index d25034d3d7f18a24beb08df7824c90a1f396ed1c..1e533484f996030e57830d909b8faa8af8c5190c 100644 (file)
     {
       "Sequence": 255,
       "Steps": [
+        {
+          "TerritoryId": 962,
+          "InteractionType": "Gather",
+          "ItemsToGather": [
+            {
+              "ItemId": 35602,
+              "ItemCount": 6,
+              "Collectability": 600
+            }
+          ]
+        },
         {
           "DataId": 1038501,
           "Position": {
             "[Old Sharlayan] Aetheryte Plaza",
             "[Old Sharlayan] The Studium"
           ],
-          "RequiredGatheredItems": [
-            {
-              "ItemId": 35602,
-              "ItemCount": 6,
-              "Collectability": 600
-            }
-          ],
           "NextQuestId": 4157
         }
       ]
index e2ebf5530c0dcc29fb5788d8433bd1b723daa2d8..3cf84c84f65d2a4f1a0ab747bd07254936dac7d2 100644 (file)
     {
       "Sequence": 5,
       "Steps": [
+        {
+          "TerritoryId": 628,
+          "InteractionType": "Gather",
+          "ItemsToGather": [
+            {
+              "ItemId": 35847,
+              "ItemCount": 1
+            }
+          ]
+        },
         {
           "DataId": 1038508,
           "Position": {
           "AethernetShortcut": [
             "[Kugane] Aetheryte Plaza",
             "[Kugane] The Ruby Bazaar"
-          ],
-          "RequiredGatheredItems": [
-            {
-              "ItemId": 35847,
-              "ItemCount": 1
-            }
           ]
         }
       ]
index aa12eb80f29d7c54ddb890eddcf09fa11e18e6f0..65f4d7b1deb6f718a1523c6f04f4da18426acad8 100644 (file)
     {
       "Sequence": 255,
       "Steps": [
+        {
+          "TerritoryId": 962,
+          "InteractionType": "Gather",
+          "ItemsToGather": [
+            {
+              "ItemId": 35603,
+              "ItemCount": 6,
+              "Collectability": 600
+            }
+          ]
+        },
         {
           "DataId": 1038501,
           "Position": {
             "[Old Sharlayan] Aetheryte Plaza",
             "[Old Sharlayan] The Studium"
           ],
-          "RequiredGatheredItems": [
-            {
-              "ItemId": 35603,
-              "ItemCount": 6,
-              "Collectability": 600
-            }
-          ],
           "NextQuestId": 4159
         }
       ]
index a7dd1f4adbd913264a30d171973d2aea737de897..64daaad4cc29e005f59e307d793cbb80ad0aee28 100644 (file)
     {
       "Sequence": 1,
       "Steps": [
+        {
+          "TerritoryId": 962,
+          "InteractionType": "Gather",
+          "ItemsToGather": [
+            {
+              "ItemId": 35848,
+              "ItemCount": 1
+            }
+          ]
+        },
         {
           "DataId": 1038503,
           "Position": {
           "AethernetShortcut": [
             "[Old Sharlayan] Aetheryte Plaza",
             "[Old Sharlayan] The Studium"
-          ],
-          "RequiredGatheredItems": [
-            {
-              "ItemId": 35848,
-              "ItemCount": 1
-            }
           ]
         }
       ]
index 6a72ac3753faa96924c3f655b0daa915854161ff..368326b8cca14426d0d88e1515c446ae1e9f5745 100644 (file)
       "Steps": [
         {
           "TerritoryId": 1185,
-          "InteractionType": "None",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "ItemId": 43899,
               "ItemCount": 6,
               "Collectability": 600
             }
-          ],
-          "AetheryteShortcut": "Tuliyollal",
-          "AethernetShortcut": [
-            "[Tuliyollal] Aetheryte Plaza",
-            "[Tuliyollal] Wachumeqimeqi"
           ]
         },
         {
           },
           "TerritoryId": 1185,
           "InteractionType": "CompleteQuest",
-          "NextQuestId": 4991
+          "NextQuestId": 4991,
+          "AetheryteShortcut": "Tuliyollal",
+          "AethernetShortcut": [
+            "[Tuliyollal] Aetheryte Plaza",
+            "[Tuliyollal] Wachumeqimeqi"
+          ]
         }
       ]
     }
index 7150a44ca4017a03f5ebe8982a240052a8e80274..923cde19e2bc3880be50561ee8009fa02e0c8321 100644 (file)
       "Steps": [
         {
           "TerritoryId": 1185,
-          "InteractionType": "None",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "ItemId": 43900,
               "ItemCount": 6,
               "Collectability": 600
             }
-          ],
-          "AetheryteShortcut": "Tuliyollal",
-          "AethernetShortcut": [
-            "[Tuliyollal] Aetheryte Plaza",
-            "[Tuliyollal] Wachumeqimeqi"
           ]
         },
         {
           },
           "TerritoryId": 1185,
           "InteractionType": "CompleteQuest",
-          "NextQuestId": 4992
+          "NextQuestId": 4992,
+          "AetheryteShortcut": "Tuliyollal",
+          "AethernetShortcut": [
+            "[Tuliyollal] Aetheryte Plaza",
+            "[Tuliyollal] Wachumeqimeqi"
+          ]
         }
       ]
     }
index dd99b09bb5d004764f56dcdc4a4800d7aa59ec3c..d0769b6e4a2e33d3c8ac41b7afd29e6451442fd2 100644 (file)
       "Steps": [
         {
           "TerritoryId": 1185,
-          "InteractionType": "None",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "ItemId": 43901,
               "ItemCount": 6,
               "Collectability": 600
             }
-          ],
-          "AetheryteShortcut": "Tuliyollal",
-          "AethernetShortcut": [
-            "[Tuliyollal] Aetheryte Plaza",
-            "[Tuliyollal] Wachumeqimeqi"
           ]
         },
         {
           },
           "TerritoryId": 1185,
           "InteractionType": "CompleteQuest",
-          "NextQuestId": 4993
+          "NextQuestId": 4993,
+          "AetheryteShortcut": "Tuliyollal",
+          "AethernetShortcut": [
+            "[Tuliyollal] Aetheryte Plaza",
+            "[Tuliyollal] Wachumeqimeqi"
+          ]
         }
       ]
     }
index 9b9155ff7e24e2767dfd0cd34278ab0b1e796335..8062685474a8a7ab6cdcd6a028e2623c10ace4f8 100644 (file)
       "Steps": [
         {
           "TerritoryId": 1185,
-          "InteractionType": "None",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "ItemId": 43913,
               "ItemCount": 1
             }
-          ],
-          "AetheryteShortcut": "Tuliyollal",
-          "AethernetShortcut": [
-            "[Tuliyollal] Aetheryte Plaza",
-            "[Tuliyollal] Wachumeqimeqi"
           ]
         },
         {
           },
           "TerritoryId": 1185,
           "InteractionType": "CompleteQuest",
-          "NextQuestId": 4994
+          "NextQuestId": 4994,
+          "AetheryteShortcut": "Tuliyollal",
+          "AethernetShortcut": [
+            "[Tuliyollal] Aetheryte Plaza",
+            "[Tuliyollal] Wachumeqimeqi"
+          ]
         }
       ]
     }
index 1202151ec6ecad38d5a5ba8aebb7a122dc4d12bb..706b71902a38173d88f82f186b887f0eff083506 100644 (file)
       "Steps": [
         {
           "TerritoryId": 1185,
-          "InteractionType": "None",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "ItemId": 43902,
               "ItemCount": 6,
               "Collectability": 600
             }
-          ],
-          "AetheryteShortcut": "Tuliyollal",
-          "AethernetShortcut": [
-            "[Tuliyollal] Aetheryte Plaza",
-            "[Tuliyollal] Wachumeqimeqi"
           ]
         },
         {
           },
           "TerritoryId": 1185,
           "InteractionType": "CompleteQuest",
-          "NextQuestId": 4995
+          "NextQuestId": 4995,
+          "AetheryteShortcut": "Tuliyollal",
+          "AethernetShortcut": [
+            "[Tuliyollal] Aetheryte Plaza",
+            "[Tuliyollal] Wachumeqimeqi"
+          ]
         }
       ]
     }
index 03be2b822351af1326963d6b9311e55109a4edd0..f79bfff6c450e5c2b71796ceae4a6e9a5dc73ee7 100644 (file)
             }
           }
         },
+        {
+          "TerritoryId": 1189,
+          "InteractionType": "Gather",
+          "ItemsToGather": [
+            {
+              "ItemId": 43914,
+              "ItemCount": 1
+            }
+          ]
+        },
         {
           "Position": {
             "X": 674.17834,
           },
           "TerritoryId": 1189,
           "InteractionType": "WalkTo",
-          "Fly": true,
-          "RequiredGatheredItems": [
-            {
-              "ItemId": 43914,
-              "ItemCount": 1
-            }
-          ]
+          "Fly": true
         },
         {
           "Position": {
index 293ab4d6b9da10defeb8bc3fb23d14c476b34ceb..6ec5d961410f692cd116085c61b02a9fb1d9c583 100644 (file)
@@ -23,8 +23,8 @@
         },
         {
           "TerritoryId": 1188,
-          "InteractionType": "None",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "ItemId": 2003516,
               "AlternativeItemId": 2003517,
index d7abd609680d035476146fb834c8731761f5c304..c9d872c388cb019ea24c014d188da1dc8d88f553 100644 (file)
@@ -23,8 +23,8 @@
         },
         {
           "TerritoryId": 1189,
-          "InteractionType": "None",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "ItemId": 2003529,
               "AlternativeItemId": 2003530,
index e5f1f29913c9026b67ff31f72a60662aae3d57b1..dd7d68cde02ed221c89f396fdf887337c702d3e3 100644 (file)
@@ -23,8 +23,8 @@
         },
         {
           "TerritoryId": 1187,
-          "InteractionType": "None",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "ItemId": 2003539,
               "AlternativeItemId": 2003540,
index 75e19368ba644505fd18430d5b09be0f411fd981..38e43e0f457cb983fe86d7681422db915a898805 100644 (file)
@@ -23,8 +23,8 @@
         },
         {
           "TerritoryId": 1189,
-          "InteractionType": "None",
-          "RequiredGatheredItems": [
+          "InteractionType": "Gather",
+          "ItemsToGather": [
             {
               "ItemId": 2003552,
               "AlternativeItemId": 2003553,
index 4c271e1af4299234bcbd6657afbbb337b9d60937..4282b7c9b8257ca1295d251a1f3fa33820daa397 100644 (file)
             "Jump",
             "Dive",
             "Craft",
+            "Gather",
             "Snipe",
             "Instruction",
             "AcceptQuest",
                 "QuestsAccepted": {
                   "type": "array",
                   "items": {
-                    "type": ["number", "string"]
+                    "type": [
+                      "number",
+                      "string"
+                    ]
                   }
                 },
                 "QuestsCompleted": {
                   "type": "array",
                   "items": {
-                    "type": ["number", "string"]
+                    "type": [
+                      "number",
+                      "string"
+                    ]
                   }
                 },
                 "AetheryteLocked": {
                 "QuestsAccepted": {
                   "type": "array",
                   "items": {
-                    "type": ["number", "string"]
+                    "type": [
+                      "number",
+                      "string"
+                    ]
                   }
                 },
                 "QuestsCompleted": {
                   "type": "array",
                   "items": {
-                    "type": ["number", "string"]
+                    "type": [
+                      "number",
+                      "string"
+                    ]
                   }
                 },
                 "AetheryteLocked": {
             }
           }
         },
-        "RequiredGatheredItems": {
-          "type": "array",
-          "items": {
-            "type": "object",
-            "properties": {
-              "ItemId": {
-                "type": "number"
-              },
-              "AlternativeItemId": {
-                "description": "For leves that allow you to gather two items with different chance percentage, this is the preferred item if the gathering chance is 100% (after buffs)",
-                "type": "number"
-              },
-              "ItemCount": {
-                "type": "number",
-                "exclusiveMinimum": 0
-              },
-              "Collectability": {
-                "type": "number",
-                "minimum": 0,
-                "maximum": 1000
-              },
-              "QuestAcceptedAsClass": {
-                "type": "string",
-                "enum": [
-                  "Miner",
-                  "Botanist"
-                ]
-              }
-            },
-            "required": [
-              "ItemId",
-              "ItemCount"
-            ]
-          }
-        },
         "DelaySecondsAtStart": {
           "description": "Time to wait before starting",
           "type": [
               "ItemCount"
             ]
           }
-        }
-      ],
-      "not": {
-        "anyOf": [
-          {
+        },
+        {
+          "if": {
+            "properties": {
+              "InteractionType": {
+                "const": "Gather"
+              }
+            }
+          },
+          "then": {
+            "properties": {
+              "ItemsToGather": {
+                "type": "array",
+                "description": "Unlike crafting steps, which will always craft a single item id regardless of class, this allows for gathering different items depending on whether you've picked the quest up as miner or botanist",
+                "items": {
+                  "type": "object",
+                  "properties": {
+                    "ItemId": {
+                      "type": "number"
+                    },
+                    "AlternativeItemId": {
+                      "description": "For leves that allow you to gather two items with different chance percentage, this is the preferred item if the gathering chance is 100% (after buffs)",
+                      "type": "number"
+                    },
+                    "ItemCount": {
+                      "type": "number",
+                      "exclusiveMinimum": 0
+                    },
+                    "Collectability": {
+                      "type": "number",
+                      "minimum": 0,
+                      "maximum": 1000
+                    },
+                    "QuestAcceptedAsClass": {
+                      "type": "string",
+                      "enum": [
+                        "Miner",
+                        "Botanist"
+                      ]
+                    }
+                  },
+                  "required": [
+                    "ItemId",
+                    "ItemCount"
+                  ]
+                }
+              }
+            },
             "required": [
-              "SkipIf"
+              "ItemsToGather"
             ]
           }
-        ]
-      }
+        }
+      ]
     }
   }
 }
index bf856da99da36de185e46b9191f1daf7d98a08b7..34320633c6ca11ad607ff3015ee0a8b8c2ebf4ea 100644 (file)
@@ -27,6 +27,7 @@ public sealed class InteractionTypeConverter() : EnumConverter<EInteractionType>
         { EInteractionType.Jump, "Jump" },
         { EInteractionType.Dive, "Dive" },
         { EInteractionType.Craft, "Craft" },
+        { EInteractionType.Gather, "Gather" },
         { EInteractionType.Snipe, "Snipe" },
         { EInteractionType.Instruction, "Instruction" },
         { EInteractionType.AcceptQuest, "AcceptQuest" },
index f251b5aee8eb8bf88a422721a847211802d7aea6..d9942ef45fd484c67a68b6de79f5ff2a2311ab69 100644 (file)
@@ -26,6 +26,7 @@ public enum EInteractionType
     Jump,
     Dive,
     Craft,
+    Gather,
     Snipe,
 
     /// <summary>
@@ -38,7 +39,4 @@ public enum EInteractionType
     AcceptLeve,
     InitiateLeve,
     CompleteLeve,
-
-    // unmapped extra types below
-    InternalGather,
 }
index 8ee496bfc55d2c372290244cf8f56661dc56e3a4..da851c83426e0ecc9dd8a071aee6e891a2ff1461 100644 (file)
@@ -74,7 +74,7 @@ public sealed class QuestStep
     public SkipConditions? SkipConditions { get; set; }
 
     public List<List<QuestWorkValue>?> RequiredQuestVariables { get; set; } = new();
-    public List<GatheredItem> RequiredGatheredItems { get; set; } = [];
+    public List<GatheredItem> ItemsToGather { get; set; } = [];
     public List<QuestWorkValue?> CompletionQuestVariablesFlags { get; set; } = [];
     public List<DialogueChoice> DialogueChoices { get; set; } = [];
     public List<uint> PointMenuChoices { get; set; } = [];
index 509d8372939c29016aaa300e9643d4c2fbee2b3a..819d8b2570da348a4e6b32e92b92d3dc9523b4fc 100644 (file)
@@ -134,8 +134,8 @@ internal sealed class ContextMenuController : IDisposable
             .Single(x => x is SatisfactionSupplyInfo);
         if (_questRegistry.TryGetQuest(info.QuestId, out Quest? quest))
         {
-            var step = quest.FindSequence(0)!.FindStep(0)!;
-            step.RequiredGatheredItems =
+            var step = quest.FindSequence(0)!.Steps.Single(x => x.InteractionType == EInteractionType.Gather);
+            step.ItemsToGather =
             [
                 new GatheredItem
                 {
index 35f89d06632bd76db8c590f904f881aa7b2db902..ce083331eb1fdd543a3bb50f989c151d312a3523 100644 (file)
@@ -658,9 +658,9 @@ internal sealed class InteractionUiController : IDisposable
                 step.TargetTerritoryId);
 
         if (step != null && (step.TerritoryId != _clientState.TerritoryType || step.TargetTerritoryId == null) &&
-            step.RequiredGatheredItems.Count > 0)
+            step.InteractionType == EInteractionType.Gather)
         {
-            if (_gatheringData.TryGetGatheringPointId(step.RequiredGatheredItems[0].ItemId,
+            if (_gatheringData.TryGetGatheringPointId(step.ItemsToGather[0].ItemId,
                     (EClassJob?)_clientState.LocalPlayer?.ClassJob.Id ?? EClassJob.Adventurer,
                     out GatheringPointId? gatheringPointId) &&
                 _gatheringPointRegistry.TryGetGatheringPoint(gatheringPointId, out GatheringRoot? root))
index ffa012440af3bf87e0bc6fbcd73ba7c8a15a5920..77860f7e772e0a53c3a6013a1d80e8977af68f13 100644 (file)
@@ -186,14 +186,13 @@ internal sealed unsafe class GatheringController : MiniTaskController<GatheringC
                 pointOnFloor = pointOnFloor.Value with { Y = pointOnFloor.Value.Y + (fly ? 3f : 0f) };
 
             _taskQueue.Enqueue(_moveFactory.Move(new MoveTo.MoveParams(territoryId, pointOnFloor ?? averagePosition,
-                50f,
-                Fly: fly, IgnoreDistanceToObject: true)));
+                null, 50f, Fly: fly, IgnoreDistanceToObject: true)));
         }
 
         _taskQueue.Enqueue(new MoveToLandingLocation(territoryId, fly, currentNode, _moveFactory, _gameFunctions,
             _objectTable, _loggerFactory.CreateLogger<MoveToLandingLocation>()));
         _taskQueue.Enqueue(_mountFactory.Unmount());
-        _taskQueue.Enqueue(_interactFactory.Interact(currentNode.DataId, null, EInteractionType.InternalGather, true));
+        _taskQueue.Enqueue(_interactFactory.Interact(currentNode.DataId, null, EInteractionType.Gather, true));
 
         QueueGatherNode(currentNode);
     }
index 63dfba1060b68a30ebb7f013ed0415e0cd631411..8d905b952b8ade56e6a21b654765df11b9df4b3f 100644 (file)
@@ -81,7 +81,7 @@ internal abstract class MiniTaskController<T>
 
                 while (_taskQueue.TryDequeue(out ITask? nextTask))
                 {
-                    if (nextTask is ILastTask or GatheringRequiredItems.SkipMarker)
+                    if (nextTask is ILastTask or Gather.SkipMarker)
                     {
                         _currentTask = nextTask;
                         return;
index 5694d65ec696e8ae3ce1cd3b491fb2dfc94b0cc0..a9ebe4a5d9897bf378ee28816638488bfbec3a1e 100644 (file)
@@ -41,8 +41,8 @@ internal sealed class MoveToLandingLocation(
             target.ToString("G", CultureInfo.InvariantCulture), degrees, range);
 
         bool fly = flyBetweenNodes && gameFunctions.IsFlyingUnlocked(territoryId);
-        _moveTask = moveFactory.Move(new MoveTo.MoveParams(territoryId, target, 0.25f, DataId: gatheringNode.DataId,
-            Fly: fly, IgnoreDistanceToObject: true));
+        _moveTask = moveFactory.Move(new MoveTo.MoveParams(territoryId, target, null, 0.25f,
+            DataId: gatheringNode.DataId, Fly: fly, IgnoreDistanceToObject: true));
         return _moveTask.Start();
     }
 
index e233bfde3ac04a78c42792c4ab750f492af6fe58..a88e6dda5a79ceeb452eeb7151e382c3cfd566a1 100644 (file)
@@ -162,7 +162,7 @@ internal static class Interact
                 if (_interactionState == EInteractionState.InteractionConfirmed)
                     return ETaskResult.TaskComplete;
 
-                if (interactionType == EInteractionType.InternalGather && condition[ConditionFlag.Gathering])
+                if (interactionType == EInteractionType.Gather && condition[ConditionFlag.Gathering])
                     return ETaskResult.TaskComplete;
             }
 
index 358c30d9306c5670161028cb98e05886f3fccfe6..8ca5f40af5d9133233ca76276ea539bffa07f5ed 100644 (file)
@@ -72,7 +72,7 @@ internal static class UseItem
                     mountFactory.Mount(140,
                         nextPosition != null ? Mount.EMountIf.AwayFromPosition : Mount.EMountIf.Always,
                         nextPosition),
-                    moveFactory.Move(new MoveTo.MoveParams(140, new(-408.92343f, 23.167036f, -351.16223f), 0.25f,
+                    moveFactory.Move(new MoveTo.MoveParams(140, new(-408.92343f, 23.167036f, -351.16223f), null, 0.25f,
                         DataId: null, DisableNavMesh: true, Sprint: false, Fly: false))
                 ];
             }
diff --git a/Questionable/Controller/Steps/Shared/Gather.cs b/Questionable/Controller/Steps/Shared/Gather.cs
new file mode 100644 (file)
index 0000000..cc5d9cf
--- /dev/null
@@ -0,0 +1,163 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Dalamud.Game.Text;
+using Dalamud.Plugin.Services;
+using FFXIVClientStructs.FFXIV.Application.Network.WorkDefinitions;
+using FFXIVClientStructs.FFXIV.Client.Game;
+using LLib.GameData;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Questionable.Controller.Steps.Common;
+using Questionable.Data;
+using Questionable.Model;
+using Questionable.Model.Gathering;
+using Questionable.Model.Questing;
+
+namespace Questionable.Controller.Steps.Shared;
+
+internal static class Gather
+{
+    internal sealed class Factory(
+        IServiceProvider serviceProvider,
+        MovementController movementController,
+        GatheringController gatheringController,
+        GatheringPointRegistry gatheringPointRegistry,
+        IClientState clientState,
+        GatheringData gatheringData,
+        TerritoryData territoryData,
+        ILogger<Factory> logger) : ITaskFactory
+    {
+        public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
+        {
+            if (step.InteractionType != EInteractionType.Gather)
+                yield break;
+
+            foreach (var itemToGather in step.ItemsToGather)
+            {
+                EClassJob currentClassJob = (EClassJob)clientState.LocalPlayer!.ClassJob.Id;
+                EClassJob classJob = currentClassJob;
+                if (itemToGather.QuestAcceptedAsClass != null)
+                {
+                    classJob = (EClassJob)itemToGather.QuestAcceptedAsClass.Value;
+                    if (!IsClassJobQuestWasAcceptedWith(quest.Id, classJob))
+                        continue;
+                }
+
+                if (!gatheringData.TryGetGatheringPointId(itemToGather.ItemId, classJob,
+                        out GatheringPointId? gatheringPointId))
+                    throw new TaskException($"No gathering point found for item {itemToGather.ItemId}");
+
+                if (!gatheringPointRegistry.TryGetGatheringPoint(gatheringPointId, out GatheringRoot? gatheringRoot))
+                    throw new TaskException($"No path found for gathering point {gatheringPointId}");
+
+                if (classJob != currentClassJob)
+                {
+                    yield return new SwitchClassJob(classJob, clientState);
+                }
+
+                if (HasRequiredItems(itemToGather))
+                    continue;
+
+                using (var _ = logger.BeginScope("Gathering(inner)"))
+                {
+                    QuestSequence gatheringSequence = new QuestSequence
+                    {
+                        Sequence = 0,
+                        Steps = gatheringRoot.Steps
+                    };
+                    foreach (var gatheringStep in gatheringSequence.Steps)
+                    {
+                        foreach (var task in serviceProvider.GetRequiredService<TaskCreator>()
+                                     .CreateTasks(quest, gatheringSequence, gatheringStep))
+                            if (task is WaitAtEnd.NextStep)
+                                yield return CreateSkipMarkerTask();
+                            else
+                                yield return task;
+                    }
+                }
+
+                ushort territoryId = gatheringRoot.Steps.Last().TerritoryId;
+                yield return new WaitConditionTask(() => clientState.TerritoryType == territoryId,
+                    $"Wait(territory: {territoryData.GetNameAndId(territoryId)})");
+
+                yield return new WaitConditionTask(() => movementController.IsNavmeshReady,
+                    "Wait(navmesh ready)");
+
+                yield return CreateStartGatheringTask(gatheringPointId, itemToGather);
+                yield return new WaitAtEnd.WaitDelay();
+            }
+        }
+
+        private unsafe bool IsClassJobQuestWasAcceptedWith(ElementId questId, EClassJob expectedClassJob)
+        {
+            if (questId is not QuestId)
+                return true;
+
+            QuestWork* questWork = QuestManager.Instance()->GetQuestById(questId.Value);
+            if (questWork->AcceptClassJob != 0)
+                return (EClassJob)questWork->AcceptClassJob == expectedClassJob;
+
+            return true;
+        }
+
+        private unsafe bool HasRequiredItems(GatheredItem itemToGather)
+        {
+            InventoryManager* inventoryManager = InventoryManager.Instance();
+            return inventoryManager != null &&
+                   inventoryManager->GetInventoryItemCount(itemToGather.ItemId,
+                       minCollectability: (short)itemToGather.Collectability) >=
+                   itemToGather.ItemCount;
+        }
+
+        private StartGathering CreateStartGatheringTask(GatheringPointId gatheringPointId, GatheredItem gatheredItem)
+        {
+            return new StartGathering(gatheringPointId, gatheredItem, gatheringController);
+        }
+
+        private static SkipMarker CreateSkipMarkerTask()
+        {
+            return new SkipMarker();
+        }
+    }
+
+    private sealed class StartGathering(
+        GatheringPointId gatheringPointId,
+        GatheredItem gatheredItem,
+        GatheringController gatheringController) : ITask
+    {
+        public bool Start()
+        {
+            return gatheringController.Start(new GatheringController.GatheringRequest(gatheringPointId,
+                gatheredItem.ItemId, gatheredItem.AlternativeItemId, gatheredItem.ItemCount,
+                gatheredItem.Collectability));
+        }
+
+        public ETaskResult Update()
+        {
+            if (gatheringController.Update() == GatheringController.EStatus.Complete)
+                return ETaskResult.TaskComplete;
+
+            return ETaskResult.StillRunning;
+        }
+
+        public override string ToString()
+        {
+            if (gatheredItem.Collectability == 0)
+                return $"Gather({gatheredItem.ItemCount}x {gatheredItem.ItemId})";
+            else
+                return
+                    $"Gather({gatheredItem.ItemCount}x {gatheredItem.ItemId} {SeIconChar.Collectible.ToIconString()} {gatheredItem.Collectability})";
+        }
+    }
+
+    /// <summary>
+    /// A task that does nothing, but if we're skipping a step, this will be the task next in queue to be executed (instead of progressing to the next step) if gathering.
+    /// </summary>
+    internal sealed class SkipMarker : ITask
+    {
+        public bool Start() => true;
+        public ETaskResult Update() => ETaskResult.TaskComplete;
+        public override string ToString() => "Gather/SkipMarker";
+    }
+}
diff --git a/Questionable/Controller/Steps/Shared/GatheringRequiredItems.cs b/Questionable/Controller/Steps/Shared/GatheringRequiredItems.cs
deleted file mode 100644 (file)
index 48ad33b..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Dalamud.Game.Text;
-using Dalamud.Plugin.Services;
-using FFXIVClientStructs.FFXIV.Application.Network.WorkDefinitions;
-using FFXIVClientStructs.FFXIV.Client.Game;
-using LLib.GameData;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-using Questionable.Controller.Steps.Common;
-using Questionable.Data;
-using Questionable.Model;
-using Questionable.Model.Gathering;
-using Questionable.Model.Questing;
-
-namespace Questionable.Controller.Steps.Shared;
-
-internal static class GatheringRequiredItems
-{
-    internal sealed class Factory(
-        IServiceProvider serviceProvider,
-        MovementController movementController,
-        GatheringController gatheringController,
-        GatheringPointRegistry gatheringPointRegistry,
-        IClientState clientState,
-        GatheringData gatheringData,
-        TerritoryData territoryData,
-        ILogger<Factory> logger) : ITaskFactory
-    {
-        public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
-        {
-            foreach (var requiredGatheredItems in step.RequiredGatheredItems)
-            {
-                EClassJob currentClassJob = (EClassJob)clientState.LocalPlayer!.ClassJob.Id;
-                EClassJob classJob = currentClassJob;
-                if (requiredGatheredItems.QuestAcceptedAsClass != null)
-                {
-                    classJob = (EClassJob)requiredGatheredItems.QuestAcceptedAsClass.Value;
-                    if (!IsClassJobQuestWasAcceptedWith(quest.Id, classJob))
-                        continue;
-                }
-
-                if (!gatheringData.TryGetGatheringPointId(requiredGatheredItems.ItemId, classJob,
-                        out GatheringPointId? gatheringPointId))
-                    throw new TaskException($"No gathering point found for item {requiredGatheredItems.ItemId}");
-
-                if (!gatheringPointRegistry.TryGetGatheringPoint(gatheringPointId, out GatheringRoot? gatheringRoot))
-                    throw new TaskException($"No path found for gathering point {gatheringPointId}");
-
-                if (classJob != currentClassJob)
-                {
-                    yield return new SwitchClassJob(classJob, clientState);
-                }
-
-                if (HasRequiredItems(requiredGatheredItems))
-                    continue;
-
-                using (var _ = logger.BeginScope("Gathering(inner)"))
-                {
-                    QuestSequence gatheringSequence = new QuestSequence
-                    {
-                        Sequence = 0,
-                        Steps = gatheringRoot.Steps
-                    };
-                    foreach (var gatheringStep in gatheringSequence.Steps)
-                    {
-                        foreach (var task in serviceProvider.GetRequiredService<TaskCreator>()
-                                     .CreateTasks(quest, gatheringSequence, gatheringStep))
-                            if (task is WaitAtEnd.NextStep)
-                                yield return CreateSkipMarkerTask();
-                            else
-                                yield return task;
-                    }
-                }
-
-                ushort territoryId = gatheringRoot.Steps.Last().TerritoryId;
-                yield return new WaitConditionTask(() => clientState.TerritoryType == territoryId,
-                    $"Wait(territory: {territoryData.GetNameAndId(territoryId)})");
-
-                yield return new WaitConditionTask(() => movementController.IsNavmeshReady,
-                    "Wait(navmesh ready)");
-
-                yield return CreateStartGatheringTask(gatheringPointId, requiredGatheredItems);
-                yield return new WaitAtEnd.WaitDelay();
-            }
-        }
-
-        private unsafe bool IsClassJobQuestWasAcceptedWith(ElementId questId, EClassJob expectedClassJob)
-        {
-            if (questId is not QuestId)
-                return true;
-
-            QuestWork* questWork = QuestManager.Instance()->GetQuestById(questId.Value);
-            if (questWork->AcceptClassJob != 0)
-                return (EClassJob)questWork->AcceptClassJob == expectedClassJob;
-
-            return true;
-        }
-
-        private unsafe bool HasRequiredItems(GatheredItem requiredGatheredItems)
-        {
-            InventoryManager* inventoryManager = InventoryManager.Instance();
-            return inventoryManager != null &&
-                   inventoryManager->GetInventoryItemCount(requiredGatheredItems.ItemId,
-                       minCollectability: (short)requiredGatheredItems.Collectability) >=
-                   requiredGatheredItems.ItemCount;
-        }
-
-        private StartGathering CreateStartGatheringTask(GatheringPointId gatheringPointId, GatheredItem gatheredItem)
-        {
-            return new StartGathering(gatheringPointId, gatheredItem, gatheringController);
-        }
-
-        private static SkipMarker CreateSkipMarkerTask()
-        {
-            return new SkipMarker();
-        }
-    }
-
-    private sealed class StartGathering(
-        GatheringPointId gatheringPointId,
-        GatheredItem gatheredItem,
-        GatheringController gatheringController) : ITask
-    {
-        public bool Start()
-        {
-            return gatheringController.Start(new GatheringController.GatheringRequest(gatheringPointId,
-                gatheredItem.ItemId, gatheredItem.AlternativeItemId, gatheredItem.ItemCount,
-                gatheredItem.Collectability));
-        }
-
-        public ETaskResult Update()
-        {
-            if (gatheringController.Update() == GatheringController.EStatus.Complete)
-                return ETaskResult.TaskComplete;
-
-            return ETaskResult.StillRunning;
-        }
-
-        public override string ToString()
-        {
-            if (gatheredItem.Collectability == 0)
-                return $"Gather({gatheredItem.ItemCount}x {gatheredItem.ItemId})";
-            else
-                return
-                    $"Gather({gatheredItem.ItemCount}x {gatheredItem.ItemId} {SeIconChar.Collectible.ToIconString()} {gatheredItem.Collectability})";
-        }
-    }
-
-    /// <summary>
-    /// A task that does nothing, but if we're skipping a step, this will be the task next in queue to be executed (instead of progressing to the next step) if gathering.
-    /// </summary>
-    internal sealed class SkipMarker : ITask
-    {
-        public bool Start() => true;
-        public ETaskResult Update() => ETaskResult.TaskComplete;
-        public override string ToString() => "Gather/SkipMarker";
-    }
-}
index ba76a6875f7b903ab03d2362bb40c4ea7413b080..cf905a6500e79539137a13265772994ef21e0571 100644 (file)
@@ -67,7 +67,7 @@ internal static class MoveTo
 
         public ITask Move(MoveParams moveParams)
         {
-            return new MoveInternal(moveParams, movementController, gameFunctions,
+            return new MoveInternal(moveParams, movementController, mountFactory, gameFunctions,
                 loggerFactory.CreateLogger<MoveInternal>(), clientState, dataManager);
         }
 
@@ -95,74 +95,18 @@ internal static class MoveTo
                 $"Wait(territory: {territoryData.GetNameAndId(step.TerritoryId)})");
 
             if (!step.DisableNavmesh)
+            {
                 yield return new WaitConditionTask(() => movementController.IsNavmeshReady,
                     "Wait(navmesh ready)");
 
-            float stopDistance = step.CalculateActualStopDistance();
-            Vector3? position = clientState.LocalPlayer?.Position;
-            float actualDistance = position == null ? float.MaxValue : Vector3.Distance(position.Value, destination);
-
-            // if we teleport to a different zone, assume we always need to move; this is primarily relevant for cases
-            // where you're e.g. in Lakeland, and the step navigates via Crystarium → Tesselation back into the same
-            // zone.
-            //
-            // Side effects of this check being broken include:
-            //   - mounting when near the target npc (if you spawn close enough for the next step)
-            //   - trying to fly when near the target npc (if close enough where no movement is required)
-            if (step.AetheryteShortcut != null &&
-                aetheryteData.TerritoryIds[step.AetheryteShortcut.Value] != step.TerritoryId)
-            {
-                logger.LogDebug("Aetheryte: Changing distance to max, previous distance: {Distance}", actualDistance);
-                actualDistance = float.MaxValue;
-            }
-
-            // Fixes a case where you're initiating the gathering step when standing next to the NPC already
-            // TODO maybe this should be delayed up until starting movement
-            if (questId is SatisfactionSupplyNpcId)
-            {
-                logger.LogDebug("SatisfactionSupply: Changing distance to max, previous distance: {Distance}",
-                    actualDistance);
-                actualDistance = float.MaxValue;
-            }
-
-            if (step.Mount == true)
-                yield return mountFactory.Mount(step.TerritoryId, Mount.EMountIf.Always);
-            else if (step.Mount == false)
-                yield return mountFactory.Unmount();
-
-            if (!step.DisableNavmesh)
-            {
-                if (step.Mount == null)
-                {
-                    Mount.EMountIf mountIf =
-                        actualDistance > stopDistance && step.Fly == true &&
-                        gameFunctions.IsFlyingUnlocked(step.TerritoryId)
-                            ? Mount.EMountIf.Always
-                            : Mount.EMountIf.AwayFromPosition;
-                    yield return mountFactory.Mount(step.TerritoryId, mountIf, destination);
-                }
-
-                if (actualDistance > stopDistance)
-                {
-                    yield return Move(step, destination);
-                }
-                else
-                    logger.LogInformation("Skipping move task, distance: {ActualDistance} < {StopDistance}",
-                        actualDistance, stopDistance);
+                yield return Move(step, destination);
             }
             else
             {
-                // navmesh won't move close enough
-                if (actualDistance > stopDistance)
-                {
-                    yield return Move(step, destination);
-                }
-                else
-                    logger.LogInformation("Skipping move task, distance: {ActualDistance} < {StopDistance}",
-                        actualDistance, stopDistance);
+                yield return Move(step, destination);
             }
 
-            if (step.Fly == true && step.Land == true)
+            if (step is { Fly: true, Land: true })
                 yield return Land();
         }
     }
@@ -171,6 +115,8 @@ internal static class MoveTo
     {
         private readonly string _cannotExecuteAtThisTime;
         private readonly MovementController _movementController;
+        private readonly Mount.Factory _mountFactory;
+        private readonly GameFunctions _gameFunctions;
         private readonly ILogger<MoveInternal> _logger;
         private readonly IClientState _clientState;
 
@@ -178,15 +124,19 @@ internal static class MoveTo
         private readonly Vector3 _destination;
         private readonly MoveParams _moveParams;
         private bool _canRestart;
+        private ITask? _mountTask;
 
         public MoveInternal(MoveParams moveParams,
             MovementController movementController,
+            Mount.Factory mountFactory,
             GameFunctions gameFunctions,
             ILogger<MoveInternal> logger,
             IClientState clientState,
             IDataManager dataManager)
         {
             _movementController = movementController;
+            _mountFactory = mountFactory;
+            _gameFunctions = gameFunctions;
             _logger = logger;
             _clientState = clientState;
             _cannotExecuteAtThisTime = dataManager.GetString<LogMessage>(579, x => x.Text)!;
@@ -225,13 +175,65 @@ internal static class MoveTo
 
         public bool Start()
         {
-            _logger.LogInformation("Moving to {Destination}", _destination.ToString("G", CultureInfo.InvariantCulture));
-            _startAction();
+            float stopDistance = _moveParams.StopDistance ?? QuestStep.DefaultStopDistance;
+            Vector3? position = _clientState.LocalPlayer?.Position;
+            float actualDistance = position == null ? float.MaxValue : Vector3.Distance(position.Value, _destination);
+
+            if (_moveParams.Mount == true)
+            {
+                var mountTask = _mountFactory.Mount(_moveParams.TerritoryId, Mount.EMountIf.Always);
+                if (mountTask.Start())
+                {
+                    _mountTask = mountTask;
+                    return true;
+                }
+            }
+            else if (_moveParams.Mount == false)
+            {
+                var mountTask = _mountFactory.Unmount();
+                if (mountTask.Start())
+                {
+                    _mountTask = mountTask;
+                    return true;
+                }
+            }
+
+            if (!_moveParams.DisableNavMesh)
+            {
+                if (_moveParams.Mount == null)
+                {
+                    Mount.EMountIf mountIf =
+                        actualDistance > stopDistance && _moveParams.Fly &&
+                        _gameFunctions.IsFlyingUnlocked(_moveParams.TerritoryId)
+                            ? Mount.EMountIf.Always
+                            : Mount.EMountIf.AwayFromPosition;
+                    var mountTask = _mountFactory.Mount(_moveParams.TerritoryId, mountIf, _destination);
+                    if (mountTask.Start())
+                    {
+                        _mountTask = mountTask;
+                        return true;
+                    }
+                }
+            }
+
+            _mountTask = new NoOpTask();
             return true;
         }
 
         public ETaskResult Update()
         {
+            if (_mountTask != null)
+            {
+                if (_mountTask.Update() == ETaskResult.TaskComplete)
+                {
+                    _mountTask = null;
+
+                    _logger.LogInformation("Moving to {Destination}", _destination.ToString("G", CultureInfo.InvariantCulture));
+                    _startAction();
+                }
+                return ETaskResult.StillRunning;
+            }
+
             if (_movementController.IsPathfinding || _movementController.IsPathRunning)
                 return ETaskResult.StillRunning;
 
@@ -269,9 +271,17 @@ internal static class MoveTo
         }
     }
 
+    private sealed class NoOpTask : ITask
+    {
+        public bool Start() => true;
+
+        public ETaskResult Update() => ETaskResult.TaskComplete;
+    }
+
     internal sealed record MoveParams(
         ushort TerritoryId,
         Vector3 Destination,
+        bool? Mount = null,
         float? StopDistance = null,
         uint? DataId = null,
         bool DisableNavMesh = false,
@@ -284,6 +294,7 @@ internal static class MoveTo
         public MoveParams(QuestStep step, Vector3 destination)
             : this(step.TerritoryId,
                 destination,
+                step.Mount,
                 step.CalculateActualStopDistance(),
                 step.DataId,
                 step.DisableNavmesh,
index b5be5760c8ecfe1ac1a20dfcf670b5fb15ab6c4f..b587835351912a3c3a649281166b4bdbaa05ad4d 100644 (file)
@@ -137,7 +137,7 @@ public sealed class QuestionablePlugin : IDalamudPlugin
         // task factories
         serviceCollection.AddTaskFactory<StepDisabled.Factory>();
         serviceCollection.AddTaskFactory<EquipRecommended.BeforeDutyOrInstance>();
-        serviceCollection.AddTaskFactory<GatheringRequiredItems.Factory>();
+        serviceCollection.AddTaskFactory<Gather.Factory>();
         serviceCollection.AddTaskFactory<AetheryteShortcut.Factory>();
         serviceCollection.AddTaskFactory<SkipCondition.Factory>();
         serviceCollection.AddTaskFactory<AethernetShortcut.Factory>();