Update how quests are embedded
This commit is contained in:
parent
39e5a5a81d
commit
5a4a693d66
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,2 +1,5 @@
|
||||
/.idea
|
||||
obj/
|
||||
bin/
|
||||
/.idea
|
||||
/.vs
|
||||
*.user
|
||||
|
37
QuestPathGenerator/QuestPathGenerator.csproj
Normal file
37
QuestPathGenerator/QuestPathGenerator.csproj
Normal file
@ -0,0 +1,37 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<LangVersion>12</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
<RootNamespace>Questionable.QuestPathGenerator</RootNamespace>
|
||||
<DebugType>portable</DebugType>
|
||||
|
||||
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
|
||||
<IsRoslynComponent>true</IsRoslynComponent>
|
||||
|
||||
<PackageId>QuestPathGenerator</PackageId>
|
||||
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2"/>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.9.2"/>
|
||||
<PackageReference Include="System.Text.Json" Version="8.0.3" PrivateAssets="all"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Questionable.Model\Questionable.Model.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="GetDependencyTargetPaths" AfterTargets="ResolvePackageDependenciesForBuild">
|
||||
<ItemGroup>
|
||||
<TargetPathWithTargetPlatformMoniker Include="..\Questionable.Model\$(OutputPath)\*.dll" IncludeRuntimeDependency="false" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
</Project>
|
316
QuestPathGenerator/QuestSourceGenerator.cs
Normal file
316
QuestPathGenerator/QuestSourceGenerator.cs
Normal file
@ -0,0 +1,316 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Questionable.Model.V1;
|
||||
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||
using static Questionable.QuestPathGenerator.RoslynShortcuts;
|
||||
|
||||
namespace Questionable.QuestPathGenerator;
|
||||
|
||||
/// <summary>
|
||||
/// A sample source generator that creates C# classes based on the text file (in this case, Domain Driven Design ubiquitous language registry).
|
||||
/// When using a simple text file as a baseline, we can create a non-incremental source generator.
|
||||
/// </summary>
|
||||
[Generator]
|
||||
public class QuestSourceGenerator : ISourceGenerator
|
||||
{
|
||||
public void Initialize(GeneratorInitializationContext context)
|
||||
{
|
||||
// No initialization required for this generator.
|
||||
}
|
||||
|
||||
public void Execute(GeneratorExecutionContext context)
|
||||
{
|
||||
List<(ushort, QuestData)> quests = [];
|
||||
|
||||
// Go through all files marked as an Additional File in file properties.
|
||||
foreach (var additionalFile in context.AdditionalFiles)
|
||||
{
|
||||
if (additionalFile == null)
|
||||
continue;
|
||||
|
||||
if (Path.GetExtension(additionalFile.Path) != ".json")
|
||||
continue;
|
||||
|
||||
string name = Path.GetFileName(additionalFile.Path);
|
||||
ushort id = ushort.Parse(name.Substring(0, name.IndexOf('_')));
|
||||
|
||||
var text = additionalFile.GetText();
|
||||
if (text == null)
|
||||
continue;
|
||||
|
||||
var quest = JsonSerializer.Deserialize<QuestData>(text.ToString())!;
|
||||
quests.Add((id, quest));
|
||||
}
|
||||
|
||||
quests = quests.OrderBy(x => x.Item1).ToList();
|
||||
|
||||
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("V1")))
|
||||
}))
|
||||
.WithMembers(
|
||||
SingletonList<MemberDeclarationSyntax>(
|
||||
FileScopedNamespaceDeclaration(
|
||||
QualifiedName(
|
||||
IdentifierName("Questionable"),
|
||||
IdentifierName("QuestPaths")))
|
||||
.WithMembers(
|
||||
SingletonList<MemberDeclarationSyntax>(
|
||||
ClassDeclaration("AssemblyQuestLoader")
|
||||
.WithModifiers(
|
||||
TokenList(
|
||||
[
|
||||
Token(SyntaxKind.PartialKeyword)
|
||||
]))
|
||||
.WithMembers(
|
||||
SingletonList<MemberDeclarationSyntax>(
|
||||
FieldDeclaration(
|
||||
VariableDeclaration(
|
||||
GenericName(
|
||||
Identifier("IReadOnlyDictionary"))
|
||||
.WithTypeArgumentList(
|
||||
TypeArgumentList(
|
||||
SeparatedList<TypeSyntax>(
|
||||
new SyntaxNodeOrToken[]
|
||||
{
|
||||
PredefinedType(
|
||||
Token(SyntaxKind
|
||||
.UShortKeyword)),
|
||||
Token(SyntaxKind.CommaToken),
|
||||
IdentifierName("QuestData")
|
||||
}))))
|
||||
.WithVariables(
|
||||
SingletonSeparatedList(
|
||||
VariableDeclarator(
|
||||
Identifier("Quests"))
|
||||
.WithInitializer(
|
||||
EqualsValueClause(
|
||||
ObjectCreationExpression(
|
||||
GenericName(
|
||||
Identifier(
|
||||
"Dictionary"))
|
||||
.WithTypeArgumentList(
|
||||
TypeArgumentList(
|
||||
SeparatedList<
|
||||
TypeSyntax>(
|
||||
new
|
||||
SyntaxNodeOrToken
|
||||
[]
|
||||
{
|
||||
PredefinedType(
|
||||
Token(
|
||||
SyntaxKind
|
||||
.UShortKeyword)),
|
||||
Token(
|
||||
SyntaxKind
|
||||
.CommaToken),
|
||||
IdentifierName(
|
||||
"QuestData")
|
||||
}))))
|
||||
.WithArgumentList(
|
||||
ArgumentList())
|
||||
.WithInitializer(
|
||||
InitializerExpression(
|
||||
SyntaxKind
|
||||
.CollectionInitializerExpression,
|
||||
SeparatedList<
|
||||
ExpressionSyntax>(
|
||||
quests.SelectMany(x =>
|
||||
CreateQuestInitializer(
|
||||
x.Item1,
|
||||
x.Item2)
|
||||
.ToArray())))))))))
|
||||
.WithModifiers(
|
||||
TokenList(
|
||||
[
|
||||
Token(SyntaxKind.InternalKeyword),
|
||||
Token(SyntaxKind.StaticKeyword)
|
||||
]))))))))
|
||||
.NormalizeWhitespace();
|
||||
|
||||
// Add the source code to the compilation.
|
||||
context.AddSource("AssemblyQuestLoader.g.cs", code.ToFullString());
|
||||
}
|
||||
|
||||
private static IEnumerable<SyntaxNodeOrToken> CreateQuestInitializer(ushort questId, QuestData quest)
|
||||
{
|
||||
return new SyntaxNodeOrToken[]
|
||||
{
|
||||
InitializerExpression(
|
||||
SyntaxKind.ComplexElementInitializerExpression,
|
||||
SeparatedList<ExpressionSyntax>(
|
||||
new SyntaxNodeOrToken[]
|
||||
{
|
||||
LiteralExpression(
|
||||
SyntaxKind.NumericLiteralExpression,
|
||||
Literal(questId)),
|
||||
Token(SyntaxKind.CommaToken),
|
||||
ObjectCreationExpression(
|
||||
IdentifierName(nameof(QuestData)))
|
||||
.WithInitializer(
|
||||
InitializerExpression(
|
||||
SyntaxKind.ObjectInitializerExpression,
|
||||
SeparatedList<ExpressionSyntax>(
|
||||
SyntaxNodeList(
|
||||
Assignment(nameof(QuestData.Author), quest.Author, null)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
AssignmentList(nameof(QuestData.Contributors), quest.Contributors)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
Assignment(nameof(QuestData.Comment), quest.Comment, null)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
AssignmentList(nameof(QuestData.TerritoryBlacklist),
|
||||
quest.TerritoryBlacklist).AsSyntaxNodeOrToken(),
|
||||
AssignmentExpression(
|
||||
SyntaxKind.SimpleAssignmentExpression,
|
||||
IdentifierName(nameof(QuestData.QuestSequence)),
|
||||
CreateQuestSequence(quest.QuestSequence))
|
||||
))))
|
||||
})),
|
||||
Token(SyntaxKind.CommaToken)
|
||||
};
|
||||
}
|
||||
|
||||
private static ExpressionSyntax CreateQuestSequence(List<QuestSequence> sequences)
|
||||
{
|
||||
return CollectionExpression(
|
||||
SeparatedList<CollectionElementSyntax>(
|
||||
sequences.SelectMany(sequence => new SyntaxNodeOrToken[]
|
||||
{
|
||||
ExpressionElement(
|
||||
ObjectCreationExpression(
|
||||
IdentifierName(nameof(QuestSequence)))
|
||||
.WithInitializer(
|
||||
InitializerExpression(
|
||||
SyntaxKind.ObjectInitializerExpression,
|
||||
SeparatedList<ExpressionSyntax>(
|
||||
SyntaxNodeList(
|
||||
Assignment<int?>(nameof(QuestSequence.Sequence), sequence.Sequence, null)
|
||||
.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<QuestStep> steps)
|
||||
{
|
||||
QuestStep emptyStep = new();
|
||||
return CollectionExpression(
|
||||
SeparatedList<CollectionElementSyntax>(
|
||||
steps.SelectMany(step => new SyntaxNodeOrToken[]
|
||||
{
|
||||
ExpressionElement(
|
||||
ObjectCreationExpression(
|
||||
IdentifierName(nameof(QuestStep)))
|
||||
.WithArgumentList(
|
||||
ArgumentList(
|
||||
SeparatedList<ArgumentSyntax>(
|
||||
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<ExpressionSyntax>(
|
||||
SyntaxNodeList(
|
||||
Assignment(nameof(QuestStep.StopDistance), step.StopDistance,
|
||||
emptyStep.StopDistance)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
Assignment(nameof(QuestStep.TargetTerritoryId), step.TargetTerritoryId,
|
||||
emptyStep.TargetTerritoryId)
|
||||
.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.Sprint), step.Sprint, emptyStep.Sprint)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
Assignment(nameof(QuestStep.Comment), step.Comment, emptyStep.Comment)
|
||||
.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.Emote), step.Emote, emptyStep.Emote)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
Assignment(nameof(QuestStep.ChatMessage), step.ChatMessage,
|
||||
emptyStep.ChatMessage)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
Assignment(nameof(QuestStep.EnemySpawnType), step.EnemySpawnType,
|
||||
emptyStep.EnemySpawnType)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
AssignmentList(nameof(QuestStep.KillEnemyDataIds), step.KillEnemyDataIds)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
Assignment(nameof(QuestStep.JumpDestination), step.JumpDestination,
|
||||
emptyStep.JumpDestination)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
Assignment(nameof(QuestStep.ContentFinderConditionId),
|
||||
step.ContentFinderConditionId, emptyStep.ContentFinderConditionId)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
AssignmentList(nameof(QuestStep.SkipIf), step.SkipIf)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
AssignmentList(nameof(QuestStep.CompletionQuestVariablesFlags),
|
||||
step.CompletionQuestVariablesFlags)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
AssignmentList(nameof(QuestStep.DialogueChoices), step.DialogueChoices)
|
||||
.AsSyntaxNodeOrToken()))))),
|
||||
Token(SyntaxKind.CommaToken),
|
||||
}.ToArray())));
|
||||
}
|
||||
}
|
208
QuestPathGenerator/RoslynShortcuts.cs
Normal file
208
QuestPathGenerator/RoslynShortcuts.cs
Normal file
@ -0,0 +1,208 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Questionable.Model.V1;
|
||||
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||
|
||||
namespace Questionable.QuestPathGenerator;
|
||||
|
||||
public static class RoslynShortcuts
|
||||
{
|
||||
public static IEnumerable<SyntaxNodeOrToken> SyntaxNodeList(params SyntaxNodeOrToken?[] nodes)
|
||||
{
|
||||
nodes = nodes.Where(x => x != null).ToArray();
|
||||
if (nodes.Length == 0)
|
||||
return [];
|
||||
|
||||
List<SyntaxNodeOrToken> list = new();
|
||||
for (int i = 0; i < nodes.Length; ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
list.Add(Token(SyntaxKind.CommaToken));
|
||||
list.Add(nodes[i].GetValueOrDefault());
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public static ExpressionSyntax LiteralValue<T>(T? value)
|
||||
{
|
||||
if (value is string s)
|
||||
return LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(s));
|
||||
else if (value is bool b)
|
||||
return LiteralExpression(b ? SyntaxKind.TrueLiteralExpression : SyntaxKind.FalseLiteralExpression);
|
||||
else if (value is short i16)
|
||||
return LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(i16));
|
||||
else if (value is int i32)
|
||||
return LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(i32));
|
||||
else if (value is ushort u16)
|
||||
return LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(u16));
|
||||
else if (value is uint u32)
|
||||
return LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(u32));
|
||||
else if (value is float f)
|
||||
return LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(f));
|
||||
else if (value != null && value.GetType().IsEnum)
|
||||
return MemberAccessExpression(
|
||||
SyntaxKind.SimpleMemberAccessExpression,
|
||||
IdentifierName(value.GetType().Name),
|
||||
IdentifierName(value.GetType().GetEnumName(value)!));
|
||||
else if (value is Vector3 vector)
|
||||
{
|
||||
return ObjectCreationExpression(
|
||||
IdentifierName(nameof(Vector3)))
|
||||
.WithArgumentList(
|
||||
ArgumentList(
|
||||
SeparatedList<ArgumentSyntax>(
|
||||
new SyntaxNodeOrToken[]
|
||||
{
|
||||
Argument(LiteralValue(vector.X)),
|
||||
Token(SyntaxKind.CommaToken),
|
||||
Argument(LiteralValue(vector.Y)),
|
||||
Token(SyntaxKind.CommaToken),
|
||||
Argument(LiteralValue(vector.Z))
|
||||
})));
|
||||
}
|
||||
else if (value is AethernetShortcut aethernetShortcut)
|
||||
{
|
||||
return ObjectCreationExpression(
|
||||
IdentifierName(nameof(AethernetShortcut)))
|
||||
.WithInitializer(
|
||||
InitializerExpression(
|
||||
SyntaxKind.ObjectInitializerExpression,
|
||||
SeparatedList<ExpressionSyntax>(
|
||||
SyntaxNodeList(
|
||||
Assignment<EAetheryteLocation?>(nameof(AethernetShortcut.From), aethernetShortcut.From,
|
||||
null)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
Assignment<EAetheryteLocation?>(nameof(AethernetShortcut.To), aethernetShortcut.To,
|
||||
null)
|
||||
.AsSyntaxNodeOrToken()))));
|
||||
}
|
||||
else if (value is ChatMessage chatMessage)
|
||||
{
|
||||
ChatMessage emptyMessage = new();
|
||||
return ObjectCreationExpression(
|
||||
IdentifierName(nameof(ChatMessage)))
|
||||
.WithInitializer(
|
||||
InitializerExpression(
|
||||
SyntaxKind.ObjectInitializerExpression,
|
||||
SeparatedList<ExpressionSyntax>(
|
||||
SyntaxNodeList(
|
||||
Assignment(nameof(ChatMessage.ExcelSheet), chatMessage.ExcelSheet,
|
||||
emptyMessage.ExcelSheet)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
Assignment(nameof(ChatMessage.Key), chatMessage.Key,
|
||||
emptyMessage.Key)
|
||||
.AsSyntaxNodeOrToken()))));
|
||||
}
|
||||
else if (value is DialogueChoice dialogueChoice)
|
||||
{
|
||||
DialogueChoice emptyChoice = new();
|
||||
return ObjectCreationExpression(
|
||||
IdentifierName(nameof(DialogueChoice)))
|
||||
.WithInitializer(
|
||||
InitializerExpression(
|
||||
SyntaxKind.ObjectInitializerExpression,
|
||||
SeparatedList<ExpressionSyntax>(
|
||||
SyntaxNodeList(
|
||||
Assignment<EDialogChoiceType?>(nameof(DialogueChoice.Type), dialogueChoice.Type, null)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
Assignment(nameof(DialogueChoice.ExcelSheet), dialogueChoice.ExcelSheet,
|
||||
emptyChoice.ExcelSheet)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
Assignment(nameof(DialogueChoice.Prompt), dialogueChoice.Prompt, emptyChoice.Prompt)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
Assignment(nameof(DialogueChoice.Yes), dialogueChoice.Yes, emptyChoice.Yes)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
Assignment(nameof(DialogueChoice.Answer), dialogueChoice.Answer, emptyChoice.Answer)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
Assignment(nameof(DialogueChoice.DataId), dialogueChoice.DataId, emptyChoice.DataId)
|
||||
.AsSyntaxNodeOrToken()))));
|
||||
}
|
||||
else if (value is JumpDestination jumpDestination)
|
||||
{
|
||||
return ObjectCreationExpression(
|
||||
IdentifierName(nameof(JumpDestination)))
|
||||
.WithInitializer(
|
||||
InitializerExpression(
|
||||
SyntaxKind.ObjectInitializerExpression,
|
||||
SeparatedList<ExpressionSyntax>(
|
||||
SyntaxNodeList(
|
||||
Assignment<Vector3?>(nameof(JumpDestination.Position), jumpDestination.Position, null)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
Assignment(nameof(JumpDestination.StopDistance), jumpDestination.StopDistance, null)
|
||||
.AsSyntaxNodeOrToken(),
|
||||
Assignment(nameof(JumpDestination.DelaySeconds), jumpDestination.DelaySeconds, null)
|
||||
.AsSyntaxNodeOrToken()))));
|
||||
}
|
||||
else if (value is ExcelRef excelRef)
|
||||
{
|
||||
if (excelRef.Type == ExcelRef.EType.Key)
|
||||
{
|
||||
return ObjectCreationExpression(
|
||||
IdentifierName(nameof(ExcelRef)))
|
||||
.WithArgumentList(
|
||||
ArgumentList(
|
||||
SingletonSeparatedList(
|
||||
Argument(LiteralValue(excelRef.AsKey())))));
|
||||
}
|
||||
else if (excelRef.Type == ExcelRef.EType.RowId)
|
||||
{
|
||||
return ObjectCreationExpression(
|
||||
IdentifierName(nameof(ExcelRef)))
|
||||
.WithArgumentList(
|
||||
ArgumentList(
|
||||
SingletonSeparatedList(
|
||||
Argument(LiteralValue(excelRef.AsRowId())))));
|
||||
}
|
||||
else
|
||||
throw new Exception($"Unsupported ExcelRef type {excelRef.Type}");
|
||||
}
|
||||
else if (value is null)
|
||||
return LiteralExpression(SyntaxKind.NullLiteralExpression);
|
||||
else
|
||||
throw new Exception($"Unsupported data type {value.GetType()} = {value}");
|
||||
}
|
||||
|
||||
public static AssignmentExpressionSyntax? Assignment<T>(string name, T? value, T? defaultValue)
|
||||
{
|
||||
if (value == null && defaultValue == null)
|
||||
return null;
|
||||
|
||||
if (value != null && defaultValue != null && value.Equals(defaultValue))
|
||||
return null;
|
||||
|
||||
return AssignmentExpression(
|
||||
SyntaxKind.SimpleAssignmentExpression,
|
||||
IdentifierName(name),
|
||||
LiteralValue(value));
|
||||
}
|
||||
|
||||
public static AssignmentExpressionSyntax? AssignmentList<T>(string name, IEnumerable<T> value)
|
||||
{
|
||||
IEnumerable<T> list = value.ToList();
|
||||
if (!list.Any())
|
||||
return null;
|
||||
|
||||
return AssignmentExpression(
|
||||
SyntaxKind.SimpleAssignmentExpression,
|
||||
IdentifierName(name),
|
||||
CollectionExpression(
|
||||
SeparatedList<CollectionElementSyntax>(
|
||||
SyntaxNodeList(list.Select(x => ExpressionElement(
|
||||
LiteralValue(x)).AsSyntaxNodeOrToken()).ToArray())
|
||||
)));
|
||||
}
|
||||
|
||||
public static SyntaxNodeOrToken? AsSyntaxNodeOrToken(this SyntaxNode? node)
|
||||
{
|
||||
if (node == null)
|
||||
return null;
|
||||
|
||||
return node;
|
||||
}
|
||||
}
|
244
QuestPathGenerator/packages.lock.json
Normal file
244
QuestPathGenerator/packages.lock.json
Normal file
@ -0,0 +1,244 @@
|
||||
{
|
||||
"version": 1,
|
||||
"dependencies": {
|
||||
".NETStandard,Version=v2.0": {
|
||||
"Microsoft.CodeAnalysis.Analyzers": {
|
||||
"type": "Direct",
|
||||
"requested": "[3.3.4, )",
|
||||
"resolved": "3.3.4",
|
||||
"contentHash": "AxkxcPR+rheX0SmvpLVIGLhOUXAKG56a64kV9VQZ4y9gR9ZmPXnqZvHJnmwLSwzrEP6junUF11vuc+aqo5r68g=="
|
||||
},
|
||||
"Microsoft.CodeAnalysis.CSharp": {
|
||||
"type": "Direct",
|
||||
"requested": "[4.9.2, )",
|
||||
"resolved": "4.9.2",
|
||||
"contentHash": "HGIo7E9Mf3exAJbUdYpDFfLoYkSVaHDJXPyusWTYUTBaOPCowGw+Gap5McE1w+K+ryIXre72oiqL88sQHmHBmg==",
|
||||
"dependencies": {
|
||||
"Microsoft.CodeAnalysis.Common": "[4.9.2]"
|
||||
}
|
||||
},
|
||||
"Microsoft.CodeAnalysis.CSharp.Workspaces": {
|
||||
"type": "Direct",
|
||||
"requested": "[4.9.2, )",
|
||||
"resolved": "4.9.2",
|
||||
"contentHash": "c74oxEil3fiZ3nXchnIgY6mXS4roHGiQBT6p3X6dMWokVqluHiqi3PNcXyxH8N/w28rQeXprF3mca83rPPNrMw==",
|
||||
"dependencies": {
|
||||
"Humanizer.Core": "2.14.1",
|
||||
"Microsoft.CodeAnalysis.CSharp": "[4.9.2]",
|
||||
"Microsoft.CodeAnalysis.Common": "[4.9.2]",
|
||||
"Microsoft.CodeAnalysis.Workspaces.Common": "[4.9.2]"
|
||||
}
|
||||
},
|
||||
"NETStandard.Library": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.0.3, )",
|
||||
"resolved": "2.0.3",
|
||||
"contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "1.1.0"
|
||||
}
|
||||
},
|
||||
"System.Text.Json": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.3, )",
|
||||
"resolved": "8.0.3",
|
||||
"contentHash": "hpagS9joOwv6efWfrMmV9MjQXpiXZH72PgN067Ysfr6AWMSD1/1hEcvh/U5mUpPLezEWsOJSuVrmqDIVD958iA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Bcl.AsyncInterfaces": "8.0.0",
|
||||
"System.Buffers": "4.5.1",
|
||||
"System.Memory": "4.5.5",
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0",
|
||||
"System.Text.Encodings.Web": "8.0.0",
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Humanizer.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.14.1",
|
||||
"contentHash": "lQKvtaTDOXnoVJ20ibTuSIOf2i0uO0MPbDhd1jm238I+U/2ZnRENj0cktKZhtchBMtCUSRQ5v4xBCUbKNmyVMw=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.CodeAnalysis.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.9.2",
|
||||
"contentHash": "M5PThug7b2AdxL7xKmQs50KzAQTl9jENw5jMT3iUt16k+DAFlw1S87juU3UuPs3gvBm8trMBSOEvSFDr31c9Vw==",
|
||||
"dependencies": {
|
||||
"Microsoft.CodeAnalysis.Analyzers": "3.3.4",
|
||||
"System.Collections.Immutable": "8.0.0",
|
||||
"System.Memory": "4.5.5",
|
||||
"System.Reflection.Metadata": "8.0.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0",
|
||||
"System.Text.Encoding.CodePages": "8.0.0",
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.CodeAnalysis.Workspaces.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.9.2",
|
||||
"contentHash": "sgBlkBjKwUdpbtwM7SnBdOxvQxuaTtO9F8QgvKY5cH/OnlwDTZqmkK8hfDbhxv9wnN2wME10BL2vIv1fLJwFGA==",
|
||||
"dependencies": {
|
||||
"Humanizer.Core": "2.14.1",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "8.0.0",
|
||||
"Microsoft.CodeAnalysis.Common": "[4.9.2]",
|
||||
"System.Composition": "8.0.0",
|
||||
"System.IO.Pipelines": "8.0.0",
|
||||
"System.Threading.Channels": "8.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.NETCore.Platforms": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A=="
|
||||
},
|
||||
"System.Buffers": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.1",
|
||||
"contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg=="
|
||||
},
|
||||
"System.Collections.Immutable": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "AurL6Y5BA1WotzlEvVaIDpqzpIPvYnnldxru8oXJU2yFxFUy3+pNXjXd1ymO+RA0rq0+590Q8gaz2l3Sr7fmqg==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.5",
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Composition": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "E9oO9olNNxA39J8CxQwf7ceIPm+j/B/PhYpyK9M4LhN/OLLRw6u5fNInkhVqaWueMB9iXxYqnwqwgz+W91loIA==",
|
||||
"dependencies": {
|
||||
"System.Composition.AttributedModel": "8.0.0",
|
||||
"System.Composition.Convention": "8.0.0",
|
||||
"System.Composition.Hosting": "8.0.0",
|
||||
"System.Composition.Runtime": "8.0.0",
|
||||
"System.Composition.TypedParts": "8.0.0"
|
||||
}
|
||||
},
|
||||
"System.Composition.AttributedModel": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "NyElSuvmBMYdn2iPG0n29i7Igu0bq99izOP3MAtEwskY3OP9jqsavvVmPn9lesVaj/KT/o/QkNjA43dOJTsDQw=="
|
||||
},
|
||||
"System.Composition.Convention": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "UuVkc1B3vQU/LzEbWLMZ1aYVssv4rpShzf8wPEyrUqoGNqdYKREmB8bXR73heOMKkwS6ZnPz3PjGODT2MenukQ==",
|
||||
"dependencies": {
|
||||
"System.Composition.AttributedModel": "8.0.0"
|
||||
}
|
||||
},
|
||||
"System.Composition.Hosting": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "qwbONqoxlazxcbiohvb3t1JWZgKIKcRdXS5uEeLbo5wtuBupIbAvdC3PYTAeBCZrZeERvrtAbhYHuuS43Zr1bQ==",
|
||||
"dependencies": {
|
||||
"System.Composition.Runtime": "8.0.0"
|
||||
}
|
||||
},
|
||||
"System.Composition.Runtime": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "G+kRyB5/6+3ucRRQz+DF4uSHGqpkK8Q4ilVdbt4zvxpmvLVZNmSkyFAQpJLcbOyVF85aomJx0m+TGMDVlwx7ZQ=="
|
||||
},
|
||||
"System.Composition.TypedParts": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "DsSklhuA+Dsgo3ZZrar8hjBFvq1wa1grrkNCTt+6SoX3vq0Vy+HXJnVXrU/nNH1BjlGH684A7h4hJQHZd/u5mA==",
|
||||
"dependencies": {
|
||||
"System.Composition.AttributedModel": "8.0.0",
|
||||
"System.Composition.Hosting": "8.0.0",
|
||||
"System.Composition.Runtime": "8.0.0"
|
||||
}
|
||||
},
|
||||
"System.IO.Pipelines": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "FHNOatmUq0sqJOkTx+UF/9YK1f180cnW5FVqnQMvYUN0elp6wFzbtPSiqbo1/ru8ICp43JM1i7kKkk6GsNGHlA==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.5.1",
|
||||
"System.Memory": "4.5.5",
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"System.Memory": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.5",
|
||||
"contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.5.1",
|
||||
"System.Numerics.Vectors": "4.4.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||
}
|
||||
},
|
||||
"System.Numerics.Vectors": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.4.0",
|
||||
"contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ=="
|
||||
},
|
||||
"System.Reflection.Metadata": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "ptvgrFh7PvWI8bcVqG5rsA/weWM09EnthFHR5SCnS6IN+P4mj6rE1lBDC4U8HL9/57htKAqy4KQ3bBj84cfYyQ==",
|
||||
"dependencies": {
|
||||
"System.Collections.Immutable": "8.0.0",
|
||||
"System.Memory": "4.5.5"
|
||||
}
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
|
||||
},
|
||||
"System.Text.Encoding.CodePages": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "OZIsVplFGaVY90G2SbpgU7EnCoOO5pw1t4ic21dBF3/1omrJFpAGoNAVpPyMVOC90/hvgkGG3VFqR13YgZMQfg==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.5",
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Text.Encodings.Web": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.5.1",
|
||||
"System.Memory": "4.5.5",
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Threading.Channels": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "CMaFr7v+57RW7uZfZkPExsPB6ljwzhjACWW1gfU35Y56rk72B/Wu+sTqxVmGSk4SFUlPc3cjeKND0zktziyjBA==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"System.Threading.Tasks.Extensions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.4",
|
||||
"contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==",
|
||||
"dependencies": {
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||
}
|
||||
},
|
||||
"questionable.model": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"System.Text.Json": "[8.0.3, )"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,30 +1,11 @@
|
||||
#if RELEASE
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Collections.Generic;
|
||||
using Questionable.Model.V1;
|
||||
|
||||
#if RELEASE
|
||||
namespace Questionable.QuestPaths;
|
||||
|
||||
public static class AssemblyQuestLoader
|
||||
public static partial class AssemblyQuestLoader
|
||||
{
|
||||
public static void LoadQuestsFromEmbeddedResources(Action<string, Stream> loadFunction)
|
||||
{
|
||||
foreach (string resourceName in typeof(AssemblyQuestLoader).Assembly.GetManifestResourceNames())
|
||||
{
|
||||
if (resourceName.EndsWith(".zip"))
|
||||
{
|
||||
using ZipArchive zipArchive =
|
||||
new ZipArchive(typeof(AssemblyQuestLoader).Assembly.GetManifestResourceStream(resourceName)!);
|
||||
foreach (ZipArchiveEntry entry in zipArchive.Entries)
|
||||
{
|
||||
if (entry.Name.EndsWith(".json"))
|
||||
{
|
||||
using Stream stream = entry.Open();
|
||||
loadFunction(entry.Name, stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public static IReadOnlyDictionary<ushort, QuestData> GetQuests() => Quests;
|
||||
}
|
||||
#endif
|
||||
|
@ -8,29 +8,22 @@
|
||||
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
||||
<DebugType>none</DebugType>
|
||||
<PathMap Condition="$(SolutionDir) != ''">$(SolutionDir)=X:\</PathMap>
|
||||
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="ZipARealmReborn" BeforeTargets="BeforeResGen" Condition="'$(Configuration)' == 'Release'">
|
||||
<ZipDirectory SourceDirectory="$(ProjectDir)\ARealmReborn"
|
||||
DestinationFile="$(TargetDir)\ARealmReborn.zip"
|
||||
Overwrite="true"/>
|
||||
</Target>
|
||||
|
||||
<Target Name="ZipShadowbringers" BeforeTargets="BeforeResGen" Condition="'$(Configuration)' == 'Release'">
|
||||
<ZipDirectory SourceDirectory="$(ProjectDir)\Shadowbringers"
|
||||
DestinationFile="$(TargetDir)\Shadowbringers.zip"
|
||||
Overwrite="true"/>
|
||||
</Target>
|
||||
|
||||
<Target Name="ZipEndwalker" BeforeTargets="BeforeResGen" Condition="'$(Configuration)' == 'Release'">
|
||||
<ZipDirectory SourceDirectory="$(ProjectDir)\Endwalker"
|
||||
DestinationFile="$(TargetDir)\Endwalker.zip"
|
||||
Overwrite="true"/>
|
||||
</Target>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Questionable.Model\Questionable.Model.csproj" />
|
||||
<ProjectReference Include="..\QuestPathGenerator\QuestPathGenerator.csproj"
|
||||
OutputItemType="Analyzer"
|
||||
ReferenceOutputAssembly="false" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<EmbeddedResource Include="$(TargetDir)\ARealmReborn.zip"/>
|
||||
<EmbeddedResource Include="$(TargetDir)\Shadowbringers.zip"/>
|
||||
<EmbeddedResource Include="$(TargetDir)\Endwalker.zip"/>
|
||||
<None Remove="ARealmReborn"/>
|
||||
<None Remove="Shadowbringers"/>
|
||||
<None Remove="Endwalker"/>
|
||||
<AdditionalFiles Include="ARealmReborn\**\*.json" />
|
||||
<AdditionalFiles Include="Shadowbringers\**\*.json" />
|
||||
<AdditionalFiles Include="Endwalker\**\*.json" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -1,6 +1,105 @@
|
||||
{
|
||||
"version": 1,
|
||||
"dependencies": {
|
||||
"net8.0-windows7.0": {}
|
||||
"net8.0-windows7.0": {
|
||||
"Dalamud.Extensions.MicrosoftLogging": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "fMEL2ajtF/30SBBku7vMyG0yye5eHN/A9fgT//1CEjUth/Wz2CYco5Ehye21T8KN1IuAPwoqJuu49rB71j+8ug==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging": "8.0.0"
|
||||
}
|
||||
},
|
||||
"DalamudPackager": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.12",
|
||||
"contentHash": "Sc0PVxvgg4NQjcI8n10/VfUQBAS4O+Fw2pZrAqBdRMbthYGeogzu5+xmIGCGmsEZ/ukMOBuAqiNiB5qA3MRalg=="
|
||||
},
|
||||
"JetBrains.Annotations": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2023.3.0",
|
||||
"contentHash": "PHfnvdBUdGaTVG9bR/GEfxgTwWM0Z97Y6X3710wiljELBISipSfF5okn/vz+C2gfO+ihoEyVPjaJwn8ZalVukA=="
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "V8S3bsm50ig6JSyrbcJJ8bW2b9QLGouz+G1miK3UTaOWmMtFwNNNzUf4AleyDWUmTrWMLNnFSLEQtxmxgNQnNQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg=="
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "tvRkov9tAJ3xP51LCv3FJ2zINmv1P8Hi8lhhtcKGqM+ImiTCC84uOPEI4z8Cdq2C3o9e+Aa0Gw0rmrsJD77W+w==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "8.0.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "8.0.0",
|
||||
"Microsoft.Extensions.Options": "8.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "JOVOfqpnqlVLUzINQ2fox8evY2SKLYJ3BV8QDe/Jyp21u1T7r45x/R/5QdteURMR5r01GxeJSBBUOCOyaNXA3g==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0",
|
||||
"Microsoft.Extensions.Primitives": "8.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "bXJEZrW9ny8vjMF1JV253WeLhpEVzFo1lyaZu1vQ4ZxWUlVvknZ/+ftFgVheLubb4eZPSwwxBeqS1JkCOjxd8g=="
|
||||
},
|
||||
"System.Text.Encodings.Web": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ=="
|
||||
},
|
||||
"System.Text.Json": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.3",
|
||||
"contentHash": "hpagS9joOwv6efWfrMmV9MjQXpiXZH72PgN067Ysfr6AWMSD1/1hEcvh/U5mUpPLezEWsOJSuVrmqDIVD958iA==",
|
||||
"dependencies": {
|
||||
"System.Text.Encodings.Web": "8.0.0"
|
||||
}
|
||||
},
|
||||
"llib": {
|
||||
"type": "Project"
|
||||
},
|
||||
"questionable": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Dalamud.Extensions.MicrosoftLogging": "[4.0.1, )",
|
||||
"DalamudPackager": "[2.1.12, )",
|
||||
"JetBrains.Annotations": "[2023.3.0, )",
|
||||
"LLib": "[1.0.0, )",
|
||||
"Microsoft.Extensions.DependencyInjection": "[8.0.0, )",
|
||||
"QuestPaths": "[1.0.0, )",
|
||||
"Questionable.Model": "[1.0.0, )",
|
||||
"System.Text.Json": "[8.0.3, )"
|
||||
}
|
||||
},
|
||||
"questionable.model": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"System.Text.Json": "[8.0.3, )"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
15
Questionable.Model/Questionable.Model.csproj
Normal file
15
Questionable.Model/Questionable.Model.csproj
Normal file
@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<LangVersion>12</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
<PathMap Condition="$(SolutionDir) != ''">$(SolutionDir)=X:\</PathMap>
|
||||
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
||||
<DebugType>portable</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Text.Json" Version="8.0.3"/>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -4,7 +4,7 @@ using Questionable.Model.V1.Converter;
|
||||
namespace Questionable.Model.V1;
|
||||
|
||||
[JsonConverter(typeof(AethernetShortcutConverter))]
|
||||
internal sealed class AethernetShortcut
|
||||
public sealed class AethernetShortcut
|
||||
{
|
||||
public EAetheryteLocation From { get; set; }
|
||||
public EAetheryteLocation To { get; set; }
|
7
Questionable.Model/V1/ChatMessage.cs
Normal file
7
Questionable.Model/V1/ChatMessage.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace Questionable.Model.V1;
|
||||
|
||||
public sealed class ChatMessage
|
||||
{
|
||||
public string? ExcelSheet { get; set; }
|
||||
public string Key { get; set; } = null!;
|
||||
}
|
@ -6,7 +6,7 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Questionable.Model.V1.Converter;
|
||||
|
||||
internal sealed class AethernetShortcutConverter : JsonConverter<AethernetShortcut>
|
||||
public sealed class AethernetShortcutConverter : JsonConverter<AethernetShortcut>
|
||||
{
|
||||
private static readonly Dictionary<EAetheryteLocation, string> EnumToString = new()
|
||||
{
|
||||
@ -151,9 +151,6 @@ internal sealed class AethernetShortcutConverter : JsonConverter<AethernetShortc
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, AethernetShortcut value, JsonSerializerOptions options)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(writer);
|
||||
ArgumentNullException.ThrowIfNull(value);
|
||||
|
||||
writer.WriteStartArray();
|
||||
writer.WriteStringValue(EnumToString[value.From]);
|
||||
writer.WriteStringValue(EnumToString[value.To]);
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace Questionable.Model.V1.Converter;
|
||||
|
||||
internal sealed class AetheryteConverter() : EnumConverter<EAetheryteLocation>(Values)
|
||||
public sealed class AetheryteConverter() : EnumConverter<EAetheryteLocation>(Values)
|
||||
{
|
||||
private static readonly Dictionary<EAetheryteLocation, string> Values = new()
|
||||
{
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace Questionable.Model.V1.Converter;
|
||||
|
||||
internal sealed class DialogueChoiceTypeConverter() : EnumConverter<EDialogChoiceType>(Values)
|
||||
public sealed class DialogueChoiceTypeConverter() : EnumConverter<EDialogChoiceType>(Values)
|
||||
{
|
||||
private static readonly Dictionary<EDialogChoiceType, string> Values = new()
|
||||
{
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace Questionable.Model.V1.Converter;
|
||||
|
||||
internal sealed class EmoteConverter() : EnumConverter<EEmote>(Values)
|
||||
public sealed class EmoteConverter() : EnumConverter<EEmote>(Values)
|
||||
{
|
||||
private static readonly Dictionary<EEmote, string> Values = new()
|
||||
{
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace Questionable.Model.V1.Converter;
|
||||
|
||||
internal sealed class EnemySpawnTypeConverter() : EnumConverter<EEnemySpawnType>(Values)
|
||||
public sealed class EnemySpawnTypeConverter() : EnumConverter<EEnemySpawnType>(Values)
|
||||
{
|
||||
private static readonly Dictionary<EEnemySpawnType, string> Values = new()
|
||||
{
|
@ -7,7 +7,7 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Questionable.Model.V1.Converter;
|
||||
|
||||
internal abstract class EnumConverter<T> : JsonConverter<T>
|
||||
public abstract class EnumConverter<T> : JsonConverter<T>
|
||||
where T : Enum
|
||||
{
|
||||
private readonly ReadOnlyDictionary<T, string> _enumToString;
|
||||
@ -17,9 +17,8 @@ internal abstract class EnumConverter<T> : JsonConverter<T>
|
||||
{
|
||||
_enumToString = values is IDictionary<T, string> dict
|
||||
? new ReadOnlyDictionary<T, string>(dict)
|
||||
: values.ToDictionary(x => x.Key, x => x.Value).AsReadOnly();
|
||||
_stringToEnum = _enumToString.ToDictionary(x => x.Value, x => x.Key)
|
||||
.AsReadOnly();
|
||||
: new ReadOnlyDictionary<T, string>(values.ToDictionary(x => x.Key, x => x.Value));
|
||||
_stringToEnum = new ReadOnlyDictionary<string, T>(_enumToString.ToDictionary(x => x.Value, x => x.Key));
|
||||
}
|
||||
|
||||
public override T? Read(ref Utf8JsonReader reader, Type typeToConvert,
|
||||
@ -37,7 +36,6 @@ internal abstract class EnumConverter<T> : JsonConverter<T>
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(writer);
|
||||
writer.WriteStringValue(_enumToString[value]);
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Questionable.Model.V1.Converter;
|
||||
|
||||
internal sealed class ExcelRefConverter : JsonConverter<ExcelRef>
|
||||
public sealed class ExcelRefConverter : JsonConverter<ExcelRef>
|
||||
{
|
||||
public override ExcelRef? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace Questionable.Model.V1.Converter;
|
||||
|
||||
internal sealed class InteractionTypeConverter() : EnumConverter<EInteractionType>(Values)
|
||||
public sealed class InteractionTypeConverter() : EnumConverter<EInteractionType>(Values)
|
||||
{
|
||||
private static readonly Dictionary<EInteractionType, string> Values = new()
|
||||
{
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace Questionable.Model.V1.Converter;
|
||||
|
||||
internal sealed class SkipConditionConverter() : EnumConverter<ESkipCondition>(Values)
|
||||
public sealed class SkipConditionConverter() : EnumConverter<ESkipCondition>(Values)
|
||||
{
|
||||
private static readonly Dictionary<ESkipCondition, string> Values = new()
|
||||
{
|
@ -5,7 +5,7 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Questionable.Model.V1.Converter;
|
||||
|
||||
internal sealed class VectorConverter : JsonConverter<Vector3>
|
||||
public sealed class VectorConverter : JsonConverter<Vector3>
|
||||
{
|
||||
public override Vector3 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
@ -55,8 +55,6 @@ internal sealed class VectorConverter : JsonConverter<Vector3>
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, Vector3 value, JsonSerializerOptions options)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(writer);
|
||||
|
||||
writer.WriteStartObject();
|
||||
writer.WriteNumber(nameof(Vector3.X), value.X);
|
||||
writer.WriteNumber(nameof(Vector3.Y), value.X);
|
@ -1,11 +1,9 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using JetBrains.Annotations;
|
||||
using Questionable.Model.V1.Converter;
|
||||
|
||||
namespace Questionable.Model.V1;
|
||||
|
||||
[UsedImplicitly(ImplicitUseKindFlags.Assign, ImplicitUseTargetFlags.WithMembers)]
|
||||
internal sealed class DialogueChoice
|
||||
public sealed class DialogueChoice
|
||||
{
|
||||
[JsonConverter(typeof(DialogueChoiceTypeConverter))]
|
||||
public EDialogChoiceType Type { get; set; }
|
@ -4,7 +4,7 @@ using Questionable.Model.V1.Converter;
|
||||
namespace Questionable.Model.V1;
|
||||
|
||||
[JsonConverter(typeof(AetheryteConverter))]
|
||||
internal enum EAetheryteLocation
|
||||
public enum EAetheryteLocation
|
||||
{
|
||||
None = 0,
|
||||
|
@ -1,6 +1,6 @@
|
||||
namespace Questionable.Model.V1;
|
||||
|
||||
internal enum EDialogChoiceType
|
||||
public enum EDialogChoiceType
|
||||
{
|
||||
None,
|
||||
YesNo,
|
@ -4,7 +4,7 @@ using Questionable.Model.V1.Converter;
|
||||
namespace Questionable.Model.V1;
|
||||
|
||||
[JsonConverter(typeof(EmoteConverter))]
|
||||
internal enum EEmote
|
||||
public enum EEmote
|
||||
{
|
||||
None = 0,
|
||||
|
@ -4,7 +4,7 @@ using Questionable.Model.V1.Converter;
|
||||
namespace Questionable.Model.V1;
|
||||
|
||||
[JsonConverter(typeof(EnemySpawnTypeConverter))]
|
||||
internal enum EEnemySpawnType
|
||||
public enum EEnemySpawnType
|
||||
{
|
||||
None = 0,
|
||||
AfterInteraction,
|
@ -4,7 +4,7 @@ using Questionable.Model.V1.Converter;
|
||||
namespace Questionable.Model.V1;
|
||||
|
||||
[JsonConverter(typeof(InteractionTypeConverter))]
|
||||
internal enum EInteractionType
|
||||
public enum EInteractionType
|
||||
{
|
||||
Interact,
|
||||
WalkTo,
|
@ -4,7 +4,7 @@ using Questionable.Model.V1.Converter;
|
||||
namespace Questionable.Model.V1;
|
||||
|
||||
[JsonConverter(typeof(SkipConditionConverter))]
|
||||
internal enum ESkipCondition
|
||||
public enum ESkipCondition
|
||||
{
|
||||
None,
|
||||
Never,
|
@ -1,12 +1,10 @@
|
||||
using System.Numerics;
|
||||
using System.Text.Json.Serialization;
|
||||
using JetBrains.Annotations;
|
||||
using Questionable.Model.V1.Converter;
|
||||
|
||||
namespace Questionable.Model.V1;
|
||||
|
||||
[UsedImplicitly(ImplicitUseKindFlags.Assign, ImplicitUseTargetFlags.WithMembers)]
|
||||
internal sealed class JumpDestination
|
||||
public sealed class JumpDestination
|
||||
{
|
||||
[JsonConverter(typeof(VectorConverter))]
|
||||
public Vector3 Position { get; set; }
|
12
Questionable.Model/V1/QuestData.cs
Normal file
12
Questionable.Model/V1/QuestData.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Questionable.Model.V1;
|
||||
|
||||
public sealed class QuestData
|
||||
{
|
||||
public string Author { get; set; } = null!;
|
||||
public List<string> Contributors { get; set; } = new();
|
||||
public string? Comment { get; set; }
|
||||
public List<ushort> TerritoryBlacklist { get; set; } = new();
|
||||
public List<QuestSequence> QuestSequence { get; set; } = new();
|
||||
}
|
@ -1,12 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Questionable.Model.V1;
|
||||
|
||||
[UsedImplicitly(ImplicitUseKindFlags.Assign, ImplicitUseTargetFlags.WithMembers)]
|
||||
internal sealed class QuestSequence
|
||||
public sealed class QuestSequence
|
||||
{
|
||||
public required int Sequence { get; set; }
|
||||
public int Sequence { get; set; }
|
||||
public string? Comment { get; set; }
|
||||
public List<QuestStep> Steps { get; set; } = new();
|
||||
|
@ -3,14 +3,11 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Numerics;
|
||||
using System.Text.Json.Serialization;
|
||||
using FFXIVClientStructs.FFXIV.Application.Network.WorkDefinitions;
|
||||
using JetBrains.Annotations;
|
||||
using Questionable.Model.V1.Converter;
|
||||
|
||||
namespace Questionable.Model.V1;
|
||||
|
||||
[UsedImplicitly(ImplicitUseKindFlags.Assign, ImplicitUseTargetFlags.WithMembers)]
|
||||
internal sealed class QuestStep
|
||||
public sealed class QuestStep
|
||||
{
|
||||
public EInteractionType InteractionType { get; set; }
|
||||
|
||||
@ -42,8 +39,8 @@ internal sealed class QuestStep
|
||||
public ChatMessage? ChatMessage { get; set; }
|
||||
|
||||
public EEnemySpawnType? EnemySpawnType { get; set; }
|
||||
|
||||
public IList<uint> KillEnemyDataIds { get; set; } = new List<uint>();
|
||||
|
||||
public JumpDestination? JumpDestination { get; set; }
|
||||
public uint? ContentFinderConditionId { get; set; }
|
||||
|
||||
@ -51,37 +48,16 @@ internal sealed class QuestStep
|
||||
public IList<short?> CompletionQuestVariablesFlags { get; set; } = new List<short?>();
|
||||
public IList<DialogueChoice> DialogueChoices { get; set; } = new List<DialogueChoice>();
|
||||
|
||||
/// <summary>
|
||||
/// Positive values: Must be set to this value; will wait for the step to have these set.
|
||||
/// Negative values: Will skip if set to this value, won't wait for this to be set.
|
||||
/// </summary>
|
||||
public unsafe bool MatchesQuestVariables(QuestWork questWork, bool forSkip)
|
||||
[JsonConstructor]
|
||||
public QuestStep()
|
||||
{
|
||||
if (CompletionQuestVariablesFlags.Count != 6)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
short? check = CompletionQuestVariablesFlags[i];
|
||||
if (check == null)
|
||||
continue;
|
||||
|
||||
byte actualValue = questWork.Variables[i];
|
||||
byte checkByte = check > 0 ? (byte)check : (byte)-check;
|
||||
if (forSkip)
|
||||
{
|
||||
byte expectedValue = (byte)Math.Abs(check.Value);
|
||||
if ((actualValue & checkByte) != expectedValue)
|
||||
return false;
|
||||
}
|
||||
else if (!forSkip && check > 0)
|
||||
{
|
||||
byte expectedValue = check > 0 ? (byte)check : (byte)0;
|
||||
if ((actualValue & checkByte) != expectedValue)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
public QuestStep(EInteractionType interactionType, uint? dataId, Vector3? position, ushort territoryId)
|
||||
{
|
||||
InteractionType = interactionType;
|
||||
DataId = dataId;
|
||||
Position = position;
|
||||
TerritoryId = territoryId;
|
||||
}
|
||||
}
|
86
Questionable.Model/packages.lock.json
Normal file
86
Questionable.Model/packages.lock.json
Normal file
@ -0,0 +1,86 @@
|
||||
{
|
||||
"version": 1,
|
||||
"dependencies": {
|
||||
".NETStandard,Version=v2.0": {
|
||||
"NETStandard.Library": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.0.3, )",
|
||||
"resolved": "2.0.3",
|
||||
"contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "1.1.0"
|
||||
}
|
||||
},
|
||||
"System.Text.Json": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.3, )",
|
||||
"resolved": "8.0.3",
|
||||
"contentHash": "hpagS9joOwv6efWfrMmV9MjQXpiXZH72PgN067Ysfr6AWMSD1/1hEcvh/U5mUpPLezEWsOJSuVrmqDIVD958iA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Bcl.AsyncInterfaces": "8.0.0",
|
||||
"System.Buffers": "4.5.1",
|
||||
"System.Memory": "4.5.5",
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0",
|
||||
"System.Text.Encodings.Web": "8.0.0",
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.NETCore.Platforms": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A=="
|
||||
},
|
||||
"System.Buffers": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.1",
|
||||
"contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg=="
|
||||
},
|
||||
"System.Memory": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.5",
|
||||
"contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.5.1",
|
||||
"System.Numerics.Vectors": "4.4.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||
}
|
||||
},
|
||||
"System.Numerics.Vectors": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.4.0",
|
||||
"contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ=="
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
|
||||
},
|
||||
"System.Text.Encodings.Web": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.5.1",
|
||||
"System.Memory": "4.5.5",
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Threading.Tasks.Extensions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.4",
|
||||
"contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==",
|
||||
"dependencies": {
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -6,6 +6,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LLib", "LLib\LLib.csproj",
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuestPaths", "QuestPaths\QuestPaths.csproj", "{7A136F28-8D5C-478D-B993-0F39F1451A47}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuestPaths", "QuestPathGenerator\QuestPathGenerator.csproj", "{DFFD56A8-FA89-4585-A47B-C6AB27B65F0F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Questionable.Model", "Questionable.Model\Questionable.Model.csproj", "{E15144A5-AFF5-4D86-9561-AFF7DF7F505D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -24,5 +28,13 @@ Global
|
||||
{7A136F28-8D5C-478D-B993-0F39F1451A47}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7A136F28-8D5C-478D-B993-0F39F1451A47}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7A136F28-8D5C-478D-B993-0F39F1451A47}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DFFD56A8-FA89-4585-A47B-C6AB27B65F0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DFFD56A8-FA89-4585-A47B-C6AB27B65F0F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DFFD56A8-FA89-4585-A47B-C6AB27B65F0F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DFFD56A8-FA89-4585-A47B-C6AB27B65F0F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E15144A5-AFF5-4D86-9561-AFF7DF7F505D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E15144A5-AFF5-4D86-9561-AFF7DF7F505D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E15144A5-AFF5-4D86-9561-AFF7DF7F505D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E15144A5-AFF5-4D86-9561-AFF7DF7F505D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
2
Questionable/.gitignore
vendored
2
Questionable/.gitignore
vendored
@ -1,3 +1 @@
|
||||
/dist
|
||||
/obj
|
||||
/bin
|
||||
|
@ -33,7 +33,17 @@ internal sealed class QuestRegistry
|
||||
|
||||
#if RELEASE
|
||||
_logger.LogInformation("Loading quests from assembly");
|
||||
QuestPaths.AssemblyQuestLoader.LoadQuestsFromEmbeddedResources(LoadQuestFromStream);
|
||||
|
||||
foreach ((ushort questId, QuestData questData) in QuestPaths.AssemblyQuestLoader.GetQuests())
|
||||
{
|
||||
Quest quest = new()
|
||||
{
|
||||
QuestId = questId,
|
||||
Name = string.Empty,
|
||||
Data = questData,
|
||||
};
|
||||
_quests[questId] = quest;
|
||||
}
|
||||
#else
|
||||
DirectoryInfo? solutionDirectory = _pluginInterface.AssemblyLocation?.Directory?.Parent?.Parent;
|
||||
if (solutionDirectory != null)
|
||||
@ -48,6 +58,7 @@ internal sealed class QuestRegistry
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
LoadFromDirectory(new DirectoryInfo(Path.Combine(_pluginInterface.ConfigDirectory.FullName, "Quests")));
|
||||
|
||||
foreach (var (questId, quest) in _quests)
|
||||
@ -60,6 +71,8 @@ internal sealed class QuestRegistry
|
||||
quest.Name = questData.Name.ToString();
|
||||
quest.Level = questData.ClassJobLevel0;
|
||||
}
|
||||
|
||||
_logger.LogInformation("Loaded {Count} quests", _quests.Count);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,10 +0,0 @@
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Questionable.Model.V1;
|
||||
|
||||
[UsedImplicitly(ImplicitUseKindFlags.Assign, ImplicitUseTargetFlags.WithMembers)]
|
||||
internal sealed class ChatMessage
|
||||
{
|
||||
public string? ExcelSheet { get; set; }
|
||||
public string Key { get; set; } = null!;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Questionable.Model.V1;
|
||||
|
||||
[UsedImplicitly(ImplicitUseKindFlags.Assign, ImplicitUseTargetFlags.WithMembers)]
|
||||
internal sealed class QuestData
|
||||
{
|
||||
public required string Author { get; set; }
|
||||
public List<string> Contributors { get; set; } = new();
|
||||
public string? Comment { get; set; }
|
||||
public List<ushort> TerritoryBlacklist { get; set; } = new();
|
||||
public required List<QuestSequence> QuestSequence { get; set; } = new();
|
||||
}
|
41
Questionable/Model/V1/QuestStepExtensions.cs
Normal file
41
Questionable/Model/V1/QuestStepExtensions.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using FFXIVClientStructs.FFXIV.Application.Network.WorkDefinitions;
|
||||
|
||||
namespace Questionable.Model.V1;
|
||||
|
||||
internal static class QuestStepExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Positive values: Must be set to this value; will wait for the step to have these set.
|
||||
/// Negative values: Will skip if set to this value, won't wait for this to be set.
|
||||
/// </summary>
|
||||
public static unsafe bool MatchesQuestVariables(this QuestStep step, QuestWork questWork, bool forSkip)
|
||||
{
|
||||
if (step.CompletionQuestVariablesFlags.Count != 6)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
short? check = step.CompletionQuestVariablesFlags[i];
|
||||
if (check == null)
|
||||
continue;
|
||||
|
||||
byte actualValue = questWork.Variables[i];
|
||||
byte checkByte = check > 0 ? (byte)check : (byte)-check;
|
||||
if (forSkip)
|
||||
{
|
||||
byte expectedValue = (byte)Math.Abs(check.Value);
|
||||
if ((actualValue & checkByte) != expectedValue)
|
||||
return false;
|
||||
}
|
||||
else if (!forSkip && check > 0)
|
||||
{
|
||||
byte expectedValue = check > 0 ? (byte)check : (byte)0;
|
||||
if ((actualValue & checkByte) != expectedValue)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -59,6 +59,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LLib\LLib.csproj" />
|
||||
<ProjectReference Include="..\Questionable.Model\Questionable.Model.csproj" />
|
||||
<ProjectReference Include="..\QuestPaths\QuestPaths.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -86,8 +86,17 @@
|
||||
"llib": {
|
||||
"type": "Project"
|
||||
},
|
||||
"questionable.model": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"System.Text.Json": "[8.0.3, )"
|
||||
}
|
||||
},
|
||||
"questpaths": {
|
||||
"type": "Project"
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Questionable.Model": "[1.0.0, )"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user