Update serialization of QuestStep
authorLiza Carvelli <liza@carvel.li>
Thu, 15 Aug 2024 23:51:12 +0000 (01:51 +0200)
committerLiza Carvelli <liza@carvel.li>
Thu, 15 Aug 2024 23:51:12 +0000 (01:51 +0200)
GatheringPathRenderer/RendererPlugin.cs
GatheringPaths/3.x - Heavensward/The Dravanian Hinterlands/353_The Makers' Quarter_MIN.json
GatheringPaths/3.x - Heavensward/The Dravanian Hinterlands/361_The Answering Quarter_BTN.json
GatheringPaths/3.x - Heavensward/The Dravanian Hinterlands/723_Quickspill Delta_BTN.json [new file with mode: 0644]
Questionable.Model/Questing/QuestStep.cs
Questionable/Controller/QuestController.cs
Questionable/Functions/QuestFunctions.cs

index 95edf94c54504c4364e651bedf360f4a5e6f1701..f3c52afcf70bba1ac3676f04c964b9c204a20d0b 100644 (file)
@@ -1,4 +1,5 @@
 using System;
+using System.Collections;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
@@ -6,6 +7,7 @@ using System.Text.Encodings.Web;
 using System.Text.Json;
 using System.Text.Json.Nodes;
 using System.Text.Json.Serialization;
+using System.Text.Json.Serialization.Metadata;
 using Dalamud.Game.ClientState.Objects;
 using Dalamud.Interface.Windowing;
 using Dalamud.Plugin;
@@ -155,6 +157,10 @@ public sealed class RendererPlugin : IDalamudPlugin
             Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
             DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault,
             WriteIndented = true,
+            TypeInfoResolver = new DefaultJsonTypeInfoResolver
+            {
+                Modifiers = { NoEmptyCollectionModifier }
+            },
         };
         using (var stream = File.Create(targetFile.FullName))
         {
@@ -176,6 +182,17 @@ public sealed class RendererPlugin : IDalamudPlugin
         Reload();
     }
 
+    private static void NoEmptyCollectionModifier(JsonTypeInfo typeInfo)
+    {
+        foreach (var property in typeInfo.Properties)
+        {
+            if (typeof(ICollection).IsAssignableFrom(property.PropertyType))
+            {
+                property.ShouldSerialize = (_, val) => val is ICollection { Count: > 0 };
+            }
+        }
+    }
+
     private void TerritoryChanged(ushort territoryId) => Redraw();
 
     private void ClassJobChanged(uint classJobId)
@@ -234,7 +251,8 @@ public sealed class RendererPlugin : IDalamudPlugin
                                     refZ = x.Position.Y,
                                     Filled = true,
                                     radius = locationOverride?.MinimumDistance ?? x.CalculateMinimumDistance(),
-                                    Donut = (locationOverride?.MaximumDistance ?? x.CalculateMaximumDistance()) - (locationOverride?.MinimumDistance ?? x.CalculateMinimumDistance()),
+                                    Donut = (locationOverride?.MaximumDistance ?? x.CalculateMaximumDistance()) -
+                                            (locationOverride?.MinimumDistance ?? x.CalculateMinimumDistance()),
                                     color = _colors[location.Root.Groups.IndexOf(group) % _colors.Count],
                                     Enabled = true,
                                     coneAngleMin = minimumAngle,
index d462b45309d9a1deb0c2e1109968601430e59810..494cd5deca16f9ec5b3e51b72a4940313c60d931 100644 (file)
@@ -9,7 +9,14 @@
       "AethernetShortcut": [
         "[Idyllshire] Aetheryte Plaza",
         "[Idyllshire] Epilogue Gate (Eastern Hinterlands)"
-      ]
+      ],
+      "SkipConditions": {
+        "AetheryteShortcutIf": {
+          "InTerritory": [
+            399
+          ]
+        }
+      }
     }
   ],
   "Groups": [
index 64e5cb8d4beb58be459968c62bf383963ebfd04d..613830f1e0fcfaf244479fb6cfe24cdda12393de 100644 (file)
@@ -9,7 +9,14 @@
       "AethernetShortcut": [
         "[Idyllshire] Aetheryte Plaza",
         "[Idyllshire] Prologue Gate (Western Hinterlands)"
-      ]
+      ],
+      "SkipConditions": {
+        "AetheryteShortcutIf": {
+          "InTerritory": [
+            399
+          ]
+        }
+      }
     }
   ],
   "Groups": [
diff --git a/GatheringPaths/3.x - Heavensward/The Dravanian Hinterlands/723_Quickspill Delta_BTN.json b/GatheringPaths/3.x - Heavensward/The Dravanian Hinterlands/723_Quickspill Delta_BTN.json
new file mode 100644 (file)
index 0000000..99a15ed
--- /dev/null
@@ -0,0 +1,119 @@
+{
+  "$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
+  "Author": "liza",
+  "Steps": [
+    {
+      "TerritoryId": 399,
+      "InteractionType": "None",
+      "AetheryteShortcut": "Idyllshire",
+      "AethernetShortcut": [
+        "[Idyllshire] Aetheryte Plaza",
+        "[Idyllshire] Prologue Gate (Western Hinterlands)"
+      ],
+      "SkipConditions": {
+        "AetheryteShortcutIf": {
+          "InTerritory": [
+            399
+          ]
+        }
+      }
+    }
+  ],
+  "Groups": [
+    {
+      "Nodes": [
+        {
+          "DataId": 33285,
+          "Locations": [
+            {
+              "Position": {
+                "X": -426.4134,
+                "Y": 137.5601,
+                "Z": 514.3357
+              }
+            }
+          ]
+        },
+        {
+          "DataId": 33286,
+          "Locations": [
+            {
+              "Position": {
+                "X": -448.7838,
+                "Y": 137.5986,
+                "Z": 514.3243
+              }
+            },
+            {
+              "Position": {
+                "X": -433.5015,
+                "Y": 137.6451,
+                "Z": 487.8173
+              }
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "Nodes": [
+        {
+          "DataId": 33288,
+          "Locations": [
+            {
+              "Position": {
+                "X": -354.5423,
+                "Y": 137.5715,
+                "Z": 638.9959
+              }
+            }
+          ]
+        },
+        {
+          "DataId": 33287,
+          "Locations": [
+            {
+              "Position": {
+                "X": -352.4377,
+                "Y": 137.5906,
+                "Z": 604.364
+              }
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "Nodes": [
+        {
+          "DataId": 33284,
+          "Locations": [
+            {
+              "Position": {
+                "X": -254.4776,
+                "Y": 137.97,
+                "Z": 591.0092
+              },
+              "MinimumAngle": -20,
+              "MaximumAngle": 85
+            }
+          ]
+        },
+        {
+          "DataId": 33283,
+          "Locations": [
+            {
+              "Position": {
+                "X": -263.1079,
+                "Y": 137.4419,
+                "Z": 569.8724
+              },
+              "MinimumAngle": -10,
+              "MaximumAngle": 190
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
index 58a7a5b6a262ccb59a0dd16e16524457058339ac..152abc745b571f634daa7c8486f3214f9ccb10e0 100644 (file)
@@ -1,4 +1,5 @@
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using System.Numerics;
 using System.Text.Json.Serialization;
 using Questionable.Model.Common;
@@ -7,20 +8,23 @@ using Questionable.Model.Questing.Converter;
 
 namespace Questionable.Model.Questing;
 
+[SuppressMessage("ReSharper", "CollectionNeverUpdated.Global")]
 public sealed class QuestStep
 {
     public const float DefaultStopDistance = 3f;
 
-    public EInteractionType InteractionType { get; set; }
-
     public uint? DataId { get; set; }
 
     [JsonConverter(typeof(VectorConverter))]
     public Vector3? Position { get; set; }
 
     public float? StopDistance { get; set; }
-    public float? NpcWaitDistance { get; set; }
     public ushort TerritoryId { get; set; }
+
+    [JsonIgnore(Condition = JsonIgnoreCondition.Never)]
+    public EInteractionType InteractionType { get; set; }
+
+    public float? NpcWaitDistance { get; set; }
     public ushort? TargetTerritoryId { get; set; }
     public float? DelaySecondsAtStart { get; set; }
 
@@ -57,8 +61,8 @@ public sealed class QuestStep
     public EAction? Action { get; set; }
 
     public EEnemySpawnType? EnemySpawnType { get; set; }
-    public IList<uint> KillEnemyDataIds { get; set; } = new List<uint>();
-    public IList<ComplexCombatData> ComplexCombatData { get; set; } = new List<ComplexCombatData>();
+    public List<uint> KillEnemyDataIds { get; set; } = [];
+    public List<ComplexCombatData> ComplexCombatData { get; set; } = [];
     public float? CombatDelaySecondsAtStart { get; set; }
 
     public JumpDestination? JumpDestination { get; set; }
@@ -67,9 +71,9 @@ public sealed class QuestStep
 
     public List<List<QuestWorkValue>?> RequiredQuestVariables { get; set; } = new();
     public List<GatheredItem> RequiredGatheredItems { get; set; } = [];
-    public IList<QuestWorkValue?> CompletionQuestVariablesFlags { get; set; } = new List<QuestWorkValue?>();
-    public IList<DialogueChoice> DialogueChoices { get; set; } = new List<DialogueChoice>();
-    public IList<uint> PointMenuChoices { get; set; } = new List<uint>();
+    public List<QuestWorkValue?> CompletionQuestVariablesFlags { get; set; } = [];
+    public List<DialogueChoice> DialogueChoices { get; set; } = [];
+    public List<uint> PointMenuChoices { get; set; } = [];
 
     // TODO: Not implemented
     [JsonConverter(typeof(ElementIdConverter))]
index a9cc655001f3da2b7398faebba725319a22b01f1..c4805bb00dae75b6364b67bc37f838f967d11938 100644 (file)
@@ -773,7 +773,6 @@ internal sealed class QuestController : MiniTaskController<QuestController>, IDi
             if (toastAware.OnErrorToast(message))
             {
                 isHandled = true;
-                return;
             }
         }
     }
index 0ac8157f6aea4da778264796090b3ee3076927d3..c26acc8d9550cc8afd2c3e288eebaee43ca5e8f6 100644 (file)
@@ -278,13 +278,13 @@ internal sealed unsafe class QuestFunctions
                 if (!_questRegistry.TryGetQuest(x, out Quest? quest))
                     return false;
 
-                return quest.AllSteps().All(x =>
+                return quest.AllSteps().All(y =>
                 {
-                    if (x.Step.AetheryteShortcut is { } aetheryteShortcut &&
+                    if (y.Step.AetheryteShortcut is { } aetheryteShortcut &&
                         _aetheryteFunctions.IsAetheryteUnlocked(aetheryteShortcut))
                         return false;
 
-                    if (x.Step.AethernetShortcut is { } aethernetShortcut &&
+                    if (y.Step.AethernetShortcut is { } aethernetShortcut &&
                         (!_aetheryteFunctions.IsAetheryteUnlocked(aethernetShortcut.From) ||
                          !_aetheryteFunctions.IsAetheryteUnlocked(aethernetShortcut.To)))
                         return false;