From dd1cba76311e301f5877f3e9cd0dd2b31d27b684 Mon Sep 17 00:00:00 2001 From: SillyStar-Github <90102598+SillyStar-Github@users.noreply.github.com> Date: Tue, 1 Jul 2025 21:23:46 -0400 Subject: [PATCH] update --- MelonLoader/AssetStore/StringStore.cs | 6 +- MelonLoader/FileLoader.cs | 2 + .../GameObjects/MinorObjects/Plant_Patch.cs | 63 +++++++---- .../MinorObjects/TrainingDummy_Patch.cs | 16 +++ .../MinorObjects/UltimateChomper_Patch.cs | 17 +++ .../GameObjects/MinorObjects/Zombie_Patch.cs | 101 ++++++++++++++++-- .../Patches/GameObjects/TravelStore_Patch.cs | 47 ++++---- ...PvZ Fusion Translator [MelonLoader].csproj | 4 +- 8 files changed, 197 insertions(+), 59 deletions(-) create mode 100644 MelonLoader/Patches/GameObjects/MinorObjects/TrainingDummy_Patch.cs create mode 100644 MelonLoader/Patches/GameObjects/MinorObjects/UltimateChomper_Patch.cs diff --git a/MelonLoader/AssetStore/StringStore.cs b/MelonLoader/AssetStore/StringStore.cs index d666b66..21c499a 100644 --- a/MelonLoader/AssetStore/StringStore.cs +++ b/MelonLoader/AssetStore/StringStore.cs @@ -29,7 +29,7 @@ namespace PvZ_Fusion_Translator.AssetStore // UI - Playing { @"-------UI - Playing" , "UI - Playing-------" }, { @"快捷键:(\d+)" , "Hotkey: {0}" }, - { @"场上敌人数量:(\d+)" , "Zombies: {0}" }, + { @"场上敌人数量:(\d+)$" , "Zombies: {0}" }, { @"难度:(\d+)" , "Difficulty: {0}" }, // UI - Adventure Mode @@ -117,8 +117,8 @@ namespace PvZ_Fusion_Translator.AssetStore { @"-------Strings - Others" , "Strings - Others-------" }, // { @"HP:(\d+)/(\d+)\s+一类:(\d+)/(\d+)" , "HP: {0}/{1}\nArmor: {2}/{3}" }, // { @"HP:(\d+)/(\d+)\s+二类:(\d+)/(\d+)" , "HP: {0}/{1}\nArmor: {2}/{3}" }, - { @"^HP:(\d+)/(\d+)\s+([^\s+])类:(\d+)/(\d+)" , "HP: {0}/{1}\nArmor: {3}/{4}" }, - { @"^HP:(\d+)/(\d+)" , "HP: {0}/{1}" }, + // { @"^HP:(\d+)/(\d+)\s+([^\s+])类:(\d+)/(\d+)" , "HP: {0}/{1}\nArmor: {3}/{4}" }, + // { @"^HP:(\d+)/(\d+)" , "HP: {0}/{1}" }, // { @"平衡性调整(([^\s]+))" , "Balance Adjustment ({0})" }, { @"旅行:守护 (\d+)轮已经完成" , "Odyssey: Last Stand | {0} Rounds Completed"}, diff --git a/MelonLoader/FileLoader.cs b/MelonLoader/FileLoader.cs index 42eb115..0bc86f9 100644 --- a/MelonLoader/FileLoader.cs +++ b/MelonLoader/FileLoader.cs @@ -1,6 +1,7 @@ using Il2Cpp; using MelonLoader; using PvZ_Fusion_Translator.AssetStore; +using PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects; using PvZ_Fusion_Translator.Patches.OtherManagers; using System.Text.Encodings.Web; using System.Text.Json; @@ -76,6 +77,7 @@ namespace PvZ_Fusion_Translator { StringStore.translationStringRegex[key] = value; } + Zombie_Patch.LoadHPStrings(); } } SaveStrings(); diff --git a/MelonLoader/Patches/GameObjects/MinorObjects/Plant_Patch.cs b/MelonLoader/Patches/GameObjects/MinorObjects/Plant_Patch.cs index 3aad6c8..0e0cbb2 100644 --- a/MelonLoader/Patches/GameObjects/MinorObjects/Plant_Patch.cs +++ b/MelonLoader/Patches/GameObjects/MinorObjects/Plant_Patch.cs @@ -1,24 +1,47 @@ -#if FIX -using HarmonyLib; +using HarmonyLib; using Il2Cpp; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; +using System.Text.RegularExpressions; namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects { - [HarmonyPatch(typeof(Plant))] - public static class Plant_Patch - { - [HarmonyPostfix] - [HarmonyPatch(nameof(Plant.UpdateHealthText))] - private static void UpdateHealthText(Plant __instance) - { - Transform healthTransform = __instance.transform.Find("health"); - if (healthTransform != null) - { - StringStore.TranslateTextTransform(__instance.transform); - } - } - } -} -#endif \ No newline at end of file + [HarmonyPatch(typeof(Plant))] + public static class Plant_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(Plant.Awake))] + private static void Awake(Plant __instance) + { + if (!(__instance.thePlantType == PlantType.SuperMachineNut || __instance.thePlantType == PlantType.MachineNut)) + return; + __instance.healthSlider.healthText.text = __instance.healthSlider.healthTextShadow.text = ChangeHPText(__instance.healthSlider.healthTextShadow.text); + } + + [HarmonyPostfix] + [HarmonyPatch(nameof(Plant.UpdateText))] + private static void Update(Plant __instance) + { + if (!(__instance.thePlantType == PlantType.SuperMachineNut || __instance.thePlantType == PlantType.MachineNut)) + return; + if (__instance.thePlantHealth < __instance.thePlantMaxHealth) + return; + __instance.healthSlider.healthText.text = __instance.healthSlider.healthTextShadow.text = ChangeHPText(__instance.healthSlider.healthTextShadow.text); + } + + static string ChangeHPText(string originalText) + { + var regex = new Regex(@"(\d+)\d\d\d/(\d)000"); + if (regex.IsMatch(originalText)) + { + var match = regex.Match(originalText); + int groupCount = match.Groups.Count; + + List dynamicParts = new List(); + + for (int i = 1; i < groupCount; i++) + dynamicParts.Add(match.Groups[i].Value); + return originalText = string.Format("{0}k/{1}k", [.. dynamicParts]); + } + return originalText; + } + } +} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/MinorObjects/TrainingDummy_Patch.cs b/MelonLoader/Patches/GameObjects/MinorObjects/TrainingDummy_Patch.cs new file mode 100644 index 0000000..de3d649 --- /dev/null +++ b/MelonLoader/Patches/GameObjects/MinorObjects/TrainingDummy_Patch.cs @@ -0,0 +1,16 @@ +using HarmonyLib; +using Il2Cpp; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects +{ + [HarmonyPatch(typeof(TrainingDummy), nameof(TrainingDummy.UpdateHealthText))] + public static class TrainingDummy_Patch + { + [HarmonyPostfix] + public static void UpdateHealthText(TrainingDummy __instance) + { + Zombie_Patch.TranslateHpUI(__instance.healthText); + Zombie_Patch.TranslateHpUI(__instance.healthTextShadow); + } + } +} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/MinorObjects/UltimateChomper_Patch.cs b/MelonLoader/Patches/GameObjects/MinorObjects/UltimateChomper_Patch.cs new file mode 100644 index 0000000..d04c947 --- /dev/null +++ b/MelonLoader/Patches/GameObjects/MinorObjects/UltimateChomper_Patch.cs @@ -0,0 +1,17 @@ +using HarmonyLib; +using Il2Cpp; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects +{ + [HarmonyPatch(typeof(UltimateChomper), nameof(UltimateChomper.UpdateText))] + public static class UltimateChomper_Patch + { + [HarmonyPostfix] + public static void UpdateText(UltimateChomper __instance) + { + StringStore.TranslateText(__instance.killingText); + StringStore.TranslateText(__instance.killingTextShadow); + } + } +} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/MinorObjects/Zombie_Patch.cs b/MelonLoader/Patches/GameObjects/MinorObjects/Zombie_Patch.cs index 222b54e..43117ba 100644 --- a/MelonLoader/Patches/GameObjects/MinorObjects/Zombie_Patch.cs +++ b/MelonLoader/Patches/GameObjects/MinorObjects/Zombie_Patch.cs @@ -1,12 +1,99 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using HarmonyLib; +using Il2Cpp; +using PvZ_Fusion_Translator.AssetStore; +using System.Text.RegularExpressions; +using UnityEngine; +using Il2CppTMPro; namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects { - class Zombie_Patch + [HarmonyPatch(typeof(Zombie))] + public static class Zombie_Patch { + private static Dictionary HPStrings = new Dictionary() + { + { "最后一击:(\\d+)\nDPS:(.+)$", "Last damage: {0}\nDPS: {1}" }, + { "^HP:(\\d+)/(\\d+)\n\\D+(\\d+)/(\\d+)\n\\D+(\\d+)/(\\d+)$", "HP: {0}/{1}\nType 1 armor: {2}/{3}\nType 2 armor: {4}/{5}" }, + { "^HP:(\\d+)/(\\d+)\n\\D+(\\d+)/(\\d+)$", "HP: {0}/{1}\nType 1 armor: {2}/{3}" }, + { "^HP:(\\d+)/(\\d+)$", "HP: {0}/{1}" }, + }; + + public static void LoadHPStrings() + { + foreach (var hp in HPStrings) + if (StringStore.translationStringRegex.ContainsKey(hp.Key)) + HPStrings[hp.Key] = StringStore.translationStringRegex[hp.Key]; + } + + [HarmonyPatch(nameof(Zombie.Start))] + [HarmonyPostfix] + public static void Start(Zombie __instance) + { + TranslateHpUI(__instance.healthText); + TranslateHpUI(__instance.healthTextShadow); + if (__instance.theFirstArmorHealth == 0 && __instance.theSecondArmorHealth != 0) + { + __instance.healthText.text = __instance.healthText.text.Replace("Type 1", "Type 2"); + __instance.healthTextShadow.text = __instance.healthText.text.Replace("Type 1", "Type 2"); + } + if (__instance.healthText.transform.rotation != Quaternion.Euler(0, 0, 0)) + __instance.healthText.transform.rotation = Quaternion.Euler(0f, 0f, 0f); + } + + [HarmonyPatch(nameof(Zombie.Update))] + [HarmonyPrefix] + public static void Update(Zombie __instance) + { + if (__instance.theZombieType == ZombieType.TrainingDummy || !Board.Instance.showZombieHealth) + return; + TranslateHpUI(__instance.healthText); + TranslateHpUI(__instance.healthTextShadow); + if (__instance.theFirstArmorHealth == 0 && __instance.theSecondArmorHealth != 0) + { + __instance.healthText.text = __instance.healthText.text.Replace("Type 1", "Type 2"); + __instance.healthTextShadow.text = __instance.healthText.text.Replace("Type 1", "Type 2"); + } + if (__instance.healthText.transform.rotation != Quaternion.Euler(0f, 0f, 0f)) + __instance.healthText.transform.rotation = Quaternion.Euler(0f, 0f, 0f); + } + + public static void TranslateHpUI(TextMeshPro textTMP) + { + if (textTMP) + { + string origText = textTMP.text; + string translatedText = TranslateHPText(origText); + textTMP.text = translatedText == origText ? origText : translatedText; + textTMP.autoSizeTextContainer = false; + if (translatedText != origText) + textTMP.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + } + + public static string TranslateHPText(string originalText) + { + foreach (var entry in HPStrings) + { + var regex = new Regex(entry.Key); + if (regex.IsMatch(originalText)) + { + var match = regex.Match(originalText); + int groupCount = match.Groups.Count; + + List dynamicParts = new List(); + + for (int i = 1; i < groupCount; i++) + { + string groupValue = match.Groups[i].Value; + string translatedValue = StringStore.translationString.ContainsKey(groupValue) + ? StringStore.translationString[groupValue] + : groupValue; + dynamicParts.Add(translatedValue); + } + return originalText = string.Format(entry.Value, [.. dynamicParts]); + } + } + return originalText; + } } -} +} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/TravelStore_Patch.cs b/MelonLoader/Patches/GameObjects/TravelStore_Patch.cs index edbf166..5725d5e 100644 --- a/MelonLoader/Patches/GameObjects/TravelStore_Patch.cs +++ b/MelonLoader/Patches/GameObjects/TravelStore_Patch.cs @@ -7,42 +7,33 @@ using UnityEngine; namespace PvZ_Fusion_Translator.Patches.GameObjects { [HarmonyPatch(typeof(TravelStore))] - internal class TravelStore_Patch + public static class TravelStore_Patch { [HarmonyPatch(nameof(TravelStore.Update))] [HarmonyPostfix] private static void Update(TravelStore __instance) - { - foreach (TextMeshProUGUI text in __instance.introduces) - { - text.text = StringStore.TranslateText(text.text); - } - - Transform moneyTransform = __instance.transform.Find("Money"); - if (moneyTransform != null) - { - StringStore.TranslateTextTransform(moneyTransform); - } - - foreach (TextMeshProUGUI text in __instance.points) - { - text.text = StringStore.TranslateText(text.text); - } + { + foreach (TextMeshProUGUI intr in __instance.introduces) + StringStore.TranslateTextUI(intr); + foreach (var textMesh in __instance.points) + StringStore.TranslateTextUI(textMesh); } - [HarmonyPatch(nameof(TravelStore.SetText), new Type[] { typeof(string)})] - [HarmonyPostfix] - private static void ShowText(TravelStore __instance) - { - foreach (TextMeshProUGUI text in __instance.introduces) - { - text.text = StringStore.TranslateText(text.text); - } - - foreach (TextMeshProUGUI text in __instance.points) + [HarmonyPatch(nameof(TravelStore.RefreshBuff))] + [HarmonyPostfix] + private static void RefreshBuff(TravelStore __instance) + { + foreach (TravelBuff buff in __instance.travelBuffs) { - text.text = StringStore.TranslateText(text.text); + TextMeshProUGUI cost = buff.transform.GetChild(1).GetComponent(); + if (!cost.text.Contains('0')) + StringStore.TranslateTextUI(cost); + cost.font = Resources.Load("fonts/Dynamic"); } + foreach (TextMeshProUGUI intr in __instance.introduces) + StringStore.TranslateTextUI(intr); + foreach (var textMesh in __instance.points) + StringStore.TranslateTextUI(textMesh); } } } diff --git a/MelonLoader/PvZ Fusion Translator [MelonLoader].csproj b/MelonLoader/PvZ Fusion Translator [MelonLoader].csproj index a2e65b8..19d1b93 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 - D:\PvZ Fusion\Game Files + G:\ML-Fusion 2.6.1\Game Files AnyCPU;ARM64;x64 @@ -406,6 +406,8 @@ + +