using System; namespace IdleSpectator; /// /// Adds a meaningful transformed-variant tone without replacing the recovered base mob voice. /// Native authored forms keep their own complete voice and do not pass through this overlay. /// public static class ActivityModifierVoiceOverlay { private const string PlaceToken = "{place_at}"; public static string Apply( string basePhrase, ProseVoice voice, string verb, long subjectId, int lineIndex) { if (string.IsNullOrEmpty(basePhrase) || voice == null || voice.Modifier == ActivityModifier.None || voice.LiveSpeciesId.Equals(voice.BaseSpeciesId, StringComparison.OrdinalIgnoreCase)) { return basePhrase; } string[] bag = OverlayBag(voice.Modifier, voice.BaseBodyTag, verb); if (bag == null || bag.Length == 0) { return basePhrase; } int index = (int)((subjectId ^ (lineIndex * 397L)) & 1L) % bag.Length; string core = basePhrase .Replace("{job_as}", "") .Replace("{job}", ""); bool restorePlace = false; if (WantsPlace(verb) && core.EndsWith(PlaceToken, StringComparison.Ordinal)) { core = core.Substring(0, core.Length - PlaceToken.Length); restorePlace = true; } else if (core.EndsWith(PlaceToken, StringComparison.Ordinal)) { // Never introduce or keep place on non-place-centric verbs via overlay. core = core.Substring(0, core.Length - PlaceToken.Length); } string result = core + bag[index]; if (restorePlace) { result += PlaceToken; } return result; } private static bool WantsPlace(string verb) { return verb == "settle" || verb == "trade" || verb == "farm"; } private static string[] OverlayBag( ActivityModifier modifier, ActivityBodyTag body, string verb) { return modifier switch { ActivityModifier.Undead => UndeadBag(body, verb), ActivityModifier.Elemental => ElementalBag(verb), ActivityModifier.Mush => MushBag(verb), ActivityModifier.Tumor => TumorBag(verb), ActivityModifier.Alien => AlienBag(verb), ActivityModifier.Construct => ConstructBag(verb), _ => null }; } private static string[] UndeadBag(ActivityBodyTag body, string verb) { if (verb == "move") { return body switch { ActivityBodyTag.Canine => V( ", its paws landing in stiff, uneven beats", ", its muzzle fixed ahead as its gait falters"), ActivityBodyTag.Feline => V( ", each silent step held rigid too long", ", its once-fluid gait broken into sharp jolts"), ActivityBodyTag.Bird => V( ", its lifeless wings beating out of rhythm", ", each ragged motion ending in a hard twitch"), ActivityBodyTag.Insect => V( ", its joints clicking in lifeless sequence", ", each small step snapping into the next"), ActivityBodyTag.Plant => V( ", its withered growth dragging behind", ", every deadened limb moving in rigid turns"), ActivityBodyTag.Dragon => V( ", its ruined frame carrying deathly weight", ", every ancient joint grinding through the motion"), _ => V( ", its gait broken by stiff, uneven jolts", ", every step landing with lifeless weight") }; } return verb switch { "wait" => V( ", holding an unnaturally rigid posture", ", without breath or any easy motion"), "play" => V( ", repeating each motion in empty jerks", ", the movement breaking into stiff, empty rhythms"), "eat" => V( ", driven by a hunger that never eases", ", consuming each bite without satisfaction"), "sleep" => V( ", lying rigid even at rest", ", never fully losing its restless tension"), "hunt" => V( ", pursuing without tiring", ", never slowing as the chase continues"), "fight" => V( ", striking without fear or pain", ", pressing the attack with deathless persistence"), "social" => V( ", answering with hollow, halting sounds", ", holding close in an uneasy silence"), "laugh" => V( ", the sound collapsing into a dry rasp", ", each note ending in a hollow groan"), "work" => V( ", continuing in tireless, rigid motions", ", never pausing as its joints grind on"), _ => V( ", its body moving with lifeless stiffness", ", each motion marked by restless undeath") }; } private static string[] ElementalBag(string verb) { return verb switch { "wait" => V(", flickering without becoming still", ", its glow rising and falling"), "sleep" => V(", dimming to a banked glow", ", its brightness settling low"), "eat" => V(", drawing the meal into its inner heat", ", feeding the flame within"), "fight" => V(", shedding sparks with every strike", ", flaring brighter through the clash"), _ => V(", edged by quick tongues of flame", ", trailing brief curls of heat") }; } private static string[] MushBag(string verb) { return verb switch { "wait" => V(", faint spores drifting from every pause", ", its soft growth gently pulsing"), "eat" => V(", drawing nourishment through fibrous growth", ", feeding in slow, spreading pulses"), "fight" => V(", bursting spores through every impact", ", its soft mass recoiling and swelling"), _ => V(", shedding a faint wake of spores", ", its softened form flexing with each motion") }; } private static string[] TumorBag(string verb) { return verb switch { "wait" => V(", its swollen mass quivering in place", ", uneven pulses passing through its body"), "eat" => V(", absorbing the meal into its growing mass", ", folding each bite into hungry tissue"), "fight" => V(", its mass surging behind every blow", ", new growth tightening through the clash"), _ => V(", its form shifting in uneven pulses", ", swollen tissue rolling through each motion") }; } private static string[] AlienBag(string verb) { return verb switch { "wait" => V(", holding a posture that is difficult to read", ", its unfamiliar joints locking at odd angles"), "social" => V(", answering in precise, unfamiliar signals", ", mirroring the exchange with uncanny timing"), "fight" => V(", changing angles without warning", ", every strike arriving with uncanny precision"), _ => V(", following an unfamiliar rhythm", ", each motion precise but difficult to predict") }; } private static string[] ConstructBag(string verb) { return verb switch { "wait" => V(", every mechanism settling into a fixed hold", ", its joints locking into measured stillness"), "sleep" => V(", its moving parts falling dormant", ", the last small mechanisms winding down"), "fight" => V(", every joint driving the next strike", ", its rigid frame absorbing the impact"), "work" => V(", repeating each step with exact precision", ", its mechanisms keeping a flawless cadence"), _ => V(", every joint moving in measured sequence", ", its mechanisms keeping a precise cadence") }; } private static string[] V(string first, string second) { return new[] { first, second }; } }