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> _overworldCurrents; private readonly ImmutableDictionary> _allCurrentsByTerritory; private readonly ImmutableDictionary _questCurrents; private ImmutableDictionary? _overworldPositions; public IReadOnlyDictionary> AllCurrentsByTerritory => _allCurrentsByTerritory; private ImmutableDictionary OverworldPositions => _overworldPositions ?? (_overworldPositions = BuildOverworldPositions()); public AetherCurrentData(IDataManager dataManager) { _dataManager = dataManager; _overworldCurrents = (from x in dataManager.GetExcelSheet() 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() where x.RowId != 0 where x.Territory.IsValid select x).ToImmutableDictionary((AetherCurrentCompFlgSet x) => (ushort)x.Territory.RowId, (AetherCurrentCompFlgSet x) => x.AetherCurrents.Where((RowRef y) => y.RowId != 0).Select(delegate(RowRef y) { uint rowId = y.Value.Quest.RowId; return new AetherCurrentInfo(y.RowId, rowId != 0, rowId); }).ToImmutableList()); _questCurrents = (from info in _allCurrentsByTerritory.Values.SelectMany((ImmutableList 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 value)) { return value.Contains(aetherCurrentId); } return false; } public ImmutableList GetCurrentsForTerritory(ushort territoryId) { return _allCurrentsByTerritory.GetValueOrDefault(territoryId, ImmutableList.Create(default(ReadOnlySpan))); } public AetherCurrentPosition? GetOverworldPosition(uint aetherCurrentId) { return OverworldPositions.GetValueOrDefault(aetherCurrentId); } public uint? GetQuestIdForCurrent(uint aetherCurrentId) { return _questCurrents.GetValueOrDefault(aetherCurrentId); } private ImmutableDictionary BuildOverworldPositions() { HashSet hashSet = _overworldCurrents.Values.SelectMany((ImmutableList list) => list).ToHashSet(); Dictionary dictionary = new Dictionary(); foreach (EObj item in _dataManager.GetExcelSheet()) { if (item.RowId != 0) { uint rowId = item.Data.RowId; if (rowId != 0 && hashSet.Contains(rowId)) { dictionary[rowId] = item.RowId; } } } Dictionary dictionary2 = dictionary.ToDictionary((KeyValuePair kv) => kv.Value, (KeyValuePair kv) => kv.Key); ImmutableDictionary.Builder builder = ImmutableDictionary.CreateBuilder(); foreach (Level item2 in _dataManager.GetExcelSheet()) { 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(); } }