Update BepInex 3.2.1

This commit is contained in:
TuanAnh2901 2025-12-27 16:36:18 +07:00
parent 25621b7df0
commit 87b375a7be
23 changed files with 1024 additions and 404 deletions

1
.gitignore vendored
View file

@ -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

View file

@ -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();
}

View file

@ -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
{

View file

@ -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<TextMeshProUGUI>(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<TextMeshProUGUI>();
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<PlantData>(json);
Il2CppSystem.Collections.Generic.List<PlantType> 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;
}
}
}

View file

@ -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<AlmanacPlantBank.PlantData>(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<AlmanacPlantBank.PlantData>(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}");
}
}
}
}

View file

@ -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<TextMeshProUGUI>(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;
}
}
}
}
}

View file

@ -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<ZombieAlmanacData>(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<ZombieAlmanacData>(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}");
}
}
}
}

View file

@ -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<TextMeshProUGUI>())
{
if (text.text == "关闭")
{
text.text = StringStore.TranslateText("合上");
}
else
{
text.text = StringStore.TranslateText(text.text);
}
text.font = font;
}
}
}
}

View file

@ -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<Transform> children = levels.GetComponentsInChildren<Transform>(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<TextMeshProUGUI>())
{
// 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"));
}
}
}

View file

@ -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());
}
}
}
}

View file

@ -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>();
TextMeshProUGUI textShadow = __instance.transform.GetChild(1).GetComponent<TextMeshProUGUI>();
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<TextMeshProUGUI>())
{
// Convert and translate legacy Text components
Text[] textComponents = __instance.GetComponentsInChildren<Text>(true);
TextMeshProUGUI[] textMeshComponents = __instance.GetComponentsInChildren<TextMeshProUGUI>(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<TextMeshProUGUI>())
{
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>();
TextMeshProUGUI[] extraTexts = __instance.transform.GetChild(1).GetComponentsInChildren<TextMeshProUGUI>();
TextMeshProUGUI text = __instance.transform.GetChild(0).GetComponent<TextMeshProUGUI>();
TextMeshProUGUI[] extraTexts = __instance.transform.GetChild(1).GetComponentsInChildren<TextMeshProUGUI>();
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>();
TextMeshProUGUI textShadow = __instance.transform.GetChild(1).GetComponent<TextMeshProUGUI>();
else
{
TextMeshProUGUI text = __instance.transform.GetChild(0).GetComponent<TextMeshProUGUI>();
TextMeshProUGUI textShadow = __instance.transform.GetChild(1).GetComponent<TextMeshProUGUI>();
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) { }

View file

@ -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<TextMeshProUGUI>())
{
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);
}
}
}
}

View file

@ -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<TextMeshProUGUI>();
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;
}
}
}
}

View file

@ -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<TextMeshPro>();
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<TextMeshPro>();
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<TextMeshPro>();
shadowText.text = __instance.points.text;
}
}
}
}

View file

@ -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<TextMeshProUGUI>();
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>();
TextMeshProUGUI contentText = contentObject.GetComponent<TextMeshProUGUI>();
contentText.text = changelogText;
ContentSizeFitter sizeFitter = contentObject.AddComponent<ContentSizeFitter>();

View file

@ -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<TextMeshProUGUI>())
{
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<TextMeshProUGUI>())
{
text.text = StringStore.TranslateText(text.text);
text.font = fontAsset;
}
}
}
}

View file

@ -41,6 +41,18 @@ namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects
List<string> 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<TextMeshProUGUI>())
{

View file

@ -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<TextMeshPro>();
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<TextMeshPro>().text);
//Log.LogInfo($"Info: {__instance.info.GetComponent<TextMeshPro>().text}");
FileLoader.DumpUntranslatedStrings(__instance.zombieName.GetComponent<TextMeshPro>().text);
//Log.LogInfo($"Zombie Name: {__instance.zombieName.GetComponent<TextMeshPro>().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>();
TextMeshPro component2 = __instance.zombieName.GetComponent<TextMeshPro>();
TextMeshPro component3 = __instance.zombieName.transform.GetChild(0).GetComponent<TextMeshPro>();
TextMeshPro component = __instance.info.GetComponent<TextMeshPro>();
TextMeshPro component2 = __instance.zombieName.GetComponent<TextMeshPro>();
TextMeshPro component3 = __instance.zombieName.transform.GetChild(0).GetComponent<TextMeshPro>();
try
{
AlmanacMgrZombie.ZombieAlmanacData zombieData = JsonUtility.FromJson<AlmanacMgrZombie.ZombieAlmanacData>(json);
ZombieAlmanacData zombieData = JsonUtility.FromJson<ZombieAlmanacData>(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<AlmanacMgrZombie.ZombieAlmanacData>(moddedJson);
ZombieAlmanacData moddedZombieData = JsonUtility.FromJson<ZombieAlmanacData>(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<TextMeshPro>();
if (component != null)
{
component.pageToDisplay = component.pageToDisplay > component.m_pageNumber ? 1 : component.pageToDisplay + 1;
return false;
}
return true;
}
}
[Serializable]
public class ZombieAlmanacData
{
public List<ZombieInfo> zombies;
}
[Serializable]
public class ZombieInfo
{
public string name;
public string info;
public string introduce;
public ZombieType theZombieType;
}
}

View file

@ -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<TextMeshPro>();
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<TextMeshPro>().text);
//Log.LogInfo($"Info: {__instance.introduce.GetComponent<TextMeshPro>().text}");
FileLoader.DumpUntranslatedStrings(__instance.plantName.GetComponent<TextMeshPro>().text);
//Log.LogInfo($"PlantName Name: {__instance.plantName.GetComponent<TextMeshPro>().text}");
//Log.LogInfo($"PlantShadow Name: {__instance.plantName.transform.GetChild(0).GetComponent<TextMeshPro>().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>();
TextMeshPro component3 = __instance.plantName.transform.GetChild(0).GetComponent<TextMeshPro>();
TextMeshPro component4 = __instance.cost.GetComponent<TextMeshPro>();
TextMeshPro component5 = __instance.introduce.GetComponentInChildren<TextMeshPro>();
#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<AlmanacPlantBank.PlantData>(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<AlmanacPlantBank.PlantData>(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<TextMeshPro>();
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<TextMeshPro>();
if (component != null)
{
component.autoSizeTextContainer = false;
}
Transform banTransform = __instance.transform.FindChild("Ban").GetChild(0);
if (banTransform != null)
{
TextMeshPro banText = banTransform.GetComponent<TextMeshPro>();
string originalBanText = banText.text;
banText.text = StringStore.TranslateText(banText.text);
banTransform.GetComponent<TextMeshPro>().text = StringStore.TranslateText(banTransform.GetComponent<TextMeshPro>().text);
}
}

View file

@ -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<TMP_InputField>(out TMP_InputField field))
{
__instance.MusicUpdate();
return false;
}
}
return true;
}
}
}

View file

@ -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<TextMeshProUGUI>(),
__instance.transform.GetChild(0).GetChild(0).GetComponent<TextMeshProUGUI>(),
];
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<TextMeshProUGUI>(),
__instance.transform.GetChild(0).GetChild(0).GetComponent<TextMeshProUGUI>(),
];
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", " ");
}
}
}

View file

@ -13,7 +13,7 @@
https://nuget.samboy.dev/v3/index.json
</RestoreAdditionalProjectSources>
<RootNamespace>PvZ_Fusion_Translator__BepInEx_</RootNamespace>
<GamePath>C:\Users\rainb\Desktop\PC_PVZ-Fusion_3.1.1-BepInEx</GamePath>
<GamePath>D:\PvZ Fusion\BepInEx Game Files</GamePath>
<GamePathMelon>C:\Users\rainb\Desktop\PC_PVZ-Fusion_3.1.1</GamePathMelon>
<Configurations>Debug;DebugEnglish;ReleaseMulti;ReleaseEnglish;DebugTesting;ReleaseOther;DebugObfuscate;ReleaseObfuscate;DebugMulti</Configurations>
<Platforms>AnyCPU;x64</Platforms>
@ -130,6 +130,11 @@
<Compile Include="Patches\GameObjects\AbyssMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\AbyssSettlementMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\AbyssStoreMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\AlmanacPlantMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\AlmanacPlantWindow_Patch.cs" />
<Compile Include="Patches\GameObjects\AlmanacZombieMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\AlmanacZombieWindow_Patch.cs" />
<Compile Include="Patches\GameObjects\Almanac_Patch.cs" />
<Compile Include="Patches\GameObjects\BaseMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\Board_Patch.cs" />
<Compile Include="Patches\GameObjects\ButtonObjects\AbyssBuffButton_Patch.cs" />
@ -152,6 +157,8 @@
<Compile Include="Patches\GameObjects\CrisisZombieWindow_Patch.cs" />
<Compile Include="Patches\GameObjects\CustomSettings_Patch.cs" />
<Compile Include="Patches\GameObjects\CustomSun_Patch.cs" />
<Compile Include="Patches\GameObjects\EveBuffMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\EveOptionWindow_Patch.cs" />
<Compile Include="Patches\GameObjects\ExploreEnterWindow_Patch.cs" />
<Compile Include="Patches\GameObjects\ExploreMakeMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\ExploreMenu_Patch.cs" />
@ -161,6 +168,7 @@
<Compile Include="Patches\GameObjects\GardenPlant_Patch.cs" />
<Compile Include="Patches\GameObjects\MainMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\MinorObjects\AbyssGoods_Patch.cs" />
<Compile Include="Patches\GameObjects\MinorObjects\Brain_Patch.cs" />
<Compile Include="Patches\GameObjects\MinorObjects\DY_Patch.cs" />
<Compile Include="Patches\GameObjects\MinorObjects\Jigsaw_Patch.cs" />
<Compile Include="Patches\GameObjects\MinorObjects\LanternUmbrella_Patch.cs" />
@ -176,6 +184,7 @@
<Compile Include="Patches\GameObjects\MinorObjects\Zombie_Patch.cs" />
<Compile Include="Patches\GameObjects\NoticePauseMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\OtherMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\PlantDamageMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\PlantInfoWindow_Patch.cs" />
<Compile Include="Patches\GameObjects\PlayerShootingMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\PlayerShootingWindow_Patch.cs" />
@ -593,7 +602,7 @@
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="COPY &quot;$(TargetPath)&quot; &quot;$(GamePath)\BepInEx\plugins&quot;" />
<Exec Command="COPY &quot;$(TargetPath)&quot; &quot;$(GamePathMelon)\Translation Builds\&quot;" />
<!--<Exec Command="COPY &quot;$(TargetPath)&quot; &quot;$(GamePathMelon)\Translation Builds\&quot;" />-->
</Target>
</Project>

View file

@ -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<int, List<int>> recipeLinks = new Dictionary<int, List<int>>();
public static void RegisterRecipeLinks()
{
recipeLinks.Clear();
Il2CppSystem.Array mixData = MixData.data.Cast<Il2CppSystem.Array>();
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<int>(), mixData.GetValue((int)checkType, seedType).Unbox<int>()];
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, @"<size=[^>]+>", string.Empty, RegexOptions.IgnoreCase);
string withoutCloseTags = Regex.Replace(withoutOpenTags, @"</size>", 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<AlmanacMgrZombie.ZombieAlmanacData>(json);
ZombieAlmanacData zombieData = JsonUtility.FromJson<ZombieAlmanacData>(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}+");