diff --git a/GatheringPathRenderer/GatheringPathRenderer.csproj b/GatheringPathRenderer/GatheringPathRenderer.csproj
new file mode 100644
index 00000000..5d22cd3f
--- /dev/null
+++ b/GatheringPathRenderer/GatheringPathRenderer.csproj
@@ -0,0 +1,3 @@
+
+
+
diff --git a/GatheringPathRenderer/RendererPlugin.cs b/GatheringPathRenderer/RendererPlugin.cs
new file mode 100644
index 00000000..d33eae96
--- /dev/null
+++ b/GatheringPathRenderer/RendererPlugin.cs
@@ -0,0 +1,11 @@
+using Dalamud.Plugin;
+
+namespace GatheringPathRenderer;
+
+public sealed class RendererPlugin : IDalamudPlugin
+{
+ public void Dispose()
+ {
+
+ }
+}
diff --git a/GatheringPathRenderer/packages.lock.json b/GatheringPathRenderer/packages.lock.json
new file mode 100644
index 00000000..0c669ebf
--- /dev/null
+++ b/GatheringPathRenderer/packages.lock.json
@@ -0,0 +1,81 @@
+{
+ "version": 1,
+ "dependencies": {
+ "net8.0-windows7.0": {
+ "DalamudPackager": {
+ "type": "Direct",
+ "requested": "[2.1.13, )",
+ "resolved": "2.1.13",
+ "contentHash": "rMN1omGe8536f4xLMvx9NwfvpAc9YFFfeXJ1t4P4PE6Gu8WCIoFliR1sh07hM+bfODmesk/dvMbji7vNI+B/pQ=="
+ },
+ "DotNet.ReproducibleBuilds": {
+ "type": "Direct",
+ "requested": "[1.1.1, )",
+ "resolved": "1.1.1",
+ "contentHash": "+H2t/t34h6mhEoUvHi8yGXyuZ2GjSovcGYehJrS2MDm2XgmPfZL2Sdxg+uL2lKgZ4M6tTwKHIlxOob2bgh0NRQ==",
+ "dependencies": {
+ "Microsoft.SourceLink.AzureRepos.Git": "1.1.1",
+ "Microsoft.SourceLink.Bitbucket.Git": "1.1.1",
+ "Microsoft.SourceLink.GitHub": "1.1.1",
+ "Microsoft.SourceLink.GitLab": "1.1.1"
+ }
+ },
+ "Microsoft.SourceLink.Gitea": {
+ "type": "Direct",
+ "requested": "[8.0.0, )",
+ "resolved": "8.0.0",
+ "contentHash": "KOBodmDnlWGIqZt2hT47Q69TIoGhIApDVLCyyj9TT5ct8ju16AbHYcB4XeknoHX562wO1pMS/1DfBIZK+V+sxg==",
+ "dependencies": {
+ "Microsoft.Build.Tasks.Git": "8.0.0",
+ "Microsoft.SourceLink.Common": "8.0.0"
+ }
+ },
+ "Microsoft.Build.Tasks.Git": {
+ "type": "Transitive",
+ "resolved": "8.0.0",
+ "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
+ },
+ "Microsoft.SourceLink.AzureRepos.Git": {
+ "type": "Transitive",
+ "resolved": "1.1.1",
+ "contentHash": "qB5urvw9LO2bG3eVAkuL+2ughxz2rR7aYgm2iyrB8Rlk9cp2ndvGRCvehk3rNIhRuNtQaeKwctOl1KvWiklv5w==",
+ "dependencies": {
+ "Microsoft.Build.Tasks.Git": "1.1.1",
+ "Microsoft.SourceLink.Common": "1.1.1"
+ }
+ },
+ "Microsoft.SourceLink.Bitbucket.Git": {
+ "type": "Transitive",
+ "resolved": "1.1.1",
+ "contentHash": "cDzxXwlyWpLWaH0em4Idj0H3AmVo3L/6xRXKssYemx+7W52iNskj/SQ4FOmfCb8YQt39otTDNMveCZzYtMoucQ==",
+ "dependencies": {
+ "Microsoft.Build.Tasks.Git": "1.1.1",
+ "Microsoft.SourceLink.Common": "1.1.1"
+ }
+ },
+ "Microsoft.SourceLink.Common": {
+ "type": "Transitive",
+ "resolved": "8.0.0",
+ "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
+ },
+ "Microsoft.SourceLink.GitHub": {
+ "type": "Transitive",
+ "resolved": "1.1.1",
+ "contentHash": "IaJGnOv/M7UQjRJks7B6p7pbPnOwisYGOIzqCz5ilGFTApZ3ktOR+6zJ12ZRPInulBmdAf1SrGdDG2MU8g6XTw==",
+ "dependencies": {
+ "Microsoft.Build.Tasks.Git": "1.1.1",
+ "Microsoft.SourceLink.Common": "1.1.1"
+ }
+ },
+ "Microsoft.SourceLink.GitLab": {
+ "type": "Transitive",
+ "resolved": "1.1.1",
+ "contentHash": "tvsg47DDLqqedlPeYVE2lmiTpND8F0hkrealQ5hYltSmvruy/Gr5nHAKSsjyw5L3NeM/HLMI5ORv7on/M4qyZw==",
+ "dependencies": {
+ "Microsoft.Build.Tasks.Git": "1.1.1",
+ "Microsoft.SourceLink.Common": "1.1.1"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/GatheringPaths/2.x - A Realm Reborn/.gitkeep b/GatheringPaths/2.x - A Realm Reborn/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/GatheringPaths/3.x - Heavensward/.gitkeep b/GatheringPaths/3.x - Heavensward/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/GatheringPaths/4.x - Stormblood/.gitkeep b/GatheringPaths/4.x - Stormblood/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/GatheringPaths/5.x - Shadowbringers/.gitkeep b/GatheringPaths/5.x - Shadowbringers/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/GatheringPaths/6.x - Endwalker/Thavnair/820_Pewter Ore.json b/GatheringPaths/6.x - Endwalker/Thavnair/820_Pewter Ore.json
new file mode 100644
index 00000000..425d77eb
--- /dev/null
+++ b/GatheringPaths/6.x - Endwalker/Thavnair/820_Pewter Ore.json
@@ -0,0 +1,56 @@
+{
+ "$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
+ "Author": "liza",
+ "TerritoryId": 957,
+ "AetheryteShortcut": "Thavnair - Great Work",
+ "Nodes": [
+ {
+ "DataId": 33918,
+ "Position": {
+ "X": -582.5132,
+ "Y": 40.54578,
+ "Z": -426.0171
+ }
+ },
+ {
+ "DataId": 33919,
+ "Position": {
+ "X": -578.2101,
+ "Y": 41.27147,
+ "Z": -447.6376
+ }
+ },
+ {
+ "DataId": 33920,
+ "Position": {
+ "X": -488.2276,
+ "Y": 34.71221,
+ "Z": -359.6945
+ }
+ },
+ {
+ "DataId": 33921,
+ "Position": {
+ "X": -498.8687,
+ "Y": 31.08014,
+ "Z": -351.9397
+ }
+ },
+ {
+ "DataId": 33922,
+ "Position": {
+ "X": -304.0609,
+ "Y": 68.76999,
+ "Z": -479.1875
+ }
+ },
+ {
+ "DataId": 33923,
+ "Position": {
+ "X": -293.6989,
+ "Y": 68.77935,
+ "Z": -484.2256
+ }
+ }
+ ]
+}
diff --git a/GatheringPaths/7.x - Dawntrail/.gitkeep b/GatheringPaths/7.x - Dawntrail/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/GatheringPaths/AssemblyGatheringLocationLoader.cs b/GatheringPaths/AssemblyGatheringLocationLoader.cs
new file mode 100644
index 00000000..04176410
--- /dev/null
+++ b/GatheringPaths/AssemblyGatheringLocationLoader.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using Questionable.Model.Gathering;
+
+namespace Questionable.GatheringPaths;
+
+[SuppressMessage("ReSharper", "PartialTypeWithSinglePart", Justification = "Required for RELEASE")]
+public static partial class AssemblyGatheringLocationLoader
+{
+ private static Dictionary? _locations;
+
+ public static IReadOnlyDictionary GetLocations()
+ {
+ if (_locations == null)
+ {
+ _locations = [];
+#if RELEASE
+ LoadLocations();
+#endif
+ }
+
+ return _locations ?? throw new InvalidOperationException("quest data is not initialized");
+ }
+
+ public static Stream QuestSchema =>
+ typeof(AssemblyGatheringLocationLoader).Assembly.GetManifestResourceStream("Questionable.GatheringPaths.GatheringLocationSchema")!;
+
+ [SuppressMessage("ReSharper", "UnusedMember.Local")]
+ private static void AddLocation(ushort questId, GatheringRoot root) => _locations![questId] = root;
+}
diff --git a/GatheringPaths/GatheringPaths.csproj b/GatheringPaths/GatheringPaths.csproj
new file mode 100644
index 00000000..f9e9725f
--- /dev/null
+++ b/GatheringPaths/GatheringPaths.csproj
@@ -0,0 +1,43 @@
+
+
+ net8.0-windows
+ 12
+ enable
+ Questionable.GatheringPaths
+ true
+ true
+ none
+ $(SolutionDir)=X:\
+ true
+ x64
+
+
+
+
+
+
+
+
+
+
+ Questionable.GatheringPaths.GatheringLocationSchema
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/GatheringPaths/gatheringlocation-v1.json b/GatheringPaths/gatheringlocation-v1.json
new file mode 100644
index 00000000..53b34f74
--- /dev/null
+++ b/GatheringPaths/gatheringlocation-v1.json
@@ -0,0 +1,98 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
+ "title": "Gathering Location V1",
+ "description": "A series of gathering locationsk",
+ "type": "object",
+ "properties": {
+ "$schema": {
+ "type": "string",
+ "const": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json"
+ },
+ "Author": {
+ "description": "Author of the gathering location data",
+ "type": [
+ "string",
+ "array"
+ ],
+ "items": {
+ "type": "string"
+ }
+ },
+ "TerritoryId": {
+ "type": "number"
+ },
+ "AetheryteShortcut": {
+ "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Aetheryte"
+ },
+ "Nodes": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "DataId": {
+ "type": "number",
+ "minimum": 30000,
+ "maximum": 50000
+ },
+ "Position": {
+ "$ref": "#/$defs/Vector3"
+ },
+ "MinimumAngle": {
+ "type": "number",
+ "minimum": -360,
+ "maximum": 360
+ },
+ "MaximumAngle": {
+ "type": "number",
+ "minimum": -360,
+ "maximum": 360
+ },
+ "MinimumDistance": {
+ "type": "number",
+ "minimum": 0
+ },
+ "MaximumDistance": {
+ "type": "number",
+ "exclusiveMinimum": 0
+ }
+ },
+ "required": [
+ "DataId",
+ "Position"
+ ],
+ "additionalProperties": false
+ }
+ }
+ },
+ "required": [
+ "$schema",
+ "Author",
+ "TerritoryId",
+ "AetheryteShortcut",
+ "Nodes"
+ ],
+ "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"
+ ]
+ }
+ }
+}
diff --git a/GatheringPaths/packages.lock.json b/GatheringPaths/packages.lock.json
new file mode 100644
index 00000000..408e267a
--- /dev/null
+++ b/GatheringPaths/packages.lock.json
@@ -0,0 +1,26 @@
+{
+ "version": 1,
+ "dependencies": {
+ "net8.0-windows7.0": {
+ "System.Text.Encodings.Web": {
+ "type": "Transitive",
+ "resolved": "8.0.0",
+ "contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ=="
+ },
+ "System.Text.Json": {
+ "type": "Transitive",
+ "resolved": "8.0.4",
+ "contentHash": "bAkhgDJ88XTsqczoxEMliSrpijKZHhbJQldhAmObj/RbrN3sU5dcokuXmWJWsdQAhiMJ9bTayWsL1C9fbbCRhw==",
+ "dependencies": {
+ "System.Text.Encodings.Web": "8.0.0"
+ }
+ },
+ "questionable.model": {
+ "type": "Project",
+ "dependencies": {
+ "System.Text.Json": "[8.0.4, )"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/QuestPathGenerator.Tests/QuestGeneratorTest.cs b/QuestPathGenerator.Tests/QuestGeneratorTest.cs
index 55d4cd64..f08606c1 100644
--- a/QuestPathGenerator.Tests/QuestGeneratorTest.cs
+++ b/QuestPathGenerator.Tests/QuestGeneratorTest.cs
@@ -1,4 +1,4 @@
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
using Questionable.QuestPathGenerator;
using Xunit;
diff --git a/QuestPathGenerator/GatheringSourceGenerator.cs b/QuestPathGenerator/GatheringSourceGenerator.cs
new file mode 100644
index 00000000..a10acd0e
--- /dev/null
+++ b/QuestPathGenerator/GatheringSourceGenerator.cs
@@ -0,0 +1,163 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using System.Linq;
+using System.Text.Json;
+using Json.Schema;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Questionable.Model.Gathering;
+using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
+using static Questionable.QuestPathGenerator.RoslynShortcuts;
+
+namespace Questionable.QuestPathGenerator;
+
+[Generator]
+[SuppressMessage("MicrosoftCodeAnalysisReleaseTracking", "RS2008")]
+public class GatheringSourceGenerator : ISourceGenerator
+{
+ private static readonly DiagnosticDescriptor InvalidJson = new("GPG0001",
+ "Invalid JSON",
+ "Invalid gathering file: {0}",
+ nameof(GatheringSourceGenerator),
+ DiagnosticSeverity.Error,
+ true);
+
+ public void Initialize(GeneratorInitializationContext context)
+ {
+ // No initialization required for this generator.
+ }
+
+ public void Execute(GeneratorExecutionContext context)
+ {
+ // Find schema definition
+ AdditionalText? gatheringSchema =
+ context.AdditionalFiles.SingleOrDefault(x => Path.GetFileName(x.Path) == "gatheringlocation-v1.json");
+ if (gatheringSchema != null)
+ GenerateGatheringSource(context, gatheringSchema);
+ }
+
+ private void GenerateGatheringSource(GeneratorExecutionContext context, AdditionalText jsonSchemaFile)
+ {
+ var gatheringSchema = JsonSchema.FromText(jsonSchemaFile.GetText()!.ToString());
+
+ List<(ushort, GatheringRoot)> gatheringLocations = [];
+ foreach (var (id, node) in Utils.GetAdditionalFiles(context, jsonSchemaFile, gatheringSchema, InvalidJson))
+ {
+ var gatheringLocation = node.Deserialize()!;
+ gatheringLocations.Add((id, gatheringLocation));
+ }
+
+ if (gatheringLocations.Count == 0)
+ return;
+
+ var partitionedLocations = gatheringLocations
+ .OrderBy(x => x.Item1)
+ .GroupBy(x => $"LoadLocation{x.Item1 / 100}")
+ .ToList();
+
+ var methods = Utils.CreateMethods("LoadLocations", partitionedLocations, CreateInitializer);
+
+ var code =
+ CompilationUnit()
+ .WithUsings(
+ List(
+ new[]
+ {
+ UsingDirective(
+ IdentifierName("System")),
+ UsingDirective(
+ QualifiedName(
+ IdentifierName("System"),
+ IdentifierName("Numerics"))),
+ UsingDirective(
+ QualifiedName(
+ IdentifierName("System"),
+ IdentifierName("IO"))),
+ UsingDirective(
+ QualifiedName(
+ QualifiedName(
+ IdentifierName("System"), IdentifierName("Collections")),
+ IdentifierName("Generic"))),
+ UsingDirective(
+ QualifiedName(
+ QualifiedName(
+ IdentifierName("Questionable"),
+ IdentifierName("Model")),
+ IdentifierName("Gathering"))),
+ UsingDirective(
+ QualifiedName(
+ QualifiedName(
+ IdentifierName("Questionable"),
+ IdentifierName("Model")),
+ IdentifierName("Common")))
+ }))
+ .WithMembers(
+ SingletonList(
+ FileScopedNamespaceDeclaration(
+ QualifiedName(
+ IdentifierName("Questionable"),
+ IdentifierName("GatheringPaths")))
+ .WithMembers(
+ SingletonList(
+ ClassDeclaration("AssemblyGatheringLocationLoader")
+ .WithModifiers(
+ TokenList(Token(SyntaxKind.PartialKeyword)))
+ .WithMembers(List(methods))))))
+ .NormalizeWhitespace();
+
+ // Add the source code to the compilation.
+ context.AddSource("AssemblyGatheringLocationLoader.g.cs", code.ToFullString());
+ }
+
+ private static StatementSyntax[] CreateInitializer(List<(ushort QuestId, GatheringRoot Root)> quests)
+ {
+ List statements = [];
+
+ foreach (var quest in quests)
+ {
+ statements.Add(
+ ExpressionStatement(
+ InvocationExpression(
+ IdentifierName("AddLocation"))
+ .WithArgumentList(
+ ArgumentList(
+ SeparatedList(
+ new SyntaxNodeOrToken[]
+ {
+ Argument(
+ LiteralExpression(SyntaxKind.NumericLiteralExpression,
+ Literal(quest.QuestId))),
+ Token(SyntaxKind.CommaToken),
+ Argument(CreateGatheringRootExpression(quest.QuestId, quest.Root))
+ })))));
+ }
+
+ return statements.ToArray();
+ }
+
+ private static ObjectCreationExpressionSyntax CreateGatheringRootExpression(ushort locationId, GatheringRoot root)
+ {
+ try
+ {
+ return ObjectCreationExpression(
+ IdentifierName(nameof(GatheringRoot)))
+ .WithInitializer(
+ InitializerExpression(
+ SyntaxKind.ObjectInitializerExpression,
+ SeparatedList(
+ SyntaxNodeList(
+ AssignmentList(nameof(GatheringRoot.Author), root.Author).AsSyntaxNodeOrToken(),
+ Assignment(nameof(GatheringRoot.TerritoryId), root.TerritoryId, default)
+ .AsSyntaxNodeOrToken(),
+ Assignment(nameof(GatheringRoot.AetheryteShortcut), root.AetheryteShortcut, null),
+ AssignmentList(nameof(GatheringRoot.Nodes), root.Nodes).AsSyntaxNodeOrToken()))));
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"GatheringGen[{locationId}]: {e.Message}", e);
+ }
+ }
+}
diff --git a/QuestPathGenerator/QuestSourceGenerator.cs b/QuestPathGenerator/QuestSourceGenerator.cs
index 47d311f2..b6cccbab 100644
--- a/QuestPathGenerator/QuestSourceGenerator.cs
+++ b/QuestPathGenerator/QuestSourceGenerator.cs
@@ -1,16 +1,14 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
-using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.Json;
-using System.Text.Json.Nodes;
using Json.Schema;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using static Questionable.QuestPathGenerator.RoslynShortcuts;
@@ -38,47 +36,21 @@ public class QuestSourceGenerator : ISourceGenerator
public void Execute(GeneratorExecutionContext context)
{
- List<(ushort, QuestRoot)> quests = [];
-
// Find schema definition
- AdditionalText jsonSchemaFile =
- context.AdditionalFiles.Single(x => Path.GetFileName(x.Path) == "quest-v1.json");
+ AdditionalText? questSchema =
+ context.AdditionalFiles.SingleOrDefault(x => Path.GetFileName(x.Path) == "quest-v1.json");
+ if (questSchema != null)
+ GenerateQuestSource(context, questSchema);
+ }
+
+ private void GenerateQuestSource(GeneratorExecutionContext context, AdditionalText jsonSchemaFile)
+ {
var questSchema = JsonSchema.FromText(jsonSchemaFile.GetText()!.ToString());
- // Go through all files marked as an Additional File in file properties.
- foreach (var additionalFile in context.AdditionalFiles)
+ List<(ushort, QuestRoot)> quests = [];
+ foreach (var (id, node) in Utils.GetAdditionalFiles(context, jsonSchemaFile, questSchema, InvalidJson))
{
- if (additionalFile == null || additionalFile == jsonSchemaFile)
- continue;
-
- if (Path.GetExtension(additionalFile.Path) != ".json")
- continue;
-
- string name = Path.GetFileName(additionalFile.Path);
- if (!name.Contains('_'))
- continue;
-
- ushort id = ushort.Parse(name.Substring(0, name.IndexOf('_')));
-
- var text = additionalFile.GetText();
- if (text == null)
- continue;
-
- var questNode = JsonNode.Parse(text.ToString());
- var evaluationResult = questSchema.Evaluate(questNode, new EvaluationOptions
- {
- Culture = CultureInfo.InvariantCulture,
- OutputFormat = OutputFormat.List
- });
- if (!evaluationResult.IsValid)
- {
- var error = Diagnostic.Create(InvalidJson,
- null,
- Path.GetFileName(additionalFile.Path));
- context.ReportDiagnostic(error);
- }
-
- var quest = questNode.Deserialize()!;
+ var quest = node.Deserialize()!;
if (quest.Disabled)
{
quest.Author = [];
@@ -97,38 +69,7 @@ public class QuestSourceGenerator : ISourceGenerator
.GroupBy(x => $"LoadQuests{x.Item1 / 50}")
.ToList();
- List methods =
- [
- MethodDeclaration(
- PredefinedType(
- Token(SyntaxKind.VoidKeyword)),
- Identifier("LoadQuests"))
- .WithModifiers(
- TokenList(
- Token(SyntaxKind.PrivateKeyword),
- Token(SyntaxKind.StaticKeyword)))
- .WithBody(
- Block(
- partitionedQuests
- .Select(x =>
- ExpressionStatement(
- InvocationExpression(
- IdentifierName(x.Key))))))
- ];
-
- foreach (var partition in partitionedQuests)
- {
- methods.Add(MethodDeclaration(
- PredefinedType(
- Token(SyntaxKind.VoidKeyword)),
- Identifier(partition.Key))
- .WithModifiers(
- TokenList(
- Token(SyntaxKind.PrivateKeyword),
- Token(SyntaxKind.StaticKeyword)))
- .WithBody(
- Block(CreateInitializer(partition.ToList()))));
- }
+ var methods = Utils.CreateMethods("LoadQuests", partitionedQuests, CreateInitializer);
var code =
CompilationUnit()
@@ -156,7 +97,13 @@ public class QuestSourceGenerator : ISourceGenerator
QualifiedName(
IdentifierName("Questionable"),
IdentifierName("Model")),
- IdentifierName("V1")))
+ IdentifierName("Questing"))),
+ UsingDirective(
+ QualifiedName(
+ QualifiedName(
+ IdentifierName("Questionable"),
+ IdentifierName("Model")),
+ IdentifierName("Common")))
}))
.WithMembers(
SingletonList(
diff --git a/QuestPathGenerator/RoslynShortcuts.cs b/QuestPathGenerator/RoslynShortcuts.cs
index 2bacaba4..4f5a8fb0 100644
--- a/QuestPathGenerator/RoslynShortcuts.cs
+++ b/QuestPathGenerator/RoslynShortcuts.cs
@@ -6,7 +6,9 @@ using System.Numerics;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
-using Questionable.Model.V1;
+using Questionable.Model.Common;
+using Questionable.Model.Gathering;
+using Questionable.Model.Questing;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
namespace Questionable.QuestPathGenerator;
@@ -312,6 +314,32 @@ public static class RoslynShortcuts
Assignment(nameof(SkipAetheryteCondition.InSameTerritory),
skipAetheryteCondition.InSameTerritory, emptyAetheryte.InSameTerritory)))));
}
+ else if (value is GatheringNodeLocation nodeLocation)
+ {
+ var emptyLocation = new GatheringNodeLocation();
+ return ObjectCreationExpression(
+ IdentifierName(nameof(GatheringNodeLocation)))
+ .WithInitializer(
+ InitializerExpression(
+ SyntaxKind.ObjectInitializerExpression,
+ SeparatedList(
+ SyntaxNodeList(
+ Assignment(nameof(GatheringNodeLocation.DataId), nodeLocation.DataId,
+ emptyLocation.DataId)
+ .AsSyntaxNodeOrToken(),
+ Assignment(nameof(GatheringNodeLocation.Position), nodeLocation.Position,
+ emptyLocation.Position).AsSyntaxNodeOrToken(),
+ Assignment(nameof(GatheringNodeLocation.MinimumAngle), nodeLocation.MinimumAngle,
+ emptyLocation.MinimumAngle).AsSyntaxNodeOrToken(),
+ Assignment(nameof(GatheringNodeLocation.MaximumAngle), nodeLocation.MaximumAngle,
+ emptyLocation.MaximumAngle).AsSyntaxNodeOrToken(),
+ Assignment(nameof(GatheringNodeLocation.MinimumDistance),
+ nodeLocation.MinimumDistance, emptyLocation.MinimumDistance)
+ .AsSyntaxNodeOrToken(),
+ Assignment(nameof(GatheringNodeLocation.MaximumDistance),
+ nodeLocation.MaximumDistance, emptyLocation.MaximumDistance)
+ .AsSyntaxNodeOrToken()))));
+ }
else if (value is null)
return LiteralExpression(SyntaxKind.NullLiteralExpression);
}
diff --git a/QuestPathGenerator/Utils.cs b/QuestPathGenerator/Utils.cs
new file mode 100644
index 00000000..12873a71
--- /dev/null
+++ b/QuestPathGenerator/Utils.cs
@@ -0,0 +1,109 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text.Json.Nodes;
+using Json.Schema;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
+
+namespace Questionable.QuestPathGenerator;
+
+public static class Utils
+{
+ public static IEnumerable<(ushort, JsonNode)> GetAdditionalFiles(GeneratorExecutionContext context,
+ AdditionalText jsonSchemaFile, JsonSchema jsonSchema, DiagnosticDescriptor invalidJson)
+ {
+ var commonSchemaFile = context.AdditionalFiles.Single(x => Path.GetFileName(x.Path) == "common-schema.json");
+ List jsonSchemaFiles = [jsonSchemaFile, commonSchemaFile];
+
+ SchemaRegistry.Global.Register(
+ new Uri("https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json"),
+ JsonSchema.FromText(commonSchemaFile.GetText()!.ToString()));
+
+ foreach (var additionalFile in context.AdditionalFiles)
+ {
+ if (additionalFile == null || jsonSchemaFiles.Contains(additionalFile))
+ continue;
+
+ if (Path.GetExtension(additionalFile.Path) != ".json")
+ continue;
+
+ string name = Path.GetFileName(additionalFile.Path);
+ if (!name.Contains("_"))
+ continue;
+
+ ushort id = ushort.Parse(name.Substring(0, name.IndexOf('_')));
+
+ var text = additionalFile.GetText();
+ if (text == null)
+ continue;
+
+ var node = JsonNode.Parse(text.ToString());
+ if (node == null)
+ continue;
+
+ string? schemaLocation = node["$schema"]?.GetValue();
+ if (schemaLocation == null || new Uri(schemaLocation) != jsonSchema.GetId())
+ continue;
+
+ var evaluationResult = jsonSchema.Evaluate(node, new EvaluationOptions
+ {
+ Culture = CultureInfo.InvariantCulture,
+ OutputFormat = OutputFormat.List,
+ });
+ if (!evaluationResult.IsValid)
+ {
+ var error = Diagnostic.Create(invalidJson,
+ null,
+ Path.GetFileName(additionalFile.Path));
+ context.ReportDiagnostic(error);
+ }
+
+ yield return (id, node);
+ }
+ }
+
+ public static List CreateMethods(string prefix,
+ List> partitions,
+ Func, StatementSyntax[]> toInitializers)
+ {
+ List methods =
+ [
+ MethodDeclaration(
+ PredefinedType(
+ Token(SyntaxKind.VoidKeyword)),
+ Identifier(prefix))
+ .WithModifiers(
+ TokenList(
+ Token(SyntaxKind.PrivateKeyword),
+ Token(SyntaxKind.StaticKeyword)))
+ .WithBody(
+ Block(
+ partitions
+ .Select(x =>
+ ExpressionStatement(
+ InvocationExpression(
+ IdentifierName(x.Key))))))
+ ];
+
+ foreach (var partition in partitions)
+ {
+ methods.Add(MethodDeclaration(
+ PredefinedType(
+ Token(SyntaxKind.VoidKeyword)),
+ Identifier(partition.Key))
+ .WithModifiers(
+ TokenList(
+ Token(SyntaxKind.PrivateKeyword),
+ Token(SyntaxKind.StaticKeyword)))
+ .WithBody(
+ Block(toInitializers(partition.ToList()))));
+ }
+
+ return methods;
+ }
+}
diff --git a/QuestPaths/AssemblyQuestLoader.cs b/QuestPaths/AssemblyQuestLoader.cs
index 90ba89a1..3ef7df15 100644
--- a/QuestPaths/AssemblyQuestLoader.cs
+++ b/QuestPaths/AssemblyQuestLoader.cs
@@ -2,8 +2,7 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
-using System.Reflection;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.QuestPaths;
diff --git a/QuestPaths/QuestPaths.csproj b/QuestPaths/QuestPaths.csproj
index e914b62d..5d91a016 100644
--- a/QuestPaths/QuestPaths.csproj
+++ b/QuestPaths/QuestPaths.csproj
@@ -23,6 +23,7 @@
Questionable.QuestPaths.QuestSchema
+
diff --git a/QuestPaths/quest-v1.json b/QuestPaths/quest-v1.json
index 751e4730..a11a610c 100644
--- a/QuestPaths/quest-v1.json
+++ b/QuestPaths/quest-v1.json
@@ -154,7 +154,7 @@
},
"AetheryteShortcut": {
"description": "The Aetheryte to teleport to (before moving)",
- "$ref": "#/$defs/Aetheryte"
+ "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Aetheryte"
},
"AethernetShortcut": {
"type": "array",
@@ -162,7 +162,7 @@
"minItems": 2,
"maxItems": 2,
"items": {
- "$ref": "#/$defs/AethernetShard"
+ "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/AethernetShard"
}
},
"ItemId": {
@@ -183,7 +183,7 @@
"type": "boolean"
},
"CompletionQuestVariablesFlags": {
- "$ref": "#/$defs/CompletionFlags"
+ "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/CompletionFlags"
},
"Flying": {
"type": "string",
@@ -271,7 +271,7 @@
"additionalProperties": false
},
"CompletionQuestVariablesFlags": {
- "$ref": "#/$defs/CompletionFlags"
+ "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/CompletionFlags"
},
"RequiredQuestVariables": {
"type": "array",
@@ -383,7 +383,7 @@
"then": {
"properties": {
"Aetheryte": {
- "$ref": "#/$defs/Aetheryte"
+ "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Aetheryte"
},
"DataId": {
"type": "null"
@@ -415,7 +415,7 @@
"then": {
"properties": {
"AethernetShard": {
- "$ref": "#/$defs/AethernetShard"
+ "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/AethernetShard"
},
"DataId": {
"type": "null"
@@ -507,7 +507,7 @@
"type": "integer"
},
"CompletionQuestVariablesFlags": {
- "$ref": "#/$defs/CompletionFlags"
+ "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/CompletionFlags"
},
"IgnoreQuestMarker": {
"type": "boolean"
@@ -1073,300 +1073,5 @@
"QuestSequence",
"Author"
],
- "additionalProperties": false,
- "$defs": {
- "Aetheryte": {
- "type": "string",
- "enum": [
- "Gridania",
- "Central Shroud - Bentbranch Meadows",
- "East Shroud - Hawthorne Hut",
- "South Shroud - Quarrymill",
- "South Shroud - Camp Tranquil",
- "North Shroud - Fallgourd Float",
- "Ul'dah",
- "Western Thanalan - Horizon",
- "Central Thanalan - Black Brush Station",
- "Eastern Thanalan - Camp Drybone",
- "Southern Thanalan - Little Ala Mhigo",
- "Southern Thanalan - Forgotten Springs",
- "Northern Thanalan - Camp Bluefog",
- "Northern Thanalan - Ceruleum Processing Plant",
- "Limsa Lominsa",
- "Middle La Noscea - Summerford Farms",
- "Lower La Noscea - Moraby Drydocks",
- "Eastern La Noscea - Costa Del Sol",
- "Eastern La Noscea - Wineport",
- "Western La Noscea - Swiftperch",
- "Western La Noscea - Aleport",
- "Upper La Noscea - Camp Bronze Lake",
- "Outer La Noscea - Camp Overlook",
- "Coerthas Central Highlands - Camp Dragonhead",
- "Mor Dhona",
- "Gold Saucer",
- "Wolves' Den Pier",
- "Ishgard",
- "Idyllshire",
- "Coerthas Western Highlands - Falcon's Nest",
- "The Sea of Clouds - Camp Cloudtop",
- "The Sea of Clouds - Ok' Zundu",
- "Azys Lla - Helix",
- "The Dravanian Forelands - Tailfeather",
- "The Dravanian Forelands - Anyx Trine",
- "The Churning Mists - Moghome",
- "The Churning Mists - Zenith",
- "Rhalgr's Reach",
- "Fringes - Castrum Oriens",
- "Fringes - Peering Stones",
- "Peaks - Ala Gannha",
- "Peaks - Ala Ghiri",
- "Lochs - Porta Praetoria",
- "Lochs - Ala Mhigan Quarter",
- "Kugane",
- "Ruby Sea - Tamamizu",
- "Ruby Sea - Onokoro",
- "Yanxia - Namai",
- "Yanxia - House of the Fierce",
- "Azim Steppe - Reunion",
- "Azim Steppe - Dawn Throne",
- "Azim Steppe - Dhoro Iloh",
- "Doman Enclave",
- "Crystarium",
- "Eulmore",
- "Lakeland - Fort Jobb",
- "Lakeland - Ostall Imperative",
- "Kholusia - Stilltide",
- "Kholusia - Wright",
- "Kholusia - Tomra",
- "Amh Araeng - Mord Souq",
- "Amh Araeng - Inn at Journey's Head",
- "Amh Araeng - Twine",
- "Rak'tika - Slitherbough",
- "Rak'tika - Fanow",
- "Il Mheg - Lydha Lran",
- "Il Mheg - Pia Enni",
- "Il Mheg - Wolekdorf",
- "Tempest - Ondo Cups",
- "Tempest - Macarenses Angle",
- "Old Sharlayan",
- "Radz-at-Han",
- "Labyrinthos - Archeion",
- "Labyrinthos - Sharlayan Hamlet",
- "Labyrinthos - Aporia",
- "Thavnair - Yedlihmad",
- "Thavnair - Great Work",
- "Thavnair - Palaka's Stand",
- "Garlemald - Camp Broken Glass",
- "Garlemald - Tertium",
- "Mare Lamentorum - Sinus Lacrimarum",
- "Mare Lamentorum - Bestways Burrow",
- "Elpis - Anagnorisis",
- "Elpis - Twelve Wonders",
- "Elpis - Poieten Oikos",
- "Ultima Thule - Reah Tahra",
- "Ultima Thule - Abode of the Ea",
- "Ultima Thule - Base Omicron",
- "Tuliyollal",
- "Solution Nine",
- "Urqopacha - Wachunpelo",
- "Urqopacha - Worlar's Echo",
- "Kozama'uka - Ok'hanu",
- "Kozama'uka - Many Fires",
- "Kozama'uka - Earthenshire",
- "Yak T'el - Iq Br'aax",
- "Yak T'el - Mamook",
- "Shaaloani - Hhusatahwi",
- "Shaaloani - Sheshenewezi Springs",
- "Shaaloani - Mehwahhetsoan",
- "Heritage Found - Yyasulani Station",
- "Heritage Found - The Outskirts",
- "Heritage Found - Electrope Strike",
- "Living Memory - Leynode Mnemo",
- "Living Memory - Leynode Pyro",
- "Living Memory - Leynode Aero"
- ]
- },
- "AethernetShard": {
- "type": "string",
- "enum": [
- "[Gridania] Aetheryte Plaza",
- "[Gridania] Archers' Guild",
- "[Gridania] Leatherworkers' Guild & Shaded Bower",
- "[Gridania] Lancers' Guild",
- "[Gridania] Conjurers' Guild",
- "[Gridania] Botanists' Guild",
- "[Gridania] Mih Khetto's Amphitheatre",
- "[Gridania] Blue Badger Gate (Central Shroud)",
- "[Gridania] Yellow Serpent Gate (North Shroud)",
- "[Gridania] White Wolf Gate (Central Shroud)",
- "[Gridania] Airship Landing",
- "[Ul'dah] Aetheryte Plaza",
- "[Ul'dah] Adventurers' Guild",
- "[Ul'dah] Thaumaturges' Guild",
- "[Ul'dah] Gladiators' Guild",
- "[Ul'dah] Miners' Guild",
- "[Ul'dah] Weavers' Guild",
- "[Ul'dah] Goldsmiths' Guild",
- "[Ul'dah] Sapphire Avenue Exchange",
- "[Ul'dah] Alchemists' Guild",
- "[Ul'dah] Gate of the Sultana (Western Thanalan)",
- "[Ul'dah] Gate of Nald (Central Thanalan)",
- "[Ul'dah] Gate of Thal (Central Thanalan)",
- "[Ul'dah] The Chamber of Rule",
- "[Ul'dah] Airship Landing",
- "[Limsa Lominsa] Aetheryte Plaza",
- "[Limsa Lominsa] Arcanists' Guild",
- "[Limsa Lominsa] Fishermens' Guild",
- "[Limsa Lominsa] Hawkers' Alley",
- "[Limsa Lominsa] The Aftcastle",
- "[Limsa Lominsa] Culinarians' Guild",
- "[Limsa Lominsa] Marauders' Guild",
- "[Limsa Lominsa] Zephyr Gate (Middle La Noscea)",
- "[Limsa Lominsa] Tempest Gate (Lower La Noscea)",
- "[Limsa Lominsa] Airship Landing",
- "[Ishgard] Aetheryte Plaza",
- "[Ishgard] The Forgotten Knight",
- "[Ishgard] Skysteel Manufactory",
- "[Ishgard] The Brume",
- "[Ishgard] Athenaeum Astrologicum",
- "[Ishgard] The Jeweled Crozier",
- "[Ishgard] Saint Reymanaud's Cathedral",
- "[Ishgard] The Tribunal",
- "[Ishgard] The Last Vigil",
- "[Ishgard] The Gates of Judgement (Coerthas Central Highlands)",
- "[Idyllshire] Aetheryte Plaza",
- "[Idyllshire] West Idyllshire",
- "[Idyllshire] Prologue Gate (Western Hinterlands)",
- "[Idyllshire] Epilogue Gate (Eastern Hinterlands)",
- "[Rhalgr's Reach] Aetheryte Plaza",
- "[Rhalgr's Reach] Western Rhalgr's Reach",
- "[Rhalgr's Reach] Northeastern Rhalgr's Reach",
- "[Rhalgr's Reach] Fringes Gate",
- "[Rhalgr's Reach] Peaks Gate",
- "[Kugane] Aetheryte Plaza",
- "[Kugane] Shiokaze Hostelry",
- "[Kugane] Pier #1",
- "[Kugane] Thavnairian Consulate",
- "[Kugane] Kogane Dori Markets",
- "[Kugane] Bokairo Inn",
- "[Kugane] The Ruby Bazaar",
- "[Kugane] Sekiseigumi Barracks",
- "[Kugane] Rakuza District",
- "[Kugane] The Ruby Price",
- "[Kugane] Airship Landing",
- "[Crystarium] Aetheryte Plaza",
- "[Crystarium] Musica Universalis Markets",
- "[Crystarium] Temenos Rookery",
- "[Crystarium] The Dossal Gate",
- "[Crystarium] The Pendants",
- "[Crystarium] The Amaro Launch",
- "[Crystarium] The Crystalline Mean",
- "[Crystarium] The Cabinet of Curiosity",
- "[Crystarium] Tessellation (Lakeland)",
- "[Eulmore] Aetheryte Plaza",
- "[Eulmore] Southeast Derelicts",
- "[Eulmore] Nightsoil Pots",
- "[Eulmore] The Glory Gate",
- "[Eulmore] The Mainstay",
- "[Eulmore] The Path to Glory (Kholusia)",
- "[Old Sharlayan] Aetheryte Plaza",
- "[Old Sharlayan] The Studium",
- "[Old Sharlayan] The Baldesion Annex",
- "[Old Sharlayan] The Rostra",
- "[Old Sharlayan] The Leveilleur Estate",
- "[Old Sharlayan] Journey's End",
- "[Old Sharlayan] Scholar's Harbor",
- "[Old Sharlayan] The Hall of Artifice (Labyrinthos)",
- "[Radz-at-Han] Aetheryte Plaza",
- "[Radz-at-Han] Meghaduta",
- "[Radz-at-Han] Ruveydah Fibers",
- "[Radz-at-Han] Airship Landing",
- "[Radz-at-Han] Alzadaal's Peace",
- "[Radz-at-Han] Hall of the Radiant Host",
- "[Radz-at-Han] Mehryde's Meyhane",
- "[Radz-at-Han] Kama",
- "[Radz-at-Han] The High Crucible of Al-Kimiya",
- "[Radz-at-Han] The Gate of First Sight (Thavnair)",
- "[Tuliyollal] Aetheryte Plaza",
- "[Tuliyollal] Dirigible Landing",
- "[Tuliyollal] The Resplendent Quarter",
- "[Tuliyollal] The For'ard Cabins",
- "[Tuliyollal] Bayside Bevy Marketplace",
- "[Tuliyollal] Vollok Shoonsa",
- "[Tuliyollal] Wachumeqimeqi",
- "[Tuliyollal] Brightploom Post",
- "[Tuliyollal] Arch of the Dawn (Urqopacha)",
- "[Tuliyollal] Arch of the Dawn (Kozama'uka)",
- "[Tuliyollal] Ihuykatumu (Kozama'uka)",
- "[Tuliyollal] Dirigible Landing (Yak T'el)",
- "[Tuliyollal] Xak Tural Skygate (Shaaloani)",
- "[Solution Nine] Aetheryte Plaza",
- "[Solution Nine] Information Center",
- "[Solution Nine] True Vue",
- "[Solution Nine] Neon Stein",
- "[Solution Nine] The Arcadion",
- "[Solution Nine] Resolution",
- "[Solution Nine] Nexus Arcade",
- "[Solution Nine] Residential Sector",
- "[Solution Nine] Scanning Port Nine (Heritage Found)"
- ]
- },
- "CompletionFlags": {
- "type": "array",
- "description": "Quest Variables that dictate whether or not this step is skipped: null is don't check, positive values need to be set, negative values need to be unset",
- "items": {
- "oneOf": [
- {
- "type": "object",
- "properties": {
- "High": {
- "type": [
- "number",
- "null"
- ],
- "minimum": 0,
- "maximum": 15
- },
- "Low": {
- "type": [
- "number",
- "null"
- ],
- "minimum": 0,
- "maximum": 15
- },
- "Negative": {
- "type": "boolean"
- },
- "Mode": {
- "type": "string",
- "enum": [
- "Bitwise",
- "Exact"
- ]
- }
- }
- },
- {
- "type": "number",
- "enum": [
- 1,
- 2,
- 4,
- 8,
- 16,
- 32,
- 64,
- 128
- ]
- },
- {
- "type": "null"
- }
- ]
- },
- "minItems": 6,
- "maxItems": 6
- }
- }
+ "additionalProperties": false
}
diff --git a/Questionable.Model/AssemblyModelLoader.cs b/Questionable.Model/AssemblyModelLoader.cs
new file mode 100644
index 00000000..d167cb25
--- /dev/null
+++ b/Questionable.Model/AssemblyModelLoader.cs
@@ -0,0 +1,9 @@
+using System.IO;
+
+namespace Questionable.Model;
+
+public static class AssemblyModelLoader
+{
+ public static Stream CommonSchema =>
+ typeof(AssemblyModelLoader).Assembly.GetManifestResourceStream("Questionable.Model.CommonSchema")!;
+}
diff --git a/Questionable.Model/V1/Converter/AetheryteConverter.cs b/Questionable.Model/Common/Converter/AetheryteConverter.cs
similarity index 98%
rename from Questionable.Model/V1/Converter/AetheryteConverter.cs
rename to Questionable.Model/Common/Converter/AetheryteConverter.cs
index ab0dd549..3887305e 100644
--- a/Questionable.Model/V1/Converter/AetheryteConverter.cs
+++ b/Questionable.Model/Common/Converter/AetheryteConverter.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
+using Questionable.Model.Common.Converter;
-namespace Questionable.Model.V1.Converter;
+namespace Questionable.Model.Common.Converter;
public sealed class AetheryteConverter() : EnumConverter(Values)
{
diff --git a/Questionable.Model/V1/Converter/EnumConverter.cs b/Questionable.Model/Common/Converter/EnumConverter.cs
similarity index 96%
rename from Questionable.Model/V1/Converter/EnumConverter.cs
rename to Questionable.Model/Common/Converter/EnumConverter.cs
index 3ed1267b..3708e28c 100644
--- a/Questionable.Model/V1/Converter/EnumConverter.cs
+++ b/Questionable.Model/Common/Converter/EnumConverter.cs
@@ -5,7 +5,7 @@ using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
-namespace Questionable.Model.V1.Converter;
+namespace Questionable.Model.Common.Converter;
public abstract class EnumConverter : JsonConverter
where T : Enum
diff --git a/Questionable.Model/V1/Converter/StringListOrValueConverter.cs b/Questionable.Model/Common/Converter/StringListOrValueConverter.cs
similarity index 96%
rename from Questionable.Model/V1/Converter/StringListOrValueConverter.cs
rename to Questionable.Model/Common/Converter/StringListOrValueConverter.cs
index b6da81a2..ebdec1cf 100644
--- a/Questionable.Model/V1/Converter/StringListOrValueConverter.cs
+++ b/Questionable.Model/Common/Converter/StringListOrValueConverter.cs
@@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
-namespace Questionable.Model.V1.Converter;
+namespace Questionable.Model.Common.Converter;
public sealed class StringListOrValueConverter : JsonConverter>
{
diff --git a/Questionable.Model/V1/Converter/VectorConverter.cs b/Questionable.Model/Common/Converter/VectorConverter.cs
similarity index 97%
rename from Questionable.Model/V1/Converter/VectorConverter.cs
rename to Questionable.Model/Common/Converter/VectorConverter.cs
index f75ffe6a..7b4833ef 100644
--- a/Questionable.Model/V1/Converter/VectorConverter.cs
+++ b/Questionable.Model/Common/Converter/VectorConverter.cs
@@ -3,7 +3,7 @@ using System.Numerics;
using System.Text.Json;
using System.Text.Json.Serialization;
-namespace Questionable.Model.V1.Converter;
+namespace Questionable.Model.Common.Converter;
public sealed class VectorConverter : JsonConverter
{
diff --git a/Questionable.Model/V1/EAetheryteLocation.cs b/Questionable.Model/Common/EAetheryteLocation.cs
similarity index 98%
rename from Questionable.Model/V1/EAetheryteLocation.cs
rename to Questionable.Model/Common/EAetheryteLocation.cs
index 1ddde305..a00f7b51 100644
--- a/Questionable.Model/V1/EAetheryteLocation.cs
+++ b/Questionable.Model/Common/EAetheryteLocation.cs
@@ -1,7 +1,8 @@
using System.Text.Json.Serialization;
-using Questionable.Model.V1.Converter;
+using Questionable.Model.Common.Converter;
+using Questionable.Model.Questing.Converter;
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Common;
[JsonConverter(typeof(AetheryteConverter))]
public enum EAetheryteLocation
diff --git a/Questionable.Model/Gathering/GatheringNodeLocation.cs b/Questionable.Model/Gathering/GatheringNodeLocation.cs
new file mode 100644
index 00000000..49a5e640
--- /dev/null
+++ b/Questionable.Model/Gathering/GatheringNodeLocation.cs
@@ -0,0 +1,13 @@
+using System.Numerics;
+
+namespace Questionable.Model.Gathering;
+
+public sealed class GatheringNodeLocation
+{
+ public uint DataId { get; set; }
+ public Vector3 Position { get; set; }
+ public float? MinimumAngle { get; set; }
+ public float? MaximumAngle { get; set; }
+ public float? MinimumDistance { get; set; } = 0.5f;
+ public float? MaximumDistance { get; set; } = 3f;
+}
diff --git a/Questionable.Model/Gathering/GatheringRoot.cs b/Questionable.Model/Gathering/GatheringRoot.cs
new file mode 100644
index 00000000..c572faab
--- /dev/null
+++ b/Questionable.Model/Gathering/GatheringRoot.cs
@@ -0,0 +1,18 @@
+using System.Collections.Generic;
+using System.Text.Json.Serialization;
+using Questionable.Model.Common;
+using Questionable.Model.Common.Converter;
+
+namespace Questionable.Model.Gathering;
+
+public sealed class GatheringRoot
+{
+ [JsonConverter(typeof(StringListOrValueConverter))]
+ public List Author { get; set; } = [];
+ public ushort TerritoryId { get; set; }
+
+ [JsonConverter(typeof(AetheryteConverter))]
+ public EAetheryteLocation? AetheryteShortcut { get; set; }
+
+ public List Nodes { get; set; } = [];
+}
diff --git a/Questionable.Model/V1/AethernetShortcut.cs b/Questionable.Model/Questing/AethernetShortcut.cs
similarity index 66%
rename from Questionable.Model/V1/AethernetShortcut.cs
rename to Questionable.Model/Questing/AethernetShortcut.cs
index 40514b58..3d046c44 100644
--- a/Questionable.Model/V1/AethernetShortcut.cs
+++ b/Questionable.Model/Questing/AethernetShortcut.cs
@@ -1,7 +1,8 @@
using System.Text.Json.Serialization;
-using Questionable.Model.V1.Converter;
+using Questionable.Model.Common;
+using Questionable.Model.Questing.Converter;
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Questing;
[JsonConverter(typeof(AethernetShortcutConverter))]
public sealed class AethernetShortcut
diff --git a/Questionable.Model/V1/ChatMessage.cs b/Questionable.Model/Questing/ChatMessage.cs
similarity index 75%
rename from Questionable.Model/V1/ChatMessage.cs
rename to Questionable.Model/Questing/ChatMessage.cs
index 71721380..b0272135 100644
--- a/Questionable.Model/V1/ChatMessage.cs
+++ b/Questionable.Model/Questing/ChatMessage.cs
@@ -1,4 +1,4 @@
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Questing;
public sealed class ChatMessage
{
diff --git a/Questionable.Model/V1/ComplexCombatData.cs b/Questionable.Model/Questing/ComplexCombatData.cs
similarity index 93%
rename from Questionable.Model/V1/ComplexCombatData.cs
rename to Questionable.Model/Questing/ComplexCombatData.cs
index d31de7e2..5f85c243 100644
--- a/Questionable.Model/V1/ComplexCombatData.cs
+++ b/Questionable.Model/Questing/ComplexCombatData.cs
@@ -1,6 +1,6 @@
using System.Collections.Generic;
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Questing;
public sealed class ComplexCombatData
{
diff --git a/Questionable.Model/V1/Converter/ActionConverter.cs b/Questionable.Model/Questing/Converter/ActionConverter.cs
similarity index 86%
rename from Questionable.Model/V1/Converter/ActionConverter.cs
rename to Questionable.Model/Questing/Converter/ActionConverter.cs
index eaf5baac..7e62c011 100644
--- a/Questionable.Model/V1/Converter/ActionConverter.cs
+++ b/Questionable.Model/Questing/Converter/ActionConverter.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
+using Questionable.Model.Common.Converter;
-namespace Questionable.Model.V1.Converter;
+namespace Questionable.Model.Questing.Converter;
public sealed class ActionConverter() : EnumConverter(Values)
{
diff --git a/Questionable.Model/V1/Converter/AethernetShardConverter.cs b/Questionable.Model/Questing/Converter/AethernetShardConverter.cs
similarity index 98%
rename from Questionable.Model/V1/Converter/AethernetShardConverter.cs
rename to Questionable.Model/Questing/Converter/AethernetShardConverter.cs
index bfb259c2..bd07bc39 100644
--- a/Questionable.Model/V1/Converter/AethernetShardConverter.cs
+++ b/Questionable.Model/Questing/Converter/AethernetShardConverter.cs
@@ -1,6 +1,8 @@
using System.Collections.Generic;
+using Questionable.Model.Common;
+using Questionable.Model.Common.Converter;
-namespace Questionable.Model.V1.Converter;
+namespace Questionable.Model.Questing.Converter;
public sealed class AethernetShardConverter() : EnumConverter(Values)
{
diff --git a/Questionable.Model/V1/Converter/AethernetShortcutConverter.cs b/Questionable.Model/Questing/Converter/AethernetShortcutConverter.cs
similarity index 95%
rename from Questionable.Model/V1/Converter/AethernetShortcutConverter.cs
rename to Questionable.Model/Questing/Converter/AethernetShortcutConverter.cs
index 8b90769f..d920d882 100644
--- a/Questionable.Model/V1/Converter/AethernetShortcutConverter.cs
+++ b/Questionable.Model/Questing/Converter/AethernetShortcutConverter.cs
@@ -3,8 +3,9 @@ using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
+using Questionable.Model.Common;
-namespace Questionable.Model.V1.Converter;
+namespace Questionable.Model.Questing.Converter;
public sealed class AethernetShortcutConverter : JsonConverter
{
diff --git a/Questionable.Model/V1/Converter/DialogueChoiceTypeConverter.cs b/Questionable.Model/Questing/Converter/DialogueChoiceTypeConverter.cs
similarity index 77%
rename from Questionable.Model/V1/Converter/DialogueChoiceTypeConverter.cs
rename to Questionable.Model/Questing/Converter/DialogueChoiceTypeConverter.cs
index ea832cac..cd66ca9b 100644
--- a/Questionable.Model/V1/Converter/DialogueChoiceTypeConverter.cs
+++ b/Questionable.Model/Questing/Converter/DialogueChoiceTypeConverter.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
+using Questionable.Model.Common.Converter;
-namespace Questionable.Model.V1.Converter;
+namespace Questionable.Model.Questing.Converter;
public sealed class DialogueChoiceTypeConverter() : EnumConverter(Values)
{
diff --git a/Questionable.Model/V1/Converter/EmoteConverter.cs b/Questionable.Model/Questing/Converter/EmoteConverter.cs
similarity index 91%
rename from Questionable.Model/V1/Converter/EmoteConverter.cs
rename to Questionable.Model/Questing/Converter/EmoteConverter.cs
index 8a327517..20c97694 100644
--- a/Questionable.Model/V1/Converter/EmoteConverter.cs
+++ b/Questionable.Model/Questing/Converter/EmoteConverter.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
+using Questionable.Model.Common.Converter;
-namespace Questionable.Model.V1.Converter;
+namespace Questionable.Model.Questing.Converter;
public sealed class EmoteConverter() : EnumConverter(Values)
{
diff --git a/Questionable.Model/V1/Converter/EnemySpawnTypeConverter.cs b/Questionable.Model/Questing/Converter/EnemySpawnTypeConverter.cs
similarity index 83%
rename from Questionable.Model/V1/Converter/EnemySpawnTypeConverter.cs
rename to Questionable.Model/Questing/Converter/EnemySpawnTypeConverter.cs
index 5c5de532..e97faa4f 100644
--- a/Questionable.Model/V1/Converter/EnemySpawnTypeConverter.cs
+++ b/Questionable.Model/Questing/Converter/EnemySpawnTypeConverter.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
+using Questionable.Model.Common.Converter;
-namespace Questionable.Model.V1.Converter;
+namespace Questionable.Model.Questing.Converter;
public sealed class EnemySpawnTypeConverter() : EnumConverter(Values)
{
diff --git a/Questionable.Model/V1/Converter/ExcelRefConverter.cs b/Questionable.Model/Questing/Converter/ExcelRefConverter.cs
similarity index 95%
rename from Questionable.Model/V1/Converter/ExcelRefConverter.cs
rename to Questionable.Model/Questing/Converter/ExcelRefConverter.cs
index 06ba3ff1..03a8168e 100644
--- a/Questionable.Model/V1/Converter/ExcelRefConverter.cs
+++ b/Questionable.Model/Questing/Converter/ExcelRefConverter.cs
@@ -2,7 +2,7 @@
using System.Text.Json;
using System.Text.Json.Serialization;
-namespace Questionable.Model.V1.Converter;
+namespace Questionable.Model.Questing.Converter;
public sealed class ExcelRefConverter : JsonConverter
{
diff --git a/Questionable.Model/V1/Converter/InteractionTypeConverter.cs b/Questionable.Model/Questing/Converter/InteractionTypeConverter.cs
similarity index 93%
rename from Questionable.Model/V1/Converter/InteractionTypeConverter.cs
rename to Questionable.Model/Questing/Converter/InteractionTypeConverter.cs
index 08be6ff6..23f0366e 100644
--- a/Questionable.Model/V1/Converter/InteractionTypeConverter.cs
+++ b/Questionable.Model/Questing/Converter/InteractionTypeConverter.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
+using Questionable.Model.Common.Converter;
-namespace Questionable.Model.V1.Converter;
+namespace Questionable.Model.Questing.Converter;
public sealed class InteractionTypeConverter() : EnumConverter(Values)
{
diff --git a/Questionable.Model/V1/Converter/JumpTypeConverter.cs b/Questionable.Model/Questing/Converter/JumpTypeConverter.cs
similarity index 76%
rename from Questionable.Model/V1/Converter/JumpTypeConverter.cs
rename to Questionable.Model/Questing/Converter/JumpTypeConverter.cs
index 94c8ea2b..95bb0846 100644
--- a/Questionable.Model/V1/Converter/JumpTypeConverter.cs
+++ b/Questionable.Model/Questing/Converter/JumpTypeConverter.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
+using Questionable.Model.Common.Converter;
-namespace Questionable.Model.V1.Converter;
+namespace Questionable.Model.Questing.Converter;
public sealed class JumpTypeConverter() : EnumConverter(Values)
{
diff --git a/Questionable.Model/V1/Converter/LockedSkipConditionConverter.cs b/Questionable.Model/Questing/Converter/LockedSkipConditionConverter.cs
similarity index 78%
rename from Questionable.Model/V1/Converter/LockedSkipConditionConverter.cs
rename to Questionable.Model/Questing/Converter/LockedSkipConditionConverter.cs
index 5d53058e..72eb9dec 100644
--- a/Questionable.Model/V1/Converter/LockedSkipConditionConverter.cs
+++ b/Questionable.Model/Questing/Converter/LockedSkipConditionConverter.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
+using Questionable.Model.Common.Converter;
-namespace Questionable.Model.V1.Converter;
+namespace Questionable.Model.Questing.Converter;
public sealed class LockedSkipConditionConverter() : EnumConverter(Values)
{
diff --git a/Questionable.Model/V1/Converter/QuestWorkConfigConverter.cs b/Questionable.Model/Questing/Converter/QuestWorkConfigConverter.cs
similarity index 97%
rename from Questionable.Model/V1/Converter/QuestWorkConfigConverter.cs
rename to Questionable.Model/Questing/Converter/QuestWorkConfigConverter.cs
index 2b376937..b6cccc46 100644
--- a/Questionable.Model/V1/Converter/QuestWorkConfigConverter.cs
+++ b/Questionable.Model/Questing/Converter/QuestWorkConfigConverter.cs
@@ -2,7 +2,7 @@
using System.Text.Json;
using System.Text.Json.Serialization;
-namespace Questionable.Model.V1.Converter;
+namespace Questionable.Model.Questing.Converter;
public sealed class QuestWorkConfigConverter : JsonConverter
{
diff --git a/Questionable.Model/V1/Converter/QuestWorkModeConverter.cs b/Questionable.Model/Questing/Converter/QuestWorkModeConverter.cs
similarity index 77%
rename from Questionable.Model/V1/Converter/QuestWorkModeConverter.cs
rename to Questionable.Model/Questing/Converter/QuestWorkModeConverter.cs
index a3697d66..322d6a19 100644
--- a/Questionable.Model/V1/Converter/QuestWorkModeConverter.cs
+++ b/Questionable.Model/Questing/Converter/QuestWorkModeConverter.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
+using Questionable.Model.Common.Converter;
-namespace Questionable.Model.V1.Converter;
+namespace Questionable.Model.Questing.Converter;
public sealed class QuestWorkModeConverter() : EnumConverter(Values)
{
diff --git a/Questionable.Model/V1/Converter/SkipConditionConverter.cs b/Questionable.Model/Questing/Converter/SkipConditionConverter.cs
similarity index 76%
rename from Questionable.Model/V1/Converter/SkipConditionConverter.cs
rename to Questionable.Model/Questing/Converter/SkipConditionConverter.cs
index f4b4e6fc..eadd84b1 100644
--- a/Questionable.Model/V1/Converter/SkipConditionConverter.cs
+++ b/Questionable.Model/Questing/Converter/SkipConditionConverter.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
+using Questionable.Model.Common.Converter;
-namespace Questionable.Model.V1.Converter;
+namespace Questionable.Model.Questing.Converter;
public sealed class SkipConditionConverter() : EnumConverter(Values)
{
diff --git a/Questionable.Model/V1/DialogueChoice.cs b/Questionable.Model/Questing/DialogueChoice.cs
similarity index 87%
rename from Questionable.Model/V1/DialogueChoice.cs
rename to Questionable.Model/Questing/DialogueChoice.cs
index 80b49d05..91370f5d 100644
--- a/Questionable.Model/V1/DialogueChoice.cs
+++ b/Questionable.Model/Questing/DialogueChoice.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Serialization;
-using Questionable.Model.V1.Converter;
+using Questionable.Model.Questing.Converter;
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Questing;
public sealed class DialogueChoice
{
diff --git a/Questionable.Model/V1/EAction.cs b/Questionable.Model/Questing/EAction.cs
similarity index 88%
rename from Questionable.Model/V1/EAction.cs
rename to Questionable.Model/Questing/EAction.cs
index 8aca752f..4b24dee1 100644
--- a/Questionable.Model/V1/EAction.cs
+++ b/Questionable.Model/Questing/EAction.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Serialization;
-using Questionable.Model.V1.Converter;
+using Questionable.Model.Questing.Converter;
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Questing;
[JsonConverter(typeof(ActionConverter))]
public enum EAction
diff --git a/Questionable.Model/V1/EDialogChoiceType.cs b/Questionable.Model/Questing/EDialogChoiceType.cs
similarity index 61%
rename from Questionable.Model/V1/EDialogChoiceType.cs
rename to Questionable.Model/Questing/EDialogChoiceType.cs
index 066639a3..9b537471 100644
--- a/Questionable.Model/V1/EDialogChoiceType.cs
+++ b/Questionable.Model/Questing/EDialogChoiceType.cs
@@ -1,4 +1,4 @@
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Questing;
public enum EDialogChoiceType
{
diff --git a/Questionable.Model/V1/EEmote.cs b/Questionable.Model/Questing/EEmote.cs
similarity index 85%
rename from Questionable.Model/V1/EEmote.cs
rename to Questionable.Model/Questing/EEmote.cs
index 6657a1dd..022930e9 100644
--- a/Questionable.Model/V1/EEmote.cs
+++ b/Questionable.Model/Questing/EEmote.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Serialization;
-using Questionable.Model.V1.Converter;
+using Questionable.Model.Questing.Converter;
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Questing;
[JsonConverter(typeof(EmoteConverter))]
public enum EEmote
diff --git a/Questionable.Model/V1/EEnemySpawnType.cs b/Questionable.Model/Questing/EEnemySpawnType.cs
similarity index 72%
rename from Questionable.Model/V1/EEnemySpawnType.cs
rename to Questionable.Model/Questing/EEnemySpawnType.cs
index 8465f011..3c42b9f4 100644
--- a/Questionable.Model/V1/EEnemySpawnType.cs
+++ b/Questionable.Model/Questing/EEnemySpawnType.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Serialization;
-using Questionable.Model.V1.Converter;
+using Questionable.Model.Questing.Converter;
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Questing;
[JsonConverter(typeof(EnemySpawnTypeConverter))]
public enum EEnemySpawnType
diff --git a/Questionable.Model/V1/EExtraSkipCondition.cs b/Questionable.Model/Questing/EExtraSkipCondition.cs
similarity index 65%
rename from Questionable.Model/V1/EExtraSkipCondition.cs
rename to Questionable.Model/Questing/EExtraSkipCondition.cs
index 227bf0f2..3f2836a9 100644
--- a/Questionable.Model/V1/EExtraSkipCondition.cs
+++ b/Questionable.Model/Questing/EExtraSkipCondition.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Serialization;
-using Questionable.Model.V1.Converter;
+using Questionable.Model.Questing.Converter;
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Questing;
[JsonConverter(typeof(SkipConditionConverter))]
public enum EExtraSkipCondition
diff --git a/Questionable.Model/V1/EInteractionType.cs b/Questionable.Model/Questing/EInteractionType.cs
similarity index 86%
rename from Questionable.Model/V1/EInteractionType.cs
rename to Questionable.Model/Questing/EInteractionType.cs
index 843f600d..5080714a 100644
--- a/Questionable.Model/V1/EInteractionType.cs
+++ b/Questionable.Model/Questing/EInteractionType.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Serialization;
-using Questionable.Model.V1.Converter;
+using Questionable.Model.Questing.Converter;
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Questing;
[JsonConverter(typeof(InteractionTypeConverter))]
public enum EInteractionType
diff --git a/Questionable.Model/V1/EJumpType.cs b/Questionable.Model/Questing/EJumpType.cs
similarity index 63%
rename from Questionable.Model/V1/EJumpType.cs
rename to Questionable.Model/Questing/EJumpType.cs
index b06365eb..e89931ac 100644
--- a/Questionable.Model/V1/EJumpType.cs
+++ b/Questionable.Model/Questing/EJumpType.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Serialization;
-using Questionable.Model.V1.Converter;
+using Questionable.Model.Questing.Converter;
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Questing;
[JsonConverter(typeof(JumpTypeConverter))]
public enum EJumpType
diff --git a/Questionable.Model/V1/ELockedSkipCondition.cs b/Questionable.Model/Questing/ELockedSkipCondition.cs
similarity index 65%
rename from Questionable.Model/V1/ELockedSkipCondition.cs
rename to Questionable.Model/Questing/ELockedSkipCondition.cs
index 2863c262..7755b129 100644
--- a/Questionable.Model/V1/ELockedSkipCondition.cs
+++ b/Questionable.Model/Questing/ELockedSkipCondition.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Serialization;
-using Questionable.Model.V1.Converter;
+using Questionable.Model.Questing.Converter;
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Questing;
[JsonConverter(typeof(LockedSkipConditionConverter))]
public enum ELockedSkipCondition
diff --git a/Questionable.Model/V1/EQuestWorkMode.cs b/Questionable.Model/Questing/EQuestWorkMode.cs
similarity index 63%
rename from Questionable.Model/V1/EQuestWorkMode.cs
rename to Questionable.Model/Questing/EQuestWorkMode.cs
index ef225b23..3d835225 100644
--- a/Questionable.Model/V1/EQuestWorkMode.cs
+++ b/Questionable.Model/Questing/EQuestWorkMode.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Serialization;
-using Questionable.Model.V1.Converter;
+using Questionable.Model.Questing.Converter;
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Questing;
[JsonConverter(typeof(QuestWorkModeConverter))]
public enum EQuestWorkMode
diff --git a/Questionable.Model/V1/ExcelRef.cs b/Questionable.Model/Questing/ExcelRef.cs
similarity index 97%
rename from Questionable.Model/V1/ExcelRef.cs
rename to Questionable.Model/Questing/ExcelRef.cs
index 295dd5ba..cdb55014 100644
--- a/Questionable.Model/V1/ExcelRef.cs
+++ b/Questionable.Model/Questing/ExcelRef.cs
@@ -1,6 +1,6 @@
using System;
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Questing;
public class ExcelRef
{
diff --git a/Questionable.Model/V1/JumpDestination.cs b/Questionable.Model/Questing/JumpDestination.cs
similarity index 76%
rename from Questionable.Model/V1/JumpDestination.cs
rename to Questionable.Model/Questing/JumpDestination.cs
index 2497560a..9682e21e 100644
--- a/Questionable.Model/V1/JumpDestination.cs
+++ b/Questionable.Model/Questing/JumpDestination.cs
@@ -1,8 +1,9 @@
using System.Numerics;
using System.Text.Json.Serialization;
-using Questionable.Model.V1.Converter;
+using Questionable.Model.Common.Converter;
+using Questionable.Model.Questing.Converter;
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Questing;
public sealed class JumpDestination
{
diff --git a/Questionable.Model/V1/QuestRoot.cs b/Questionable.Model/Questing/QuestRoot.cs
similarity index 80%
rename from Questionable.Model/V1/QuestRoot.cs
rename to Questionable.Model/Questing/QuestRoot.cs
index ada2e9fd..e1158fc8 100644
--- a/Questionable.Model/V1/QuestRoot.cs
+++ b/Questionable.Model/Questing/QuestRoot.cs
@@ -1,8 +1,9 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
-using Questionable.Model.V1.Converter;
+using Questionable.Model.Common.Converter;
+using Questionable.Model.Questing.Converter;
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Questing;
public sealed class QuestRoot
{
diff --git a/Questionable.Model/V1/QuestSequence.cs b/Questionable.Model/Questing/QuestSequence.cs
similarity index 91%
rename from Questionable.Model/V1/QuestSequence.cs
rename to Questionable.Model/Questing/QuestSequence.cs
index 73807e0b..3e42e098 100644
--- a/Questionable.Model/V1/QuestSequence.cs
+++ b/Questionable.Model/Questing/QuestSequence.cs
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.Linq;
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Questing;
public sealed class QuestSequence
{
diff --git a/Questionable.Model/V1/QuestStep.cs b/Questionable.Model/Questing/QuestStep.cs
similarity index 95%
rename from Questionable.Model/V1/QuestStep.cs
rename to Questionable.Model/Questing/QuestStep.cs
index accd6623..53ed7ced 100644
--- a/Questionable.Model/V1/QuestStep.cs
+++ b/Questionable.Model/Questing/QuestStep.cs
@@ -1,9 +1,11 @@
using System.Collections.Generic;
using System.Numerics;
using System.Text.Json.Serialization;
-using Questionable.Model.V1.Converter;
+using Questionable.Model.Common;
+using Questionable.Model.Common.Converter;
+using Questionable.Model.Questing.Converter;
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Questing;
public sealed class QuestStep
{
diff --git a/Questionable.Model/V1/QuestWorkValue.cs b/Questionable.Model/Questing/QuestWorkValue.cs
similarity index 90%
rename from Questionable.Model/V1/QuestWorkValue.cs
rename to Questionable.Model/Questing/QuestWorkValue.cs
index 75c68511..d4db77ef 100644
--- a/Questionable.Model/V1/QuestWorkValue.cs
+++ b/Questionable.Model/Questing/QuestWorkValue.cs
@@ -1,8 +1,8 @@
using System;
using System.Text.Json.Serialization;
-using Questionable.Model.V1.Converter;
+using Questionable.Model.Questing.Converter;
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Questing;
[JsonConverter(typeof(QuestWorkConfigConverter))]
public sealed class QuestWorkValue(byte? high, byte? low, EQuestWorkMode mode)
diff --git a/Questionable.Model/V1/SkipAetheryteCondition.cs b/Questionable.Model/Questing/SkipAetheryteCondition.cs
similarity index 75%
rename from Questionable.Model/V1/SkipAetheryteCondition.cs
rename to Questionable.Model/Questing/SkipAetheryteCondition.cs
index 86d0a1c6..0109e4de 100644
--- a/Questionable.Model/V1/SkipAetheryteCondition.cs
+++ b/Questionable.Model/Questing/SkipAetheryteCondition.cs
@@ -1,4 +1,4 @@
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Questing;
public sealed class SkipAetheryteCondition
{
diff --git a/Questionable.Model/V1/SkipConditions.cs b/Questionable.Model/Questing/SkipConditions.cs
similarity index 84%
rename from Questionable.Model/V1/SkipConditions.cs
rename to Questionable.Model/Questing/SkipConditions.cs
index 5f866865..6525ec0f 100644
--- a/Questionable.Model/V1/SkipConditions.cs
+++ b/Questionable.Model/Questing/SkipConditions.cs
@@ -1,4 +1,4 @@
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Questing;
public sealed class SkipConditions
{
diff --git a/Questionable.Model/V1/SkipItemConditions.cs b/Questionable.Model/Questing/SkipItemConditions.cs
similarity index 67%
rename from Questionable.Model/V1/SkipItemConditions.cs
rename to Questionable.Model/Questing/SkipItemConditions.cs
index 9154dcd4..04c38f6e 100644
--- a/Questionable.Model/V1/SkipItemConditions.cs
+++ b/Questionable.Model/Questing/SkipItemConditions.cs
@@ -1,4 +1,4 @@
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Questing;
public sealed class SkipItemConditions
{
diff --git a/Questionable.Model/V1/SkipStepConditions.cs b/Questionable.Model/Questing/SkipStepConditions.cs
similarity index 97%
rename from Questionable.Model/V1/SkipStepConditions.cs
rename to Questionable.Model/Questing/SkipStepConditions.cs
index be8df96b..ee7e7dcf 100644
--- a/Questionable.Model/V1/SkipStepConditions.cs
+++ b/Questionable.Model/Questing/SkipStepConditions.cs
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.Linq;
-namespace Questionable.Model.V1;
+namespace Questionable.Model.Questing;
public sealed class SkipStepConditions
{
diff --git a/Questionable.Model/Questionable.Model.csproj b/Questionable.Model/Questionable.Model.csproj
index cb320ec5..54301430 100644
--- a/Questionable.Model/Questionable.Model.csproj
+++ b/Questionable.Model/Questionable.Model.csproj
@@ -13,4 +13,12 @@
+
+
+
+
+
+ Questionable.Model.CommonSchema
+
+
diff --git a/Questionable.Model/common-schema.json b/Questionable.Model/common-schema.json
new file mode 100644
index 00000000..6017ecb7
--- /dev/null
+++ b/Questionable.Model/common-schema.json
@@ -0,0 +1,299 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json",
+ "$defs": {
+ "Aetheryte": {
+ "type": "string",
+ "enum": [
+ "Gridania",
+ "Central Shroud - Bentbranch Meadows",
+ "East Shroud - Hawthorne Hut",
+ "South Shroud - Quarrymill",
+ "South Shroud - Camp Tranquil",
+ "North Shroud - Fallgourd Float",
+ "Ul'dah",
+ "Western Thanalan - Horizon",
+ "Central Thanalan - Black Brush Station",
+ "Eastern Thanalan - Camp Drybone",
+ "Southern Thanalan - Little Ala Mhigo",
+ "Southern Thanalan - Forgotten Springs",
+ "Northern Thanalan - Camp Bluefog",
+ "Northern Thanalan - Ceruleum Processing Plant",
+ "Limsa Lominsa",
+ "Middle La Noscea - Summerford Farms",
+ "Lower La Noscea - Moraby Drydocks",
+ "Eastern La Noscea - Costa Del Sol",
+ "Eastern La Noscea - Wineport",
+ "Western La Noscea - Swiftperch",
+ "Western La Noscea - Aleport",
+ "Upper La Noscea - Camp Bronze Lake",
+ "Outer La Noscea - Camp Overlook",
+ "Coerthas Central Highlands - Camp Dragonhead",
+ "Mor Dhona",
+ "Gold Saucer",
+ "Wolves' Den Pier",
+ "Ishgard",
+ "Idyllshire",
+ "Coerthas Western Highlands - Falcon's Nest",
+ "The Sea of Clouds - Camp Cloudtop",
+ "The Sea of Clouds - Ok' Zundu",
+ "Azys Lla - Helix",
+ "The Dravanian Forelands - Tailfeather",
+ "The Dravanian Forelands - Anyx Trine",
+ "The Churning Mists - Moghome",
+ "The Churning Mists - Zenith",
+ "Rhalgr's Reach",
+ "Fringes - Castrum Oriens",
+ "Fringes - Peering Stones",
+ "Peaks - Ala Gannha",
+ "Peaks - Ala Ghiri",
+ "Lochs - Porta Praetoria",
+ "Lochs - Ala Mhigan Quarter",
+ "Kugane",
+ "Ruby Sea - Tamamizu",
+ "Ruby Sea - Onokoro",
+ "Yanxia - Namai",
+ "Yanxia - House of the Fierce",
+ "Azim Steppe - Reunion",
+ "Azim Steppe - Dawn Throne",
+ "Azim Steppe - Dhoro Iloh",
+ "Doman Enclave",
+ "Crystarium",
+ "Eulmore",
+ "Lakeland - Fort Jobb",
+ "Lakeland - Ostall Imperative",
+ "Kholusia - Stilltide",
+ "Kholusia - Wright",
+ "Kholusia - Tomra",
+ "Amh Araeng - Mord Souq",
+ "Amh Araeng - Inn at Journey's Head",
+ "Amh Araeng - Twine",
+ "Rak'tika - Slitherbough",
+ "Rak'tika - Fanow",
+ "Il Mheg - Lydha Lran",
+ "Il Mheg - Pia Enni",
+ "Il Mheg - Wolekdorf",
+ "Tempest - Ondo Cups",
+ "Tempest - Macarenses Angle",
+ "Old Sharlayan",
+ "Radz-at-Han",
+ "Labyrinthos - Archeion",
+ "Labyrinthos - Sharlayan Hamlet",
+ "Labyrinthos - Aporia",
+ "Thavnair - Yedlihmad",
+ "Thavnair - Great Work",
+ "Thavnair - Palaka's Stand",
+ "Garlemald - Camp Broken Glass",
+ "Garlemald - Tertium",
+ "Mare Lamentorum - Sinus Lacrimarum",
+ "Mare Lamentorum - Bestways Burrow",
+ "Elpis - Anagnorisis",
+ "Elpis - Twelve Wonders",
+ "Elpis - Poieten Oikos",
+ "Ultima Thule - Reah Tahra",
+ "Ultima Thule - Abode of the Ea",
+ "Ultima Thule - Base Omicron",
+ "Tuliyollal",
+ "Solution Nine",
+ "Urqopacha - Wachunpelo",
+ "Urqopacha - Worlar's Echo",
+ "Kozama'uka - Ok'hanu",
+ "Kozama'uka - Many Fires",
+ "Kozama'uka - Earthenshire",
+ "Yak T'el - Iq Br'aax",
+ "Yak T'el - Mamook",
+ "Shaaloani - Hhusatahwi",
+ "Shaaloani - Sheshenewezi Springs",
+ "Shaaloani - Mehwahhetsoan",
+ "Heritage Found - Yyasulani Station",
+ "Heritage Found - The Outskirts",
+ "Heritage Found - Electrope Strike",
+ "Living Memory - Leynode Mnemo",
+ "Living Memory - Leynode Pyro",
+ "Living Memory - Leynode Aero"
+ ]
+ },
+ "AethernetShard": {
+ "type": "string",
+ "enum": [
+ "[Gridania] Aetheryte Plaza",
+ "[Gridania] Archers' Guild",
+ "[Gridania] Leatherworkers' Guild & Shaded Bower",
+ "[Gridania] Lancers' Guild",
+ "[Gridania] Conjurers' Guild",
+ "[Gridania] Botanists' Guild",
+ "[Gridania] Mih Khetto's Amphitheatre",
+ "[Gridania] Blue Badger Gate (Central Shroud)",
+ "[Gridania] Yellow Serpent Gate (North Shroud)",
+ "[Gridania] White Wolf Gate (Central Shroud)",
+ "[Gridania] Airship Landing",
+ "[Ul'dah] Aetheryte Plaza",
+ "[Ul'dah] Adventurers' Guild",
+ "[Ul'dah] Thaumaturges' Guild",
+ "[Ul'dah] Gladiators' Guild",
+ "[Ul'dah] Miners' Guild",
+ "[Ul'dah] Weavers' Guild",
+ "[Ul'dah] Goldsmiths' Guild",
+ "[Ul'dah] Sapphire Avenue Exchange",
+ "[Ul'dah] Alchemists' Guild",
+ "[Ul'dah] Gate of the Sultana (Western Thanalan)",
+ "[Ul'dah] Gate of Nald (Central Thanalan)",
+ "[Ul'dah] Gate of Thal (Central Thanalan)",
+ "[Ul'dah] The Chamber of Rule",
+ "[Ul'dah] Airship Landing",
+ "[Limsa Lominsa] Aetheryte Plaza",
+ "[Limsa Lominsa] Arcanists' Guild",
+ "[Limsa Lominsa] Fishermens' Guild",
+ "[Limsa Lominsa] Hawkers' Alley",
+ "[Limsa Lominsa] The Aftcastle",
+ "[Limsa Lominsa] Culinarians' Guild",
+ "[Limsa Lominsa] Marauders' Guild",
+ "[Limsa Lominsa] Zephyr Gate (Middle La Noscea)",
+ "[Limsa Lominsa] Tempest Gate (Lower La Noscea)",
+ "[Limsa Lominsa] Airship Landing",
+ "[Ishgard] Aetheryte Plaza",
+ "[Ishgard] The Forgotten Knight",
+ "[Ishgard] Skysteel Manufactory",
+ "[Ishgard] The Brume",
+ "[Ishgard] Athenaeum Astrologicum",
+ "[Ishgard] The Jeweled Crozier",
+ "[Ishgard] Saint Reymanaud's Cathedral",
+ "[Ishgard] The Tribunal",
+ "[Ishgard] The Last Vigil",
+ "[Ishgard] The Gates of Judgement (Coerthas Central Highlands)",
+ "[Idyllshire] Aetheryte Plaza",
+ "[Idyllshire] West Idyllshire",
+ "[Idyllshire] Prologue Gate (Western Hinterlands)",
+ "[Idyllshire] Epilogue Gate (Eastern Hinterlands)",
+ "[Rhalgr's Reach] Aetheryte Plaza",
+ "[Rhalgr's Reach] Western Rhalgr's Reach",
+ "[Rhalgr's Reach] Northeastern Rhalgr's Reach",
+ "[Rhalgr's Reach] Fringes Gate",
+ "[Rhalgr's Reach] Peaks Gate",
+ "[Kugane] Aetheryte Plaza",
+ "[Kugane] Shiokaze Hostelry",
+ "[Kugane] Pier #1",
+ "[Kugane] Thavnairian Consulate",
+ "[Kugane] Kogane Dori Markets",
+ "[Kugane] Bokairo Inn",
+ "[Kugane] The Ruby Bazaar",
+ "[Kugane] Sekiseigumi Barracks",
+ "[Kugane] Rakuza District",
+ "[Kugane] The Ruby Price",
+ "[Kugane] Airship Landing",
+ "[Crystarium] Aetheryte Plaza",
+ "[Crystarium] Musica Universalis Markets",
+ "[Crystarium] Temenos Rookery",
+ "[Crystarium] The Dossal Gate",
+ "[Crystarium] The Pendants",
+ "[Crystarium] The Amaro Launch",
+ "[Crystarium] The Crystalline Mean",
+ "[Crystarium] The Cabinet of Curiosity",
+ "[Crystarium] Tessellation (Lakeland)",
+ "[Eulmore] Aetheryte Plaza",
+ "[Eulmore] Southeast Derelicts",
+ "[Eulmore] Nightsoil Pots",
+ "[Eulmore] The Glory Gate",
+ "[Eulmore] The Mainstay",
+ "[Eulmore] The Path to Glory (Kholusia)",
+ "[Old Sharlayan] Aetheryte Plaza",
+ "[Old Sharlayan] The Studium",
+ "[Old Sharlayan] The Baldesion Annex",
+ "[Old Sharlayan] The Rostra",
+ "[Old Sharlayan] The Leveilleur Estate",
+ "[Old Sharlayan] Journey's End",
+ "[Old Sharlayan] Scholar's Harbor",
+ "[Old Sharlayan] The Hall of Artifice (Labyrinthos)",
+ "[Radz-at-Han] Aetheryte Plaza",
+ "[Radz-at-Han] Meghaduta",
+ "[Radz-at-Han] Ruveydah Fibers",
+ "[Radz-at-Han] Airship Landing",
+ "[Radz-at-Han] Alzadaal's Peace",
+ "[Radz-at-Han] Hall of the Radiant Host",
+ "[Radz-at-Han] Mehryde's Meyhane",
+ "[Radz-at-Han] Kama",
+ "[Radz-at-Han] The High Crucible of Al-Kimiya",
+ "[Radz-at-Han] The Gate of First Sight (Thavnair)",
+ "[Tuliyollal] Aetheryte Plaza",
+ "[Tuliyollal] Dirigible Landing",
+ "[Tuliyollal] The Resplendent Quarter",
+ "[Tuliyollal] The For'ard Cabins",
+ "[Tuliyollal] Bayside Bevy Marketplace",
+ "[Tuliyollal] Vollok Shoonsa",
+ "[Tuliyollal] Wachumeqimeqi",
+ "[Tuliyollal] Brightploom Post",
+ "[Tuliyollal] Arch of the Dawn (Urqopacha)",
+ "[Tuliyollal] Arch of the Dawn (Kozama'uka)",
+ "[Tuliyollal] Ihuykatumu (Kozama'uka)",
+ "[Tuliyollal] Dirigible Landing (Yak T'el)",
+ "[Tuliyollal] Xak Tural Skygate (Shaaloani)",
+ "[Solution Nine] Aetheryte Plaza",
+ "[Solution Nine] Information Center",
+ "[Solution Nine] True Vue",
+ "[Solution Nine] Neon Stein",
+ "[Solution Nine] The Arcadion",
+ "[Solution Nine] Resolution",
+ "[Solution Nine] Nexus Arcade",
+ "[Solution Nine] Residential Sector",
+ "[Solution Nine] Scanning Port Nine (Heritage Found)"
+ ]
+ },
+ "CompletionFlags": {
+ "type": "array",
+ "description": "Quest Variables that dictate whether or not this step is skipped: null is don't check, positive values need to be set, negative values need to be unset",
+ "items": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "High": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "minimum": 0,
+ "maximum": 15
+ },
+ "Low": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "minimum": 0,
+ "maximum": 15
+ },
+ "Negative": {
+ "type": "boolean"
+ },
+ "Mode": {
+ "type": "string",
+ "enum": [
+ "Bitwise",
+ "Exact"
+ ]
+ }
+ }
+ },
+ {
+ "type": "number",
+ "enum": [
+ 1,
+ 2,
+ 4,
+ 8,
+ 16,
+ 32,
+ 64,
+ 128
+ ]
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "minItems": 6,
+ "maxItems": 6
+ }
+ }
+}
diff --git a/Questionable.sln b/Questionable.sln
index a083acfb..b5314287 100644
--- a/Questionable.sln
+++ b/Questionable.sln
@@ -15,6 +15,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Questionable.Model", "Quest
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QuestPathGenerator.Tests", "QuestPathGenerator.Tests\QuestPathGenerator.Tests.csproj", "{4FD6F346-8961-4BD5-BDA2-E5F426DE4FC7}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GatheringPaths", "GatheringPaths\GatheringPaths.csproj", "{8BF98BEF-6F00-4197-91ED-75F8F1C35FFB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GatheringPathRenderer", "GatheringPathRenderer\GatheringPathRenderer.csproj", "{F514DA95-9867-4F3F-8062-ACE0C62E8740}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -45,6 +49,14 @@ Global
{C91EEF13-A1AC-4A40-B695-DD4E378E5989}.Debug|x64.Build.0 = Debug|x64
{C91EEF13-A1AC-4A40-B695-DD4E378E5989}.Release|x64.ActiveCfg = Release|x64
{C91EEF13-A1AC-4A40-B695-DD4E378E5989}.Release|x64.Build.0 = Release|x64
+ {8BF98BEF-6F00-4197-91ED-75F8F1C35FFB}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {8BF98BEF-6F00-4197-91ED-75F8F1C35FFB}.Debug|x64.Build.0 = Debug|Any CPU
+ {8BF98BEF-6F00-4197-91ED-75F8F1C35FFB}.Release|x64.ActiveCfg = Release|Any CPU
+ {8BF98BEF-6F00-4197-91ED-75F8F1C35FFB}.Release|x64.Build.0 = Release|Any CPU
+ {F514DA95-9867-4F3F-8062-ACE0C62E8740}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {F514DA95-9867-4F3F-8062-ACE0C62E8740}.Debug|x64.Build.0 = Debug|Any CPU
+ {F514DA95-9867-4F3F-8062-ACE0C62E8740}.Release|x64.ActiveCfg = Release|Any CPU
+ {F514DA95-9867-4F3F-8062-ACE0C62E8740}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Questionable/ChatFunctions.cs b/Questionable/ChatFunctions.cs
index 26ca9a22..d28946a8 100644
--- a/Questionable/ChatFunctions.cs
+++ b/Questionable/ChatFunctions.cs
@@ -14,7 +14,7 @@ using FFXIVClientStructs.FFXIV.Client.System.Memory;
using FFXIVClientStructs.FFXIV.Client.System.String;
using Lumina.Excel.GeneratedSheets;
using Microsoft.Extensions.Logging;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable;
diff --git a/Questionable/Controller/CombatController.cs b/Questionable/Controller/CombatController.cs
index f747966e..1f95e9da 100644
--- a/Questionable/Controller/CombatController.cs
+++ b/Questionable/Controller/CombatController.cs
@@ -14,7 +14,7 @@ using FFXIVClientStructs.FFXIV.Common.Math;
using Microsoft.Extensions.Logging;
using Questionable.Controller.CombatModules;
using Questionable.Controller.Utils;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Controller;
diff --git a/Questionable/Controller/GameUiController.cs b/Questionable/Controller/GameUiController.cs
index 0bb4e12b..61d31fbd 100644
--- a/Questionable/Controller/GameUiController.cs
+++ b/Questionable/Controller/GameUiController.cs
@@ -14,7 +14,7 @@ using LLib.GameUI;
using Lumina.Excel.GeneratedSheets;
using Microsoft.Extensions.Logging;
using Questionable.Data;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
using Quest = Questionable.Model.Quest;
using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType;
diff --git a/Questionable/Controller/MovementController.cs b/Questionable/Controller/MovementController.cs
index 1db1d5cf..d7fc74a9 100644
--- a/Questionable/Controller/MovementController.cs
+++ b/Questionable/Controller/MovementController.cs
@@ -18,8 +18,10 @@ using Microsoft.Extensions.Logging;
using Questionable.Controller.NavigationOverrides;
using Questionable.External;
using Questionable.Model;
-using Questionable.Model.V1;
-using Questionable.Model.V1.Converter;
+using Questionable.Model.Common;
+using Questionable.Model.Common.Converter;
+using Questionable.Model.Questing;
+using Questionable.Model.Questing.Converter;
namespace Questionable.Controller;
diff --git a/Questionable/Controller/QuestController.cs b/Questionable/Controller/QuestController.cs
index c92fee2b..e50891d2 100644
--- a/Questionable/Controller/QuestController.cs
+++ b/Questionable/Controller/QuestController.cs
@@ -10,7 +10,7 @@ using Questionable.Controller.Steps;
using Questionable.Controller.Steps.Shared;
using Questionable.External;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Controller;
diff --git a/Questionable/Controller/QuestRegistry.cs b/Questionable/Controller/QuestRegistry.cs
index 71750a1c..f472c115 100644
--- a/Questionable/Controller/QuestRegistry.cs
+++ b/Questionable/Controller/QuestRegistry.cs
@@ -11,7 +11,7 @@ using Dalamud.Plugin;
using Microsoft.Extensions.Logging;
using Questionable.Data;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
using Questionable.QuestPaths;
using Questionable.Validation;
using Questionable.Validation.Validators;
diff --git a/Questionable/Controller/Steps/Common/NextQuest.cs b/Questionable/Controller/Steps/Common/NextQuest.cs
index 30a705e6..dddc8f9d 100644
--- a/Questionable/Controller/Steps/Common/NextQuest.cs
+++ b/Questionable/Controller/Steps/Common/NextQuest.cs
@@ -2,7 +2,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Controller.Steps.Common;
diff --git a/Questionable/Controller/Steps/ITaskFactory.cs b/Questionable/Controller/Steps/ITaskFactory.cs
index 159d5c12..287f029f 100644
--- a/Questionable/Controller/Steps/ITaskFactory.cs
+++ b/Questionable/Controller/Steps/ITaskFactory.cs
@@ -1,6 +1,6 @@
using System.Collections.Generic;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Controller.Steps;
diff --git a/Questionable/Controller/Steps/Interactions/Action.cs b/Questionable/Controller/Steps/Interactions/Action.cs
index 94125e43..000811ca 100644
--- a/Questionable/Controller/Steps/Interactions/Action.cs
+++ b/Questionable/Controller/Steps/Interactions/Action.cs
@@ -7,7 +7,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Questionable.Controller.Steps.Common;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Controller.Steps.Interactions;
diff --git a/Questionable/Controller/Steps/Interactions/AetherCurrent.cs b/Questionable/Controller/Steps/Interactions/AetherCurrent.cs
index 82b13d27..3ae2c4b3 100644
--- a/Questionable/Controller/Steps/Interactions/AetherCurrent.cs
+++ b/Questionable/Controller/Steps/Interactions/AetherCurrent.cs
@@ -4,7 +4,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Questionable.Data;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Controller.Steps.Interactions;
diff --git a/Questionable/Controller/Steps/Interactions/AethernetShard.cs b/Questionable/Controller/Steps/Interactions/AethernetShard.cs
index 87a4f348..b3219a6e 100644
--- a/Questionable/Controller/Steps/Interactions/AethernetShard.cs
+++ b/Questionable/Controller/Steps/Interactions/AethernetShard.cs
@@ -1,9 +1,9 @@
using System;
-using FFXIVClientStructs.FFXIV.Client.Game.Object;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Common;
+using Questionable.Model.Questing;
using ObjectKind = Dalamud.Game.ClientState.Objects.Enums.ObjectKind;
namespace Questionable.Controller.Steps.Interactions;
diff --git a/Questionable/Controller/Steps/Interactions/Aetheryte.cs b/Questionable/Controller/Steps/Interactions/Aetheryte.cs
index a6bccc4c..c2cab7df 100644
--- a/Questionable/Controller/Steps/Interactions/Aetheryte.cs
+++ b/Questionable/Controller/Steps/Interactions/Aetheryte.cs
@@ -2,7 +2,8 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Common;
+using Questionable.Model.Questing;
namespace Questionable.Controller.Steps.Interactions;
diff --git a/Questionable/Controller/Steps/Interactions/Combat.cs b/Questionable/Controller/Steps/Interactions/Combat.cs
index 97201b46..2d7de402 100644
--- a/Questionable/Controller/Steps/Interactions/Combat.cs
+++ b/Questionable/Controller/Steps/Interactions/Combat.cs
@@ -6,7 +6,7 @@ using Questionable.Controller.Steps.Common;
using Questionable.Controller.Steps.Shared;
using Questionable.Controller.Utils;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Controller.Steps.Interactions;
diff --git a/Questionable/Controller/Steps/Interactions/Dive.cs b/Questionable/Controller/Steps/Interactions/Dive.cs
index 05e9cf44..3976eb73 100644
--- a/Questionable/Controller/Steps/Interactions/Dive.cs
+++ b/Questionable/Controller/Steps/Interactions/Dive.cs
@@ -12,7 +12,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Questionable.Controller.Steps.Common;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Controller.Steps.Interactions;
diff --git a/Questionable/Controller/Steps/Interactions/Duty.cs b/Questionable/Controller/Steps/Interactions/Duty.cs
index a7de058c..ab2afdcd 100644
--- a/Questionable/Controller/Steps/Interactions/Duty.cs
+++ b/Questionable/Controller/Steps/Interactions/Duty.cs
@@ -3,7 +3,7 @@ using Dalamud.Game.ClientState.Conditions;
using Dalamud.Plugin.Services;
using Microsoft.Extensions.DependencyInjection;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Controller.Steps.Interactions;
diff --git a/Questionable/Controller/Steps/Interactions/Emote.cs b/Questionable/Controller/Steps/Interactions/Emote.cs
index 44478475..0a5e9064 100644
--- a/Questionable/Controller/Steps/Interactions/Emote.cs
+++ b/Questionable/Controller/Steps/Interactions/Emote.cs
@@ -3,7 +3,7 @@ using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Questionable.Controller.Steps.Common;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Controller.Steps.Interactions;
diff --git a/Questionable/Controller/Steps/Interactions/EquipItem.cs b/Questionable/Controller/Steps/Interactions/EquipItem.cs
index 9322563d..95aad266 100644
--- a/Questionable/Controller/Steps/Interactions/EquipItem.cs
+++ b/Questionable/Controller/Steps/Interactions/EquipItem.cs
@@ -6,7 +6,7 @@ using FFXIVClientStructs.FFXIV.Client.Game;
using Lumina.Excel.GeneratedSheets;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
using Quest = Questionable.Model.Quest;
namespace Questionable.Controller.Steps.Interactions;
diff --git a/Questionable/Controller/Steps/Interactions/Interact.cs b/Questionable/Controller/Steps/Interactions/Interact.cs
index f49394de..7dba0d44 100644
--- a/Questionable/Controller/Steps/Interactions/Interact.cs
+++ b/Questionable/Controller/Steps/Interactions/Interact.cs
@@ -8,7 +8,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Questionable.Controller.Steps.Shared;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Controller.Steps.Interactions;
diff --git a/Questionable/Controller/Steps/Interactions/Jump.cs b/Questionable/Controller/Steps/Interactions/Jump.cs
index 5c3d9add..0b0b099d 100644
--- a/Questionable/Controller/Steps/Interactions/Jump.cs
+++ b/Questionable/Controller/Steps/Interactions/Jump.cs
@@ -5,7 +5,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Questionable.Controller.Steps.Common;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Controller.Steps.Interactions;
diff --git a/Questionable/Controller/Steps/Interactions/Say.cs b/Questionable/Controller/Steps/Interactions/Say.cs
index c833badc..20fc7f67 100644
--- a/Questionable/Controller/Steps/Interactions/Say.cs
+++ b/Questionable/Controller/Steps/Interactions/Say.cs
@@ -3,7 +3,7 @@ using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Questionable.Controller.Steps.Common;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Controller.Steps.Interactions;
diff --git a/Questionable/Controller/Steps/Interactions/SinglePlayerDuty.cs b/Questionable/Controller/Steps/Interactions/SinglePlayerDuty.cs
index f7d5172a..648627c1 100644
--- a/Questionable/Controller/Steps/Interactions/SinglePlayerDuty.cs
+++ b/Questionable/Controller/Steps/Interactions/SinglePlayerDuty.cs
@@ -4,7 +4,7 @@ using Dalamud.Plugin.Services;
using Microsoft.Extensions.DependencyInjection;
using Questionable.External;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Controller.Steps.Interactions;
diff --git a/Questionable/Controller/Steps/Interactions/UseItem.cs b/Questionable/Controller/Steps/Interactions/UseItem.cs
index 3e1212f8..e17f005e 100644
--- a/Questionable/Controller/Steps/Interactions/UseItem.cs
+++ b/Questionable/Controller/Steps/Interactions/UseItem.cs
@@ -13,7 +13,8 @@ using Questionable.Controller.Steps.Shared;
using Questionable.Controller.Utils;
using Questionable.Data;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Common;
+using Questionable.Model.Questing;
using AethernetShortcut = Questionable.Controller.Steps.Shared.AethernetShortcut;
namespace Questionable.Controller.Steps.Interactions;
diff --git a/Questionable/Controller/Steps/Shared/AethernetShortcut.cs b/Questionable/Controller/Steps/Shared/AethernetShortcut.cs
index df7f5788..a66e7c0f 100644
--- a/Questionable/Controller/Steps/Shared/AethernetShortcut.cs
+++ b/Questionable/Controller/Steps/Shared/AethernetShortcut.cs
@@ -8,8 +8,10 @@ using Microsoft.Extensions.Logging;
using Questionable.Data;
using Questionable.External;
using Questionable.Model;
-using Questionable.Model.V1;
-using Questionable.Model.V1.Converter;
+using Questionable.Model.Common;
+using Questionable.Model.Common.Converter;
+using Questionable.Model.Questing;
+using Questionable.Model.Questing.Converter;
namespace Questionable.Controller.Steps.Shared;
diff --git a/Questionable/Controller/Steps/Shared/AetheryteShortcut.cs b/Questionable/Controller/Steps/Shared/AetheryteShortcut.cs
index 413dd37a..ed8d1c07 100644
--- a/Questionable/Controller/Steps/Shared/AetheryteShortcut.cs
+++ b/Questionable/Controller/Steps/Shared/AetheryteShortcut.cs
@@ -7,7 +7,8 @@ using Microsoft.Extensions.Logging;
using Questionable.Controller.Steps.Common;
using Questionable.Data;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Common;
+using Questionable.Model.Questing;
namespace Questionable.Controller.Steps.Shared;
diff --git a/Questionable/Controller/Steps/Shared/Move.cs b/Questionable/Controller/Steps/Shared/Move.cs
index e7474688..24d3e7f8 100644
--- a/Questionable/Controller/Steps/Shared/Move.cs
+++ b/Questionable/Controller/Steps/Shared/Move.cs
@@ -13,7 +13,7 @@ using Questionable.Controller.NavigationOverrides;
using Questionable.Controller.Steps.Common;
using Questionable.Data;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Controller.Steps.Shared;
diff --git a/Questionable/Controller/Steps/Shared/SkipCondition.cs b/Questionable/Controller/Steps/Shared/SkipCondition.cs
index 2f768ecd..5d50ba18 100644
--- a/Questionable/Controller/Steps/Shared/SkipCondition.cs
+++ b/Questionable/Controller/Steps/Shared/SkipCondition.cs
@@ -11,7 +11,8 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Questionable.Controller.Utils;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Common;
+using Questionable.Model.Questing;
namespace Questionable.Controller.Steps.Shared;
diff --git a/Questionable/Controller/Steps/Shared/StepDisabled.cs b/Questionable/Controller/Steps/Shared/StepDisabled.cs
index 16bb8365..609f3143 100644
--- a/Questionable/Controller/Steps/Shared/StepDisabled.cs
+++ b/Questionable/Controller/Steps/Shared/StepDisabled.cs
@@ -2,7 +2,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Controller.Steps.Shared;
diff --git a/Questionable/Controller/Steps/Shared/WaitAtEnd.cs b/Questionable/Controller/Steps/Shared/WaitAtEnd.cs
index 0d44663c..6d54623e 100644
--- a/Questionable/Controller/Steps/Shared/WaitAtEnd.cs
+++ b/Questionable/Controller/Steps/Shared/WaitAtEnd.cs
@@ -12,7 +12,7 @@ using Questionable.Controller.Steps.Common;
using Questionable.Controller.Utils;
using Questionable.Data;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Controller.Steps.Shared;
diff --git a/Questionable/Controller/Steps/Shared/WaitAtStart.cs b/Questionable/Controller/Steps/Shared/WaitAtStart.cs
index 4a1f411e..b39e301d 100644
--- a/Questionable/Controller/Steps/Shared/WaitAtStart.cs
+++ b/Questionable/Controller/Steps/Shared/WaitAtStart.cs
@@ -2,7 +2,7 @@
using Microsoft.Extensions.DependencyInjection;
using Questionable.Controller.Steps.Common;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Controller.Steps.Shared;
diff --git a/Questionable/Controller/Utils/QuestWorkUtils.cs b/Questionable/Controller/Utils/QuestWorkUtils.cs
index 6bb77180..59235918 100644
--- a/Questionable/Controller/Utils/QuestWorkUtils.cs
+++ b/Questionable/Controller/Utils/QuestWorkUtils.cs
@@ -4,7 +4,7 @@ using System.Linq;
using FFXIVClientStructs.FFXIV.Application.Network.WorkDefinitions;
using Microsoft.Extensions.Logging;
using Questionable.Controller.Steps.Shared;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Controller.Utils;
diff --git a/Questionable/Data/AetheryteData.cs b/Questionable/Data/AetheryteData.cs
index 9e216cdc..28d8e459 100644
--- a/Questionable/Data/AetheryteData.cs
+++ b/Questionable/Data/AetheryteData.cs
@@ -4,8 +4,7 @@ using System.Linq;
using System.Numerics;
using Dalamud.Plugin.Services;
using Lumina.Excel.GeneratedSheets;
-using Microsoft.Extensions.Logging;
-using Questionable.Model.V1;
+using Questionable.Model.Common;
namespace Questionable.Data;
diff --git a/Questionable/External/LifestreamIpc.cs b/Questionable/External/LifestreamIpc.cs
index deab3a24..f3267709 100644
--- a/Questionable/External/LifestreamIpc.cs
+++ b/Questionable/External/LifestreamIpc.cs
@@ -1,7 +1,7 @@
using Dalamud.Plugin;
using Dalamud.Plugin.Ipc;
using Questionable.Data;
-using Questionable.Model.V1;
+using Questionable.Model.Common;
namespace Questionable.External;
diff --git a/Questionable/GameFunctions.cs b/Questionable/GameFunctions.cs
index 6487eb98..724f2f11 100644
--- a/Questionable/GameFunctions.cs
+++ b/Questionable/GameFunctions.cs
@@ -24,7 +24,8 @@ using Microsoft.Extensions.Logging;
using Questionable.Controller;
using Questionable.Data;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Common;
+using Questionable.Model.Questing;
using Action = Lumina.Excel.GeneratedSheets2.Action;
using BattleChara = FFXIVClientStructs.FFXIV.Client.Game.Character.BattleChara;
using ContentFinderCondition = Lumina.Excel.GeneratedSheets.ContentFinderCondition;
diff --git a/Questionable/Model/Quest.cs b/Questionable/Model/Quest.cs
index a33bcd18..5124de9d 100644
--- a/Questionable/Model/Quest.cs
+++ b/Questionable/Model/Quest.cs
@@ -1,6 +1,6 @@
using System.Collections.Generic;
using System.Linq;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Model;
diff --git a/Questionable/Validation/Validators/AethernetShortcutValidator.cs b/Questionable/Validation/Validators/AethernetShortcutValidator.cs
index 36643c3e..e620d8a5 100644
--- a/Questionable/Validation/Validators/AethernetShortcutValidator.cs
+++ b/Questionable/Validation/Validators/AethernetShortcutValidator.cs
@@ -2,7 +2,7 @@
using System.Linq;
using Questionable.Data;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Validation.Validators;
diff --git a/Questionable/Validation/Validators/BasicSequenceValidator.cs b/Questionable/Validation/Validators/BasicSequenceValidator.cs
index 0c10e032..0127bc19 100644
--- a/Questionable/Validation/Validators/BasicSequenceValidator.cs
+++ b/Questionable/Validation/Validators/BasicSequenceValidator.cs
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Validation.Validators;
diff --git a/Questionable/Validation/Validators/CompletionFlagsValidator.cs b/Questionable/Validation/Validators/CompletionFlagsValidator.cs
index 1d36c8c4..2cfc58d7 100644
--- a/Questionable/Validation/Validators/CompletionFlagsValidator.cs
+++ b/Questionable/Validation/Validators/CompletionFlagsValidator.cs
@@ -3,7 +3,7 @@ using System.Linq;
using System.Numerics;
using Questionable.Controller.Utils;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Validation.Validators;
diff --git a/Questionable/Validation/Validators/JsonSchemaValidator.cs b/Questionable/Validation/Validators/JsonSchemaValidator.cs
index b3ed6f4e..7cacc520 100644
--- a/Questionable/Validation/Validators/JsonSchemaValidator.cs
+++ b/Questionable/Validation/Validators/JsonSchemaValidator.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Text.Json.Nodes;
using Json.Schema;
@@ -12,6 +13,13 @@ internal sealed class JsonSchemaValidator : IQuestValidator
private readonly Dictionary _questNodes = new();
private JsonSchema? _questSchema;
+ public JsonSchemaValidator()
+ {
+ SchemaRegistry.Global.Register(
+ new Uri("https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json"),
+ JsonSchema.FromStream(AssemblyModelLoader.CommonSchema).AsTask().Result);
+ }
+
public IEnumerable Validate(Quest quest)
{
_questSchema ??= JsonSchema.FromStream(AssemblyQuestLoader.QuestSchema).AsTask().Result;
@@ -36,7 +44,6 @@ internal sealed class JsonSchemaValidator : IQuestValidator
};
}
}
-
}
public void Enqueue(ushort questId, JsonNode questNode) => _questNodes[questId] = questNode;
diff --git a/Questionable/Validation/Validators/UniqueStartStopValidator.cs b/Questionable/Validation/Validators/UniqueStartStopValidator.cs
index b95522f1..b385306d 100644
--- a/Questionable/Validation/Validators/UniqueStartStopValidator.cs
+++ b/Questionable/Validation/Validators/UniqueStartStopValidator.cs
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Validation.Validators;
diff --git a/Questionable/Windows/DebugOverlay.cs b/Questionable/Windows/DebugOverlay.cs
index 20b572fe..e7cc34e7 100644
--- a/Questionable/Windows/DebugOverlay.cs
+++ b/Questionable/Windows/DebugOverlay.cs
@@ -11,7 +11,7 @@ using ImGuiNET;
using Questionable.Controller;
using Questionable.Data;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Windows;
diff --git a/Questionable/Windows/QuestComponents/ActiveQuestComponent.cs b/Questionable/Windows/QuestComponents/ActiveQuestComponent.cs
index f819526a..14b628d3 100644
--- a/Questionable/Windows/QuestComponents/ActiveQuestComponent.cs
+++ b/Questionable/Windows/QuestComponents/ActiveQuestComponent.cs
@@ -13,7 +13,7 @@ using FFXIVClientStructs.FFXIV.Application.Network.WorkDefinitions;
using ImGuiNET;
using Questionable.Controller;
using Questionable.Controller.Steps.Shared;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
namespace Questionable.Windows.QuestComponents;
diff --git a/Questionable/Windows/QuestComponents/CreationUtilsComponent.cs b/Questionable/Windows/QuestComponents/CreationUtilsComponent.cs
index a1fac0a4..b824f1af 100644
--- a/Questionable/Windows/QuestComponents/CreationUtilsComponent.cs
+++ b/Questionable/Windows/QuestComponents/CreationUtilsComponent.cs
@@ -16,7 +16,8 @@ using Microsoft.Extensions.Logging;
using Questionable.Controller;
using Questionable.Data;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Common;
+using Questionable.Model.Questing;
using ObjectKind = Dalamud.Game.ClientState.Objects.Enums.ObjectKind;
namespace Questionable.Windows.QuestComponents;
@@ -160,23 +161,38 @@ internal sealed class CreationUtilsComponent
"Left click: Copy target position as JSON.\nRight click: Copy target position as C# code.");
if (copy)
{
- string interactionType = gameObject->NamePlateIconId switch
+ var target = _targetManager.Target;
+ if (target.ObjectKind == ObjectKind.GatheringPoint)
{
- 71201 or 71211 or 71221 or 71231 or 71341 or 71351 => "AcceptQuest",
- 71202 or 71212 or 71222 or 71232 or 71342 or 71352 => "AcceptQuest", // repeatable
- 71205 or 71215 or 71225 or 71235 or 71345 or 71355 => "CompleteQuest",
- _ => "Interact",
- };
- ImGui.SetClipboardText($$"""
- "DataId": {{_targetManager.Target.DataId}},
- "Position": {
- "X": {{_targetManager.Target.Position.X.ToString(CultureInfo.InvariantCulture)}},
- "Y": {{_targetManager.Target.Position.Y.ToString(CultureInfo.InvariantCulture)}},
- "Z": {{_targetManager.Target.Position.Z.ToString(CultureInfo.InvariantCulture)}}
- },
- "TerritoryId": {{_clientState.TerritoryType}},
- "InteractionType": "{{interactionType}}"
- """);
+ ImGui.SetClipboardText($$"""
+ "DataId": {{target.DataId}},
+ "Position": {
+ "X": {{target.Position.X.ToString(CultureInfo.InvariantCulture)}},
+ "Y": {{target.Position.Y.ToString(CultureInfo.InvariantCulture)}},
+ "Z": {{target.Position.Z.ToString(CultureInfo.InvariantCulture)}}
+ }
+ """);
+ }
+ else
+ {
+ string interactionType = gameObject->NamePlateIconId switch
+ {
+ 71201 or 71211 or 71221 or 71231 or 71341 or 71351 => "AcceptQuest",
+ 71202 or 71212 or 71222 or 71232 or 71342 or 71352 => "AcceptQuest", // repeatable
+ 71205 or 71215 or 71225 or 71235 or 71345 or 71355 => "CompleteQuest",
+ _ => "Interact",
+ };
+ ImGui.SetClipboardText($$"""
+ "DataId": {{target.DataId}},
+ "Position": {
+ "X": {{target.Position.X.ToString(CultureInfo.InvariantCulture)}},
+ "Y": {{target.Position.Y.ToString(CultureInfo.InvariantCulture)}},
+ "Z": {{target.Position.Z.ToString(CultureInfo.InvariantCulture)}}
+ },
+ "TerritoryId": {{_clientState.TerritoryType}},
+ "InteractionType": "{{interactionType}}"
+ """);
+ }
}
else if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
{
diff --git a/Questionable/Windows/QuestSelectionWindow.cs b/Questionable/Windows/QuestSelectionWindow.cs
index 6f420786..8da2c2d0 100644
--- a/Questionable/Windows/QuestSelectionWindow.cs
+++ b/Questionable/Windows/QuestSelectionWindow.cs
@@ -19,7 +19,7 @@ using LLib.ImGui;
using Questionable.Controller;
using Questionable.Data;
using Questionable.Model;
-using Questionable.Model.V1;
+using Questionable.Model.Questing;
using Questionable.Windows.QuestComponents;
namespace Questionable.Windows;