Allow for more complex gathering (preparation) steps; add firmament aetheryte

This commit is contained in:
Liza 2024-08-16 01:21:15 +02:00
parent 2955cff165
commit f1165a3937
Signed by: liza
GPG Key ID: 7199F8D727D55F67
100 changed files with 1907 additions and 1339 deletions

View File

@ -15,6 +15,7 @@ using Dalamud.Plugin.Services;
using Lumina.Excel.GeneratedSheets;
using Questionable.Model;
using Questionable.Model.Gathering;
using Questionable.Model.Questing;
namespace GatheringPathRenderer;
@ -186,7 +187,14 @@ internal sealed class EditorCommands : IDisposable
var root = new GatheringRoot
{
Author = [_configuration.AuthorName],
TerritoryId = _clientState.TerritoryType,
Steps =
[
new QuestStep
{
TerritoryId = _clientState.TerritoryType,
InteractionType = EInteractionType.None,
}
],
Groups =
[
new GatheringNodeGroup

View File

@ -146,7 +146,7 @@ public sealed class RendererPlugin : IDalamudPlugin
}
internal IEnumerable<GatheringLocationContext> GetLocationsInTerritory(ushort territoryId)
=> _gatheringLocations.Where(x => x.Root.TerritoryId == territoryId);
=> _gatheringLocations.Where(x => x.Root.Steps.LastOrDefault()?.TerritoryId == territoryId);
internal void Save(FileInfo targetFile, GatheringRoot root)
{

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 141,
"AetheryteShortcut": "Central Thanalan - Black Brush Station",
"Steps": [
{
"TerritoryId": 141,
"InteractionType": "None",
"AetheryteShortcut": "Central Thanalan - Black Brush Station"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 140,
"AetheryteShortcut": "Western Thanalan - Horizon",
"Steps": [
{
"TerritoryId": 140,
"InteractionType": "None",
"AetheryteShortcut": "Western Thanalan - Horizon"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 397,
"AetheryteShortcut": "Coerthas Western Highlands - Falcon's Nest",
"Steps": [
{
"TerritoryId": 397,
"InteractionType": "None",
"AetheryteShortcut": "Coerthas Western Highlands - Falcon's Nest"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 397,
"AetheryteShortcut": "Coerthas Western Highlands - Falcon's Nest",
"Steps": [
{
"TerritoryId": 397,
"InteractionType": "None",
"AetheryteShortcut": "Coerthas Western Highlands - Falcon's Nest"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 397,
"AetheryteShortcut": "Coerthas Western Highlands - Falcon's Nest",
"Steps": [
{
"TerritoryId": 397,
"InteractionType": "None",
"AetheryteShortcut": "Coerthas Western Highlands - Falcon's Nest"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 397,
"AetheryteShortcut": "Coerthas Western Highlands - Falcon's Nest",
"Steps": [
{
"TerritoryId": 397,
"InteractionType": "None",
"AetheryteShortcut": "Coerthas Western Highlands - Falcon's Nest"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 400,
"AetheryteShortcut": "The Churning Mists - Moghome",
"Steps": [
{
"TerritoryId": 400,
"InteractionType": "None",
"AetheryteShortcut": "The Churning Mists - Moghome"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 400,
"AetheryteShortcut": "The Churning Mists - Zenith",
"Steps": [
{
"TerritoryId": 400,
"InteractionType": "None",
"AetheryteShortcut": "The Churning Mists - Zenith"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 400,
"AetheryteShortcut": "The Churning Mists - Moghome",
"Steps": [
{
"TerritoryId": 400,
"InteractionType": "None",
"AetheryteShortcut": "The Churning Mists - Moghome"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 400,
"AetheryteShortcut": "The Churning Mists - Zenith",
"Steps": [
{
"TerritoryId": 400,
"InteractionType": "None",
"AetheryteShortcut": "The Churning Mists - Zenith"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 398,
"AetheryteShortcut": "The Dravanian Forelands - Anyx Trine",
"Steps": [
{
"TerritoryId": 398,
"InteractionType": "None",
"AetheryteShortcut": "The Dravanian Forelands - Anyx Trine"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 398,
"AetheryteShortcut": "The Dravanian Forelands - Anyx Trine",
"Steps": [
{
"TerritoryId": 398,
"InteractionType": "None",
"AetheryteShortcut": "The Dravanian Forelands - Anyx Trine"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,11 +1,16 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 399,
"AetheryteShortcut": "Idyllshire",
"AethernetShortcut": [
"[Idyllshire] Aetheryte Plaza",
"[Idyllshire] Epilogue Gate (Eastern Hinterlands)"
"Steps": [
{
"TerritoryId": 399,
"InteractionType": "None",
"AetheryteShortcut": "Idyllshire",
"AethernetShortcut": [
"[Idyllshire] Aetheryte Plaza",
"[Idyllshire] Epilogue Gate (Eastern Hinterlands)"
]
}
],
"Groups": [
{

View File

@ -1,11 +1,16 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 399,
"AetheryteShortcut": "Idyllshire",
"AethernetShortcut": [
"[Idyllshire] Aetheryte Plaza",
"[Idyllshire] Prologue Gate (Western Hinterlands)"
"Steps": [
{
"TerritoryId": 399,
"InteractionType": "None",
"AetheryteShortcut": "Idyllshire",
"AethernetShortcut": [
"[Idyllshire] Aetheryte Plaza",
"[Idyllshire] Prologue Gate (Western Hinterlands)"
]
}
],
"Groups": [
{

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 401,
"AetheryteShortcut": "The Sea of Clouds - Camp Cloudtop",
"Steps": [
{
"TerritoryId": 401,
"InteractionType": "None",
"AetheryteShortcut": "The Sea of Clouds - Camp Cloudtop"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 401,
"AetheryteShortcut": "The Sea of Clouds - Ok' Zundu",
"Steps": [
{
"TerritoryId": 401,
"InteractionType": "None",
"AetheryteShortcut": "The Sea of Clouds - Ok' Zundu"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 622,
"AetheryteShortcut": "Azim Steppe - Dawn Throne",
"Steps": [
{
"TerritoryId": 622,
"InteractionType": "None",
"AetheryteShortcut": "Azim Steppe - Dawn Throne"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 622,
"AetheryteShortcut": "Azim Steppe - Dawn Throne",
"Steps": [
{
"TerritoryId": 622,
"InteractionType": "None",
"AetheryteShortcut": "Azim Steppe - Dawn Throne"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 622,
"AetheryteShortcut": "Azim Steppe - Dawn Throne",
"Steps": [
{
"TerritoryId": 622,
"InteractionType": "None",
"AetheryteShortcut": "Azim Steppe - Dawn Throne"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 612,
"AetheryteShortcut": "Fringes - Castrum Oriens",
"Steps": [
{
"TerritoryId": 612,
"InteractionType": "None",
"AetheryteShortcut": "Fringes - Castrum Oriens"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 612,
"AetheryteShortcut": "Fringes - Castrum Oriens",
"Steps": [
{
"TerritoryId": 612,
"InteractionType": "None",
"AetheryteShortcut": "Fringes - Castrum Oriens"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 612,
"AetheryteShortcut": "Fringes - Castrum Oriens",
"Steps": [
{
"TerritoryId": 612,
"InteractionType": "None",
"AetheryteShortcut": "Fringes - Castrum Oriens"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 612,
"AetheryteShortcut": "Fringes - Castrum Oriens",
"Steps": [
{
"TerritoryId": 612,
"InteractionType": "None",
"AetheryteShortcut": "Fringes - Castrum Oriens"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 612,
"AetheryteShortcut": "Fringes - Castrum Oriens",
"Steps": [
{
"TerritoryId": 612,
"InteractionType": "None",
"AetheryteShortcut": "Fringes - Castrum Oriens"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 621,
"AetheryteShortcut": "Lochs - Porta Praetoria",
"Steps": [
{
"TerritoryId": 621,
"InteractionType": "None",
"AetheryteShortcut": "Lochs - Porta Praetoria"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 621,
"AetheryteShortcut": "Lochs - Ala Mhigan Quarter",
"Steps": [
{
"TerritoryId": 621,
"InteractionType": "None",
"AetheryteShortcut": "Lochs - Ala Mhigan Quarter"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 621,
"AetheryteShortcut": "Lochs - Porta Praetoria",
"Steps": [
{
"TerritoryId": 621,
"InteractionType": "None",
"AetheryteShortcut": "Lochs - Porta Praetoria"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 620,
"AetheryteShortcut": "Peaks - Ala Gannha",
"Steps": [
{
"TerritoryId": 620,
"InteractionType": "None",
"AetheryteShortcut": "Peaks - Ala Gannha"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 620,
"AetheryteShortcut": "Peaks - Ala Gannha",
"Steps": [
{
"TerritoryId": 620,
"InteractionType": "None",
"AetheryteShortcut": "Peaks - Ala Gannha"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 620,
"AetheryteShortcut": "Peaks - Ala Gannha",
"Steps": [
{
"TerritoryId": 620,
"InteractionType": "None",
"AetheryteShortcut": "Peaks - Ala Gannha"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 620,
"AetheryteShortcut": "Peaks - Ala Gannha",
"Steps": [
{
"TerritoryId": 620,
"InteractionType": "None",
"AetheryteShortcut": "Peaks - Ala Gannha"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,11 +1,16 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 613,
"AetheryteShortcut": "Kugane",
"AethernetShortcut": [
"[Kugane] Aetheryte Plaza",
"[Kugane] The Ruby Price"
"Steps": [
{
"TerritoryId": 613,
"InteractionType": "None",
"AetheryteShortcut": "Kugane",
"AethernetShortcut": [
"[Kugane] Aetheryte Plaza",
"[Kugane] The Ruby Price"
]
}
],
"Groups": [
{

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 613,
"AetheryteShortcut": "Ruby Sea - Onokoro",
"Steps": [
{
"TerritoryId": 613,
"InteractionType": "None",
"AetheryteShortcut": "Ruby Sea - Onokoro"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 613,
"AetheryteShortcut": "Ruby Sea - Onokoro",
"Steps": [
{
"TerritoryId": 613,
"InteractionType": "None",
"AetheryteShortcut": "Ruby Sea - Onokoro"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 613,
"AetheryteShortcut": "Ruby Sea - Tamamizu",
"Steps": [
{
"TerritoryId": 613,
"InteractionType": "None",
"AetheryteShortcut": "Ruby Sea - Tamamizu"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 613,
"AetheryteShortcut": "Ruby Sea - Onokoro",
"Steps": [
{
"TerritoryId": 613,
"InteractionType": "None",
"AetheryteShortcut": "Ruby Sea - Onokoro"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,11 +1,16 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 613,
"AetheryteShortcut": "Kugane",
"AethernetShortcut": [
"[Kugane] Aetheryte Plaza",
"[Kugane] The Ruby Price"
"Steps": [
{
"TerritoryId": 613,
"InteractionType": "None",
"AetheryteShortcut": "Kugane",
"AethernetShortcut": [
"[Kugane] Aetheryte Plaza",
"[Kugane] The Ruby Price"
]
}
],
"FlyBetweenNodes": true,
"Groups": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 613,
"AetheryteShortcut": "Ruby Sea - Tamamizu",
"Steps": [
{
"TerritoryId": 613,
"InteractionType": "None",
"AetheryteShortcut": "Ruby Sea - Tamamizu"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 614,
"AetheryteShortcut": "Yanxia - Namai",
"Steps": [
{
"TerritoryId": 614,
"InteractionType": "None",
"AetheryteShortcut": "Yanxia - Namai"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 614,
"AetheryteShortcut": "Yanxia - Namai",
"Steps": [
{
"TerritoryId": 614,
"InteractionType": "None",
"AetheryteShortcut": "Yanxia - Namai"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 614,
"AetheryteShortcut": "Yanxia - Namai",
"Steps": [
{
"TerritoryId": 614,
"InteractionType": "None",
"AetheryteShortcut": "Yanxia - Namai"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 614,
"AetheryteShortcut": "Yanxia - Namai",
"Steps": [
{
"TerritoryId": 614,
"InteractionType": "None",
"AetheryteShortcut": "Yanxia - Namai"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 814,
"AetheryteShortcut": "Kholusia - Wright",
"Steps": [
{
"TerritoryId": 814,
"InteractionType": "None",
"AetheryteShortcut": "Kholusia - Wright"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 814,
"AetheryteShortcut": "Kholusia - Wright",
"Steps": [
{
"TerritoryId": 814,
"InteractionType": "None",
"AetheryteShortcut": "Kholusia - Wright"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,7 +1,12 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 817,
"Steps": [
{
"TerritoryId": 817,
"InteractionType": "None"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,7 +1,12 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 817,
"Steps": [
{
"TerritoryId": 817,
"InteractionType": "None"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 961,
"AetheryteShortcut": "Elpis - Poieten Oikos",
"Steps": [
{
"TerritoryId": 961,
"InteractionType": "None",
"AetheryteShortcut": "Elpis - Poieten Oikos"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 961,
"AetheryteShortcut": "Elpis - Anagnorisis",
"Steps": [
{
"TerritoryId": 961,
"InteractionType": "None",
"AetheryteShortcut": "Elpis - Anagnorisis"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,7 +1,12 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1073,
"Steps": [
{
"TerritoryId": 1073,
"InteractionType": "None"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,7 +1,12 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1073,
"Steps": [
{
"TerritoryId": 1073,
"InteractionType": "None"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,7 +1,12 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1073,
"Steps": [
{
"TerritoryId": 1073,
"InteractionType": "None"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,7 +1,12 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1073,
"Steps": [
{
"TerritoryId": 1073,
"InteractionType": "None"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,7 +1,12 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1073,
"Steps": [
{
"TerritoryId": 1073,
"InteractionType": "None"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,7 +1,12 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1073,
"Steps": [
{
"TerritoryId": 1073,
"InteractionType": "None"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,7 +1,12 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1073,
"Steps": [
{
"TerritoryId": 1073,
"InteractionType": "None"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,7 +1,12 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1073,
"Steps": [
{
"TerritoryId": 1073,
"InteractionType": "None"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 958,
"AetheryteShortcut": "Garlemald - Camp Broken Glass",
"Steps": [
{
"TerritoryId": 958,
"InteractionType": "None",
"AetheryteShortcut": "Garlemald - Camp Broken Glass"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 958,
"AetheryteShortcut": "Garlemald - Camp Broken Glass",
"Steps": [
{
"TerritoryId": 958,
"InteractionType": "None",
"AetheryteShortcut": "Garlemald - Camp Broken Glass"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 956,
"AetheryteShortcut": "Labyrinthos - Archeion",
"Steps": [
{
"TerritoryId": 956,
"InteractionType": "None",
"AetheryteShortcut": "Labyrinthos - Archeion"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 956,
"AetheryteShortcut": "Labyrinthos - Archeion",
"Steps": [
{
"TerritoryId": 956,
"InteractionType": "None",
"AetheryteShortcut": "Labyrinthos - Archeion"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 959,
"AetheryteShortcut": "Mare Lamentorum - Sinus Lacrimarum",
"Steps": [
{
"TerritoryId": 959,
"InteractionType": "None",
"AetheryteShortcut": "Mare Lamentorum - Sinus Lacrimarum"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 959,
"AetheryteShortcut": "Mare Lamentorum - Bestways Burrow",
"Steps": [
{
"TerritoryId": 959,
"InteractionType": "None",
"AetheryteShortcut": "Mare Lamentorum - Bestways Burrow"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 957,
"AetheryteShortcut": "Thavnair - Great Work",
"Steps": [
{
"TerritoryId": 957,
"InteractionType": "None",
"AetheryteShortcut": "Thavnair - Great Work"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 957,
"AetheryteShortcut": "Thavnair - Great Work",
"Steps": [
{
"TerritoryId": 957,
"InteractionType": "None",
"AetheryteShortcut": "Thavnair - Great Work"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1188,
"AetheryteShortcut": "Kozama'uka - Ok'hanu",
"Steps": [
{
"TerritoryId": 1188,
"InteractionType": "None",
"AetheryteShortcut": "Kozama'uka - Ok'hanu"
}
],
"FlyBetweenNodes": true,
"Groups": [
{

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1188,
"AetheryteShortcut": "Kozama'uka - Ok'hanu",
"Steps": [
{
"TerritoryId": 1188,
"InteractionType": "None",
"AetheryteShortcut": "Kozama'uka - Ok'hanu"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1188,
"AetheryteShortcut": "Kozama'uka - Ok'hanu",
"Steps": [
{
"TerritoryId": 1188,
"InteractionType": "None",
"AetheryteShortcut": "Kozama'uka - Ok'hanu"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1190,
"AetheryteShortcut": "Shaaloani - Mehwahhetsoan",
"Steps": [
{
"TerritoryId": 1190,
"InteractionType": "None",
"AetheryteShortcut": "Shaaloani - Mehwahhetsoan"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1190,
"AetheryteShortcut": "Shaaloani - Hhusatahwi",
"Steps": [
{
"TerritoryId": 1190,
"InteractionType": "None",
"AetheryteShortcut": "Shaaloani - Hhusatahwi"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1187,
"AetheryteShortcut": "Urqopacha - Wachunpelo",
"Steps": [
{
"TerritoryId": 1187,
"InteractionType": "None",
"AetheryteShortcut": "Urqopacha - Wachunpelo"
}
],
"FlyBetweenNodes": false,
"Groups": [
{

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1187,
"AetheryteShortcut": "Urqopacha - Wachunpelo",
"Steps": [
{
"TerritoryId": 1187,
"InteractionType": "None",
"AetheryteShortcut": "Urqopacha - Wachunpelo"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1187,
"AetheryteShortcut": "Urqopacha - Worlar's Echo",
"Steps": [
{
"TerritoryId": 1187,
"InteractionType": "None",
"AetheryteShortcut": "Urqopacha - Worlar's Echo"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1187,
"AetheryteShortcut": "Urqopacha - Wachunpelo",
"Steps": [
{
"TerritoryId": 1187,
"InteractionType": "None",
"AetheryteShortcut": "Urqopacha - Wachunpelo"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1187,
"AetheryteShortcut": "Urqopacha - Wachunpelo",
"Steps": [
{
"TerritoryId": 1187,
"InteractionType": "None",
"AetheryteShortcut": "Urqopacha - Wachunpelo"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1187,
"AetheryteShortcut": "Urqopacha - Worlar's Echo",
"Steps": [
{
"TerritoryId": 1187,
"InteractionType": "None",
"AetheryteShortcut": "Urqopacha - Worlar's Echo"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1189,
"AetheryteShortcut": "Yak T'el - Iq Br'aax",
"Steps": [
{
"TerritoryId": 1189,
"InteractionType": "None",
"AetheryteShortcut": "Yak T'el - Iq Br'aax"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1189,
"AetheryteShortcut": "Yak T'el - Iq Br'aax",
"Steps": [
{
"TerritoryId": 1189,
"InteractionType": "None",
"AetheryteShortcut": "Yak T'el - Iq Br'aax"
}
],
"FlyBetweenNodes": true,
"Groups": [
{

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1189,
"AetheryteShortcut": "Yak T'el - Mamook",
"Steps": [
{
"TerritoryId": 1189,
"InteractionType": "None",
"AetheryteShortcut": "Yak T'el - Mamook"
}
],
"Groups": [
{
"Nodes": [

View File

@ -1,8 +1,13 @@
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1189,
"AetheryteShortcut": "Yak T'el - Iq Br'aax",
"Steps": [
{
"TerritoryId": 1189,
"InteractionType": "None",
"AetheryteShortcut": "Yak T'el - Iq Br'aax"
}
],
"Groups": [
{
"Nodes": [

View File

@ -19,20 +19,12 @@
"type": "string"
}
},
"TerritoryId": {
"type": "number"
},
"AetheryteShortcut": {
"$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Aetheryte"
},
"AethernetShortcut": {
"Steps": {
"type": "array",
"description": "A pair of aethernet locations (from + to) to use as a shortcut",
"minItems": 2,
"maxItems": 2,
"items": {
"$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/AethernetShard"
}
"$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json#/$defs/Step"
},
"minItems": 1
},
"FlyBetweenNodes": {
"description": "If nodes are close enough together, flying makes no sense due to the pathfinding overhead",
@ -63,7 +55,7 @@
"type": "object",
"properties": {
"Position": {
"$ref": "#/$defs/Vector3"
"$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Vector3"
},
"MinimumAngle": {
"type": "number",
@ -108,30 +100,8 @@
"required": [
"$schema",
"Author",
"TerritoryId",
"Steps",
"Groups"
],
"additionalProperties": false,
"$defs": {
"Vector3": {
"type": "object",
"description": "Position to (typically) walk to",
"properties": {
"X": {
"type": "number"
},
"Y": {
"type": "number"
},
"Z": {
"type": "number"
}
},
"required": [
"X",
"Y",
"Z"
]
}
}
"additionalProperties": false
}

View File

@ -152,13 +152,7 @@ public class GatheringSourceGenerator : ISourceGenerator
SeparatedList<ExpressionSyntax>(
SyntaxNodeList(
AssignmentList(nameof(GatheringRoot.Author), root.Author).AsSyntaxNodeOrToken(),
Assignment(nameof(GatheringRoot.TerritoryId), root.TerritoryId, emptyRoot.TerritoryId)
.AsSyntaxNodeOrToken(),
Assignment(nameof(GatheringRoot.AetheryteShortcut), root.AetheryteShortcut,
emptyRoot.AetheryteShortcut)
.AsSyntaxNodeOrToken(),
Assignment(nameof(GatheringRoot.AethernetShortcut), root.AethernetShortcut,
emptyRoot.AethernetShortcut)
AssignmentList(nameof(GatheringRoot.Steps), root.Steps)
.AsSyntaxNodeOrToken(),
Assignment(nameof(GatheringRoot.FlyBetweenNodes), root.FlyBetweenNodes,
emptyRoot.FlyBetweenNodes)

View File

@ -5,6 +5,25 @@
{
"Sequence": 0,
"Steps": [
{
"TerritoryId": 886,
"InteractionType": "None",
"AetheryteShortcut": "Ishgard",
"AethernetShortcut": [
"[Ishgard] Aetheryte Plaza",
"[Ishgard] Firmament"
],
"SkipConditions": {
"AetheryteShortcutIf": {
"InTerritory": [
886
]
},
"AethernetShortcutIf": {
"InSameTerritory": true
}
}
},
{
"DataId": 1035211,
"Position": {
@ -14,10 +33,9 @@
},
"TerritoryId": 886,
"InteractionType": "Interact",
"AetheryteShortcut": "Ishgard",
"AethernetShortcut": [
"[Ishgard] Aetheryte Plaza",
"[Ishgard] Firmament"
"[Firmament] The Mendicant's Court",
"[Firmament] Western Risensong Quarter"
],
"DialogueChoices": [
{

View File

@ -5,6 +5,25 @@
{
"Sequence": 0,
"Steps": [
{
"TerritoryId": 886,
"InteractionType": "None",
"AetheryteShortcut": "Ishgard",
"AethernetShortcut": [
"[Ishgard] Aetheryte Plaza",
"[Ishgard] Firmament"
],
"SkipConditions": {
"AetheryteShortcutIf": {
"InTerritory": [
886
]
},
"AethernetShortcutIf": {
"InSameTerritory": true
}
}
},
{
"DataId": 1033543,
"Position": {
@ -14,10 +33,9 @@
},
"TerritoryId": 886,
"InteractionType": "Interact",
"AetheryteShortcut": "Ishgard",
"AethernetShortcut": [
"[Ishgard] Aetheryte Plaza",
"[Ishgard] Firmament"
"[Firmament] The Mendicant's Court",
"[Firmament] The Mattock"
],
"DialogueChoices": [
{

File diff suppressed because it is too large Load Diff

View File

@ -87,6 +87,15 @@ public enum EAetheryteLocation
IshgardGatesOfJudgement = 88,
IshgardFirmament = 100001,
FirmamentMendicantsCourt = 2011373,
FirmamentMattock = 2011374,
FirmamentNewNest = 2011384,
FirmanentSaintRoellesDais = 2011385,
FirmamentFeatherfall = 2011386,
FirmamentHoarfrostHall = 2011387,
FirmamentWesternRisensongQuarter = 2011388,
FIrmamentEasternRisensongQuarter = 2011389,
Idyllshire = 75,
IdyllshireWest = 90,
IdyllshirePrologueGate = 91,
@ -251,3 +260,17 @@ public enum EAetheryteLocation
LivingMemoryLeynodePyro = 214,
LivingMemoryLeynodeAero = 215,
}
public static class EAetheryteLocationExtensions
{
public static bool IsFirmamentAetheryte(this EAetheryteLocation aetheryteLocation) =>
aetheryteLocation is EAetheryteLocation.IshgardFirmament
or EAetheryteLocation.FirmamentMendicantsCourt
or EAetheryteLocation.FirmamentMattock
or EAetheryteLocation.FirmamentNewNest
or EAetheryteLocation.FirmanentSaintRoellesDais
or EAetheryteLocation.FirmamentFeatherfall
or EAetheryteLocation.FirmamentHoarfrostHall
or EAetheryteLocation.FirmamentWesternRisensongQuarter
or EAetheryteLocation.FIrmamentEasternRisensongQuarter;
}

View File

@ -2,6 +2,7 @@
using System.Text.Json.Serialization;
using Questionable.Model.Common;
using Questionable.Model.Common.Converter;
using Questionable.Model.Questing;
using Questionable.Model.Questing.Converter;
namespace Questionable.Model.Gathering;
@ -10,12 +11,8 @@ public sealed class GatheringRoot
{
[JsonConverter(typeof(StringListOrValueConverter))]
public List<string> Author { get; set; } = [];
public ushort TerritoryId { get; set; }
[JsonConverter(typeof(AetheryteConverter))]
public EAetheryteLocation? AetheryteShortcut { get; set; }
public AethernetShortcut? AethernetShortcut { get; set; }
public List<QuestStep> Steps { get; set; } = [];
public bool? FlyBetweenNodes { get; set; }
public List<GatheringNodeGroup> Groups { get; set; } = [];
}

View File

@ -58,6 +58,15 @@ public sealed class AethernetShardConverter() : EnumConverter<EAetheryteLocation
{ EAetheryteLocation.IshgardGatesOfJudgement, "[Ishgard] The Gates of Judgement (Coerthas Central Highlands)" },
{ EAetheryteLocation.IshgardFirmament, "[Ishgard] Firmament" },
{ EAetheryteLocation.FirmamentMendicantsCourt, "[Firmament] The Mendicant's Court" },
{ EAetheryteLocation.FirmamentMattock, "[Firmament] The Mattock" },
{ EAetheryteLocation.FirmamentNewNest, "[Firmament] The New Nest" },
{ EAetheryteLocation.FirmanentSaintRoellesDais, "[Firmament] Saint Roelle's Dais" },
{ EAetheryteLocation.FirmamentFeatherfall, "[Firmament] Featherfall" },
{ EAetheryteLocation.FirmamentHoarfrostHall, "[Firmament] Hoarfrost Hall" },
{ EAetheryteLocation.FirmamentWesternRisensongQuarter, "[Firmament] Western Risensong Quarter" },
{ EAetheryteLocation.FIrmamentEasternRisensongQuarter, "[Firmament] Eastern Risensong Quarter" },
{ EAetheryteLocation.Idyllshire, "[Idyllshire] Aetheryte Plaza" },
{ EAetheryteLocation.IdyllshireWest, "[Idyllshire] West Idyllshire" },
{ EAetheryteLocation.IdyllshirePrologueGate, "[Idyllshire] Prologue Gate (Western Hinterlands)" },

View File

@ -182,6 +182,14 @@
"[Ishgard] The Last Vigil",
"[Ishgard] The Gates of Judgement (Coerthas Central Highlands)",
"[Ishgard] Firmament",
"[Firmament] The Mendicant's Court",
"[Firmament] The Mattock",
"[Firmament] The New Nest",
"[Firmament] Saint Roelle's Dais",
"[Firmament] Featherfall",
"[Firmament] Hoarfrost Hall",
"[Firmament] Western Risensong Quarter",
"[Firmament] Eastern Risensong Quarter",
"[Idyllshire] Aetheryte Plaza",
"[Idyllshire] West Idyllshire",
"[Idyllshire] Prologue Gate (Western Hinterlands)",

View File

@ -20,7 +20,9 @@ using Questionable.Controller.Steps.Interactions;
using Questionable.Data;
using Questionable.Functions;
using Questionable.Model;
using Questionable.Model.Common;
using Questionable.Model.Questing;
using AethernetShortcut = Questionable.Controller.Steps.Shared.AethernetShortcut;
using Quest = Questionable.Model.Quest;
using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType;
@ -88,6 +90,7 @@ internal sealed class GameUiController : IDisposable
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "HousingSelectBlock", HousingSelectBlockPostSetup);
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "JournalResult", JournalResultPostSetup);
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "GuildLeve", GuildLevePostSetup);
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "TelepotTown", TeleportTownPostSetup);
}
private bool ShouldHandleUiInteractions => _isInitialCheck || _questController.IsRunning;
@ -916,6 +919,46 @@ internal sealed class GameUiController : IDisposable
addon->Close(true);
}
private void TeleportTownPostSetup(AddonEvent type, AddonArgs args)
{
if (ShouldHandleUiInteractions &&
_questController.HasCurrentTaskMatching(out AethernetShortcut.UseAethernetShortcut? aethernetShortcut) &&
aethernetShortcut.From.IsFirmamentAetheryte())
{
// this might be better via atkvalues; but this works for now
uint toIndex = aethernetShortcut.To switch
{
EAetheryteLocation.FirmamentMendicantsCourt => 0,
EAetheryteLocation.FirmamentMattock => 1,
EAetheryteLocation.FirmamentNewNest => 2,
EAetheryteLocation.FirmanentSaintRoellesDais => 3,
EAetheryteLocation.FirmamentFeatherfall => 4,
EAetheryteLocation.FirmamentHoarfrostHall => 5,
EAetheryteLocation.FirmamentWesternRisensongQuarter => 6,
EAetheryteLocation.FIrmamentEasternRisensongQuarter => 7,
_ => uint.MaxValue,
};
if (toIndex == uint.MaxValue)
return;
_logger.LogInformation("Teleporting to {ToName} with menu index {ToIndex}", aethernetShortcut.From,
toIndex);
unsafe
{
var teleportToDestination = stackalloc AtkValue[]
{
new() { Type = ValueType.Int, Int = 11 },
new() { Type = ValueType.UInt, UInt = toIndex }
};
var addon = (AtkUnitBase*)args.Addon;
addon->FireCallback(2, teleportToDestination);
addon->FireCallback(2, teleportToDestination, true);
}
}
}
private StringOrRegex? ResolveReference(Quest? quest, string? excelSheet, ExcelRef? excelRef, bool isRegExp)
{
if (excelRef == null)
@ -933,6 +976,7 @@ internal sealed class GameUiController : IDisposable
public void Dispose()
{
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "TelepotTown", TeleportTownPostSetup);
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "GuildLeve", GuildLevePostSetup);
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "JournalResult", JournalResultPostSetup);
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "HousingSelectBlock", HousingSelectBlockPostSetup);

View File

@ -151,11 +151,12 @@ internal sealed unsafe class GatheringController : MiniTaskController<GatheringC
if (currentNode == null)
return;
ushort territoryId = _currentRequest.Root.Steps.Last().TerritoryId;
_taskQueue.Enqueue(_serviceProvider.GetRequiredService<MountTask>()
.With(_currentRequest.Root.TerritoryId, MountTask.EMountIf.Always));
.With(territoryId, MountTask.EMountIf.Always));
bool fly = currentNode.Fly.GetValueOrDefault(_currentRequest.Root.FlyBetweenNodes.GetValueOrDefault(true)) &&
_gameFunctions.IsFlyingUnlocked(_currentRequest.Root.TerritoryId);
_gameFunctions.IsFlyingUnlocked(territoryId);
if (currentNode.Locations.Count > 1)
{
Vector3 averagePosition = new Vector3
@ -170,12 +171,12 @@ internal sealed unsafe class GatheringController : MiniTaskController<GatheringC
pointOnFloor = pointOnFloor.Value with { Y = pointOnFloor.Value.Y + (fly ? 3f : 0f) };
_taskQueue.Enqueue(_serviceProvider.GetRequiredService<Move.MoveInternal>()
.With(_currentRequest.Root.TerritoryId, pointOnFloor ?? averagePosition, 50f, fly: fly,
.With(territoryId, pointOnFloor ?? averagePosition, 50f, fly: fly,
ignoreDistanceToObject: true));
}
_taskQueue.Enqueue(_serviceProvider.GetRequiredService<MoveToLandingLocation>()
.With(_currentRequest.Root.TerritoryId, fly, currentNode));
.With(territoryId, fly, currentNode));
_taskQueue.Enqueue(_serviceProvider.GetRequiredService<Interact.DoInteract>()
.With(currentNode.DataId, null, EInteractionType.InternalGather, true));

View File

@ -35,7 +35,7 @@ internal sealed class QuestController : MiniTaskController<QuestController>, IDi
private readonly IToastGui _toastGui;
private readonly Configuration _configuration;
private readonly YesAlreadyIpc _yesAlreadyIpc;
private readonly IReadOnlyList<ITaskFactory> _taskFactories;
private readonly TaskCreator _taskCreator;
private readonly object _progressLock = new();
@ -73,7 +73,7 @@ internal sealed class QuestController : MiniTaskController<QuestController>, IDi
IToastGui toastGui,
Configuration configuration,
YesAlreadyIpc yesAlreadyIpc,
IEnumerable<ITaskFactory> taskFactories)
TaskCreator taskCreator)
: base(chatGui, logger)
{
_clientState = clientState;
@ -88,7 +88,7 @@ internal sealed class QuestController : MiniTaskController<QuestController>, IDi
_toastGui = toastGui;
_configuration = configuration;
_yesAlreadyIpc = yesAlreadyIpc;
_taskFactories = taskFactories.ToList().AsReadOnly();
_taskCreator = taskCreator;
_condition.ConditionChange += OnConditionChange;
_toastGui.Toast += OnNormalToast;
@ -607,34 +607,7 @@ internal sealed class QuestController : MiniTaskController<QuestController>, IDi
try
{
var newTasks = _taskFactories
.SelectMany(x =>
{
IList<ITask> tasks = x.CreateAllTasks(CurrentQuest.Quest, seq, step).ToList();
if (tasks.Count > 0 && _logger.IsEnabled(LogLevel.Trace))
{
string factoryName = x.GetType().FullName ?? x.GetType().Name;
if (factoryName.Contains('.', StringComparison.Ordinal))
factoryName = factoryName[(factoryName.LastIndexOf('.') + 1)..];
_logger.LogTrace("Factory {FactoryName} created Task {TaskNames}",
factoryName, string.Join(", ", tasks.Select(y => y.ToString())));
}
return tasks;
})
.ToList();
if (newTasks.Count == 0)
{
_logger.LogInformation("Nothing to execute for step?");
return;
}
_logger.LogInformation("Tasks for {QuestId}, {Sequence}, {Step}: {Tasks}",
CurrentQuest.Quest.Id, seq.Sequence, seq.Steps.IndexOf(step),
string.Join(", ", newTasks.Select(x => x.ToString())));
foreach (var task in newTasks)
foreach (var task in _taskCreator.CreateTasks(CurrentQuest.Quest, seq, step))
_taskQueue.Enqueue(task);
}
catch (Exception e)

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Dalamud.Game.ClientState.Conditions;
using Dalamud.Game.ClientState.Objects.Enums;
using Dalamud.Plugin.Services;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@ -102,12 +103,9 @@ internal static class AethernetShortcut
if (aetheryteData.CalculateDistance(playerPosition, territoryType, From) <
aetheryteData.CalculateDistance(playerPosition, territoryType, To))
{
if (aetheryteData.CalculateDistance(playerPosition, territoryType, From) < 11)
if (aetheryteData.CalculateDistance(playerPosition, territoryType, From) < (From.IsFirmamentAetheryte() ? 11f : 4f))
{
logger.LogInformation("Using lifestream to teleport to {Destination}", To);
lifestreamIpc.Teleport(To);
_teleported = true;
DoTeleport();
return true;
}
else if (From == EAetheryteLocation.SolutionNine)
@ -141,7 +139,7 @@ internal static class AethernetShortcut
}
}
MoveTo(From);
MoveTo();
return true;
}
}
@ -154,13 +152,32 @@ internal static class AethernetShortcut
return false;
}
private void MoveTo(EAetheryteLocation from)
private void MoveTo()
{
logger.LogInformation("Moving to aethernet shortcut");
_moving = true;
movementController.NavigateTo(EMovementType.Quest, (uint)From, aetheryteData.Locations[From],
false, true,
AetheryteConverter.IsLargeAetheryte(From) ? 10.9f : 6.9f);
From.IsFirmamentAetheryte()
? 4.4f
: AetheryteConverter.IsLargeAetheryte(From)
? 10.9f
: 6.9f);
}
private void DoTeleport()
{
if (From.IsFirmamentAetheryte())
{
logger.LogInformation("Using manual teleport interaction");
_teleported = gameFunctions.InteractWith((uint)From, ObjectKind.EventObj);
}
else
{
logger.LogInformation("Using lifestream to teleport to {Destination}", To);
lifestreamIpc.Teleport(To);
_teleported = true;
}
}
public ETaskResult Update()
@ -173,7 +190,7 @@ internal static class AethernetShortcut
if (condition[ConditionFlag.Mounted])
{
_triedMounting = false;
MoveTo(From);
MoveTo();
return ETaskResult.StillRunning;
}
else
@ -194,10 +211,7 @@ internal static class AethernetShortcut
if (!_teleported)
{
logger.LogInformation("Using lifestream to teleport to {Destination}", To);
lifestreamIpc.Teleport(To);
_teleported = true;
DoTeleport();
return ETaskResult.StillRunning;
}

View File

@ -1,13 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Dalamud.Game.Text;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Game;
using LLib.GameData;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Questionable.Controller.Steps.Common;
using Questionable.Data;
using Questionable.GatheringPaths;
using Questionable.Model;
using Questionable.Model.Gathering;
using Questionable.Model.Questing;
@ -23,7 +24,7 @@ internal static class GatheringRequiredItems
IClientState clientState,
GatheringData gatheringData,
TerritoryData territoryData,
AetheryteData aetheryteData) : ITaskFactory
ILogger<Factory> logger) : ITaskFactory
{
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
{
@ -50,24 +51,25 @@ internal static class GatheringRequiredItems
if (HasRequiredItems(requiredGatheredItems))
continue;
if (gatheringRoot.AetheryteShortcut != null && clientState.TerritoryType != gatheringRoot.TerritoryId)
using (var _ = logger.BeginScope("Gathering(inner)"))
{
ushort expectedTerritoryId = gatheringRoot.TerritoryId;
if (gatheringRoot.AethernetShortcut != null)
expectedTerritoryId = aetheryteData.TerritoryIds[gatheringRoot.AethernetShortcut.From];
yield return serviceProvider.GetRequiredService<AetheryteShortcut.UseAetheryteShortcut>()
.With(null, gatheringRoot.AetheryteShortcut.Value, expectedTerritoryId);
QuestSequence gatheringSequence = new QuestSequence
{
Sequence = 0,
Steps = gatheringRoot.Steps
};
foreach (var gatheringStep in gatheringSequence.Steps)
{
foreach (var task in serviceProvider.GetRequiredService<TaskCreator>()
.CreateTasks(quest, gatheringSequence, gatheringStep))
if (task is not WaitAtEnd.NextStep)
yield return task;
}
}
if (gatheringRoot.AethernetShortcut != null)
{
yield return serviceProvider.GetRequiredService<AethernetShortcut.UseAethernetShortcut>()
.With(gatheringRoot.AethernetShortcut.From, gatheringRoot.AethernetShortcut.To);
}
yield return new WaitConditionTask(() => clientState.TerritoryType == gatheringRoot.TerritoryId,
$"Wait(territory: {territoryData.GetNameAndId(gatheringRoot.TerritoryId)})");
ushort territoryId = gatheringRoot.Steps.Last().TerritoryId;
yield return new WaitConditionTask(() => clientState.TerritoryType == territoryId,
$"Wait(territory: {territoryData.GetNameAndId(territoryId)})");
yield return new WaitConditionTask(() => movementController.IsNavmeshReady,
"Wait(navmesh ready)");

View File

@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.Logging;
using Questionable.Model;
using Questionable.Model.Questing;
namespace Questionable.Controller.Steps;
internal sealed class TaskCreator
{
private readonly IReadOnlyList<ITaskFactory> _taskFactories;
private readonly ILogger<TaskCreator> _logger;
public TaskCreator(IEnumerable<ITaskFactory> taskFactories, ILogger<TaskCreator> logger)
{
_taskFactories = taskFactories.ToList().AsReadOnly();
_logger = logger;
}
public IReadOnlyList<ITask> CreateTasks(Quest quest, QuestSequence sequence, QuestStep step)
{
var newTasks = _taskFactories
.SelectMany(x =>
{
IList<ITask> tasks = x.CreateAllTasks(quest, sequence, step).ToList();
if (tasks.Count > 0 && _logger.IsEnabled(LogLevel.Trace))
{
string factoryName = x.GetType().FullName ?? x.GetType().Name;
if (factoryName.Contains('.', StringComparison.Ordinal))
factoryName = factoryName[(factoryName.LastIndexOf('.') + 1)..];
_logger.LogTrace("Factory {FactoryName} created Task {TaskNames}",
factoryName, string.Join(", ", tasks.Select(y => y.ToString())));
}
return tasks;
})
.ToList();
if (newTasks.Count == 0)
_logger.LogInformation("Nothing to execute for step?");
else
{
_logger.LogInformation("Tasks for {QuestId}, {Sequence}, {Step}: {Tasks}",
quest.Id, sequence.Sequence, sequence.Steps.IndexOf(step),
string.Join(", ", newTasks.Select(x => x.ToString())));
}
return newTasks;
}
}

View File

@ -3,6 +3,7 @@ using System.Collections.ObjectModel;
using System.Linq;
using System.Numerics;
using Dalamud.Plugin.Services;
using Dalamud.Utility;
using Lumina.Excel.GeneratedSheets;
using Questionable.Model.Common;
@ -14,7 +15,25 @@ internal sealed class AetheryteData
{
Dictionary<EAetheryteLocation, string> aethernetNames = new();
Dictionary<EAetheryteLocation, ushort> territoryIds = new();
Dictionary<EAetheryteLocation, byte> aethernetGroups = new();
Dictionary<EAetheryteLocation, ushort> aethernetGroups = new();
void ConfigureAetheryte(EAetheryteLocation aetheryteLocation, string name, ushort territoryId,
ushort aethernetGroup)
{
aethernetNames[aetheryteLocation] = name;
territoryIds[aetheryteLocation] = territoryId;
aethernetGroups[aetheryteLocation] = aethernetGroup;
}
void ConfigureAetheryteWithPlaceName(EAetheryteLocation aetheryteLocation, uint placeNameId, ushort territoryId)
{
ConfigureAetheryte(aetheryteLocation,
dataManager.GetExcelSheet<PlaceName>()!.GetRow(placeNameId)!.Name.ToDalamudString().TextValue,
territoryId,
(ushort)((int)aetheryteLocation / 100));
}
foreach (var aetheryte in dataManager.GetExcelSheet<Aetheryte>()!.Where(x => x.RowId > 0))
{
string? aethernetName = aetheryte.AethernetName?.Value?.Name.ToString();
@ -28,9 +47,16 @@ internal sealed class AetheryteData
aethernetGroups[(EAetheryteLocation)aetheryte.RowId] = aetheryte.AethernetGroup;
}
aethernetNames[EAetheryteLocation.IshgardFirmament] = "Firmament";
territoryIds[EAetheryteLocation.IshgardFirmament] = 886;
aethernetGroups[EAetheryteLocation.IshgardFirmament] = aethernetGroups[EAetheryteLocation.Ishgard];
ConfigureAetheryte(EAetheryteLocation.IshgardFirmament, "Firmament", 886,
aethernetGroups[EAetheryteLocation.Ishgard]);
ConfigureAetheryteWithPlaceName(EAetheryteLocation.FirmamentMendicantsCourt, 3436, 886);
ConfigureAetheryteWithPlaceName(EAetheryteLocation.FirmamentMattock, 3473, 886);
ConfigureAetheryteWithPlaceName(EAetheryteLocation.FirmamentNewNest, 3475, 886);
ConfigureAetheryteWithPlaceName(EAetheryteLocation.FirmanentSaintRoellesDais, 3474, 886);
ConfigureAetheryteWithPlaceName(EAetheryteLocation.FirmamentFeatherfall, 3525, 886);
ConfigureAetheryteWithPlaceName(EAetheryteLocation.FirmamentHoarfrostHall, 3528, 886);
ConfigureAetheryteWithPlaceName(EAetheryteLocation.FirmamentWesternRisensongQuarter, 3646, 886);
ConfigureAetheryteWithPlaceName(EAetheryteLocation.FIrmamentEasternRisensongQuarter, 3645, 886);
AethernetNames = aethernetNames.AsReadOnly();
TerritoryIds = territoryIds.AsReadOnly();
@ -207,6 +233,15 @@ internal sealed class AetheryteData
{ EAetheryteLocation.RadzAtHanKama, new(129.59485f, 26.993164f, 13.473633f) },
{ EAetheryteLocation.RadzAtHanHighCrucible, new(57.90796f, -24.704407f, -210.6203f) },
{ EAetheryteLocation.FirmamentMendicantsCourt, new(23.941406f, -16.006714f, 169.35986f) },
{ EAetheryteLocation.FirmamentMattock, new(76.035645f, -18.509216f, 10.299805f) },
{ EAetheryteLocation.FirmamentNewNest, new(149.49255f, -50.003845f, 98.55798f) },
{ EAetheryteLocation.FirmanentSaintRoellesDais, new(207.75159f, -40.024475f, -25.589417f) },
{ EAetheryteLocation.FirmamentFeatherfall, new(-78.78235f, -0.015319824f, 75.97461f) },
{ EAetheryteLocation.FirmamentHoarfrostHall, new(-132.55518f, 9.964111f, -14.66394f) },
{ EAetheryteLocation.FirmamentWesternRisensongQuarter, new(-91.722046f, -0.015319824f, -115.19043f) },
{ EAetheryteLocation.FIrmamentEasternRisensongQuarter, new(114.3053f, -20.004639f, -107.43884f) },
{ EAetheryteLocation.LabyrinthosArcheion, new(443.5338f, 170.6416f, -476.18835f) },
{ EAetheryteLocation.LabyrinthosSharlayanHamlet, new(8.377136f, -27.542603f, -46.67737f) },
{ EAetheryteLocation.LabyrinthosAporia, new(-729.18286f, -27.634155f, 302.1438f) },
@ -276,7 +311,7 @@ internal sealed class AetheryteData
public ReadOnlyDictionary<EAetheryteLocation, string> AethernetNames { get; }
public ReadOnlyDictionary<EAetheryteLocation, ushort> TerritoryIds { get; }
public ReadOnlyDictionary<EAetheryteLocation, byte> AethernetGroups { get; }
public ReadOnlyDictionary<EAetheryteLocation, ushort> AethernetGroups { get; }
public IReadOnlyList<ushort> TownTerritoryIds { get; set; }
public float CalculateDistance(Vector3 fromPosition, ushort fromTerritoryType, EAetheryteLocation to)

View File

@ -41,7 +41,7 @@ internal sealed unsafe class AetheryteFunctions
public bool IsAetheryteUnlocked(EAetheryteLocation aetheryteLocation)
{
if (aetheryteLocation == EAetheryteLocation.IshgardFirmament)
if (aetheryteLocation.IsFirmamentAetheryte())
return _serviceProvider.GetRequiredService<QuestFunctions>().IsQuestComplete(new QuestId(3672));
return IsAetheryteUnlocked((uint)aetheryteLocation, out _);
}

View File

@ -171,6 +171,8 @@ public sealed class QuestionablePlugin : IDalamudPlugin
WaitAtEnd.WaitObjectAtPosition>();
serviceCollection.AddTransient<WaitAtEnd.WaitQuestAccepted>();
serviceCollection.AddTransient<WaitAtEnd.WaitQuestCompleted>();
serviceCollection.AddSingleton<TaskCreator>();
}
private static void AddControllers(ServiceCollection serviceCollection)

View File

@ -29,8 +29,8 @@ internal sealed class AethernetShortcutValidator : IQuestValidator
if (aethernetShortcut == null)
return null;
byte fromGroup = _aetheryteData.AethernetGroups.GetValueOrDefault(aethernetShortcut.From);
byte toGroup = _aetheryteData.AethernetGroups.GetValueOrDefault(aethernetShortcut.To);
ushort fromGroup = _aetheryteData.AethernetGroups.GetValueOrDefault(aethernetShortcut.From);
ushort toGroup = _aetheryteData.AethernetGroups.GetValueOrDefault(aethernetShortcut.To);
if (fromGroup != toGroup)
{
return new ValidationIssue