diff --git a/.gitignore b/.gitignore index 8c7d99d..c2e129d 100644 --- a/.gitignore +++ b/.gitignore @@ -133,3 +133,4 @@ MelonLoader/bin/x64/Debug/net6.0/WebSocketDotNet.dll /BepInEx/bin/Debug/net6.0 .HOWTO-sync-MelonLoader-from-origin-main.txt /MelonLoader/bin/ReleaseMulti/net6.0 +BepInEx/Patches/GameObjects/changes.txt diff --git a/BepInEx/Core.cs b/BepInEx/Core.cs index 6446187..4c488b8 100644 --- a/BepInEx/Core.cs +++ b/BepInEx/Core.cs @@ -54,7 +54,9 @@ public class Core : BasePlugin StringStore.Init(); FontStore.Init(); Utils.RegisterPlantIndices(); - //PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects.Zombie_Patch.LoadHPStrings(); + + //Utils.RegisterRecipeLinks(); + //PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects.Zombie_Patch.LoadHPStrings(); InitCoroutine(); } diff --git a/BepInEx/Patches/BaseTextObjects/TMP_InputField_Patch.cs b/BepInEx/Patches/BaseTextObjects/TMP_InputField_Patch.cs index 8928a4c..c8046b6 100644 --- a/BepInEx/Patches/BaseTextObjects/TMP_InputField_Patch.cs +++ b/BepInEx/Patches/BaseTextObjects/TMP_InputField_Patch.cs @@ -2,6 +2,7 @@ using HarmonyLib; using System; using TMPro; using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using UnityEngine; namespace PvZ_Fusion_Translator__BepInEx_.Patches.BaseTextObjects { diff --git a/BepInEx/Patches/GameObjects/AlmanacPlantMenu_Patch.cs b/BepInEx/Patches/GameObjects/AlmanacPlantMenu_Patch.cs new file mode 100644 index 0000000..3dbb2e6 --- /dev/null +++ b/BepInEx/Patches/GameObjects/AlmanacPlantMenu_Patch.cs @@ -0,0 +1,88 @@ +using HarmonyLib; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using TMPro; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using UnityEngine; +using UnityEngine.UI; +using static PvZ_Fusion_Translator__BepInEx_.FileLoader; +using static PvZ_Fusion_Translator__BepInEx_.Utils; +using static PvZ_Fusion_Translator__BepInEx_.Log; +using static AlmanacPlantBank; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(AlmanacPlantMenu))] + public static class AlmanacPlantMenu_Patch + { + [HarmonyPatch(nameof(AlmanacPlantMenu.Awake))] + [HarmonyPostfix] + private static void Awake(AlmanacPlantMenu __instance) + { + TMP_FontAsset font = FontStore.LoadTMPFont(Utils.Language.ToString()); + foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren(true)) + { + bool isPlantName = text.gameObject.name.Contains("Name") && text.transform.parent.name != "Background"; + if (text.gameObject.name != "Description" && !isPlantName) + { + text.text = StringStore.TranslateText(text.text); + text.font = font; + text.autoSizeTextContainer = true; + } + } + + // skin button resize + + AlmanacPlantWindow window = __instance.window; + GameObject skinButton = window.skinButton; + GameObject skinTextObj = skinButton.transform.GetChild(0).gameObject; + GameObject skinShadowTextObj = skinTextObj.transform.GetChild(0).gameObject; + TextMeshProUGUI skinShadowText = skinShadowTextObj.GetComponent(); + skinShadowText.text = StringStore.TranslateText("换肤_S"); + skinButton.transform.localScale /= 1.75f; + skinButton.transform.localPosition = new Vector3(0.0f, 111.345f, 0.0f); + skinButton.transform.GetChild(1).Translate(new Vector3(-0.35f, 0)); + skinButton.transform.GetChild(2).Translate(new Vector3(0.35f, 0)); + } + + [HarmonyPatch(nameof(AlmanacPlantMenu.SearchChanged))] + [HarmonyPrefix] + public static bool SearchChanged(AlmanacPlantMenu __instance, ref TMP_InputField inputField) + { + string search = inputField.text; + if (search != StringStore.TranslateText("搜索") && search != "") + { + string currentLanguage = Utils.Language.ToString(); + string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); + string path = Path.Combine(almanacDir, "LawnStringsTranslate.json"); + string moddedPath = Path.Combine(almanacDir, "ModdedPlantsTranslate.json"); + + string json; + json = File.ReadAllText(path); + + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); + + PlantData plantData = JsonUtility.FromJson(json); + + Il2CppSystem.Collections.Generic.List searchedPlants = new(); + + foreach (PlantInfo plantInfo in plantData.plants) + { + if (plantInfo.name.ToLower().Contains(search.ToLower())) + { + searchedPlants.Add((PlantType)plantInfo.seedType); + } + } + + __instance.ShowPlants(searchedPlants); + + return false; + } + + return true; + } + } +} + diff --git a/BepInEx/Patches/GameObjects/AlmanacPlantWindow_Patch.cs b/BepInEx/Patches/GameObjects/AlmanacPlantWindow_Patch.cs new file mode 100644 index 0000000..347fdc0 --- /dev/null +++ b/BepInEx/Patches/GameObjects/AlmanacPlantWindow_Patch.cs @@ -0,0 +1,187 @@ +using HarmonyLib; +using TMPro; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using System; +using UnityEngine; +using UnityEngine.UI; +using System.IO; +using static PvZ_Fusion_Translator__BepInEx_.FileLoader; +using static PvZ_Fusion_Translator__BepInEx_.Log; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(AlmanacPlantWindow))] + public static class AlmanacPlantWindow_Patch + { + [HarmonyPatch(nameof(AlmanacPlantWindow.UpdateText))] + [HarmonyPostfix] + private static void UpdateText(AlmanacPlantWindow __instance) + { + try + { + if (__instance == null) + { + Log.LogWarning("[AlmanacPlantWindow_Patch] __instance is null"); + return; + } + + if (__instance.showedPlantName == null || __instance.showedPlantIntroduce == null || __instance.plantTextContent == null) + { + Log.LogWarning("[AlmanacPlantWindow_Patch] Required UI components are null"); + return; + } + + string currentLanguage = Utils.Language.ToString(); + string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); + string path = Path.Combine(almanacDir, "LawnStringsTranslate.json"); + string moddedPath = Path.Combine(almanacDir, "ModdedPlantsTranslate.json"); + + if (!File.Exists(path)) + { + Log.LogWarning($"[AlmanacPlantWindow_Patch] LawnStringsTranslate.json not found at: {path}"); + return; + } + + string json; + json = File.ReadAllText(path); + + bool hasAlmanacFont = false; + TMP_FontAsset almanacFontAsset = null; + if (FontStore.fontAssetDictSecondary != null && + (FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage + "_Almanac") || + FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage))) + almanacFontAsset = FontStore.LoadTMPFontAlmanac(currentLanguage); + hasAlmanacFont = almanacFontAsset != null; + + TMP_FontAsset fontAsset = null; + fontAsset = (hasAlmanacFont) ? FontStore.LoadTMPFontAlmanac(Utils.Language.ToString()) : FontStore.LoadTMPFont(Utils.Language.ToString()); + + AlmanacPlantBank.PlantData plantData = null; + + plantData = JsonUtility.FromJson(json); + + + bool foundMatch = false; + foreach (AlmanacPlantBank.PlantInfo plantInfo in plantData.plants) + { + if (plantInfo == null) continue; + if (plantInfo.seedType == (int)__instance.currentPlantType) + { + foundMatch = true; + try + { + if (__instance.showedPlantName != null) + { + foreach (TextMeshProUGUI text in __instance.showedPlantName) + { + if (text == null) continue; + text.autoSizeTextContainer = false; + string plantName = plantInfo.name ?? ""; + text.text = $"{Utils.RemoveSizeTags(plantName)} ({plantInfo.seedType})"; + text.font = fontAsset; + text.fontSizeMax = 21; + } + } + + if (__instance.showedPlantIntroduce != null) + { + string info = plantInfo.info ?? ""; + string introduce = plantInfo.introduce ?? ""; + __instance.showedPlantIntroduce.text = Utils.RemoveSizeTags(info) + "\n\n" + Utils.RemoveSizeTags(introduce) + "\n\n"; + __instance.showedPlantIntroduce.font = fontAsset; + __instance.showedPlantIntroduce.margin = new Vector4(6, 2, 12, 0); + __instance.showedPlantIntroduce.enableWordWrapping = true; + __instance.showedPlantIntroduce.overflowMode = TextOverflowModes.ScrollRect; + + Canvas.ForceUpdateCanvases(); + __instance.showedPlantIntroduce.ForceMeshUpdate(); + + if (__instance.plantTextContent != null) + { + float textHeight = __instance.showedPlantIntroduce.preferredHeight; + __instance.plantTextContent.sizeDelta = new Vector2(__instance.plantTextContent.sizeDelta.x, textHeight); + } + } + } + catch (Exception ex) + { + Log.LogError($"[AlmanacPlantWindow_Patch] Error updating plant info: {ex.Message}"); + } + break; + } + } + + if (!foundMatch && File.Exists(moddedPath)) + { + try + { + string moddedJson = File.ReadAllText(moddedPath); + if (!string.IsNullOrEmpty(moddedJson)) + { + AlmanacPlantBank.PlantData moddedPlantData = JsonUtility.FromJson(moddedJson); + if (moddedPlantData != null && moddedPlantData.plants != null) + { + foreach (AlmanacPlantBank.PlantInfo plantInfo in moddedPlantData.plants) + { + if (plantInfo == null) continue; + if (plantInfo.seedType == (int)__instance.currentPlantType) + { + try + { + if (__instance.showedPlantName != null) + { + foreach (TextMeshProUGUI text in __instance.showedPlantName) + { + if (text == null) continue; + text.autoSizeTextContainer = false; + string plantName = plantInfo.name ?? ""; + text.text = $"{Utils.RemoveSizeTags(plantName)} ({plantInfo.seedType})"; + text.font = fontAsset; + text.fontSizeMax = 21; + } + } + + if (__instance.showedPlantIntroduce != null) + { + string info = plantInfo.info ?? ""; + string introduce = plantInfo.introduce ?? ""; + __instance.showedPlantIntroduce.text = Utils.RemoveSizeTags(info) + "\n\n" + Utils.RemoveSizeTags(introduce) + "\n\n"; + __instance.showedPlantIntroduce.font = fontAsset; + __instance.showedPlantIntroduce.margin = new Vector4(6, 2, 12, 0); + __instance.showedPlantIntroduce.enableWordWrapping = true; + __instance.showedPlantIntroduce.overflowMode = TextOverflowModes.ScrollRect; + + Canvas.ForceUpdateCanvases(); + __instance.showedPlantIntroduce.ForceMeshUpdate(); + + if (__instance.plantTextContent != null) + { + float textHeight = __instance.showedPlantIntroduce.preferredHeight; + __instance.plantTextContent.sizeDelta = new Vector2(__instance.plantTextContent.sizeDelta.x, textHeight); + } + } + } + catch (Exception ex) + { + Log.LogError($"[AlmanacPlantWindow_Patch] Error updating modded plant info: {ex.Message}"); + } + break; + } + } + } + } + } + catch (Exception ex) + { + Log.LogWarning($"[AlmanacPlantWindow_Patch] Error reading ModdedPlantsTranslate.json: {ex.Message}"); + } + } + } + catch (Exception ex) + { + Log.LogError($"[AlmanacPlantWindow_Patch] Unexpected error in UpdateText: {ex.Message}\n{ex.StackTrace}"); + } + } + } +} + diff --git a/BepInEx/Patches/GameObjects/AlmanacZombieMenu_Patch.cs b/BepInEx/Patches/GameObjects/AlmanacZombieMenu_Patch.cs new file mode 100644 index 0000000..e85aef2 --- /dev/null +++ b/BepInEx/Patches/GameObjects/AlmanacZombieMenu_Patch.cs @@ -0,0 +1,31 @@ +using HarmonyLib; +using System; +using TMPro; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using UnityEngine; +using static PvZ_Fusion_Translator__BepInEx_.Log; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(AlmanacZombieMenu))] + public static class AlmanacZombieMenu_Patch + { + [HarmonyPatch(nameof(AlmanacZombieMenu.Awake))] + [HarmonyPostfix] + private static void Awake(AlmanacZombieMenu __instance) + { + TMP_FontAsset font = FontStore.LoadTMPFont(Utils.Language.ToString()); + foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren(true)) + { + bool isZombieName = text.gameObject.name.Contains("Name") && text.transform.parent.name != "Background"; + if (text.gameObject.name != "Description" && !isZombieName) + { + text.text = StringStore.TranslateText(text.text); + text.font = font; + text.autoSizeTextContainer = true; + } + } + } + } +} + diff --git a/BepInEx/Patches/GameObjects/AlmanacZombieWindow_Patch.cs b/BepInEx/Patches/GameObjects/AlmanacZombieWindow_Patch.cs new file mode 100644 index 0000000..8e16f2e --- /dev/null +++ b/BepInEx/Patches/GameObjects/AlmanacZombieWindow_Patch.cs @@ -0,0 +1,176 @@ +using HarmonyLib; +using TMPro; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using System; +using UnityEngine; +using UnityEngine.UI; +using System.IO; +using static PvZ_Fusion_Translator__BepInEx_.FileLoader; +using static PvZ_Fusion_Translator__BepInEx_.Log; +using PvZ_Fusion_Translator__BepInEx_.Patches.Managers; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(AlmanacZombieWindow))] + public static class AlmanacZombieWindow_Patch + { + [HarmonyPatch(nameof(AlmanacZombieWindow.UpdateText))] + [HarmonyPostfix] + private static void UpdateText(AlmanacZombieWindow __instance) + { + try + { + string currentLanguage = Utils.Language.ToString(); + string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); + string path = Path.Combine(almanacDir, "ZombieStringsTranslate.json"); + string moddedPath = Path.Combine(almanacDir, "ModdedZombiesTranslate.json"); + + if (!File.Exists(path)) + { + Log.LogWarning($"[AlmanacZombieWindow_Patch] ZombieStringsTranslate.json not found at: {path}"); + return; + } + + string json; + json = File.ReadAllText(path); + + bool hasAlmanacFont = false; + TMP_FontAsset almanacFontAsset = null; + if (FontStore.fontAssetDictSecondary != null && + (FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage + "_Almanac") || + FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage))) + { + almanacFontAsset = FontStore.LoadTMPFontAlmanac(currentLanguage); + hasAlmanacFont = almanacFontAsset != null; + } + + TMP_FontAsset fontAsset = null; + fontAsset = (hasAlmanacFont) ? FontStore.LoadTMPFontAlmanac(Utils.Language.ToString()) : FontStore.LoadTMPFont(Utils.Language.ToString()); + + ZombieAlmanacData zombieData = null; + zombieData = JsonUtility.FromJson(json); + + bool foundMatch = false; + foreach (ZombieInfo zombieInfo in zombieData.zombies) + { + if (zombieInfo == null) continue; + if (zombieInfo.theZombieType == __instance.currentZombieType) + { + foundMatch = true; + try + { + if (__instance.showedZombieName != null) + { + foreach (TextMeshProUGUI text in __instance.showedZombieName) + { + if (text == null) continue; + text.autoSizeTextContainer = false; + string zombieName = zombieInfo.name ?? ""; + text.text = $"{Utils.RemoveSizeTags(zombieName)} ({(int)zombieInfo.theZombieType})"; + text.font = fontAsset; + text.fontSizeMax = 21; + } + } + + if (__instance.showedZombieIntroduce != null) + { + string info = zombieInfo.info ?? ""; + string introduce = zombieInfo.introduce ?? ""; + __instance.showedZombieIntroduce.text = Utils.RemoveSizeTags(info) + "\n\n" + Utils.RemoveSizeTags(introduce) + "\n\n"; + __instance.showedZombieIntroduce.font = fontAsset; + __instance.showedZombieIntroduce.margin = new Vector4(3, 2, 12, 0); + __instance.showedZombieIntroduce.enableWordWrapping = true; + __instance.showedZombieIntroduce.overflowMode = TextOverflowModes.ScrollRect; + + Canvas.ForceUpdateCanvases(); + __instance.showedZombieIntroduce.ForceMeshUpdate(); + + if (__instance.zombieTextContent != null) + { + float textHeight = __instance.showedZombieIntroduce.preferredHeight; + __instance.zombieTextContent.sizeDelta = new Vector2(__instance.zombieTextContent.sizeDelta.x, textHeight); + } + } + } + catch (Exception ex) + { + Log.LogError($"[AlmanacZombieWindow_Patch] Error updating zombie info: {ex.Message}"); + } + break; + } + } + + if (!foundMatch && File.Exists(moddedPath)) + { + try + { + string moddedJson = File.ReadAllText(moddedPath); + if (!string.IsNullOrEmpty(moddedJson)) + { + ZombieAlmanacData moddedZombieData = JsonUtility.FromJson(moddedJson); + if (moddedZombieData != null && moddedZombieData.zombies != null) + { + foreach (ZombieInfo zombieInfo in moddedZombieData.zombies) + { + if (zombieInfo == null) continue; + if (zombieInfo.theZombieType == __instance.currentZombieType) + { + try + { + if (__instance.showedZombieName != null) + { + foreach (TextMeshProUGUI text in __instance.showedZombieName) + { + if (text == null) continue; + text.autoSizeTextContainer = false; + string zombieName = zombieInfo.name ?? ""; + text.text = $"{Utils.RemoveSizeTags(zombieName)} ({(int)zombieInfo.theZombieType})"; + text.font = fontAsset; + text.fontSizeMax = 21; + } + } + + if (__instance.showedZombieIntroduce != null) + { + string info = zombieInfo.info ?? ""; + string introduce = zombieInfo.introduce ?? ""; + __instance.showedZombieIntroduce.text = Utils.RemoveSizeTags(info) + "\n\n" + Utils.RemoveSizeTags(introduce) + "\n\n"; + __instance.showedZombieIntroduce.font = fontAsset; + __instance.showedZombieIntroduce.margin = new Vector4(3, 2, 12, 0); + __instance.showedZombieIntroduce.enableWordWrapping = true; + __instance.showedZombieIntroduce.overflowMode = TextOverflowModes.ScrollRect; + + Canvas.ForceUpdateCanvases(); + __instance.showedZombieIntroduce.ForceMeshUpdate(); + + if (__instance.zombieTextContent != null) + { + float textHeight = __instance.showedZombieIntroduce.preferredHeight; + __instance.zombieTextContent.sizeDelta = new Vector2(__instance.zombieTextContent.sizeDelta.x, textHeight); + } + } + } + catch (Exception ex) + { + Log.LogError($"[AlmanacZombieWindow_Patch] Error updating modded zombie info: {ex.Message}"); + } + break; + } + } + } + } + } + catch (Exception ex) + { + Log.LogWarning($"[AlmanacZombieWindow_Patch] Error reading ModdedZombiesTranslate.json: {ex.Message}"); + } + } + } + catch (Exception ex) + { + Log.LogError($"[AlmanacZombieWindow_Patch] Unexpected error in UpdateText: {ex.Message}\n{ex.StackTrace}"); + } + } + } +} + diff --git a/BepInEx/Patches/GameObjects/Almanac_Patch.cs b/BepInEx/Patches/GameObjects/Almanac_Patch.cs new file mode 100644 index 0000000..5ae5678 --- /dev/null +++ b/BepInEx/Patches/GameObjects/Almanac_Patch.cs @@ -0,0 +1,49 @@ +using HarmonyLib; +using TMPro; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(Almanac))] + public static class Almanac_Patch + { + [HarmonyPatch(nameof(Almanac.Awake))] + [HarmonyPostfix] + private static void Awake(Almanac __instance) + { + TranslateAlmanacMenu(__instance); + } + + [HarmonyPatch(nameof(Almanac.OldAlmanac))] + [HarmonyPostfix] + private static void OldAlmanac(Almanac __instance) + { + TranslateAlmanacMenu(__instance); + } + + [HarmonyPatch(nameof(Almanac.AnimSwitch))] + [HarmonyPostfix] + private static void AnimSwitch(Almanac __instance) + { + TranslateAlmanacMenu(__instance); + } + + public static void TranslateAlmanacMenu(Almanac __instance) + { + TMP_FontAsset font = FontStore.LoadTMPFont(Utils.Language.ToString()); + foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) + { + if (text.text == "关闭") + { + text.text = StringStore.TranslateText("合上"); + } + else + { + text.text = StringStore.TranslateText(text.text); + } + text.font = font; + } + } + } +} + diff --git a/BepInEx/Patches/GameObjects/BaseMenu_Patch.cs b/BepInEx/Patches/GameObjects/BaseMenu_Patch.cs index a5b96c8..7d7bd47 100644 --- a/BepInEx/Patches/GameObjects/BaseMenu_Patch.cs +++ b/BepInEx/Patches/GameObjects/BaseMenu_Patch.cs @@ -1,5 +1,6 @@ using HarmonyLib; -using System; +using System.Collections.Generic; +using System.Linq; using TMPro; using PvZ_Fusion_Translator__BepInEx_.AssetStore; using UnityEngine; @@ -13,122 +14,27 @@ namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects [HarmonyPostfix] private static void Awake(BaseMenu __instance) { - Transform mainTransform = __instance.transform; - if (mainTransform != null) + TranslateBaseMenu(__instance, "Level"); + TranslateBaseMenu(__instance, "Levels"); + TranslateBaseMenu(__instance, "CustomLevel"); + } + + public static void TranslateBaseMenu(BaseMenu __instance, string levelsName) + { + Transform levels = __instance.transform.Find(levelsName); + if (levels != null) { - StringStore.TranslateTextTransform(mainTransform.Find("Goback")); - StringStore.TranslateTextTransform(mainTransform.Find("Switich")); - - Transform levelTransform = mainTransform.Find("Level"); - if (levelTransform != null) + List children = levels.GetComponentsInChildren(true).ToList(); + foreach (Transform child in children) { - StringStore.TranslateTextTransform(levelTransform.Find("Nextpage")); - StringStore.TranslateTextTransform(levelTransform.Find("LastPage")); + if (child.name == "Nextpage" || child.name == "LastPage" || child.name == "BackToIndex") + { + StringStore.TranslateTextTransform(child); + } } - Transform customLevelTransform = mainTransform.Find("CustomLevel"); - if (customLevelTransform != null) - { - StringStore.TranslateTextTransform(customLevelTransform.Find("Nextpage")); - StringStore.TranslateTextTransform(customLevelTransform.Find("LastPage")); - } - - Transform levelsTransform = mainTransform.Find("Levels"); - if (levelsTransform != null) - { - - StringStore.TranslateTextTransform(levelsTransform.Find("Nextpage")); - StringStore.TranslateTextTransform(levelsTransform.Find("LastPage")); - - Transform pageMiniGamesTransform = levelsTransform.transform.Find("PageMiniGames"); - if (pageMiniGamesTransform != null) - { - StringStore.TranslateTextTransform(pageMiniGamesTransform.Find("BackToIndex")); - StringStore.TranslateTextTransform(pageMiniGamesTransform.Find("Nextpage")); - StringStore.TranslateTextTransform(pageMiniGamesTransform.Find("LastPage")); - } - - Transform pageUnlockChallengeTransform = levelsTransform.transform.Find("PageUnlockChallenge"); - if (pageUnlockChallengeTransform != null) - { - StringStore.TranslateTextTransform(pageUnlockChallengeTransform.Find("BackToIndex")); - } - - Transform pageFlagChallengeTransform = levelsTransform.transform.Find("PageFlagChallenge"); - if (pageFlagChallengeTransform != null) - { - StringStore.TranslateTextTransform(pageFlagChallengeTransform.Find("BackToIndex")); - } - - Transform pageTravelExperienceTransform = levelsTransform.transform.Find("PageTravelExperience"); - if (pageTravelExperienceTransform != null) - { - StringStore.TranslateTextTransform(pageTravelExperienceTransform.Find("BackToIndex")); - } - - Transform pageGardenProtectionTransform = levelsTransform.transform.Find("PageGardenProtection"); - if (pageGardenProtectionTransform != null) - { - StringStore.TranslateTextTransform(pageGardenProtectionTransform.Find("BackToIndex")); - } - - Transform pageNormalTravelTransform = levelsTransform.transform.Find("PageNormalTravel"); - if (pageNormalTravelTransform != null) - { - StringStore.TranslateTextTransform(pageNormalTravelTransform.Find("BackToIndex")); - } - - Transform pageRandomLevelTransform = levelsTransform.transform.Find("PageRandomLevel"); - if (pageRandomLevelTransform != null) - { - StringStore.TranslateTextTransform(pageRandomLevelTransform.Find("BackToIndex")); - } - - Transform pageUltimateExperienceTransform = levelsTransform.transform.Find("PageUltimateExprience"); - if (pageUltimateExperienceTransform != null) - { - StringStore.TranslateTextTransform(pageUltimateExperienceTransform.Find("BackToIndex")); - } - - Transform pageAdvantureLevelTransform = levelsTransform.transform.Find("PageAdvantureLevel"); - if (pageAdvantureLevelTransform != null) - { - StringStore.TranslateTextTransform(pageAdvantureLevelTransform.Find("BackToIndex")); - StringStore.TranslateTextTransform(pageAdvantureLevelTransform.Find("Nextpage")); - StringStore.TranslateTextTransform(pageAdvantureLevelTransform.Find("LastPage")); - } - - Transform pageScaryPotTransform = levelsTransform.transform.Find("PageScaryPot"); - if (pageScaryPotTransform != null) - { - StringStore.TranslateTextTransform(pageScaryPotTransform.Find("BackToIndex")); - StringStore.TranslateTextTransform(pageScaryPotTransform.Find("Nextpage")); - StringStore.TranslateTextTransform(pageScaryPotTransform.Find("LastPage")); - } - - Transform pageEndlessLevelTransform = levelsTransform.transform.Find("PageEndlessLevel"); - if (pageEndlessLevelTransform != null) - { - StringStore.TranslateTextTransform(pageEndlessLevelTransform.Find("BackToIndex")); - StringStore.TranslateTextTransform(pageEndlessLevelTransform.Find("Nextpage")); - StringStore.TranslateTextTransform(pageEndlessLevelTransform.Find("LastPage")); - } - - Transform pageNewAdvantureLevelTransform = levelsTransform.transform.Find("PageNewAdvantureLevel"); - if (pageNewAdvantureLevelTransform != null) - { - StringStore.TranslateTextTransform(pageNewAdvantureLevelTransform.Find("BackToIndex")); - StringStore.TranslateTextTransform(pageNewAdvantureLevelTransform.Find("Nextpage")); - StringStore.TranslateTextTransform(pageNewAdvantureLevelTransform.Find("LastPage")); - } - - foreach (TextMeshProUGUI txt in mainTransform.GetComponentsInChildren()) - { - // Still dump untranslated strings for modded plants and zombies - FileLoader.DumpUntranslatedStrings(txt.text); - txt.text = StringStore.TranslateText(txt.text); - } - } + StringStore.TranslateTextTransform(__instance.transform.Find("Goback")); + StringStore.TranslateTextTransform(__instance.transform.Find("Switich")); } } } diff --git a/BepInEx/Patches/GameObjects/ButtonObjects/ExploreMakeZombieButton_Patch.cs b/BepInEx/Patches/GameObjects/ButtonObjects/ExploreMakeZombieButton_Patch.cs index e981930..1429902 100644 --- a/BepInEx/Patches/GameObjects/ButtonObjects/ExploreMakeZombieButton_Patch.cs +++ b/BepInEx/Patches/GameObjects/ButtonObjects/ExploreMakeZombieButton_Patch.cs @@ -15,6 +15,6 @@ namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.ButtonObjects { __instance.sceneText.text = Utils.GetZombieNameFromAlmanac(__instance.theZombieType); __instance.sceneText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } + } } } \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/ButtonObjects/UIButton_Patch.cs b/BepInEx/Patches/GameObjects/ButtonObjects/UIButton_Patch.cs index 5e572c9..0de74e2 100644 --- a/BepInEx/Patches/GameObjects/ButtonObjects/UIButton_Patch.cs +++ b/BepInEx/Patches/GameObjects/ButtonObjects/UIButton_Patch.cs @@ -1,59 +1,45 @@ -using System; -using HarmonyLib; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using HarmonyLib; using TMPro; +using System; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; using UnityEngine; -using UnityEngine.TextCore.Text; using UnityEngine.UI; +using UnityEngine.UIElements; namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects { [HarmonyPatch(typeof(UIButton))] public static class UIButton_Patch { - [HarmonyPatch(nameof(UIButton.Start))] + [HarmonyPatch(typeof(UIButton), nameof(UIButton.Start))] [HarmonyPostfix] - private static void Postfix_Start(UIButton __instance) + public static void Start(UIButton __instance) { - try + if (__instance.transform.childCount >= 2) { - // Also handle TMP components directly under the button - if (__instance.transform.childCount >= 2) - { - TextMeshProUGUI text = __instance.transform.GetChild(0).GetComponent(); - TextMeshProUGUI textShadow = __instance.transform.GetChild(1).GetComponent(); + TMP_FontAsset font = FontStore.LoadTMPFont(Utils.Language.ToString()); - text.text = StringStore.TranslateText(text.text, false); - textShadow.text = StringStore.TranslateText(textShadow.text, false); - - text.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - textShadow.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - else + foreach (TextMeshProUGUI text in __instance.transform.GetComponentsInChildren()) { - // Convert and translate legacy Text components - Text[] textComponents = __instance.GetComponentsInChildren(true); - TextMeshProUGUI[] textMeshComponents = __instance.GetComponentsInChildren(true); - foreach (Text textComponent in textComponents) + if (__instance.transform.name == "Goback") { - if (textComponent != null && !string.IsNullOrEmpty(textComponent.text)) - { - string translatedText = StringStore.TranslateText(textComponent.text); - if (!string.IsNullOrEmpty(translatedText) && translatedText != textComponent.text) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - TextMeshProUGUI newTMP = StringStore.ConvertToTextMeshPro(textComponent, fontAsset, true); - - if (newTMP != null) - { - newTMP.text = translatedText; - } - } - } + text.text = "合上"; + } + text.text = StringStore.TranslateText(text.text); + text.font = font; + } + } + else + { + StringStore.TranslateTextTransform(__instance.transform); + if (__instance.transform.name == "Goback") + { + foreach (TextMeshProUGUI text in __instance.transform.GetComponentsInChildren()) + { + text.text = StringStore.TranslateText("合上"); } } } - catch (Exception) { } } [HarmonyPatch(nameof(UIButton.OnMouseUpAsButton))] @@ -68,29 +54,29 @@ namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects { TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - TextMeshProUGUI text = __instance.transform.GetChild(0).GetComponent(); - TextMeshProUGUI[] extraTexts = __instance.transform.GetChild(1).GetComponentsInChildren(); + TextMeshProUGUI text = __instance.transform.GetChild(0).GetComponent(); + TextMeshProUGUI[] extraTexts = __instance.transform.GetChild(1).GetComponentsInChildren(); - text.text = StringStore.TranslateText(text.text, false); - text.font = fontAsset; + text.text = StringStore.TranslateText(text.text, false); + text.font = fontAsset; - foreach (TextMeshProUGUI extraText in extraTexts) - { - extraText.text = StringStore.TranslateText(extraText.text, false); - extraText.font = fontAsset; + foreach (TextMeshProUGUI extraText in extraTexts) + { + extraText.text = StringStore.TranslateText(extraText.text, false); + extraText.font = fontAsset; + } } - } - else - { - TextMeshProUGUI text = __instance.transform.GetChild(0).GetComponent(); - TextMeshProUGUI textShadow = __instance.transform.GetChild(1).GetComponent(); + else + { + TextMeshProUGUI text = __instance.transform.GetChild(0).GetComponent(); + TextMeshProUGUI textShadow = __instance.transform.GetChild(1).GetComponent(); - text.text = StringStore.TranslateText(text.text, false); - textShadow.text = StringStore.TranslateText(textShadow.text, false); + text.text = StringStore.TranslateText(text.text, false); + textShadow.text = StringStore.TranslateText(textShadow.text, false); - text.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - textShadow.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } + text.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + textShadow.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } } } catch (Exception) { } diff --git a/BepInEx/Patches/GameObjects/EveBuffMenu_Patch.cs b/BepInEx/Patches/GameObjects/EveBuffMenu_Patch.cs new file mode 100644 index 0000000..68beceb --- /dev/null +++ b/BepInEx/Patches/GameObjects/EveBuffMenu_Patch.cs @@ -0,0 +1,37 @@ +using System.Text.RegularExpressions; +using HarmonyLib; +using TMPro; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(EveBuffMenu))] + public static class EveBuffMenu_Patch + { + [HarmonyPatch(nameof(EveBuffMenu.Start))] + [HarmonyPostfix] + private static void Start(EveBuffMenu __instance) + { + foreach (EveOptionWindow window in __instance.windows) + { + EveOptionWindow_Patch.TranslateEveOptionWindow(window); + } + + foreach (TextMeshProUGUI text in __instance.quitButton.GetComponentsInChildren()) + { + text.text = StringStore.TranslateText("合上"); + } + } + + [HarmonyPatch(nameof(EveBuffMenu.InitWindows))] + [HarmonyPostfix] + private static void InitWindows(EveBuffMenu __instance) + { + foreach (EveOptionWindow window in __instance.windows) + { + EveOptionWindow_Patch.TranslateEveOptionWindow(window); + } + } + } +} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/EveOptionWindow_Patch.cs b/BepInEx/Patches/GameObjects/EveOptionWindow_Patch.cs new file mode 100644 index 0000000..f751dcd --- /dev/null +++ b/BepInEx/Patches/GameObjects/EveOptionWindow_Patch.cs @@ -0,0 +1,49 @@ +using System.Text.RegularExpressions; +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using TMPro; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(EveOptionWindow))] + public static class EveOptionWindow_Patch + { + [HarmonyPatch(nameof(EveOptionWindow.SetType))] + [HarmonyPostfix] + private static void SetType(EveOptionWindow __instance) + { + TranslateEveOptionWindow(__instance); + } + + [HarmonyPatch(nameof(EveOptionWindow.OnAnimOver))] + [HarmonyPostfix] + private static void OnAnimOver(EveOptionWindow __instance) + { + TranslateEveOptionWindow(__instance); + } + + [HarmonyPatch(nameof(EveOptionWindow.SelectedByRow))] + [HarmonyPostfix] + private static void SelectedByRow(EveOptionWindow __instance) + { + TranslateEveOptionWindow(__instance); + } + + public static void TranslateEveOptionWindow(EveOptionWindow __instance) + { + Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + TextMeshProUGUI introduceText = introduceTransform.GetComponent(); + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + + foreach (TextMeshProUGUI text in __instance.buttonText) + { + text.text = StringStore.TranslateText(text.text); + text.font = fontAsset; + } + } + } +} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/MinorObjects/Brain_Patch.cs b/BepInEx/Patches/GameObjects/MinorObjects/Brain_Patch.cs new file mode 100644 index 0000000..ed896cf --- /dev/null +++ b/BepInEx/Patches/GameObjects/MinorObjects/Brain_Patch.cs @@ -0,0 +1,56 @@ +using System.Text.RegularExpressions; +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using TMPro; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects +{ + [HarmonyPatch(typeof(Brain))] + public static class Brain_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(Brain.Awake))] + private static void Awake(Brain __instance) + { + // reposition original points + Transform pointsTransform = __instance.points.transform; + GameObject pointsObject = __instance.points.gameObject; + pointsTransform.position = new Vector3(-6.5f, pointsTransform.position.y, pointsTransform.position.z); + + // instantiate and move new shadow + GameObject pointsShadowObject = UnityEngine.Object.Instantiate(pointsObject, parent: pointsTransform); + pointsShadowObject.SetActive(true); + Transform pointsShadowTransform = pointsShadowObject.transform; + pointsShadowTransform.position = new Vector3(-6.485f, pointsTransform.position.y - 0.015f, pointsTransform.position.z); + + // set points text + TextMeshPro pointsShadowText = pointsShadowObject.GetComponent(); + pointsShadowText.text = __instance.points.text; + pointsShadowText.sortingOrder -= 2; + pointsShadowText.color = Color.black; + } + + [HarmonyPostfix] + [HarmonyPatch(nameof(Brain.Update))] + private static void Update(Brain __instance) + { + if (__instance.transform.Find("Points").GetChild(0) != null) + { + TextMeshPro shadowText = __instance.transform.Find("Points").GetChild(0).GetComponent(); + shadowText.text = __instance.points.text; + } + } + + [HarmonyPostfix] + [HarmonyPatch(nameof(Brain.WinAction))] + private static void WinAction(Brain __instance) + { + if (__instance.transform.Find("Points").GetChild(0) != null) + { + TextMeshPro shadowText = __instance.transform.Find("Points").GetChild(0).GetComponent(); + shadowText.text = __instance.points.text; + } + } + } +} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/NoticePauseMenu_Patch.cs b/BepInEx/Patches/GameObjects/NoticePauseMenu_Patch.cs index af1441b..8ce33ea 100644 --- a/BepInEx/Patches/GameObjects/NoticePauseMenu_Patch.cs +++ b/BepInEx/Patches/GameObjects/NoticePauseMenu_Patch.cs @@ -15,7 +15,7 @@ namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects [HarmonyPatch(nameof(NoticeMenu.Awake))] private static void Pre_Awake(NoticeMenu __instance) { - GameObject contentObject = __instance.transform.FindChild("Scroll View").GetChild(0).GetChild(0).gameObject; //bc normal Find or FindChild didn't work + GameObject contentObject = __instance.transform.FindChild("Scroll View/Viewport/Content").gameObject; TextMeshProUGUI contentText = contentObject.GetComponent(); File.WriteAllText(Path.Combine(FileLoader.GetAssetDir(FileLoader.AssetType.Dumps), "changelog.txt"), contentText.text); @@ -38,9 +38,9 @@ namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects string changelogText = File.ReadAllText(changelogDir); - GameObject contentObject = __instance.transform.FindChild("Scroll View").GetChild(0).GetChild(0).gameObject; //bc normal Find or FindChild didn't work + GameObject contentObject = __instance.transform.FindChild("Scroll View/Viewport/Content").gameObject; - TextMeshProUGUI contentText = contentObject.GetComponent(); + TextMeshProUGUI contentText = contentObject.GetComponent(); contentText.text = changelogText; ContentSizeFitter sizeFitter = contentObject.AddComponent(); diff --git a/BepInEx/Patches/GameObjects/PlantDamageMenu_Patch.cs b/BepInEx/Patches/GameObjects/PlantDamageMenu_Patch.cs new file mode 100644 index 0000000..d30635a --- /dev/null +++ b/BepInEx/Patches/GameObjects/PlantDamageMenu_Patch.cs @@ -0,0 +1,36 @@ +using System.Text.RegularExpressions; +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using TMPro; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(PlantDamageMenu))] + public static class PlantDamageMenu_Patch + { + [HarmonyPatch(nameof(PlantDamageMenu.Awake))] + [HarmonyPostfix] + private static void Awake(PlantDamageMenu __instance) + { + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) + { + text.text = StringStore.TranslateText(text.text); + text.font = fontAsset; + } + } + + [HarmonyPatch(nameof(PlantDamageMenu.InitCards))] + [HarmonyPostfix] + private static void InitCards(PlantDamageMenu __instance) + { + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) + { + text.text = StringStore.TranslateText(text.text); + text.font = fontAsset; + } + } + } +} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/TravelLookBuff_Patch.cs b/BepInEx/Patches/GameObjects/TravelLookBuff_Patch.cs index 2711176..d5e9697 100644 --- a/BepInEx/Patches/GameObjects/TravelLookBuff_Patch.cs +++ b/BepInEx/Patches/GameObjects/TravelLookBuff_Patch.cs @@ -41,6 +41,18 @@ namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects List buffSet = translatedTravelBuffs[buffLinks[__instance.buffType]]; string buffText = (__instance.buffIndex < buffSet.Count) ? buffSet[__instance.buffIndex] : StringStore.TranslateText(__instance.introduce.text); __instance.introduce.text = buffText; +#if DEBUG + if (__instance.introduce.text != null) + { + Log.LogInfo($"BuffType: {__instance.buffType}, BuffIndex: {__instance.buffIndex}, BuffIntroduce: {__instance.introduce.text}"); + if (__instance.introduce.text != buffText) + { + FileLoader.DumpUntranslatedStrings(__instance.introduce.text); + //Log.LogInfo($"Mapped BuffIntroduce: {buffText}"); + } + } + +#endif foreach (TextMeshProUGUI text in __instance.transform.FindChild("Images").FindChild("Button").GetComponentsInChildren()) { diff --git a/BepInEx/Patches/Managers/AlmanacMgrZombie_Patch.cs b/BepInEx/Patches/Managers/AlmanacMgrZombie_Patch.cs index cddee06..002d522 100644 --- a/BepInEx/Patches/Managers/AlmanacMgrZombie_Patch.cs +++ b/BepInEx/Patches/Managers/AlmanacMgrZombie_Patch.cs @@ -1,8 +1,7 @@ using HarmonyLib; using System; -using System.IO; -using System.Linq; using System.Collections.Generic; +using System.IO; using TMPro; using PvZ_Fusion_Translator__BepInEx_.AssetStore; using UnityEngine; @@ -17,67 +16,21 @@ namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers [HarmonyPostfix] private static void InitNameAndInfoFromJson(AlmanacMgrZombie __instance) { - TranslateTextAlmanac(__instance); - DumpAlmanacModdedZombies(__instance); - return; - } - - [HarmonyPatch(nameof(AlmanacMgrZombie.OnMouseDown))] - [HarmonyPrefix] - private static bool OnMouseDown(AlmanacMgrZombie __instance) - { - TextMeshPro component = __instance.info.GetComponent(); - if (component != null) - { - component.pageToDisplay = component.pageToDisplay > component.m_pageNumber ? 1 : component.pageToDisplay + 1; - return false; - } - return true; - } - } - - - [HarmonyPatch(typeof(AlmanacMgrZombie))] - public static partial class AlmanacMgrZombie_Patch - { - [HarmonyPatch(nameof(AlmanacMgrZombie.OnMouseDown))] - [HarmonyPostfix] - public static void DumpAlmanacModdedZombies(AlmanacMgrZombie __instance) - { - // Dump the texts if needed using Ctrl key - if (Input.GetKey(KeyCode.LeftControl)) - { - FileLoader.DumpUntranslatedStrings(__instance.info.GetComponent().text); - //Log.LogInfo($"Info: {__instance.info.GetComponent().text}"); - FileLoader.DumpUntranslatedStrings(__instance.zombieName.GetComponent().text); - //Log.LogInfo($"Zombie Name: {__instance.zombieName.GetComponent().text}"); - } - } - } - - // Patch to translate the modded almanac zombie names and info - [HarmonyPatch(typeof(AlmanacMgrZombie))] - public static partial class AlmanacMgrZombie_Patch - { - [HarmonyPatch(nameof(AlmanacMgrZombie.Start))] - [HarmonyPostfix] - public static void TranslateTextAlmanac(AlmanacMgrZombie __instance) - { #if MULTI_LANGUAGE - string currentLanguage = Utils.Language.ToString(); - string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); + string currentLanguage = Utils.Language.ToString(); + string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); #else string almanacDir = almanacDir = GetAssetDir(AssetType.Almanac); string currentLanguage = "English"; #endif - string path = Path.Combine(almanacDir, "ZombieStringsTranslate.json"); - string moddedPath = Path.Combine(almanacDir, "ModdedZombiesTranslate.json"); + string path = Path.Combine(almanacDir, "ZombieStringsTranslate.json"); + string moddedPath = Path.Combine(almanacDir, "ModdedZombiesTranslate.json"); - if (!File.Exists(path)) - { - Log.LogError($"ZombieStringsTranslate.json file not found at path: {path}"); - return; - } + if (!File.Exists(path)) + { + Log.LogError($"ZombieStringsTranslate.json file not found at path: {path}"); + return; + } #if OBFUSCATE if (CheckSumStore.IsModified(path)) @@ -87,96 +40,106 @@ namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers } #endif - string json; - json = File.ReadAllText(path); + string json; + json = File.ReadAllText(path); - bool hasAlmanacFont = false; - TMP_FontAsset almanacFontAsset = null; - if (FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage + "_Almanac") || FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage)) - { - almanacFontAsset = FontStore.LoadTMPFontAlmanac(currentLanguage); - hasAlmanacFont = true; - } + bool hasAlmanacFont = false; + TMP_FontAsset almanacFontAsset = null; + if (FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage + "_Almanac") || FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage)) + { + almanacFontAsset = FontStore.LoadTMPFontAlmanac(currentLanguage); + hasAlmanacFont = true; + } #if MULTI_LANGUAGE - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); #else TMP_FontAsset fontAsset = FontStore.LoadTMPFont(); #endif - TextMeshPro component = __instance.info.GetComponent(); - TextMeshPro component2 = __instance.zombieName.GetComponent(); - TextMeshPro component3 = __instance.zombieName.transform.GetChild(0).GetComponent(); + TextMeshPro component = __instance.info.GetComponent(); + TextMeshPro component2 = __instance.zombieName.GetComponent(); + TextMeshPro component3 = __instance.zombieName.transform.GetChild(0).GetComponent(); - try - { - AlmanacMgrZombie.ZombieAlmanacData zombieData = JsonUtility.FromJson(json); + ZombieAlmanacData zombieData = JsonUtility.FromJson(json); - if (zombieData != null && zombieData.zombies != null) - { - foreach (AlmanacMgrZombie.ZombieInfo zombieInfo in zombieData.zombies) - { - if (zombieInfo.theZombieType == __instance.theZombieType) - { - component.text = zombieInfo.info + "\n\n" + zombieInfo.introduce; - component.overflowMode = TextOverflowModes.Page; - component2.text = zombieInfo.name; - component2.autoSizeTextContainer = true; - component3.text = Utils.RemoveColorTags(zombieInfo.name); - component3.autoSizeTextContainer = true; + foreach (ZombieInfo zombieInfo in zombieData.zombies) + { + if (zombieInfo.theZombieType == __instance.theZombieType) + { + component.text = zombieInfo.info + "\n\n" + zombieInfo.introduce; + component.overflowMode = TextOverflowModes.Page; + component2.text = zombieInfo.name; + component2.autoSizeTextContainer = true; + component3.text = Utils.RemoveColorTags(zombieInfo.name); + component3.autoSizeTextContainer = true; - if (hasAlmanacFont) - component.font = almanacFontAsset; - else - component.font = fontAsset; - component2.font = fontAsset; - component3.font = fontAsset; - } - } - } - } - catch (System.Exception ex) - { - Log.LogError($"Error parsing JSON in AlmanacMgrZombie_Patch: {ex.Message}"); - } + if (hasAlmanacFont) + component.font = almanacFontAsset; + else + component.font = fontAsset; + component2.font = fontAsset; + component3.font = fontAsset; + } + } - if (File.Exists(moddedPath)) - { - try - { - string moddedJson; - moddedJson = File.ReadAllText(moddedPath); + if (File.Exists(moddedPath)) + { + string moddedJson; + moddedJson = File.ReadAllText(moddedPath); - AlmanacMgrZombie.ZombieAlmanacData moddedZombieData = JsonUtility.FromJson(moddedJson); + ZombieAlmanacData moddedZombieData = JsonUtility.FromJson(moddedJson); - if (moddedZombieData != null && moddedZombieData.zombies != null) - { - foreach (AlmanacMgrZombie.ZombieInfo zombieInfo in moddedZombieData.zombies) - { - if (zombieInfo.theZombieType == __instance.theZombieType) - { - component.text = zombieInfo.info + "\n\n" + zombieInfo.introduce; - component.overflowMode = TextOverflowModes.Page; - component2.text = zombieInfo.name; - component2.autoSizeTextContainer = true; - component3.text = Utils.RemoveColorTags(zombieInfo.name); - component3.autoSizeTextContainer = true; + foreach (ZombieInfo zombieInfo in moddedZombieData.zombies) + { + if (zombieInfo.theZombieType == __instance.theZombieType) + { + component.text = zombieInfo.info + "\n\n" + zombieInfo.introduce; + component.overflowMode = TextOverflowModes.Page; + component2.text = zombieInfo.name; + component2.autoSizeTextContainer = true; + component3.text = Utils.RemoveColorTags(zombieInfo.name); + component3.autoSizeTextContainer = true; - if (hasAlmanacFont) - component.font = almanacFontAsset; - else - component.font = fontAsset; - component2.font = fontAsset; - component3.font = fontAsset; - } - } - } - } - catch (System.Exception ex) - { - Log.LogError($"Error parsing modded JSON in AlmanacMgrZombie_Patch: {ex.Message}"); - } - } - } + if (hasAlmanacFont) + component.font = almanacFontAsset; + else + component.font = fontAsset; + component2.font = fontAsset; + component3.font = fontAsset; + } + } + } + + return; + } + + [HarmonyPatch(nameof(AlmanacMgrZombie.OnMouseDown))] + [HarmonyPrefix] + private static bool OnMouseDown(AlmanacMgrZombie __instance) + { + TextMeshPro component = __instance.info.GetComponent(); + if (component != null) + { + component.pageToDisplay = component.pageToDisplay > component.m_pageNumber ? 1 : component.pageToDisplay + 1; + return false; + } + return true; + } + } + + [Serializable] + public class ZombieAlmanacData + { + public List zombies; + } + + [Serializable] + public class ZombieInfo + { + public string name; + public string info; + public string introduce; + public ZombieType theZombieType; } } diff --git a/BepInEx/Patches/Managers/AlmanacPlantBank_Patch.cs b/BepInEx/Patches/Managers/AlmanacPlantBank_Patch.cs index 5d70093..9e23635 100644 --- a/BepInEx/Patches/Managers/AlmanacPlantBank_Patch.cs +++ b/BepInEx/Patches/Managers/AlmanacPlantBank_Patch.cs @@ -1,11 +1,8 @@ using HarmonyLib; -using Il2CppInterop.Runtime; -using PvZ_Fusion_Translator__BepInEx_; +using TMPro; using PvZ_Fusion_Translator__BepInEx_.AssetStore; using System.IO; -using TMPro; using UnityEngine; -using UnityEngine.TextCore.Text; using static PvZ_Fusion_Translator__BepInEx_.FileLoader; namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers @@ -15,41 +12,8 @@ namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers { [HarmonyPatch(nameof(AlmanacPlantBank.InitNameAndInfoFromJson))] [HarmonyPostfix] - public static void InitNameAndInfoFromJson(AlmanacPlantBank __instance) + private static void InitNameAndInfoFromJson(AlmanacPlantBank __instance) { - TranslateTextAlmanac(__instance); - } - - [HarmonyPatch(nameof(AlmanacPlantBank.OnMouseDown))] - [HarmonyPrefix] - private static bool OnMouseDown(AlmanacPlantBank __instance) - { - TranslateTextAlmanac(__instance); - TextMeshPro component = __instance.introduce.GetComponent(); - if (component != null) - { - component.pageToDisplay = component.pageToDisplay > component.m_pageNumber ? 1 : component.pageToDisplay + 1; - return false; - } - return true; - } - - // This method is used to translate the text in the AlmanacPlantBank when it starts. And some plants like LibraHp plants have different text type in the Almanac. - [HarmonyPatch(nameof(AlmanacPlantBank.Start))] - [HarmonyPostfix] - public static void TranslateTextAlmanac(AlmanacPlantBank __instance) - { - - // Dump the texts if needed - if (Input.GetKey(KeyCode.LeftControl)) - { - FileLoader.DumpUntranslatedStrings(__instance.introduce.GetComponent().text); - //Log.LogInfo($"Info: {__instance.introduce.GetComponent().text}"); - FileLoader.DumpUntranslatedStrings(__instance.plantName.GetComponent().text); - //Log.LogInfo($"PlantName Name: {__instance.plantName.GetComponent().text}"); - //Log.LogInfo($"PlantShadow Name: {__instance.plantName.transform.GetChild(0).GetComponent().text}"); - } - #if MULTI_LANGUAGE string currentLanguage = Utils.Language.ToString(); string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); @@ -62,17 +26,20 @@ namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers if (!File.Exists(path)) { + Log.LogError($"LawnStringsTranslate.json file not found at path: {path}"); return; } #if OBFUSCATE - if (CheckSumStore.IsModified(path)) - { - return; - } + if (CheckSumStore.IsModified(path)) + { + Log.LogError("File {0} was modified!", path); + return; + } #endif - string json = File.ReadAllText(path); + string json; + json = File.ReadAllText(path); bool hasAlmanacFont = false; TMP_FontAsset almanacFontAsset = null; @@ -92,12 +59,6 @@ namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers TextMeshPro component2 = __instance.plantName.GetComponent(); TextMeshPro component3 = __instance.plantName.transform.GetChild(0).GetComponent(); TextMeshPro component4 = __instance.cost.GetComponent(); - TextMeshPro component5 = __instance.introduce.GetComponentInChildren(); -#if DEBUG - Log.LogWarning($"Introduce text: {component?.text}"); - Log.LogWarning($"Plant name: {component2?.text}"); -#endif - //component.text = component.text ?? string.Empty; AlmanacPlantBank.PlantData plantData = JsonUtility.FromJson(json); @@ -105,25 +66,20 @@ namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers { if (plantInfo.seedType == __instance.theSeedType && !string.IsNullOrEmpty(plantInfo.name)) { -#if DEBUG - Log.LogInfo($"Processing plant type: {plantInfo.seedType}"); - Log.LogInfo($"Plant info: {plantInfo.info}, Name: {plantInfo.name}, Cost: {plantInfo.cost}, Introduce: {plantInfo.introduce}"); -#endif component.autoSizeTextContainer = false; component.text = plantInfo.info + "\n\n" + plantInfo.introduce; component.overflowMode = TextOverflowModes.Page; + // fix dimensions for cost text component.rectTransform.offsetMax = new Vector2(component.rectTransform.offsetMax.x, 27.3839f); component.rectTransform.offsetMin = new Vector2(component.rectTransform.offsetMin.x, -29.3079f); component.rectTransform.sizeDelta = new Vector2(component.rectTransform.sizeDelta.x, 50.917f); component.transform.localPosition = new Vector3(component.transform.localPosition.x, component.transform.localPosition.y + 0.15f, component.transform.localPosition.z); + component2.text = plantInfo.name; component2.autoSizeTextContainer = true; -#if DEBUG - Log.LogInfo($"Processing plant name: '{plantInfo.name}' (null: {plantInfo.name == null})"); -#endif component3.text = Utils.RemoveColorTags(plantInfo.name ?? string.Empty); component3.autoSizeTextContainer = true; @@ -146,7 +102,9 @@ namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers if (File.Exists(moddedPath)) { - string moddedJson = File.ReadAllText(moddedPath); + string moddedJson; + moddedJson = File.ReadAllText(moddedPath); + AlmanacPlantBank.PlantData moddedPlantData = JsonUtility.FromJson(moddedJson); foreach (AlmanacPlantBank.PlantInfo plantInfo in moddedPlantData.plants) @@ -157,17 +115,16 @@ namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers component.text = plantInfo.info + "\n\n" + plantInfo.introduce; component.overflowMode = TextOverflowModes.Page; + // fix dimensions for cost text component.rectTransform.offsetMax = new Vector2(component.rectTransform.offsetMax.x, 27.3839f); component.rectTransform.offsetMin = new Vector2(component.rectTransform.offsetMin.x, -29.3079f); component.rectTransform.sizeDelta = new Vector2(component.rectTransform.sizeDelta.x, 50.917f); component.transform.localPosition = new Vector3(component.transform.localPosition.x, component.transform.localPosition.y + 0.15f, component.transform.localPosition.z); + component2.text = plantInfo.name; component2.autoSizeTextContainer = true; -#if DEBUG - Log.LogInfo($"Processing plant name: '{plantInfo.name}' (null: {plantInfo.name == null})"); -#endif component3.text = Utils.RemoveColorTags(plantInfo.name ?? string.Empty); component3.autoSizeTextContainer = true; @@ -188,20 +145,37 @@ namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers } } } + + return; + } + + [HarmonyPatch(nameof(AlmanacPlantBank.OnMouseDown))] + [HarmonyPrefix] + private static bool OnMouseDown(AlmanacPlantBank __instance) + { + TextMeshPro component = __instance.introduce.GetComponent(); + if (component != null) + { + component.pageToDisplay = component.pageToDisplay > component.m_pageNumber ? 1 : component.pageToDisplay + 1; + return false; + } + return true; } [HarmonyPatch(nameof(AlmanacPlantBank.PVPInit))] [HarmonyPostfix] private static void PVPInit(AlmanacPlantBank __instance) { - TranslateTextAlmanac(__instance); + TextMeshPro component = __instance.introduce.GetComponent(); + if (component != null) + { + component.autoSizeTextContainer = false; + } Transform banTransform = __instance.transform.FindChild("Ban").GetChild(0); if (banTransform != null) { - TextMeshPro banText = banTransform.GetComponent(); - string originalBanText = banText.text; - banText.text = StringStore.TranslateText(banText.text); + banTransform.GetComponent().text = StringStore.TranslateText(banTransform.GetComponent().text); } } diff --git a/BepInEx/Patches/Managers/GameAPP_Patch.cs b/BepInEx/Patches/Managers/GameAPP_Patch.cs index 7355d28..3fdccef 100644 --- a/BepInEx/Patches/Managers/GameAPP_Patch.cs +++ b/BepInEx/Patches/Managers/GameAPP_Patch.cs @@ -1,7 +1,6 @@ using HarmonyLib; -using System; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; +using TMPro; +using UnityEngine.EventSystems; namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers { @@ -9,10 +8,20 @@ namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers public class GameAPP_Patch { [HarmonyPatch(nameof(GameAPP.Update))] - [HarmonyPostfix] - private static void Update(GameAPP __instance) + [HarmonyPrefix] + private static bool Update(GameAPP __instance) { - Core.Instance.OnUpdate(); + Core.Instance.OnUpdate(); + + if (EventSystem.current?.currentSelectedGameObject != null) + { + if (EventSystem.current.currentSelectedGameObject.TryGetComponent(out TMP_InputField field)) + { + __instance.MusicUpdate(); + return false; + } + } + return true; } } } \ No newline at end of file diff --git a/BepInEx/Patches/Managers/IZBottomMenu_Patch.cs b/BepInEx/Patches/Managers/IZBottomMenu_Patch.cs index 93907c7..c114a24 100644 --- a/BepInEx/Patches/Managers/IZBottomMenu_Patch.cs +++ b/BepInEx/Patches/Managers/IZBottomMenu_Patch.cs @@ -14,24 +14,19 @@ namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers [HarmonyPostfix] public static void ChangeStringz(IZBottomMenu __instance) { - TextMeshProUGUI[] array = - [ - __instance.transform.GetChild(0).GetComponent(), - __instance.transform.GetChild(0).GetChild(0).GetComponent(), - ]; - for (int i = 0; i < array.Length; i++) + foreach (TextMeshProUGUI text in __instance.levelName) { string fStr = StringStore.translationStringRegex["([^\\s]+),推荐难度:(\\d+)"]; - string[] parts = array[i].text.Split(",推荐难度:"); + string[] parts = text.text.Split(",推荐难度:"); - if (new Regex("([^\\s]+),推荐难度:(\\d+)").IsMatch(array[i].text)) + if (new Regex("([^\\s]+),推荐难度:(\\d+)").IsMatch(text.text)) { string customName = (StringStore.translationString.ContainsKey(parts[0] + "_IZ")) ? parts[0] + "_IZ" : parts[0]; - array[i].text = string.Format(fStr, StringStore.TranslateText(customName), parts[1]); + text.text = string.Format(fStr, StringStore.TranslateText(customName), parts[1]); } - array[i] = StringStore.TranslateText(array[i]); - array[i].text = array[i].text.Replace("\n", " "); + text.text = StringStore.TranslateText(text.text); + text.text = text.text.Replace("\n", " "); } } @@ -39,23 +34,18 @@ namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers [HarmonyPostfix] public static void SetLevelName(IZBottomMenu __instance) { - TextMeshProUGUI[] array = - [ - __instance.transform.GetChild(0).GetComponent(), - __instance.transform.GetChild(0).GetChild(0).GetComponent(), - ]; - for (int i = 0; i < array.Length; i++) + foreach (TextMeshProUGUI text in __instance.levelName) { string fStr = StringStore.translationStringRegex["([^\\s]+),推荐难度:(\\d+)"]; - string[] parts = array[i].text.Split(",推荐难度:"); + string[] parts = text.text.Split(",推荐难度:"); - if (new Regex("([^\\s]+),推荐难度:(\\d+)").IsMatch(array[i].text)) + if (new Regex("([^\\s]+),推荐难度:(\\d+)").IsMatch(text.text)) { - array[i].text = string.Format(fStr, StringStore.TranslateText(parts[0]), parts[1]); + text.text = string.Format(fStr, StringStore.TranslateText(parts[0]), parts[1]); } - array[i] = StringStore.TranslateText(array[i]); - array[i].text = array[i].text.Replace("\n", " "); + text.text = StringStore.TranslateText(text.text); + text.text = text.text.Replace("\n", " "); } } } diff --git a/BepInEx/PvZ Fusion Translator [BepInEx].csproj b/BepInEx/PvZ Fusion Translator [BepInEx].csproj index 5efe955..669b76c 100644 --- a/BepInEx/PvZ Fusion Translator [BepInEx].csproj +++ b/BepInEx/PvZ Fusion Translator [BepInEx].csproj @@ -13,7 +13,7 @@ https://nuget.samboy.dev/v3/index.json PvZ_Fusion_Translator__BepInEx_ - C:\Users\rainb\Desktop\PC_PVZ-Fusion_3.1.1-BepInEx + D:\PvZ Fusion\BepInEx Game Files C:\Users\rainb\Desktop\PC_PVZ-Fusion_3.1.1 Debug;DebugEnglish;ReleaseMulti;ReleaseEnglish;DebugTesting;ReleaseOther;DebugObfuscate;ReleaseObfuscate;DebugMulti AnyCPU;x64 @@ -130,6 +130,11 @@ + + + + + @@ -152,6 +157,8 @@ + + @@ -161,6 +168,7 @@ + @@ -176,6 +184,7 @@ + @@ -593,7 +602,7 @@ - + diff --git a/BepInEx/Utils.cs b/BepInEx/Utils.cs index c5d7bb0..663474a 100644 --- a/BepInEx/Utils.cs +++ b/BepInEx/Utils.cs @@ -1,12 +1,14 @@ using BepInEx; using BepInEx.Configuration; using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using PvZ_Fusion_Translator__BepInEx_.Patches.Managers; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text.RegularExpressions; using TMPro; +using Unity.Burst.Intrinsics; using Unity.VisualScripting.FullSerializer; using UnityEngine; using UnityEngine.Experimental.Rendering; @@ -63,6 +65,50 @@ namespace PvZ_Fusion_Translator__BepInEx_ } } } + + public static Dictionary> recipeLinks = new Dictionary>(); + + public static void RegisterRecipeLinks() + { + recipeLinks.Clear(); + + Il2CppSystem.Array mixData = MixData.data.Cast(); + int rows = mixData.GetLength(0); + int columns = mixData.GetLength(1); + + foreach (PlantType plantType in Enum.GetValues(typeof(PlantType))) + { + int seedType = (int)plantType; + + recipeLinks.Add(seedType, new()); + + if (seedType > 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()]; + + if (checks[0] != 0) + { + recipeLinks[seedType].Add(checks[0]); + } + + if (checks[1] != 0) + { + recipeLinks[seedType].Add(checks[1]); + } + } + } + } + if (recipeLinks[seedType].Count > 0) + { + Log.LogDebug($"Found {recipeLinks[seedType].Count} fusions for {seedType}!"); + } + } + } + internal static bool TryReplaceTexture2D(Texture2D ogTexture) { if (ogTexture != null) @@ -137,6 +183,16 @@ namespace PvZ_Fusion_Translator__BepInEx_ return withoutCloseTags; } + public static string RemoveSizeTags(string text) + { + if (string.IsNullOrEmpty(text)) + return text ?? string.Empty; + + string withoutOpenTags = Regex.Replace(text, @"]+>", string.Empty, RegexOptions.IgnoreCase); + string withoutCloseTags = Regex.Replace(withoutOpenTags, @"", string.Empty, RegexOptions.IgnoreCase); + return withoutCloseTags; + } + public static GameObject ConvertToTextMeshProUGUI(GameObject originalText, Transform parent, string name) { GameObject newObj = new GameObject(name); @@ -266,9 +322,9 @@ namespace PvZ_Fusion_Translator__BepInEx_ else { json = File.ReadAllText(path); - AlmanacMgrZombie.ZombieAlmanacData zombieData = JsonUtility.FromJson(json); + ZombieAlmanacData zombieData = JsonUtility.FromJson(json); - foreach (AlmanacMgrZombie.ZombieInfo zombieInfo in zombieData.zombies) + foreach (ZombieInfo zombieInfo in zombieData.zombies) { if ((int)zombieInfo.theZombieType == (int)theZombieType) { @@ -280,6 +336,8 @@ namespace PvZ_Fusion_Translator__BepInEx_ return theZombieName; } + + public static bool CheckForUntranslatedText(string text) { Regex regex = new("\\p{IsCJKUnifiedIdeographs}+");