qstbak/LLib/LLib.Shop.Searchers/SpecialShopSearcher.cs
2026-08-17 20:29:32 +10:00

130 lines
3.2 KiB
C#

using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Dalamud.Plugin.Services;
using LLib.Shop.Model;
using Lumina.Excel;
using Lumina.Excel.Sheets;
namespace LLib.Shop.Searchers;
internal sealed class SpecialShopSearcher
{
private const uint SpecialShopHandlerType = 27u;
private static readonly Dictionary<uint, uint> SpecialCurrencies = new Dictionary<uint, uint>
{
{ 1u, 28u },
{ 2u, 33913u },
{ 4u, 33914u },
{ 6u, 41784u },
{ 7u, 41785u }
};
private readonly IDataManager _dataManager;
private readonly NpcPositionCache _positionCache;
private readonly uint[] _tomestoneItemIds;
public SpecialShopSearcher(IDataManager dataManager, NpcPositionCache positionCache)
{
_dataManager = dataManager;
_positionCache = positionCache;
_tomestoneItemIds = (from t in dataManager.GetExcelSheet<TomestonesItem>()
where t.Tomestones.RowId != 0
orderby t.Tomestones.RowId
select t.Item.RowId).ToArray();
}
public List<ShopSearchResult> Search(uint itemId)
{
List<ShopSearchResult> list = new List<ShopSearchResult>();
ExcelSheet<ENpcBase> excelSheet = _dataManager.GetExcelSheet<ENpcBase>();
ExcelSheet<SpecialShop> excelSheet2 = _dataManager.GetExcelSheet<SpecialShop>();
foreach (ENpcBase item in excelSheet)
{
if (item.RowId == 0)
{
continue;
}
(ushort, Vector3)? position = _positionCache.GetPosition(item.RowId);
if (!position.HasValue)
{
continue;
}
(ushort, Vector3) valueOrDefault = position.GetValueOrDefault();
int num = 0;
foreach (RowRef eNpcDatum in item.ENpcData)
{
if (eNpcDatum.RowId >> 16 != 27)
{
continue;
}
uint rowId = eNpcDatum.RowId;
if (!excelSheet2.TryGetRow(rowId, out var row))
{
num++;
continue;
}
bool flag = false;
uint currencyItemId = 0u;
uint price = 0u;
for (int i = 0; i < row.Item.Count; i++)
{
SpecialShop.ItemStruct itemStruct = row.Item[i];
for (int j = 0; j < itemStruct.ReceiveItems.Count; j++)
{
if (itemStruct.ReceiveItems[j].Item.RowId != itemId)
{
continue;
}
flag = true;
for (int k = 0; k < itemStruct.ItemCosts.Count; k++)
{
SpecialShop.ItemStruct.ItemCostsStruct itemCostsStruct = itemStruct.ItemCosts[k];
if (itemCostsStruct.ItemCost.RowId != 0)
{
currencyItemId = ConvertCurrencyItemId(itemCostsStruct.ItemCost.RowId, in row);
price = itemCostsStruct.CurrencyCost;
break;
}
}
break;
}
if (flag)
{
break;
}
}
if (flag)
{
list.Add(new ShopSearchResult(rowId, item.RowId, valueOrDefault.Item1, valueOrDefault.Item2, EShopType.SpecialShop, price, currencyItemId, num));
}
num++;
}
}
return list;
}
private uint ConvertCurrencyItemId(uint costItemId, in SpecialShop shop)
{
if (costItemId == 0 || costItemId >= 8)
{
return costItemId;
}
ushort num = shop.UseCurrencyType;
uint rowId = shop.RowId;
if (rowId - 1770637 <= 1)
{
num = 16;
}
return num switch
{
16 => SpecialCurrencies.GetValueOrDefault(costItemId, costItemId),
8 => 1u,
4 => (costItemId <= _tomestoneItemIds.Length) ? _tomestoneItemIds[costItemId - 1] : costItemId,
_ => costItemId,
};
}
}