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

120 lines
2.6 KiB
C#

using System;
using System.Collections.Generic;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Game;
using Lumina.Excel.Sheets;
namespace LLib.Gear;
public static class MateriaHelper
{
private const int MaxMateriaSlots = 5;
public unsafe static List<MeldSlotInfo> GetMeldedMateria(InventoryItem* item)
{
List<MeldSlotInfo> list = new List<MeldSlotInfo>(5);
if (item == null || item->ItemId == 0)
{
return list;
}
for (int i = 0; i < 5; i++)
{
uint num = item->Materia[i];
if (num != 0)
{
list.Add(new MeldSlotInfo(i, num, item->MateriaGrades[i]));
}
}
return list;
}
public static int GetNormalSlotCount(IDataManager dataManager, uint itemId)
{
if (!dataManager.GetExcelSheet<Item>().TryGetRow(itemId, out var row))
{
return 0;
}
return row.MateriaSlotCount;
}
public static bool CanOvermeld(IDataManager dataManager, uint itemId)
{
if (!dataManager.GetExcelSheet<Item>().TryGetRow(itemId, out var row))
{
return false;
}
return row.IsAdvancedMeldingPermitted;
}
public static int GetOvermeldSuccessRate(IDataManager dataManager, byte grade, int overmeldSlot, bool isHq)
{
if (overmeldSlot < 0)
{
return 0;
}
if (!dataManager.GetExcelSheet<MateriaGrade>().TryGetRow(grade, out var row))
{
return 0;
}
if (isHq)
{
if (overmeldSlot >= row.OvermeldHQPercent.Count)
{
return 0;
}
return row.OvermeldHQPercent[overmeldSlot];
}
if (overmeldSlot >= row.OvermeldNQPercent.Count)
{
return 0;
}
return row.OvermeldNQPercent[overmeldSlot];
}
public unsafe static int CountMateriaInInventory(uint materiaItemId)
{
InventoryManager* ptr = InventoryManager.Instance();
if (ptr == null)
{
return 0;
}
return ptr->GetInventoryItemCount(materiaItemId, isHq: false, checkEquipped: true, checkArmory: true, 0);
}
public static int EstimateMateriaNeeded(int successRatePercent, int confidencePercent = 90)
{
if (successRatePercent >= 100)
{
return 1;
}
if (successRatePercent <= 0)
{
return int.MaxValue;
}
double num = (double)successRatePercent / 100.0;
double num2 = (double)Math.Clamp(confidencePercent, 0, 99) / 100.0;
double num3 = Math.Ceiling(Math.Log(1.0 - num2) / Math.Log(1.0 - num));
if (num3 < 1.0)
{
return 1;
}
if (num3 > 2147483647.0)
{
return int.MaxValue;
}
return (int)num3;
}
public static uint GetMateriaItemId(IDataManager dataManager, uint materiaRowId, byte grade)
{
if (!dataManager.GetExcelSheet<Materia>().TryGetRow(materiaRowId, out var row))
{
return 0u;
}
if (grade >= row.Item.Count)
{
return 0u;
}
return row.Item[grade].RowId;
}
}