using Microsoft.Extensions.Logging; using RPG.GameCore.Level.Floor; using RPG.GameCore.Level.Group; using RPG.GameCore.Resources; using System.Collections.Immutable; using System.Text.Json; namespace RPG.GameCore.Level; public class LevelTables { private readonly IResourceProvider _resourceProvider; private readonly ILogger _logger; private ImmutableDictionary? _floors; private ImmutableDictionary? _groups; public LevelTables(IResourceProvider resourceProvider, ILogger logger) { _resourceProvider = resourceProvider; _logger = logger; } public void Load() { _floors = LoadFloors(); _groups = LoadGroups(); _logger.LogInformation("Loaded {floorCount} floors and {groupCount} groups!", _floors.Count, _groups.Count); } public LevelFloorInfo GetFloorInfo(uint id) => _floors != null ? _floors[id] : throw new InvalidOperationException("GetFloorInfo called when tables aren't loaded!"); public LevelGroupInfo? GetGroupInfo(string guid) { if (_groups == null) throw new InvalidOperationException("GetGroupInfo called when tables aren't loaded!"); _ = _groups.TryGetValue(guid, out LevelGroupInfo? group); return group; } private ImmutableDictionary LoadFloors() { IEnumerable floorAssets = _resourceProvider.EnumerateAllLevelFloorAssets(); var builder = ImmutableDictionary.CreateBuilder(); foreach (string jsonFileName in floorAssets) { JsonDocument json = _resourceProvider.GetJsonAsset(jsonFileName); LevelFloorInfo? floorInfo = JsonSerializer.Deserialize(json); if (floorInfo == null) { _logger.LogWarning("Failed to parse level floor: {path}", jsonFileName); continue; } builder.Add(floorInfo.FloorID, floorInfo); } return builder.ToImmutable(); } private ImmutableDictionary LoadGroups() { var builder = ImmutableDictionary.CreateBuilder(); foreach (LevelFloorInfo floor in _floors!.Values) { foreach (LevelGroupInstanceInfo groupInstanceInfo in floor.GroupList) { JsonDocument json = _resourceProvider.GetJsonAsset(groupInstanceInfo.GroupPath); LevelGroupInfo? groupInfo = JsonSerializer.Deserialize(json); if (groupInfo == null) { _logger.LogError("Failed to parse level group: {path}", groupInstanceInfo.GroupPath); throw new InvalidDataException(); } builder.Add(groupInfo.GroupGUID, groupInfo); } } return builder.ToImmutable(); } }