diff --git a/Automaton/Features/LalaLookup.cs b/Automaton/Features/LalaLookup.cs index 5c62470..492a177 100644 --- a/Automaton/Features/LalaLookup.cs +++ b/Automaton/Features/LalaLookup.cs @@ -1,5 +1,4 @@ using Dalamud.Game.Gui.ContextMenu; -using Dalamud.Utility; using Lumina.Excel.Sheets; using NetStone; using NetStone.Search.Character; @@ -31,7 +30,7 @@ private void OnOpenContextMenu(IMenuOpenedArgs menuOpenedArgs) menuOpenedArgs.AddMenuItem(new MenuItem { - PrefixChar = 'A', + PrefixChar = 'C', Name = "Search on Lala", OnClicked = Search, }); @@ -94,7 +93,7 @@ private async Task SearchPlayerFromMenu(IMenuItemClickedArgs menuArgs) var lodestoneCharacter = searchResponse?.Results.FirstOrDefault(entry => string.Equals(entry.Name, playerName, StringComparison.OrdinalIgnoreCase)); if (lodestoneCharacter is not null) - Util.OpenLink($"https://lalachievements.com/char/{lodestoneCharacter.Id}/"); + Dalamud.Utility.Util.OpenLink($"https://lalachievements.com/char/{lodestoneCharacter.Id}/"); else ModuleMessage($"Unable to find lodestone ID for {playerName}"); } diff --git a/Automaton/Features/RetrieveMateria.cs b/Automaton/Features/RetrieveMateria.cs new file mode 100644 index 0000000..f5567d8 --- /dev/null +++ b/Automaton/Features/RetrieveMateria.cs @@ -0,0 +1,25 @@ +using Automaton.Tasks; +using Dalamud.Game.Gui.ContextMenu; + +namespace Automaton.Features; +[Tweak] +internal class RetrieveMateria : Tweak +{ + public override string Name => "Retrieve All Materia"; + public override string Description => "Adds a context menu item that will retrieve all materia from an item."; + + public override void Enable() => Svc.ContextMenu.OnMenuOpened += OnOpenContextMenu; + public override void Disable() => Svc.ContextMenu.OnMenuOpened -= OnOpenContextMenu; + + private void OnOpenContextMenu(IMenuOpenedArgs args) + { + if (args.MenuType != ContextMenuType.Inventory || args.Target is not MenuTargetInventory inv || inv.TargetItem == null || inv.TargetItem.Value.ItemId == 0) return; + args.AddMenuItem(new MenuItem + { + PrefixChar = 'C', + Name = "Retrieve All Materia", + OnClicked = (a) => P.Automation.Start(new RetrieveAllMateria(inv.TargetItem.Value)), + IsEnabled = inv.TargetItem.Value.Materia.ToArray().Any(m => m != 0) && !Svc.Condition[ConditionFlag.Occupied39], + }); + } +} diff --git a/Automaton/Global.cs b/Automaton/Global.cs index 099a767..2098fff 100644 --- a/Automaton/Global.cs +++ b/Automaton/Global.cs @@ -14,6 +14,7 @@ global using System.Linq; global using System.Numerics; global using static Automaton.Plugin; +global using static Automaton.Utilities.Enums; global using static Automaton.Utilities.Extensions; global using static ECommons.GenericHelpers; global using AtkValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType; diff --git a/Automaton/Tasks/KillFlag.cs b/Automaton/Tasks/KillFlag.cs index 42572da..81cc649 100644 --- a/Automaton/Tasks/KillFlag.cs +++ b/Automaton/Tasks/KillFlag.cs @@ -14,8 +14,8 @@ protected override async Task Execute() await Mount(); Status = "Moving To"; Chat.Instance.SendMessage("/vnav flyflag"); - await FlyFlag(); - await Kill(); + //await FlyFlag(); + //await Kill(); } private async Task FlyFlag() diff --git a/Automaton/Tasks/RetrieveAllMateria.cs b/Automaton/Tasks/RetrieveAllMateria.cs new file mode 100644 index 0000000..4f7e06d --- /dev/null +++ b/Automaton/Tasks/RetrieveAllMateria.cs @@ -0,0 +1,29 @@ +using Dalamud.Game.Inventory; +using FFXIVClientStructs.FFXIV.Client.Game; +using FFXIVClientStructs.FFXIV.Client.Game.Event; +using System.Threading.Tasks; + +namespace Automaton.Tasks; +public sealed class RetrieveAllMateria(GameInventoryItem item) : CommonTasks +{ + protected override async Task Execute() + { + Status = $"Retrieving Materia"; + var materias = item.Materia.ToArray().Where(x => x != 0); + foreach (var materia in materias) + { + Retrieve(); + await WaitUntilThenFalse(() => Svc.Condition[ConditionFlag.Occupied39], "RetrivingMateria"); + } + } + + private unsafe void Retrieve() + { + try + { + var _item = (InventoryItem*)item.Address; + P.Memory.RetrieveMateria?.Invoke(EventFramework.Instance(), 0x390001, _item->Container, _item->Slot, 0); + } + catch (Exception e) { e.Log(); } + } +} diff --git a/Automaton/Utilities/Memory.cs b/Automaton/Utilities/Memory.cs index e72dda3..61651c4 100644 --- a/Automaton/Utilities/Memory.cs +++ b/Automaton/Utilities/Memory.cs @@ -9,7 +9,6 @@ using FFXIVClientStructs.FFXIV.Client.UI.Info; using FFXIVClientStructs.FFXIV.Common.Lua; using System.Runtime.InteropServices; -using static Automaton.Utilities.Enums; namespace Automaton.Utilities; #pragma warning disable CS0649 @@ -20,8 +19,8 @@ public static class Signatures internal const string AgentReturnReceiveEvent = "E8 ?? ?? ?? ?? 41 8D 5E 0D"; internal const string AbandonDuty = "E8 ?? ?? ?? ?? 48 8B 43 28 41 B2 01"; internal const string BewitchProc = "40 53 48 83 EC 50 45 33 C0"; - internal const string EnqueueSnipeTask = "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 ??"; - internal const string FollowQuestRecast = "E8 ?? ?? ?? ?? 48 8B 9C 24 ?? ?? ?? ?? 0F 28 74 24 ?? 0F 28 7C 24 ?? 44 0F 28 44 24 ?? 48 81 C4"; + internal const string EnqueueSnipeTask = "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 ??"; // xan + internal const string FollowQuestRecast = "E8 ?? ?? ?? ?? 48 8B 9C 24 ?? ?? ?? ?? 0F 28 74 24 ?? 0F 28 7C 24 ?? 44 0F 28 44 24 ?? 48 81 C4"; // atmo internal const string ExecuteCommand = "E8 ?? ?? ?? ?? 8D 46 0A"; // st internal const string ExecuteCommandComplexLocation = "E8 ?? ?? ?? ?? EB 1E 48 8B 53 08"; internal const string GetGrandCompanyRank = "E8 ?? ?? ?? ?? 3A 43 01"; // cs @@ -34,13 +33,16 @@ public static class Signatures internal const string PlayerGroundSpeed = "F3 0F 59 05 ?? ?? ?? ?? F3 0F 59 05 ?? ?? ?? ?? F3 0F 58 05 ?? ?? ?? ?? 44 0F 28 C8"; internal const string ReceiveAchievementProgress = "C7 81 ?? ?? ?? ?? ?? ?? ?? ?? 89 91 ?? ?? ?? ?? 44 89 81"; // cs internal const string RidePillion = "48 85 C9 0F 84 ?? ?? ?? ?? 48 89 6C 24 ?? 56 48 83 EC"; - internal const string SalvageItem = "E8 ?? ?? ?? ?? EB 5A 48 8B 07"; - internal const string ShouldDraw = "E8 ?? ?? ?? ?? 84 C0 75 18 48 8D 0D ?? ?? ?? ?? B3 01"; + internal const string SalvageItem = "E8 ?? ?? ?? ?? EB 5A 48 8B 07"; // veyn + internal const string ShouldDraw = "E8 ?? ?? ?? ?? 84 C0 75 18 48 8D 0D ?? ?? ?? ?? B3 01"; // hasel internal const string WorldTravel = "40 55 53 56 57 41 54 41 56 41 57 48 8D AC 24 ?? ?? ?? ?? B8"; internal const string WorldTravelSetupInfo = "48 8B CB E8 ?? ?? ?? ?? 48 8D 8B ?? ?? ?? ?? E8 ?? ?? ?? ?? 4C 8B 05 ?? ?? ?? ??"; internal const string InventoryManagerUniqueItemCheck = "E8 ?? ?? ?? ?? 44 8B E0 EB 29"; internal const string ItemIsUniqueConditionalJump = "75 4D"; - internal const string FreeCompanyDialogPacketReceive = "48 89 5C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 0F B6 42 31"; + internal const string FreeCompanyDialogPacketReceive = "48 89 5C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 0F B6 42 31"; // xan + internal const string SendLogout = "40 53 48 83 EC ?? 48 8B 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8B D8 48 85 C0 74 ?? 48 8B 0D"; // Client::Game::Event::EventSceneModuleUsualImpl.Logout push rbx + internal const string ProcessSentChat = "E8 ?? ?? ?? ?? FE 86 ?? ?? ?? ?? C7 86 ?? ?? ?? ?? ?? ?? ?? ??"; + internal const string RetrieveMateria = "E8 ?? ?? ?? ?? EB 27 48 8B 01"; // Client::UI::Agent::AgentMaterialize.ReceiveEvent call sub_140B209C0 // +47: 75 57 // 270: 75 12 // 107: 0f 85 ea 00 00 00 @@ -65,6 +67,9 @@ public static class Signatures internal delegate nint WorldTravelSetupInfoDelegate(nint worldTravel, ushort currentWorld, ushort targetWorld); internal WorldTravelSetupInfoDelegate WorldTravelSetupInfo = null!; + internal delegate void RetrieveMateriaDelegate(EventFramework* framework, int eventID, InventoryType inventoryType, short inventorySlot, int extraParam); + internal RetrieveMateriaDelegate? RetrieveMateria = null!; + public Memory() { EzSignatureHelper.Initialize(this); @@ -73,6 +78,7 @@ public Memory() AbandonDuty = Marshal.GetDelegateForFunctionPointer(Svc.SigScanner.ScanText(Signatures.AbandonDuty)); WorldTravel = Marshal.GetDelegateForFunctionPointer(Svc.SigScanner.ScanText(Signatures.WorldTravel)); WorldTravelSetupInfo = Marshal.GetDelegateForFunctionPointer(Svc.SigScanner.ScanText(Signatures.WorldTravelSetupInfo)); + RetrieveMateria = Marshal.GetDelegateForFunctionPointer(Svc.SigScanner.ScanText(Signatures.RetrieveMateria)); } public void Dispose() { } diff --git a/Automaton/Utilities/Utils.cs b/Automaton/Utilities/Utils.cs index 7f62d9f..b27142f 100644 --- a/Automaton/Utilities/Utils.cs +++ b/Automaton/Utilities/Utils.cs @@ -1,5 +1,4 @@ using Dalamud.Interface.Textures.TextureWraps; -using Dalamud.Plugin; using ECommons.Reflection; using FFXIVClientStructs.Attributes; using FFXIVClientStructs.FFXIV.Client.System.Framework;