Add snipe cheat
authorLiza Carvelli <liza@carvel.li>
Wed, 11 Sep 2024 14:58:07 +0000 (16:58 +0200)
committerLiza Carvelli <liza@carvel.li>
Wed, 11 Sep 2024 14:58:07 +0000 (16:58 +0200)
34 files changed:
QuestPaths/4.x - Stormblood/Aether Currents/The Azim Steppe/2771_Sheep Snatcher.json
QuestPaths/4.x - Stormblood/Alliance Raid Quests/3091_Desire.json
QuestPaths/4.x - Stormblood/MSQ/A3.2-Yanxia 1/2495_A New Ruby Tithe.json
QuestPaths/4.x - Stormblood/MSQ/B-4.1/2970_Securing the Saltery.json
QuestPaths/5.x - Shadowbringers/Allied Societies/Pixies/Dailies/3707_Not the Beavers.json
QuestPaths/5.x - Shadowbringers/MSQ/A2-Kholusia 1/3285_A Fickle Existence.json
QuestPaths/5.x - Shadowbringers/MSQ/A3-Amh Araeng 1/3292_City of the Mord.json
QuestPaths/5.x - Shadowbringers/MSQ/C-Rak'tika/3323_A Little Faith.json
QuestPaths/5.x - Shadowbringers/MSQ/C-Rak'tika/3330_A Beeautiful Plan.json
QuestPaths/5.x - Shadowbringers/MSQ/E-Kholusia 2/3634_The View from Above.json
QuestPaths/5.x - Shadowbringers/MSQ/E-Kholusia 2/3637_Meet the Tholls.json
QuestPaths/5.x - Shadowbringers/MSQ/F-Tempest/3649_City of the Ancients.json
QuestPaths/5.x - Shadowbringers/MSQ/G-5.1/3680_Finding Good Help.json
QuestPaths/6.x - Endwalker/MSQ/A-Thavnair1-Labyrinthos1/4363_Deeper into the Maze.json
QuestPaths/6.x - Endwalker/MSQ/C-MareLamentorum/4406_Setting Things Straight.json
QuestPaths/6.x - Endwalker/MSQ/F-Labyrinthos2/4443_Wise Guides.json
QuestPaths/6.x - Endwalker/MSQ/G-UltimaThule/4460_x.json
QuestPaths/6.x - Endwalker/MSQ/G-UltimaThule/4461_Hello World.json
QuestPaths/6.x - Endwalker/Side Quests/Old Sharlayan/4181_Scholarly Perspective.json
QuestPaths/7.x - Dawntrail/MSQ/A-Kozama'uka1-Urqopacha1/4867_The Feat of Reeds.json
QuestPaths/7.x - Dawntrail/MSQ/B-Kozama'uka2-Urqopacha2/4881_Lending a Helphand.json
QuestPaths/7.x - Dawntrail/MSQ/D-Shaaloani-HeritageFound1/4921_Pick up the Pieces.json
QuestPaths/7.x - Dawntrail/Side Quests/Shaaloani/5126_A Refined Perspective.json
QuestPaths/7.x - Dawntrail/Side Quests/Yak T'el/5100_Carved in Stone.json
QuestPaths/quest-v1.json
Questionable.Model/Questing/Converter/InteractionTypeConverter.cs
Questionable.Model/Questing/EInteractionType.cs
Questionable/Configuration.cs
Questionable/Controller/Steps/Interactions/Interact.cs
Questionable/Controller/Steps/Shared/WaitAtEnd.cs
Questionable/Controller/Utils/AutoSnipeHandler.cs [new file with mode: 0644]
Questionable/QuestionablePlugin.cs
Questionable/Windows/ConfigWindow.cs
Questionable/Windows/QuestComponents/ActiveQuestComponent.cs

index 3d3167abd96141823326858c7772f46dda51cc96..034df26b628919402a1c5958bfb07db6e6a4d973 100644 (file)
@@ -28,7 +28,7 @@
             "Z": -210.22363
           },
           "TerritoryId": 622,
-          "InteractionType": "Instruction",
+          "InteractionType": "Snipe",
           "Comment": "Snipe sheep"
         }
       ]
index 4242e0f797a9fad256eb8eaeb2a81e85d3c48408..d0c8d2a9116db7db1bd40392583d4325aa9226ab 100644 (file)
@@ -54,7 +54,7 @@
             "Z": 208.484
           },
           "TerritoryId": 787,
-          "InteractionType": "Instruction",
+          "InteractionType": "Snipe",
           "Comment": "Far on the left"
         }
       ]
index b86394da0ae774f4cc88d24be2a4d7aeb2ba1bf1..1045490b669bfb9c6b773e8133644fc0148ec967 100644 (file)
             "Z": 147.23425
           },
           "TerritoryId": 614,
-          "InteractionType": "Instruction",
+          "InteractionType": "Snipe",
           "Comment": "Snipe soldiers"
         }
       ]
             "Z": 237.04883
           },
           "TerritoryId": 614,
-          "InteractionType": "Instruction",
+          "InteractionType": "Snipe",
           "Comment": "Snipe soldiers"
         }
       ]
             "Z": 603.2959
           },
           "TerritoryId": 614,
-          "InteractionType": "Instruction",
+          "InteractionType": "Snipe",
           "Comment": "Snipe soldiers"
         }
       ]
index 284a29d32b18b35cfa19dd542ada99188a3902f9..b7da884eb7375b3cd2d4e1aefc7d36aa74f514c9 100644 (file)
@@ -62,7 +62,7 @@
             "Z": 196.55139\r
           },\r
           "TerritoryId": 621,\r
-          "InteractionType": "Instruction",\r
+          "InteractionType": "Snipe",\r
           "Comment": "Aim at jaw",\r
           "Fly": true\r
         }\r
@@ -95,7 +95,7 @@
             "Z": 282.7954\r
           },\r
           "TerritoryId": 621,\r
-          "InteractionType": "Instruction",\r
+          "InteractionType": "Snipe",\r
           "Fly": true,\r
           "Comment": "Aim at nearest eye"\r
         }\r
index ae181ec1cc97724bcfe2d15fb8dc3596cd786173..8d99337d1816ce8f4e34c8a404b753e6df8e9330 100644 (file)
@@ -28,7 +28,7 @@
             "Z": 755.58093
           },
           "TerritoryId": 816,
-          "InteractionType": "Instruction",
+          "InteractionType": "Snipe",
           "Fly": true,
           "Comment": "Throw Porxies at Beavers"
         }
index d70949f9f652f28a097686aac611dbc76ebf16c0..78b6e3cac7b208e94fd90e907b06941fc6cdfff5 100644 (file)
@@ -48,7 +48,7 @@
             "Z": 656.9772
           },
           "TerritoryId": 814,
-          "InteractionType": "Instruction",
+          "InteractionType": "Snipe",
           "Comment": "Click the guy in front of (or near) the light house stairs"
         }
       ]
index ded86bd5f2d215ef1f9b9e56df00220756a4e9a2..813814f30e42edd6b6358ffc47570af34311610b 100644 (file)
@@ -48,7 +48,7 @@
             "Z": -186.14484
           },
           "TerritoryId": 815,
-          "InteractionType": "Instruction",
+          "InteractionType": "Snipe",
           "Comment": "Click all four foods"
         }
       ]
index a5286f4e7fd62824e2d90c37b1100ec15e3f1766..b5c2d0d61d4ce07ee13843ed4609fd74ba105e13 100644 (file)
             "Z": -92.97333
           },
           "TerritoryId": 813,
-          "InteractionType": "WaitForManualProgress",
+          "InteractionType": "Snipe",
           "Comment": "Tablet is on the right middle shelf of the table"
         }
       ]
index 960e9293771b520274bfd3a0aece79cc6b48012d..51a28c182021d48b04ae2cb3b6cad7da25fc9195 100644 (file)
@@ -84,7 +84,7 @@
             "Z": -359.4873
           },
           "TerritoryId": 817,
-          "InteractionType": "WaitForManualProgress",
+          "InteractionType": "Snipe",
           "Comment": "Click murals"
         }
       ]
index 2c9e1fff4421265e918762b904ad8cfcdfabcd63..5285a8a242c09ce03cb098e95c90f39525988238 100644 (file)
@@ -73,7 +73,7 @@
             "Z": 22.47644
           },
           "TerritoryId": 814,
-          "InteractionType": "WaitForManualProgress",
+          "InteractionType": "Snipe",
           "Comment": "Click on the guy left of the the rock"
         }
       ]
index ee2b89dc8cb3ecfc92c6006124bb8265d58199c3..8396eed78c4cd296c65608244c65e596fb3f4056 100644 (file)
@@ -59,7 +59,7 @@
             "Z": -616.47974
           },
           "TerritoryId": 814,
-          "InteractionType": "WaitForManualProgress",
+          "InteractionType": "Snipe",
           "Comment": "Click red hat dwarf (always shows up in the same location)"
         }
       ]
@@ -75,7 +75,7 @@
             "Z": -616.47974
           },
           "TerritoryId": 814,
-          "InteractionType": "WaitForManualProgress",
+          "InteractionType": "Snipe",
           "Comment": "Click red hat dwarf"
         }
       ]
index 34fa28fc2b3c72d602542d6a056c747bc63fd838..3242f9d596391d231d340c3895f555738bcda407 100644 (file)
@@ -54,7 +54,7 @@
             "Z": -414.38928
           },
           "TerritoryId": 818,
-          "InteractionType": "WaitForManualProgress",
+          "InteractionType": "Snipe",
           "Comment": "Click top left (broken) window",
           "CompletionQuestVariablesFlags": [
             null,
index 19ac490634ce34d7c47e4291366137b18f32d29d..2416c087cce856e83ceeab2a544663a0b0a344ab 100644 (file)
@@ -44,7 +44,7 @@
             "Z": -161.45575
           },
           "TerritoryId": 814,
-          "InteractionType": "WaitForManualProgress",
+          "InteractionType": "Snipe",
           "Comment": "Help Master Chai dodge enemies"
         }
       ]
index 75cf15c68d072c26ad248c0e3747c2739bdd28a2..15fb42ae6ddc494f7510f2ea7a7036257f09d1bf 100644 (file)
             "Z": -519.18823
           },
           "TerritoryId": 956,
-          "InteractionType": "WaitForManualProgress",
+          "InteractionType": "Snipe",
           "Comment": "Shoot Large Green Bird"
         }
       ]
index 00c79a9a8479de8f3b0173ed1f7a39eeb33d86b3..b84bfe286260f0af7f03d4ab23ad6010bc9e8f20 100644 (file)
             "Z": -654.13904
           },
           "TerritoryId": 959,
-          "InteractionType": "WaitForManualProgress",
+          "InteractionType": "Snipe",
           "Comment": "Find \"Runninway?\""
         }
       ]
index d7c5efa7bd630064fefa16ba6ab685c94f5a600b..56b49ff638f7a2bff7c189975cd2dfa4026f91b8 100644 (file)
@@ -45,7 +45,7 @@
           },
           "StopDistance": 5,
           "TerritoryId": 956,
-          "InteractionType": "WaitForManualProgress",
+          "InteractionType": "Snipe",
           "Comment": "Find Points of Interest"
         }
       ]
index 35dcefaf157fa9f043be428db426abc897aeb34b..de94694bdc99aabcba2ab2ba799f5034ba92f11f 100644 (file)
             "Z": 375.50916
           },
           "TerritoryId": 960,
-          "InteractionType": "WaitForManualProgress",
+          "InteractionType": "Snipe",
           "Comment": "Find Errant Omicron"
         }
       ]
index 48ae66728c83f6b0acdecc4f0a51fd700be4dea0..300ba5658c9b95600c05cafa7e87d807dcf6ba23 100644 (file)
@@ -44,7 +44,7 @@
             "Z": 398.42822
           },
           "TerritoryId": 960,
-          "InteractionType": "WaitForManualProgress",
+          "InteractionType": "Snipe",
           "Comment": "Identify Anomaly (Head, Elbow or Knee)"
         }
       ]
index d78b2a99feca2f45618abe71e4b7de1b8389bec4..ae18351672cdece6c8bb8c5407718e7800db16dc 100644 (file)
@@ -28,7 +28,7 @@
             "Z": 276.81384
           },
           "TerritoryId": 962,
-          "InteractionType": "Instruction",
+          "InteractionType": "Snipe",
           "Comment": "Click ewer, head and feet",
           "AethernetShortcut": [
             "[Old Sharlayan] Aetheryte Plaza",
index c69575bd4a9431dfce67c7c907f4a6041ea8fb24..b3a2d6b25c0708f5727d61e08f8064a2cfc66fe6 100644 (file)
             "Z": -532.15845
           },
           "TerritoryId": 1188,
-          "InteractionType": "WaitForManualProgress",
+          "InteractionType": "Snipe",
           "Comment": "Inspect Eye, Carrying Pole and Tail",
           "AetheryteShortcut": "Kozama'uka - Ok'hanu"
         }
index 5fbb423b17857526bd7acfe9ecbfba0b2b69cc6b..29d5bcb02c12b691a901621764ca0263ba56dc4e 100644 (file)
@@ -28,7 +28,7 @@
             "Z": 343.7704
           },
           "TerritoryId": 1188,
-          "InteractionType": "WaitForManualProgress",
+          "InteractionType": "Snipe",
           "Comment": "Click (from left to right) worn tools, Kaahe, crafting materials, untouched meal"
         }
       ]
index bcace20596b98889516360c40a691f95be1e7107..a5347bfec4b17d53901a9c510eda634188339dd3 100644 (file)
@@ -28,7 +28,7 @@
             "Z": 25.680908
           },
           "TerritoryId": 1185,
-          "InteractionType": "WaitForManualProgress",
+          "InteractionType": "Snipe",
           "Comment": "Inspect Helm, Corpse, Weapon"
         }
       ]
index 4412991d64020a1f13d01a776ebcd082deec43eb..31d973757a1a0def31a4c17fcaca80e69bab1f96 100644 (file)
@@ -28,7 +28,7 @@
             "Z": -141.92426
           },
           "TerritoryId": 1190,
-          "InteractionType": "Instruction",
+          "InteractionType": "Snipe",
           "Comment": "Click (from left to right) pump, middle of the connecting pipes, barrels"
         }
       ]
index b50e254d285c496a2f997b55256e0c9c14c5c456..2244ebb92e83ee71bd93b25e999b86f7d5f7eb31 100644 (file)
@@ -28,7 +28,7 @@
             "Z": 557.7018
           },
           "TerritoryId": 1189,
-          "InteractionType": "Instruction",
+          "InteractionType": "Snipe",
           "Comment": "Inspect Flag, Red Head, Blue Head"
         }
       ]
index 8068adef12606f69cb68dd86e9ce34e0d7a3b645..a3bfd6f98cc61f8c7f013d05eaa4236fc317f6ff 100644 (file)
             "Jump",
             "Dive",
             "Craft",
+            "Snipe",
             "Instruction",
             "AcceptQuest",
             "CompleteQuest",
index 8683a57a7fcbbffe489d383097179abe5890aea4..bf856da99da36de185e46b9191f1daf7d98a08b7 100644 (file)
@@ -27,6 +27,7 @@ public sealed class InteractionTypeConverter() : EnumConverter<EInteractionType>
         { EInteractionType.Jump, "Jump" },
         { EInteractionType.Dive, "Dive" },
         { EInteractionType.Craft, "Craft" },
+        { EInteractionType.Snipe, "Snipe" },
         { EInteractionType.Instruction, "Instruction" },
         { EInteractionType.AcceptQuest, "AcceptQuest" },
         { EInteractionType.CompleteQuest, "CompleteQuest" },
index c0b3eede27f98c17bfdd01b47b500c35f75a444a..f251b5aee8eb8bf88a422721a847211802d7aea6 100644 (file)
@@ -26,6 +26,7 @@ public enum EInteractionType
     Jump,
     Dive,
     Craft,
+    Snipe,
 
     /// <summary>
     /// Needs to be manually continued.
index 9f86cb94f98020fafc5212abbd14cbf30546a637..3ea014cb81f83633d96e64a0187ba0d127627235 100644 (file)
@@ -19,6 +19,7 @@ internal sealed class Configuration : IPluginConfiguration
         public bool HideInAllInstances { get; set; } = true;
         public bool UseEscToCancelQuesting { get; set; } = true;
         public bool ShowIncompleteSeasonalEvents { get; set; } = true;
+        public bool AutomaticallyCompleteSnipeTasks { get; set; }
     }
 
     internal sealed class AdvancedConfiguration
index 4988b2ae40be33096bbde5689d8985dd36b3c0dc..b048b7ff27dd29ab6628560d13074a4e6c83e1b2 100644 (file)
@@ -16,7 +16,8 @@ namespace Questionable.Controller.Steps.Interactions;
 
 internal static class Interact
 {
-    internal sealed class Factory(GameFunctions gameFunctions, ICondition condition, ILoggerFactory loggerFactory)
+    internal sealed class Factory(GameFunctions gameFunctions, Configuration configuration, ICondition condition,
+        ILoggerFactory loggerFactory)
         : ITaskFactory
     {
         public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
@@ -37,6 +38,11 @@ internal static class Interact
                 if (step.DataId == null)
                     yield break;
             }
+            else if (step.InteractionType == EInteractionType.Snipe)
+            {
+                if (!configuration.General.AutomaticallyCompleteSnipeTasks)
+                    yield break;
+            }
             else if (step.InteractionType != EInteractionType.Interact)
                 yield break;
 
index 47c0fe4a59cb50f294651f267a24cb7cdc5e96b3..e2a0864f510f496ebe204fa178555dbd4ac15ac2 100644 (file)
@@ -49,6 +49,7 @@ internal static class WaitAtEnd
 
                 case EInteractionType.WaitForManualProgress:
                 case EInteractionType.Instruction:
+                case EInteractionType.Snipe:
                     return [new WaitNextStepOrSequence()];
 
                 case EInteractionType.Duty:
diff --git a/Questionable/Controller/Utils/AutoSnipeHandler.cs b/Questionable/Controller/Utils/AutoSnipeHandler.cs
new file mode 100644 (file)
index 0000000..dc48c3a
--- /dev/null
@@ -0,0 +1,48 @@
+using System;
+using Dalamud.Hooking;
+using Dalamud.Plugin.Services;
+using FFXIVClientStructs.FFXIV.Client.Game.Event;
+using FFXIVClientStructs.FFXIV.Common.Lua;
+
+namespace Questionable.Controller.Utils;
+
+internal sealed unsafe class AutoSnipeHandler : IDisposable
+{
+    private readonly QuestController _questController;
+    private readonly Configuration _configuration;
+    private readonly Hook<EnqueueSnipeTaskDelegate> _enqueueSnipeTaskHook;
+
+    private delegate ulong EnqueueSnipeTaskDelegate(EventSceneModuleImplBase* scene, lua_State* state);
+
+    public AutoSnipeHandler(QuestController questController, Configuration configuration, IGameInteropProvider gameInteropProvider)
+    {
+        _questController = questController;
+        _configuration = configuration;
+
+        _enqueueSnipeTaskHook =
+            gameInteropProvider.HookFromSignature<EnqueueSnipeTaskDelegate>(
+                "48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 50 48 8B F1 48 8D 4C 24 ?? E8 ?? ?? ?? ?? 48 8B 4C 24 ??",
+                EnqueueSnipeTask);
+    }
+
+    public void Enable() => _enqueueSnipeTaskHook.Enable();
+
+    private ulong EnqueueSnipeTask(EventSceneModuleImplBase* scene, lua_State* state)
+    {
+        if (_configuration.General.AutomaticallyCompleteSnipeTasks && _questController.IsRunning)
+        {
+            var val = state->top;
+            val->tt = 3;
+            val->value.n = 1;
+            state->top += 1;
+            return 1;
+        }
+        else
+            return _enqueueSnipeTaskHook.Original.Invoke(scene, state);
+    }
+
+    public void Dispose()
+    {
+        _enqueueSnipeTaskHook.Dispose();
+    }
+}
index 5c74c00bdefb9430663e38b494aaa46c7b229d1b..b5be5760c8ecfe1ac1a20dfcf670b5fb15ab6c4f 100644 (file)
@@ -18,6 +18,7 @@ using Questionable.Controller.Steps.Common;
 using Questionable.Controller.Steps.Gathering;
 using Questionable.Controller.Steps.Interactions;
 using Questionable.Controller.Steps.Leves;
+using Questionable.Controller.Utils;
 using Questionable.Data;
 using Questionable.External;
 using Questionable.Functions;
@@ -108,6 +109,7 @@ public sealed class QuestionablePlugin : IDalamudPlugin
         serviceCollection.AddSingleton<GameFunctions>();
         serviceCollection.AddSingleton<ChatFunctions>();
         serviceCollection.AddSingleton<QuestFunctions>();
+        serviceCollection.AddSingleton<AutoSnipeHandler>();
 
         serviceCollection.AddSingleton<AetherCurrentData>();
         serviceCollection.AddSingleton<AetheryteData>();
@@ -240,6 +242,7 @@ public sealed class QuestionablePlugin : IDalamudPlugin
         serviceProvider.GetRequiredService<LeveUiController>();
         serviceProvider.GetRequiredService<QuestionableIpc>();
         serviceProvider.GetRequiredService<DalamudInitializer>();
+        serviceProvider.GetRequiredService<AutoSnipeHandler>().Enable();
     }
 
     public void Dispose()
index a419249cc86bec2a8d1b8e9b20ba003fbdcf6d62..e69a7c377105befb02070b6d47961421ea58724b 100644 (file)
@@ -90,6 +90,16 @@ internal sealed class ConfigWindow : LWindow, IPersistableWindowConfig
                     Save();
                 }
 
+                if (ImGui.CollapsingHeader("Cheats"))
+                {
+                    bool automaticallyCompleteSnipeTasks = _configuration.General.AutomaticallyCompleteSnipeTasks;
+                    if (ImGui.Checkbox("Automatically complete snipe tasks", ref automaticallyCompleteSnipeTasks))
+                    {
+                        _configuration.General.AutomaticallyCompleteSnipeTasks = automaticallyCompleteSnipeTasks;
+                        Save();
+                    }
+                }
+
                 ImGui.EndTabItem();
             }
 
index b1ffd40bd8becb3723626eaa5866342311b8f39d..34beb090740976da38d8786b47552043d17d2bb0 100644 (file)
@@ -84,7 +84,7 @@ internal sealed partial class ActiveQuestComponent
             if (!isMinimized)
             {
                 bool colored = currentStep is
-                    { InteractionType: EInteractionType.Instruction or EInteractionType.WaitForManualProgress };
+                    { InteractionType: EInteractionType.Instruction or EInteractionType.WaitForManualProgress or EInteractionType.Snipe };
                 if (colored)
                     ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudOrange);
                 ImGui.TextUnformatted(currentStep?.Comment ??