121 lines
4.0 KiB
C#
121 lines
4.0 KiB
C#
namespace HSchool.Content;
|
|
|
|
/// <summary>
|
|
/// Frozen set of defs and locale strings for one school. Built once at create/load; the worker
|
|
/// never re-reads pack files afterwards.
|
|
/// </summary>
|
|
public sealed class DefCatalog
|
|
{
|
|
internal DefCatalog(
|
|
IReadOnlyList<string> packIds,
|
|
IReadOnlyDictionary<string, ActionDef> actions,
|
|
IReadOnlyDictionary<string, ThingDef> things,
|
|
IReadOnlyDictionary<string, PositionDef> positions,
|
|
IReadOnlyDictionary<string, WorkDef> works,
|
|
IReadOnlyDictionary<string, RoomDef> rooms,
|
|
IReadOnlyDictionary<string, BuildingDef> buildings,
|
|
IReadOnlyDictionary<string, FloorDef> floors,
|
|
IReadOnlyDictionary<string, TerritoryDef> territories,
|
|
IReadOnlyDictionary<string, string> ru,
|
|
IReadOnlyDictionary<string, string> 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<string> PackIds { get; }
|
|
|
|
public IReadOnlyDictionary<string, ActionDef> Actions { get; }
|
|
|
|
public IReadOnlyDictionary<string, ThingDef> Things { get; }
|
|
|
|
public IReadOnlyDictionary<string, PositionDef> Positions { get; }
|
|
|
|
public IReadOnlyDictionary<string, WorkDef> Works { get; }
|
|
|
|
public IReadOnlyDictionary<string, RoomDef> Rooms { get; }
|
|
|
|
public IReadOnlyDictionary<string, BuildingDef> Buildings { get; }
|
|
|
|
public IReadOnlyDictionary<string, FloorDef> Floors { get; }
|
|
|
|
public IReadOnlyDictionary<string, TerritoryDef> Territories { get; }
|
|
|
|
private readonly IReadOnlyDictionary<string, string> _ru;
|
|
private readonly IReadOnlyDictionary<string, string> _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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Positions the location panel should list for this node type. Only RoomDefs carry them today.
|
|
/// </summary>
|
|
public IReadOnlyList<string> PositionsFor(DefKind kind, string defName) =>
|
|
kind == DefKind.Room && Rooms.TryGetValue(defName, out var room) ? room.Positions : [];
|
|
|
|
/// <summary>Locale string for a def, walking <c>parent</c> when the key is missing. Falls back to <c>defName</c>.</summary>
|
|
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)),
|
|
};
|
|
}
|