UI/ModelThumbs.cs

Static helper that maps a model path to a thumbnail image under ui/modeles/, falling back to the editor's thumb: scheme when the file is missing. Caches results and supports clearing the cache after a thumbnail re-render.

File Access
namespace HorizonRP;

/// <summary>
/// L'image d'un modèle dans un menu (objets d'inventaire, props, armes, véhicules).
///
/// Les menus montraient « thumb:&lt;modèle&gt; », les miniatures que l'éditeur génère pour son
/// explorateur. Celles du contenu de base de s&box (models/citizen…, models/dev) ne sont pas
/// livrées avec un jeu publié : sur le serveur, props et nourriture avaient des cases vides
/// (armes, munitions, véhicules et clé, eux, s'affichaient). Nos images sont rendues dans l'éditeur par
/// outils/modeles/vignettes_modeles.cs dans ui/modeles/, au nom tiré du chemin du modèle ; la
/// miniature de l'éditeur ne sert plus que de secours (un modèle ajouté depuis le dernier rendu).
/// </summary>
public static class ModelThumbs
{
	public const string Folder = "ui/modeles/";

	static readonly Dictionary<string, string> known = new();

	/// <summary>« models/citizen_props/chippacket01.vmdl » → « ui/modeles/models_citizen_props_chippacket01.png ».</summary>
	public static string PathOf( string model )
	{
		var name = (model ?? "").Replace( '\\', '/' ).ToLowerInvariant();
		if ( name.EndsWith( ".vmdl" ) )
			name = name[..^".vmdl".Length];
		return $"{Folder}{new string( name.Select( c => char.IsLetterOrDigit( c ) ? c : '_' ).ToArray() )}.png";
	}

	/// <summary>Notre image du modèle, sinon la miniature de l'éditeur.</summary>
	public static string Of( string model )
	{
		if ( string.IsNullOrEmpty( model ) )
			return "";
		if ( known.TryGetValue( model, out var path ) )
			return path;
		var own = PathOf( model );
		path = FileSystem.Mounted.FileExists( own ) ? own : $"thumb:{model}";
		known[model] = path;
		return path;
	}

	/// <summary>Après un rendu des images : on les recherche.</summary>
	public static void Forget() => known.Clear();
}