Started work on translation update and sanitizing input.
Translation update will allow for dialogue scraping of dictionaries for different supported languages. Sanitizing input will replace game variables with a generic string so that voice acting can be more flexible and not have to record a million lines.
This commit is contained in:
parent
4e10d7efc6
commit
2acd5f32a1
|
@ -15,6 +15,12 @@ namespace Vocalization.Framework
|
||||||
/// The name of the NPC.
|
/// The name of the NPC.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string name;
|
public string name;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The name of the dialogue file to scrape for inputting values into the dictionary of dialogueCues.
|
||||||
|
/// </summary>
|
||||||
|
public string dialogueFileName;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A dictionary of dialogue strings that correspond to audio files.
|
/// A dictionary of dialogue strings that correspond to audio files.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
using StardewValley;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Vocalization.Framework
|
||||||
|
{
|
||||||
|
public class ReplacementStrings
|
||||||
|
{
|
||||||
|
|
||||||
|
public string farmerName = "<Player's Name>";
|
||||||
|
public string bandName = "<Sam's Band Name>";
|
||||||
|
public string bookName = "<Elliott's Book Name>";
|
||||||
|
public string rivalName = "<Rival's Name>";
|
||||||
|
public string petName = "<Pet's Name>";
|
||||||
|
public string farmName = "<Farm Name>";
|
||||||
|
public string favoriteThing = "<Favorite Thing>";
|
||||||
|
public string kid1Name = "<Kid 1's Name>";
|
||||||
|
public string kid2Name = "<Kid 2's Name>";
|
||||||
|
|
||||||
|
public List<string> adjStrings;
|
||||||
|
public List<string> nounStrings;
|
||||||
|
public List<string> placeStrings;
|
||||||
|
public List<string> spouseNames;
|
||||||
|
|
||||||
|
|
||||||
|
public ReplacementStrings()
|
||||||
|
{
|
||||||
|
loadAdjStrings();
|
||||||
|
loadNounStrings();
|
||||||
|
loadPlaceStrings();
|
||||||
|
loadSpouseStrings();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadAdjStrings()
|
||||||
|
{
|
||||||
|
adjStrings = new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadNounStrings()
|
||||||
|
{
|
||||||
|
nounStrings = new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadPlaceStrings()
|
||||||
|
{
|
||||||
|
placeStrings = new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Load all associated spouse names.
|
||||||
|
/// </summary>
|
||||||
|
public void loadSpouseStrings()
|
||||||
|
{
|
||||||
|
spouseNames = new List<string>();
|
||||||
|
foreach(var loc in Game1.locations)
|
||||||
|
{
|
||||||
|
foreach(var character in loc.characters)
|
||||||
|
{
|
||||||
|
if (character.datable.Value)
|
||||||
|
{
|
||||||
|
spouseNames.Add(character.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,11 +27,14 @@ namespace Vocalization
|
||||||
///
|
///
|
||||||
/// Sanitize input to remove variables such as pet names, farm names, farmer name. (done?)
|
/// Sanitize input to remove variables such as pet names, farm names, farmer name. (done?)
|
||||||
///
|
///
|
||||||
/// !!!!!!!Loop through common variables and add them to the dialogue list.
|
/// !!!!!!!Loop through common variables and add them to the dialogue list inside of ReplacementString.cs
|
||||||
///
|
///
|
||||||
/// !!!!!!!Add in dialogue for npcs into their respective VoiceCue.json files.
|
/// !!!!!!!Add in dialogue for npcs into their respective VoiceCue.json files.
|
||||||
///
|
///
|
||||||
/// !!!!!!!Add support for different kinds of menus. TV, shops, etc.
|
/// !!!!!!!Add support for different kinds of menus. TV, shops, etc.
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// !!!!!!!!!Make moddable to support other languages, portuguese, russian, etc (Needs testing)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Vocalization : Mod
|
public class Vocalization : Mod
|
||||||
{
|
{
|
||||||
|
@ -53,6 +56,8 @@ namespace Vocalization
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string VoicePath = "";
|
public static string VoicePath = "";
|
||||||
|
|
||||||
|
public static ReplacementStrings replacementStrings;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A dictionary that keeps track of all of the npcs whom have voice acting for their dialogue.
|
/// A dictionary that keeps track of all of the npcs whom have voice acting for their dialogue.
|
||||||
|
@ -63,6 +68,7 @@ namespace Vocalization
|
||||||
{
|
{
|
||||||
StardewModdingAPI.Events.SaveEvents.AfterLoad += SaveEvents_AfterLoad;
|
StardewModdingAPI.Events.SaveEvents.AfterLoad += SaveEvents_AfterLoad;
|
||||||
DialogueCues = new Dictionary<string, CharacterVoiceCue>();
|
DialogueCues = new Dictionary<string, CharacterVoiceCue>();
|
||||||
|
replacementStrings = new ReplacementStrings();
|
||||||
|
|
||||||
StardewModdingAPI.Events.GameEvents.UpdateTick += GameEvents_UpdateTick;
|
StardewModdingAPI.Events.GameEvents.UpdateTick += GameEvents_UpdateTick;
|
||||||
StardewModdingAPI.Events.MenuEvents.MenuClosed += MenuEvents_MenuClosed;
|
StardewModdingAPI.Events.MenuEvents.MenuClosed += MenuEvents_MenuClosed;
|
||||||
|
@ -125,7 +131,7 @@ namespace Vocalization
|
||||||
|
|
||||||
CharacterVoiceCue voice;
|
CharacterVoiceCue voice;
|
||||||
DialogueCues.TryGetValue(speakerName,out voice);
|
DialogueCues.TryGetValue(speakerName,out voice);
|
||||||
currentDialogue=sanitizeDialogue(currentDialogue); //If contains the stuff in the else statement, change things up.
|
currentDialogue=sanitizeDialogueInGame(currentDialogue); //If contains the stuff in the else statement, change things up.
|
||||||
if (voice.dialogueCues.ContainsKey(currentDialogue))
|
if (voice.dialogueCues.ContainsKey(currentDialogue))
|
||||||
{
|
{
|
||||||
//Not variable messages. Aka messages that don't contain words the user can change such as farm name, farmer name etc.
|
//Not variable messages. Aka messages that don't contain words the user can change such as farm name, farmer name etc.
|
||||||
|
@ -150,24 +156,41 @@ namespace Vocalization
|
||||||
string contentPath = Path.Combine(basePath, "Content");
|
string contentPath = Path.Combine(basePath, "Content");
|
||||||
string audioPath = Path.Combine(contentPath, "Audio");
|
string audioPath = Path.Combine(contentPath, "Audio");
|
||||||
string voicePath = Path.Combine(audioPath, "VoiceFiles");
|
string voicePath = Path.Combine(audioPath, "VoiceFiles");
|
||||||
|
|
||||||
|
|
||||||
|
List<string> translationFolders = new List<string>();
|
||||||
|
|
||||||
|
//TODO: Add more translations.
|
||||||
|
translationFolders.Add(Path.Combine(voicePath, "English"));
|
||||||
|
|
||||||
VoicePath = voicePath; //Set a static reference to my voice files directory.
|
VoicePath = voicePath; //Set a static reference to my voice files directory.
|
||||||
|
|
||||||
List<string> characterDialoguePaths = new List<string>();
|
List<string> characterDialoguePaths = new List<string>();
|
||||||
|
|
||||||
//Get a list of all characters in the game and make voice directories for them.
|
//Get a list of all characters in the game and make voice directories for them in each supported translation of the mod.
|
||||||
foreach (var loc in Game1.locations)
|
foreach (var loc in Game1.locations)
|
||||||
{
|
{
|
||||||
foreach(var NPC in loc.characters)
|
foreach(var NPC in loc.characters)
|
||||||
{
|
{
|
||||||
string characterPath = Path.Combine(voicePath, NPC.Name);
|
foreach (var translation in translationFolders)
|
||||||
|
{
|
||||||
|
string characterPath = Path.Combine(translation, NPC.Name);
|
||||||
characterDialoguePaths.Add(characterPath);
|
characterDialoguePaths.Add(characterPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!Directory.Exists(contentPath)) Directory.CreateDirectory(contentPath);
|
if (!Directory.Exists(contentPath)) Directory.CreateDirectory(contentPath);
|
||||||
if (!Directory.Exists(audioPath)) Directory.CreateDirectory(audioPath);
|
if (!Directory.Exists(audioPath)) Directory.CreateDirectory(audioPath);
|
||||||
if (!Directory.Exists(voicePath)) Directory.CreateDirectory(voicePath);
|
if (!Directory.Exists(voicePath)) Directory.CreateDirectory(voicePath);
|
||||||
|
|
||||||
|
|
||||||
|
//Create all of the necessary folders for different translations.
|
||||||
|
foreach(var dir in translationFolders)
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
|
||||||
|
}
|
||||||
|
|
||||||
//Create a list of new directories if the corresponding character directory doesn't exist.
|
//Create a list of new directories if the corresponding character directory doesn't exist.
|
||||||
//Note: A modder could also manually add in their own character directory for voice lines instead of having to add it via code.
|
//Note: A modder could also manually add in their own character directory for voice lines instead of having to add it via code.
|
||||||
foreach (var dir in characterDialoguePaths)
|
foreach (var dir in characterDialoguePaths)
|
||||||
|
@ -182,40 +205,67 @@ namespace Vocalization
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void loadAllVoiceFiles()
|
public void loadAllVoiceFiles()
|
||||||
{
|
{
|
||||||
List<string> directories = Directory.GetDirectories(VoicePath).ToList();
|
//get a list of all translations supported by this mod.
|
||||||
foreach(var dir in directories)
|
List<string> translations = Directory.GetDirectories(VoicePath).ToList();
|
||||||
|
foreach (var translation in translations)
|
||||||
{
|
{
|
||||||
|
List<string> characterVoiceLines = Directory.GetDirectories(translation).ToList();
|
||||||
|
//get a list of all characters supported in this translation and load their voice cue file.
|
||||||
|
foreach (var dir in characterVoiceLines)
|
||||||
|
{
|
||||||
|
|
||||||
List<string> audioClips = Directory.GetFiles(dir, ".wav").ToList();
|
List<string> audioClips = Directory.GetFiles(dir, ".wav").ToList();
|
||||||
//For every .wav file in every character voice clip directory load in the voice clip.
|
//For every .wav file in every character voice clip directory load in the voice clip.
|
||||||
foreach(var file in audioClips)
|
foreach (var file in audioClips)
|
||||||
{
|
{
|
||||||
string fileName = Path.GetFileNameWithoutExtension(file);
|
string fileName = Path.GetFileNameWithoutExtension(file);
|
||||||
soundManager.loadWavFile(ModHelper, fileName, file);
|
soundManager.loadWavFile(ModHelper, fileName, file);
|
||||||
ModMonitor.Log("Loaded sound file: " + fileName+ " from: "+ file);
|
ModMonitor.Log("Loaded sound file: " + fileName + " from: " + file);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get the character dialogue cues (aka when the character should "speak") from the .json file.
|
//Get the character dialogue cues (aka when the character should "speak") from the .json file.
|
||||||
string voiceCueFile=Path.Combine(dir,"VoiceCues.json");
|
string voiceCueFile = Path.Combine(dir, "VoiceCues.json");
|
||||||
string characterName = Path.GetFileName(dir);
|
string characterName = Path.GetFileName(dir);
|
||||||
|
|
||||||
//If a file was not found, create one and add it to the list of character voice cues.
|
//If a file was not found, create one and add it to the list of character voice cues.
|
||||||
if (!File.Exists(voiceCueFile))
|
if (!File.Exists(voiceCueFile))
|
||||||
{
|
{
|
||||||
CharacterVoiceCue cue= new CharacterVoiceCue(characterName);
|
CharacterVoiceCue cue = new CharacterVoiceCue(characterName);
|
||||||
|
|
||||||
|
var contentDirectory = Game1.content.RootDirectory;
|
||||||
|
|
||||||
|
var DialogueDict=ModHelper.Content.Load<Dictionary<string,string>>(cue.dialogueFileName, ContentSource.GameContent);
|
||||||
|
|
||||||
|
foreach(KeyValuePair<string,string>pair in DialogueDict)
|
||||||
|
{
|
||||||
|
string dialogue = pair.Value;
|
||||||
|
dialogue = sanitizeDialogueFromDictionaries(dialogue);
|
||||||
|
}
|
||||||
|
|
||||||
//Loop through all variations of...
|
//Loop through all variations of...
|
||||||
//time %time
|
//time %time
|
||||||
//adjectives $adj
|
//adjectives $adj
|
||||||
//nouns %noun
|
//nouns %noun
|
||||||
//location %place
|
//location %place
|
||||||
//spouse %spouse
|
//spouse %spouse
|
||||||
|
|
||||||
//If found in a string of dialogue in a character file.
|
//If found in a string of dialogue in a character file.
|
||||||
|
/*
|
||||||
|
*DialogueDict=load dict
|
||||||
|
* foreach(KeyValuePair<string,string> pair in ){
|
||||||
|
* dialogue=
|
||||||
|
*
|
||||||
|
* }
|
||||||
|
*/
|
||||||
ModHelper.WriteJsonFile<CharacterVoiceCue>(Path.Combine(dir, "VoiceCues.json"), cue);
|
ModHelper.WriteJsonFile<CharacterVoiceCue>(Path.Combine(dir, "VoiceCues.json"), cue);
|
||||||
DialogueCues.Add(characterName, cue);
|
DialogueCues.Add(characterName, cue);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CharacterVoiceCue cue=ModHelper.ReadJsonFile<CharacterVoiceCue>(voiceCueFile);
|
CharacterVoiceCue cue = ModHelper.ReadJsonFile<CharacterVoiceCue>(voiceCueFile);
|
||||||
DialogueCues.Add(characterName,cue);
|
DialogueCues.Add(characterName, cue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,48 +276,127 @@ namespace Vocalization
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dialogue"></param>
|
/// <param name="dialogue"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public string sanitizeDialogue(string dialogue)
|
public string sanitizeDialogueInGame(string dialogue)
|
||||||
{
|
{
|
||||||
if (dialogue.Contains(Game1.player.Name))
|
if (dialogue.Contains(Game1.player.Name))
|
||||||
{
|
{
|
||||||
dialogue = dialogue.Replace(Game1.player.name, ""); //Remove player's name from dialogue.
|
dialogue = dialogue.Replace(Game1.player.name, ); //Remove player's name from dialogue.
|
||||||
dialogue = dialogue.Replace(" ", " "); //Remove awkward double space that is left when removing player's name.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Game1.player.hasPet())
|
if (Game1.player.hasPet())
|
||||||
{
|
{
|
||||||
if (dialogue.Contains(Game1.player.getPetName()))
|
if (dialogue.Contains(Game1.player.getPetName()))
|
||||||
{
|
{
|
||||||
dialogue.Replace(Game1.player.getPetName(), "");
|
dialogue=dialogue.Replace(Game1.player.getPetName(), );
|
||||||
dialogue = dialogue.Replace(" ", " "); //Remove awkward double space that is left when removing player's pet's name.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dialogue.Contains(Game1.player.farmName.Value))
|
if (dialogue.Contains(Game1.player.farmName.Value))
|
||||||
{
|
{
|
||||||
dialogue.Replace(Game1.player.farmName.Value, "");
|
dialogue=dialogue.Replace(Game1.player.farmName.Value, );
|
||||||
dialogue = dialogue.Replace(" ", " "); //Remove awkward double space that is left when removing player's farm name.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dialogue.Contains(Game1.player.favoriteThing.Value))
|
if (dialogue.Contains(Game1.player.favoriteThing.Value))
|
||||||
{
|
{
|
||||||
dialogue.Replace(Game1.player.favoriteThing.Value, "");
|
dialogue=dialogue.Replace(Game1.player.favoriteThing.Value, );
|
||||||
dialogue = dialogue.Replace(" ", " "); //Remove awkward double space that is left when removing player's favorite thing.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dialogue.Contains(Game1.samBandName))
|
if (dialogue.Contains(Game1.samBandName))
|
||||||
{
|
{
|
||||||
dialogue.Replace(Game1.samBandName, "");
|
dialogue=dialogue.Replace(Game1.samBandName, );
|
||||||
dialogue = dialogue.Replace(" ", " "); //Remove awkward double space that is left when removing Sam's band name.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dialogue.Contains(Game1.elliottBookName))
|
if (dialogue.Contains(Game1.elliottBookName))
|
||||||
{
|
{
|
||||||
dialogue.Replace(Game1.elliottBookName, "");
|
dialogue=dialogue.Replace(Game1.elliottBookName, );
|
||||||
dialogue = dialogue.Replace(" ", " "); //Remove awkward double space that is left when removing Elliott's book name.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return dialogue;
|
return dialogue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string sanitizeDialogueFromDictionaries(string dialogue)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (dialogue.Contains("@"))
|
||||||
|
{
|
||||||
|
//replace with farmer name.
|
||||||
|
dialogue=dialogue.Replace("@",);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dialogue.Contains("%adj"))
|
||||||
|
{
|
||||||
|
//??? Loop through all possible adj combinations.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dialogue.Contains("%noun"))
|
||||||
|
{
|
||||||
|
//??? Loop through all possible noun combinations.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dialogue.Contains("%place"))
|
||||||
|
{
|
||||||
|
//??? Loop through all place combinations.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dialogue.Contains("%spouse"))
|
||||||
|
{
|
||||||
|
//Replace with all possible marriageable npcs
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dialogue.Contains("%time"))
|
||||||
|
{
|
||||||
|
//Replace with all times of day. 600-2600.
|
||||||
|
for(int i = 600; i <= 2600; i += 10)
|
||||||
|
{
|
||||||
|
string time = i.ToString();
|
||||||
|
dialogue = dialogue.Replace("%time", time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dialogue.Contains("%band"))
|
||||||
|
{
|
||||||
|
//Replace with<Sam's Band Name>
|
||||||
|
dialogue = dialogue.Replace("%band", );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dialogue.Contains("%book"))
|
||||||
|
{
|
||||||
|
//Replace with<Elliott's Book Name>
|
||||||
|
dialogue = dialogue.Replace("%book",);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dialogue.Contains("%rival"))
|
||||||
|
{
|
||||||
|
//Replace with<Rival Name>
|
||||||
|
dialogue = dialogue.Replace("%rival",);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dialogue.Contains("%pet"))
|
||||||
|
{
|
||||||
|
//Replace with <Pet Name>
|
||||||
|
dialogue = dialogue.Replace("%pet",);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dialogue.Contains("%farm"))
|
||||||
|
{
|
||||||
|
//Replace with <Farm Name>
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dialogue.Contains("%favorite"))
|
||||||
|
{
|
||||||
|
//Replace with <Favorite thing>
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dialogue.Contains("%kid1"))
|
||||||
|
{
|
||||||
|
//Replace with <Kid 1's Name>
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dialogue.Contains("%kid2"))
|
||||||
|
{
|
||||||
|
//Replace with <Kid 2's Name>
|
||||||
|
}
|
||||||
|
return dialogue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
038fb9dcd07cce9441d42d4051eb2db1b115c7e2
|
080c6a8807c043af2887ea474b0027cde5781876
|
||||||
|
|
Loading…
Reference in New Issue