qstbak/Questionable/Questionable.Data/MenderDataService.cs
2026-08-17 20:29:32 +10:00

71 lines
2.2 KiB
C#

using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Dalamud.Plugin.Services;
using LLib.Shop;
using Lumina.Excel;
using Lumina.Excel.Sheets;
using Microsoft.Extensions.Logging;
namespace Questionable.Data;
internal sealed class MenderDataService(IDataManager dataManager, NpcPositionCache npcPositionCache, ILogger<MenderDataService> logger)
{
public static readonly IReadOnlyList<MenderNpc> CityFallbacks = new global::_003C_003Ez__ReadOnlyArray<MenderNpc>(new MenderNpc[3]
{
new MenderNpc(1003251u, 128, new Vector3(17.715698f, 40.200005f, 3.9520264f)),
new MenderNpc(1000394u, 132, new Vector3(24.826416f, -8f, 93.18677f)),
new MenderNpc(1004416u, 130, new Vector3(32.85266f, 6.999999f, -81.31531f))
});
private readonly object _lock = new object();
private ILookup<ushort, MenderNpc>? _byTerritory;
public MenderNpc? FindNearestInTerritory(ushort territoryId, Vector3 nearPosition)
{
ILookup<ushort, MenderNpc> lookup;
lock (_lock)
{
if (_byTerritory == null && !npcPositionCache.IsBuilt)
{
return null;
}
lookup = _byTerritory ?? (_byTerritory = BuildIndex());
}
return lookup[territoryId].OrderBy((MenderNpc x) => Vector3.DistanceSquared(x.Position, nearPosition)).FirstOrDefault();
}
private ILookup<ushort, MenderNpc> BuildIndex()
{
ExcelSheet<ENpcBase> excelSheet = dataManager.GetExcelSheet<ENpcBase>();
List<MenderNpc> list = new List<MenderNpc>();
foreach (uint allNpcId in npcPositionCache.GetAllNpcIds())
{
if (!excelSheet.TryGetRow(allNpcId, out var row))
{
continue;
}
bool flag = false;
for (int i = 0; i < row.ENpcData.Count; i++)
{
if (row.ENpcData[i].RowId == 720915)
{
flag = true;
break;
}
}
if (flag)
{
(ushort, Vector3)? position = npcPositionCache.GetPosition(allNpcId);
if (position.HasValue)
{
(ushort, Vector3) valueOrDefault = position.GetValueOrDefault();
list.Add(new MenderNpc(allNpcId, valueOrDefault.Item1, valueOrDefault.Item2));
}
}
}
logger.LogDebug("Mender index built with {Count} menders across {Territories} territories", list.Count, list.Select((MenderNpc x) => x.TerritoryId).Distinct().Count());
return list.ToLookup((MenderNpc x) => x.TerritoryId);
}
}