using System; using System.Collections.Generic; namespace IdleSpectator; /// Authoritative authored voice registry keyed by verified base actor asset id. public static partial class ActivitySpeciesVoiceCatalog { private static readonly Dictionary Voices = Build(); private static Dictionary Build() { var voices = new Dictionary(StringComparer.OrdinalIgnoreCase); AddCivVoices(voices); AddMammalVoices(voices); AddAnimalVoices(voices); AddInvertebrateVoices(voices); AddFantasyVoices(voices); AddCivExtendedVoices(voices); AddMammalExtendedVoices(voices); AddAnimalExtendedVoices(voices); AddInvertebrateExtendedVoices(voices); AddFantasyExtendedVoices(voices); AddCivSpecializedVoices(voices); AddMammalSpecializedVoices(voices); AddAnimalSpecializedVoices(voices); AddInvertebrateSpecializedVoices(voices); AddFantasySpecializedVoices(voices); return voices; } public static bool TryGet(string baseSpeciesId, out ActivitySpeciesVoice voice) { return Voices.TryGetValue(baseSpeciesId ?? "", out voice); } public static bool HasCompleteVoice(string baseSpeciesId) { return TryGet(baseSpeciesId, out ActivitySpeciesVoice voice) && voice.HasCompleteCore(); } public static string VoiceKey(string baseSpeciesId) { return TryGet(baseSpeciesId, out ActivitySpeciesVoice voice) ? voice.Id : ""; } public static string[] GetBag(string baseSpeciesId, string verb, ActivityTerrain terrain) { return TryGet(baseSpeciesId, out ActivitySpeciesVoice voice) ? voice.GetBag(verb, terrain) : null; } public static List AuthoredIds() { var ids = new List(Voices.Keys); ids.Sort(StringComparer.Ordinal); return ids; } private static void Add( Dictionary voices, string id, string[] move, string[] wait, string[] play, string[] eat, string[] sleep, string[] hunt, string[] fight, string[] social, string[] laugh, string[] work) { var bags = new Dictionary(StringComparer.Ordinal) { ["move"] = Contextualize("move", move), ["wait"] = Contextualize("wait", wait), ["play"] = Contextualize("play", play), ["eat"] = Contextualize("eat", eat), ["sleep"] = Contextualize("sleep", sleep), ["hunt"] = Contextualize("hunt", hunt), ["fight"] = Contextualize("fight", fight), ["social"] = Contextualize("social", social), ["laugh"] = Contextualize("laugh", laugh), ["work"] = Contextualize("work", work) }; voices[id] = new ActivitySpeciesVoice(id, bags); } private static void AddLiquid( Dictionary voices, string id, string verb, string first, string second) { if (voices.TryGetValue(id, out ActivitySpeciesVoice voice)) { voice.SetLiquidBag(verb, Contextualize(verb, V(first, second))); } } private static void AddExtended( Dictionary voices, string id, string[] sing, string[] lover, string[] farm, string[] pollinate, string[] trade, string[] fish, string[] haul, string[] heal, string[] fire, string[] flee, string[] settle, string[] warrior, string[] read, string[] gatherLife, string[] relieve, string[] confused, string[] recharge, string[] strangeUrge, string[] steal, string[] possessed, string[] dream) { if (!voices.TryGetValue(id, out ActivitySpeciesVoice voice)) { throw new InvalidOperationException("Extended voice has no base entry: " + id); } Set(voice, "sing", sing); Set(voice, "lover", lover); Set(voice, "farm", farm); Set(voice, "pollinate", pollinate); Set(voice, "trade", trade); Set(voice, "fish", fish); Set(voice, "haul", haul); Set(voice, "heal", heal); Set(voice, "fire", fire); Set(voice, "flee", flee); Set(voice, "settle", settle); Set(voice, "warrior", warrior); Set(voice, "read", read); Set(voice, "gather_life", gatherLife); Set(voice, "relieve", relieve); Set(voice, "confused", confused); Set(voice, "recharge", recharge); Set(voice, "strange_urge", strangeUrge); Set(voice, "steal", steal); Set(voice, "possessed", possessed); Set(voice, "dream", dream); } private static void Set(ActivitySpeciesVoice voice, string verb, string[] phrases) { voice.SetBag(verb, Contextualize(verb, phrases)); } private static void AddSpecialized( Dictionary voices, string id, string[] ignite, string[] extinguish, string[] group, string[] harvestLife, string[] loot, string[] cry, string[] swear) { if (!voices.TryGetValue(id, out ActivitySpeciesVoice voice)) { throw new InvalidOperationException("Specialized voice has no base entry: " + id); } Set(voice, "ignite", ignite); Set(voice, "extinguish", extinguish); Set(voice, "group", group); Set(voice, "harvest_life", harvestLife); Set(voice, "loot", loot); Set(voice, "cry", cry); Set(voice, "swear", swear); } private static string[] V(string first, string second) { return new[] { first, second }; } /// /// Place only on settle / trade / farm. Never append job tokens. /// private static string[] Contextualize(string verb, string[] phrases) { if (phrases == null) { return null; } string suffix = WantsPlace(verb) ? "{place_at}" : ""; var result = new string[phrases.Length]; for (int i = 0; i < phrases.Length; i++) { result[i] = (phrases[i] ?? "") + suffix; } return result; } private static bool WantsPlace(string verb) { return verb == "settle" || verb == "trade" || verb == "farm"; } }