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:
Joshua Navarro 2018-07-08 09:22:21 -07:00 committed by GitHub
parent 4e10d7efc6
commit 2acd5f32a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 251 additions and 44 deletions

View File

@ -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>

View File

@ -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);
}
}
}
}
}
}

View File

@ -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,9 +205,15 @@ 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)
@ -202,16 +231,36 @@ namespace Vocalization
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);
@ -219,6 +268,7 @@ namespace Vocalization
} }
} }
} }
}
/// <summary> /// <summary>
@ -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;
}
} }
} }

View File

@ -1 +1 @@
038fb9dcd07cce9441d42d4051eb2db1b115c7e2 080c6a8807c043af2887ea474b0027cde5781876