From d39d0482591c274e0786b434d505999fb61c11af Mon Sep 17 00:00:00 2001 From: SillyStar-Github <90102598+SillyStar-Github@users.noreply.github.com> Date: Sun, 29 Mar 2026 04:18:29 -0400 Subject: [PATCH] 3.5 code changes + live update level list --- .gitignore | 1 + MelonLoader/Core.cs | 13 +- MelonLoader/FileLoader.cs | 4 - MelonLoader/ModFeatures.cs | 11 + .../BaseTextObjects/InGameText_Patch.cs | 260 ++++++++++++++---- .../GameObjects/AlmanacZombieWindow_Patch.cs | 2 +- .../Patches/GameObjects/BaseMenu_Patch.cs | 5 + .../ButtonObjects/OptLanguageBtn_Patch.cs | 28 +- .../Patches/GameObjects/ConfirmMenu_Patch.cs | 24 ++ .../Patches/GameObjects/LoseMenu_Patch.cs | 26 ++ .../Patches/GameObjects/MainMenu_Patch.cs | 124 +++++++-- .../GameObjects/PlantDataMenu_Patch.cs | 1 - .../GameObjects/PlayerSaveMenu_Patch.cs | 36 +++ .../Patches/Managers/InGameUI_Patch.cs | 29 +- MelonLoader/Patches/Managers/UIMgr_Patch.cs | 19 +- .../Modes/Odyssey/TravelRefresh_Patch.cs | 4 +- .../Super Editor/CustomLevelMenu_Patch.cs | 162 +++++++++++ .../CustomMenuPage_initZombies_Patch.cs | 32 +++ .../CustomMenuPage_page3_Patch.cs | 34 +++ .../CustomMenuPage_shooting_Patch.cs | 65 +++++ .../Super Editor/CustomOnlineMenu_Patch.cs | 39 +++ ...PvZ Fusion Translator [MelonLoader].csproj | 10 +- MelonLoader/Utils.cs | 87 +++--- 23 files changed, 861 insertions(+), 155 deletions(-) create mode 100644 MelonLoader/Patches/GameObjects/ConfirmMenu_Patch.cs create mode 100644 MelonLoader/Patches/GameObjects/LoseMenu_Patch.cs create mode 100644 MelonLoader/Patches/GameObjects/PlayerSaveMenu_Patch.cs create mode 100644 MelonLoader/Patches/Modes/Super Editor/CustomLevelMenu_Patch.cs create mode 100644 MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_initZombies_Patch.cs create mode 100644 MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_page3_Patch.cs create mode 100644 MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_shooting_Patch.cs create mode 100644 MelonLoader/Patches/Modes/Super Editor/CustomOnlineMenu_Patch.cs diff --git a/.gitignore b/.gitignore index e067033..54dd915 100644 --- a/.gitignore +++ b/.gitignore @@ -252,3 +252,4 @@ MelonLoader/bin/Debug/net6.0/AsmResolver.PE.dll MelonLoader/bin/Debug/net6.0/AsmResolver.DotNet.dll MelonLoader/bin/Debug/net6.0/AsmResolver.dll MelonLoader/bin/Debug/net6.0/0Harmony.dll +/MelonLoader/bin diff --git a/MelonLoader/Core.cs b/MelonLoader/Core.cs index 05812ca..3b8f9ca 100644 --- a/MelonLoader/Core.cs +++ b/MelonLoader/Core.cs @@ -5,6 +5,7 @@ using MelonLoader.Utils; using PvZ_Fusion_Translator.AssetStore; using PvZ_Fusion_Translator.Patches.Managers; using PvZ_Fusion_Translator.Patches.Modes.Odyssey; +using PvZ_Fusion_Translator.Patches.Modes.Super_Editor; using System.Runtime.CompilerServices; using System.Text.Json; using UnityEngine; @@ -82,10 +83,16 @@ namespace PvZ_Fusion_Translator Utils.OpenTrello(); } - if(TowerManager.Instance != null) + TowerManager_Patch.UpdateText(); + + if (CustomLevelMenu_Patch.requestTimer > 0) { - TowerManager_Patch.UpdateText(); - } + CustomLevelMenu_Patch.requestTimer -= Time.deltaTime; + if(CustomLevelMenu_Patch.requestTimer < 0) + { + CustomLevelMenu_Patch.requestTimer = 0; + } + } } public override void OnGUI() diff --git a/MelonLoader/FileLoader.cs b/MelonLoader/FileLoader.cs index f4ca6b2..7abd116 100644 --- a/MelonLoader/FileLoader.cs +++ b/MelonLoader/FileLoader.cs @@ -116,10 +116,6 @@ namespace PvZ_Fusion_Translator } #if MULTI_LANGUAGE - if (Utils.Language != Utils.LanguageEnum.English) - { - LoadLocalizedTextures(Utils.LanguageEnum.English); - } LoadLocalizedTextures(Utils.Language); LoadLocalizedSprites(Utils.Language); #else diff --git a/MelonLoader/ModFeatures.cs b/MelonLoader/ModFeatures.cs index 0bc356e..413d252 100644 --- a/MelonLoader/ModFeatures.cs +++ b/MelonLoader/ModFeatures.cs @@ -1,5 +1,6 @@ //#if DEBUG using PvZ_Fusion_Translator.AssetStore; +using PvZ_Fusion_Translator.Patches.Modes.Super_Editor; using UnityEngine; namespace PvZ_Fusion_Translator @@ -10,6 +11,7 @@ namespace PvZ_Fusion_Translator { ReloadStrings, ReloadTextures, + SwapLevelData } private class ModFeature @@ -42,6 +44,14 @@ namespace PvZ_Fusion_Translator Core.ShowToast("Textures Reloaded!"); return; } + + if(this.ModType == ModType.SwapLevelData) + { + CustomLevelMenu_Patch.SwapLevelData(); + string toast = (CustomLevelMenu_Patch.useLocal) ? "Using Local Data..." : "Using Online Data..."; + Core.ShowToast(toast); + return; + } } } @@ -49,6 +59,7 @@ namespace PvZ_Fusion_Translator { {ModType.ReloadStrings,new ModFeature("Reload Strings",ModType.ReloadStrings,KeyCode.Home, true)}, {ModType.ReloadTextures,new ModFeature("Reload Textures",ModType.ReloadTextures,KeyCode.End, true)}, + {ModType.SwapLevelData,new ModFeature("Swap Level Data Type",ModType.SwapLevelData,KeyCode.PageUp, true)}, }; diff --git a/MelonLoader/Patches/BaseTextObjects/InGameText_Patch.cs b/MelonLoader/Patches/BaseTextObjects/InGameText_Patch.cs index 6fa5ac4..26b5636 100644 --- a/MelonLoader/Patches/BaseTextObjects/InGameText_Patch.cs +++ b/MelonLoader/Patches/BaseTextObjects/InGameText_Patch.cs @@ -14,68 +14,224 @@ namespace PvZ_Fusion_Translator.Patches.BaseTextObjects [HarmonyPatch(typeof(InGameText))] public static class InGameText_Patch { + public static string currentText = ""; + [HarmonyPatch(nameof(InGameText.ShowText))] [HarmonyPostfix] public static void ShowText(InGameText __instance) { + TranslateInGameText(__instance); + } + + [HarmonyPatch(nameof(InGameText.DebugWarning))] + [HarmonyPostfix] + public static void DebugWarning(InGameText __instance) + { + TranslateInGameText(__instance); + } + + [HarmonyPatch(nameof(InGameText.Update))] + [HarmonyPostfix] + public static void Update(InGameText __instance) + { + TranslateInGameText(__instance); + } + + public static void TranslateInGameText(InGameText __instance) + { + if (__instance.textMesh == null) return; + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) + currentText = __instance.textMesh.text; + + TextMeshProUGUI txt = __instance.textMesh; + string originalText = txt.text; + string travelMatch = TravelMgr_Patch.MatchTravelBuff(originalText); + int godsGachaCheck = CheckGodsGachaPopup(originalText); + string godsGachaMatch = ""; + string superEditorPlantMatch = CheckSuperEditorPopup(originalText); + + switch(godsGachaCheck) { - string originalText = txt.text; - string travelMatch = TravelMgr_Patch.MatchTravelBuff(originalText); - - if (txt.gameObject.name.Contains("shadow")) - { - continue; - } - - if (travelMatch != "") - { - txt.text = travelMatch; - if (txt.gameObject.name.Contains("main")) - { - originalText = txt.text; - Transform shadowText = txt.transform.parent.Find("Text_shadow"); - if (shadowText != null) - { - shadowText.GetComponent().text = Utils.RemoveColorTags(originalText); - } - } - } - else if((Regex.Match(txt.text, @"(]*>.*?)", RegexOptions.Singleline).Success) && !StringStore.translationString.ContainsKey(txt.text)) - { - txt.text = StringStore.TranslateColorText(txt.text, true); - if (txt.gameObject.name.Contains("main")) - { - originalText = txt.text; - Transform shadowText = txt.transform.parent.Find("Text_shadow"); - if (shadowText != null) - { - shadowText.GetComponent().text = Utils.RemoveColorTags(originalText); - } - } - } - else - { - txt.text = StringStore.TranslateText(txt.text, true); - if (txt.gameObject.name.Contains("main")) - { - originalText = txt.text; - Transform shadowText = txt.transform.parent.Find("Text_shadow"); - if (shadowText != null) - { - shadowText.GetComponent().text = Utils.RemoveColorTags(originalText); - } - } - } - txt.font = fontAsset; + case 1: + case 2: + case 3: + godsGachaMatch = TranslateGodsGachaPopup(originalText, godsGachaCheck); + break; + default: + break; } - if(__instance.TryGetComponent(out TextMeshProUGUI text)) + if(godsGachaMatch != "") { - text.text = StringStore.TranslateText(text.text); + txt.text = godsGachaMatch; + if (txt.gameObject.name.Contains("main")) + { + originalText = txt.text; + Transform shadowText = txt.transform.parent.Find("Text_shadow"); + if (shadowText != null) + { + shadowText.GetComponent().text = Utils.RemoveColorTags(originalText); + } + } } + else if (travelMatch != "") + { + txt.text = travelMatch; + if (txt.gameObject.name.Contains("main")) + { + originalText = txt.text; + Transform shadowText = txt.transform.parent.Find("Text_shadow"); + if (shadowText != null) + { + shadowText.GetComponent().text = Utils.RemoveColorTags(originalText); + } + } + } + else if(superEditorPlantMatch != "") + { + txt.text = superEditorPlantMatch; + } + else if((Regex.Match(txt.text, @"(]*>.*?)", RegexOptions.Singleline).Success) && !StringStore.translationString.ContainsKey(txt.text)) + { + txt.text = StringStore.TranslateColorText(txt.text, true); + if (txt.gameObject.name.Contains("main")) + { + originalText = txt.text; + Transform shadowText = txt.transform.parent.Find("Text_shadow"); + if (shadowText != null) + { + shadowText.GetComponent().text = Utils.RemoveColorTags(originalText); + } + } + } + else + { + txt.text = StringStore.TranslateText(txt.text, true); + if (txt.gameObject.name.Contains("main")) + { + originalText = txt.text; + Transform shadowText = txt.transform.parent.Find("Text_shadow"); + if (shadowText != null) + { + shadowText.GetComponent().text = Utils.RemoveColorTags(originalText); + } + } + } + txt.font = fontAsset; } - } + + public static string namePlantedPattern = "种植了:([^\\s]+)"; + public static string nameUpgradedPattern = "升级成功:([^\\s]+) -> ([^\\s]+)"; + public static string nameAlreadyPlantedPattern = "场上已经有一个([^\\s]+)了"; + + public static Dictionary fallbackFStrs = new Dictionary() + { + {"种植了:([^\\s]+)", "{0} planted!"}, + {"升级成功:([^\\s]+) -> ([^\\s]+)", "{0} successfully upgraded to {1}!"}, + {"场上已经有一个([^\\s]+)了", "{0} already exists on the lawn!"}, + {"已移除路线:([^\\s]+)", "Upgrade Path removed for {0}" }, + { @"([^\s]+)\((\d+)\)", "{0}({1})" } + }; + + public static int CheckGodsGachaPopup(string originalText) + { + int res = 0; + + if (Regex.IsMatch(originalText, namePlantedPattern)) + { + res = 1; + } + else if(Regex.IsMatch(originalText, nameUpgradedPattern)) + { + res = 2; + } + else if(Regex.IsMatch(originalText, nameAlreadyPlantedPattern)) + { + res = 3; + } + + return res; + } + + public static string TranslateGodsGachaPopup(string originalText, int type) + { + string res = originalText; + + switch(type) + { + case 1: + res = TranslatePlantNameParts(originalText, namePlantedPattern); + break; + case 2: + res = TranslatePlantNameParts(originalText, nameUpgradedPattern); + break; + case 3: + res = TranslatePlantNameParts(originalText, nameAlreadyPlantedPattern); + break; + default: + break; + } + + return res; + } + + public static string TranslatePlantNameParts(string originalText, string pattern) + { + string res = ""; + string fStr = ""; + Match match = Regex.Match(originalText, pattern); + if(match.Success) + { + GroupCollection groups = match.Groups; + fStr = StringStore.translationStringRegex.ContainsKey(pattern) ? StringStore.translationStringRegex[pattern] : fallbackFStrs[pattern]; + List dynamicParts = []; + for(int i = 1; i < groups.Count; i++) + { + string group = groups[i].Value; + string plantName = Utils.GetPlantNameFromAlmanac(group); + dynamicParts.Add(plantName); + } + res = string.Format(fStr, [.. dynamicParts]); + } + return res; + } + + public static string CheckSuperEditorPopup(string originalText) + { + string res = ""; + + if(Regex.IsMatch(originalText, "已移除路线:([^\\s]+)")) + { + res = TranslatePlantNameParts(originalText, "已移除路线:([^\\s]+)"); + } + else if(Regex.IsMatch(originalText, "当前全部基础植物:(.*)")) + { + string pattern = "当前全部基础植物:(.*)"; + Match match = Regex.Match(originalText, pattern); + if(match.Success) + { + GroupCollection groups = match.Groups; + string plantNameGroup = groups[1].Value; + string[] plantNames = plantNameGroup.Split(" "); + string plantRes = ""; + string shortPattern = @"([^\s]+)\((\d+)\)"; + foreach (string plantName in plantNames) + { + Match shortMatch = Regex.Match(plantName, shortPattern); + if(shortMatch.Success) + { + string fStr = StringStore.translationStringRegex.ContainsKey(shortPattern) ? StringStore.translationStringRegex[shortPattern] : fallbackFStrs[shortPattern]; + string shortRes = string.Format(fStr, [Utils.GetPlantNameFromAlmanac(shortMatch.Groups[1].Value), shortMatch.Groups[2].Value]); + plantRes += shortRes + " "; + } + } + res = StringStore.TranslateText("当前全部基础植物:" + plantRes); + } + } + + return res; + } + } } \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/AlmanacZombieWindow_Patch.cs b/MelonLoader/Patches/GameObjects/AlmanacZombieWindow_Patch.cs index 3f8179e..64ea817 100644 --- a/MelonLoader/Patches/GameObjects/AlmanacZombieWindow_Patch.cs +++ b/MelonLoader/Patches/GameObjects/AlmanacZombieWindow_Patch.cs @@ -53,7 +53,7 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects ZombieDataManager.ZombieData zombieData = zombieDataDic[__instance.currentZombieType]; string spawnInfo = ""; - string spawnInfoFormat = StringStore.translationStringRegex["出怪等级: (\\d+)\n出怪权重: (\\d+)"]; + string spawnInfoFormat = StringStore.translationStringRegex.ContainsKey("出怪等级: (\\d+)\n出怪权重: (\\d+)") ? StringStore.translationStringRegex["出怪等级: (\\d+)\n出怪权重: (\\d+)"] : null; if(spawnInfoFormat != null) { spawnInfo = string.Format(spawnInfoFormat, [zombieData.summonLevel, zombieData.summonWeight]) + "\n\n"; diff --git a/MelonLoader/Patches/GameObjects/BaseMenu_Patch.cs b/MelonLoader/Patches/GameObjects/BaseMenu_Patch.cs index a8dee09..b38c940 100644 --- a/MelonLoader/Patches/GameObjects/BaseMenu_Patch.cs +++ b/MelonLoader/Patches/GameObjects/BaseMenu_Patch.cs @@ -29,6 +29,11 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects NoticePauseMenu_Patch.Post_Awake(__instance); } + if(__instance.name.StartsWith("MainMenu(Clone)")) + { + MainMenu_Patch.AnimOver(__instance); + } + TranslateBaseMenu(__instance, "Level"); TranslateBaseMenu(__instance, "Levels"); TranslateBaseMenu(__instance, "CustomLevel"); diff --git a/MelonLoader/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs b/MelonLoader/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs index 5fffd82..ab8dcd7 100644 --- a/MelonLoader/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs +++ b/MelonLoader/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs @@ -7,6 +7,7 @@ using PvZ_Fusion_Translator; using PvZ_Fusion_Translator.AssetStore; using UnityEngine; using UnityEngine.UIElements; +using static MelonLoader.MelonLogger; using Object = UnityEngine.Object; public class OptionButtonData @@ -58,6 +59,11 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects for (int i = 0; i < 6; i++) { var newButton = Object.Instantiate(templateButton, templateButton.transform.parent); + newButton.tag = "LangOpt"; + foreach(Transform child in newButton.GetComponentsInChildren()) + { + child.tag = "LangOpt"; + } newButton.optionType = 80 + i; float yPos = startY - i * ySpacing; @@ -90,6 +96,11 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects for (int i = 0; i < 2; i++) { var newButton = Object.Instantiate(templateButton, templateButton.transform.parent); + newButton.tag = "LangOpt"; + foreach(Transform child in newButton.GetComponentsInChildren()) + { + child.tag = "LangOpt"; + } newButton.optionType = 100 + i; float yPos = toggleStartY - i * ySpacing; @@ -125,7 +136,8 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects data.Language = lang; data.IsNextButton = false; btn.gameObject.SetActive(true); - UpdateButtonText(btn, lang.ToString()); + + UpdateButtonText(btn, Utils.LanguageNames[lang], FontStore.LoadTMPFont(lang.ToString())); } else { @@ -148,7 +160,7 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects data.Toggle = toggle; data.IsNextButton = false; btn.gameObject.SetActive(true); - UpdateButtonText(btn, toggle.ToString()); + UpdateButtonText(btn, StringStore.TranslateText(toggle.ToString()), FontStore.LoadTMPFont(Utils.Language.ToString())); } else { @@ -168,7 +180,7 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects UpdateButtonText(nextBtn, "Next"); } - public static void UpdateButtonText(OptionBtn button, string languageName) + public static void UpdateButtonText(OptionBtn button, string languageName, TMP_FontAsset fontAsset = null) { TMP_FontAsset defaultAsset = FontStore.LoadTMPFont("English"); @@ -192,7 +204,7 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects text.text = languageName; } text.fontSize = 16; - text.font = defaultAsset; + text.font = (fontAsset != null) ? fontAsset : defaultAsset; text.autoSizeTextContainer = false; } } @@ -257,17 +269,15 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects [HarmonyPatch(typeof(OptionBtn))] public static class OptLangBtn_Patch { - [HarmonyPatch(nameof(OptionBtn.Awake))] - [HarmonyPostfix] - private static void Awake(OptionBtn __instance) + public static void Awake(OptionBtn __instance) { if (!buttonsCreated || cachedTemplateButton == null) { buttonsCreated = false; togglesCreated = false; - CreateLanguageButtons(__instance); + CreateLanguageButtons(__instance); CreateToggleButtons(__instance); - } + } } [HarmonyPatch("OnMouseUpAsButton")] diff --git a/MelonLoader/Patches/GameObjects/ConfirmMenu_Patch.cs b/MelonLoader/Patches/GameObjects/ConfirmMenu_Patch.cs new file mode 100644 index 0000000..6dc92b7 --- /dev/null +++ b/MelonLoader/Patches/GameObjects/ConfirmMenu_Patch.cs @@ -0,0 +1,24 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; +using System.Text.RegularExpressions; + +namespace PvZ_Fusion_Translator.Patches.GameObjects +{ + [HarmonyPatch(typeof(ConfirmMenu))] + public static class ConfirmMenu_Patch + { + [HarmonyPatch(nameof(ConfirmMenu.SetTitle))] + [HarmonyPostfix] + private static void SetTitle(ConfirmMenu __instance) + { + foreach(TextMeshProUGUI title in __instance.title) + { + title.text = StringStore.TranslateText(title.text); + title.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + } + } +} diff --git a/MelonLoader/Patches/GameObjects/LoseMenu_Patch.cs b/MelonLoader/Patches/GameObjects/LoseMenu_Patch.cs new file mode 100644 index 0000000..2ba8b25 --- /dev/null +++ b/MelonLoader/Patches/GameObjects/LoseMenu_Patch.cs @@ -0,0 +1,26 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using MelonLoader; +using PvZ_Fusion_Translator.AssetStore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.GameObjects +{ + [HarmonyPatch(typeof(LoseMenu))] + public static class LoseMenu_Patch + { + public static void TranslateLoseMenu(BaseMenu __instance) + { + if(__instance.TryGetComponent(out LoseMenu loseMenu)) + { + loseMenu.title.text = StringStore.TranslateText(loseMenu.title.text); + } + } + } +} diff --git a/MelonLoader/Patches/GameObjects/MainMenu_Patch.cs b/MelonLoader/Patches/GameObjects/MainMenu_Patch.cs index 5093466..ee63097 100644 --- a/MelonLoader/Patches/GameObjects/MainMenu_Patch.cs +++ b/MelonLoader/Patches/GameObjects/MainMenu_Patch.cs @@ -1,24 +1,106 @@ -//using HarmonyLib; -//using Il2Cpp; -//using PvZ_Fusion_Translator.AssetStore; -//using UnityEngine; +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; +using PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects; +using Unity.VisualScripting; +using UnityEngine; +using UnityEngine.Events; +using UnityEngine.Rendering; +using UnityEngine.UIElements; -//namespace PvZ_Fusion_Translator.Patches.GameObjects -//{ -// [HarmonyPatch(typeof(MainMenu))] -// public class MainMenu_Patch -// { -// private static bool _warningShown = false; +namespace PvZ_Fusion_Translator.Patches.GameObjects +{ + public class MainMenu_Patch + { + public static void AnimOver(BaseMenu __instance) + { + Transform changelogObj = __instance.transform.Find("Grave/UpdateInfo"); + Transform langObj = UnityEngine.Object.Instantiate(changelogObj, changelogObj.position + new Vector3(0.0f, 0.855f), changelogObj.rotation, __instance.transform.Find("Grave")); + langObj.name = "Languages"; + UIButton langBtn = langObj.GetComponent(); -// [HarmonyPostfix] -// [HarmonyPatch(nameof(MainMenu.AnimOver))] -// private static void AnimOver(MainMenu __instance) -// { -// if (_warningShown || NoticeMenu.Instance == null) -// return; + foreach(TextMeshProUGUI text in langObj.GetComponentsInChildren()) + { + text.text = StringStore.TranslateText("Languages"); + } -// WarningStore.WarningReload(Utils.Language, NoticeMenu.Instance); -// _warningShown = true; -// } -// } -//} \ No newline at end of file + langBtn.clickEvent = new UnityEvent(); + langBtn.clickEvent.AddListener(new Action(() => OpenLanguageMenu(langBtn.gameObject))); + langBtn.clickEvent.AddListener(new Action(() => HideLangButton(langBtn.gameObject))); + } + + public static void OpenLanguageMenu(GameObject langBtn) + { + UIMgr.EnterOptionMenu(); + GameObject newOptionsMenu = GameAPP.canvasUp.Find("OptionMenu(Clone)").gameObject; + newOptionsMenu.name = "LanguageMenu"; + + List toKeep = new List() { "Background", "F", "Goback"}; + foreach(Transform child in newOptionsMenu.GetComponentsInChildren()) + { + if(!toKeep.Contains(child.name) && !toKeep.Contains(child.parent.name) && child.name != "LanguageMenu") + { + child.gameObject.SetActive(false); + } + } + + OptionBtn templateButton = newOptionsMenu.transform.Find("F").GetComponent(); + OptLanguageBtn_Patch.OptLangBtn_Patch.Awake(templateButton); + + UIButton goBackButton = newOptionsMenu.transform.Find("Goback").GetComponent(); + goBackButton.clickEvent.AddListener(new Action(() => ShowLangButton(langBtn.gameObject))); + + newOptionsMenu.transform.Find("F").gameObject.SetActive(false); + + foreach (TextMeshProUGUI text in newOptionsMenu.transform.Find("Background").GetComponentsInChildren()) + { + text.text = StringStore.TranslateText("Language Settings"); + } + + /*GameObject optionMenuAnchor = UnityEngine.Object.Instantiate(assetBundle.LoadAsset("OptionMenu").TryCast(), GameAPP.canvasUp); + optionMenuAnchor.transform.SetParent(newOptionsMenu.transform, false); + Transform messageAnchor = optionMenuAnchor.transform.Find("MessageAnchor"); + Transform plantAnchor = optionMenuAnchor.transform.Find("PlantAnchor"); + + System.Random random = new System.Random(); + var plantTypes = Enum.GetValues(typeof(PlantType)); + PlantType randomPlantChoice = (PlantType)plantTypes.GetValue(random.Next(plantTypes.Length)); + + if(!GameAPP.resourcesManager.plantPrefabs.ContainsKey(randomPlantChoice) || GameAPP.resourcesManager.plantPrefabs[randomPlantChoice] == null) + { + randomPlantChoice = (PlantType)plantTypes.GetValue(random.Next(plantTypes.Length)); + } + + if (GameAPP.resourcesManager.plantPrefabs[randomPlantChoice] != null) + { + GameObject plant = CreatePlant.SetPlantInAlmamac(plantAnchor.position, (int)randomPlantChoice); + plant.transform.SetParent(newOptionsMenu.transform); + SortingGroup sortingGroup = plant.AddComponent(); + sortingGroup.sortingLayerName = "UI"; + sortingGroup.sortingOrder = 20001; + //plant.transform.position = new Vector3(-7.21f, -3.66f); + UnityEngine.Object.Destroy(plant.GetComponent()); + }*/ + + /*GameObject messageObj = new GameObject(); + messageObj.name = "MultilangMessage"; + messageObj.transform.SetParent(newOptionsMenu.transform); + TextMeshProUGUI messageText = messageObj.AddComponent(); + messageObj.transform.localScale = Vector3.one; + messageText.autoSizeTextContainer = false; + messageText.font = FontStore.LoadTMPFont(Utils.LanguageEnum.English.ToString()); + messageText.text = "Hello this is multilanguage choose language over there ------>";*/ + } + + public static void HideLangButton(GameObject btn) + { + btn.GetComponent().enabled = false; + } + + public static void ShowLangButton(GameObject btn) + { + btn.GetComponent().enabled = true; + } + } +} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/PlantDataMenu_Patch.cs b/MelonLoader/Patches/GameObjects/PlantDataMenu_Patch.cs index 66a5a39..0dafc50 100644 --- a/MelonLoader/Patches/GameObjects/PlantDataMenu_Patch.cs +++ b/MelonLoader/Patches/GameObjects/PlantDataMenu_Patch.cs @@ -52,7 +52,6 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects { startColorTag = match.Groups[1].Value; toTranslate = match.Groups[2].Value; - Log.LogDebug(toTranslate); } string[] parts = toTranslate.Split("\n"); diff --git a/MelonLoader/Patches/GameObjects/PlayerSaveMenu_Patch.cs b/MelonLoader/Patches/GameObjects/PlayerSaveMenu_Patch.cs new file mode 100644 index 0000000..f8e702d --- /dev/null +++ b/MelonLoader/Patches/GameObjects/PlayerSaveMenu_Patch.cs @@ -0,0 +1,36 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; +using System.Text.RegularExpressions; + +namespace PvZ_Fusion_Translator.Patches.GameObjects +{ + [HarmonyPatch(typeof(PlayerSaveMenu))] + public static class PlayerSaveMenu_Patch + { + [HarmonyPatch(nameof(PlayerSaveMenu.CreatePlayerData))] + [HarmonyPostfix] + public static void CreatePlayerData(PlayerSaveMenu __instance) + { + TranslateCreatePlayerSaveMenu(); + } + + [HarmonyPatch(nameof(PlayerSaveMenu.ResetName))] + [HarmonyPostfix] + public static void ResetName(PlayerSaveMenu __instance) + { + TranslateCreatePlayerSaveMenu(); + } + + public static void TranslateCreatePlayerSaveMenu() + { + Transform createPlayerSaveMenuTransform = GameAPP.canvasUp.Find("CreatePlayerSaveMenu(Clone)"); + if(createPlayerSaveMenuTransform.TryGetComponent(out CreatePlayerSaveMenu createPlayerSaveMenu)) + { + createPlayerSaveMenu.title.text = StringStore.TranslateText(createPlayerSaveMenu.title.text); + } + } + } +} diff --git a/MelonLoader/Patches/Managers/InGameUI_Patch.cs b/MelonLoader/Patches/Managers/InGameUI_Patch.cs index c5fd833..cd07a31 100644 --- a/MelonLoader/Patches/Managers/InGameUI_Patch.cs +++ b/MelonLoader/Patches/Managers/InGameUI_Patch.cs @@ -15,37 +15,30 @@ namespace PvZ_Fusion_Translator.Patches.Managers [HarmonyPostfix] private static void Start(InGameUI __instance) { - TextMeshProUGUI[] array = new TextMeshProUGUI[] + foreach(TextMeshProUGUI text in __instance.GetComponentsInChildren()) { - __instance.transform.GetChild(4).GetComponent(), - __instance.transform.GetChild(4).GetChild(0).GetComponent(), - __instance.transform.GetChild(5).GetComponent(), - __instance.transform.GetChild(5).GetChild(0).GetComponent(), - __instance.transform.GetChild(6).GetComponent(), - __instance.transform.GetChild(6).GetChild(0).GetComponent()}; - TextMeshProUGUI[] array2 = array; - for (int i = 0; i < array2.Length; i++) - { - string originalText = array2[i].text; - array2[i].text = array2[i].text.Replace("\n", " "); + if (text.text == null) continue; + + string originalText = text.text; + text.text = text.text.Replace("\n", " "); Regex checkFusionChallenge = new Regex("^超级([^\\s:]+)(:?挑战1?)"); - if (array2[i].text.Contains("配方:") && !checkFusionChallenge.IsMatch(array2[i].text)) + if (text.text.Contains("配方:") && !checkFusionChallenge.IsMatch(text.text)) { - string[] lines = array2[i].text.Split(":"); + string[] lines = text.text.Split(":"); lines[1] = Utils.GetPlantNameFromAlmanac(lines[1]); if (lines[1] == "") { Log.LogError("Couldn't find plant! (Fusion Showcase)"); lines[1] = StringStore.TranslateText(lines[1]); } - array2[i].text = StringStore.TranslateText("配方:") + lines[1]; - array2[i].autoSizeTextContainer = true; + text.text = StringStore.TranslateText("配方:") + lines[1]; + text.autoSizeTextContainer = true; } else { - array2[i].text = (StringStore.translationString.ContainsKey(array2[i].text + "_MG")) ? StringStore.TranslateText(array2[i].text + "_MG") : StringStore.TranslateText(array2[i].text); - array2[i].text = array2[i].text.Replace("\n", " "); + text.text = (StringStore.translationString.ContainsKey(text.text + "_MG")) ? StringStore.TranslateText(text.text + "_MG") : StringStore.TranslateText(text.text); + text.text = text.text.Replace("\n", " "); } } } diff --git a/MelonLoader/Patches/Managers/UIMgr_Patch.cs b/MelonLoader/Patches/Managers/UIMgr_Patch.cs index 3b49429..e3e1bad 100644 --- a/MelonLoader/Patches/Managers/UIMgr_Patch.cs +++ b/MelonLoader/Patches/Managers/UIMgr_Patch.cs @@ -1,22 +1,19 @@ using HarmonyLib; using Il2Cpp; using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; namespace PvZ_Fusion_Translator.Patches.Managers { [HarmonyPatch(typeof(UIMgr))] public class UIMgr_Patch { - //[HarmonyPatch(nameof(UIMgr.EnterMainMenu))] - //[HarmonyPostfix] - //private static void EnterMainMenu(UIMgr __instance) - //{ - // // Log.LogInfo("Entered Main Menu"); - // #if MULTI_LANGUAGE - // WarningStore.WarningReload(Utils.Language); - // #else - // WarningStore.WarningReload(); - // #endif - //} + [HarmonyPatch(nameof(UIMgr.EnterLoseMenu))] + [HarmonyPostfix] + private static void EnterLoseMenu(UIMgr __instance) + { + LoseMenu loseMenu = GameObject.FindObjectOfType(); + loseMenu.title.text = StringStore.TranslateText(loseMenu.title.text); + } } } \ No newline at end of file diff --git a/MelonLoader/Patches/Modes/Odyssey/TravelRefresh_Patch.cs b/MelonLoader/Patches/Modes/Odyssey/TravelRefresh_Patch.cs index 56f73e4..5d58593 100644 --- a/MelonLoader/Patches/Modes/Odyssey/TravelRefresh_Patch.cs +++ b/MelonLoader/Patches/Modes/Odyssey/TravelRefresh_Patch.cs @@ -9,9 +9,9 @@ namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey [HarmonyPatch(typeof(TravelRefresh))] public static class TravelRefresh_Patch { - [HarmonyPatch(nameof(TravelRefresh.Start))] + [HarmonyPatch(nameof(TravelRefresh.Awake))] [HarmonyPostfix] - private static void Start(TravelRefresh __instance) + private static void Awake(TravelRefresh __instance) { __instance.text = StringStore.TranslateText(__instance.text); __instance.text_shadow = StringStore.TranslateText(__instance.text_shadow); diff --git a/MelonLoader/Patches/Modes/Super Editor/CustomLevelMenu_Patch.cs b/MelonLoader/Patches/Modes/Super Editor/CustomLevelMenu_Patch.cs new file mode 100644 index 0000000..a0822cb --- /dev/null +++ b/MelonLoader/Patches/Modes/Super Editor/CustomLevelMenu_Patch.cs @@ -0,0 +1,162 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using MelonLoader; +using Newtonsoft.Json; +using PvZ_Fusion_Translator.AssetStore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Encodings.Web; +using System.Text.Json; +using System.Threading.Tasks; +using System.Threading.Tasks; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor +{ + [HarmonyPatch(typeof(CustomLevelMenu))] + public static class CustomLevelMenu_Patch + { + public static Dictionary translatedLevelData = new Dictionary(); + public static float requestTimer = 0f; + public static bool useLocal = false; + + [HarmonyPatch(nameof(CustomLevelMenu.LoadOnlineFiles))] + [HarmonyPostfix] + public static void LoadOnlineFiles(CustomLevelMenu __instance) + { + translatedLevelData = new Dictionary(); + + if (!useLocal) + { + LoadOnlineData(); + } + else + { + LoadLocalData(); + } + } + + [HarmonyPatch(nameof(CustomLevelMenu.InitWindows))] + [HarmonyPostfix] + public static void InitWindows(CustomLevelMenu __instance) + { + TranslateLevelButtons(__instance); + } + + [HarmonyPatch(nameof(CustomLevelMenu.ReloadFiles))] + [HarmonyPostfix] + public static void ReloadFiles(CustomLevelMenu __instance) + { + TranslateLevelButtons(__instance); + } + + public static void TranslateLevelButtons(CustomLevelMenu __instance) + { + Dictionary dumpData = new Dictionary(); + + foreach(CustomButton_enterGame level in __instance.levels) + { + string levelId = level.levelData.levelId; + if(levelId != null) + { + if(translatedLevelData.ContainsKey(levelId)) + { + TranslatedLevelData levelData = translatedLevelData[levelId]; + level.levelName.text = levelData.name; + level.levelData.Name = levelData.name; + level.serializedLevel.boardConfig.startTip = levelData.startTip; + } + else + { + TranslatedLevelData dumpedLevelData = new TranslatedLevelData(level.levelData.Name, level.serializedLevel.boardConfig.startTip); + dumpData.Add(levelId, dumpedLevelData); + } + } + else + { + level.levelName.text = StringStore.TranslateText(level.levelData.Name); + } + } + + string dumpPath = Path.Combine(FileLoader.GetAssetDir(FileLoader.AssetType.Dumps), "custom_level_data.json"); + File.WriteAllText(dumpPath, System.Text.Json.JsonSerializer.Serialize(dumpData, new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping + })); + } + + public static async System.Threading.Tasks.Task> GetTranslatedLevelData() + { + var levelDataRequest = await new HttpClient().GetAsync($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Strings/custom_level_data.json"); + if(levelDataRequest.StatusCode == System.Net.HttpStatusCode.OK) + { + string levelDataString = await levelDataRequest.Content.ReadAsStringAsync(); + Dictionary levelDataJson = JsonConvert.DeserializeObject>(levelDataString); + return levelDataJson; + } + else + { + new CancellationTokenSource().Cancel(); + return null; + } + } + + public static void LoadOnlineData() + { + if (requestTimer <= 0) + { + requestTimer = 5f; // 5 seconds in between request attempts to prevent any issues with github + + var translatedLevelDataRequest = System.Threading.Tasks.Task.Run(() => GetTranslatedLevelData()); + + if (translatedLevelDataRequest.Result != null) + { + translatedLevelData = translatedLevelDataRequest.Result; + Log.LogInfo($"Successfully loaded level data for {Utils.Language.ToString()}!"); + } + else + { + Log.LogError($"Couldn't find level data for {Utils.Language.ToString()}!"); + } + } + else + { + Log.LogInfo($"Please wait before requesting levels again! Current cooldown: {Math.Round(requestTimer, 3)}s"); + } + } + + public static void LoadLocalData() + { + string assetDir = Path.Combine(FileLoader.GetAssetDir(FileLoader.AssetType.Strings, Utils.Language), "custom_level_data.json"); + if (!File.Exists(assetDir)) + { + File.CreateText(assetDir); + File.WriteAllText(assetDir, "{}"); + } + string levelDataString = File.ReadAllText(assetDir); + Dictionary levelDataJson = JsonConvert.DeserializeObject>(levelDataString); + translatedLevelData = levelDataJson; + } + + public static void SwapLevelData() + { + useLocal = !useLocal; + } + } + + public class TranslatedLevelData + { + public string name { get; set; } + public string startTip { get; set; } + + public TranslatedLevelData(string name, string startTip) + { + this.name = name; + this.startTip = startTip; + } + } +} diff --git a/MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_initZombies_Patch.cs b/MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_initZombies_Patch.cs new file mode 100644 index 0000000..cc0df54 --- /dev/null +++ b/MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_initZombies_Patch.cs @@ -0,0 +1,32 @@ +using MelonLoader; +using HarmonyLib; +using UnityEngine; +using Il2Cpp; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor +{ + [HarmonyPatch(typeof(CustomMenuPage_initZombies))] + public static class CustomMenuPage_initZombies_Patch + { + [HarmonyPatch(nameof(CustomMenuPage_initZombies.SubWave))] + [HarmonyPostfix] + public static void SubWave(CustomMenuPage_initZombies __instance) + { + __instance.currentWaveText.text = StringStore.TranslateText(__instance.currentWaveText.text); + } + + [HarmonyPatch(nameof(CustomMenuPage_initZombies.AddWave))] + [HarmonyPostfix] + public static void AddWave(CustomMenuPage_initZombies __instance) + { + __instance.currentWaveText.text = StringStore.TranslateText(__instance.currentWaveText.text); + } + } +} diff --git a/MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_page3_Patch.cs b/MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_page3_Patch.cs new file mode 100644 index 0000000..7b0d4dd --- /dev/null +++ b/MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_page3_Patch.cs @@ -0,0 +1,34 @@ +using MelonLoader; +using HarmonyLib; +using UnityEngine; +using Il2Cpp; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor +{ + [HarmonyPatch(typeof(CustomMenu_page3))] + public static class CustomMenuPage_page3_Patch + { + [HarmonyPatch(nameof(CustomMenu_page3.UpdateCardsText))] + [HarmonyPostfix] + public static void UpdateCardsText(CustomMenu_page3 __instance) + { + string plantName = Utils.GetPlantNameFromAlmanac(__instance.nameText.text); + __instance.nameText.text = (plantName != "") ? (plantName) : StringStore.TranslateText(__instance.nameText.text); + } + + [HarmonyPatch(nameof(CustomMenu_page3.UpdateAdvancedInfo))] + [HarmonyPostfix] + public static void UpdateAdvancedInfo(CustomMenu_page3 __instance) + { + string plantName = Utils.GetPlantNameFromAlmanac(__instance.nameText.text); + __instance.nameText.text = (plantName != "") ? (plantName) : StringStore.TranslateText(__instance.nameText.text); + } + } +} diff --git a/MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_shooting_Patch.cs b/MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_shooting_Patch.cs new file mode 100644 index 0000000..a019938 --- /dev/null +++ b/MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_shooting_Patch.cs @@ -0,0 +1,65 @@ +using MelonLoader; +using HarmonyLib; +using UnityEngine; +using Il2Cpp; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor +{ + [HarmonyPatch(typeof(CustomMenuPage_shooting))] + public static class CustomMenuPage_shooting_Patch + { + [HarmonyPatch(nameof(CustomMenuPage_shooting.CreateRoute))] + [HarmonyPostfix] + public static void CreateRoute(CustomMenuPage_shooting __instance) + { + TranslateRoutes(__instance); + } + + [HarmonyPatch(nameof(CustomMenuPage_shooting.CreateStage))] + [HarmonyPostfix] + public static void CreateStage(CustomMenuPage_shooting __instance) + { + TranslateRoutes(__instance); + } + + [HarmonyPatch(nameof(CustomMenuPage_shooting.Awake))] + [HarmonyPostfix] + public static void Awake(CustomMenuPage_shooting __instance) + { + TranslateRoutes(__instance); + } + + [HarmonyPatch(nameof(CustomMenuPage_shooting.SearchRoute))] + [HarmonyPostfix] + public static void SearchRoute(CustomMenuPage_shooting __instance) + { + TranslateRoutes(__instance); + } + + [HarmonyPatch(nameof(CustomMenuPage_shooting.SearchAllRoute))] + [HarmonyPostfix] + public static void SearchAllRoute(CustomMenuPage_shooting __instance) + { + TranslateRoutes(__instance); + } + + public static void TranslateRoutes(CustomMenuPage_shooting __instance) + { + foreach(TextMeshProUGUI text in __instance.scollContent.GetComponentsInChildren()) + { + if (text.name == "PlantText") + { + string plantName = Utils.GetPlantNameFromAlmanac(text.text); + text.text = (plantName != "") ? plantName : StringStore.TranslateText(text.text); + } + } + } + } +} diff --git a/MelonLoader/Patches/Modes/Super Editor/CustomOnlineMenu_Patch.cs b/MelonLoader/Patches/Modes/Super Editor/CustomOnlineMenu_Patch.cs new file mode 100644 index 0000000..c01fd95 --- /dev/null +++ b/MelonLoader/Patches/Modes/Super Editor/CustomOnlineMenu_Patch.cs @@ -0,0 +1,39 @@ +using MelonLoader; +using HarmonyLib; +using UnityEngine; +using Il2Cpp; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor +{ + [HarmonyPatch(typeof(CustomOnlineMenu))] + public static class CustomOnlineMenu_Patch + { + [HarmonyPatch(nameof(CustomOnlineMenu.EditLevel))] + [HarmonyPostfix] + public static void EditLevel(CustomOnlineMenu __instance) + { + TranslateLevelName(__instance); + } + + [HarmonyPatch(nameof(CustomOnlineMenu.Start))] + [HarmonyPostfix] + public static void Start(CustomOnlineMenu __instance) + { + TranslateLevelName(__instance); + } + + public static void TranslateLevelName(CustomOnlineMenu __instance) + { + string translatedText = StringStore.TranslateText(__instance.title.text); + __instance.title.text = translatedText; + __instance.title2.text = translatedText; + } + } +} diff --git a/MelonLoader/PvZ Fusion Translator [MelonLoader].csproj b/MelonLoader/PvZ Fusion Translator [MelonLoader].csproj index 740ef7e..1374c50 100644 --- a/MelonLoader/PvZ Fusion Translator [MelonLoader].csproj +++ b/MelonLoader/PvZ Fusion Translator [MelonLoader].csproj @@ -13,7 +13,7 @@ latest enable Debug;DebugEnglish;ReleaseMulti;ReleaseEnglish;DebugTesting;ReleaseOther;DebugObfuscate;ReleaseObfuscate - C:\Users\rainb\Desktop\PC_PVZ-Fusion_3.4.2 + C:\Users\rainb\Desktop\PC_PVZ-Fusion_3.5 AnyCPU;ARM64;x64 @@ -400,6 +400,9 @@ + + + @@ -502,6 +505,11 @@ + + + + + diff --git a/MelonLoader/Utils.cs b/MelonLoader/Utils.cs index 9899cf0..db81a67 100644 --- a/MelonLoader/Utils.cs +++ b/MelonLoader/Utils.cs @@ -167,7 +167,7 @@ namespace PvZ_Fusion_Translator return thePlantName; } - public static string GetPlantNameFromAlmanac(string theOriginalPlantName) + public static string GetPlantNameFromAlmanac(string theOriginalPlantName, bool log = false) { string originalJson; string translatedJson; @@ -181,8 +181,11 @@ namespace PvZ_Fusion_Translator if ((!File.Exists(path)) || (!File.Exists(originalPath))) { - Log.LogError($"LawnStringsTranslate.json file not found at path: {path}"); - Log.LogError("Plant name could not be found!"); + if(log) + { + Log.LogError($"LawnStringsTranslate.json file not found at path: {path}"); + Log.LogError("Plant name could not be found!"); + } thePlantName = ""; } else @@ -208,7 +211,10 @@ namespace PvZ_Fusion_Translator if (!foundPlantName) { - Log.LogInfo("Couldn't find plant name!"); + if(log) + { + Log.LogInfo("Couldn't find plant name!"); + } thePlantName = ""; } } @@ -300,7 +306,7 @@ namespace PvZ_Fusion_Translator } } - public static Dictionary> recipeLinks = new Dictionary>(); + /*public static Dictionary> recipeLinks = new Dictionary>(); public static void RegisterRecipeLinks() { @@ -316,32 +322,32 @@ namespace PvZ_Fusion_Translator recipeLinks.Add(seedType, new()); - if(seedType > 0) + if (seedType > 0) { - foreach (PlantType checkType in Enum.GetValues(typeof(PlantType))) - { - if(checkType > 0) + foreach (PlantType checkType in Enum.GetValues(typeof(PlantType))) + { + if (checkType > 0) { - int[] checks = [mixData.GetValue(seedType, (int)checkType).Unbox(), mixData.GetValue((int)checkType, seedType).Unbox()]; + int[] checks = [mixData.GetValue(seedType, (int)checkType).Unbox(), mixData.GetValue((int)checkType, seedType).Unbox()]; - if (checks[0] != 0) - { - recipeLinks[seedType].Add(checks[0]); - } + if (checks[0] != 0) + { + recipeLinks[seedType].Add(checks[0]); + } - if (checks[1] != 0) - { - recipeLinks[seedType].Add(checks[1]); - } - } - } - } + if (checks[1] != 0) + { + recipeLinks[seedType].Add(checks[1]); + } + } + } + } if (recipeLinks[seedType].Count > 0) { Log.LogDebug($"Found {recipeLinks[seedType].Count} fusions for {seedType}!"); } - } - } + } + }*/ public static bool CheckForUntranslatedText(string text) { @@ -396,31 +402,48 @@ namespace PvZ_Fusion_Translator { // first column English, + Chinese_cn, French, - Italian, - German, + //Italian, + //German, Spanish, - Portuguese, + // second column - Javanese, //Filipino, + //Portuguese, + //Javanese, + //Filipino, Vietnamese, - Indonesian, - Russian, //NOTE: legacy language + //Indonesian, + //Russian, //NOTE: legacy language Japanese, - Korean, + // third column - Ukrainian, + Korean, + Ukrainian, // Slovak, //Polish, - Turkish, + //Turkish, //Arabic, Romanian, LANG_END } + public static Dictionary LanguageNames = new Dictionary() + { + { LanguageEnum.English, "English"}, + { LanguageEnum.Chinese_cn, "简体中文"}, + { LanguageEnum.French, "Français"}, + { LanguageEnum.Spanish, "Español"}, + { LanguageEnum.Vietnamese, "Tiếng Việt"}, + { LanguageEnum.Japanese, "日本語"}, + { LanguageEnum.Korean, "한국어"}, + { LanguageEnum.Ukrainian, "українська"}, + { LanguageEnum.Romanian, "Română"} + }; + public enum ToggleEnum { Textures,