Updating vocalization. Finished NPC Gift Tastes and Speech Bubbles. Only Temp and UI remain.

This commit is contained in:
2018-08-13 13:55:02 -07:00
parent 36a6de2908
commit 2cafe14bbe
9 changed files with 361 additions and 163 deletions

View File

@ -1,148 +1,159 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Vocalization.Framework namespace Vocalization.Framework
{ {
/// <summary> /// <summary>
/// A class that handles all of the storage of references to the audio files for this character. /// A class that handles all of the storage of references to the audio files for this character.
/// </summary> /// </summary>
public class CharacterVoiceCue public class CharacterVoiceCue
{ {
/// <summary> /// <summary>
/// The name of the NPC. /// The name of the NPC.
/// </summary> /// </summary>
public string name; public string name;
/// <summary> /// <summary>
/// The name of the dialogue file to scrape from Content/Characters/Dialogue for inputting values into the dictionary of dialogueCues. /// The name of the dialogue file to scrape from Content/Characters/Dialogue for inputting values into the dictionary of dialogueCues.
/// </summary> /// </summary>
public List<string> dialogueFileNames; public List<string> dialogueFileNames;
/// <summary> /// <summary>
/// The name of the files in Content/Strings to scrape for dialogue. /// The name of the files in Content/Strings to scrape for dialogue.
/// </summary> /// </summary>
public List<string> stringsFileNames; public List<string> stringsFileNames;
/// <summary> /// <summary>
/// The names of the files in Content/Data to scrape for dialogue. /// The names of the files in Content/Data to scrape for dialogue.
/// </summary> /// </summary>
public List<string> dataFileNames; public List<string> dataFileNames;
/// <summary> /// <summary>
/// A dictionary of dialogue strings that correspond to audio files. /// A dictionary of dialogue strings that correspond to audio files.
/// </summary> /// </summary>
public Dictionary<string, string> dialogueCues; public Dictionary<string, string> dialogueCues;
/// <summary> /// <summary>
/// Constructor. /// Constructor.
/// </summary> /// </summary>
/// <param name="name">The name of the NPC.</param> /// <param name="name">The name of the NPC.</param>
public CharacterVoiceCue(string name) public CharacterVoiceCue(string name)
{ {
this.name = name; this.name = name;
this.dialogueCues = new Dictionary<string, string>(); this.dialogueCues = new Dictionary<string, string>();
this.stringsFileNames = new List<string>(); this.stringsFileNames = new List<string>();
this.dialogueFileNames = new List<string>(); this.dialogueFileNames = new List<string>();
this.dataFileNames = new List<string>(); this.dataFileNames = new List<string>();
} }
/// <summary> /// <summary>
/// Plays the associated dialogue file. /// Plays the associated dialogue file.
/// </summary> /// </summary>
/// <param name="dialogueString">The current dialogue string to play audio for.</param> /// <param name="dialogueString">The current dialogue string to play audio for.</param>
public void speak(string dialogueString) public void speak(string dialogueString)
{ {
string voiceFileName = ""; string voiceFileName = "";
bool exists = dialogueCues.TryGetValue(dialogueString, out voiceFileName); bool exists = dialogueCues.TryGetValue(dialogueString, out voiceFileName);
if (exists) if (exists)
{ {
Vocalization.soundManager.swapSounds(voiceFileName); Vocalization.soundManager.swapSounds(voiceFileName);
} }
else else
{ {
Vocalization.ModMonitor.Log("The dialogue cue for the current dialogue could not be found. Please ensure that the dialogue is added the character's voice file and that the proper file for the voice exists."); Vocalization.ModMonitor.Log("The dialogue cue for the current dialogue could not be found. Please ensure that the dialogue is added the character's voice file and that the proper file for the voice exists.");
return; return;
} }
} }
public void addDialogue(string key, string value) public void addDialogue(string key, string value)
{ {
if (dialogueCues.ContainsKey(key)) if (dialogueCues.ContainsKey(key))
{ {
return; return;
} }
else else
{ {
this.dialogueCues.Add(key, value); this.dialogueCues.Add(key, value);
} }
} }
public void initializeEnglishScrape() public void initializeEnglishScrape()
{ {
if (name == "TV") if (name == "TV")
{ {
dataFileNames.Add("CookingChannel.xnb"); dataFileNames.Add("CookingChannel.xnb");
dataFileNames.Add("InterviewShow.xnb"); dataFileNames.Add("InterviewShow.xnb");
dataFileNames.Add("TipChannel.xnb"); dataFileNames.Add("TipChannel.xnb");
stringsFileNames.Add("StringsFromCSFiles.xnb"); stringsFileNames.Add("StringsFromCSFiles.xnb");
} }
else if (name == "Shops") else if (name == "Shops")
{ {
stringsFileNames.Add("StringsFromCSFiles.xnb"); stringsFileNames.Add("StringsFromCSFiles.xnb");
} }
else if (name == "ExtraDialogue") else if (name == "ExtraDialogue")
{ {
dataFileNames.Add("ExtraDialogue.xnb"); dataFileNames.Add("ExtraDialogue.xnb");
} }
else if (name == "LocationDialogue") else if (name == "LocationDialogue")
{ {
stringsFileNames.Add("Locations.xnb"); stringsFileNames.Add("Locations.xnb");
stringsFileNames.Add("StringsFromMaps.xnb"); stringsFileNames.Add("StringsFromMaps.xnb");
} }
else if (name == "Events") else if (name == "Events")
{ {
stringsFileNames.Add("Events.xnb"); stringsFileNames.Add("Events.xnb");
stringsFileNames.Add("StringsFromCSFiles.xnb"); stringsFileNames.Add("StringsFromCSFiles.xnb");
} }
else if (name == "Mail") else if (name == "Mail")
{ {
dataFileNames.Add("mail.xnb"); dataFileNames.Add("mail.xnb");
} }
else if (name == "Characters") else if (name == "Characters")
{ {
stringsFileNames.Add("Characters.xnb"); stringsFileNames.Add("Characters.xnb");
} }
else if (name == "Notes") else if (name == "Notes")
{ {
stringsFileNames.Add("Notes.xnb"); stringsFileNames.Add("Notes.xnb");
dataFileNames.Add("SecretNotes.xnb"); dataFileNames.Add("SecretNotes.xnb");
} }
else if (name == "Utility") else if (name == "Utility")
{ {
stringsFileNames.Add("StringsFromCSFiles.xnb"); stringsFileNames.Add("StringsFromCSFiles.xnb");
} }
else
{ else if (name == "GiftTastes")
dialogueFileNames.Add(name + ".xnb"); {
dialogueFileNames.Add("rainy.xnb"); dataFileNames.Add("NPCGiftTastes.xnb");
dialogueFileNames.Add("MarriageDialogue.xnb"); }
dialogueFileNames.Add("MarriageDialogue"+name+".xnb");
else if (name == "SpeechBubbles")
dataFileNames.Add("EngagementDialogue.xnb"); {
stringsFileNames.Add("SpeechBubbles.xnb");
stringsFileNames.Add("StringsFromCSFiles.xnb"); }
stringsFileNames.Add(name + ".xnb");
} else
{
dialogueFileNames.Add(name + ".xnb");
dialogueFileNames.Add("rainy.xnb");
} dialogueFileNames.Add("MarriageDialogue.xnb");
} dialogueFileNames.Add("MarriageDialogue"+name+".xnb");
}
dataFileNames.Add("EngagementDialogue.xnb");
stringsFileNames.Add("StringsFromCSFiles.xnb");
stringsFileNames.Add(name + ".xnb");
}
}
}
}

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
@ -138,8 +139,8 @@ namespace Vocalization
/// ///
/// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! All in Strings folder /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! All in Strings folder
/// -Quests (done) /// -Quests (done)
/// -NPC Gift tastes /// -NPC Gift tastes (done)
/// speach bubbles /// speech bubbles (done)
/// -temp /// -temp
/// -ui /// -ui
/// /// /// ///
@ -219,6 +220,23 @@ namespace Vocalization
loadAllVoiceFiles(); loadAllVoiceFiles();
} }
public static object GetInstanceField(Type type, object instance, string fieldName)
{
BindingFlags bindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
FieldInfo field = type.GetField(fieldName, bindFlags);
/*
FieldInfo[] meh = type.GetFields(bindFlags);
foreach(var v in meh)
{
if (v.Name == null)
{
continue;
}
Monitor.Log(v.Name);
}
*/
return field.GetValue(instance);
}
/// <summary> /// <summary>
/// Runs every game tick to check if the player is talking to an npc. /// Runs every game tick to check if the player is talking to an npc.
/// </summary> /// </summary>
@ -226,6 +244,39 @@ namespace Vocalization
/// <param name="e"></param> /// <param name="e"></param>
private void GameEvents_UpdateTick(object sender, EventArgs e) private void GameEvents_UpdateTick(object sender, EventArgs e)
{ {
if (Game1.player != null) {
if (Game1.player.currentLocation != null) {
foreach (NPC v in Game1.currentLocation.characters)
{
string text = (string)GetInstanceField(typeof(NPC), v, "textAboveHead");
if (text == null) continue;
string currentDialogue = text;
if (previousDialogue != currentDialogue)
{
List<string> tries = new List<string>();
tries.Add("SpeechBubbles");
foreach (var speech in tries)
{
CharacterVoiceCue voice;
DialogueCues.TryGetValue(speech, out voice);
currentDialogue = sanitizeDialogueInGame(currentDialogue); //If contains the stuff in the else statement, change things up.
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.
voice.speak(currentDialogue);
}
else
{
ModMonitor.Log("New unregistered dialogue detected for NPC: " + speech + " saying: " + currentDialogue, LogLevel.Alert);
ModMonitor.Log("Make sure to add this to their respective VoiceCue.json file if you wish for this dialogue to have voice acting associated with it!", LogLevel.Alert);
}
}
}
}
}
}
if (Game1.currentSpeaker != null) if (Game1.currentSpeaker != null)
{ {
string speakerName = Game1.currentSpeaker.Name; string speakerName = Game1.currentSpeaker.Name;
@ -249,10 +300,12 @@ namespace Vocalization
tries.Add("CharactersStrings"); tries.Add("CharactersStrings");
tries.Add("LocationDialogue"); tries.Add("LocationDialogue");
tries.Add("Utility"); tries.Add("Utility");
tries.Add("Quests");
tries.Add("NPCGiftTastes");
foreach (var v in tries) foreach (var v in tries)
{ {
CharacterVoiceCue voice; CharacterVoiceCue voice;
DialogueCues.TryGetValue(speakerName, out voice); DialogueCues.TryGetValue(v, out voice);
currentDialogue = sanitizeDialogueInGame(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))
{ {
@ -261,7 +314,7 @@ namespace Vocalization
} }
else else
{ {
ModMonitor.Log("New unregistered dialogue detected for NPC: " + speakerName + " saying: " + currentDialogue, LogLevel.Alert); ModMonitor.Log("New unregistered dialogue detected for NPC: " + v + " saying: " + currentDialogue, LogLevel.Alert);
ModMonitor.Log("Make sure to add this to their respective VoiceCue.json file if you wish for this dialogue to have voice acting associated with it!", LogLevel.Alert); ModMonitor.Log("Make sure to add this to their respective VoiceCue.json file if you wish for this dialogue to have voice acting associated with it!", LogLevel.Alert);
} }
@ -289,6 +342,8 @@ namespace Vocalization
tries.Add("LocationDialogue"); tries.Add("LocationDialogue");
tries.Add("Notes"); tries.Add("Notes");
tries.Add("Utility"); tries.Add("Utility");
tries.Add("Quests");
tries.Add("NPCGiftTastes");
foreach (var v in tries) foreach (var v in tries)
{ {
//Add in support for TV Shows //Add in support for TV Shows
@ -473,6 +528,18 @@ namespace Vocalization
characterDialoguePaths.Add(extra); characterDialoguePaths.Add(extra);
} }
foreach (var translation in config.translations)
{
string extra = Path.Combine(translation, "NPCGiftTastes");
characterDialoguePaths.Add(extra);
}
foreach (var translation in config.translations)
{
string extra = Path.Combine(translation, "SpeechBubbles");
characterDialoguePaths.Add(extra);
}
foreach (var translation in config.translations) foreach (var translation in config.translations)
{ {
string kent = Path.Combine(translation, "Kent"); string kent = Path.Combine(translation, "Kent");
@ -1066,6 +1133,105 @@ namespace Vocalization
} }
} }
else if (cue.name == "NPCGiftTastes")
{
foreach (var fileName in cue.dataFileNames)
{
ModMonitor.Log(" Scraping dialogue file: " + fileName, LogLevel.Info);
string dialoguePath2 = Path.Combine(stringsPath, fileName);
string root = Game1.content.RootDirectory;///////USE THIS TO CHECK FOR EXISTENCE!!!!!
if (!File.Exists(Path.Combine(root, dialoguePath2)))
{
ModMonitor.Log("Dialogue file not found for:" + fileName + ". This might not necessarily be a mistake just a safety check.");
continue; //If the file is not found for some reason...
}
var DialogueDict = ModHelper.Content.Load<Dictionary<string, string>>(dialoguePath2, ContentSource.GameContent);
//Scrape the whole dictionary looking for the character's name.
List<string> ignoreKeys = new List<string>();
ignoreKeys.Add("Universal_Love");
ignoreKeys.Add("Universal_Like");
ignoreKeys.Add("Universal_Neutral");
ignoreKeys.Add("Universal_Dislike");
ignoreKeys.Add("Universal_Hate");
foreach (KeyValuePair<string, string> pair in DialogueDict)
{
//Get the key in the dictionary
string key = pair.Key;
string rawDialogue = pair.Value;
//Check to see if I need to ignore this key in my dictionary I am scaping.
bool ignore = false;
foreach(var value in ignoreKeys)
{
if (key == value)
{
ignore = true;
break;
}
}
if (ignore) continue;
List<string> strippedRawQuestDialogue = new List<string>();
List<string> strippedFreshQuestDialogue = new List<string>();
strippedRawQuestDialogue = rawDialogue.Split('/').ToList();
string prompt1 = strippedRawQuestDialogue.ElementAt(0);
string prompt2 = strippedRawQuestDialogue.ElementAt(2);
string prompt3 = strippedRawQuestDialogue.ElementAt(4);
string prompt4 = strippedRawQuestDialogue.ElementAt(6);
string prompt5 = strippedRawQuestDialogue.ElementAt(8);
strippedFreshQuestDialogue.Add(prompt1);
strippedFreshQuestDialogue.Add(prompt2);
strippedFreshQuestDialogue.Add(prompt3);
strippedFreshQuestDialogue.Add(prompt4);
strippedFreshQuestDialogue.Add(prompt5);
List<string> cleanDialogues = new List<string>();
foreach (var dia in strippedFreshQuestDialogue)
{
cleanDialogues = sanitizeDialogueFromDictionaries(rawDialogue);
foreach (var str in cleanDialogues)
{
cue.addDialogue(str, ""); //Make a new dialogue line based off of the text, but have the .wav value as empty.
}
}
}
continue;
}
}
else if (cue.name == "SpeechBubbles")
{
foreach (var fileName in cue.dataFileNames)
{
ModMonitor.Log(" Scraping dialogue file: " + fileName, LogLevel.Info);
string dialoguePath2 = Path.Combine(stringsPath, fileName);
string root = Game1.content.RootDirectory;///////USE THIS TO CHECK FOR EXISTENCE!!!!!
if (!File.Exists(Path.Combine(root, dialoguePath2)))
{
ModMonitor.Log("Dialogue file not found for:" + fileName + ". This might not necessarily be a mistake just a safety check.");
continue; //If the file is not found for some reason...
}
var DialogueDict = ModHelper.Content.Load<Dictionary<string, string>>(dialoguePath2, ContentSource.GameContent);
//Scrape the whole dictionary looking for the character's name.
foreach (KeyValuePair<string, string> pair in DialogueDict)
{
//Get the key in the dictionary
string key = pair.Key;
string rawDialogue = pair.Value;
string cleanString = sanitizeDialogueFromSpeechBubblesDictionary(rawDialogue);
cue.addDialogue(cleanString, ""); //Make a new dialogue line based off of the text, but have the .wav value as empty.
}
continue;
}
}
//Dialogue scrape for npc specific text. //Dialogue scrape for npc specific text.
else else
{ {
@ -1647,6 +1813,19 @@ namespace Vocalization
return possibleDialogues; return possibleDialogues;
} }
public string sanitizeDialogueFromSpeechBubblesDictionary(string text)
{
if (text.Contains("{0}"))
{
text = text.Replace("{0}", replacementStrings.farmerName);
}
if (text.Contains("{1}"))
{
text = text.Replace("{1}", replacementStrings.farmName);
}
return text;
}
/// <summary> /// <summary>
/// Used to remove all garbage strings from Content/Data/mail.yaml /// Used to remove all garbage strings from Content/Data/mail.yaml
/// </summary> /// </summary>

View File

@ -1,11 +1,19 @@
C:\Users\iD Student\Desktop\Stardew\Vocalization\Vocalization\bin\Debug\Vocalization.dll C:\Users\iD Student\Desktop\Stardew\Vocalization\Vocalization\bin\Debug\Vocalization.dll
C:\Users\iD Student\Desktop\Stardew\Vocalization\Vocalization\bin\Debug\Vocalization.pdb C:\Users\iD Student\Desktop\Stardew\Vocalization\Vocalization\bin\Debug\Vocalization.pdb
C:\Users\iD Student\Desktop\Stardew\Vocalization\Vocalization\obj\Debug\Vocalization.csproj.CoreCompileInputs.cache C:\Users\iD Student\Desktop\Stardew\Vocalization\Vocalization\obj\Debug\Vocalization.csproj.CoreCompileInputs.cache
C:\Users\iD Student\Desktop\Stardew\Vocalization\Vocalization\obj\Debug\Vocalization.dll C:\Users\iD Student\Desktop\Stardew\Vocalization\Vocalization\obj\Debug\Vocalization.dll
C:\Users\iD Student\Desktop\Stardew\Vocalization\Vocalization\obj\Debug\Vocalization.pdb C:\Users\iD Student\Desktop\Stardew\Vocalization\Vocalization\obj\Debug\Vocalization.pdb
C:\Users\iD Student\Desktop\Stardew\Vocalization\Vocalization\bin\Debug\Netcode.dll C:\Users\iD Student\Desktop\Stardew\Vocalization\Vocalization\bin\Debug\Netcode.dll
C:\Users\iD Student\Desktop\Stardew\Vocalization\Vocalization\bin\Debug\Netcode.pdb C:\Users\iD Student\Desktop\Stardew\Vocalization\Vocalization\bin\Debug\Netcode.pdb
C:\Users\iD Student\Desktop\Stardew\Vocalization\Vocalization\obj\Debug\Vocalization.csproj.CopyComplete C:\Users\iD Student\Desktop\Stardew\Vocalization\Vocalization\obj\Debug\Vocalization.csproj.CopyComplete
C:\Users\iD Student\Desktop\Stardew\Vocalization\Vocalization\bin\Debug\SimpleSoundManager.dll C:\Users\iD Student\Desktop\Stardew\Vocalization\Vocalization\bin\Debug\SimpleSoundManager.dll
C:\Users\iD Student\Desktop\Stardew\Vocalization\Vocalization\bin\Debug\SimpleSoundManager.pdb C:\Users\iD Student\Desktop\Stardew\Vocalization\Vocalization\bin\Debug\SimpleSoundManager.pdb
C:\Users\iD Student\Desktop\Stardew\Vocalization\Vocalization\obj\Debug\Vocalization.csprojResolveAssemblyReference.cache C:\Users\iD Student\Desktop\Stardew\Vocalization\Vocalization\obj\Debug\Vocalization.csprojResolveAssemblyReference.cache
C:\Users\owner\Documents\Visual Studio 2015\Projects\github\StardewValleyMods\Vocalization\Vocalization\bin\Debug\Vocalization.dll
C:\Users\owner\Documents\Visual Studio 2015\Projects\github\StardewValleyMods\Vocalization\Vocalization\bin\Debug\Vocalization.pdb
C:\Users\owner\Documents\Visual Studio 2015\Projects\github\StardewValleyMods\Vocalization\Vocalization\bin\Debug\Netcode.pdb
C:\Users\owner\Documents\Visual Studio 2015\Projects\github\StardewValleyMods\Vocalization\Vocalization\bin\Debug\SimpleSoundManager.pdb
C:\Users\owner\Documents\Visual Studio 2015\Projects\github\StardewValleyMods\Vocalization\Vocalization\obj\Debug\Vocalization.csprojResolveAssemblyReference.cache
C:\Users\owner\Documents\Visual Studio 2015\Projects\github\StardewValleyMods\Vocalization\Vocalization\obj\Debug\Vocalization.csproj.CoreCompileInputs.cache
C:\Users\owner\Documents\Visual Studio 2015\Projects\github\StardewValleyMods\Vocalization\Vocalization\obj\Debug\Vocalization.dll
C:\Users\owner\Documents\Visual Studio 2015\Projects\github\StardewValleyMods\Vocalization\Vocalization\obj\Debug\Vocalization.pdb