Fixes for early limsa quests
authorLiza Carvelli <liza@carvel.li>
Thu, 22 Aug 2024 10:14:12 +0000 (12:14 +0200)
committerLiza Carvelli <liza@carvel.li>
Thu, 22 Aug 2024 10:14:12 +0000 (12:14 +0200)
QuestPathGenerator/RoslynElements/QuestStepExtensions.cs
QuestPaths/2.x - A Realm Reborn/MSQ-1/Limsa/402_Thanks a Million.json
QuestPaths/2.x - A Realm Reborn/MSQ-1/Limsa/465_Washed Up.json
QuestPaths/quest-v1.json
Questionable.Model/Questing/QuestStep.cs
Questionable/Controller/Steps/Interactions/Interact.cs

index 0e4e9dd0cc4c079fa6f72341f1fe0643c6f4e62a..11cdc214207d70a7c4dba6f68a2360430d74cdd8 100644 (file)
@@ -44,6 +44,8 @@ internal static class QuestStepExtensions
                             Assignment(nameof(QuestStep.DelaySecondsAtStart), step.DelaySecondsAtStart,
                                     emptyStep.DelaySecondsAtStart)
                                 .AsSyntaxNodeOrToken(),
+                            Assignment(nameof(QuestStep.PickUpItemId), step.PickUpItemId, emptyStep.PickUpItemId)
+                                .AsSyntaxNodeOrToken(),
                             Assignment(nameof(QuestStep.Disabled), step.Disabled, emptyStep.Disabled)
                                 .AsSyntaxNodeOrToken(),
                             Assignment(nameof(QuestStep.DisableNavmesh), step.DisableNavmesh,
index 2f02ad56e3abd2cdaa2c0d8146a8b567e56273a5..88a45ef3801ef7ccc18f0c5269b309c63acb8b49 100644 (file)
@@ -29,7 +29,8 @@
           },
           "TerritoryId": 134,
           "InteractionType": "Interact",
-          "Comment": "Technically triggers combat, but can be ignored"
+          "Comment": "Technically triggers combat, but can be ignored",
+          "PickUpItemId": 2000342
         }
       ]
     },
index 8a9700f89a7946c1f9f12dfacde88469dfc7d240..2619b49f89ca9dd94884e523db12d7c036169222 100644 (file)
@@ -59,6 +59,7 @@
           "StopDistance": 5,
           "TerritoryId": 134,
           "InteractionType": "Interact",
+          "DelaySecondsAtStart": 3,
           "DialogueChoices": [
             {
               "Type": "List",
index 06f9a711c632c9d76ba1524275103d8091509bbf..c717679f2aac6d76d5c3e84a2d9597017c01916d 100644 (file)
             }
           },
           "then": {
+            "properties": {
+              "PickUpItemId": {
+                "type": "number"
+              }
+            },
             "required": [
               "DataId"
             ]
index bb2f71402fd06a0a4667787d68b51f816ad69e25..a09386bc1c6ad4aca8b3c7d49fddfa342f893d17 100644 (file)
@@ -27,6 +27,7 @@ public sealed class QuestStep
     public float? NpcWaitDistance { get; set; }
     public ushort? TargetTerritoryId { get; set; }
     public float? DelaySecondsAtStart { get; set; }
+    public uint? PickUpItemId { get; set; }
 
     public bool Disabled { get; set; }
     public bool DisableNavmesh { get; set; }
index 49b9e419ff91448c4a7c86360654d9bd78fb1f38..0482d88b09b3f78b888162c5ec587264742403b5 100644 (file)
@@ -4,6 +4,7 @@ using Dalamud.Game.ClientState.Conditions;
 using Dalamud.Game.ClientState.Objects.Enums;
 using Dalamud.Game.ClientState.Objects.Types;
 using Dalamud.Plugin.Services;
+using FFXIVClientStructs.FFXIV.Client.Game;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Logging;
 using Questionable.Controller.Steps.Shared;
@@ -15,7 +16,8 @@ namespace Questionable.Controller.Steps.Interactions;
 
 internal static class Interact
 {
-    internal sealed class Factory(GameFunctions gameFunctions, ICondition condition, ILoggerFactory loggerFactory) : ITaskFactory
+    internal sealed class Factory(GameFunctions gameFunctions, ICondition condition, ILoggerFactory loggerFactory)
+        : ITaskFactory
     {
         public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
         {
@@ -39,13 +41,14 @@ internal static class Interact
                 yield return new WaitAtEnd.WaitDelay();
 
             yield return Interact(step.DataId.Value, quest, step.InteractionType,
-                    step.TargetTerritoryId != null || quest.Id is SatisfactionSupplyNpcId);
+                step.TargetTerritoryId != null || quest.Id is SatisfactionSupplyNpcId, step.PickUpItemId);
         }
 
-        internal ITask Interact(uint dataId, Quest? quest, EInteractionType interactionType, bool skipMarkerCheck = false)
+        internal ITask Interact(uint dataId, Quest? quest, EInteractionType interactionType,
+            bool skipMarkerCheck = false, uint? pickUpItemId = null)
         {
-            return new DoInteract(dataId, quest, interactionType, skipMarkerCheck, gameFunctions, condition,
-                loggerFactory.CreateLogger<DoInteract>());
+            return new DoInteract(dataId, quest, interactionType, skipMarkerCheck, pickUpItemId, gameFunctions,
+                condition, loggerFactory.CreateLogger<DoInteract>());
         }
     }
 
@@ -54,6 +57,7 @@ internal static class Interact
         Quest? quest,
         EInteractionType interactionType,
         bool skipMarkerCheck,
+        uint? pickUpItemId,
         GameFunctions gameFunctions,
         ICondition condition,
         ILogger<DoInteract> logger)
@@ -64,6 +68,7 @@ internal static class Interact
         private DateTime _continueAt = DateTime.MinValue;
 
         public Quest? Quest => quest;
+
         public EInteractionType InteractionType
         {
             get => interactionType;
@@ -119,11 +124,23 @@ internal static class Interact
                     _needsUnmount = false;
             }
 
-            if (_interactionState == EInteractionState.InteractionConfirmed)
-                return ETaskResult.TaskComplete;
+            if (pickUpItemId != null)
+            {
+                unsafe
+                {
+                    InventoryManager* inventoryManager = InventoryManager.Instance();
+                    if (inventoryManager->GetInventoryItemCount(pickUpItemId.Value) > 0)
+                        return ETaskResult.TaskComplete;
+                }
+            }
+            else
+            {
+                if (_interactionState == EInteractionState.InteractionConfirmed)
+                    return ETaskResult.TaskComplete;
 
-            if (interactionType == EInteractionType.InternalGather && condition[ConditionFlag.Gathering])
-                return ETaskResult.TaskComplete;
+                if (interactionType == EInteractionType.InternalGather && condition[ConditionFlag.Gathering])
+                    return ETaskResult.TaskComplete;
+            }
 
             IGameObject? gameObject = gameFunctions.FindObjectByDataId(dataId);
             if (gameObject == null || !gameObject.IsTargetable || !HasAnyMarker(gameObject))