Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions SpeechMod/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ public class Settings : UnityModManager.ModSettings
{
public string[] AvailableVoices;

public bool UseBracketNarratorVoice = true;

public int NarratorVoice = 0;
public int NarratorRate = 0;
public int NarratorVolume = 100;
Expand Down
7 changes: 7 additions & 0 deletions SpeechMod/Unity/MenuGUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ public static void OnGui()
{
AddVoiceSelector("Narrator Voice - See nationality below", ref Main.Settings.NarratorVoice, ref m_NarratorPreviewText, ref Main.Settings.NarratorRate, ref Main.Settings.NarratorVolume, ref Main.Settings.NarratorPitch, VoiceType.Narrator);

GUILayout.BeginVertical("", GUI.skin.box);
GUILayout.BeginHorizontal();
GUILayout.Label("Use Narrator voice for text in brackets [ ]", GUILayout.ExpandWidth(false));
Main.Settings.UseBracketNarratorVoice = GUILayout.Toggle(Main.Settings.UseBracketNarratorVoice, "Enabled");
GUILayout.EndHorizontal();
GUILayout.EndVertical();

GUILayout.BeginVertical("", GUI.skin.box);

GUILayout.BeginHorizontal();
Expand Down
56 changes: 56 additions & 0 deletions SpeechMod/Voice/WindowsSpeech.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Kingmaker.Blueprints;
using Kingmaker.UnitLogic.Abilities.Components.TargetCheckers;
using SpeechMod.Unity;
using System.Text;

#if DEBUG
using System.Reflection;
Expand Down Expand Up @@ -68,8 +69,61 @@ public static int Length(string text)
return arr.Aggregate(text, (current, t) => current.Replace(t, "")).Length;
}

private string GetVoiceStartTag(VoiceType voiceType)
{
return voiceType switch
{
VoiceType.Narrator => CombinedNarratorVoiceStart,
VoiceType.Female => CombinedFemaleVoiceStart,
VoiceType.Male => CombinedMaleVoiceStart,
VoiceType.Protagonist => CombinedProtagonistVoiceStart,
_ => CombinedDialogVoiceStart // Fallback
};
}

// Process text with brackets to switch voices
private string ProcessBrackets(string text, VoiceType? voiceType = null)
{
if (!Main.Settings.UseBracketNarratorVoice || string.IsNullOrEmpty(text) || !text.Contains("["))
{
return text;
}

// Determine what voice to switch back to after the ']'
string returnVoiceTag = voiceType.HasValue ? GetVoiceStartTag(voiceType.Value) : CombinedDialogVoiceStart;

StringBuilder sb = new();
int depth = 0;

// Iterate through each character instead of using regex to handle nested brackets as regex would struggle with nested structures
for (int i = 0; i < text.Length; i++)
{
char c = text[i];
if (c == '[')
{
if (depth == 0) sb.Append($"</voice>{CombinedNarratorVoiceStart}");
depth++;
}
else if (c == ']')
{
if (depth > 0)
{
depth--;
if (depth == 0) sb.Append($"</voice>{returnVoiceTag}");
}
}
else
{
sb.Append(c);
}
}
return sb.ToString();
}

private string FormatGenderSpecificVoices(string text)
{
text = ProcessBrackets(text);

text = text.Replace("<color=#616060>", $"</voice>{CombinedNarratorVoiceStart}");
text = text.Replace("</color>", $"</voice>{CombinedDialogVoiceStart}");

Expand Down Expand Up @@ -195,6 +249,8 @@ public void SpeakAs(string text, VoiceType voiceType, float delay = 0)
return;
}

text = ProcessBrackets(text, voiceType);

if (Main.Settings!.UseProtagonistSpecificVoice && voiceType == VoiceType.Protagonist)
{
text = $"{CombinedProtagonistVoiceStart}{text}</voice>";
Expand Down