qstbak/LLib/LLib.Gear/RepairActions.cs
2026-08-17 20:29:32 +10:00

172 lines
4.5 KiB
C#

using System;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.UI;
using FFXIVClientStructs.FFXIV.Component.GUI;
using LLib.GameUI;
using Lumina.Excel;
using Lumina.Excel.Sheets;
namespace LLib.Gear;
public static class RepairActions
{
public const uint RepairServiceDataId = 720915u;
public unsafe static bool TryOpenRepairWindow()
{
ActionManager* ptr = ActionManager.Instance();
if (ptr == null)
{
return false;
}
return ptr->UseAction(ActionType.GeneralAction, 6u, 3758096384uL, 0u, ActionManager.UseActionMode.None, 0u, null);
}
public unsafe static bool IsRepairAddonReady(IGameGui gameGui)
{
AtkUnitBase* addonPtr;
return gameGui.TryGetReadyAddon<AtkUnitBase>("Repair", out addonPtr);
}
public unsafe static bool TryRepairAll(IGameGui gameGui)
{
if (!gameGui.TryGetReadyAddon<AtkUnitBase>("Repair", out var addonPtr))
{
return false;
}
return AddonCallback.ClickButton(addonPtr, ((AddonRepair*)addonPtr)->RepairAllButton);
}
public unsafe static bool TryConfirmDialog(IGameGui gameGui)
{
if (!gameGui.TryGetReadyAddon<AtkUnitBase>("Repair", out var _))
{
return false;
}
if (!gameGui.TryGetReadyAddon<AtkUnitBase>("SelectYesno", out var addonPtr2))
{
return false;
}
AddonCallback.ClickYes(addonPtr2);
return true;
}
public unsafe static string DescribeRepairAddon(IGameGui gameGui)
{
if (!gameGui.TryGetAddonByName<AtkUnitBase>("Repair", out var addonPtr))
{
return "addon: not open";
}
AtkComponentButton* repairAllButton = ((AddonRepair*)addonPtr)->RepairAllButton;
string value = ((repairAllButton == null) ? "null" : (repairAllButton->IsEnabled ? "enabled" : "disabled"));
return $"addon: visible={addonPtr->IsVisible}, ready={LAddon.IsAddonReady(addonPtr)}, repair-all button: {value}";
}
public unsafe static bool TryCloseRepairWindow(IGameGui gameGui)
{
if (!gameGui.TryGetAddonByName<AtkUnitBase>("Repair", out var addonPtr))
{
return false;
}
addonPtr->Close(fireCallback: true);
return true;
}
public unsafe static bool TrySelectRepairFromMenu(IGameGui gameGui, int repairIndex)
{
if (!gameGui.TryGetReadyAddon<AtkUnitBase>("SelectIconString", out var addonPtr))
{
return false;
}
AddonCallback.FireWithUpdate(addonPtr, repairIndex);
return true;
}
public static int? FindRepairIndex(IDataManager dataManager, uint npcBaseId)
{
if (!dataManager.GetExcelSheet<ENpcBase>().TryGetRow(npcBaseId, out var row))
{
return null;
}
for (int i = 0; i < row.ENpcData.Count; i++)
{
if (row.ENpcData[i].RowId == 720915)
{
return i;
}
}
return null;
}
public static bool CanSelfRepairItem(uint itemId, IDataManager dataManager, Func<uint, byte> jobLevelLookup)
{
if (!dataManager.GetExcelSheet<Item>().TryGetRow(itemId, out var row))
{
return false;
}
uint rowId = row.ClassJobRepair.RowId;
if (rowId == 0)
{
return false;
}
byte num = jobLevelLookup(rowId);
int num2 = Math.Max(row.LevelEquip - 10, 1);
if (num < num2)
{
return false;
}
uint num3 = row.ItemRepair.ValueNullable?.Item.RowId ?? 0;
if (num3 == 0)
{
return false;
}
return HasDarkMatterOrBetter(dataManager, num3);
}
public unsafe static bool CanSelfRepairAny(IDataManager dataManager, Func<uint, byte> jobLevelLookup, int thresholdPercent = 100)
{
InventoryManager* ptr = InventoryManager.Instance();
if (ptr == null)
{
return false;
}
InventoryContainer* inventoryContainer = ptr->GetInventoryContainer(InventoryType.EquippedItems);
if (inventoryContainer == null)
{
return false;
}
for (int i = 0; i < inventoryContainer->Size; i++)
{
InventoryItem* inventorySlot = inventoryContainer->GetInventorySlot(i);
if (inventorySlot != null && inventorySlot->ItemId != 0 && inventorySlot->Condition * 100 / 30000 < thresholdPercent && CanSelfRepairItem(inventorySlot->ItemId, dataManager, jobLevelLookup))
{
return true;
}
}
return false;
}
private unsafe static bool HasDarkMatterOrBetter(IDataManager dataManager, uint requiredItemId)
{
InventoryManager* ptr = InventoryManager.Instance();
if (ptr == null)
{
return false;
}
ExcelSheet<ItemRepairResource> excelSheet = dataManager.GetExcelSheet<ItemRepairResource>();
bool flag = false;
foreach (ItemRepairResource item in excelSheet)
{
if (item.Item.RowId == requiredItemId)
{
flag = true;
}
if (flag && ptr->GetInventoryItemCount(item.Item.RowId, isHq: false, checkEquipped: true, checkArmory: true, 0) > 0)
{
return true;
}
}
return false;
}
}