using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.UI.Agent; using FFXIVClientStructs.FFXIV.Component.GUI; using LLib.GameUI; using Lumina.Excel.Sheets; namespace LLib.Gear; public static class MeldActions { public const uint MeldUnlockQuestId = 66175u; public const uint OvermeldUnlockQuestId = 66176u; public unsafe static bool TryOpenMeldAgent() { ActionManager* ptr = ActionManager.Instance(); if (ptr == null) { return false; } return ptr->UseAction(ActionType.GeneralAction, 13u, 3758096384uL, 0u, ActionManager.UseActionMode.None, 0u, null); } public unsafe static bool IsMeldAgentReady() { AgentInterface* agentByInternalId = AgentModule.Instance()->GetAgentByInternalId(AgentId.MateriaAttach); if (agentByInternalId != null) { return agentByInternalId->IsAgentActive(); } return false; } public unsafe static void CloseMeldAgent() { AgentInterface* agentByInternalId = AgentModule.Instance()->GetAgentByInternalId(AgentId.MateriaAttach); if (agentByInternalId != null) { agentByInternalId->Hide(); } } public unsafe static bool TrySelectItemCategory(int category) { AgentInterface* agentByInternalId = AgentModule.Instance()->GetAgentByInternalId(AgentId.MateriaAttach); if (agentByInternalId == null || !agentByInternalId->IsAgentActive()) { return false; } AgentHelper.SendEvent(agentByInternalId, 0uL, 0, category); return true; } public unsafe static bool TrySelectItem(int itemIndex) { AgentInterface* agentByInternalId = AgentModule.Instance()->GetAgentByInternalId(AgentId.MateriaAttach); if (agentByInternalId == null || !agentByInternalId->IsAgentActive()) { return false; } AgentHelper.SendEvent(agentByInternalId, 0uL, 1, itemIndex, 1, 0); return true; } public unsafe static bool TrySelectMateria(int materiaIndex) { AgentInterface* agentByInternalId = AgentModule.Instance()->GetAgentByInternalId(AgentId.MateriaAttach); if (agentByInternalId == null || !agentByInternalId->IsAgentActive()) { return false; } AgentHelper.SendEvent(agentByInternalId, 0uL, 2, materiaIndex, 1, 0); return true; } public unsafe static bool TryConfirmMeld(IGameGui gameGui) { if (!gameGui.TryGetReadyAddon("MateriaAttachDialog", out var addonPtr)) { return false; } AddonCallback.Fire(addonPtr, 0, 0, 1); addonPtr->Close(fireCallback: true); return true; } public unsafe static bool TryConfirmOvermeld(IGameGui gameGui) { AgentInterface* agentByInternalId = AgentModule.Instance()->GetAgentByInternalId(AgentId.MateriaAttach); if (agentByInternalId == null || !agentByInternalId->IsAgentActive()) { return false; } if (!gameGui.TryGetReadyAddon("SelectYesno", out var addonPtr)) { return false; } AddonCallback.ClickYes(addonPtr); addonPtr->Close(fireCallback: true); return true; } public unsafe static bool TryRequestRetrieve() { AgentInterface* agentByInternalId = AgentModule.Instance()->GetAgentByInternalId(AgentId.MateriaAttach); if (agentByInternalId == null || !agentByInternalId->IsAgentActive()) { return false; } AgentHelper.SendEvent(agentByInternalId, 4uL, 0, 1, 0, 0, 0); return true; } public unsafe static bool TryConfirmRetrieve(IGameGui gameGui) { if (!gameGui.TryGetReadyAddon("MateriaRetrieveDialog", out var addonPtr)) { return false; } AddonCallback.Fire(addonPtr, default(int)); addonPtr->Close(fireCallback: true); return true; } public unsafe static bool IsMeldDialogReady(IGameGui gameGui) { AtkUnitBase* addonPtr; return gameGui.TryGetReadyAddon("MateriaAttachDialog", out addonPtr); } public unsafe static bool IsRetrieveDialogReady(IGameGui gameGui) { AtkUnitBase* addonPtr; return gameGui.TryGetReadyAddon("MateriaRetrieveDialog", out addonPtr); } public unsafe static bool IsAgentLoading() { AgentMateriaAttach* ptr = AgentMateriaAttach.Instance(); if (ptr != null) { return ptr->UpdateState != 0; } return false; } public unsafe static int GetSelectedItemIndex() { AgentMateriaAttach* ptr = AgentMateriaAttach.Instance(); if (ptr != null) { return ptr->SelectedItemIndex; } return -1; } public static AgentMateriaAttach.FilterCategory GetFilterCategory(InventoryType inventoryType) { switch (inventoryType) { case InventoryType.Inventory1: case InventoryType.Inventory2: case InventoryType.Inventory3: case InventoryType.Inventory4: return AgentMateriaAttach.FilterCategory.Inventory; case InventoryType.ArmoryOffHand: case InventoryType.ArmoryMainHand: return AgentMateriaAttach.FilterCategory.ArmouryWeapon; case InventoryType.ArmoryHead: case InventoryType.ArmoryBody: case InventoryType.ArmoryHands: return AgentMateriaAttach.FilterCategory.ArmouryHeadBodyHands; case InventoryType.ArmoryLegs: case InventoryType.ArmoryFeets: return AgentMateriaAttach.FilterCategory.ArmouryLegsFeet; case InventoryType.ArmoryEar: case InventoryType.ArmoryNeck: return AgentMateriaAttach.FilterCategory.ArmouryNeckEars; case InventoryType.ArmoryWrist: case InventoryType.ArmoryRings: return AgentMateriaAttach.FilterCategory.ArmouryWristRing; case InventoryType.EquippedItems: return AgentMateriaAttach.FilterCategory.Equipped; default: return AgentMateriaAttach.FilterCategory.None; } } public unsafe static int? FindItemIndex(InventoryItem* target) { if (target == null) { return null; } AgentMateriaAttach* ptr = AgentMateriaAttach.Instance(); if (ptr == null || !ptr->IsAgentActive() || ptr->Data == null) { return null; } for (int i = 0; i < ptr->ItemCount; i++) { AgentMateriaAttach.MateriaAttachEntry* value = ptr->Data->ItemsSorted[i].Value; if (value != null && value->Item == target) { return i; } } return null; } public unsafe static int? FindMateriaIndex(uint materiaItemId) { AgentMateriaAttach* ptr = AgentMateriaAttach.Instance(); if (ptr == null || !ptr->IsAgentActive() || ptr->Data == null) { return null; } for (int i = 0; i < ptr->MateriaCount; i++) { AgentMateriaAttach.MateriaAttachEntry* value = ptr->Data->MateriaSorted[i].Value; if (value != null && value->Item != null && value->Item->ItemId == materiaItemId) { return i; } } return null; } public static bool IsMeldingUnlocked() { return GearFeatures.IsMeldingUnlocked(); } public static bool IsOvermeldingUnlocked() { return GearFeatures.IsOvermeldingUnlocked(); } public unsafe static bool CanMeldItem(IDataManager dataManager, InventoryItem* item) { if (item == null || item->ItemId == 0) { return false; } if (!dataManager.GetExcelSheet().TryGetRow(item->ItemId, out var row)) { return false; } if (row.MateriaSlotCount == 0) { return false; } int num = row.MateriaSlotCount; if (row.IsAdvancedMeldingPermitted) { num = 5; } for (int i = 0; i < num; i++) { if (item->Materia[i] == 0) { return true; } } return false; } }