worldbox-observer-mod/IdleSpectator/DeferredLibraryCatalogs.cs

406 lines
12 KiB
C#

using System;
using System.Collections.Generic;
namespace IdleSpectator;
/// <summary>Live spells library interest overlay (Signal when cast resolves to a unit).</summary>
public static class SpellInterestCatalog
{
private static readonly Dictionary<string, DiscreteEventEntry> Entries =
new Dictionary<string, DiscreteEventEntry>(StringComparer.OrdinalIgnoreCase);
private static readonly HashSet<string> SignalIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"summon_lightning", "summon_tornado", "cast_curse", "cast_fire",
"cast_blood_rain", "summon_meteor", "teleport"
};
private static void Ensure() =>
LiveLibraryInterest.EnsureSeeded(
Entries,
ActivityAssetCatalog.EnumerateLiveSpellIds,
"Spectacle",
"Spell: {id} ({a})",
ambientStrength: 48f,
SignalIds,
signalStrength: 88f);
public static IEnumerable<string> AuthoredIds
{
get
{
Ensure();
return Entries.Keys;
}
}
public static DiscreteEventEntry GetOrFallback(string id)
{
Ensure();
return LiveLibraryInterest.Lookup(Entries, id, "Spectacle", "Spell: {id} ({a})", 55f);
}
}
/// <summary>God powers library - mostly Ambient; Signal for disaster/spectacle ids.</summary>
public static class PowerInterestCatalog
{
private static readonly Dictionary<string, DiscreteEventEntry> Entries =
new Dictionary<string, DiscreteEventEntry>(StringComparer.OrdinalIgnoreCase);
private static bool IsSpectaclePower(string id)
{
if (string.IsNullOrEmpty(id))
{
return false;
}
string s = id.ToLowerInvariant();
return s.Contains("meteor")
|| s.Contains("earthquake")
|| s.Contains("tornado")
|| s.Contains("volcano")
|| s.Contains("nuke")
|| s.Contains("bomb")
|| s.Contains("rain_blood")
|| s.Contains("hell")
|| s.Contains("lightning")
|| s.Contains("storm")
|| s.Contains("acid")
|| s.Contains("fire")
|| s.Contains("disaster");
}
private static void Ensure() =>
LiveLibraryInterest.EnsureSeeded(
Entries,
ActivityAssetCatalog.EnumerateLivePowerIds,
"Spectacle",
"Power: {id}",
ambientStrength: 28f,
signalIds: null,
signalStrength: 92f,
signalPredicate: IsSpectaclePower);
public static IEnumerable<string> AuthoredIds
{
get
{
Ensure();
return Entries.Keys;
}
}
public static DiscreteEventEntry GetOrFallback(string id)
{
Ensure();
return LiveLibraryInterest.Lookup(Entries, id, "Spectacle", "Power: {id}", 30f);
}
}
/// <summary>AI decisions - Signal for war/rebellion/kingdom-affecting; Ambient otherwise.</summary>
public static class DecisionInterestCatalog
{
private static readonly Dictionary<string, DiscreteEventEntry> Entries =
new Dictionary<string, DiscreteEventEntry>(StringComparer.OrdinalIgnoreCase);
private static bool IsKingdomDecision(string id)
{
if (string.IsNullOrEmpty(id))
{
return false;
}
string s = id.ToLowerInvariant();
// Routine AI ticks often include "king" in the name - those are not camera events.
if (s.Contains("idle")
|| s.Contains("walking")
|| s.Contains("check")
|| s.Contains("wait")
|| s.Contains("sleep"))
{
return false;
}
return s.Contains("war")
|| s.Contains("rebellion")
|| s.Contains("revolt")
|| s.Contains("alliance")
|| s.Contains("coup")
|| s.Contains("betray")
|| s.Contains("declare")
|| s.Contains("invade")
|| s.Contains("siege")
|| s.Contains("found")
|| s.Contains("city_foundation")
|| (s.Contains("king") && (s.Contains("war") || s.Contains("city") || s.Contains("rebellion")));
}
/// <summary>True when a decision id should be allowed to own the idle camera.</summary>
public static bool IsCameraWorthy(string id) => IsKingdomDecision(id);
private static void Ensure() =>
LiveLibraryInterest.EnsureSeeded(
Entries,
ActivityAssetCatalog.EnumerateLiveDecisionIds,
"Politics",
"Decision: {id} ({a})",
ambientStrength: 32f,
signalIds: null,
signalStrength: 86f,
signalPredicate: IsKingdomDecision);
public static IEnumerable<string> AuthoredIds
{
get
{
Ensure();
return Entries.Keys;
}
}
public static DiscreteEventEntry GetOrFallback(string id)
{
Ensure();
return LiveLibraryInterest.Lookup(Entries, id, "Politics", "Decision: {id} ({a})", 35f);
}
}
/// <summary>Items library - Signal for legendary/wonder subset.</summary>
public static class ItemInterestCatalog
{
private static readonly Dictionary<string, DiscreteEventEntry> Entries =
new Dictionary<string, DiscreteEventEntry>(StringComparer.OrdinalIgnoreCase);
private static bool IsLegendaryItem(string id)
{
if (string.IsNullOrEmpty(id))
{
return false;
}
string s = id.ToLowerInvariant();
return s.Contains("legendary")
|| s.Contains("mythic")
|| s.Contains("artifact")
|| s.Contains("relic")
|| s.Contains("divine")
|| s.Contains("demon")
|| s.Contains("dragon")
|| s.Contains("nuke")
|| s.Contains("excalibur")
|| s.Contains("wonder");
}
private static void Ensure() =>
LiveLibraryInterest.EnsureSeeded(
Entries,
ActivityAssetCatalog.EnumerateLiveItemIds,
"Item",
"Item forged: {id} ({a})",
ambientStrength: 36f,
signalIds: null,
signalStrength: 80f,
signalPredicate: IsLegendaryItem);
public static IEnumerable<string> AuthoredIds
{
get
{
Ensure();
return Entries.Keys;
}
}
public static DiscreteEventEntry GetOrFallback(string id)
{
Ensure();
return LiveLibraryInterest.Lookup(Entries, id, "Item", "Item forged: {id} ({a})", 40f);
}
}
/// <summary>Subspecies traits - Signal for dramatic; Ambient fill-capped.</summary>
public static class SubspeciesTraitInterestCatalog
{
private static readonly Dictionary<string, DiscreteEventEntry> Entries =
new Dictionary<string, DiscreteEventEntry>(StringComparer.OrdinalIgnoreCase);
private static bool IsDramatic(string id)
{
if (string.IsNullOrEmpty(id))
{
return false;
}
string s = id.ToLowerInvariant();
return s.Contains("immortal")
|| s.Contains("giant")
|| s.Contains("tiny")
|| s.Contains("fire")
|| s.Contains("frost")
|| s.Contains("poison")
|| s.Contains("plague")
|| s.Contains("magic")
|| s.Contains("divine")
|| s.Contains("demon")
|| s.Contains("undead")
|| s.Contains("dragon")
|| s.Contains("evolve")
|| s.Contains("mutate");
}
private static void Ensure() =>
LiveLibraryInterest.EnsureSeeded(
Entries,
ActivityAssetCatalog.EnumerateLiveSubspeciesTraitIds,
"Evolution",
"Subspecies trait: {id}",
ambientStrength: 34f,
signalIds: null,
signalStrength: 78f,
signalPredicate: IsDramatic);
public static IEnumerable<string> AuthoredIds
{
get
{
Ensure();
return Entries.Keys;
}
}
public static DiscreteEventEntry GetOrFallback(string id)
{
Ensure();
return LiveLibraryInterest.Lookup(Entries, id, "Evolution", "Subspecies trait: {id}", 36f);
}
}
/// <summary>Genes - Ambient default.</summary>
public static class GeneInterestCatalog
{
private static readonly Dictionary<string, DiscreteEventEntry> Entries =
new Dictionary<string, DiscreteEventEntry>(StringComparer.OrdinalIgnoreCase);
private static void Ensure() =>
LiveLibraryInterest.EnsureSeeded(
Entries,
ActivityAssetCatalog.EnumerateLiveGeneIds,
"Genetics",
"Gene: {id} ({a})",
ambientStrength: 30f,
signalIds: null,
signalStrength: 70f,
signalPredicate: id => id != null && (id.Contains("warfare") || id.Contains("magic")));
public static IEnumerable<string> AuthoredIds
{
get
{
Ensure();
return Entries.Keys;
}
}
public static DiscreteEventEntry GetOrFallback(string id)
{
Ensure();
return LiveLibraryInterest.Lookup(Entries, id, "Genetics", "Gene: {id} ({a})", 30f);
}
}
/// <summary>Phenotypes - Ambient default.</summary>
public static class PhenotypeInterestCatalog
{
private static readonly Dictionary<string, DiscreteEventEntry> Entries =
new Dictionary<string, DiscreteEventEntry>(StringComparer.OrdinalIgnoreCase);
private static void Ensure() =>
LiveLibraryInterest.EnsureSeeded(
Entries,
ActivityAssetCatalog.EnumerateLivePhenotypeIds,
"Genetics",
"Phenotype: {id} ({a})",
ambientStrength: 28f,
signalIds: null,
signalStrength: 60f);
public static IEnumerable<string> AuthoredIds
{
get
{
Ensure();
return Entries.Keys;
}
}
public static DiscreteEventEntry GetOrFallback(string id)
{
Ensure();
return LiveLibraryInterest.Lookup(Entries, id, "Genetics", "Phenotype: {id} ({a})", 28f);
}
}
/// <summary>World laws - Ambient / location-only style.</summary>
public static class WorldLawInterestCatalog
{
private static readonly Dictionary<string, DiscreteEventEntry> Entries =
new Dictionary<string, DiscreteEventEntry>(StringComparer.OrdinalIgnoreCase);
private static void Ensure() =>
LiveLibraryInterest.EnsureSeeded(
Entries,
ActivityAssetCatalog.EnumerateLiveWorldLawIds,
"WorldLaw",
"World law: {id}",
ambientStrength: 40f,
signalIds: null,
signalStrength: 70f,
signalPredicate: id => id != null && (id.Contains("war") || id.Contains("death") || id.Contains("plague")));
public static IEnumerable<string> AuthoredIds
{
get
{
Ensure();
return Entries.Keys;
}
}
public static DiscreteEventEntry GetOrFallback(string id)
{
Ensure();
return LiveLibraryInterest.Lookup(Entries, id, "WorldLaw", "World law: {id}", 40f);
}
}
/// <summary>Biomes - Ambient.</summary>
public static class BiomeInterestCatalog
{
private static readonly Dictionary<string, DiscreteEventEntry> Entries =
new Dictionary<string, DiscreteEventEntry>(StringComparer.OrdinalIgnoreCase);
private static void Ensure() =>
LiveLibraryInterest.EnsureSeeded(
Entries,
ActivityAssetCatalog.EnumerateLiveBiomeIds,
"Biome",
"Biome: {id}",
ambientStrength: 26f,
signalIds: null,
signalStrength: 50f);
public static IEnumerable<string> AuthoredIds
{
get
{
Ensure();
return Entries.Keys;
}
}
public static DiscreteEventEntry GetOrFallback(string id)
{
Ensure();
return LiveLibraryInterest.Lookup(Entries, id, "Biome", "Biome: {id}", 26f);
}
}