Add aetheryte shortcuts to sequence 0 of class/job quests that didn't have any (and...
authorLiza Carvelli <liza@carvel.li>
Mon, 2 Sep 2024 20:03:29 +0000 (22:03 +0200)
committerLiza Carvelli <liza@carvel.li>
Mon, 2 Sep 2024 20:04:14 +0000 (22:04 +0200)
48 files changed:
QuestPaths/2.x - A Realm Reborn/Class Quests/BRD/1086_The Archer's Anthem.json
QuestPaths/2.x - A Realm Reborn/Class Quests/BTN/3_Way of the Botanist.json
QuestPaths/2.x - A Realm Reborn/Class Quests/MIN/192_So You Want to Be a Miner.json
QuestPaths/2.x - A Realm Reborn/Class Quests/MIN/597_Way of the Miner.json
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/2.x - A Realm Reborn/Class Quests/MNK/532_Way of the Pugilist.json
QuestPaths/2.x - A Realm Reborn/Class Quests/MNK/533_Way of the Pugilist.json
QuestPaths/2.x - A Realm Reborn/Class Quests/PLD/1055_Paladin's Pledge.json
QuestPaths/2.x - A Realm Reborn/Class Quests/PLD/256_Kicking the Hornet's Nest.json
QuestPaths/2.x - A Realm Reborn/Class Quests/SCH/1097_Forgotten but Not Gone.json
QuestPaths/2.x - A Realm Reborn/Class Quests/SCH/1098_The Last Remnants.json
QuestPaths/2.x - A Realm Reborn/Class Quests/SCH/1099_The Consequences of Anger.json
QuestPaths/2.x - A Realm Reborn/Class Quests/SCH/1100_In the Image of the Ancients.json
QuestPaths/2.x - A Realm Reborn/Class Quests/SCH/1101_For Your Fellow Man.json
QuestPaths/2.x - A Realm Reborn/Class Quests/SCH/1102_The Beast Within.json
QuestPaths/2.x - A Realm Reborn/Class Quests/WHM/1081_O Brother, Where Art Thou.json
QuestPaths/5.x - Shadowbringers/Class Quests/DNC/3250_Gamboling for Gil.json
QuestPaths/5.x - Shadowbringers/Role Quests/Magical Ranged/3623_Hollow Pursuits.json
QuestPaths/5.x - Shadowbringers/Role Quests/Tank/3243_The Man with Too Many Scars.json
QuestPaths/7.x - Dawntrail/Class Quests/PCT/4854_The Joy of Pictomancy.json
QuestPaths/7.x - Dawntrail/Class Quests/PCT/4855_Mind over Manor.json
QuestPaths/7.x - Dawntrail/Class Quests/VPR/4848_Enter the Viper.json
QuestPaths/7.x - Dawntrail/Class Quests/VPR/4849_Fangs of the Viper.json
QuestPaths/7.x - Dawntrail/Role Quests/Magical Ranged/4842_Power Forgotten.json
QuestPaths/7.x - Dawntrail/Role Quests/Magical Ranged/4843_A Brand of Justice.json
QuestPaths/7.x - Dawntrail/Role Quests/Magical Ranged/4844_The Seeds of Popularity.json
QuestPaths/7.x - Dawntrail/Role Quests/Magical Ranged/4845_Floundering Fame.json
QuestPaths/7.x - Dawntrail/Role Quests/Magical Ranged/4846_Behind the Helm.json
QuestPaths/7.x - Dawntrail/Role Quests/Magical Ranged/4847_Heroes and Pretenders.json
QuestPaths/7.x - Dawntrail/Role Quests/Physical Ranged/4838_Take Me to Your Leader.json
QuestPaths/7.x - Dawntrail/Role Quests/Physical Ranged/4839_The Milk of Mamool Ja Kindness.json
QuestPaths/7.x - Dawntrail/Role Quests/Physical Ranged/4840_Ally in the Alley.json
QuestPaths/7.x - Dawntrail/Role Quests/Physical Ranged/4841_The Mightiest Shield.json
QuestPaths/7.x - Dawntrail/Role Quests/Tank/4818_The Narwhal Beckons.json
QuestPaths/7.x - Dawntrail/Role Quests/Tank/4819_Sleepless in Ishgard.json
QuestPaths/7.x - Dawntrail/Role Quests/Tank/4820_Between Sleep and Death.json
QuestPaths/7.x - Dawntrail/Role Quests/Tank/4821_Beacon in the Darkness.json
QuestPaths/7.x - Dawntrail/Role Quests/Tank/4822_Awakened, not Stirred.json
QuestPaths/7.x - Dawntrail/Role Quests/Tank/4823_Dreams of a New Day.json
Questionable.Model/Questing/QuestStep.cs
Questionable/Controller/Steps/Interactions/UseItem.cs
Questionable/Controller/Steps/Shared/AetheryteShortcut.cs
Questionable/Controller/Steps/Shared/SkipCondition.cs
Questionable/Functions/QuestFunctions.cs
Questionable/QuestionablePlugin.cs
Questionable/Validation/EIssueType.cs
Questionable/Validation/Validators/ClassQuestShouldHaveShortcutValidator.cs

index 58b792d69846823b45bbff0e51dc1714de1b2545..cced8794983094bd8c0853abe16392f56bba32bf 100644 (file)
@@ -8,7 +8,14 @@
         {
           "TerritoryId": 153,
           "InteractionType": "EquipItem",
-          "ItemId": 4546
+          "ItemId": 4546,
+          "AetheryteShortcut": "South Shroud - Quarrymill",
+          "Fly": true,
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
+            }
+          }
         },
         {
           "TerritoryId": 153,
             "Z": -7.3396606
           },
           "TerritoryId": 153,
-          "InteractionType": "AcceptQuest",
-          "AetheryteShortcut": "South Shroud - Quarrymill",
-          "Fly": true,
-          "SkipConditions": {
-            "AetheryteShortcutIf": {
-              "InSameTerritory": true
-            }
-          }
+          "InteractionType": "AcceptQuest"
         }
       ]
     },
index 23abee99151f862520f22ac7da4188ec45e7f535..1a5f96dcca55f837acea3356ba0f2434a90c61b2 100644 (file)
             "Z": -142.93127\r
           },\r
           "TerritoryId": 133,\r
-          "InteractionType": "AcceptQuest"\r
+          "InteractionType": "AcceptQuest",\r
+          "AetheryteShortcut": "Gridania",\r
+          "AethernetShortcut": [\r
+            "[Gridania] Aetheryte Plaza",\r
+            "[Gridania] Botanists' Guild"\r
+          ],\r
+          "SkipConditions": {\r
+            "AetheryteShortcutIf": {\r
+              "InSameTerritory": true,\r
+              "InTerritory": [\r
+                133\r
+              ]\r
+            }\r
+          }\r
         }\r
       ]\r
     },\r
index faaf1166bb1a5fc1b98fb6dbe35553f6ef2b74f9..ea8b8257b09fd3d5fd0361e8319049275861983b 100644 (file)
           },
           "TerritoryId": 131,
           "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Ul'dah",
+          "AethernetShortcut": [
+            "[Ul'dah] Aetheryte Plaza",
+            "[Ul'dah] Miners' Guild"
+          ],
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true,
+              "InTerritory": [
+                131
+              ]
+            }
+          },
           "DialogueChoices": [
             {
               "Type": "YesNo",
index ab55d722f8c27bde324ada7087de426a8f86ee71..5ab37fe6610220a705bc246146e7f33debd720ce 100644 (file)
             "Z": 153.2157
           },
           "TerritoryId": 131,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Ul'dah",
+          "AethernetShortcut": [
+            "[Ul'dah] Aetheryte Plaza",
+            "[Ul'dah] Miners' Guild"
+          ],
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true,
+              "InTerritory": [
+                131
+              ]
+            }
+          }
         }
       ]
     },
index c9bcf3776fe461c79e43b7b336f4e4d6c04f0e08..07dd8fbf14e1d4742b098c273c3b812ee6e9f239 100644 (file)
             "Z": 157.42725
           },
           "TerritoryId": 131,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Ul'dah",
+          "AethernetShortcut": [
+            "[Ul'dah] Aetheryte Plaza",
+            "[Ul'dah] Miners' Guild"
+          ],
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true,
+              "InTerritory": [
+                131
+              ]
+            }
+          }
         }
       ]
     },
index ae8417c0c30a4f0efb56b29f90427c603129f847..50ff25c8c016862d305d034bde78cce92806e4b4 100644 (file)
             "Z": 157.42725
           },
           "TerritoryId": 131,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Ul'dah",
+          "AethernetShortcut": [
+            "[Ul'dah] Aetheryte Plaza",
+            "[Ul'dah] Miners' Guild"
+          ],
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true,
+              "InTerritory": [
+                131
+              ]
+            }
+          }
         }
       ]
     },
index 2e25eb22191716b481c4f84bc3adeac004c44173..130b69e0d177d7688873b5b729fcf1cffd88953b 100644 (file)
             "Z": -51.163513\r
           },\r
           "TerritoryId": 130,\r
-          "InteractionType": "AcceptQuest"\r
+          "InteractionType": "AcceptQuest",\r
+          "AetheryteShortcut": "Ul'dah",\r
+          "SkipConditions": {\r
+            "AetheryteShortcutIf": {\r
+              "InSameTerritory": true\r
+            }\r
+          }\r
         }\r
       ]\r
     },\r
index cbbb57c3a894b31e236fef15e4485c2f2adf349e..8c00e6a2278f6a946cb5ecf772d578f26808b413 100644 (file)
             "Z": -51.163513
           },
           "TerritoryId": 130,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Ul'dah",
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
+            }
+          }
         }
       ]
     }
index eba6e3051c57d25a5f7ba6644d4afe164cbf4f2c..d7d54815ef5eb34ffb39181d6fb8194d2dbefe27 100644 (file)
@@ -14,6 +14,7 @@
           },\r
           "TerritoryId": 131,\r
           "InteractionType": "AcceptQuest",\r
+          "AetheryteShortcut": "Ul'dah",\r
           "AethernetShortcut": [\r
             "[Ul'dah] Aetheryte Plaza",\r
             "[Ul'dah] Gladiators' Guild"\r
index 88320c09b1d7680d3a15a1efc01236528c3d0794..e12a5e43e999c297a7958b9aff5aa0daeb9c76b8 100644 (file)
             "Z": 39.81079
           },
           "TerritoryId": 131,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Ul'dah",
+          "AethernetShortcut": [
+            "[Ul'dah] Aetheryte Plaza",
+            "[Ul'dah] Gladiators' Guild"
+          ],
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true,
+              "InTerritory": [
+                131
+              ]
+            }
+          }
         }
       ]
     },
index 615cf8be3e27e2405fd6b4a2a6696fa2abdee94c..5d4a5b35c6c10e85a0d777687635514cb5923460 100644 (file)
             "Z": 4.017052
           },
           "TerritoryId": 129,
-          "InteractionType": "WalkTo"
+          "InteractionType": "WalkTo",
+          "AetheryteShortcut": "Limsa Lominsa",
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
+            }
+          }
         },
         {
           "DataId": 1000895,
index 66e6af532bdaead68662a923ac3ea7bad21acf40..19cbfbe7ca6f4a2bf35ab5d9d0aa370811198ab3 100644 (file)
@@ -8,7 +8,20 @@
         {
           "TerritoryId": 128,
           "InteractionType": "EquipItem",
-          "ItemId": 4550
+          "ItemId": 4550,
+          "AetheryteShortcut": "Limsa Lominsa",
+          "AethernetShortcut": [
+            "[Limsa Lominsa] Aetheryte Plaza",
+            "[Limsa Lominsa] Marauders' Guild"
+          ],
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true,
+              "InTerritory": [
+                128
+              ]
+            }
+          }
         },
         {
           "DataId": 1006757,
index 2fbe65db6ff05e2c31b17f33864354ad883d473b..18257f4594dccf27d7c4c1a6cf0a8a403bc91a70 100644 (file)
             "Z": -250.56848
           },
           "TerritoryId": 128,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Limsa Lominsa",
+          "AethernetShortcut": [
+            "[Limsa Lominsa] Aetheryte Plaza",
+            "[Limsa Lominsa] Marauders' Guild"
+          ],
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true,
+              "InTerritory": [
+                128
+              ]
+            }
+          }
         }
       ]
     },
index 8e87dd8b2353715221199b1ca9f308f2ae1290c7..aa5a054fbf3a7f5cee6428d1234ebfa28e4c6e52 100644 (file)
             "Z": -250.56848
           },
           "TerritoryId": 128,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Limsa Lominsa",
+          "AethernetShortcut": [
+            "[Limsa Lominsa] Aetheryte Plaza",
+            "[Limsa Lominsa] Marauders' Guild"
+          ],
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true,
+              "InTerritory": [
+                128
+              ]
+            }
+          }
         }
       ]
     },
index a2b6469035ef6a260ccdb300f0c1a3b8b7036c33..270a798d3951d7c90c900736c0557c853d65d002 100644 (file)
             "Z": -250.56848
           },
           "TerritoryId": 128,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Limsa Lominsa",
+          "AethernetShortcut": [
+            "[Limsa Lominsa] Aetheryte Plaza",
+            "[Limsa Lominsa] Marauders' Guild"
+          ],
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true,
+              "InTerritory": [
+                128
+              ]
+            }
+          }
         }
       ]
     },
index 8169dfbd40677cb463aba13893bb114f14bdf5f5..06d12fb34eef3805955b963f83545f24d287d9d5 100644 (file)
             "Z": -250.56848
           },
           "TerritoryId": 128,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Limsa Lominsa",
+          "AethernetShortcut": [
+            "[Limsa Lominsa] Aetheryte Plaza",
+            "[Limsa Lominsa] Marauders' Guild"
+          ],
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true,
+              "InTerritory": [
+                128
+              ]
+            }
+          }
         }
       ]
     },
index 48d669d23fabe8804f7f1e423fb2f5a402798d7c..8f55a98ece23952db804570c1ea234758db524ad 100644 (file)
@@ -35,7 +35,8 @@
                   "Y": 8.712891,\r
                   "Z": 281.69678\r
                 },\r
-                "MaximumDistance": 3\r
+                "MaximumDistance": 3,\r
+                "TerritoryId": 153\r
               }\r
             }\r
           }\r
                   "Y": 8.712891,\r
                   "Z": 281.69678\r
                 },\r
-                "MaximumDistance": 3\r
+                "MaximumDistance": 3,\r
+                "TerritoryId": 153\r
               }\r
             }\r
           }\r
index 18979d0a870fca4a2e1f1e5ba40f1a919a1a4398..cc2dcd8517b74cc568202534ebcda9626e97dd46 100644 (file)
             "Z": 195.94104
           },
           "TerritoryId": 129,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Limsa Lominsa",
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
+            }
+          }
         }
       ]
     },
index 212b5074687ec67295aa272be78f164873000109..83dc2b9773272ca0fb942f6c8c23960b7c01933c 100644 (file)
             "Z": 201.9226
           },
           "TerritoryId": 819,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Crystarium",
+          "AethernetShortcut": [
+            "[Crystarium] Aetheryte Plaza",
+            "[Crystarium] Musica Universalis Markets"
+          ],
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
+            }
+          }
         }
       ]
     },
index be65d1d64ae9e289c7e97a3dddcf279129e9724a..02adab4a20bb71a56500eb556763ef44fd17f33b 100644 (file)
             "Z": 251.75854
           },
           "TerritoryId": 819,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Crystarium",
+          "AethernetShortcut": [
+            "[Crystarium] Aetheryte Plaza",
+            "[Crystarium] Musica Universalis Markets"
+          ],
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
+            }
+          }
         }
       ]
     }
index 86f5071cafb32b3390ab5b8682c157ce7f75b212..4423e4d1190bec65ffcf4baecc52f4cdc5570d48 100644 (file)
               "Prompt": "TEXT_KINGBB201_04854_Q1_000_000",
               "Answer": "TEXT_KINGBB201_04854_A1_000_002"
             }
-          ]
+          ],
+          "AetheryteShortcut": "Gridania",
+          "AethernetShortcut": [
+            "[Gridania] Aetheryte Plaza",
+            "[Gridania] Conjurers' Guild"
+          ],
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true,
+              "InTerritory": [
+                133
+              ]
+            }
+          }
         }
       ]
     },
index d134ace354e1a1b2705412265f32cf5c46368fef..abc4342acfd7a8d0d823b9d0bae113d1ebde5217 100644 (file)
           "TerritoryId": 132,
           "InteractionType": "UseItem",
           "ItemId": 43538,
+          "AetheryteShortcut": "Gridania",
           "SkipConditions": {
             "StepIf": {
               "Item": {
                 "NotInInventory": true
               }
+            },
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
             }
           }
         },
index 6e2461987987cc131942ba0c63cff0094e383704..2a3451f3ca69116663ed184f1056f48f53b1e8ea 100644 (file)
             "Z": -99.321045
           },
           "TerritoryId": 130,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Ul'dah",
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
+            }
+          }
         }
       ]
     },
index ccf61580babfc636278ee1097df44cc0e8a32958..dec630ecdb573b29290fe80b4632c647b1d9f8da 100644 (file)
           "TerritoryId": 131,
           "InteractionType": "UseItem",
           "ItemId": 43537,
+          "AetheryteShortcut": "Ul'dah",
+          "AethernetShortcut": [
+            "[Ul'dah] Aetheryte Plaza",
+            "[Ul'dah] Weavers' Guild"
+          ],
           "SkipConditions": {
             "StepIf": {
               "Item": {
                 "NotInInventory": true
               }
+            },
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true,
+              "InTerritory": [
+                131
+              ]
             }
           }
         },
         {
-         "TerritoryId": 131,
+          "TerritoryId": 131,
           "InteractionType": "EquipItem",
           "ItemId": 41808,
           "SkipConditions": {
index 33df55b7044afef9fd7a05da0bf434ee121f554e..c04f2dc78e5d7b840535d1d059d0b04c75602873 100644 (file)
             "Z": 194.72034
           },
           "TerritoryId": 1185,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Tuliyollal",
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
+            }
+          }
         }
       ]
     },
index 6b6425ea5f4a8d07d7e6422a1566d59386c3de61..a26a9fca3e14c60da0dfff6558eafc0f9ab0f7aa 100644 (file)
             "Z": 628.3817
           },
           "TerritoryId": 957,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Thavnair - Yedlihmad",
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
+            }
+          }
         }
       ]
     },
index 40af8b559723432109beffd0d7d6120bce5faafd..5542bd4b2d71749ac329825a93a67194c7a62e2b 100644 (file)
             "Z": 628.3817
           },
           "TerritoryId": 957,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Thavnair - Yedlihmad",
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
+            }
+          }
         }
       ]
     },
index cbe6d95716921f54a335487b1da70fb4ada9062e..0150bd00f4a8794b4d99b923844b85d648fa687a 100644 (file)
           },
           "TerritoryId": 957,
           "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Thavnair - Yedlihmad",
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
+            }
+          },
           "DialogueChoices": [
             {
               "Type": "List",
index 9b581e947ffc7a8de9af7cd5cbc0258ad6b75d6b..493730251f7d4b6018a87b140db43b77fa281e47 100644 (file)
             "Z": 628.3817
           },
           "TerritoryId": 957,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Thavnair - Yedlihmad",
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
+            }
+          }
         }
       ]
     },
index feff8b349e6cd413d5d90411785f66f135c177f5..73a1350de601471911ccf22737a065046dd87fd8 100644 (file)
             "Z": 628.3817
           },
           "TerritoryId": 957,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Thavnair - Yedlihmad",
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
+            }
+          }
         }
       ]
     },
index ed65c14dd271028552d22ba8f49ab9593ee4e03b..9fd434103a10eb04f17e6e525d77d9c86e175af7 100644 (file)
             "Z": -3.6469727
           },
           "TerritoryId": 621,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Lochs - Porta Praetoria",
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
+            }
+          }
         }
       ]
     },
index 90b8d6de8d8d4598c5a11e2c67b23552a3b4ab6f..e51f3ef2647099f6a8efecee1b505d22348972df 100644 (file)
             "Z": 739.4979
           },
           "TerritoryId": 620,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Peaks - Ala Ghiri",
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
+            }
+          }
         }
       ]
     },
index d73e1be944bba263f1931a54e69fa7d19196256f..0e23ceddc0b9771d21b27bf1460d5e698398988f 100644 (file)
             "Z": 739.4979
           },
           "TerritoryId": 620,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Peaks - Ala Ghiri",
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
+            }
+          }
         }
       ]
     },
index cba86057d97e995392f948388f809dc1e6697769..599b3b1760c6af4ced11344254b4a48009608050 100644 (file)
             "Z": 618.09717
           },
           "TerritoryId": 621,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Lochs - Ala Mhigan Quarter",
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
+            }
+          }
         }
       ]
     },
index ab8d951ab26ea86451cbe96cc7d065022e485cd1..960d223321d30bc6153494997e79c1a67c4d2125 100644 (file)
             "Z": 203.14331
           },
           "TerritoryId": 1185,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Tuliyollal",
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
+            }
+          }
         }
       ]
     },
index 69caf918121492df86e3dc1144eb0e107cb56880..668b23afe27f00e9c6d6a8355ea0494bb83f6774 100644 (file)
             "Z": -48.05072
           },
           "TerritoryId": 418,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Ishgard",
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
+            }
+          }
         }
       ]
     },
index 09bfe8e26cd38484d2b0803863dd9fec1c1dd2fa..9b08c1c9622820264fd22e21e8abf227b174d597 100644 (file)
           },
           "TerritoryId": 418,
           "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Ishgard",
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
+            }
+          },
           "DialogueChoices": [
             {
               "Type": "List",
index 67f58ebbbf1be698af5fa1726d698091fa9bab25..4691ec7c2398d2b3f887c7ca5ce8f0623fcf137b 100644 (file)
             "Z": -1.7243042
           },
           "TerritoryId": 418,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Ishgard",
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
+            }
+          }
         }
       ]
     },
index 544b366f1743619e16b5736dc47d2cf368951c35..a29c5a66571a0702bbb31c3a24fdf9788eda38d9 100644 (file)
           },
           "StopDistance": 5,
           "TerritoryId": 418,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Ishgard",
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
+            }
+          }
         }
       ]
     },
index 1fe65e91ffe2bb6409de0c738f538d4310d1c1de..db15f8e23be3ab73902acec8c567a82b8c1c311d 100644 (file)
             "Z": -48.17273
           },
           "TerritoryId": 418,
-          "InteractionType": "AcceptQuest"
+          "InteractionType": "AcceptQuest",
+          "AetheryteShortcut": "Ishgard",
+          "SkipConditions": {
+            "AetheryteShortcutIf": {
+              "InSameTerritory": true
+            }
+          }
         }
       ]
     },
index 5a23e6e4714d8440f054268c84c4b40cbb188f7c..8ee496bfc55d2c372290244cf8f56661dc56e3a4 100644 (file)
@@ -12,6 +12,7 @@ namespace Questionable.Model.Questing;
 public sealed class QuestStep
 {
     public const float DefaultStopDistance = 3f;
+    public const int VesperBayAetheryteTicket = 30362;
 
     public uint? DataId { get; set; }
 
@@ -110,4 +111,19 @@ public sealed class QuestStep
         else
             return StopDistance ?? DefaultStopDistance;
     }
+
+    /// <summary>
+    /// Only relevant for the step 0 in sequence 0: Whether this step is valid for teleporting to it.
+    /// </summary>
+    /// <returns></returns>
+    public bool IsTeleportableForPriorityQuests()
+    {
+        if (AetheryteShortcut != null)
+            return true;
+
+        if (InteractionType == EInteractionType.UseItem && ItemId == VesperBayAetheryteTicket)
+            return true;
+
+        return false;
+    }
 }
index 2481e8f5c93279874a5a445bedf31481b9be00e5..1e5d51bd3d86a0926c9df7d889957cdcb01e465d 100644 (file)
@@ -23,8 +23,6 @@ namespace Questionable.Controller.Steps.Interactions;
 
 internal static class UseItem
 {
-    public const int VesperBayAetheryteTicket = 30362;
-
     internal sealed class Factory(
         Mount.Factory mountFactory,
         MoveTo.Factory moveFactory,
@@ -47,7 +45,7 @@ internal static class UseItem
 
             ArgumentNullException.ThrowIfNull(step.ItemId);
 
-            if (step.ItemId == VesperBayAetheryteTicket)
+            if (step.ItemId == QuestStep.VesperBayAetheryteTicket)
             {
                 unsafe
                 {
@@ -196,7 +194,7 @@ internal static class UseItem
             if (StartingCombat && condition[ConditionFlag.InCombat])
                 return ETaskResult.TaskComplete;
 
-            if (ItemId == VesperBayAetheryteTicket && _usedItem)
+            if (ItemId == QuestStep.VesperBayAetheryteTicket && _usedItem)
             {
                 InventoryManager* inventoryManager = InventoryManager.Instance();
                 if (inventoryManager == null)
@@ -228,7 +226,7 @@ internal static class UseItem
 
         private TimeSpan GetRetryDelay()
         {
-            if (ItemId == VesperBayAetheryteTicket)
+            if (ItemId == QuestStep.VesperBayAetheryteTicket)
                 return TimeSpan.FromSeconds(11);
             else
                 return TimeSpan.FromSeconds(5);
index 0b12bb3fc36c334fcd6b3255d970036b09e75793..0ac347a24dc67b83e4f9240980256dff7db2f4cd 100644 (file)
@@ -137,7 +137,7 @@ internal static class AetheryteShortcut
 
 
                     if (skipConditions.NearPosition is { } nearPosition &&
-                        clientState.TerritoryType == step.TerritoryId)
+                        clientState.TerritoryType == nearPosition.TerritoryId)
                     {
                         if (Vector3.Distance(nearPosition.Position, clientState.LocalPlayer!.Position) <=
                             nearPosition.MaximumDistance)
index 1d2420cfb85a011331443d388723958164a4833b..1c8a3fa3804c4fa302c9fc1341467b68aaf9005c 100644 (file)
@@ -204,7 +204,7 @@ internal static class SkipCondition
                 }
             }
 
-            if (skipConditions.NearPosition is { } nearPosition && clientState.TerritoryType == step.TerritoryId)
+            if (skipConditions.NearPosition is { } nearPosition && clientState.TerritoryType == nearPosition.TerritoryId)
             {
                 if (Vector3.Distance(nearPosition.Position, clientState.LocalPlayer!.Position) <=
                     nearPosition.MaximumDistance)
index e346822dc6491aafe749b1ea4934cd5f22370830..3f48db397dca3a6b03477136f6b1e8f549f5009e 100644 (file)
@@ -262,14 +262,7 @@ internal sealed unsafe class QuestFunctions
                 if (firstStep == null)
                     return false;
 
-                if (firstStep.AetheryteShortcut != null)
-                    return true;
-
-                if (firstStep is
-                    { InteractionType: EInteractionType.UseItem, ItemId: UseItem.VesperBayAetheryteTicket })
-                    return true;
-
-                return false;
+                return firstStep.IsTeleportableForPriorityQuests();
             })
             .FirstOrDefault(x =>
             {
index 88ebc1b36a9e0b422b41a989f0ff16cca819fb12..5c74c00bdefb9430663e38b494aaa46c7b229d1b 100644 (file)
@@ -223,6 +223,7 @@ public sealed class QuestionablePlugin : IDalamudPlugin
         serviceCollection.AddSingleton<IQuestValidator, CompletionFlagsValidator>();
         serviceCollection.AddSingleton<IQuestValidator, AethernetShortcutValidator>();
         serviceCollection.AddSingleton<IQuestValidator, DialogueChoiceValidator>();
+        serviceCollection.AddSingleton<IQuestValidator, ClassQuestShouldHaveShortcutValidator>();
         serviceCollection.AddSingleton<JsonSchemaValidator>();
         serviceCollection.AddSingleton<IQuestValidator>(sp => sp.GetRequiredService<JsonSchemaValidator>());
     }
index 0f51ce6be15fe5e77bfa0052320799f9ff19b019..755124814be1cba8adccb48e34f02c3fb3e4e093 100644 (file)
@@ -17,4 +17,5 @@ public enum EIssueType
     UnexpectedCompleteQuestStep,
     InvalidAethernetShortcut,
     InvalidExcelRef,
+    ClassQuestWithoutAetheryteShortcut,
 }
index 405c8f88a82e7d3a2e66fd8cecc865f1752b1020..680ef12437e3a6f3259b6725cb8d9e939f88e5e5 100644 (file)
@@ -1,6 +1,51 @@
-namespace Questionable.Validation.Validators;
+using System.Collections.Generic;
+using LLib.GameData;
+using Questionable.Data;
+using Questionable.Model;
+using Questionable.Model.Questing;
 
-public class ClassQuestShouldHaveShortcut
+namespace Questionable.Validation.Validators;
+
+internal sealed class ClassQuestShouldHaveShortcutValidator : IQuestValidator
 {
-    
+    private readonly HashSet<ElementId> _classJobQuests = [];
+
+    public ClassQuestShouldHaveShortcutValidator(QuestData questData)
+    {
+        foreach (EClassJob classJob in typeof(EClassJob).GetEnumValues())
+        {
+            if (classJob == EClassJob.Adventurer)
+                continue;
+
+            foreach (var questInfo in questData.GetClassJobQuests(classJob))
+            {
+                // TODO maybe remove the level check
+                if (questInfo.Level > 1)
+                    _classJobQuests.Add(questInfo.QuestId);
+            }
+        }
+    }
+
+    public IEnumerable<ValidationIssue> Validate(Quest quest)
+    {
+        if (!_classJobQuests.Contains(quest.Id))
+            yield break;
+
+        var firstStep = quest.FindSequence(0)?.FindStep(0);
+        if (firstStep == null)
+            yield break;
+
+        if (firstStep.IsTeleportableForPriorityQuests())
+            yield break;
+
+        yield return new ValidationIssue
+        {
+            ElementId = quest.Id,
+            Sequence = 0,
+            Step = 0,
+            Type = EIssueType.ClassQuestWithoutAetheryteShortcut,
+            Severity = EIssueSeverity.Error,
+            Description = "Class quest should have an aetheryte shortcut to be done automatically",
+        };
+    }
 }