namespace Cthangover.Mods.Stats
{
using System;
using System.Collections.Generic;
using System.Linq;
using Cthangover.Core.Utils;
///
/// The registered s. Filled by
/// per mod assembly, so a source leaves with its mod on reload; a throwing source is
/// logged and skipped, it never breaks the sheet of everyone else.
///
public static class TraitSources
{
private static readonly List Sources = new();
/// The registered sources, in registration order.
public static IReadOnlyList All => Sources;
///
/// Adds a source (ignored when already present). Only the cached sheets are dropped:
/// sources arrive while mods register, before any game state exists, so this must
/// not reach the roster (the next scene entry syncs it).
///
public static void Add(ITraitSource source)
{
if (source != null && !Sources.Contains(source))
Sources.Add(source);
StatsService.ClearCache();
}
/// Removes a source (cached sheets are dropped, see ).
public static void Remove(ITraitSource source)
{
if (Sources.Remove(source))
StatsService.ClearCache();
}
/// Every trait all sources give .
public static List Collect(string characterId)
{
var result = new List();
foreach (var source in Sources.ToList())
{
try
{
var traits = source.TraitsOf(characterId);
if (traits != null)
result.AddRange(traits.Where(t => t != null));
}
catch (Exception ex)
{
GameLogger.Log("STATS", $"trait source '{source.Id}' failed for '{characterId}': {ex.Message}", LogLevel.Error);
}
}
return result;
}
}
}