namespace HSchool.Content; /// /// Frozen set of defs and locale strings for one school. Built once at create/load; the worker /// never re-reads pack files afterwards. /// public sealed class DefCatalog { internal DefCatalog( IReadOnlyList packIds, IReadOnlyDictionary actions, IReadOnlyDictionary things, IReadOnlyDictionary positions, IReadOnlyDictionary works, IReadOnlyDictionary rooms, IReadOnlyDictionary buildings, IReadOnlyDictionary floors, IReadOnlyDictionary territories, IReadOnlyDictionary ru, IReadOnlyDictionary en) { PackIds = packIds; Actions = actions; Things = things; Positions = positions; Works = works; Rooms = rooms; Buildings = buildings; Floors = floors; Territories = territories; _ru = ru; _en = en; } public IReadOnlyList PackIds { get; } public IReadOnlyDictionary Actions { get; } public IReadOnlyDictionary Things { get; } public IReadOnlyDictionary Positions { get; } public IReadOnlyDictionary Works { get; } public IReadOnlyDictionary Rooms { get; } public IReadOnlyDictionary Buildings { get; } public IReadOnlyDictionary Floors { get; } public IReadOnlyDictionary Territories { get; } private readonly IReadOnlyDictionary _ru; private readonly IReadOnlyDictionary _en; public bool TryGet(DefKind kind, string defName, out Def def) { Def? found = kind switch { DefKind.Action => Actions.GetValueOrDefault(defName), DefKind.Thing => Things.GetValueOrDefault(defName), DefKind.Position => Positions.GetValueOrDefault(defName), DefKind.Work => Works.GetValueOrDefault(defName), DefKind.Room => Rooms.GetValueOrDefault(defName), DefKind.Building => Buildings.GetValueOrDefault(defName), DefKind.Floor => Floors.GetValueOrDefault(defName), DefKind.Territory => Territories.GetValueOrDefault(defName), _ => null, }; if (found is null) { def = null!; return false; } def = found; return true; } /// /// Positions the location panel should list for this node type. Only RoomDefs carry them today. /// public IReadOnlyList PositionsFor(DefKind kind, string defName) => kind == DefKind.Room && Rooms.TryGetValue(defName, out var room) ? room.Positions : []; /// Locale string for a def, walking parent when the key is missing. Falls back to defName. public string Label(string locale, Def def) { var table = locale.Equals("en", StringComparison.OrdinalIgnoreCase) ? _en : _ru; var current = def; while (true) { if (table.TryGetValue(current.DefName, out var label)) { return label; } if (current.Parent is null || !TryGet(KindOf(current), current.Parent, out var parent) || parent.DefName == current.DefName) { return def.DefName; } current = parent; } } internal static DefKind KindOf(Def def) => def switch { ActionDef => DefKind.Action, ThingDef => DefKind.Thing, PositionDef => DefKind.Position, WorkDef => DefKind.Work, RoomDef => DefKind.Room, BuildingDef => DefKind.Building, FloorDef => DefKind.Floor, TerritoryDef => DefKind.Territory, _ => throw new ArgumentOutOfRangeException(nameof(def)), }; }