From 9bfbc99144eca664024f439bd4c6e79569da9548 Mon Sep 17 00:00:00 2001 From: Liza Carvelli Date: Fri, 2 Aug 2024 20:04:45 +0200 Subject: [PATCH] Schema update --- .gitmodules | 3 + .../GatheringPathRenderer.csproj | 5 + .../GatheringPathRenderer.json | 6 + GatheringPathRenderer/RendererPlugin.cs | 180 +++++++++++++++++- GatheringPathRenderer/packages.lock.json | 28 +++ .../Thavnair/820_Pewter Ore.json | 180 +++++++++++++----- .../AssemblyGatheringLocationLoader.cs | 4 +- GatheringPaths/GatheringPaths.csproj | 2 +- GatheringPaths/gatheringlocation-v1.json | 79 +++++--- .../GatheringSourceGenerator.cs | 2 +- QuestPathGenerator/RoslynShortcuts.cs | 47 +++-- QuestPathGenerator/Utils.cs | 3 +- .../Gathering/GatheringLocation.cs | 21 ++ Questionable.Model/Gathering/GatheringNode.cs | 10 + .../Gathering/GatheringNodeGroup.cs | 8 + .../Gathering/GatheringNodeLocation.cs | 13 -- Questionable.Model/Gathering/GatheringRoot.cs | 2 +- Questionable.sln | 6 + Questionable/Controller/QuestRegistry.cs | 6 +- vendor/ECommons | 1 + 20 files changed, 502 insertions(+), 104 deletions(-) create mode 100644 GatheringPathRenderer/GatheringPathRenderer.json create mode 100644 Questionable.Model/Gathering/GatheringLocation.cs create mode 100644 Questionable.Model/Gathering/GatheringNode.cs create mode 100644 Questionable.Model/Gathering/GatheringNodeGroup.cs delete mode 100644 Questionable.Model/Gathering/GatheringNodeLocation.cs create mode 160000 vendor/ECommons diff --git a/.gitmodules b/.gitmodules index 4ac68e0..0bc08a3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "LLib"] path = LLib url = https://git.carvel.li/liza/LLib.git +[submodule "vendor/ECommons"] + path = vendor/ECommons + url = https://github.com/NightmareXIV/ECommons.git diff --git a/GatheringPathRenderer/GatheringPathRenderer.csproj b/GatheringPathRenderer/GatheringPathRenderer.csproj index 5d22cd3..1d3aeae 100644 --- a/GatheringPathRenderer/GatheringPathRenderer.csproj +++ b/GatheringPathRenderer/GatheringPathRenderer.csproj @@ -1,3 +1,8 @@ + + + + + diff --git a/GatheringPathRenderer/GatheringPathRenderer.json b/GatheringPathRenderer/GatheringPathRenderer.json new file mode 100644 index 0000000..8d68d1d --- /dev/null +++ b/GatheringPathRenderer/GatheringPathRenderer.json @@ -0,0 +1,6 @@ +{ + "Name": "GatheringPathRenderer", + "Author": "Liza Carvelli", + "Punchline": "dev only plugin: Renders gathering location.", + "Description": "dev only plugin: Renders gathering location (without ECommons polluting the entire normal project)." +} diff --git a/GatheringPathRenderer/RendererPlugin.cs b/GatheringPathRenderer/RendererPlugin.cs index d33eae9..9c9a50d 100644 --- a/GatheringPathRenderer/RendererPlugin.cs +++ b/GatheringPathRenderer/RendererPlugin.cs @@ -1,11 +1,189 @@ -using Dalamud.Plugin; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.Json; +using System.Text.Json.Nodes; +using Dalamud.Plugin; +using Dalamud.Plugin.Services; +using ECommons; +using ECommons.Schedulers; +using ECommons.SplatoonAPI; +using Questionable.Model.Gathering; namespace GatheringPathRenderer; public sealed class RendererPlugin : IDalamudPlugin { + private const long OnTerritoryChange = -2; + private readonly IDalamudPluginInterface _pluginInterface; + private readonly IClientState _clientState; + private readonly IPluginLog _pluginLog; + private readonly List<(ushort Id, GatheringRoot Root)> _gatheringLocations = []; + + public RendererPlugin(IDalamudPluginInterface pluginInterface, IClientState clientState, IPluginLog pluginLog) + { + _pluginInterface = pluginInterface; + _clientState = clientState; + _pluginLog = pluginLog; + + _pluginInterface.GetIpcSubscriber("Questionable.ReloadData") + .Subscribe(Reload); + + ECommonsMain.Init(pluginInterface, this, Module.SplatoonAPI); + LoadGatheringLocationsFromDirectory(); + + _clientState.TerritoryChanged += TerritoryChanged; + if (_clientState.IsLoggedIn) + TerritoryChanged(_clientState.TerritoryType); + } + + private void Reload() + { + LoadGatheringLocationsFromDirectory(); + TerritoryChanged(_clientState.TerritoryType); + } + + private void LoadGatheringLocationsFromDirectory() + { + _gatheringLocations.Clear(); + + DirectoryInfo? solutionDirectory = _pluginInterface.AssemblyLocation.Directory?.Parent?.Parent?.Parent; + if (solutionDirectory != null) + { + DirectoryInfo pathProjectDirectory = + new DirectoryInfo(Path.Combine(solutionDirectory.FullName, "GatheringPaths")); + if (pathProjectDirectory.Exists) + { + try + { + LoadFromDirectory( + new DirectoryInfo(Path.Combine(pathProjectDirectory.FullName, "2.x - A Realm Reborn"))); + LoadFromDirectory( + new DirectoryInfo(Path.Combine(pathProjectDirectory.FullName, "3.x - Heavensward"))); + LoadFromDirectory( + new DirectoryInfo(Path.Combine(pathProjectDirectory.FullName, "4.x - Stormblood"))); + LoadFromDirectory( + new DirectoryInfo(Path.Combine(pathProjectDirectory.FullName, "5.x - Shadowbringers"))); + LoadFromDirectory( + new DirectoryInfo(Path.Combine(pathProjectDirectory.FullName, "6.x - Endwalker"))); + LoadFromDirectory( + new DirectoryInfo(Path.Combine(pathProjectDirectory.FullName, "7.x - Dawntrail"))); + + _pluginLog.Information( + $"Loaded {_gatheringLocations.Count} gathering root locations from project directory"); + } + catch (Exception e) + { + _pluginLog.Error(e, "Failed to load quests from project directory"); + } + } + else + _pluginLog.Warning($"Project directory {pathProjectDirectory} does not exist"); + } + else + _pluginLog.Warning($"Solution directory {solutionDirectory} does not exist"); + } + + private void LoadFromDirectory(DirectoryInfo directory) + { + if (!directory.Exists) + return; + + _pluginLog.Information($"Loading locations from {directory}"); + foreach (FileInfo fileInfo in directory.GetFiles("*.json")) + { + try + { + using FileStream stream = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read); + LoadLocationFromStream(fileInfo.Name, stream); + } + catch (Exception e) + { + throw new InvalidDataException($"Unable to load file {fileInfo.FullName}", e); + } + } + + foreach (DirectoryInfo childDirectory in directory.GetDirectories()) + LoadFromDirectory(childDirectory); + } + + private void LoadLocationFromStream(string fileName, Stream stream) + { + var locationNode = JsonNode.Parse(stream)!; + GatheringRoot root = locationNode.Deserialize()!; + _gatheringLocations.Add((ushort.Parse(fileName.Split('_')[0]), root)); + } + + private void TerritoryChanged(ushort territoryId) + { + Splatoon.RemoveDynamicElements("GatheringPathRenderer"); + + var elements = _gatheringLocations + .Where(x => x.Root.TerritoryId == territoryId) + .SelectMany(v => + v.Root.Groups.SelectMany(group => + group.Nodes.SelectMany(node => node.Locations + .SelectMany(x => + new List + { + new Element(x.IsCone() + ? ElementType.ConeAtFixedCoordinates + : ElementType.CircleAtFixedCoordinates) + { + refX = x.Position.X, + refY = x.Position.Z, + refZ = x.Position.Y, + Filled = true, + radius = x.MinimumDistance, + Donut = x.MaximumDistance - x.MinimumDistance, + color = 0x2020FF80, + Enabled = true, + coneAngleMin = x.IsCone() ? (int)x.MinimumAngle.GetValueOrDefault() : 0, + coneAngleMax = x.IsCone() ? (int)x.MaximumAngle.GetValueOrDefault() : 0 + }, + new Element(ElementType.CircleAtFixedCoordinates) + { + refX = x.Position.X, + refY = x.Position.Z, + refZ = x.Position.Y, + color = 0x00000000, + Enabled = true, + overlayText = $"{v.Id} // {node.DataId} / {node.Locations.IndexOf(x)}" + } + })))) + .ToList(); + + if (elements.Count == 0) + { + _pluginLog.Information("No new elements to render."); + return; + } + + _ = new TickScheduler(delegate + { + try + { + Splatoon.AddDynamicElements("GatheringPathRenderer", + elements.ToArray(), + new[] { OnTerritoryChange }); + _pluginLog.Information($"Created {elements.Count} splatoon elements."); + } + catch (Exception e) + { + _pluginLog.Error(e, "Unable to create splatoon layer"); + } + }); + } + public void Dispose() { + _clientState.TerritoryChanged -= TerritoryChanged; + Splatoon.RemoveDynamicElements("GatheringPathRenderer"); + ECommonsMain.Dispose(); + + _pluginInterface.GetIpcSubscriber("Questionable.ReloadData") + .Unsubscribe(Reload); } } diff --git a/GatheringPathRenderer/packages.lock.json b/GatheringPathRenderer/packages.lock.json index 0c669eb..c7a267a 100644 --- a/GatheringPathRenderer/packages.lock.json +++ b/GatheringPathRenderer/packages.lock.json @@ -75,6 +75,34 @@ "Microsoft.Build.Tasks.Git": "1.1.1", "Microsoft.SourceLink.Common": "1.1.1" } + }, + "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" + } + }, + "ecommons": { + "type": "Project" + }, + "gatheringpaths": { + "type": "Project", + "dependencies": { + "Questionable.Model": "[1.0.0, )" + } + }, + "questionable.model": { + "type": "Project", + "dependencies": { + "System.Text.Json": "[8.0.4, )" + } } } } diff --git a/GatheringPaths/6.x - Endwalker/Thavnair/820_Pewter Ore.json b/GatheringPaths/6.x - Endwalker/Thavnair/820_Pewter Ore.json index 425d77e..de17572 100644 --- a/GatheringPaths/6.x - Endwalker/Thavnair/820_Pewter Ore.json +++ b/GatheringPaths/6.x - Endwalker/Thavnair/820_Pewter Ore.json @@ -3,54 +3,148 @@ "Author": "liza", "TerritoryId": 957, "AetheryteShortcut": "Thavnair - Great Work", - "Nodes": [ + "Groups": [ { - "DataId": 33918, - "Position": { - "X": -582.5132, - "Y": 40.54578, - "Z": -426.0171 - } + "Nodes": [ + { + "DataId": 33918, + "Locations": [ + { + "Position": { + "X": -582.5132, + "Y": 40.54578, + "Z": -426.0171 + }, + "MinimumAngle": -50, + "MaximumAngle": 90 + } + ] + }, + { + "DataId": 33919, + "Locations": [ + { + "Position": { + "X": -578.2101, + "Y": 41.27147, + "Z": -447.6376 + }, + "MinimumAngle": 130, + "MaximumAngle": 220 + }, + { + "Position": { + "X": -546.2882, + "Y": 44.52267, + "Z": -435.8184 + }, + "MinimumAngle": 200, + "MaximumAngle": 360 + } + ] + } + ] }, { - "DataId": 33919, - "Position": { - "X": -578.2101, - "Y": 41.27147, - "Z": -447.6376 - } + "Nodes": [ + { + "DataId": 33920, + "Locations": [ + { + "Position": { + "X": -488.2276, + "Y": 34.71221, + "Z": -359.6945 + }, + "MinimumAngle": 20, + "MaximumAngle": 128, + "MinimumDistance": 1.3 + } + ] + }, + { + "DataId": 33921, + "Locations": [ + { + "Position": { + "X": -498.8687, + "Y": 31.08014, + "Z": -351.9397 + }, + "MinimumAngle": 40, + "MaximumAngle": 190 + }, + { + "Position": { + "X": -490.7759, + "Y": 28.70215, + "Z": -344.4114 + }, + "MinimumAngle": -110, + "MaximumAngle": 60 + }, + { + "Position": { + "X": -494.1286, + "Y": 32.89971, + "Z": -355.0208 + }, + "MinimumAngle": 80, + "MaximumAngle": 230 + } + ] + } + ] }, { - "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 - } + "Nodes": [ + { + "DataId": 33922, + "Locations": [ + { + "Position": { + "X": -304.0609, + "Y": 68.76999, + "Z": -479.1875 + }, + "MinimumAngle": -110, + "MaximumAngle": 70 + } + ] + }, + { + "DataId": 33923, + "Locations": [ + { + "Position": { + "X": -293.6989, + "Y": 68.77935, + "Z": -484.2256 + }, + "MinimumAngle": -30, + "MaximumAngle": 110 + }, + { + "Position": { + "X": -295.0806, + "Y": 69.12621, + "Z": -498.1898 + }, + "MinimumAngle": 10, + "MaximumAngle": 200 + }, + { + "Position": { + "X": -281.4858, + "Y": 67.64153, + "Z": -477.6673 + }, + "MinimumAngle": -90, + "MaximumAngle": 60 + } + ] + } + ] } ] } diff --git a/GatheringPaths/AssemblyGatheringLocationLoader.cs b/GatheringPaths/AssemblyGatheringLocationLoader.cs index 0417641..e74e59f 100644 --- a/GatheringPaths/AssemblyGatheringLocationLoader.cs +++ b/GatheringPaths/AssemblyGatheringLocationLoader.cs @@ -16,12 +16,10 @@ public static partial class AssemblyGatheringLocationLoader if (_locations == null) { _locations = []; -#if RELEASE LoadLocations(); -#endif } - return _locations ?? throw new InvalidOperationException("quest data is not initialized"); + return _locations ?? throw new InvalidOperationException("location data is not initialized"); } public static Stream QuestSchema => diff --git a/GatheringPaths/GatheringPaths.csproj b/GatheringPaths/GatheringPaths.csproj index f9e9725..8a5f329 100644 --- a/GatheringPaths/GatheringPaths.csproj +++ b/GatheringPaths/GatheringPaths.csproj @@ -26,7 +26,7 @@ - + diff --git a/GatheringPaths/gatheringlocation-v1.json b/GatheringPaths/gatheringlocation-v1.json index 53b34f7..cba558a 100644 --- a/GatheringPaths/gatheringlocation-v1.json +++ b/GatheringPaths/gatheringlocation-v1.json @@ -25,41 +25,64 @@ "AetheryteShortcut": { "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Aetheryte" }, - "Nodes": { + "Groups": { "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 + "Nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "DataId": { + "type": "number", + "minimum": 30000, + "maximum": 50000 + }, + "Locations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "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": [ + "Position" + ], + "additionalProperties": false + } + } + }, + "required": [ + "DataId" + ], + "additionalProperties": false + } } }, "required": [ - "DataId", - "Position" + "Nodes" ], "additionalProperties": false } diff --git a/QuestPathGenerator/GatheringSourceGenerator.cs b/QuestPathGenerator/GatheringSourceGenerator.cs index a10acd0..4995c3e 100644 --- a/QuestPathGenerator/GatheringSourceGenerator.cs +++ b/QuestPathGenerator/GatheringSourceGenerator.cs @@ -153,7 +153,7 @@ public class GatheringSourceGenerator : ISourceGenerator Assignment(nameof(GatheringRoot.TerritoryId), root.TerritoryId, default) .AsSyntaxNodeOrToken(), Assignment(nameof(GatheringRoot.AetheryteShortcut), root.AetheryteShortcut, null), - AssignmentList(nameof(GatheringRoot.Nodes), root.Nodes).AsSyntaxNodeOrToken())))); + AssignmentList(nameof(GatheringRoot.Groups), root.Groups).AsSyntaxNodeOrToken())))); } catch (Exception e) { diff --git a/QuestPathGenerator/RoslynShortcuts.cs b/QuestPathGenerator/RoslynShortcuts.cs index 4f5a8fb..07b8291 100644 --- a/QuestPathGenerator/RoslynShortcuts.cs +++ b/QuestPathGenerator/RoslynShortcuts.cs @@ -314,30 +314,55 @@ public static class RoslynShortcuts Assignment(nameof(SkipAetheryteCondition.InSameTerritory), skipAetheryteCondition.InSameTerritory, emptyAetheryte.InSameTerritory))))); } - else if (value is GatheringNodeLocation nodeLocation) + else if (value is GatheringNodeGroup nodeGroup) { - var emptyLocation = new GatheringNodeLocation(); return ObjectCreationExpression( - IdentifierName(nameof(GatheringNodeLocation))) + IdentifierName(nameof(GatheringNodeGroup))) .WithInitializer( InitializerExpression( SyntaxKind.ObjectInitializerExpression, SeparatedList( SyntaxNodeList( - Assignment(nameof(GatheringNodeLocation.DataId), nodeLocation.DataId, + AssignmentList(nameof(GatheringNodeGroup.Nodes), nodeGroup.Nodes) + .AsSyntaxNodeOrToken())))); + } + else if (value is GatheringNode nodeLocation) + { + var emptyLocation = new GatheringNode(); + return ObjectCreationExpression( + IdentifierName(nameof(GatheringNode))) + .WithInitializer( + InitializerExpression( + SyntaxKind.ObjectInitializerExpression, + SeparatedList( + SyntaxNodeList( + Assignment(nameof(GatheringNode.DataId), nodeLocation.DataId, emptyLocation.DataId) .AsSyntaxNodeOrToken(), - Assignment(nameof(GatheringNodeLocation.Position), nodeLocation.Position, + AssignmentList(nameof(GatheringNode.Locations), nodeLocation.Locations) + .AsSyntaxNodeOrToken())))); + } + else if (value is GatheringLocation location) + { + var emptyLocation = new GatheringLocation(); + return ObjectCreationExpression( + IdentifierName(nameof(GatheringLocation))) + .WithInitializer( + InitializerExpression( + SyntaxKind.ObjectInitializerExpression, + SeparatedList( + SyntaxNodeList( + Assignment(nameof(GatheringLocation.Position), location.Position, emptyLocation.Position).AsSyntaxNodeOrToken(), - Assignment(nameof(GatheringNodeLocation.MinimumAngle), nodeLocation.MinimumAngle, + Assignment(nameof(GatheringLocation.MinimumAngle), location.MinimumAngle, emptyLocation.MinimumAngle).AsSyntaxNodeOrToken(), - Assignment(nameof(GatheringNodeLocation.MaximumAngle), nodeLocation.MaximumAngle, + Assignment(nameof(GatheringLocation.MaximumAngle), location.MaximumAngle, emptyLocation.MaximumAngle).AsSyntaxNodeOrToken(), - Assignment(nameof(GatheringNodeLocation.MinimumDistance), - nodeLocation.MinimumDistance, emptyLocation.MinimumDistance) + Assignment(nameof(GatheringLocation.MinimumDistance), + location.MinimumDistance, emptyLocation.MinimumDistance) .AsSyntaxNodeOrToken(), - Assignment(nameof(GatheringNodeLocation.MaximumDistance), - nodeLocation.MaximumDistance, emptyLocation.MaximumDistance) + Assignment(nameof(GatheringLocation.MaximumDistance), + location.MaximumDistance, emptyLocation.MaximumDistance) .AsSyntaxNodeOrToken())))); } else if (value is null) diff --git a/QuestPathGenerator/Utils.cs b/QuestPathGenerator/Utils.cs index 12873a7..5e1baac 100644 --- a/QuestPathGenerator/Utils.cs +++ b/QuestPathGenerator/Utils.cs @@ -55,12 +55,13 @@ public static class Utils Culture = CultureInfo.InvariantCulture, OutputFormat = OutputFormat.List, }); - if (!evaluationResult.IsValid) + if (evaluationResult.HasErrors) { var error = Diagnostic.Create(invalidJson, null, Path.GetFileName(additionalFile.Path)); context.ReportDiagnostic(error); + continue; } yield return (id, node); diff --git a/Questionable.Model/Gathering/GatheringLocation.cs b/Questionable.Model/Gathering/GatheringLocation.cs new file mode 100644 index 0000000..5d14a55 --- /dev/null +++ b/Questionable.Model/Gathering/GatheringLocation.cs @@ -0,0 +1,21 @@ +using System.Numerics; +using System.Text.Json.Serialization; +using Questionable.Model.Common.Converter; + +namespace Questionable.Model.Gathering; + +public sealed class GatheringLocation +{ + [JsonConverter(typeof(VectorConverter))] + public Vector3 Position { get; set; } + + public float? MinimumAngle { get; set; } + public float? MaximumAngle { get; set; } + public float MinimumDistance { get; set; } = 1f; + public float MaximumDistance { get; set; } = 3f; + + public bool IsCone() + { + return MinimumAngle != null && MaximumAngle != null; + } +} diff --git a/Questionable.Model/Gathering/GatheringNode.cs b/Questionable.Model/Gathering/GatheringNode.cs new file mode 100644 index 0000000..a88f53e --- /dev/null +++ b/Questionable.Model/Gathering/GatheringNode.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace Questionable.Model.Gathering; + +public sealed class GatheringNode +{ + public uint DataId { get; set; } + + public List Locations { get; set; } = []; +} diff --git a/Questionable.Model/Gathering/GatheringNodeGroup.cs b/Questionable.Model/Gathering/GatheringNodeGroup.cs new file mode 100644 index 0000000..7922d62 --- /dev/null +++ b/Questionable.Model/Gathering/GatheringNodeGroup.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace Questionable.Model.Gathering; + +public sealed class GatheringNodeGroup +{ + public List Nodes { get; set; } = []; +} diff --git a/Questionable.Model/Gathering/GatheringNodeLocation.cs b/Questionable.Model/Gathering/GatheringNodeLocation.cs deleted file mode 100644 index 49a5e64..0000000 --- a/Questionable.Model/Gathering/GatheringNodeLocation.cs +++ /dev/null @@ -1,13 +0,0 @@ -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 index c572faa..5670482 100644 --- a/Questionable.Model/Gathering/GatheringRoot.cs +++ b/Questionable.Model/Gathering/GatheringRoot.cs @@ -14,5 +14,5 @@ public sealed class GatheringRoot [JsonConverter(typeof(AetheryteConverter))] public EAetheryteLocation? AetheryteShortcut { get; set; } - public List Nodes { get; set; } = []; + public List Groups { get; set; } = []; } diff --git a/Questionable.sln b/Questionable.sln index b531428..7ca82fc 100644 --- a/Questionable.sln +++ b/Questionable.sln @@ -19,6 +19,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GatheringPaths", "Gathering EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GatheringPathRenderer", "GatheringPathRenderer\GatheringPathRenderer.csproj", "{F514DA95-9867-4F3F-8062-ACE0C62E8740}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ECommons", "vendor\ECommons\ECommons\ECommons.csproj", "{A12D7B4B-8E6E-4DCF-A41A-12F62E9FF94B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -57,6 +59,10 @@ Global {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 + {A12D7B4B-8E6E-4DCF-A41A-12F62E9FF94B}.Debug|x64.ActiveCfg = Debug|x64 + {A12D7B4B-8E6E-4DCF-A41A-12F62E9FF94B}.Debug|x64.Build.0 = Debug|x64 + {A12D7B4B-8E6E-4DCF-A41A-12F62E9FF94B}.Release|x64.ActiveCfg = Release|x64 + {A12D7B4B-8E6E-4DCF-A41A-12F62E9FF94B}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Questionable/Controller/QuestRegistry.cs b/Questionable/Controller/QuestRegistry.cs index f472c11..038fe12 100644 --- a/Questionable/Controller/QuestRegistry.cs +++ b/Questionable/Controller/QuestRegistry.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Text.Json; using System.Text.Json.Nodes; using Dalamud.Plugin; +using Dalamud.Plugin.Ipc; using Microsoft.Extensions.Logging; using Questionable.Data; using Questionable.Model; @@ -23,8 +24,9 @@ internal sealed class QuestRegistry private readonly IDalamudPluginInterface _pluginInterface; private readonly QuestData _questData; private readonly QuestValidator _questValidator; - private readonly ILogger _logger; private readonly JsonSchemaValidator _jsonSchemaValidator; + private readonly ILogger _logger; + private readonly ICallGateProvider _reloadDataIpc; private readonly Dictionary _quests = new(); @@ -37,6 +39,7 @@ internal sealed class QuestRegistry _questValidator = questValidator; _jsonSchemaValidator = jsonSchemaValidator; _logger = logger; + _reloadDataIpc = _pluginInterface.GetIpcProvider("Questionable.ReloadData"); } public IEnumerable AllQuests => _quests.Values; @@ -66,6 +69,7 @@ internal sealed class QuestRegistry ValidateQuests(); Reloaded?.Invoke(this, EventArgs.Empty); + _reloadDataIpc.SendMessage(); _logger.LogInformation("Loaded {Count} quests in total", _quests.Count); } diff --git a/vendor/ECommons b/vendor/ECommons new file mode 160000 index 0000000..9e90d00 --- /dev/null +++ b/vendor/ECommons @@ -0,0 +1 @@ +Subproject commit 9e90d0032f0efd4c9e65d9c5a8e8bd0e99557d68