- Update building event patches to include completion notifications - Introduce earthquake event handling for ongoing seismic activity - Modify event catalog to reflect changes in ambient interest settings - Add new harness scenarios for library asset label validation - Increment version to 0.28.17 in mod.json
314 lines
9.8 KiB
C#
314 lines
9.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
|
|
namespace IdleSpectator;
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
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<string> AllKinds => LibraryKinds;
|
|
|
|
/// <summary>Spectator-facing name for a library asset id (localized when available).</summary>
|
|
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<string> 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<string>();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Item watch verb from live asset shape: equipment/weapons/armor gain; forge-y ids forge; else gain.
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|