Match scenery vehicles by folder too, as the old starter did

The old starter looked a vehicle up by folder, skin and model. The folder was
left out here, and 39 skin names recur across folders - "red" is a Clio, an
Audi and a crane - so a vehicle could get another folder's livery.
This commit is contained in:
maj00r
2026-10-04 19:07:23 +02:00
parent e5c46d23ea
commit 8c046cfed4
10 changed files with 75 additions and 39 deletions

View File

@@ -27,8 +27,16 @@ public sealed class VehicleCatalog
public Dictionary<string, VehicleTexture> TextureBySkin { get; } = new();
/// <summary>For a skin shared by several models, which one dresses which.</summary>
private readonly Dictionary<string, VehicleTexture> _textureBySkinAndModel = new();
/// <summary>
/// The way the old starter matched a scenery vehicle: folder, skin and model.
/// A skin name recurs across folders ("red" for a Clio and a crane), and one
/// skin may dress several models (both halves of the ET42-026).
/// </summary>
private readonly Dictionary<string, VehicleTexture> _textureByFolderSkinModel = new();
private readonly Dictionary<string, VehicleTexture> _textureByFolderSkin = new();
private readonly Dictionary<string, VehicleTexture> _textureBySkinModel = new();
public void BeginLoad()
{
@@ -38,7 +46,9 @@ public sealed class VehicleCatalog
SetByTextureUuid.Clear();
TextureByUuid.Clear();
TextureBySkin.Clear();
_textureBySkinAndModel.Clear();
_textureByFolderSkinModel.Clear();
_textureByFolderSkin.Clear();
_textureBySkinModel.Clear();
}
public void Ingest(VehicleEntry entry)
@@ -55,7 +65,9 @@ public sealed class VehicleCatalog
if (!string.IsNullOrEmpty(texture.Skinfile))
{
TextureBySkin.TryAdd(Key(texture.Skinfile), texture);
_textureBySkinAndModel.TryAdd(Key(texture.Skinfile, texture.Model), texture);
_textureByFolderSkinModel.TryAdd(FolderSkinModelKey(texture.Directory, texture.Skinfile, texture.Model), texture);
_textureByFolderSkin.TryAdd(FolderSkinKey(texture.Directory, texture.Skinfile), texture);
_textureBySkinModel.TryAdd(SkinModelKey(texture.Skinfile, texture.Model), texture);
}
if (texture.Wreck)
@@ -112,21 +124,22 @@ public sealed class VehicleCatalog
return texture.TextureMini;
}
public string? MiniFor(string? skinFile, string? model) =>
TextureFor(skinFile, model) is { } texture ? ResolveMiniName(texture) : null;
public string? MiniFor(string? dataFolder, string? skinFile, string? model) =>
TextureFor(dataFolder, skinFile, model) is { } texture ? ResolveMiniName(texture) : null;
/// <summary>
/// The texture a vehicle wears: by the skin, and where one skin dresses several
/// models, by the model too - the scenery names both.
/// The texture a scenery vehicle wears, matched like the old starter did: by
/// folder, skin and model, then by less of it for a vehicle that moved.
/// </summary>
public VehicleTexture? TextureFor(string? skinFile, string? model)
public VehicleTexture? TextureFor(string? dataFolder, string? skinFile, string? model)
{
if (string.IsNullOrEmpty(skinFile))
return null;
if (!string.IsNullOrEmpty(model) &&
_textureBySkinAndModel.TryGetValue(Key(skinFile, model), out var exact))
return exact;
if (_textureByFolderSkinModel.TryGetValue(FolderSkinModelKey(dataFolder, skinFile, model), out var texture) ||
_textureByFolderSkin.TryGetValue(FolderSkinKey(dataFolder, skinFile), out texture) ||
_textureBySkinModel.TryGetValue(SkinModelKey(skinFile, model), out texture))
return texture;
return TextureForSkin(skinFile);
}
@@ -141,9 +154,18 @@ public sealed class VehicleCatalog
private static string Key(string skinFile) => Path.GetFileNameWithoutExtension(skinFile).ToLowerInvariant();
private static string Key(string skinFile, string? model) =>
private static string SkinModelKey(string skinFile, string? model) =>
Key(skinFile) + "|" + (string.IsNullOrEmpty(model) ? "" : Path.GetFileNameWithoutExtension(model).ToLowerInvariant());
private static string FolderSkinKey(string? folder, string skinFile) => Folder(folder) + "|" + Key(skinFile);
private static string FolderSkinModelKey(string? folder, string skinFile, string? model) =>
Folder(folder) + "|" + SkinModelKey(skinFile, model);
/// <summary>"PKP\ET42_V2" in a scenery, "pkp/et42_v2/" in the catalogue.</summary>
private static string Folder(string? folder) =>
(folder ?? "").Replace('\\', '/').Trim('/').ToLowerInvariant();
public string GroupHeader(string? groupId)
{
if (string.IsNullOrEmpty(groupId) || !GroupsById.TryGetValue(groupId, out var group))