Improve quest chain handling (auto-accepting next quest, dialogue choices) v1.4
authorLiza Carvelli <liza@carvel.li>
Fri, 12 Jul 2024 00:42:37 +0000 (02:42 +0200)
committerLiza Carvelli <liza@carvel.li>
Fri, 12 Jul 2024 00:42:37 +0000 (02:42 +0200)
26 files changed:
QuestPaths/Dawntrail/RoleQuests/Healer/4829_An Antidote for Anarchy.json
QuestPaths/Dawntrail/RoleQuests/MagicalRanged/4845_Floundering Fame.json
QuestPaths/Dawntrail/RoleQuests/MagicalRanged/4846_Behind the Helm.json [new file with mode: 0644]
QuestPaths/Dawntrail/RoleQuests/MagicalRanged/4847_Heroes and Pretenders.json [new file with mode: 0644]
QuestPaths/Dawntrail/SideQuests/Urqopacha/5054_Springing the Trap.json
QuestPaths/Endwalker/Tribal/Arkasodara/4567_Vanaspati's Blessing.json [new file with mode: 0644]
QuestPaths/Endwalker/Tribal/Arkasodara/4568_Hells Hath No Fury as a Hippo Scorned.json [new file with mode: 0644]
QuestPaths/Endwalker/Tribal/Arkasodara/4569_Tusk Trouble.json [new file with mode: 0644]
QuestPaths/Endwalker/Unlocks/Hunts/4176_The Hunt for Specimens.json [new file with mode: 0644]
QuestPaths/Endwalker/Unlocks/Hunts/4177_That Specimen Came from the Moon.json [new file with mode: 0644]
QuestPaths/Endwalker/Unlocks/Hunts/4178_A Hunt for the Ages.json [new file with mode: 0644]
QuestPaths/Endwalker/Unlocks/Hunts/4179_Perfect Specimens.json [new file with mode: 0644]
QuestPaths/Shadowbringers/MSQ/H-5.2/3768_A Whale's Tale.json
QuestPaths/Shadowbringers/MSQ/I-5.3/3772_Heroic Dreams.json
QuestPaths/Shadowbringers/MSQ/I-5.3/3774_Food for the Soul.json
QuestPaths/Shadowbringers/MSQ/I-5.3/3775_Faded Memories.json
QuestPaths/quest-v1.json
Questionable.Model/V1/Converter/SkipConditionConverter.cs
Questionable.Model/V1/ESkipCondition.cs
Questionable/Controller/GameUiController.cs
Questionable/Controller/QuestController.cs
Questionable/Controller/Steps/BaseFactory/SkipCondition.cs
Questionable/Data/QuestData.cs
Questionable/Model/QuestInfo.cs
Questionable/Windows/DebugOverlay.cs
Questionable/Windows/QuestWindow.cs

index a994b992a7d1804e4ded693605b11a4b338383a4..d8ee70078ab9c6b82c6f1b104ca5c0f731430f09 100644 (file)
           ]
         }
       ]
+    },
+    {
+      "Sequence": 1,
+      "Steps": [
+        {
+          "DataId": 1046319,
+          "Position": {
+            "X": -335.3476,
+            "Y": 69.418495,
+            "Z": 155.87085
+          },
+          "TerritoryId": 137,
+          "InteractionType": "Interact",
+          "AetheryteShortcut": "Eastern La Noscea - Wineport"
+        }
+      ]
+    },
+    {
+      "Sequence": 2,
+      "Steps": [
+        {
+          "DataId": 1046319,
+          "Position": {
+            "X": -335.3476,
+            "Y": 69.418495,
+            "Z": 155.87085
+          },
+          "TerritoryId": 137,
+          "InteractionType": "SinglePlayerDuty"
+        }
+      ]
+    },
+    {
+      "Sequence": 3,
+      "Steps": [
+        {
+          "Position": {
+            "X": 0,
+            "Y": 0,
+            "Z": 0
+          },
+          "TerritoryId": 1,
+          "InteractionType": "WalkTo",
+          "Comment": "Filler"
+        }
+      ]
+    },
+    {
+      "Sequence": 4,
+      "Steps": [
+        {
+          "DataId": 1046319,
+          "Position": {
+            "X": -335.3476,
+            "Y": 69.418495,
+            "Z": 155.87085
+          },
+          "StopDistance": 5,
+          "TerritoryId": 137,
+          "InteractionType": "Interact"
+        }
+      ]
+    },
+    {
+      "Sequence": 5,
+      "Steps": [
+        {
+          "DataId": 1046320,
+          "Position": {
+            "X": 267.01758,
+            "Y": -25,
+            "Z": 264.88135
+          },
+          "TerritoryId": 138,
+          "InteractionType": "Interact",
+          "AetheryteShortcut": "Western La Noscea - Aleport"
+        }
+      ]
+    },
+    {
+      "Sequence": 255,
+      "Steps": [
+        {
+          "DataId": 1046289,
+          "Position": {
+            "X": -64.62195,
+            "Y": -17.95485,
+            "Z": 201.28174
+          },
+          "TerritoryId": 1185,
+          "InteractionType": "CompleteQuest",
+          "AetheryteShortcut": "Tuliyollal",
+          "AethernetShortcut": [
+            "[Tuliyollal] Aetheryte Plaza",
+            "[Tuliyollal] Bayside Bevy Marketplace"
+          ]
+        }
+      ]
     }
   ]
 }
index 121237bc994218d507abe838cbe9085a61b0feba..b6ab46ab4be4e887e7dccc256d5f40b037cc3e48 100644 (file)
           "InteractionType": "Interact"
         }
       ]
+    },
+    {
+      "Sequence": 6,
+      "Steps": [
+        {
+          "DataId": 2013713,
+          "Position": {
+            "X": 362.35596,
+            "Y": 3.616333,
+            "Z": -241.77924
+          },
+          "StopDistance": 0.25,
+          "TerritoryId": 957,
+          "InteractionType": "Interact",
+          "Fly": true,
+          "SkipIf": [
+            "NotTargetable"
+          ],
+          "DialogueChoices": [
+            {
+              "Type": "YesNo",
+              "Prompt": "TEXT_KINGBA531_04845_Q1_000_054",
+              "Yes": true
+            }
+          ],
+          "Comment": "retry point"
+        },
+        {
+          "DataId": 1048364,
+          "Position": {
+            "X": 387.43045,
+            "Y": 5.8062716,
+            "Z": -203.20459
+          },
+          "TerritoryId": 957,
+          "InteractionType": "WaitForNpcAtPosition",
+          "StopDistance": 50,
+          "Mount": false,
+          "Sprint": false
+        },
+        {
+          "Position": {
+            "X": 386.85394,
+            "Y": 3.0972311,
+            "Z": -220.57103
+          },
+          "TerritoryId": 957,
+          "InteractionType": "WalkTo",
+          "Mount": false,
+          "Sprint": false
+        },
+        {
+          "DataId": 1048364,
+          "Position": {
+            "X": 398.46808,
+            "Y": 12.103142,
+            "Z": -174.068
+          },
+          "TerritoryId": 957,
+          "InteractionType": "WaitForNpcAtPosition",
+          "StopDistance": 50,
+          "Mount": false,
+          "Sprint": false
+        },
+        {
+          "Position": {
+            "X": 395.88028,
+            "Y": 10.267179,
+            "Z": -192.21916
+          },
+          "TerritoryId": 957,
+          "InteractionType": "WalkTo",
+          "Mount": false,
+          "Sprint": false
+        },
+        {
+          "DataId": 1048364,
+          "Position": {
+            "X": 395.6862,
+            "Y": 11.099065,
+            "Z": -169.7558
+          },
+          "TerritoryId": 957,
+          "InteractionType": "WaitForNpcAtPosition",
+          "StopDistance": 50,
+          "Mount": false,
+          "Sprint": false
+        },
+        {
+          "Position": {
+            "X": 398.42825,
+            "Y": 12.946791,
+            "Z": -180.08061
+          },
+          "TerritoryId": 957,
+          "InteractionType": "WalkTo",
+          "Mount": false,
+          "Sprint": false
+        },
+        {
+          "Position": {
+            "X": 368.02908,
+            "Y": 5.7749786,
+            "Z": -135.06207
+          },
+          "TerritoryId": 957,
+          "InteractionType": "WalkTo",
+          "Mount": false,
+          "Sprint": false
+        },
+        {
+          "Position": {
+            "X": 300.81885,
+            "Y": 18.925224,
+            "Z": -43.56831
+          },
+          "TerritoryId": 957,
+          "InteractionType": "WalkTo",
+          "Mount": false,
+          "Sprint": false
+        },
+        {
+          "DataId": 1048364,
+          "Position": {
+            "X": 274.41418,
+            "Y": 17.838093,
+            "Z": -2.1020741
+          },
+          "TerritoryId": 957,
+          "InteractionType": "WaitForNpcAtPosition",
+          "StopDistance": 50,
+          "Mount": false,
+          "Sprint": false
+        },
+        {
+          "Position": {
+            "X": 256.60135,
+            "Y": 19.312042,
+            "Z": -1.2628903
+          },
+          "TerritoryId": 957,
+          "InteractionType": "WalkTo",
+          "Mount": false,
+          "Sprint": false
+        },
+        {
+          "Position": {
+            "X": 244.453,
+            "Y": 16.725914,
+            "Z": 14.936783
+          },
+          "TerritoryId": 957,
+          "InteractionType": "WalkTo",
+          "Mount": false,
+          "Sprint": false
+        }
+      ]
+    },
+    {
+      "Sequence": 7,
+      "Steps": [
+        {
+          "DataId": 1048368,
+          "Position": {
+            "X": 239.33765,
+            "Y": 11.061386,
+            "Z": 69.99304
+          },
+          "TerritoryId": 957,
+          "InteractionType": "Interact"
+        }
+      ]
+    },
+    {
+      "Sequence": 255,
+      "Steps": [
+        {
+          "DataId": 1048331,
+          "Position": {
+            "X": 214.03821,
+            "Y": 5.2600574,
+            "Z": 628.3817
+          },
+          "TerritoryId": 957,
+          "InteractionType": "CompleteQuest",
+          "AetheryteShortcut": "Thavnair - Yedlihmad",
+          "NextQuestId": 4846
+        }
+      ]
     }
   ]
 }
diff --git a/QuestPaths/Dawntrail/RoleQuests/MagicalRanged/4846_Behind the Helm.json b/QuestPaths/Dawntrail/RoleQuests/MagicalRanged/4846_Behind the Helm.json
new file mode 100644 (file)
index 0000000..5fb5341
--- /dev/null
@@ -0,0 +1,138 @@
+{
+  "$schema": "https://carvel.li/questionable/quest-1.0",
+  "Author": "liza",
+  "QuestSequence": [
+    {
+      "Sequence": 0,
+      "Steps": [
+        {
+          "DataId": 1048331,
+          "Position": {
+            "X": 214.03821,
+            "Y": 5.2600574,
+            "Z": 628.3817
+          },
+          "TerritoryId": 957,
+          "InteractionType": "AcceptQuest"
+        }
+      ]
+    },
+    {
+      "Sequence": 1,
+      "Steps": [
+        {
+          "DataId": 1048330,
+          "Position": {
+            "X": -28.732727,
+            "Y": -17.972864,
+            "Z": 194.72034
+          },
+          "TerritoryId": 1185,
+          "InteractionType": "Interact",
+          "AetheryteShortcut": "Tuliyollal",
+          "AethernetShortcut": [
+            "[Tuliyollal] Aetheryte Plaza",
+            "[Tuliyollal] Bayside Bevy Marketplace"
+          ]
+        }
+      ]
+    },
+    {
+      "Sequence": 2,
+      "Steps": [
+        {
+          "Position": {
+            "X": 327.87598,
+            "Y": -15.862221,
+            "Z": -236.6933
+          },
+          "TerritoryId": 1190,
+          "InteractionType": "WalkTo",
+          "AetheryteShortcut": "Shaaloani - Mehwahhetsoan",
+          "SkipIf": [
+            "FlyingUnlocked"
+          ]
+        },
+        {
+          "Position": {
+            "X": 442.79218,
+            "Y": -16.660347,
+            "Z": -111.04725
+          },
+          "TerritoryId": 1190,
+          "InteractionType": "Combat",
+          "EnemySpawnType": "AutoOnEnterArea",
+          "KillEnemyDataIds": [
+            17627
+          ],
+          "Fly": true
+        }
+      ]
+    },
+    {
+      "Sequence": 3,
+      "Steps": [
+        {
+          "DataId": 1048369,
+          "Position": {
+            "X": 441.5503,
+            "Y": -16.619904,
+            "Z": -109.14783
+          },
+          "StopDistance": 7,
+          "TerritoryId": 1190,
+          "InteractionType": "Interact"
+        }
+      ]
+    },
+    {
+      "Sequence": 4,
+      "Steps": [
+        {
+          "DataId": 1048333,
+          "Position": {
+            "X": 52.506226,
+            "Y": -5.20688E-07,
+            "Z": -54.154297
+          },
+          "TerritoryId": 963,
+          "InteractionType": "Interact",
+          "AetheryteShortcut": "Radz-at-Han"
+        }
+      ]
+    },
+    {
+      "Sequence": 5,
+      "Steps": [
+        {
+          "DataId": 1048372,
+          "Position": {
+            "X": -53.177734,
+            "Y": -1.9999962,
+            "Z": 147.60046
+          },
+          "StopDistance": 7,
+          "TerritoryId": 963,
+          "InteractionType": "Interact"
+        }
+      ]
+    },
+    {
+      "Sequence": 255,
+      "Steps": [
+        {
+          "DataId": 1048331,
+          "Position": {
+            "X": 214.03821,
+            "Y": 5.2600574,
+            "Z": 628.3817
+          },
+          "TerritoryId": 957,
+          "InteractionType": "CompleteQuest",
+          "AetheryteShortcut": "Thavnair - Yedlihmad",
+          "NextQuestId": 4847
+        }
+      ]
+    }
+  ]
+}
diff --git a/QuestPaths/Dawntrail/RoleQuests/MagicalRanged/4847_Heroes and Pretenders.json b/QuestPaths/Dawntrail/RoleQuests/MagicalRanged/4847_Heroes and Pretenders.json
new file mode 100644 (file)
index 0000000..d3023ce
--- /dev/null
@@ -0,0 +1,95 @@
+{
+  "$schema": "https://carvel.li/questionable/quest-1.0",
+  "Author": "liza",
+  "TerritoryBlacklist": [
+    1218
+  ],
+  "QuestSequence": [
+    {
+      "Sequence": 0,
+      "Steps": [
+        {
+          "DataId": 1048331,
+          "Position": {
+            "X": 214.03821,
+            "Y": 5.2600574,
+            "Z": 628.3817
+          },
+          "TerritoryId": 957,
+          "InteractionType": "AcceptQuest"
+        }
+      ]
+    },
+    {
+      "Sequence": 1,
+      "Steps": [
+        {
+          "DataId": 1048374,
+          "Position": {
+            "X": -77.04285,
+            "Y": 99.946754,
+            "Z": -711.0552
+          },
+          "TerritoryId": 957,
+          "InteractionType": "SinglePlayerDuty",
+          "AetheryteShortcut": "Radz-at-Han",
+          "AethernetShortcut": [
+            "[Radz-at-Han] Aetheryte Plaza",
+            "[Radz-at-Han] The Gate of First Sight (Thavnair)"
+          ],
+          "Fly": true
+        }
+      ]
+    },
+    {
+      "Sequence": 2,
+      "Steps": [
+        {
+          "Position": {
+            "X": 0,
+            "Y": 0,
+            "Z": 0
+          },
+          "TerritoryId": 1,
+          "InteractionType": "WalkTo",
+          "Comment": "Filler"
+        }
+      ]
+    },
+    {
+      "Sequence": 3,
+      "Steps": [
+        {
+          "DataId": 1048374,
+          "Position": {
+            "X": -77.04285,
+            "Y": 99.946754,
+            "Z": -711.0552
+          },
+          "TerritoryId": 957,
+          "InteractionType": "Interact"
+        }
+      ]
+    },
+    {
+      "Sequence": 255,
+      "Steps": [
+        {
+          "DataId": 1048330,
+          "Position": {
+            "X": -28.732727,
+            "Y": -17.972864,
+            "Z": 194.72034
+          },
+          "TerritoryId": 1185,
+          "InteractionType": "CompleteQuest",
+          "AetheryteShortcut": "Tuliyollal",
+          "AethernetShortcut": [
+            "[Tuliyollal] Aetheryte Plaza",
+            "[Tuliyollal] Bayside Bevy Marketplace"
+          ]
+        }
+      ]
+    }
+  ]
+}
index d336dec797d853a7c3fb4c703b2d1eb1e185c580..27040e8ab91ab594e566a684bd7220fff5f4a9f1 100644 (file)
@@ -45,7 +45,7 @@
           },
           "TerritoryId": 1187,
           "InteractionType": "Interact",
-          "Fly": true,
+          "DisableNavmesh": true,
           "DialogueChoices": [
             {
               "Type": "YesNo",
diff --git a/QuestPaths/Endwalker/Tribal/Arkasodara/4567_Vanaspati's Blessing.json b/QuestPaths/Endwalker/Tribal/Arkasodara/4567_Vanaspati's Blessing.json
new file mode 100644 (file)
index 0000000..18b9b83
--- /dev/null
@@ -0,0 +1,97 @@
+{
+  "$schema": "https://carvel.li/questionable/quest-1.0",
+  "Author": "liza",
+  "QuestSequence": [
+    {
+      "Sequence": 0,
+      "Steps": [
+        {
+          "DataId": 1042301,
+          "Position": {
+            "X": -66.02582,
+            "Y": 39.994705,
+            "Z": 321.06494
+          },
+          "TerritoryId": 957,
+          "InteractionType": "Interact"
+        }
+      ]
+    },
+    {
+      "Sequence": 1,
+      "Steps": [
+        {
+          "DataId": 2012858,
+          "Position": {
+            "X": 280.78125,
+            "Y": 0.045776367,
+            "Z": 556.7252
+          },
+          "TerritoryId": 957,
+          "InteractionType": "Interact",
+          "Fly": true,
+          "CompletionQuestVariablesFlags": [
+            null,
+            null,
+            null,
+            null,
+            null,
+            32
+          ]
+        },
+        {
+          "DataId": 2012857,
+          "Position": {
+            "X": 303.36462,
+            "Y": 0.015197754,
+            "Z": 530.44934
+          },
+          "TerritoryId": 957,
+          "InteractionType": "Interact",
+          "CompletionQuestVariablesFlags": [
+            null,
+            null,
+            null,
+            null,
+            null,
+            64
+          ]
+        },
+        {
+          "DataId": 2012856,
+          "Position": {
+            "X": 281.94092,
+            "Y": 0.015197754,
+            "Z": 510.64307
+          },
+          "TerritoryId": 957,
+          "InteractionType": "Interact",
+          "CompletionQuestVariablesFlags": [
+            null,
+            null,
+            null,
+            null,
+            null,
+            128
+          ]
+        }
+      ]
+    },
+    {
+      "Sequence": 255,
+      "Steps": [
+        {
+          "DataId": 1042301,
+          "Position": {
+            "X": -66.02582,
+            "Y": 39.994705,
+            "Z": 321.06494
+          },
+          "TerritoryId": 957,
+          "InteractionType": "CompleteQuest",
+          "Fly": true
+        }
+      ]
+    }
+  ]
+}
diff --git a/QuestPaths/Endwalker/Tribal/Arkasodara/4568_Hells Hath No Fury as a Hippo Scorned.json b/QuestPaths/Endwalker/Tribal/Arkasodara/4568_Hells Hath No Fury as a Hippo Scorned.json
new file mode 100644 (file)
index 0000000..0a0aaa8
--- /dev/null
@@ -0,0 +1,70 @@
+{
+  "$schema": "https://carvel.li/questionable/quest-1.0",
+  "Author": "liza",
+  "QuestSequence": [
+    {
+      "Sequence": 0,
+      "Steps": [
+        {
+          "DataId": 1042301,
+          "Position": {
+            "X": -66.02582,
+            "Y": 39.994705,
+            "Z": 321.06494
+          },
+          "TerritoryId": 957,
+          "InteractionType": "Interact"
+        }
+      ]
+    },
+    {
+      "Sequence": 1,
+      "Steps": [
+        {
+          "DataId": 2012892,
+          "Position": {
+            "X": -120.19531,
+            "Y": 41.000854,
+            "Z": 340.41345
+          },
+          "TerritoryId": 957,
+          "InteractionType": "Interact"
+        }
+      ]
+    },
+    {
+      "Sequence": 2,
+      "Steps": [
+        {
+          "DataId": 1042458,
+          "Position": {
+            "X": 416.5254,
+            "Y": 8.834262,
+            "Z": -344.38086
+          },
+          "TerritoryId": 957,
+          "InteractionType": "Interact",
+          "AetheryteShortcut": "Thavnair - Palaka's Stand",
+          "Fly": true
+        }
+      ]
+    },
+    {
+      "Sequence": 255,
+      "Steps": [
+        {
+          "DataId": 1042301,
+          "Position": {
+            "X": -66.02582,
+            "Y": 39.994705,
+            "Z": 321.06494
+          },
+          "TerritoryId": 957,
+          "InteractionType": "CompleteQuest",
+          "AetheryteShortcut": "Thavnair - Yedlihmad",
+          "Fly": true
+        }
+      ]
+    }
+  ]
+}
diff --git a/QuestPaths/Endwalker/Tribal/Arkasodara/4569_Tusk Trouble.json b/QuestPaths/Endwalker/Tribal/Arkasodara/4569_Tusk Trouble.json
new file mode 100644 (file)
index 0000000..0d01f38
--- /dev/null
@@ -0,0 +1,74 @@
+{
+  "$schema": "https://carvel.li/questionable/quest-1.0",
+  "Author": "liza",
+  "QuestSequence": [
+    {
+      "Sequence": 0,
+      "Steps": [
+        {
+          "DataId": 1042301,
+          "Position": {
+            "X": -66.02582,
+            "Y": 39.994705,
+            "Z": 321.06494
+          },
+          "TerritoryId": 957,
+          "InteractionType": "Interact"
+        }
+      ]
+    },
+    {
+      "Sequence": 1,
+      "Steps": [
+        {
+          "DataId": 2012893,
+          "Position": {
+            "X": 267.32275,
+            "Y": 7.156433,
+            "Z": -476.34088
+          },
+          "TerritoryId": 957,
+          "InteractionType": "UseItem",
+          "ItemId": 2003403,
+          "AetheryteShortcut": "Thavnair - Palaka's Stand"
+        }
+      ]
+    },
+    {
+      "Sequence": 2,
+      "Steps": [
+        {
+          "DataId": 2012894,
+          "Position": {
+            "X": 257.09924,
+            "Y": 6.6071167,
+            "Z": -468.0705
+          },
+          "TerritoryId": 957,
+          "InteractionType": "Combat",
+          "EnemySpawnType": "AfterInteraction",
+          "KillEnemyDataIds": [
+            14678
+          ]
+        }
+      ]
+    },
+    {
+      "Sequence": 255,
+      "Steps": [
+        {
+          "DataId": 1042301,
+          "Position": {
+            "X": -66.02582,
+            "Y": 39.994705,
+            "Z": 321.06494
+          },
+          "TerritoryId": 957,
+          "InteractionType": "CompleteQuest",
+          "AetheryteShortcut": "Thavnair - Yedlihmad",
+          "Fly": true
+        }
+      ]
+    }
+  ]
+}
diff --git a/QuestPaths/Endwalker/Unlocks/Hunts/4176_The Hunt for Specimens.json b/QuestPaths/Endwalker/Unlocks/Hunts/4176_The Hunt for Specimens.json
new file mode 100644 (file)
index 0000000..6231068
--- /dev/null
@@ -0,0 +1,41 @@
+{
+  "$schema": "https://carvel.li/questionable/quest-1.0",
+  "Author": "liza",
+  "QuestSequence": [
+    {
+      "Sequence": 0,
+      "Steps": [
+        {
+          "DataId": 1041960,
+          "Position": {
+            "X": -1.9379272,
+            "Y": -7.758,
+            "Z": 42.282715
+          },
+          "TerritoryId": 962,
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Old Sharlayan",
+          "SkipIf": [
+            "AetheryteShortcutIfInSameTerritory"
+          ]
+        }
+      ]
+    },
+    {
+      "Sequence": 255,
+      "Steps": [
+        {
+          "DataId": 1037060,
+          "Position": {
+            "X": 25.894531,
+            "Y": -15.646991,
+            "Z": 99.68713
+          },
+          "TerritoryId": 962,
+          "InteractionType": "CompleteQuest",
+          "NextQuestId": 4177
+        }
+      ]
+    }
+  ]
+}
diff --git a/QuestPaths/Endwalker/Unlocks/Hunts/4177_That Specimen Came from the Moon.json b/QuestPaths/Endwalker/Unlocks/Hunts/4177_That Specimen Came from the Moon.json
new file mode 100644 (file)
index 0000000..05ef5bf
--- /dev/null
@@ -0,0 +1,41 @@
+{
+  "$schema": "https://carvel.li/questionable/quest-1.0",
+  "Author": "liza",
+  "QuestSequence": [
+    {
+      "Sequence": 0,
+      "Steps": [
+        {
+          "DataId": 1037060,
+          "Position": {
+            "X": 25.894531,
+            "Y": -15.646991,
+            "Z": 99.68713
+          },
+          "TerritoryId": 962,
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Old Sharlayan",
+          "SkipIf": [
+            "AetheryteShortcutIfInSameTerritory"
+          ]
+        }
+      ]
+    },
+    {
+      "Sequence": 255,
+      "Steps": [
+        {
+          "DataId": 1037059,
+          "Position": {
+            "X": 35.202515,
+            "Y": -15.646992,
+            "Z": 102.4032
+          },
+          "TerritoryId": 962,
+          "InteractionType": "CompleteQuest",
+          "NextQuestId": 4178
+        }
+      ]
+    }
+  ]
+}
diff --git a/QuestPaths/Endwalker/Unlocks/Hunts/4178_A Hunt for the Ages.json b/QuestPaths/Endwalker/Unlocks/Hunts/4178_A Hunt for the Ages.json
new file mode 100644 (file)
index 0000000..f518bf0
--- /dev/null
@@ -0,0 +1,41 @@
+{
+  "$schema": "https://carvel.li/questionable/quest-1.0",
+  "Author": "liza",
+  "QuestSequence": [
+    {
+      "Sequence": 0,
+      "Steps": [
+        {
+          "DataId": 1037060,
+          "Position": {
+            "X": 25.894531,
+            "Y": -15.646991,
+            "Z": 99.68713
+          },
+          "TerritoryId": 962,
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Old Sharlayan",
+          "SkipIf": [
+            "AetheryteShortcutIfInSameTerritory"
+          ]
+        }
+      ]
+    },
+    {
+      "Sequence": 255,
+      "Steps": [
+        {
+          "DataId": 1037059,
+          "Position": {
+            "X": 35.202515,
+            "Y": -15.646992,
+            "Z": 102.4032
+          },
+          "TerritoryId": 962,
+          "InteractionType": "CompleteQuest",
+          "NextQuestId": 4179
+        }
+      ]
+    }
+  ]
+}
diff --git a/QuestPaths/Endwalker/Unlocks/Hunts/4179_Perfect Specimens.json b/QuestPaths/Endwalker/Unlocks/Hunts/4179_Perfect Specimens.json
new file mode 100644 (file)
index 0000000..8f89f85
--- /dev/null
@@ -0,0 +1,41 @@
+{
+  "$schema": "https://carvel.li/questionable/quest-1.0",
+  "Author": "liza",
+  "QuestSequence": [
+    {
+      "Sequence": 0,
+      "Steps": [
+        {
+          "DataId": 1037060,
+          "Position": {
+            "X": 25.894531,
+            "Y": -15.646991,
+            "Z": 99.68713
+          },
+          "TerritoryId": 962,
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Old Sharlayan",
+          "SkipIf": [
+            "AetheryteShortcutIfInSameTerritory"
+          ]
+        }
+      ]
+    },
+    {
+      "Sequence": 255,
+      "Steps": [
+        {
+          "DataId": 1037059,
+          "Position": {
+            "X": 35.202515,
+            "Y": -15.646992,
+            "Z": 102.4032
+          },
+          "TerritoryId": 962,
+          "InteractionType": "CompleteQuest",
+          "NextQuestId": 5009
+        }
+      ]
+    }
+  ]
+}
index 6fee81f6c021609b90a9443084e12b094ea14287..48e0e15e607bca817ceea64419de628081d35100 100644 (file)
           },
           "TerritoryId": 813,
           "InteractionType": "Interact",
-          "DisableNavmesh": true,
           "CompletionQuestVariablesFlags": [
             null,
             null,
index ef9d506202c6d33b94d878efcc3a53fff443aca4..17a19db83b745fe53419122e0912671c7afd29fb 100644 (file)
           "KillEnemyDataIds": [
             12168
           ],
-          "Comment": "TODO Missing enemy ids",
           "Fly": true,
           "$.2": "QuestVariables if done after [1, 2]: irrelevant because it automatically progresses to the next step"
         }
index ce3d658b434ee997be8aeedb1d615cd05c2acf1a..b9c6b4b8fef67fbbbccdac37d38164e2783db0f5 100644 (file)
@@ -38,7 +38,8 @@
             "Z": -653.85443
           },
           "TerritoryId": 156,
-          "InteractionType": "WalkTo"
+          "InteractionType": "WalkTo",
+          "Mount": true
         },
         {
           "Position": {
index 9955355d4293aca8231d1e86cc4514a8ad3c8169..c053f22e6d8216602fec21ab19b6c58aac18f9e9 100644 (file)
@@ -15,6 +15,7 @@
             "Y": -2.0168546E-08,
             "Z": 1.9378662
           },
+          "StopDistance": 5,
           "TerritoryId": 819,
           "InteractionType": "AcceptQuest"
         }
           },
           "TerritoryId": 918,
           "InteractionType": "SinglePlayerDuty",
-          "Comment": "Fight NPCs, then Elidibus"
+          "Comment": "Fight NPCs, then Elidibus",
+          "DialogueChoices": [
+            {
+              "Type": "List",
+              "ExcelSheet": "ContentTalk",
+              "Prompt": 209,
+              "Answer": 211
+            },
+            {
+              "Type": "List",
+              "ExcelSheet": "ContentTalk",
+              "Prompt": 209,
+              "Answer": 216
+            },
+            {
+              "Type": "List",
+              "ExcelSheet": "ContentTalk",
+              "Prompt": 241,
+              "Answer": 222
+            }
+          ]
         }
       ]
     },
index 32f9de52a675688c23f7ec1e63f4650dfec6bd3e..dbf3465aa9e94dcbdade99c2dcf38770df573329 100644 (file)
                       "FlyingUnlocked",
                       "DifferentTerritory",
                       "ChocoboUnlocked",
-                      "AetheryteShortcutIfInSameTerritory"
+                      "AetheryteShortcutIfInSameTerritory",
+                      "NotTargetable"
                     ]
                   }
                 },
index 3ae25769787df950781187da9bb7020263d578ef..adf008bafe7dd36f05ce39a5acac472b3104ec41 100644 (file)
@@ -11,5 +11,6 @@ public sealed class SkipConditionConverter() : EnumConverter<ESkipCondition>(Val
         { ESkipCondition.FlyingUnlocked, "FlyingUnlocked" },
         { ESkipCondition.ChocoboUnlocked, "ChocoboUnlocked" },
         { ESkipCondition.AetheryteShortcutIfInSameTerritory, "AetheryteShortcutIfInSameTerritory" },
+        { ESkipCondition.NotTargetable, "NotTargetable" },
     };
 }
index fd8ee6a33b451b07140a5794f0d3678483c00ef6..3ece172b9c7d12577b25f79dc9e9b77780f1254f 100644 (file)
@@ -12,4 +12,5 @@ public enum ESkipCondition
     FlyingUnlocked,
     ChocoboUnlocked,
     AetheryteShortcutIfInSameTerritory,
+    NotTargetable,
 }
index 29071202da3944a4ca0aa806652fddd10d5a22f7..fdbf7d1c23be1cfeb59b3cfa1a2a6d234220cc5e 100644 (file)
@@ -162,7 +162,7 @@ internal sealed class GameUiController : IDisposable
             return;
         }
 
-        var currentQuest = _questController.CurrentQuest;
+        var currentQuest = _questController.StartedQuest;
         if (currentQuest != null && actualPrompt == null)
         {
             // it is possible for this to be a quest selection
@@ -177,7 +177,7 @@ internal sealed class GameUiController : IDisposable
     private int? HandleListChoice(string? actualPrompt, List<string?> answers, bool checkAllSteps)
     {
         List<DialogueChoiceInfo> dialogueChoices = [];
-        var currentQuest = _questController.CurrentQuest;
+        var currentQuest = _questController.StartedQuest;
         if (currentQuest != null)
         {
             var quest = currentQuest.Quest;
@@ -305,7 +305,7 @@ internal sealed class GameUiController : IDisposable
 
         _logger.LogTrace("Prompt: '{Prompt}'", actualPrompt);
 
-        var currentQuest = _questController.CurrentQuest;
+        var currentQuest = _questController.StartedQuest;
         if (currentQuest == null)
             return;
 
@@ -421,7 +421,7 @@ internal sealed class GameUiController : IDisposable
 
     private unsafe void PointMenuPostSetup(AtkUnitBase* addonPointMenu)
     {
-        var currentQuest = _questController.CurrentQuest;
+        var currentQuest = _questController.StartedQuest;
         if (currentQuest == null)
         {
             _logger.LogInformation("Ignoring point menu, no active quest");
@@ -471,7 +471,7 @@ internal sealed class GameUiController : IDisposable
 
     private unsafe void UnendingCodexPostSetup(AddonEvent type, AddonArgs args)
     {
-        if (_questController.CurrentQuest?.Quest.QuestId == 4526)
+        if (_questController.StartedQuest?.Quest.QuestId == 4526)
         {
             _logger.LogInformation("Closing Unending Codex");
             AtkUnitBase* addon = (AtkUnitBase*)args.Addon;
@@ -481,7 +481,7 @@ internal sealed class GameUiController : IDisposable
 
     private unsafe void ContentsTutorialPostSetup(AddonEvent type, AddonArgs args)
     {
-        if (_questController.CurrentQuest?.Quest.QuestId == 245)
+        if (_questController.StartedQuest?.Quest.QuestId == 245)
         {
             _logger.LogInformation("Closing ContentsTutorial");
             AtkUnitBase* addon = (AtkUnitBase*)args.Addon;
@@ -491,7 +491,7 @@ internal sealed class GameUiController : IDisposable
 
     private unsafe void MultipleHelpWindowPostSetup(AddonEvent type, AddonArgs args)
     {
-        if (_questController.CurrentQuest?.Quest.QuestId == 245)
+        if (_questController.StartedQuest?.Quest.QuestId == 245)
         {
             _logger.LogInformation("Closing MultipleHelpWindow");
             AtkUnitBase* addon = (AtkUnitBase*)args.Addon;
index 221bb2242216b9da28fbc8c3219880579a57b1eb..e00ab5d327fbcf8bdfc65e76304b8e4e1cabb09d 100644 (file)
@@ -5,6 +5,7 @@ using Dalamud.Game.ClientState.Keys;
 using Dalamud.Plugin.Services;
 using Microsoft.Extensions.Logging;
 using Questionable.Controller.Steps;
+using Questionable.Controller.Steps.BaseFactory;
 using Questionable.External;
 using Questionable.Model;
 using Questionable.Model.V1;
@@ -55,19 +56,24 @@ internal sealed class QuestController
         _taskFactories = taskFactories.ToList().AsReadOnly();
     }
 
-    public QuestProgress? CurrentQuest
+    public (QuestProgress Progress, CurrentQuestType Type)? CurrentQuestDetails
     {
         get
         {
             if (_simulatedQuest != null)
-                return _simulatedQuest;
+                return (_simulatedQuest, CurrentQuestType.Simulated);
             else if (_nextQuest != null && _gameFunctions.IsReadyToAcceptQuest(_nextQuest.Quest.QuestId))
-                return _nextQuest;
+                return (_nextQuest, CurrentQuestType.Next);
+            else if (_startedQuest != null)
+                return (_startedQuest, CurrentQuestType.Normal);
             else
-                return _startedQuest;
+                return null;
         }
     }
 
+    public QuestProgress? CurrentQuest => CurrentQuestDetails?.Progress;
+
+    public QuestProgress? StartedQuest => _startedQuest;
     public QuestProgress? SimulatedQuest => _simulatedQuest;
     public QuestProgress? NextQuest => _nextQuest;
 
@@ -106,7 +112,6 @@ internal sealed class QuestController
         if (CurrentQuest != null && CurrentQuest.Quest.Root.TerritoryBlacklist.Contains(_clientState.TerritoryType))
             return;
 
-        // not verified to work
         if (_automatic && _currentTask == null && _taskQueue.Count == 0
             && CurrentQuest is { Sequence: 0, Step: 0 } or { Sequence: 0, Step: 255 }
             && DateTime.Now >= CurrentQuest.StepProgress.StartedAt.AddSeconds(15))
@@ -140,12 +145,16 @@ internal sealed class QuestController
                 // if the quest is accepted, we no longer track it
                 if (_gameFunctions.IsQuestAcceptedOrComplete(_nextQuest.Quest.QuestId))
                 {
+                    _logger.LogInformation("Next quest {QuestId} accepted or completed", _nextQuest.Quest.QuestId);
+
                     _nextQuest = null;
                     currentSequence = 0;
                 }
                 else
                 {
                     currentSequence = _nextQuest.Sequence; // by definition, this should always be 0
+                    if (_nextQuest.Step == 0 && _currentTask == null && _taskQueue.Count == 0 && _automatic)
+                        ExecuteNextStep(true);
                 }
             }
 
@@ -325,6 +334,8 @@ internal sealed class QuestController
         {
             if (CurrentQuest?.Step is >= 0 and < 255)
                 ExecuteNextStep(true);
+            else
+                _logger.LogInformation("Couldn't execute next step during Stop() call");
         }
         else if (_automatic)
         {
@@ -422,6 +433,10 @@ internal sealed class QuestController
             case ETaskResult.TaskComplete:
                 _logger.LogInformation("{Task} → {Result}, remaining tasks: {RemainingTaskCount}",
                     _currentTask, result, _taskQueue.Count);
+
+                if (_currentTask is WaitAtEnd.WaitQuestCompleted)
+                    _simulatedQuest = null;
+
                 _currentTask = null;
 
                 // handled in next update
@@ -566,7 +581,19 @@ internal sealed class QuestController
         }
     }
 
+    public void SkipSimulatedTask()
+    {
+        _currentTask = null;
+    }
+
     public sealed record StepProgress(
         DateTime StartedAt,
         int PointMenuCounter = 0);
+
+    public enum CurrentQuestType
+    {
+        Normal,
+        Next,
+        Simulated,
+    }
 }
index 6757aa20cffa809aaeb0dbf4616f0361436ab824..d31f46e6fdb0a726a0911265e64429b1f223fe00 100644 (file)
@@ -1,6 +1,8 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using Dalamud.Game.ClientState.Objects.Types;
+using Dalamud.Plugin.Services;
 using FFXIVClientStructs.FFXIV.Application.Network.WorkDefinitions;
 using FFXIVClientStructs.FFXIV.Client.Game.UI;
 using FFXIVClientStructs.FFXIV.Client.System.Framework;
@@ -32,7 +34,8 @@ internal static class SkipCondition
 
     internal sealed class CheckTask(
         ILogger<CheckTask> logger,
-        GameFunctions gameFunctions) : ITask
+        GameFunctions gameFunctions,
+        IClientState clientState) : ITask
     {
         public QuestStep Step { get; set; } = null!;
         public List<ESkipCondition> SkipConditions { get; set; } = null!;
@@ -71,6 +74,25 @@ internal static class SkipCondition
                 return true;
             }
 
+            if (SkipConditions.Contains(ESkipCondition.NotTargetable) &&
+                Step is { DataId: not null })
+            {
+                IGameObject? gameObject = gameFunctions.FindObjectByDataId(Step.DataId.Value);
+                if (gameObject == null)
+                {
+                    if ((Step.Position.GetValueOrDefault() - clientState.LocalPlayer!.Position).Length() < 100)
+                    {
+                        logger.LogInformation("Skipping step, object is not nearby (but we are)");
+                        return true;
+                    }
+                }
+                else if (!gameObject.IsTargetable)
+                {
+                    logger.LogInformation("Skipping step, object is not targetable");
+                    return true;
+                }
+            }
+
             if (Step is
                 {
                     DataId: not null,
index 3a2c5682682a76475bf6d40d3f95587e105c2897..1d309750c3f2ba096c6df8472caf6727abce22ea 100644 (file)
@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Collections.Immutable;
 using System.Linq;
 using Dalamud.Game.ClientState.Objects;
+using Dalamud.Game.Text;
 using Dalamud.Plugin.Services;
 using Questionable.Model;
 using Quest = Lumina.Excel.GeneratedSheets.Quest;
@@ -40,6 +41,8 @@ internal sealed class QuestData
             .ToList();
     }
 
+    public bool IsIssuerOfAnyQuest(uint targetId) => _quests.Values.Any(x => x.IssuerDataId == targetId);
+
     public void ShowQuestsIssuedByTarget()
     {
         var targetId = _targetManager.Target?.DataId;
@@ -53,6 +56,6 @@ internal sealed class QuestData
         _chatGui.Print($"{quests.Count} quest(s) issued by target {_targetManager.Target?.Name}:");
 
         foreach (QuestInfo quest in quests)
-            _chatGui.Print($"  {quest.QuestId}: {quest.Name}");
+            _chatGui.Print($"  {quest.QuestId}_{quest.SimplifiedName}");
     }
 }
index 6730180183d61b185dcc4751ae9b34bb2b50e5f6..f0902fd1530915dc59e0c73c4387484b7da4e3e2 100644 (file)
@@ -1,4 +1,6 @@
-using ExcelQuest = Lumina.Excel.GeneratedSheets.Quest;
+using System;
+using Dalamud.Game.Text;
+using ExcelQuest = Lumina.Excel.GeneratedSheets.Quest;
 
 namespace Questionable.Model;
 
@@ -16,4 +18,7 @@ internal sealed class QuestInfo
     public string Name { get; }
     public ushort Level { get; }
     public uint IssuerDataId { get; }
+
+    public string SimplifiedName => Name
+        .TrimStart(SeIconChar.QuestSync.ToIconChar(), SeIconChar.QuestRepeatable.ToIconChar(), ' ');
 }
index bbbc4302bc1d0db1a2ea5ed783daf3d71b06ad33..902d247a332e2803a7b131908c051b51532b1a0c 100644 (file)
@@ -100,6 +100,6 @@ internal sealed class DebugOverlay : Window
 
         ImGui.GetWindowDrawList().AddCircleFilled(screenPos, 3f, color);
         ImGui.GetWindowDrawList().AddText(screenPos + new Vector2(10, -8), color,
-            $"{counter}: {step.InteractionType}\n{step.Position.Value.ToString("G", CultureInfo.InvariantCulture)}\n{step.Comment}");
+            $"{counter}: {step.InteractionType}\n{step.Position.Value.ToString("G", CultureInfo.InvariantCulture)} [{(step.Position.Value - _clientState.LocalPlayer!.Position).Length():N2}]\n{step.Comment}");
     }
 }
index 2a47215ae099362f03d8724d5f93b8dc3f487186..0a6b81020538ecbeaf7bccc81cf234c5c43f52fe 100644 (file)
@@ -119,10 +119,37 @@ internal sealed class QuestWindow : LWindow, IPersistableWindowConfig
 
     private void DrawQuest()
     {
-        var currentQuest = _questController.CurrentQuest;
+        var currentQuestDetails = _questController.CurrentQuestDetails;
+        QuestController.QuestProgress? currentQuest = currentQuestDetails?.Progress;
+        QuestController.CurrentQuestType? currentQuestType = currentQuestDetails?.Type;
         if (currentQuest != null)
         {
-            ImGui.TextUnformatted($"Quest: {currentQuest.Quest.Info.Name} / {currentQuest.Sequence} / {currentQuest.Step}");
+            if (currentQuestType == QuestController.CurrentQuestType.Simulated)
+            {
+                var simulatedQuest = _questController.SimulatedQuest ?? currentQuest;
+                using var _ = ImRaii.PushColor(ImGuiCol.Text, 0xFF0000FF);
+                ImGui.TextUnformatted(
+                    $"Simulated Quest: {simulatedQuest.Quest.Info.Name} / {simulatedQuest.Sequence} / {simulatedQuest.Step}");
+            }
+            else if (currentQuestType == QuestController.CurrentQuestType.Next)
+            {
+                var startedQuest = _questController.StartedQuest;
+                if (startedQuest != null)
+                {
+                    ImGui.TextUnformatted(
+                        $"Quest: {startedQuest.Quest.Info.Name} / {startedQuest.Sequence} / {startedQuest.Step}");
+                }
+
+                using var _ = ImRaii.PushColor(ImGuiCol.Text, 0xFF00FFFF);
+                ImGui.TextUnformatted(
+                    $"Next Quest: {currentQuest.Quest.Info.Name} / {currentQuest.Sequence} / {currentQuest.Step}");
+            }
+            else
+            {
+                ImGui.TextUnformatted(
+                    $"Quest: {currentQuest.Quest.Info.Name} / {currentQuest.Sequence} / {currentQuest.Step}");
+            }
+
 
             ImGui.BeginDisabled();
             var questWork = _gameFunctions.GetQuestEx(currentQuest.Quest.QuestId);
@@ -295,6 +322,12 @@ internal sealed class QuestWindow : LWindow, IPersistableWindowConfig
 
                     ImGui.EndDisabled();
 
+                    if (ImGui.Button("Skip current task"))
+                    {
+                        _questController.SkipSimulatedTask();
+                    }
+
+                    ImGui.SameLine();
                     if (ImGui.Button("Clear sim"))
                     {
                         _questController.SimulateQuest(null);
@@ -378,7 +411,7 @@ internal sealed class QuestWindow : LWindow, IPersistableWindowConfig
             ImGui.EndDisabled();
 
             ImGui.SameLine();
-            ImGui.BeginDisabled(gameObject->NamePlateIconId == 0);
+            ImGui.BeginDisabled(!_questData.IsIssuerOfAnyQuest(_targetManager.Target.DataId));
             if (ImGuiComponents.IconButton(FontAwesomeIcon.Bars))
                 _questData.ShowQuestsIssuedByTarget();
             ImGui.EndDisabled();