diff --git a/GatheringPaths/GatheringPaths.csproj b/GatheringPaths/GatheringPaths.csproj index f9e9725..eca2d02 100644 --- a/GatheringPaths/GatheringPaths.csproj +++ b/GatheringPaths/GatheringPaths.csproj @@ -24,6 +24,7 @@ + diff --git a/QuestPathGenerator/GatheringSourceGenerator.cs b/QuestPathGenerator/GatheringSourceGenerator.cs index 1a341ed..cf1dd6f 100644 --- a/QuestPathGenerator/GatheringSourceGenerator.cs +++ b/QuestPathGenerator/GatheringSourceGenerator.cs @@ -42,9 +42,10 @@ public class GatheringSourceGenerator : ISourceGenerator private void GenerateGatheringSource(GeneratorExecutionContext context, AdditionalText jsonSchemaFile) { var gatheringSchema = JsonSchema.FromText(jsonSchemaFile.GetText()!.ToString()); + var jsonSchemaFiles = Utils.RegisterSchemas(context); List<(ushort, GatheringRoot)> gatheringLocations = []; - foreach (var (id, node) in Utils.GetAdditionalFiles(context, jsonSchemaFile, gatheringSchema, InvalidJson, + foreach (var (id, node) in Utils.GetAdditionalFiles(context, jsonSchemaFiles, gatheringSchema, InvalidJson, ushort.Parse)) { var gatheringLocation = node.Deserialize()!; @@ -88,6 +89,12 @@ public class GatheringSourceGenerator : ISourceGenerator IdentifierName("Questionable"), IdentifierName("Model")), IdentifierName("Gathering"))), + UsingDirective( + QualifiedName( + QualifiedName( + IdentifierName("Questionable"), + IdentifierName("Model")), + IdentifierName("Questing"))), UsingDirective( QualifiedName( QualifiedName( diff --git a/QuestPathGenerator/QuestSourceGenerator.cs b/QuestPathGenerator/QuestSourceGenerator.cs index 06ce85a..bcf960f 100644 --- a/QuestPathGenerator/QuestSourceGenerator.cs +++ b/QuestPathGenerator/QuestSourceGenerator.cs @@ -46,9 +46,10 @@ public class QuestSourceGenerator : ISourceGenerator private void GenerateQuestSource(GeneratorExecutionContext context, AdditionalText jsonSchemaFile) { var questSchema = JsonSchema.FromText(jsonSchemaFile.GetText()!.ToString()); + var jsonSchemaFiles = Utils.RegisterSchemas(context); List<(ElementId, QuestRoot)> quests = []; - foreach (var (id, node) in Utils.GetAdditionalFiles(context, jsonSchemaFile, questSchema, InvalidJson, + foreach (var (id, node) in Utils.GetAdditionalFiles(context, jsonSchemaFiles, questSchema, InvalidJson, ElementId.FromString)) { var quest = node.Deserialize()!; @@ -195,140 +196,7 @@ public class QuestSourceGenerator : ISourceGenerator .AsSyntaxNodeOrToken(), Assignment(nameof(QuestSequence.Comment), sequence.Comment, null) .AsSyntaxNodeOrToken(), - AssignmentExpression( - SyntaxKind.SimpleAssignmentExpression, - IdentifierName(nameof(QuestSequence.Steps)), - CreateQuestSteps(sequence.Steps))))))), - Token(SyntaxKind.CommaToken), - }.ToArray()))); - } - - private static ExpressionSyntax CreateQuestSteps(List steps) - { - QuestStep emptyStep = new(); - return CollectionExpression( - SeparatedList( - steps.SelectMany(step => new SyntaxNodeOrToken[] - { - ExpressionElement( - ObjectCreationExpression( - IdentifierName(nameof(QuestStep))) - .WithArgumentList( - ArgumentList( - SeparatedList( - new SyntaxNodeOrToken[] - { - Argument(LiteralValue(step.InteractionType)), - Token(SyntaxKind.CommaToken), - Argument(LiteralValue(step.DataId)), - Token(SyntaxKind.CommaToken), - Argument(LiteralValue(step.Position)), - Token(SyntaxKind.CommaToken), - Argument(LiteralValue(step.TerritoryId)) - }))) - .WithInitializer( - InitializerExpression( - SyntaxKind.ObjectInitializerExpression, - SeparatedList( - SyntaxNodeList( - Assignment(nameof(QuestStep.StopDistance), step.StopDistance, - emptyStep.StopDistance) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.NpcWaitDistance), step.NpcWaitDistance, - emptyStep.NpcWaitDistance) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.TargetTerritoryId), step.TargetTerritoryId, - emptyStep.TargetTerritoryId) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.DelaySecondsAtStart), step.DelaySecondsAtStart, - emptyStep.DelaySecondsAtStart) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.Disabled), step.Disabled, emptyStep.Disabled) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.DisableNavmesh), step.DisableNavmesh, - emptyStep.DisableNavmesh) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.Mount), step.Mount, emptyStep.Mount) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.Fly), step.Fly, emptyStep.Fly) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.Land), step.Land, emptyStep.Land) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.Sprint), step.Sprint, emptyStep.Sprint) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.IgnoreDistanceToObject), - step.IgnoreDistanceToObject, emptyStep.IgnoreDistanceToObject) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.Comment), step.Comment, emptyStep.Comment) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.Aetheryte), step.Aetheryte, emptyStep.Aetheryte) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.AethernetShard), step.AethernetShard, - emptyStep.AethernetShard) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.AetheryteShortcut), step.AetheryteShortcut, - emptyStep.AetheryteShortcut) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.AethernetShortcut), step.AethernetShortcut, - emptyStep.AethernetShortcut) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.AetherCurrentId), step.AetherCurrentId, - emptyStep.AetherCurrentId) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.ItemId), step.ItemId, emptyStep.ItemId) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.GroundTarget), step.GroundTarget, - emptyStep.GroundTarget) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.ItemCount), step.ItemCount, emptyStep.ItemCount) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.Emote), step.Emote, emptyStep.Emote) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.ChatMessage), step.ChatMessage, - emptyStep.ChatMessage) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.Action), step.Action, emptyStep.Action) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.EnemySpawnType), step.EnemySpawnType, - emptyStep.EnemySpawnType) - .AsSyntaxNodeOrToken(), - AssignmentList(nameof(QuestStep.KillEnemyDataIds), step.KillEnemyDataIds) - .AsSyntaxNodeOrToken(), - AssignmentList(nameof(QuestStep.ComplexCombatData), step.ComplexCombatData) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.CombatDelaySecondsAtStart), - step.CombatDelaySecondsAtStart, - emptyStep.CombatDelaySecondsAtStart) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.JumpDestination), step.JumpDestination, - emptyStep.JumpDestination) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.ContentFinderConditionId), - step.ContentFinderConditionId, emptyStep.ContentFinderConditionId) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.SkipConditions), step.SkipConditions, - emptyStep.SkipConditions) - .AsSyntaxNodeOrToken(), - AssignmentList(nameof(QuestStep.RequiredQuestVariables), - step.RequiredQuestVariables) - .AsSyntaxNodeOrToken(), - AssignmentList(nameof(QuestStep.RequiredGatheredItems), - step.RequiredGatheredItems), - AssignmentList(nameof(QuestStep.CompletionQuestVariablesFlags), - step.CompletionQuestVariablesFlags) - .AsSyntaxNodeOrToken(), - AssignmentList(nameof(QuestStep.DialogueChoices), step.DialogueChoices) - .AsSyntaxNodeOrToken(), - AssignmentList(nameof(QuestStep.PointMenuChoices), step.PointMenuChoices) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.PickUpQuestId), step.PickUpQuestId, - emptyStep.PickUpQuestId) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.TurnInQuestId), step.TurnInQuestId, - emptyStep.TurnInQuestId) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.NextQuestId), step.NextQuestId, - emptyStep.NextQuestId) + AssignmentList(nameof(QuestSequence.Steps), sequence.Steps) .AsSyntaxNodeOrToken()))))), Token(SyntaxKind.CommaToken), }.ToArray()))); diff --git a/QuestPathGenerator/RoslynShortcuts.cs b/QuestPathGenerator/RoslynShortcuts.cs index 940e243..3d251f2 100644 --- a/QuestPathGenerator/RoslynShortcuts.cs +++ b/QuestPathGenerator/RoslynShortcuts.cs @@ -56,6 +56,129 @@ public static class RoslynShortcuts SyntaxKind.SimpleMemberAccessExpression, IdentifierName(value.GetType().Name), IdentifierName(value.GetType().GetEnumName(value)!)); + else if (value is QuestStep step) + { + var emptyStep = new QuestStep(); + return ObjectCreationExpression( + IdentifierName(nameof(QuestStep))) + .WithArgumentList( + ArgumentList( + SeparatedList( + new SyntaxNodeOrToken[] + { + Argument(LiteralValue(step.InteractionType)), + Token(SyntaxKind.CommaToken), + Argument(LiteralValue(step.DataId)), + Token(SyntaxKind.CommaToken), + Argument(LiteralValue(step.Position)), + Token(SyntaxKind.CommaToken), + Argument(LiteralValue(step.TerritoryId)) + }))) + .WithInitializer( + InitializerExpression( + SyntaxKind.ObjectInitializerExpression, + SeparatedList( + SyntaxNodeList( + Assignment(nameof(QuestStep.StopDistance), step.StopDistance, + emptyStep.StopDistance) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.NpcWaitDistance), step.NpcWaitDistance, + emptyStep.NpcWaitDistance) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.TargetTerritoryId), step.TargetTerritoryId, + emptyStep.TargetTerritoryId) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.DelaySecondsAtStart), step.DelaySecondsAtStart, + emptyStep.DelaySecondsAtStart) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.Disabled), step.Disabled, emptyStep.Disabled) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.DisableNavmesh), step.DisableNavmesh, + emptyStep.DisableNavmesh) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.Mount), step.Mount, emptyStep.Mount) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.Fly), step.Fly, emptyStep.Fly) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.Land), step.Land, emptyStep.Land) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.Sprint), step.Sprint, emptyStep.Sprint) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.IgnoreDistanceToObject), + step.IgnoreDistanceToObject, emptyStep.IgnoreDistanceToObject) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.Comment), step.Comment, emptyStep.Comment) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.Aetheryte), step.Aetheryte, emptyStep.Aetheryte) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.AethernetShard), step.AethernetShard, + emptyStep.AethernetShard) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.AetheryteShortcut), step.AetheryteShortcut, + emptyStep.AetheryteShortcut) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.AethernetShortcut), step.AethernetShortcut, + emptyStep.AethernetShortcut) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.AetherCurrentId), step.AetherCurrentId, + emptyStep.AetherCurrentId) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.ItemId), step.ItemId, emptyStep.ItemId) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.GroundTarget), step.GroundTarget, + emptyStep.GroundTarget) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.ItemCount), step.ItemCount, emptyStep.ItemCount) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.Emote), step.Emote, emptyStep.Emote) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.ChatMessage), step.ChatMessage, + emptyStep.ChatMessage) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.Action), step.Action, emptyStep.Action) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.EnemySpawnType), step.EnemySpawnType, + emptyStep.EnemySpawnType) + .AsSyntaxNodeOrToken(), + AssignmentList(nameof(QuestStep.KillEnemyDataIds), step.KillEnemyDataIds) + .AsSyntaxNodeOrToken(), + AssignmentList(nameof(QuestStep.ComplexCombatData), step.ComplexCombatData) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.CombatDelaySecondsAtStart), + step.CombatDelaySecondsAtStart, + emptyStep.CombatDelaySecondsAtStart) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.JumpDestination), step.JumpDestination, + emptyStep.JumpDestination) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.ContentFinderConditionId), + step.ContentFinderConditionId, emptyStep.ContentFinderConditionId) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.SkipConditions), step.SkipConditions, + emptyStep.SkipConditions) + .AsSyntaxNodeOrToken(), + AssignmentList(nameof(QuestStep.RequiredQuestVariables), + step.RequiredQuestVariables) + .AsSyntaxNodeOrToken(), + AssignmentList(nameof(QuestStep.RequiredGatheredItems), + step.RequiredGatheredItems), + AssignmentList(nameof(QuestStep.CompletionQuestVariablesFlags), + step.CompletionQuestVariablesFlags) + .AsSyntaxNodeOrToken(), + AssignmentList(nameof(QuestStep.DialogueChoices), step.DialogueChoices) + .AsSyntaxNodeOrToken(), + AssignmentList(nameof(QuestStep.PointMenuChoices), step.PointMenuChoices) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.PickUpQuestId), step.PickUpQuestId, + emptyStep.PickUpQuestId) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.TurnInQuestId), step.TurnInQuestId, + emptyStep.TurnInQuestId) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestStep.NextQuestId), step.NextQuestId, + emptyStep.NextQuestId) + .AsSyntaxNodeOrToken())))); + } else if (value is QuestId questId) { return ObjectCreationExpression( @@ -398,7 +521,8 @@ public static class RoslynShortcuts Assignment(nameof(GatheredItem.Collectability), gatheredItem.Collectability, emptyItem.Collectability) .AsSyntaxNodeOrToken(), - Assignment(nameof(GatheredItem.QuestAcceptedAsClass), gatheredItem.QuestAcceptedAsClass, + Assignment(nameof(GatheredItem.QuestAcceptedAsClass), + gatheredItem.QuestAcceptedAsClass, emptyItem.QuestAcceptedAsClass) .AsSyntaxNodeOrToken())))); } diff --git a/QuestPathGenerator/Utils.cs b/QuestPathGenerator/Utils.cs index bbae892..4a08c9e 100644 --- a/QuestPathGenerator/Utils.cs +++ b/QuestPathGenerator/Utils.cs @@ -14,16 +14,40 @@ namespace Questionable.QuestPathGenerator; public static class Utils { - public static IEnumerable<(T, JsonNode)> GetAdditionalFiles(GeneratorExecutionContext context, - AdditionalText jsonSchemaFile, JsonSchema jsonSchema, DiagnosticDescriptor invalidJson, Func idParser) + public static List RegisterSchemas(GeneratorExecutionContext context) { var commonSchemaFile = context.AdditionalFiles.Single(x => Path.GetFileName(x.Path) == "common-schema.json"); - List jsonSchemaFiles = [jsonSchemaFile, commonSchemaFile]; + var gatheringSchemaFile = + context.AdditionalFiles.SingleOrDefault(x => Path.GetFileName(x.Path) == "gatheringlocation-v1.json"); + var questSchemaFile = context.AdditionalFiles.SingleOrDefault(x => Path.GetFileName(x.Path) == "quest-v1.json"); SchemaRegistry.Global.Register( new Uri("https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json"), JsonSchema.FromText(commonSchemaFile.GetText()!.ToString())); + if (gatheringSchemaFile != null) + { + SchemaRegistry.Global.Register( + new Uri( + "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json"), + JsonSchema.FromText(gatheringSchemaFile.GetText()!.ToString())); + } + + if (questSchemaFile != null) + { + SchemaRegistry.Global.Register( + new Uri("https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json"), + JsonSchema.FromText(questSchemaFile.GetText()!.ToString())); + } + + List jsonSchemaFiles = [commonSchemaFile, gatheringSchemaFile, questSchemaFile]; + return jsonSchemaFiles.Where(x => x != null).Cast().ToList(); + } + + public static IEnumerable<(T, JsonNode)> GetAdditionalFiles(GeneratorExecutionContext context, + List jsonSchemaFiles, JsonSchema jsonSchema, DiagnosticDescriptor invalidJson, + Func idParser) + { foreach (var additionalFile in context.AdditionalFiles) { if (additionalFile == null || jsonSchemaFiles.Contains(additionalFile))