From 6674a4c6e6f9076573b835624abf943fa2d43457 Mon Sep 17 00:00:00 2001 From: Noah Pilarski Date: Sat, 27 Apr 2024 20:42:27 -0400 Subject: [PATCH 1/8] Upper/Lower extensions for translations --- .../ShipLog/ShipLogStarChartMode.cs | 2 +- NewHorizons/Handlers/TranslationHandler.cs | 2 +- .../SignalPatches/AudioSignalPatches.cs | 5 +- NewHorizons/Utility/DebugTools/DebugReload.cs | 2 +- .../Utility/DebugTools/Menu/DebugMenu.cs | 2 +- NewHorizons/Utility/NewHorizonExtensions.cs | 61 +++++++++++++++++++ 6 files changed, 68 insertions(+), 6 deletions(-) diff --git a/NewHorizons/Components/ShipLog/ShipLogStarChartMode.cs b/NewHorizons/Components/ShipLog/ShipLogStarChartMode.cs index a1d466eb..57d48c35 100644 --- a/NewHorizons/Components/ShipLog/ShipLogStarChartMode.cs +++ b/NewHorizons/Components/ShipLog/ShipLogStarChartMode.cs @@ -282,7 +282,7 @@ namespace NewHorizons.Components.ShipLog var name = UniqueIDToName(shipLogEntryCard.name); - var warpNotificationDataText = TranslationHandler.GetTranslation("WARP_LOCKED", TranslationHandler.TextType.UI).Replace("{0}", name.ToUpper()); + var warpNotificationDataText = TranslationHandler.GetTranslation("WARP_LOCKED", TranslationHandler.TextType.UI).Replace("{0}", name.ToUpperFixed()); _warpNotificationData = new NotificationData(warpNotificationDataText); NotificationManager.SharedInstance.PostNotification(_warpNotificationData, true); diff --git a/NewHorizons/Handlers/TranslationHandler.cs b/NewHorizons/Handlers/TranslationHandler.cs index c2f49ebf..b90bb870 100644 --- a/NewHorizons/Handlers/TranslationHandler.cs +++ b/NewHorizons/Handlers/TranslationHandler.cs @@ -189,7 +189,7 @@ namespace NewHorizons.Handlers { var uiTable = TextTranslation.Get().m_table.theUITable; - var text = GetTranslation(rawText, TextType.UI).ToUpper(); + var text = GetTranslation(rawText, TextType.UI).ToUpperFixed(); var key = uiTable.Keys.Max() + 1; try diff --git a/NewHorizons/Patches/SignalPatches/AudioSignalPatches.cs b/NewHorizons/Patches/SignalPatches/AudioSignalPatches.cs index 9f1aacfe..58beba59 100644 --- a/NewHorizons/Patches/SignalPatches/AudioSignalPatches.cs +++ b/NewHorizons/Patches/SignalPatches/AudioSignalPatches.cs @@ -2,6 +2,7 @@ using HarmonyLib; using NewHorizons.Builder.Props.Audio; using NewHorizons.External; using NewHorizons.Handlers; +using NewHorizons.Utility; using System; using UnityEngine; @@ -17,7 +18,7 @@ namespace NewHorizons.Patches.SignalPatches var customSignalName = SignalBuilder.GetCustomSignalName(name); if (!string.IsNullOrEmpty(customSignalName)) { - __result = TranslationHandler.GetTranslation(customSignalName, TranslationHandler.TextType.UI, false).ToUpper(); + __result = TranslationHandler.GetTranslation(customSignalName, TranslationHandler.TextType.UI, false).ToUpperFixed(); return false; } return true; @@ -68,7 +69,7 @@ namespace NewHorizons.Patches.SignalPatches var customName = SignalBuilder.GetCustomFrequencyName(frequency); if (!string.IsNullOrEmpty(customName)) { - if (NewHorizonsData.KnowsFrequency(customName)) __result = TranslationHandler.GetTranslation(customName, TranslationHandler.TextType.UI, false).ToUpper(); + if (NewHorizonsData.KnowsFrequency(customName)) __result = TranslationHandler.GetTranslation(customName, TranslationHandler.TextType.UI, false).ToUpperFixed(); else __result = UITextLibrary.GetString(UITextType.SignalFreqUnidentified); return false; } diff --git a/NewHorizons/Utility/DebugTools/DebugReload.cs b/NewHorizons/Utility/DebugTools/DebugReload.cs index cd067d98..c40d76b8 100644 --- a/NewHorizons/Utility/DebugTools/DebugReload.cs +++ b/NewHorizons/Utility/DebugTools/DebugReload.cs @@ -15,7 +15,7 @@ namespace NewHorizons.Utility.DebugTools public static void InitializePauseMenu(IPauseMenuManager pauseMenu) { - _reloadButton = pauseMenu.MakeSimpleButton(TranslationHandler.GetTranslation("Reload Configs", TranslationHandler.TextType.UI).ToUpper(), 3, true); + _reloadButton = pauseMenu.MakeSimpleButton(TranslationHandler.GetTranslation("Reload Configs", TranslationHandler.TextType.UI).ToUpperFixed(), 3, true); _reloadButton.OnSubmitAction += ReloadConfigs; UpdateReloadButton(); } diff --git a/NewHorizons/Utility/DebugTools/Menu/DebugMenu.cs b/NewHorizons/Utility/DebugTools/Menu/DebugMenu.cs index 92e77893..882b9cee 100644 --- a/NewHorizons/Utility/DebugTools/Menu/DebugMenu.cs +++ b/NewHorizons/Utility/DebugTools/Menu/DebugMenu.cs @@ -89,7 +89,7 @@ namespace NewHorizons.Utility.DebugTools.Menu public static void InitializePauseMenu(IPauseMenuManager pauseMenu) { - pauseMenuButton = pauseMenu.MakeSimpleButton(TranslationHandler.GetTranslation("Toggle Dev Tools Menu", TranslationHandler.TextType.UI).ToUpper(), 3, true); + pauseMenuButton = pauseMenu.MakeSimpleButton(TranslationHandler.GetTranslation("Toggle Dev Tools Menu", TranslationHandler.TextType.UI).ToUpperFixed(), 3, true); _instance?.InitMenu(); } diff --git a/NewHorizons/Utility/NewHorizonExtensions.cs b/NewHorizons/Utility/NewHorizonExtensions.cs index c34182e1..63593ba2 100644 --- a/NewHorizons/Utility/NewHorizonExtensions.cs +++ b/NewHorizons/Utility/NewHorizonExtensions.cs @@ -7,6 +7,7 @@ using Newtonsoft.Json; using OWML.Utils; using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Reflection; @@ -69,6 +70,66 @@ namespace NewHorizons.Utility return 0; } + public static string ToLanguageName(this TextTranslation.Language language) + { + switch (language) + { + case TextTranslation.Language.UNKNOWN: + case TextTranslation.Language.TOTAL: + case TextTranslation.Language.ENGLISH: + return "English"; + case TextTranslation.Language.SPANISH_LA: + return "Spanish"; + case TextTranslation.Language.GERMAN: + return "German"; + case TextTranslation.Language.FRENCH: + return "French"; + case TextTranslation.Language.ITALIAN: + return "Italian"; + case TextTranslation.Language.POLISH: + return "Polish"; + case TextTranslation.Language.PORTUGUESE_BR: + return "Portuguese (Brazil)"; + case TextTranslation.Language.JAPANESE: + return "Japanese"; + case TextTranslation.Language.RUSSIAN: + return "Russian"; + case TextTranslation.Language.CHINESE_SIMPLE: + return "Chinese (Simplified)"; + case TextTranslation.Language.KOREAN: + return "Korean"; + case TextTranslation.Language.TURKISH: + return "Turkish"; + default: + return language.ToString().Replace("_", " ").ToLowerInvariant().ToTitleCase(); + } + } + + public static CultureInfo ToCultureInfo(this TextTranslation.Language language) + { + return CultureInfo.GetCultures(CultureTypes.AllCultures).FirstOrDefault(culture => culture.DisplayName == language.ToLanguageName()) ?? CultureInfo.CurrentCulture; + } + + public static string ToUpperFixed(this string str) + { + return str.ToUpper(TextTranslation.Get().m_language); + } + + public static string ToLowerFixed(this string str) + { + return str.ToLower(TextTranslation.Get().m_language); + } + + public static string ToUpper(this string str, TextTranslation.Language language) + { + return str.ToUpper(language.ToCultureInfo()); + } + + public static string ToLower(this string str, TextTranslation.Language language) + { + return str.ToLower(language.ToCultureInfo()); + } + public static string ToCamelCase(this string str) { StringBuilder strBuilder = new StringBuilder(str); From a21b2c693c5b9ec7bd4fb9574485a13e444eb218 Mon Sep 17 00:00:00 2001 From: Noah Pilarski Date: Sat, 27 Apr 2024 21:00:44 -0400 Subject: [PATCH 2/8] Display name is localized so don't use + account for custom langs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tested on the 3 current custom languages Czech Icelandic and Andalûh (Andalûh didn't work because it doesn't have a windows culture) --- NewHorizons/Utility/NewHorizonExtensions.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/NewHorizons/Utility/NewHorizonExtensions.cs b/NewHorizons/Utility/NewHorizonExtensions.cs index 63593ba2..1169625b 100644 --- a/NewHorizons/Utility/NewHorizonExtensions.cs +++ b/NewHorizons/Utility/NewHorizonExtensions.cs @@ -101,13 +101,17 @@ namespace NewHorizons.Utility case TextTranslation.Language.TURKISH: return "Turkish"; default: - return language.ToString().Replace("_", " ").ToLowerInvariant().ToTitleCase(); + return language.ToString().Replace("_", " ").ToTitleCase(); } } public static CultureInfo ToCultureInfo(this TextTranslation.Language language) { - return CultureInfo.GetCultures(CultureTypes.AllCultures).FirstOrDefault(culture => culture.DisplayName == language.ToLanguageName()) ?? CultureInfo.CurrentCulture; + return CultureInfo.GetCultures(CultureTypes.AllCultures).FirstOrDefault(culture => + { + var name = language.ToLanguageName(); + return culture.EnglishName == name || culture.NativeName.ToTitleCase() == name; + }) ?? CultureInfo.CurrentCulture; } public static string ToUpperFixed(this string str) @@ -139,7 +143,7 @@ namespace NewHorizons.Utility public static string ToTitleCase(this string str) { - StringBuilder strBuilder = new StringBuilder(str); + StringBuilder strBuilder = new StringBuilder(str.ToLowerInvariant()); strBuilder[0] = strBuilder[0].ToString().ToUpperInvariant().ToCharArray()[0]; return strBuilder.ToString(); } From 700baec85a1dbeacd883c445ec97b97269311e83 Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 29 Apr 2024 12:07:50 -0400 Subject: [PATCH 3/8] Implement the feature --- NewHorizons/Builder/Props/DialogueBuilder.cs | 50 ++++++++++++++++++++ NewHorizons/Utility/NewHorizonExtensions.cs | 2 +- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/NewHorizons/Builder/Props/DialogueBuilder.cs b/NewHorizons/Builder/Props/DialogueBuilder.cs index 429626e5..93898e6d 100644 --- a/NewHorizons/Builder/Props/DialogueBuilder.cs +++ b/NewHorizons/Builder/Props/DialogueBuilder.cs @@ -8,6 +8,7 @@ using OWML.Common; using System.Collections.Generic; using System.IO; using System.Xml; +using System.Xml.Linq; using UnityEngine; namespace NewHorizons.Builder.Props @@ -118,6 +119,8 @@ namespace NewHorizons.Builder.Props } } + DoDialogueOptionsListReplacement(existingDialogueTree); + var newTextAsset = new TextAsset(existingDialogueDoc.OuterXml) { name = existingDialogue._xmlCharacterDialogueAsset.name @@ -132,6 +135,51 @@ namespace NewHorizons.Builder.Props return existingDialogue; } + private static string DoDialogueOptionsListReplacement(string xmlString) + { + var dialogueDoc = new XmlDocument(); + dialogueDoc.LoadXml(xmlString); + var xmlNode = dialogueDoc.SelectSingleNode("DialogueTree"); + DoDialogueOptionsListReplacement(xmlNode); + return xmlNode.OuterXml; + } + + private static void DoDialogueOptionsListReplacement(XmlNode dialogueTree) + { + var optionsListsByName = new Dictionary(); + var dialogueNodes = dialogueTree.GetChildNodes("DialogueNode"); + foreach (XmlNode dialogueNode in dialogueNodes) + { + var optionsList = dialogueNode.GetChildNode("DialogueOptionsList"); + if (optionsList != null) + { + var name = dialogueNode.GetChildNode("Name").InnerText; + optionsListsByName[name] = optionsList; + } + } + foreach (var (name, optionsList) in optionsListsByName) + { + var replacement = optionsList.GetChildNode("ReuseDialogueOptionsListFrom"); + if (replacement != null) + { + if (optionsListsByName.TryGetValue(replacement.InnerText, out var replacementOptionsList)) + { + if (replacementOptionsList.GetChildNode("ReuseDialogueOptionsListFrom") != null) + { + NHLogger.LogError($"Can not target a node with ReuseDialogueOptionsListFrom that also reuses options when making dialogue. Node {name} cannot reuse the list from {replacement.InnerText}"); + } + var dialogueNode = optionsList.ParentNode; + dialogueNode.RemoveChild(optionsList); + dialogueNode.AppendChild(replacementOptionsList.Clone()); + } + else + { + NHLogger.LogError($"Could not reuse dialogue options list from node with Name {replacement.InnerText} to node with Name {name}"); + } + } + } + } + private static RemoteDialogueTrigger MakeRemoteDialogueTrigger(GameObject planetGO, Sector sector, DialogueInfo info, CharacterDialogueTree dialogue) { var conversationTrigger = GeneralPropBuilder.MakeNew("ConversationTrigger", planetGO, sector, info.remoteTrigger, defaultPosition: info.position, defaultParentPath: info.pathToAnimController); @@ -187,6 +235,8 @@ namespace NewHorizons.Builder.Props var dialogueTree = conversationZone.AddComponent(); + xml = DoDialogueOptionsListReplacement(xml); + var text = new TextAsset(xml) { // Text assets need a name to be used with VoiceMod diff --git a/NewHorizons/Utility/NewHorizonExtensions.cs b/NewHorizons/Utility/NewHorizonExtensions.cs index c34182e1..7a2ba5b0 100644 --- a/NewHorizons/Utility/NewHorizonExtensions.cs +++ b/NewHorizons/Utility/NewHorizonExtensions.cs @@ -348,7 +348,7 @@ namespace NewHorizons.Utility public static XmlNode GetChildNode(this XmlNode parentNode, string tagName) { - return parentNode.ChildNodes.Cast().First(node => node.LocalName == tagName); + return parentNode.ChildNodes.Cast().FirstOrDefault(node => node.LocalName == tagName); } public static string TruncateWhitespaceAndToLower(this string text) From a7bbbc1bd1f2c867cbd4aa3cc2c9b1b749082c45 Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 29 Apr 2024 12:46:27 -0400 Subject: [PATCH 4/8] Clean up some code to avoid making a billion XmlDocuments --- NewHorizons/Builder/Props/DetailBuilder.cs | 2 +- NewHorizons/Builder/Props/DialogueBuilder.cs | 42 ++++++++++++++------ 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/NewHorizons/Builder/Props/DetailBuilder.cs b/NewHorizons/Builder/Props/DetailBuilder.cs index 6a05cb09..65a37584 100644 --- a/NewHorizons/Builder/Props/DetailBuilder.cs +++ b/NewHorizons/Builder/Props/DetailBuilder.cs @@ -156,7 +156,7 @@ namespace NewHorizons.Builder.Props // If they're adding dialogue we have to manually register the xml text if (isFromAssetBundle && component is CharacterDialogueTree dialogue) { - DialogueBuilder.AddTranslation(dialogue._xmlCharacterDialogueAsset.text, null); + DialogueBuilder.HandleUnityCreatedDialogue(dialogue); } FixComponent(component, go, detail.ignoreSun); diff --git a/NewHorizons/Builder/Props/DialogueBuilder.cs b/NewHorizons/Builder/Props/DialogueBuilder.cs index 93898e6d..779b9a37 100644 --- a/NewHorizons/Builder/Props/DialogueBuilder.cs +++ b/NewHorizons/Builder/Props/DialogueBuilder.cs @@ -5,7 +5,9 @@ using NewHorizons.Utility; using NewHorizons.Utility.OuterWilds; using NewHorizons.Utility.OWML; using OWML.Common; +using System; using System.Collections.Generic; +using System.Data.SqlTypes; using System.IO; using System.Xml; using System.Xml.Linq; @@ -130,20 +132,11 @@ namespace NewHorizons.Builder.Props // Chracter name is required for adding translations, something to do with how OW prefixes its dialogue var characterName = existingDialogueTree.SelectSingleNode("NameField").InnerText; - AddTranslation(xml, characterName); + AddTranslation(additionalDialogueDoc.GetChildNode("DialogueTree"), characterName); return existingDialogue; } - private static string DoDialogueOptionsListReplacement(string xmlString) - { - var dialogueDoc = new XmlDocument(); - dialogueDoc.LoadXml(xmlString); - var xmlNode = dialogueDoc.SelectSingleNode("DialogueTree"); - DoDialogueOptionsListReplacement(xmlNode); - return xmlNode.OuterXml; - } - private static void DoDialogueOptionsListReplacement(XmlNode dialogueTree) { var optionsListsByName = new Dictionary(); @@ -235,7 +228,12 @@ namespace NewHorizons.Builder.Props var dialogueTree = conversationZone.AddComponent(); - xml = DoDialogueOptionsListReplacement(xml); + var dialogueDoc = new XmlDocument(); + dialogueDoc.LoadXml(xml); + var xmlNode = dialogueDoc.SelectSingleNode("DialogueTree"); + DoDialogueOptionsListReplacement(xmlNode); + AddTranslation(xmlNode); + xml = xmlNode.OuterXml; var text = new TextAsset(xml) { @@ -243,7 +241,6 @@ namespace NewHorizons.Builder.Props name = dialogueName }; dialogueTree.SetTextXml(text); - AddTranslation(xml); switch (info.flashlightToggle) { @@ -428,11 +425,17 @@ namespace NewHorizons.Builder.Props } } + [Obsolete("Pass in the DialogueTree XmlNode instead, this is still here because Pikpik was using it in EOTP")] public static void AddTranslation(string xml, string characterName = null) { var xmlDocument = new XmlDocument(); xmlDocument.LoadXml(xml); var xmlNode = xmlDocument.SelectSingleNode("DialogueTree"); + AddTranslation(xmlNode, characterName); + } + + public static void AddTranslation(XmlNode xmlNode, string characterName = null) + { var xmlNodeList = xmlNode.SelectNodes("DialogueNode"); // When adding dialogue to existing stuff, we have to pass in the character name @@ -467,5 +470,20 @@ namespace NewHorizons.Builder.Props } } } + + public static void HandleUnityCreatedDialogue(CharacterDialogueTree dialogue) + { + var text = dialogue._xmlCharacterDialogueAsset.text; + var dialogueDoc = new XmlDocument(); + dialogueDoc.LoadXml(text); + var xmlNode = dialogueDoc.SelectSingleNode("DialogueTree"); + AddTranslation(xmlNode, null); + DoDialogueOptionsListReplacement(xmlNode); + var newTextAsset = new TextAsset(dialogueDoc.OuterXml) + { + name = dialogue._xmlCharacterDialogueAsset.name + }; + dialogue.SetTextXml(newTextAsset); + } } } From 8a983f18ce98e3f24a1ed74412183b54146e9298 Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 29 Apr 2024 12:46:40 -0400 Subject: [PATCH 5/8] Fix an NRE I just got --- .../Components/Fixers/PlayerShipAtmosphereDetectorFix.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/NewHorizons/Components/Fixers/PlayerShipAtmosphereDetectorFix.cs b/NewHorizons/Components/Fixers/PlayerShipAtmosphereDetectorFix.cs index 25d135c1..1eb440d9 100644 --- a/NewHorizons/Components/Fixers/PlayerShipAtmosphereDetectorFix.cs +++ b/NewHorizons/Components/Fixers/PlayerShipAtmosphereDetectorFix.cs @@ -14,7 +14,11 @@ internal class PlayerShipAtmosphereDetectorFix : MonoBehaviour public void Start() { _fluidDetector = Locator.GetPlayerCameraDetector().GetComponent(); - _shipAtmosphereVolume = Locator.GetShipBody().transform.Find("Volumes/ShipAtmosphereVolume").GetComponent(); + _shipAtmosphereVolume = Locator.GetShipBody()?.transform?.Find("Volumes/ShipAtmosphereVolume")?.GetComponent(); + if (_shipAtmosphereVolume == null) + { + Destroy(this); + } } public void Update() From 71dafe9046a90341572c0c96d1a92d24c2fd9270 Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 29 Apr 2024 14:26:16 -0400 Subject: [PATCH 6/8] Fix translation issues when reusing dialogue options --- NewHorizons/Builder/Props/DialogueBuilder.cs | 29 ++++++++++++++++---- NewHorizons/Handlers/TranslationHandler.cs | 20 ++++++++++++++ 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/NewHorizons/Builder/Props/DialogueBuilder.cs b/NewHorizons/Builder/Props/DialogueBuilder.cs index 779b9a37..3066eea8 100644 --- a/NewHorizons/Builder/Props/DialogueBuilder.cs +++ b/NewHorizons/Builder/Props/DialogueBuilder.cs @@ -12,6 +12,7 @@ using System.IO; using System.Xml; using System.Xml.Linq; using UnityEngine; +using UnityEngine.XR; namespace NewHorizons.Builder.Props { @@ -121,6 +122,10 @@ namespace NewHorizons.Builder.Props } } + // Character name is required for adding translations, something to do with how OW prefixes its dialogue + var characterName = existingDialogueTree.SelectSingleNode("NameField").InnerText; + AddTranslation(additionalDialogueDoc.GetChildNode("DialogueTree"), characterName); + DoDialogueOptionsListReplacement(existingDialogueTree); var newTextAsset = new TextAsset(existingDialogueDoc.OuterXml) @@ -130,13 +135,13 @@ namespace NewHorizons.Builder.Props existingDialogue.SetTextXml(newTextAsset); - // Chracter name is required for adding translations, something to do with how OW prefixes its dialogue - var characterName = existingDialogueTree.SelectSingleNode("NameField").InnerText; - AddTranslation(additionalDialogueDoc.GetChildNode("DialogueTree"), characterName); - return existingDialogue; } + /// + /// Always call this after adding translations, else it won't update them properly + /// + /// private static void DoDialogueOptionsListReplacement(XmlNode dialogueTree) { var optionsListsByName = new Dictionary(); @@ -155,7 +160,8 @@ namespace NewHorizons.Builder.Props var replacement = optionsList.GetChildNode("ReuseDialogueOptionsListFrom"); if (replacement != null) { - if (optionsListsByName.TryGetValue(replacement.InnerText, out var replacementOptionsList)) + var replacementName = replacement.InnerText; + if (optionsListsByName.TryGetValue(replacementName, out var replacementOptionsList)) { if (replacementOptionsList.GetChildNode("ReuseDialogueOptionsListFrom") != null) { @@ -164,6 +170,17 @@ namespace NewHorizons.Builder.Props var dialogueNode = optionsList.ParentNode; dialogueNode.RemoveChild(optionsList); dialogueNode.AppendChild(replacementOptionsList.Clone()); + + // Have to manually fix the translations here + var characterName = dialogueTree.SelectSingleNode("NameField").InnerText; + + var xmlText = replacementOptionsList.SelectNodes("DialogueOption/Text"); + foreach (object option in xmlText) + { + var optionData = (XmlNode)option; + var text = optionData.InnerText.Trim(); + TranslationHandler.ReuseDialogueTranslation(text, new string[] { characterName, replacementName }, new string[] { characterName, name }); + } } else { @@ -231,8 +248,8 @@ namespace NewHorizons.Builder.Props var dialogueDoc = new XmlDocument(); dialogueDoc.LoadXml(xml); var xmlNode = dialogueDoc.SelectSingleNode("DialogueTree"); - DoDialogueOptionsListReplacement(xmlNode); AddTranslation(xmlNode); + DoDialogueOptionsListReplacement(xmlNode); xml = xmlNode.OuterXml; var text = new TextAsset(xml) diff --git a/NewHorizons/Handlers/TranslationHandler.cs b/NewHorizons/Handlers/TranslationHandler.cs index c2f49ebf..409266bc 100644 --- a/NewHorizons/Handlers/TranslationHandler.cs +++ b/NewHorizons/Handlers/TranslationHandler.cs @@ -173,6 +173,26 @@ namespace NewHorizons.Handlers TextTranslation.Get().m_table.theTable[key] = value; } + /// + /// Two dialogue nodes might share indentical text but they will have different prefixes. Still, we want to reuse that old text. + /// + /// + /// + /// + public static void ReuseDialogueTranslation(string rawText, string[] oldPrefixes, string[] newPrefixes) + { + var key = string.Join(string.Empty, newPrefixes) + rawText; + var existingKey = string.Join(string.Empty, oldPrefixes) + rawText; + if (TextTranslation.Get().m_table.theTable.TryGetValue(existingKey, out var existingTranslation)) + { + TextTranslation.Get().m_table.theTable[key] = existingTranslation; + } + else + { + NHLogger.LogWarning($"Couldn't find translation key {existingKey}"); + } + } + public static void AddShipLog(string rawText, params string[] rawPreText) { var key = string.Join(string.Empty, rawPreText) + rawText; From 037d3e02f570792496db39c0e8eec5c10f8fcbe9 Mon Sep 17 00:00:00 2001 From: Nick Date: Tue, 30 Apr 2024 00:49:36 -0400 Subject: [PATCH 7/8] Prisoner and maybe solanum dialogue are really weird and idk it NREs here but this fixes it --- NewHorizons/Builder/Props/DialogueBuilder.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/NewHorizons/Builder/Props/DialogueBuilder.cs b/NewHorizons/Builder/Props/DialogueBuilder.cs index 3066eea8..99e75d70 100644 --- a/NewHorizons/Builder/Props/DialogueBuilder.cs +++ b/NewHorizons/Builder/Props/DialogueBuilder.cs @@ -106,7 +106,11 @@ namespace NewHorizons.Builder.Props // We just have to merge the dialogue options var dialogueOptions = newDialogueNode.GetChildNode("DialogueOptionsList").GetChildNodes("DialogueOption"); var existingDialogueOptionsList = existingNode.GetChildNode("DialogueOptionsList"); - var firstNode = existingDialogueOptionsList.ChildNodes[0]; + if (existingDialogueOptionsList == null) + { + existingDialogueOptionsList = existingDialogueDoc.CreateElement("DialogueOptionsList"); + existingNode.AppendChild(existingDialogueOptionsList); + } foreach (XmlNode node in dialogueOptions) { var importedNode = existingDialogueOptionsList.OwnerDocument.ImportNode(node, true); From 5392a1f3b505f52c52e61e6cabfeffee6b34d201 Mon Sep 17 00:00:00 2001 From: Nick Date: Tue, 30 Apr 2024 18:00:07 -0400 Subject: [PATCH 8/8] Fix dialogue reuse thing not including dialogue added by other mods --- NewHorizons/Builder/Props/DialogueBuilder.cs | 32 +++++++++++++++++--- NewHorizons/manifest.json | 2 +- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/NewHorizons/Builder/Props/DialogueBuilder.cs b/NewHorizons/Builder/Props/DialogueBuilder.cs index 99e75d70..89d70da7 100644 --- a/NewHorizons/Builder/Props/DialogueBuilder.cs +++ b/NewHorizons/Builder/Props/DialogueBuilder.cs @@ -130,8 +130,6 @@ namespace NewHorizons.Builder.Props var characterName = existingDialogueTree.SelectSingleNode("NameField").InnerText; AddTranslation(additionalDialogueDoc.GetChildNode("DialogueTree"), characterName); - DoDialogueOptionsListReplacement(existingDialogueTree); - var newTextAsset = new TextAsset(existingDialogueDoc.OuterXml) { name = existingDialogue._xmlCharacterDialogueAsset.name @@ -139,9 +137,32 @@ namespace NewHorizons.Builder.Props existingDialogue.SetTextXml(newTextAsset); + FixDialogueNextFrame(existingDialogue); + return existingDialogue; } + private static void FixDialogueNextFrame(CharacterDialogueTree characterDialogueTree) + { + Delay.FireOnNextUpdate(() => + { + var rawText = characterDialogueTree._xmlCharacterDialogueAsset.text; + + var doc = new XmlDocument(); + doc.LoadXml(rawText); + var dialogueTree = doc.DocumentElement.SelectSingleNode("//DialogueTree"); + + DoDialogueOptionsListReplacement(dialogueTree); + + var newTextAsset = new TextAsset(doc.OuterXml) + { + name = characterDialogueTree._xmlCharacterDialogueAsset.name + }; + + characterDialogueTree.SetTextXml(newTextAsset); + }); + } + /// /// Always call this after adding translations, else it won't update them properly /// @@ -253,7 +274,7 @@ namespace NewHorizons.Builder.Props dialogueDoc.LoadXml(xml); var xmlNode = dialogueDoc.SelectSingleNode("DialogueTree"); AddTranslation(xmlNode); - DoDialogueOptionsListReplacement(xmlNode); + xml = xmlNode.OuterXml; var text = new TextAsset(xml) @@ -282,6 +303,8 @@ namespace NewHorizons.Builder.Props conversationZone.SetActive(true); + FixDialogueNextFrame(dialogueTree); + return dialogueTree; } @@ -499,12 +522,13 @@ namespace NewHorizons.Builder.Props dialogueDoc.LoadXml(text); var xmlNode = dialogueDoc.SelectSingleNode("DialogueTree"); AddTranslation(xmlNode, null); - DoDialogueOptionsListReplacement(xmlNode); var newTextAsset = new TextAsset(dialogueDoc.OuterXml) { name = dialogue._xmlCharacterDialogueAsset.name }; dialogue.SetTextXml(newTextAsset); + + FixDialogueNextFrame(dialogue); } } } diff --git a/NewHorizons/manifest.json b/NewHorizons/manifest.json index 74ce1e6e..c57ae22d 100644 --- a/NewHorizons/manifest.json +++ b/NewHorizons/manifest.json @@ -4,7 +4,7 @@ "author": "xen, Bwc9876, JohnCorby, MegaPiggy, Clay, Trifid, and friends", "name": "New Horizons", "uniqueName": "xen.NewHorizons", - "version": "1.20.1", + "version": "1.20.2", "owmlVersion": "2.10.3", "dependencies": [ "JohnCorby.VanillaFix", "xen.CommonCameraUtility", "dgarro.CustomShipLogModes" ], "conflicts": [ "PacificEngine.OW_CommonResources" ],