using System; using System.Collections.Generic; using System.Reflection; namespace IdleSpectator; /// /// Localized / humanized display names for live AssetManager library ids. /// Used by library event Labels so watch tips never show raw snake_case when the game has a name. /// public static class LibraryAssetNames { private static readonly string[] LibraryKinds = { "spell", "power", "item", "gene", "phenotype", "worldlaw", "subspecies_trait", "culture_trait", "religion_trait", "clan_trait", "language_trait", "biome", "building" }; public static IReadOnlyList AllKinds => LibraryKinds; /// Spectator-facing name for a library asset id (localized when available). public static string DisplayName(string kind, string assetId) { if (string.IsNullOrEmpty(assetId)) { return ""; } object asset = TryGetAsset(kind, assetId); string localized = TryLocalizedName(asset); if (!string.IsNullOrEmpty(localized)) { return localized; } return EventReason.HumanizeId(assetId); } public static object TryGetAsset(string kind, string assetId) { if (string.IsNullOrEmpty(kind) || string.IsNullOrEmpty(assetId)) { return null; } string id = assetId.Trim(); string k = kind.Trim().ToLowerInvariant(); try { switch (k) { case "spell": return AssetManager.spells?.get(id); case "power": return AssetManager.powers?.get(id); case "item": return AssetManager.items?.get(id); case "gene": return AssetManager.gene_library?.get(id); case "phenotype": return AssetManager.phenotype_library?.get(id); case "worldlaw": case "world_law": return AssetManager.world_laws_library?.get(id); case "subspecies_trait": return AssetManager.subspecies_traits?.get(id); case "culture_trait": return AssetManager.culture_traits?.get(id); case "religion_trait": return AssetManager.religion_traits?.get(id); case "clan_trait": return AssetManager.clan_traits?.get(id); case "language_trait": return AssetManager.language_traits?.get(id); case "biome": return AssetManager.biome_library?.get(id); case "building": return AssetManager.buildings?.get(id); case "trait": return AssetManager.traits?.get(id); default: return null; } } catch { return null; } } public static List EnumerateLiveIds(string kind) { string k = (kind ?? "").Trim().ToLowerInvariant(); switch (k) { case "spell": return ActivityAssetCatalog.EnumerateLiveSpellIds(); case "power": return ActivityAssetCatalog.EnumerateLivePowerIds(); case "item": return ActivityAssetCatalog.EnumerateLiveItemIds(); case "gene": return ActivityAssetCatalog.EnumerateLiveGeneIds(); case "phenotype": return ActivityAssetCatalog.EnumerateLivePhenotypeIds(); case "worldlaw": case "world_law": return ActivityAssetCatalog.EnumerateLiveWorldLawIds(); case "subspecies_trait": return ActivityAssetCatalog.EnumerateLiveSubspeciesTraitIds(); case "culture_trait": return ActivityAssetCatalog.EnumerateLiveCultureTraitIds(); case "religion_trait": return ActivityAssetCatalog.EnumerateLiveReligionTraitIds(); case "clan_trait": return ActivityAssetCatalog.EnumerateLiveClanTraitIds(); case "language_trait": return ActivityAssetCatalog.EnumerateLiveLanguageTraitIds(); case "biome": return ActivityAssetCatalog.EnumerateLiveBiomeIds(); case "building": return ActivityAssetCatalog.EnumerateLiveBuildingIds(); default: return new List(); } } /// /// Item watch verb from live asset shape: equipment/weapons/armor gain; forge-y ids forge; else gain. /// public static string ItemVerb(string itemId) { if (string.IsNullOrEmpty(itemId)) { return "gains"; } string s = itemId.ToLowerInvariant(); if (s.Contains("forge") || s.Contains("smith") || s.Contains("anvil")) { return "forges"; } try { ItemAsset item = AssetManager.items?.get(itemId.Trim()); if (item != null) { string subtype = item.equipment_subtype ?? ""; string material = item.material ?? ""; if (!string.IsNullOrEmpty(subtype) || item.equipment_value > 0 || s.StartsWith("armor_", StringComparison.Ordinal) || s.StartsWith("weapon_", StringComparison.Ordinal) || s.StartsWith("helmet_", StringComparison.Ordinal) || s.StartsWith("boots_", StringComparison.Ordinal) || s.StartsWith("ring_", StringComparison.Ordinal) || s.StartsWith("amulet_", StringComparison.Ordinal)) { return "gains"; } _ = material; } } catch { // fall through } return "gains"; } public static bool IsSpectacleBuilding(string buildingId, BuildingAsset asset) { string id = (buildingId ?? "").ToLowerInvariant(); if (id.StartsWith("temple_", StringComparison.Ordinal) || id == "statue" || id.Contains("statue") || id.Contains("monument") || id.Contains("wonder")) { return true; } try { string group = asset != null ? (asset.group ?? "") : ""; if (group.IndexOf("temple", StringComparison.OrdinalIgnoreCase) >= 0 || group.IndexOf("wonder", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } catch { // ignore } return false; } public static bool IsCivBuilding(BuildingAsset asset) { if (asset == null) { return false; } try { return asset.building_type == BuildingType.Building_Civ; } catch { try { string type = asset.type ?? ""; return type.IndexOf("civ", StringComparison.OrdinalIgnoreCase) >= 0; } catch { return false; } } } private static string TryLocalizedName(object asset) { if (asset == null) { return ""; } try { MethodInfo translated = asset.GetType().GetMethod( "getTranslatedName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (translated != null && translated.GetParameters().Length == 0) { string name = translated.Invoke(asset, null) as string; if (IsUsableDisplay(name, asset)) { return ActivityAssetCatalog.TitleCaseWords(name.Trim()); } } } catch { // fall through } try { MethodInfo locale = asset.GetType().GetMethod( "getLocaleID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (locale != null && locale.GetParameters().Length == 0) { string localeId = locale.Invoke(asset, null) as string; if (!string.IsNullOrEmpty(localeId)) { string text = LocalizedTextManager.getText(localeId); if (IsUsableDisplay(text, asset) && !string.Equals(text, localeId, StringComparison.Ordinal)) { return ActivityAssetCatalog.TitleCaseWords(text.Trim()); } } } } catch { // fall through } return ""; } private static bool IsUsableDisplay(string name, object asset) { if (string.IsNullOrEmpty(name)) { return false; } string trimmed = name.Trim(); if (trimmed.Length == 0 || trimmed.IndexOf('_') >= 0) { return false; } try { PropertyInfo idProp = asset.GetType().GetProperty("id"); FieldInfo idField = asset.GetType().GetField("id"); string id = idProp != null ? idProp.GetValue(asset) as string : idField != null ? idField.GetValue(asset) as string : null; if (!string.IsNullOrEmpty(id) && string.Equals(trimmed, id, StringComparison.OrdinalIgnoreCase)) { return false; } } catch { // keep name } return true; } }