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)),
};
}