From 0ed129f8a6fb4ef61110864daed79536c2df16ba Mon Sep 17 00:00:00 2001
From: Liza Carvelli <liza@carvel.li>
Date: Sat, 13 Jul 2024 13:47:49 +0200
Subject: [PATCH] Fix not being able to attune to aetherytes/aethernet shards
 if certain other GameObjects share the same DataId

---
 .../4358_Old Sharlayan New to You.json        |  1 +
 .../4359_Hitting the Books.json               |  1 +
 .../Steps/Interactions/AethernetShard.cs      |  4 ++-
 Questionable/GameFunctions.cs                 | 25 ++++++++++++-------
 4 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/QuestPaths/6.x - Endwalker/MSQ/A-Thavnair1-Labyrinthos1/4358_Old Sharlayan New to You.json b/QuestPaths/6.x - Endwalker/MSQ/A-Thavnair1-Labyrinthos1/4358_Old Sharlayan New to You.json
index 8c3c3f09..2d27822a 100644
--- a/QuestPaths/6.x - Endwalker/MSQ/A-Thavnair1-Labyrinthos1/4358_Old Sharlayan New to You.json	
+++ b/QuestPaths/6.x - Endwalker/MSQ/A-Thavnair1-Labyrinthos1/4358_Old Sharlayan New to You.json	
@@ -27,6 +27,7 @@
             "Y": -16.246998,
             "Z": 147.02063
           },
+          "StopDistance": 5,
           "TerritoryId": 962,
           "InteractionType": "Interact"
         }
diff --git a/QuestPaths/6.x - Endwalker/MSQ/A-Thavnair1-Labyrinthos1/4359_Hitting the Books.json b/QuestPaths/6.x - Endwalker/MSQ/A-Thavnair1-Labyrinthos1/4359_Hitting the Books.json
index 3b85e5b7..60212ed8 100644
--- a/QuestPaths/6.x - Endwalker/MSQ/A-Thavnair1-Labyrinthos1/4359_Hitting the Books.json	
+++ b/QuestPaths/6.x - Endwalker/MSQ/A-Thavnair1-Labyrinthos1/4359_Hitting the Books.json	
@@ -12,6 +12,7 @@
             "Y": 1.9073486E-06,
             "Z": 0.16778564
           },
+          "StopDistance": 5,
           "TerritoryId": 987,
           "InteractionType": "AcceptQuest"
         }
diff --git a/Questionable/Controller/Steps/Interactions/AethernetShard.cs b/Questionable/Controller/Steps/Interactions/AethernetShard.cs
index 059a2c34..5177c078 100644
--- a/Questionable/Controller/Steps/Interactions/AethernetShard.cs
+++ b/Questionable/Controller/Steps/Interactions/AethernetShard.cs
@@ -1,8 +1,10 @@
 using System;
+using FFXIVClientStructs.FFXIV.Client.Game.Object;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Logging;
 using Questionable.Model;
 using Questionable.Model.V1;
+using ObjectKind = Dalamud.Game.ClientState.Objects.Enums.ObjectKind;
 
 namespace Questionable.Controller.Steps.Interactions;
 
@@ -37,7 +39,7 @@ internal static class AethernetShard
             if (!gameFunctions.IsAetheryteUnlocked(AetheryteLocation))
             {
                 logger.LogInformation("Attuning to aethernet shard {AethernetShard}", AetheryteLocation);
-                gameFunctions.InteractWith((uint)AetheryteLocation);
+                gameFunctions.InteractWith((uint)AetheryteLocation, ObjectKind.Aetheryte);
                 return true;
             }
 
diff --git a/Questionable/GameFunctions.cs b/Questionable/GameFunctions.cs
index d26e139a..f8e5fd2f 100644
--- a/Questionable/GameFunctions.cs
+++ b/Questionable/GameFunctions.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.Linq;
 using System.Numerics;
-using Dalamud.Game;
 using Dalamud.Game.ClientState.Conditions;
 using Dalamud.Game.ClientState.Objects;
 using Dalamud.Game.ClientState.Objects.Types;
@@ -29,6 +28,7 @@ using ContentFinderCondition = Lumina.Excel.GeneratedSheets.ContentFinderConditi
 using ContentTalk = Lumina.Excel.GeneratedSheets.ContentTalk;
 using EventPathMove = Lumina.Excel.GeneratedSheets.EventPathMove;
 using GrandCompany = FFXIVClientStructs.FFXIV.Client.UI.Agent.GrandCompany;
+using ObjectKind = Dalamud.Game.ClientState.Objects.Enums.ObjectKind;
 using Quest = Questionable.Model.Quest;
 using TerritoryType = Lumina.Excel.GeneratedSheets.TerritoryType;
 
@@ -316,11 +316,15 @@ internal sealed unsafe class GameFunctions
                playerState->IsAetherCurrentUnlocked(aetherCurrentId);
     }
 
-    public IGameObject? FindObjectByDataId(uint dataId)
+    public IGameObject? FindObjectByDataId(uint dataId, ObjectKind? kind = null)
     {
         foreach (var gameObject in _objectTable)
         {
-            if (gameObject.DataId == dataId)
+            if (gameObject.ObjectKind is ObjectKind.Player or ObjectKind.Companion or ObjectKind.MountType
+                or ObjectKind.Retainer or ObjectKind.Housing)
+                continue;
+
+            if (gameObject.DataId == dataId && (kind == null || kind.Value == gameObject.ObjectKind))
             {
                 return gameObject;
             }
@@ -330,9 +334,9 @@ internal sealed unsafe class GameFunctions
         return null;
     }
 
-    public bool InteractWith(uint dataId)
+    public bool InteractWith(uint dataId, ObjectKind? kind = null)
     {
-        IGameObject? gameObject = FindObjectByDataId(dataId);
+        IGameObject? gameObject = FindObjectByDataId(dataId, kind);
         if (gameObject != null)
         {
             _logger.LogInformation("Setting target with {DataId} to {ObjectId}", dataId, gameObject.EntityId);
@@ -342,7 +346,7 @@ internal sealed unsafe class GameFunctions
             long result = (long)TargetSystem.Instance()->InteractWithObject((GameObject*)gameObject.Address, false);
 
             _logger.LogInformation("Interact result: {Result}", result);
-            return result > 0;
+            return result != 7 && result > 0;
         }
 
         _logger.LogDebug("Game object is null");
@@ -413,11 +417,14 @@ internal sealed unsafe class GameFunctions
             if (actionRow.TargetArea)
             {
                 Vector3 position = gameObject.Position;
-                result = ActionManager.Instance()->UseActionLocation(ActionType.Action, (uint)action, location: &position);
-                _logger.LogInformation("UseAction {Action} on target area {Target} result: {Result}", action, gameObject,
+                result = ActionManager.Instance()->UseActionLocation(ActionType.Action, (uint)action,
+                    location: &position);
+                _logger.LogInformation("UseAction {Action} on target area {Target} result: {Result}", action,
+                    gameObject,
                     result);
             }
-            else {
+            else
+            {
                 result = ActionManager.Instance()->UseAction(ActionType.Action, (uint)action, gameObject.GameObjectId);
                 _logger.LogInformation("UseAction {Action} on target {Target} result: {Result}", action, gameObject,
                     result);