diff --git a/Directory.Build.targets b/Directory.Build.targets
index cfa9441e..729f81b6 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -1,5 +1,5 @@
- 4.15
+ 4.16
diff --git a/GatheringPathRenderer/RendererPlugin.cs b/GatheringPathRenderer/RendererPlugin.cs
index 93c666a8..aa88906c 100644
--- a/GatheringPathRenderer/RendererPlugin.cs
+++ b/GatheringPathRenderer/RendererPlugin.cs
@@ -82,7 +82,7 @@ public sealed class RendererPlugin : IDalamudPlugin
get
{
#if DEBUG
- DirectoryInfo? solutionDirectory = _pluginInterface.AssemblyLocation.Directory?.Parent?.Parent?.Parent;
+ DirectoryInfo? solutionDirectory = _pluginInterface.AssemblyLocation.Directory?.Parent?.Parent;
if (solutionDirectory != null)
{
DirectoryInfo pathProjectDirectory =
@@ -91,7 +91,7 @@ public sealed class RendererPlugin : IDalamudPlugin
return pathProjectDirectory;
}
- throw new Exception("Unable to resolve project path");
+ throw new Exception($"Unable to resolve project path ({_pluginInterface.AssemblyLocation.Directory})");
#else
var allPluginsDirectory = _pluginInterface.ConfigFile.Directory ?? throw new Exception("Unknown directory for plugin configs");
return allPluginsDirectory
diff --git a/QuestPaths/2.x - A Realm Reborn/Alliance Raid Quests/1709_Legacy of Allag.json b/QuestPaths/2.x - A Realm Reborn/Alliance Raid Quests/1709_Legacy of Allag.json
index 1e363fb4..064e9a43 100644
--- a/QuestPaths/2.x - A Realm Reborn/Alliance Raid Quests/1709_Legacy of Allag.json
+++ b/QuestPaths/2.x - A Realm Reborn/Alliance Raid Quests/1709_Legacy of Allag.json
@@ -329,9 +329,9 @@
},
{
"Position": {
- "X": -0.75614685,
+ "X": 3.8795898,
"Y": 38.80212,
- "Z": -11.007636
+ "Z": 0.40251642
},
"TerritoryId": 146,
"InteractionType": "WalkTo",
@@ -359,7 +359,8 @@
null,
128
],
- "Fly": true
+ "Fly": true,
+ "DisableNavmesh": true
},
{
"DataId": 2000078,
diff --git a/QuestPaths/2.x - A Realm Reborn/Class Quests/WAR/1052_Looking the Part.json b/QuestPaths/2.x - A Realm Reborn/Class Quests/WAR/1052_Looking the Part.json
index a3ae2649..59241a3d 100644
--- a/QuestPaths/2.x - A Realm Reborn/Class Quests/WAR/1052_Looking the Part.json
+++ b/QuestPaths/2.x - A Realm Reborn/Class Quests/WAR/1052_Looking the Part.json
@@ -112,9 +112,18 @@
"SkipConditions": {
"AetheryteShortcutIf": {
"InSameTerritory": true
+ },
+ "StepIf": {
+ "CompletionQuestVariablesFlags": [
+ null,
+ null,
+ null,
+ null,
+ null,
+ 64
+ ]
}
- },
- "Comment": "TODO Verify enemy id"
+ }
},
{
"DataId": 2002309,
diff --git a/QuestPaths/2.x - A Realm Reborn/MSQ-1/Shared/272_Life, Materia and Everything.json b/QuestPaths/2.x - A Realm Reborn/MSQ-1/Shared/272_Life, Materia and Everything.json
index 6af9e61b..f56212fb 100644
--- a/QuestPaths/2.x - A Realm Reborn/MSQ-1/Shared/272_Life, Materia and Everything.json
+++ b/QuestPaths/2.x - A Realm Reborn/MSQ-1/Shared/272_Life, Materia and Everything.json
@@ -21,16 +21,30 @@
"Sequence": 1,
"Steps": [
{
- "DataId": 1001426,
"Position": {
- "X": 123.33862,
- "Y": 30.999996,
- "Z": -384.9394
+ "X": 2.7922537,
+ "Y": 8.206551,
+ "Z": -274.32318
},
"TerritoryId": 141,
- "InteractionType": "Interact",
- "Comment": "'Forging the Spirit'",
- "AetheryteShortcut": "Central Thanalan - Black Brush Station"
+ "InteractionType": "WalkTo",
+ "AetheryteShortcut": "Central Thanalan - Black Brush Station",
+ "SkipConditions": {
+ "AetheryteShortcutIf": {
+ "InSameTerritory": true
+ },
+ "StepIf": {
+ "NearPosition": {
+ "Position": {
+ "X": 123.33862,
+ "Y": 30.999996,
+ "Z": -384.9394
+ },
+ "TerritoryId": 141,
+ "MaximumDistance": 30
+ }
+ }
+ }
},
{
"DataId": 1001426,
@@ -40,8 +54,8 @@
"Z": -384.9394
},
"TerritoryId": 141,
- "InteractionType": "Interact",
- "Comment": "Quest Turn-In 'Forging the Spirit'"
+ "InteractionType": "AcceptQuest",
+ "PickUpQuestId": 638
},
{
"DataId": 1001425,
diff --git a/QuestPaths/2.x - A Realm Reborn/MSQ-2/A9-Haukke Manor/801_Skeletons in Her Closet.json b/QuestPaths/2.x - A Realm Reborn/MSQ-2/A9-Haukke Manor/801_Skeletons in Her Closet.json
index 9269a84b..a17b715c 100644
--- a/QuestPaths/2.x - A Realm Reborn/MSQ-2/A9-Haukke Manor/801_Skeletons in Her Closet.json
+++ b/QuestPaths/2.x - A Realm Reborn/MSQ-2/A9-Haukke Manor/801_Skeletons in Her Closet.json
@@ -67,7 +67,7 @@
"TerritoryId": 148,
"InteractionType": "Duty",
"ContentFinderConditionId": 6,
- "AutoDutyEnabled": true
+ "AutoDutyEnabled": false
}
]
},
diff --git a/QuestPaths/2.x - A Realm Reborn/MSQ-2/B2-Eastern La Noscea, Brayflox, Cheese and Wine/832_The Things We Do for Cheese.json b/QuestPaths/2.x - A Realm Reborn/MSQ-2/B2-Eastern La Noscea, Brayflox, Cheese and Wine/832_The Things We Do for Cheese.json
index 06402bac..960ac4ec 100644
--- a/QuestPaths/2.x - A Realm Reborn/MSQ-2/B2-Eastern La Noscea, Brayflox, Cheese and Wine/832_The Things We Do for Cheese.json
+++ b/QuestPaths/2.x - A Realm Reborn/MSQ-2/B2-Eastern La Noscea, Brayflox, Cheese and Wine/832_The Things We Do for Cheese.json
@@ -86,7 +86,7 @@
"TerritoryId": 137,
"InteractionType": "Duty",
"ContentFinderConditionId": 8,
- "AutoDutyEnabled": true
+ "AutoDutyEnabled": false
}
]
},
diff --git a/QuestPaths/2.x - A Realm Reborn/MSQ-2/C6-Mor Dhona/1001_Drowning Out the Voices.json b/QuestPaths/2.x - A Realm Reborn/MSQ-2/C6-Mor Dhona/1001_Drowning Out the Voices.json
index 1fcf9d81..59a79e75 100644
--- a/QuestPaths/2.x - A Realm Reborn/MSQ-2/C6-Mor Dhona/1001_Drowning Out the Voices.json
+++ b/QuestPaths/2.x - A Realm Reborn/MSQ-2/C6-Mor Dhona/1001_Drowning Out the Voices.json
@@ -51,6 +51,7 @@
},
"TerritoryId": 156,
"InteractionType": "Combat",
+ "DelaySecondsAtStart": 2,
"EnemySpawnType": "AfterItemUse",
"ItemId": 2000766,
"KillEnemyDataIds": [
@@ -180,6 +181,7 @@
},
"TerritoryId": 156,
"InteractionType": "Combat",
+ "DelaySecondsAtStart": 2,
"EnemySpawnType": "AfterItemUse",
"ItemId": 2000766,
"KillEnemyDataIds": [
@@ -238,7 +240,8 @@
},
"TerritoryId": 156,
"InteractionType": "UseItem",
- "ItemId": 2000766
+ "ItemId": 2000766,
+ "DelaySecondsAtStart": 2
}
]
},
diff --git a/QuestPaths/2.x - A Realm Reborn/MSQ-2/C9-Ultimate Weapon/3873_Rock the Castrum.json b/QuestPaths/2.x - A Realm Reborn/MSQ-2/C9-Ultimate Weapon/3873_Rock the Castrum.json
index 7eec220a..dba66d15 100644
--- a/QuestPaths/2.x - A Realm Reborn/MSQ-2/C9-Ultimate Weapon/3873_Rock the Castrum.json
+++ b/QuestPaths/2.x - A Realm Reborn/MSQ-2/C9-Ultimate Weapon/3873_Rock the Castrum.json
@@ -35,13 +35,163 @@
"Z": -225.17743
},
"TerritoryId": 147,
- "InteractionType": "Interact"
+ "InteractionType": "Interact",
+ "AetheryteShortcut": "Northern Thanalan - Ceruleum Processing Plant",
+ "SkipConditions": {
+ "AetheryteShortcutIf": {
+ "InSameTerritory": true
+ }
+ }
}
]
},
{
"Sequence": 2,
+ "$": "This doesn't include the DRK/MCH/AST coffers that exist at level 50, but you cannot obtain them until HW",
"Steps": [
+ {
+ "TerritoryId": 147,
+ "InteractionType": "UseItem",
+ "ItemId": 31337,
+ "$": "Lv49 Weapon Coffer",
+ "SkipConditions": {
+ "StepIf": {
+ "Item": {
+ "NotInInventory": true
+ }
+ }
+ }
+ },
+ {
+ "TerritoryId": 147,
+ "InteractionType": "UseItem",
+ "ItemId": 20642,
+ "$": "Lv50 PLD Coffer",
+ "SkipConditions": {
+ "StepIf": {
+ "Item": {
+ "NotInInventory": true
+ }
+ }
+ }
+ },
+ {
+ "TerritoryId": 147,
+ "InteractionType": "UseItem",
+ "ItemId": 20643,
+ "$": "Lv50 MNK Coffer",
+ "SkipConditions": {
+ "StepIf": {
+ "Item": {
+ "NotInInventory": true
+ }
+ }
+ }
+ },
+ {
+ "TerritoryId": 147,
+ "InteractionType": "UseItem",
+ "ItemId": 20644,
+ "$": "Lv50 WAR Coffer",
+ "SkipConditions": {
+ "StepIf": {
+ "Item": {
+ "NotInInventory": true
+ }
+ }
+ }
+ },
+ {
+ "TerritoryId": 147,
+ "InteractionType": "UseItem",
+ "ItemId": 20645,
+ "$": "Lv50 DRG Coffer",
+ "SkipConditions": {
+ "StepIf": {
+ "Item": {
+ "NotInInventory": true
+ }
+ }
+ }
+ },
+ {
+ "TerritoryId": 147,
+ "InteractionType": "UseItem",
+ "ItemId": 20646,
+ "$": "Lv50 BRD Coffer",
+ "SkipConditions": {
+ "StepIf": {
+ "Item": {
+ "NotInInventory": true
+ }
+ }
+ }
+ },
+ {
+ "TerritoryId": 147,
+ "InteractionType": "UseItem",
+ "ItemId": 20647,
+ "$": "Lv50 NIN Coffer",
+ "SkipConditions": {
+ "StepIf": {
+ "Item": {
+ "NotInInventory": true
+ }
+ }
+ }
+ },
+ {
+ "TerritoryId": 147,
+ "InteractionType": "UseItem",
+ "ItemId": 20648,
+ "$": "Lv50 WHM Coffer",
+ "SkipConditions": {
+ "StepIf": {
+ "Item": {
+ "NotInInventory": true
+ }
+ }
+ }
+ },
+ {
+ "TerritoryId": 147,
+ "InteractionType": "UseItem",
+ "ItemId": 20649,
+ "$": "Lv50 BLM Coffer",
+ "SkipConditions": {
+ "StepIf": {
+ "Item": {
+ "NotInInventory": true
+ }
+ }
+ }
+ },
+ {
+ "TerritoryId": 147,
+ "InteractionType": "UseItem",
+ "ItemId": 20650,
+ "$": "Lv50 SMN Coffer",
+ "SkipConditions": {
+ "StepIf": {
+ "Item": {
+ "NotInInventory": true
+ }
+ }
+ }
+ },
+ {
+ "TerritoryId": 147,
+ "InteractionType": "UseItem",
+ "ItemId": 20651,
+ "$": "Lv50 SCH Coffer",
+ "SkipConditions": {
+ "StepIf": {
+ "Item": {
+ "NotInInventory": true
+ }
+ }
+ }
+ },
{
"TerritoryId": 147,
"InteractionType": "Duty",
diff --git a/QuestPaths/2.x - A Realm Reborn/MSQ-2/C9-Ultimate Weapon/4521_Operation Archon.json b/QuestPaths/2.x - A Realm Reborn/MSQ-2/C9-Ultimate Weapon/4521_Operation Archon.json
index 81c32c86..2f33376f 100644
--- a/QuestPaths/2.x - A Realm Reborn/MSQ-2/C9-Ultimate Weapon/4521_Operation Archon.json
+++ b/QuestPaths/2.x - A Realm Reborn/MSQ-2/C9-Ultimate Weapon/4521_Operation Archon.json
@@ -5,6 +5,71 @@
{
"Sequence": 0,
"Steps": [
+ {
+ "TerritoryId": 132,
+ "InteractionType": "UseItem",
+ "ItemId": 30362,
+ "TargetTerritoryId": 140,
+ "SkipConditions": {
+ "StepIf": {
+ "InTerritory": [
+ 140,
+ 212
+ ]
+ }
+ }
+ },
+ {
+ "Position": {
+ "X": -492.96475,
+ "Y": 20.999884,
+ "Z": -380.82272
+ },
+ "TerritoryId": 140,
+ "InteractionType": "WalkTo",
+ "$": "Avoid walking around Waking Sands table",
+ "SkipConditions": {
+ "StepIf": {
+ "InTerritory": [
+ 212
+ ]
+ }
+ }
+ },
+ {
+ "DataId": 2001711,
+ "Position": {
+ "X": -480.9181,
+ "Y": 18.00103,
+ "Z": -386.862
+ },
+ "TerritoryId": 140,
+ "InteractionType": "Interact",
+ "TargetTerritoryId": 212,
+ "SkipConditions": {
+ "StepIf": {
+ "InTerritory": [
+ 212
+ ]
+ }
+ }
+ },
+ {
+ "DataId": 2001715,
+ "Position": {
+ "X": 23.23944,
+ "Y": 2.090454,
+ "Z": -0.015319824
+ },
+ "TerritoryId": 212,
+ "InteractionType": "Interact",
+ "TargetTerritoryId": 212,
+ "SkipConditions": {
+ "StepIf": {
+ "ExtraCondition": "WakingSandsSolar"
+ }
+ }
+ },
{
"DataId": 1006690,
"Position": {
@@ -29,7 +94,14 @@
},
"TerritoryId": 212,
"InteractionType": "Interact",
- "TargetTerritoryId": 212
+ "TargetTerritoryId": 212,
+ "SkipConditions": {
+ "StepIf": {
+ "InTerritory": [
+ 140
+ ]
+ }
+ }
},
{
"DataId": 2001716,
@@ -40,7 +112,14 @@
},
"TerritoryId": 212,
"InteractionType": "Interact",
- "TargetTerritoryId": 140
+ "TargetTerritoryId": 140,
+ "SkipConditions": {
+ "StepIf": {
+ "InTerritory": [
+ 140
+ ]
+ }
+ }
},
{
"DataId": 1006578,
diff --git a/QuestPaths/2.x - A Realm Reborn/Side Quests/Thanalan/Eastern Thanalan/638_Forging the Spirit.json b/QuestPaths/2.x - A Realm Reborn/Side Quests/Thanalan/Eastern Thanalan/638_Forging the Spirit.json
new file mode 100644
index 00000000..dae2a859
--- /dev/null
+++ b/QuestPaths/2.x - A Realm Reborn/Side Quests/Thanalan/Eastern Thanalan/638_Forging the Spirit.json
@@ -0,0 +1,36 @@
+{
+ "$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
+ "Author": "liza",
+ "QuestSequence": [
+ {
+ "Sequence": 0,
+ "Steps": [
+ {
+ "DataId": 1001426,
+ "Position": {
+ "X": 123.33862,
+ "Y": 30.999996,
+ "Z": -384.9394
+ },
+ "TerritoryId": 141,
+ "InteractionType": "AcceptQuest"
+ }
+ ]
+ },
+ {
+ "Sequence": 255,
+ "Steps": [
+ {
+ "DataId": 1001426,
+ "Position": {
+ "X": 123.33862,
+ "Y": 30.999996,
+ "Z": -384.9394
+ },
+ "TerritoryId": 141,
+ "InteractionType": "CompleteQuest"
+ }
+ ]
+ }
+ ]
+}
diff --git a/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2734_Perchance to Hanami.json b/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2734_Perchance to Hanami.json
index 4c41c9a6..35b1eb35 100644
--- a/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2734_Perchance to Hanami.json
+++ b/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2734_Perchance to Hanami.json
@@ -86,9 +86,10 @@
},
"TerritoryId": 614,
"InteractionType": "CompleteQuest",
- "Fly": true
+ "Fly": true,
+ "NextQuestId": 2748
}
]
}
]
-}
\ No newline at end of file
+}
diff --git a/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2736_Courage the Cowardly Lupin.json b/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2736_Courage the Cowardly Lupin.json
index a319d70c..137f6fc8 100644
--- a/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2736_Courage the Cowardly Lupin.json
+++ b/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2736_Courage the Cowardly Lupin.json
@@ -131,9 +131,10 @@
}
}
},
- "Fly": true
+ "Fly": true,
+ "NextQuestId": 2737
}
]
}
]
-}
\ No newline at end of file
+}
diff --git a/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2737_Kurobana vs the Rice Sacks.json b/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2737_Kurobana vs the Rice Sacks.json
index 76c060a6..c0640ae1 100644
--- a/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2737_Kurobana vs the Rice Sacks.json
+++ b/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2737_Kurobana vs the Rice Sacks.json
@@ -123,9 +123,10 @@
}
}
},
- "Fly": true
+ "Fly": true,
+ "NextQuestId": 2738
}
]
}
]
-}
\ No newline at end of file
+}
diff --git a/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2738_Kurobana vs the Arrowheads.json b/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2738_Kurobana vs the Arrowheads.json
index 7203fa8f..44eb2726 100644
--- a/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2738_Kurobana vs the Arrowheads.json
+++ b/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2738_Kurobana vs the Arrowheads.json
@@ -159,9 +159,10 @@
}
}
},
- "Fly": true
+ "Fly": true,
+ "NextQuestId": 2739
}
]
}
]
-}
\ No newline at end of file
+}
diff --git a/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2739_Kurobana Holmes.json b/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2739_Kurobana Holmes.json
index a5211c3d..f5809f06 100644
--- a/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2739_Kurobana Holmes.json
+++ b/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2739_Kurobana Holmes.json
@@ -142,9 +142,10 @@
}
}
},
- "Fly": true
+ "Fly": true,
+ "NextQuestId": 2740
}
]
}
]
-}
\ No newline at end of file
+}
diff --git a/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2747_Amber Alert.json b/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2747_Amber Alert.json
index 20d4eb7c..52185f15 100644
--- a/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2747_Amber Alert.json
+++ b/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2747_Amber Alert.json
@@ -24,7 +24,7 @@
},
"TerritoryId": 614,
"InteractionType": "AcceptQuest",
- "StopDistance": 0.1
+ "StopDistance": 0.25
}
]
},
@@ -67,7 +67,7 @@
},
"TerritoryId": 614,
"InteractionType": "Interact",
- "StopDistance": 0.1
+ "StopDistance": 0.25
}
]
},
@@ -84,9 +84,10 @@
"TerritoryId": 614,
"InteractionType": "CompleteQuest",
"Fly": true,
- "AetheryteShortcut": "Yanxia - Namai"
+ "AetheryteShortcut": "Yanxia - Namai",
+ "NextQuestId": 2740
}
]
}
]
-}
\ No newline at end of file
+}
diff --git a/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2748_Gyorin the Namazu.json b/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2748_Gyorin the Namazu.json
new file mode 100644
index 00000000..910bc8fe
--- /dev/null
+++ b/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2748_Gyorin the Namazu.json
@@ -0,0 +1,143 @@
+{
+ "$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
+ "Author": "liza",
+ "QuestSequence": [
+ {
+ "Sequence": 0,
+ "Steps": [
+ {
+ "DataId": 1023236,
+ "Position": {
+ "X": -300.06866,
+ "Y": 16.806112,
+ "Z": 539.45215
+ },
+ "TerritoryId": 614,
+ "InteractionType": "AcceptQuest",
+ "Fly": true
+ }
+ ]
+ },
+ {
+ "Sequence": 1,
+ "Steps": [
+ {
+ "DataId": 1023237,
+ "Position": {
+ "X": -233.72241,
+ "Y": 17.628202,
+ "Z": 485.3131
+ },
+ "TerritoryId": 614,
+ "InteractionType": "Interact",
+ "Fly": true
+ }
+ ]
+ },
+ {
+ "Sequence": 2,
+ "Steps": [
+ {
+ "Position": {
+ "X": -463.34363,
+ "Y": 1.3011811,
+ "Z": 578.3476
+ },
+ "TerritoryId": 614,
+ "InteractionType": "WalkTo",
+ "Fly": true
+ },
+ {
+ "DataId": 1023238,
+ "Position": {
+ "X": -464.49988,
+ "Y": 1.3011812,
+ "Z": 577.32495
+ },
+ "TerritoryId": 614,
+ "InteractionType": "Interact"
+ }
+ ]
+ },
+ {
+ "Sequence": 3,
+ "Steps": [
+ {
+ "Position": {
+ "X": -487.5986,
+ "Y": -0.5999999,
+ "Z": 578.5466
+ },
+ "TerritoryId": 614,
+ "InteractionType": "Dive",
+ "DisableNavmesh": true
+ },
+ {
+ "DataId": 2008799,
+ "Position": {
+ "X": -549.7063,
+ "Y": -109.51398,
+ "Z": 569.32935
+ },
+ "TerritoryId": 614,
+ "InteractionType": "Interact",
+ "Fly": true,
+ "Mount": true
+ }
+ ]
+ },
+ {
+ "Sequence": 4,
+ "Steps": [
+ {
+ "Position": {
+ "X": -487.5986,
+ "Y": -0.5999999,
+ "Z": 578.5466
+ },
+ "TerritoryId": 614,
+ "InteractionType": "WalkTo",
+ "DisableNavmesh": true,
+ "RestartNavigationIfCancelled": false
+ },
+ {
+ "Position": {
+ "X": -463.34363,
+ "Y": 1.3011811,
+ "Z": 578.3476
+ },
+ "TerritoryId": 614,
+ "InteractionType": "WalkTo",
+ "Fly": true
+ },
+ {
+ "DataId": 1023238,
+ "Position": {
+ "X": -464.49988,
+ "Y": 1.3011812,
+ "Z": 577.32495
+ },
+ "TerritoryId": 614,
+ "InteractionType": "Interact"
+ }
+ ]
+ },
+ {
+ "Sequence": 255,
+ "Steps": [
+ {
+ "DataId": 1023237,
+ "Position": {
+ "X": -233.72241,
+ "Y": 17.628202,
+ "Z": 485.3131
+ },
+ "TerritoryId": 614,
+ "InteractionType": "CompleteQuest",
+ "Fly": true,
+ "NextQuestId": 2749
+ }
+ ]
+ }
+ ]
+}
diff --git a/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2749_No Wealth Like Mineral Wealth.json b/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2749_No Wealth Like Mineral Wealth.json
index b63fe369..d85ab406 100644
--- a/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2749_No Wealth Like Mineral Wealth.json
+++ b/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2749_No Wealth Like Mineral Wealth.json
@@ -37,6 +37,21 @@
{
"Sequence": 2,
"Steps": [
+ {
+ "Position": {
+ "X": -239.56377,
+ "Y": 49.354053,
+ "Z": 284.94565
+ },
+ "TerritoryId": 614,
+ "InteractionType": "WalkTo",
+ "Fly": true,
+ "SkipConditions": {
+ "StepIf": {
+ "Flying": "Locked"
+ }
+ }
+ },
{
"DataId": 1023240,
"Position": {
@@ -59,6 +74,7 @@
"Y": 39.150906,
"Z": 206.95801
},
+ "StopDistance": 0.5,
"TerritoryId": 614,
"InteractionType": "Combat",
"Fly": true,
@@ -113,9 +129,10 @@
},
"TerritoryId": 614,
"InteractionType": "CompleteQuest",
- "Fly": true
+ "Fly": true,
+ "NextQuestId": 2750
}
]
}
]
-}
\ No newline at end of file
+}
diff --git a/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2750_Fresh Flesh.json b/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2750_Fresh Flesh.json
index dd88387b..79b79e9b 100644
--- a/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2750_Fresh Flesh.json
+++ b/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2750_Fresh Flesh.json
@@ -98,9 +98,10 @@
},
"TerritoryId": 614,
"InteractionType": "CompleteQuest",
- "Fly": true
+ "Fly": true,
+ "NextQuestId": 2751
}
]
}
]
-}
\ No newline at end of file
+}
diff --git a/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2751_Show Me the New Money.json b/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2751_Show Me the New Money.json
index 080d2189..4a9a8aa8 100644
--- a/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2751_Show Me the New Money.json
+++ b/QuestPaths/4.x - Stormblood/Side Quests/Yanxia/2751_Show Me the New Money.json
@@ -112,9 +112,10 @@
},
"TerritoryId": 614,
"InteractionType": "CompleteQuest",
- "Fly": true
+ "Fly": true,
+ "NextQuestId": 2747
}
]
}
]
-}
\ No newline at end of file
+}
diff --git a/QuestPaths/7.x - Dawntrail/Role Quests/5188_Picking Up the Torch.json b/QuestPaths/7.x - Dawntrail/Role Quests/5188_Picking Up the Torch.json
new file mode 100644
index 00000000..d8d59f15
--- /dev/null
+++ b/QuestPaths/7.x - Dawntrail/Role Quests/5188_Picking Up the Torch.json
@@ -0,0 +1,161 @@
+{
+ "$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
+ "Author": "liza",
+ "QuestSequence": [
+ {
+ "Sequence": 0,
+ "Steps": [
+ {
+ "DataId": 1050871,
+ "Position": {
+ "X": -51.895935,
+ "Y": -17.97287,
+ "Z": 182.7268
+ },
+ "TerritoryId": 1185,
+ "InteractionType": "AcceptQuest",
+ "AetheryteShortcut": "Tuliyollal",
+ "AethernetShortcut": [
+ "[Tuliyollal] Aetheryte Plaza",
+ "[Tuliyollal] The For'ard Cabins"
+ ],
+ "SkipConditions": {
+ "AetheryteShortcutIf": {
+ "InSameTerritory": true
+ }
+ }
+ }
+ ]
+ },
+ {
+ "Sequence": 1,
+ "Steps": [
+ {
+ "DataId": 1001657,
+ "Position": {
+ "X": 94.80432,
+ "Y": 7.9804688,
+ "Z": -34.042908
+ },
+ "TerritoryId": 131,
+ "InteractionType": "Interact",
+ "AetheryteShortcut": "Ul'dah",
+ "AethernetShortcut": [
+ "[Ul'dah] Aetheryte Plaza",
+ "[Ul'dah] Sapphire Avenue Exchange"
+ ],
+ "CompletionQuestVariablesFlags": [
+ null,
+ null,
+ null,
+ null,
+ null,
+ 32
+ ]
+ },
+ {
+ "DataId": 1006440,
+ "Position": {
+ "X": 140.3982,
+ "Y": 4,
+ "Z": -54.154297
+ },
+ "TerritoryId": 131,
+ "InteractionType": "Interact",
+ "CompletionQuestVariablesFlags": [
+ null,
+ null,
+ null,
+ null,
+ null,
+ 64
+ ]
+ },
+ {
+ "DataId": 1051655,
+ "Position": {
+ "X": 137.74304,
+ "Y": 4,
+ "Z": 5.9662476
+ },
+ "TerritoryId": 131,
+ "InteractionType": "Interact",
+ "CompletionQuestVariablesFlags": [
+ null,
+ null,
+ null,
+ null,
+ null,
+ 128
+ ]
+ }
+ ]
+ },
+ {
+ "Sequence": 2,
+ "Steps": [
+ {
+ "Position": {
+ "X": 146.12386,
+ "Y": 4,
+ "Z": -23.562449
+ },
+ "StopDistance": 0.5,
+ "TerritoryId": 131,
+ "InteractionType": "Emote",
+ "Emote": "angry"
+ }
+ ]
+ },
+ {
+ "Sequence": 3,
+ "Steps": [
+ {
+ "DataId": 1051656,
+ "Position": {
+ "X": 56.443115,
+ "Y": 10,
+ "Z": 5.935669
+ },
+ "TerritoryId": 131,
+ "InteractionType": "Interact"
+ }
+ ]
+ },
+ {
+ "Sequence": 255,
+ "Steps": [
+ {
+ "DataId": 2012114,
+ "Position": {
+ "X": 0,
+ "Y": 1.15,
+ "Z": 10.23451
+ },
+ "TerritoryId": 1255,
+ "InteractionType": "Interact",
+ "TargetTerritoryId": 131,
+ "SkipConditions": {
+ "StepIf": {
+ "InTerritory": [
+ 131
+ ]
+ }
+ }
+ },
+ {
+ "DataId": 1051656,
+ "Position": {
+ "X": 56.443115,
+ "Y": 10,
+ "Z": 5.935669
+ },
+ "StopDistance": 7,
+ "TerritoryId": 131,
+ "InteractionType": "CompleteQuest",
+ "NextQuestId": 5189
+ }
+ ]
+ }
+ ]
+}
diff --git a/QuestPaths/7.x - Dawntrail/Role Quests/5189_Imposing Views.json b/QuestPaths/7.x - Dawntrail/Role Quests/5189_Imposing Views.json
new file mode 100644
index 00000000..17c2bf46
--- /dev/null
+++ b/QuestPaths/7.x - Dawntrail/Role Quests/5189_Imposing Views.json
@@ -0,0 +1,129 @@
+{
+ "$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
+ "Author": "liza",
+ "QuestSequence": [
+ {
+ "Sequence": 0,
+ "Steps": [
+ {
+ "DataId": 1051656,
+ "Position": {
+ "X": 56.443115,
+ "Y": 10,
+ "Z": 5.935669
+ },
+ "StopDistance": 7,
+ "TerritoryId": 131,
+ "InteractionType": "AcceptQuest"
+ }
+ ]
+ },
+ {
+ "Sequence": 1,
+ "Steps": [
+ {
+ "DataId": 2014419,
+ "Position": {
+ "X": -158.86176,
+ "Y": 7.4921875,
+ "Z": 493.88867
+ },
+ "TerritoryId": 146,
+ "InteractionType": "Interact",
+ "AetheryteShortcut": "Southern Thanalan - Forgotten Springs",
+ "Fly": true
+ }
+ ]
+ },
+ {
+ "Sequence": 2,
+ "Steps": [
+ {
+ "DataId": 1051661,
+ "Position": {
+ "X": 1.7852783,
+ "Y": 19.026453,
+ "Z": 581.62805
+ },
+ "StopDistance": 5,
+ "TerritoryId": 146,
+ "InteractionType": "Interact",
+ "DialogueChoices": [
+ {
+ "Type": "List",
+ "Prompt": "TEXT_KINGBZ002_05189_Q1_000_000",
+ "Answer": "TEXT_KINGBZ002_05189_A1_000_001"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Sequence": 3,
+ "Steps": [
+ {
+ "DataId": 1051663,
+ "Position": {
+ "X": 51.68225,
+ "Y": 0.7631253,
+ "Z": 711.57385
+ },
+ "TerritoryId": 146,
+ "InteractionType": "Combat",
+ "EnemySpawnType": "AfterInteraction",
+ "KillEnemyDataIds": [
+ 18178
+ ],
+ "Fly": true
+ }
+ ]
+ },
+ {
+ "Sequence": 4,
+ "Steps": [
+ {
+ "DataId": 1051663,
+ "Position": {
+ "X": 51.68225,
+ "Y": 0.7631253,
+ "Z": 711.57385
+ },
+ "TerritoryId": 146,
+ "InteractionType": "Interact"
+ }
+ ]
+ },
+ {
+ "Sequence": 5,
+ "Steps": [
+ {
+ "DataId": 1051668,
+ "Position": {
+ "X": 170.42798,
+ "Y": 15.943722,
+ "Z": 897.94763
+ },
+ "TerritoryId": 146,
+ "InteractionType": "Interact",
+ "Fly": true
+ }
+ ]
+ },
+ {
+ "Sequence": 255,
+ "Steps": [
+ {
+ "DataId": 1051668,
+ "Position": {
+ "X": 170.42798,
+ "Y": 15.943722,
+ "Z": 897.94763
+ },
+ "TerritoryId": 146,
+ "InteractionType": "CompleteQuest",
+ "NextQuestId": 5190
+ }
+ ]
+ }
+ ]
+}
diff --git a/QuestPaths/7.x - Dawntrail/Role Quests/5190_Enforcing Freedom.json b/QuestPaths/7.x - Dawntrail/Role Quests/5190_Enforcing Freedom.json
new file mode 100644
index 00000000..6f05c439
--- /dev/null
+++ b/QuestPaths/7.x - Dawntrail/Role Quests/5190_Enforcing Freedom.json
@@ -0,0 +1,175 @@
+{
+ "$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
+ "Author": "liza",
+ "QuestSequence": [
+ {
+ "Sequence": 0,
+ "Steps": [
+ {
+ "DataId": 1051668,
+ "Position": {
+ "X": 170.42798,
+ "Y": 15.943722,
+ "Z": 897.94763
+ },
+ "TerritoryId": 146,
+ "InteractionType": "AcceptQuest"
+ }
+ ]
+ },
+ {
+ "Sequence": 1,
+ "Steps": [
+ {
+ "DataId": 1050871,
+ "Position": {
+ "X": -51.895935,
+ "Y": -17.97287,
+ "Z": 182.7268
+ },
+ "TerritoryId": 1185,
+ "InteractionType": "Interact",
+ "AetheryteShortcut": "Tuliyollal",
+ "AethernetShortcut": [
+ "[Tuliyollal] Aetheryte Plaza",
+ "[Tuliyollal] The For'ard Cabins"
+ ]
+ }
+ ]
+ },
+ {
+ "Sequence": 2,
+ "Steps": [
+ {
+ "DataId": 1051670,
+ "Position": {
+ "X": -15.976257,
+ "Y": -19.928413,
+ "Z": 224.90259
+ },
+ "TerritoryId": 1185,
+ "InteractionType": "Interact"
+ }
+ ]
+ },
+ {
+ "Sequence": 3,
+ "Steps": [
+ {
+ "DataId": 1051675,
+ "Position": {
+ "X": 358.23608,
+ "Y": 5.957184,
+ "Z": 428.36658
+ },
+ "StopDistance": 1,
+ "TerritoryId": 1190,
+ "InteractionType": "Interact",
+ "AetheryteShortcut": "Shaaloani - Hhusatahwi",
+ "Fly": true
+ }
+ ]
+ },
+ {
+ "Sequence": 4,
+ "Steps": [
+ {
+ "Position": {
+ "X": 363.81656,
+ "Y": 5.9295864,
+ "Z": 435.17932
+ },
+ "TerritoryId": 1190,
+ "InteractionType": "WalkTo"
+ },
+ {
+ "DataId": 1051677,
+ "Position": {
+ "X": 371.4198,
+ "Y": 5.95728,
+ "Z": 425.4978
+ },
+ "TerritoryId": 1190,
+ "InteractionType": "Interact"
+ }
+ ]
+ },
+ {
+ "Sequence": 5,
+ "Steps": [
+ {
+ "DataId": 1051677,
+ "Position": {
+ "X": 371.4198,
+ "Y": 5.95728,
+ "Z": 425.4978
+ },
+ "TerritoryId": 1190,
+ "InteractionType": "Emote",
+ "Emote": "unbound"
+ }
+ ]
+ },
+ {
+ "Sequence": 6,
+ "Steps": [
+ {
+ "DataId": 1051682,
+ "Position": {
+ "X": 387.5028,
+ "Y": -0.60167974,
+ "Z": 426.99304
+ },
+ "TerritoryId": 1190,
+ "InteractionType": "Interact"
+ }
+ ]
+ },
+ {
+ "Sequence": 7,
+ "Steps": [
+ {
+ "Position": {
+ "X": 425.24307,
+ "Y": 0.7699772,
+ "Z": 473.79095
+ },
+ "TerritoryId": 1190,
+ "InteractionType": "WalkTo",
+ "Fly": true
+ },
+ {
+ "DataId": 1051684,
+ "Position": {
+ "X": 426.04712,
+ "Y": 0.7461932,
+ "Z": 472.3125
+ },
+ "TerritoryId": 1190,
+ "InteractionType": "Interact"
+ }
+ ]
+ },
+ {
+ "Sequence": 255,
+ "Steps": [
+ {
+ "DataId": 1050871,
+ "Position": {
+ "X": -51.895935,
+ "Y": -17.97287,
+ "Z": 182.7268
+ },
+ "TerritoryId": 1185,
+ "InteractionType": "CompleteQuest",
+ "AetheryteShortcut": "Tuliyollal",
+ "AethernetShortcut": [
+ "[Tuliyollal] Aetheryte Plaza",
+ "[Tuliyollal] The For'ard Cabins"
+ ],
+ "NextQuestId": 5191
+ }
+ ]
+ }
+ ]
+}
diff --git a/QuestPaths/7.x - Dawntrail/Role Quests/5191_Bar the Passage.json b/QuestPaths/7.x - Dawntrail/Role Quests/5191_Bar the Passage.json
new file mode 100644
index 00000000..ac9a8790
--- /dev/null
+++ b/QuestPaths/7.x - Dawntrail/Role Quests/5191_Bar the Passage.json
@@ -0,0 +1,182 @@
+{
+ "$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
+ "Author": "liza",
+ "QuestSequence": [
+ {
+ "Sequence": 0,
+ "Steps": [
+ {
+ "DataId": 1050871,
+ "Position": {
+ "X": -51.895935,
+ "Y": -17.97287,
+ "Z": 182.7268
+ },
+ "TerritoryId": 1185,
+ "InteractionType": "AcceptQuest"
+ }
+ ]
+ },
+ {
+ "Sequence": 1,
+ "Steps": [
+ {
+ "DataId": 1051689,
+ "Position": {
+ "X": 273.33484,
+ "Y": 15.999998,
+ "Z": 740.6576
+ },
+ "TerritoryId": 1190,
+ "InteractionType": "SinglePlayerDuty",
+ "AethernetShortcut": [
+ "[Tuliyollal] The For'ard Cabins",
+ "[Tuliyollal] Xak Tural Skygate (Shaaloani)"
+ ]
+ }
+ ]
+ },
+ {
+ "Sequence": 2
+ },
+ {
+ "Sequence": 3,
+ "Steps": [
+ {
+ "DataId": 1051691,
+ "Position": {
+ "X": 273.85364,
+ "Y": 15.999996,
+ "Z": 738.2771
+ },
+ "TerritoryId": 1190,
+ "InteractionType": "Interact"
+ }
+ ]
+ },
+ {
+ "Sequence": 4,
+ "Steps": [
+ {
+ "DataId": 1050871,
+ "Position": {
+ "X": -51.895935,
+ "Y": -17.97287,
+ "Z": 182.7268
+ },
+ "TerritoryId": 1185,
+ "InteractionType": "Interact",
+ "AetheryteShortcut": "Tuliyollal",
+ "AethernetShortcut": [
+ "[Tuliyollal] Aetheryte Plaza",
+ "[Tuliyollal] The For'ard Cabins"
+ ]
+ }
+ ]
+ },
+ {
+ "Sequence": 5,
+ "Steps": [
+ {
+ "DataId": 1051672,
+ "Position": {
+ "X": -14.816589,
+ "Y": -19.881973,
+ "Z": 223.3158
+ },
+ "TerritoryId": 1185,
+ "InteractionType": "Interact"
+ }
+ ]
+ },
+ {
+ "Sequence": 6,
+ "Steps": [
+ {
+ "DataId": 1051673,
+ "Position": {
+ "X": -15.243774,
+ "Y": -19.762682,
+ "Z": 221.72876
+ },
+ "StopDistance": 5,
+ "TerritoryId": 1185,
+ "InteractionType": "Interact"
+ }
+ ]
+ },
+ {
+ "Sequence": 7,
+ "Steps": [
+ {
+ "DataId": 1051670,
+ "Position": {
+ "X": -15.976257,
+ "Y": -19.928413,
+ "Z": 224.90259
+ },
+ "StopDistance": 5,
+ "TerritoryId": 1185,
+ "InteractionType": "Interact"
+ }
+ ]
+ },
+ {
+ "Sequence": 8,
+ "Steps": [
+ {
+ "DataId": 1051671,
+ "Position": {
+ "X": -17.95996,
+ "Y": -19.784014,
+ "Z": 224.17017
+ },
+ "StopDistance": 5,
+ "TerritoryId": 1185,
+ "InteractionType": "Interact"
+ }
+ ]
+ },
+ {
+ "Sequence": 9,
+ "Steps": [
+ {
+ "DataId": 1051674,
+ "Position": {
+ "X": -16.617126,
+ "Y": -19.752277,
+ "Z": 222.64429
+ },
+ "TerritoryId": 1185,
+ "InteractionType": "Interact"
+ }
+ ]
+ },
+ {
+ "Sequence": 255,
+ "Steps": [
+ {
+ "Position": {
+ "X": -44.643284,
+ "Y": -17.972864,
+ "Z": 203.87883
+ },
+ "TerritoryId": 1185,
+ "InteractionType": "WalkTo"
+ },
+ {
+ "DataId": 1046521,
+ "Position": {
+ "X": -46.616333,
+ "Y": -17.97287,
+ "Z": 180.3158
+ },
+ "StopDistance": 5,
+ "TerritoryId": 1185,
+ "InteractionType": "CompleteQuest",
+ "DisableNavmesh": true
+ }
+ ]
+ }
+ ]
+}
diff --git a/QuestPaths/quest-v1.json b/QuestPaths/quest-v1.json
index f0f82637..0ca8c368 100644
--- a/QuestPaths/quest-v1.json
+++ b/QuestPaths/quest-v1.json
@@ -47,6 +47,10 @@
},
"Comment": {
"type": "string"
+ },
+ "$": {
+ "type": "string",
+ "description": "Dev Comment (not visible in-game)"
}
},
"required": [
@@ -292,6 +296,7 @@
"type": "string",
"enum": [
"WakingSandsMainArea",
+ "WakingSandsSolar",
"RisingStonesSolar",
"RoguesGuild",
"DockStorehouse"
@@ -698,9 +703,7 @@
"const": "UseItem"
},
"ItemId": {
- "not": {
- "const": 30362
- }
+ "minimum": 2000000
}
}
},
@@ -863,7 +866,9 @@
"mogdance",
"salute",
"laugh",
- "greeting"
+ "greeting",
+ "angry",
+ "unbound"
]
}
}
diff --git a/Questionable.Model/Questing/Converter/EmoteConverter.cs b/Questionable.Model/Questing/Converter/EmoteConverter.cs
index bdfe5581..576a77e5 100644
--- a/Questionable.Model/Questing/Converter/EmoteConverter.cs
+++ b/Questionable.Model/Questing/Converter/EmoteConverter.cs
@@ -7,6 +7,7 @@ public sealed class EmoteConverter() : EnumConverter(Values)
{
private static readonly Dictionary Values = new()
{
+ { EEmote.Angry, "angry" },
{ EEmote.Bow, "bow" },
{ EEmote.Cheer, "cheer" },
{ EEmote.Clap, "clap" },
@@ -45,5 +46,6 @@ public sealed class EmoteConverter() : EnumConverter(Values)
{ EEmote.Box, "box" },
{ EEmote.Greeting, "greeting" },
{ EEmote.Uchiwasshoi, "uchiwasshoi" },
+ { EEmote.Unbound, "unbound" },
};
}
diff --git a/Questionable.Model/Questing/Converter/SkipConditionConverter.cs b/Questionable.Model/Questing/Converter/SkipConditionConverter.cs
index 3de919b9..eb917950 100644
--- a/Questionable.Model/Questing/Converter/SkipConditionConverter.cs
+++ b/Questionable.Model/Questing/Converter/SkipConditionConverter.cs
@@ -8,6 +8,7 @@ public sealed class SkipConditionConverter() : EnumConverter Values = new()
{
{ EExtraSkipCondition.WakingSandsMainArea, "WakingSandsMainArea" },
+ { EExtraSkipCondition.WakingSandsSolar, "WakingSandsSolar" },
{ EExtraSkipCondition.RisingStonesSolar, "RisingStonesSolar"},
{ EExtraSkipCondition.RoguesGuild, "RoguesGuild"},
{ EExtraSkipCondition.DockStorehouse, "DockStorehouse"},
diff --git a/Questionable.Model/Questing/EEmote.cs b/Questionable.Model/Questing/EEmote.cs
index 78e7b650..7855bd15 100644
--- a/Questionable.Model/Questing/EEmote.cs
+++ b/Questionable.Model/Questing/EEmote.cs
@@ -8,6 +8,7 @@ public enum EEmote
{
None = 0,
+ Angry = 2,
Bow = 5,
Cheer = 6,
Clap = 7,
@@ -45,6 +46,7 @@ public enum EEmote
Respect = 140,
Box = 166,
Greeting = 172,
- Uchiwasshoi = 278
+ Uchiwasshoi = 278,
+ Unbound = 282,
}
diff --git a/Questionable.Model/Questing/EExtraSkipCondition.cs b/Questionable.Model/Questing/EExtraSkipCondition.cs
index d9d7b0be..8ec77d49 100644
--- a/Questionable.Model/Questing/EExtraSkipCondition.cs
+++ b/Questionable.Model/Questing/EExtraSkipCondition.cs
@@ -8,6 +8,7 @@ public enum EExtraSkipCondition
{
None,
WakingSandsMainArea,
+ WakingSandsSolar,
RisingStonesSolar,
///
diff --git a/Questionable/Controller/GameUi/HelpUiController.cs b/Questionable/Controller/GameUi/HelpUiController.cs
index 0d869add..504f8cd0 100644
--- a/Questionable/Controller/GameUi/HelpUiController.cs
+++ b/Questionable/Controller/GameUi/HelpUiController.cs
@@ -3,6 +3,7 @@ using Dalamud.Game.Addon.Lifecycle;
using Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Component.GUI;
+using LLib.GameUI;
using Microsoft.Extensions.Logging;
namespace Questionable.Controller.GameUi;
@@ -11,17 +12,45 @@ internal sealed class HelpUiController : IDisposable
{
private readonly QuestController _questController;
private readonly IAddonLifecycle _addonLifecycle;
+ private readonly IGameGui _gameGui;
private readonly ILogger _logger;
- public HelpUiController(QuestController questController, IAddonLifecycle addonLifecycle, ILogger logger)
+ public HelpUiController(
+ QuestController questController,
+ IAddonLifecycle addonLifecycle,
+ IGameGui gameGui,
+ ILogger logger)
{
_questController = questController;
_addonLifecycle = addonLifecycle;
+ _gameGui = gameGui;
_logger = logger;
+ _questController.AutomationTypeChanged += CloseHelpWindowsWhenStartingQuests;
+
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "AkatsukiNote", UnendingCodexPostSetup);
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "ContentsTutorial", ContentsTutorialPostSetup);
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "MultipleHelpWindow", MultipleHelpWindowPostSetup);
+ _addonLifecycle.RegisterListener(AddonEvent.PostSetup, "JobHudNotice", JobHudNoticePostSetup);
+ _addonLifecycle.RegisterListener(AddonEvent.PostSetup, "Guide", GuidePostSetup);
+ }
+
+ private unsafe void CloseHelpWindowsWhenStartingQuests(object sender, QuestController.EAutomationType e)
+ {
+ if (e is QuestController.EAutomationType.Manual)
+ return;
+
+ if (_gameGui.TryGetAddonByName("Guide", out AtkUnitBase* addonGuide))
+ {
+ _logger.LogInformation("Guide window is open");
+ GuidePostSetup(addonGuide);
+ }
+
+ if (_gameGui.TryGetAddonByName("JobHudNotice", out AtkUnitBase* addonJobHudNotice))
+ {
+ _logger.LogInformation("JobHudNotice window is open");
+ JobHudNoticePostSetup(addonJobHudNotice);
+ }
}
private unsafe void UnendingCodexPostSetup(AddonEvent type, AddonArgs args)
@@ -36,7 +65,7 @@ internal sealed class HelpUiController : IDisposable
private unsafe void ContentsTutorialPostSetup(AddonEvent type, AddonArgs args)
{
- if (_questController.StartedQuest?.Quest.Id.Value == 245)
+ if (_questController.StartedQuest?.Quest.Id.Value is 245 or 3872)
{
_logger.LogInformation("Closing ContentsTutorial");
AtkUnitBase* addon = (AtkUnitBase*)args.Addon;
@@ -58,10 +87,38 @@ internal sealed class HelpUiController : IDisposable
}
}
+ private unsafe void JobHudNoticePostSetup(AddonEvent type, AddonArgs args)
+ {
+ if (_questController.IsRunning || _questController.AutomationType != QuestController.EAutomationType.Manual)
+ JobHudNoticePostSetup((AtkUnitBase*)args.Addon);
+ }
+
+ private unsafe void JobHudNoticePostSetup(AtkUnitBase* addon)
+ {
+ _logger.LogInformation("Clicking the JobHudNotice window to open the relevant Guide page");
+ addon->FireCallbackInt(0);
+ }
+
+ private unsafe void GuidePostSetup(AddonEvent type, AddonArgs args)
+ {
+ if (_questController.IsRunning || _questController.AutomationType != QuestController.EAutomationType.Manual)
+ GuidePostSetup((AtkUnitBase*)args.Addon);
+ }
+
+ private unsafe void GuidePostSetup(AtkUnitBase* addon)
+ {
+ _logger.LogInformation("Closing Guide window");
+ addon->FireCallbackInt(-1);
+ }
+
public void Dispose()
{
+ _addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "Guide", GuidePostSetup);
+ _addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "JobHudNotice", JobHudNoticePostSetup);
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "MultipleHelpWindow", MultipleHelpWindowPostSetup);
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "ContentsTutorial", ContentsTutorialPostSetup);
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "AkatsukiNote", UnendingCodexPostSetup);
+
+ _questController.AutomationTypeChanged -= CloseHelpWindowsWhenStartingQuests;
}
}
diff --git a/Questionable/Controller/InterruptHandler.cs b/Questionable/Controller/InterruptHandler.cs
index 9171432f..49b24abc 100644
--- a/Questionable/Controller/InterruptHandler.cs
+++ b/Questionable/Controller/InterruptHandler.cs
@@ -94,7 +94,6 @@ internal sealed unsafe class InterruptHandler : IDisposable
[FieldOffset(6)] public ushort Value;
public byte AttackType => (byte)(Param1 & 0xF);
- public uint Damage => Mult == 0 ? Value : Value + ((uint)ushort.MaxValue + 1) * Mult;
public override string ToString()
{
diff --git a/Questionable/Controller/MiniTaskController.cs b/Questionable/Controller/MiniTaskController.cs
index c9aec197..4099a17d 100644
--- a/Questionable/Controller/MiniTaskController.cs
+++ b/Questionable/Controller/MiniTaskController.cs
@@ -28,6 +28,7 @@ internal abstract class MiniTaskController : IDisposable
private readonly ILogger _logger;
private readonly string _actionCanceledText;
+ private readonly string _cantExecuteDueToStatusText;
protected MiniTaskController(IChatGui chatGui, ICondition condition, IServiceProvider serviceProvider,
InterruptHandler interruptHandler, IDataManager dataManager, ILogger logger)
@@ -39,6 +40,7 @@ internal abstract class MiniTaskController : IDisposable
_condition = condition;
_actionCanceledText = dataManager.GetString(1314, x => x.Text)!;
+ _cantExecuteDueToStatusText = dataManager.GetString(7728, x => x.Text)!;
_interruptHandler.Interrupted += HandleInterruption;
}
@@ -68,7 +70,7 @@ internal abstract class MiniTaskController : IDisposable
{
_logger.LogError(e, "Failed to start task {TaskName}", upcomingTask.ToString());
_chatGui.PrintError(
- $"[Questionable] Failed to start task '{upcomingTask}', please check /xllog for details.");
+ $"Failed to start task '{upcomingTask}', please check /xllog for details.", CommandHandler.MessageTag, CommandHandler.TagColor);
Stop("Task failed to start");
return;
}
@@ -93,7 +95,7 @@ internal abstract class MiniTaskController : IDisposable
_logger.LogError(e, "Failed to update task {TaskName}",
_taskQueue.CurrentTaskExecutor.CurrentTask.ToString());
_chatGui.PrintError(
- $"[Questionable] Failed to update task '{_taskQueue.CurrentTaskExecutor.CurrentTask}', please check /xllog for details.");
+ $"Failed to update task '{_taskQueue.CurrentTaskExecutor.CurrentTask}', please check /xllog for details.", CommandHandler.MessageTag, CommandHandler.TagColor);
Stop("Task failed to update");
return;
}
@@ -183,6 +185,19 @@ internal abstract class MiniTaskController : IDisposable
else
_taskQueue.InterruptWith([new WaitAtEnd.WaitDelay()]);
+ LogTasksAfterInterruption();
+ }
+
+ private void InterruptWithoutCombat()
+ {
+ _logger.LogWarning("Interrupted, attempting to redo previous tasks (not in combat)");
+ _taskQueue.InterruptWith([new WaitAtEnd.WaitDelay()]);
+
+ LogTasksAfterInterruption();
+ }
+
+ private void LogTasksAfterInterruption()
+ {
_logger.LogInformation("Remaining tasks after interruption:");
foreach (ITask task in _taskQueue.RemainingTasks)
_logger.LogInformation("- {TaskName}", task);
@@ -204,6 +219,8 @@ internal abstract class MiniTaskController : IDisposable
!_condition[ConditionFlag.InFlight] &&
_taskQueue.CurrentTaskExecutor?.ShouldInterruptOnDamage() == true)
InterruptQueueWithCombat();
+ else if (GameFunctions.GameStringEquals(_cantExecuteDueToStatusText, message.TextValue))
+ InterruptWithoutCombat();
}
}
diff --git a/Questionable/Controller/QuestController.cs b/Questionable/Controller/QuestController.cs
index d514f267..def1c297 100644
--- a/Questionable/Controller/QuestController.cs
+++ b/Questionable/Controller/QuestController.cs
@@ -19,7 +19,7 @@ using Quest = Questionable.Model.Quest;
namespace Questionable.Controller;
-internal sealed class QuestController : MiniTaskController, IDisposable
+internal sealed class QuestController : MiniTaskController
{
private readonly IClientState _clientState;
private readonly GameFunctions _gameFunctions;
@@ -111,9 +111,13 @@ internal sealed class QuestController : MiniTaskController, IDi
_logger.LogInformation("Setting automation type to {NewAutomationType} (previous: {OldAutomationType})",
value, _automationType);
_automationType = value;
+ AutomationTypeChanged?.Invoke(this, value);
}
}
+ public delegate void AutomationTypeChangedEventHandler(object sender, EAutomationType e);
+ public event AutomationTypeChangedEventHandler? AutomationTypeChanged;
+
public (QuestProgress Progress, ECurrentQuestType Type)? CurrentQuestDetails
{
get
@@ -623,7 +627,7 @@ internal sealed class QuestController : MiniTaskController, IDi
catch (Exception e)
{
_logger.LogError(e, "Failed to create tasks");
- _chatGui.PrintError("[Questionable] Failed to start next task sequence, please check /xllog for details.");
+ _chatGui.PrintError("Failed to start next task sequence, please check /xllog for details.", CommandHandler.MessageTag, CommandHandler.TagColor);
Stop("Tasks failed to create");
}
}
diff --git a/Questionable/Controller/Steps/Interactions/AetherCurrent.cs b/Questionable/Controller/Steps/Interactions/AetherCurrent.cs
index 7632e574..7c1f6338 100644
--- a/Questionable/Controller/Steps/Interactions/AetherCurrent.cs
+++ b/Questionable/Controller/Steps/Interactions/AetherCurrent.cs
@@ -26,7 +26,8 @@ internal static class AetherCurrent
if (!aetherCurrentData.IsValidAetherCurrent(step.TerritoryId, step.AetherCurrentId.Value))
{
chatGui.PrintError(
- $"[Questionable] Aether current with id {step.AetherCurrentId} is referencing an invalid aether current, will skip attunement");
+ $"Aether current with id {step.AetherCurrentId} is referencing an invalid aether current, will skip attunement",
+ CommandHandler.MessageTag, CommandHandler.TagColor);
return null;
}
diff --git a/Questionable/Controller/Steps/Interactions/EquipRecommended.cs b/Questionable/Controller/Steps/Interactions/EquipRecommended.cs
index 295bb8cc..a71cc3b0 100644
--- a/Questionable/Controller/Steps/Interactions/EquipRecommended.cs
+++ b/Questionable/Controller/Steps/Interactions/EquipRecommended.cs
@@ -40,9 +40,11 @@ internal static class EquipRecommended
public override string ToString() => "EquipRecommended";
}
- internal sealed unsafe class DoEquipRecommended(IClientState clientState, IChatGui chatGui, ICondition condition) : TaskExecutor
+ internal sealed unsafe class DoEquipRecommended(IClientState clientState, IChatGui chatGui, ICondition condition)
+ : TaskExecutor
{
- private bool _equipped;
+ private bool _checkedOrTriggeredEquipmentUpdate;
+ private DateTime _continueAt = DateTime.MinValue;
protected override bool Start()
{
@@ -59,44 +61,51 @@ internal static class EquipRecommended
if (recommendedEquipModule->IsUpdating)
return ETaskResult.StillRunning;
- if (!_equipped)
+ if (!_checkedOrTriggeredEquipmentUpdate)
{
- InventoryManager* inventoryManager = InventoryManager.Instance();
- InventoryContainer* equippedItems =
- inventoryManager->GetInventoryContainer(InventoryType.EquippedItems);
- bool isAllEquipped = true;
- foreach (var recommendedItemPtr in recommendedEquipModule->RecommendedItems)
+ if (!IsAllRecommendeGearEquipped())
{
- var recommendedItem = recommendedItemPtr.Value;
- if (recommendedItem == null || recommendedItem->ItemId == 0)
- continue;
-
- bool isEquipped = false;
- for (int i = 0; i < equippedItems->Size; ++i)
- {
- var equippedItem = equippedItems->Items[i];
- if (equippedItem.ItemId != 0 && equippedItem.ItemId == recommendedItem->ItemId)
- {
- isEquipped = true;
- break;
- }
- }
-
- if (!isEquipped)
- isAllEquipped = false;
- }
-
- if (!isAllEquipped)
- {
- chatGui.Print("Equipping recommended gear.", "Questionable");
+ chatGui.Print("Equipping recommended gear.", CommandHandler.MessageTag, CommandHandler.TagColor);
recommendedEquipModule->EquipRecommendedGear();
+ _continueAt = DateTime.Now.AddSeconds(1);
}
- _equipped = true;
+ _checkedOrTriggeredEquipmentUpdate = true;
return ETaskResult.StillRunning;
}
- return ETaskResult.TaskComplete;
+ return DateTime.Now >= _continueAt ? ETaskResult.TaskComplete : ETaskResult.StillRunning;
+ }
+
+ private bool IsAllRecommendeGearEquipped()
+ {
+ var recommendedEquipModule = RecommendEquipModule.Instance();
+ InventoryManager* inventoryManager = InventoryManager.Instance();
+ InventoryContainer* equippedItems =
+ inventoryManager->GetInventoryContainer(InventoryType.EquippedItems);
+ bool isAllEquipped = true;
+ foreach (var recommendedItemPtr in recommendedEquipModule->RecommendedItems)
+ {
+ var recommendedItem = recommendedItemPtr.Value;
+ if (recommendedItem == null || recommendedItem->ItemId == 0)
+ continue;
+
+ bool isEquipped = false;
+ for (int i = 0; i < equippedItems->Size; ++i)
+ {
+ var equippedItem = equippedItems->Items[i];
+ if (equippedItem.ItemId != 0 && equippedItem.ItemId == recommendedItem->ItemId)
+ {
+ isEquipped = true;
+ break;
+ }
+ }
+
+ if (!isEquipped)
+ isAllEquipped = false;
+ }
+
+ return isAllEquipped;
}
public override bool ShouldInterruptOnDamage() => true;
diff --git a/Questionable/Controller/Steps/Shared/AetheryteShortcut.cs b/Questionable/Controller/Steps/Shared/AetheryteShortcut.cs
index b2748b18..4a56e929 100644
--- a/Questionable/Controller/Steps/Shared/AetheryteShortcut.cs
+++ b/Questionable/Controller/Steps/Shared/AetheryteShortcut.cs
@@ -201,7 +201,7 @@ internal static class AetheryteShortcut
if (!aetheryteFunctions.IsAetheryteUnlocked(Task.TargetAetheryte))
{
- chatGui.PrintError($"[Questionable] Aetheryte {Task.TargetAetheryte} is not unlocked.");
+ chatGui.PrintError($"Aetheryte {Task.TargetAetheryte} is not unlocked.", CommandHandler.MessageTag, CommandHandler.TagColor);
throw new TaskException("Aetheryte is not unlocked");
}
@@ -215,7 +215,7 @@ internal static class AetheryteShortcut
}
else
{
- chatGui.Print("[Questionable] Unable to teleport to aetheryte.");
+ chatGui.Print("Unable to teleport to aetheryte.", CommandHandler.MessageTag, CommandHandler.TagColor);
throw new TaskException("Unable to teleport to aetheryte");
}
}
diff --git a/Questionable/Controller/Steps/Shared/SkipCondition.cs b/Questionable/Controller/Steps/Shared/SkipCondition.cs
index ebf1dc1f..bd953539 100644
--- a/Questionable/Controller/Steps/Shared/SkipCondition.cs
+++ b/Questionable/Controller/Steps/Shared/SkipCondition.cs
@@ -307,6 +307,7 @@ internal static class SkipCondition
return condition switch
{
EExtraSkipCondition.WakingSandsMainArea => territoryType == 212 && position.X < 24,
+ EExtraSkipCondition.WakingSandsSolar => territoryType == 212 && position.X >= 24,
EExtraSkipCondition.RisingStonesSolar => territoryType == 351 && position.Z <= -28,
EExtraSkipCondition.RoguesGuild => territoryType == 129 && position.Y <= -115,
EExtraSkipCondition.DockStorehouse => territoryType == 137 && position.Y <= -20,
diff --git a/Questionable/Data/QuestData.cs b/Questionable/Data/QuestData.cs
index 65225863..f84edb95 100644
--- a/Questionable/Data/QuestData.cs
+++ b/Questionable/Data/QuestData.cs
@@ -189,6 +189,12 @@ internal sealed class QuestData
AddPreviousQuest(new QuestId(3833), new QuestId(spearfishing));
*/
+ // Shadow Walk with Me
+ AddPreviousQuest(new QuestId(3629), new QuestId(3248));
+ AddPreviousQuest(new QuestId(3629), new QuestId(3272));
+ AddPreviousQuest(new QuestId(3629), new QuestId(3278));
+ AddPreviousQuest(new QuestId(3629), new QuestId(3628));
+
// The Hero's Journey
AddPreviousQuest(new QuestId(3986), new QuestId(2115));
AddPreviousQuest(new QuestId(3986), new QuestId(2116));
@@ -197,6 +203,11 @@ internal sealed class QuestData
AddPreviousQuest(new QuestId(3986), new QuestId(2395));
AddPreviousQuest(new QuestId(3986), new QuestId(3985));
+ // Picking up the Torch has half the quests in the sheets(??)
+ AddPreviousQuest(new QuestId(5188), new QuestId(4841));
+ AddPreviousQuest(new QuestId(5188), new QuestId(4847));
+ AddPreviousQuest(new QuestId(5188), new QuestId(4959));
+
// initial city quests are side quests
// unclear if 470 can be started as the required quest isn't available anymore
ushort[] limsaSideQuests =