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

106 lines
4.1 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Numerics;
using Dalamud.Plugin.Services;
using Lumina.Excel;
using Lumina.Excel.Sheets;
namespace Questionable.Data;
internal sealed class AetherCurrentData
{
private readonly IDataManager _dataManager;
private readonly ImmutableDictionary<ushort, ImmutableList<uint>> _overworldCurrents;
private readonly ImmutableDictionary<ushort, ImmutableList<AetherCurrentInfo>> _allCurrentsByTerritory;
private readonly ImmutableDictionary<uint, uint> _questCurrents;
private ImmutableDictionary<uint, AetherCurrentPosition>? _overworldPositions;
public IReadOnlyDictionary<ushort, ImmutableList<AetherCurrentInfo>> AllCurrentsByTerritory => _allCurrentsByTerritory;
private ImmutableDictionary<uint, AetherCurrentPosition> OverworldPositions => _overworldPositions ?? (_overworldPositions = BuildOverworldPositions());
public AetherCurrentData(IDataManager dataManager)
{
_dataManager = dataManager;
_overworldCurrents = (from x in dataManager.GetExcelSheet<AetherCurrentCompFlgSet>()
where x.RowId != 0
where x.Territory.IsValid
select x).ToImmutableDictionary((AetherCurrentCompFlgSet x) => (ushort)x.Territory.RowId, (AetherCurrentCompFlgSet x) => (from y in x.AetherCurrents
where y.RowId != 0 && y.Value.Quest.RowId == 0
select y.RowId).ToImmutableList());
_allCurrentsByTerritory = (from x in dataManager.GetExcelSheet<AetherCurrentCompFlgSet>()
where x.RowId != 0
where x.Territory.IsValid
select x).ToImmutableDictionary((AetherCurrentCompFlgSet x) => (ushort)x.Territory.RowId, (AetherCurrentCompFlgSet x) => x.AetherCurrents.Where((RowRef<AetherCurrent> y) => y.RowId != 0).Select(delegate(RowRef<AetherCurrent> y)
{
uint rowId = y.Value.Quest.RowId;
return new AetherCurrentInfo(y.RowId, rowId != 0, rowId);
}).ToImmutableList());
_questCurrents = (from info in _allCurrentsByTerritory.Values.SelectMany((ImmutableList<AetherCurrentInfo> list) => list)
where info.IsQuestGated
select info).ToImmutableDictionary((AetherCurrentInfo info) => info.AetherCurrentId, (AetherCurrentInfo info) => info.QuestId);
}
public bool IsValidAetherCurrent(ushort territoryId, uint aetherCurrentId)
{
if (_overworldCurrents.TryGetValue(territoryId, out ImmutableList<uint> value))
{
return value.Contains(aetherCurrentId);
}
return false;
}
public ImmutableList<AetherCurrentInfo> GetCurrentsForTerritory(ushort territoryId)
{
return _allCurrentsByTerritory.GetValueOrDefault(territoryId, ImmutableList.Create(default(ReadOnlySpan<AetherCurrentInfo>)));
}
public AetherCurrentPosition? GetOverworldPosition(uint aetherCurrentId)
{
return OverworldPositions.GetValueOrDefault(aetherCurrentId);
}
public uint? GetQuestIdForCurrent(uint aetherCurrentId)
{
return _questCurrents.GetValueOrDefault(aetherCurrentId);
}
private ImmutableDictionary<uint, AetherCurrentPosition> BuildOverworldPositions()
{
HashSet<uint> hashSet = _overworldCurrents.Values.SelectMany((ImmutableList<uint> list) => list).ToHashSet();
Dictionary<uint, uint> dictionary = new Dictionary<uint, uint>();
foreach (EObj item in _dataManager.GetExcelSheet<EObj>())
{
if (item.RowId != 0)
{
uint rowId = item.Data.RowId;
if (rowId != 0 && hashSet.Contains(rowId))
{
dictionary[rowId] = item.RowId;
}
}
}
Dictionary<uint, uint> dictionary2 = dictionary.ToDictionary((KeyValuePair<uint, uint> kv) => kv.Value, (KeyValuePair<uint, uint> kv) => kv.Key);
ImmutableDictionary<uint, AetherCurrentPosition>.Builder builder = ImmutableDictionary.CreateBuilder<uint, AetherCurrentPosition>();
foreach (Level item2 in _dataManager.GetExcelSheet<Level>())
{
if (item2.RowId != 0)
{
uint rowId2 = item2.Object.RowId;
if (dictionary2.TryGetValue(rowId2, out var value) && item2.Territory.IsValid)
{
ushort territoryId = (ushort)item2.Territory.RowId;
Vector3 position = new Vector3(item2.X, item2.Y, item2.Z);
builder[value] = new AetherCurrentPosition(territoryId, position, rowId2);
}
}
}
return builder.ToImmutable();
}
}