Sync MelonLoader from origin/main (keep BepInEx changes)

This commit is contained in:
TuanAnh2901 2025-12-23 17:59:18 +07:00
parent fdf4bd8e5b
commit e36fad45ca
22 changed files with 768 additions and 437 deletions

View file

@ -1,6 +1,7 @@
using HarmonyLib; using HarmonyLib;
using Il2CppTMPro; using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore; using PvZ_Fusion_Translator.AssetStore;
using UnityEngine;
namespace PvZ_Fusion_Translator.Patches.BaseTextObjects namespace PvZ_Fusion_Translator.Patches.BaseTextObjects
{ {

View file

@ -0,0 +1,163 @@
using HarmonyLib;
using Il2Cpp;
using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore;
using System.Text.RegularExpressions;
using Unity.Collections;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;
using static PvZ_Fusion_Translator.FileLoader;
using static PvZ_Fusion_Translator.Utils;
namespace PvZ_Fusion_Translator.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("搜索"))
{
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);
AlmanacPlantBank.PlantData plantData = JsonUtility.FromJson<AlmanacPlantBank.PlantData>(json);
Il2CppSystem.Collections.Generic.List<PlantType> searchedPlants = new();
foreach (AlmanacPlantBank.PlantInfo plantInfo in plantData.plants)
{
//List<int> uniqueIngredients = GetIngredients(plantInfo.seedType);
//// ingredient-based search
//foreach(int i in uniqueIngredients)
//{
// string name = Utils.GetPlantNameFromAlmanac((PlantType)i);
// if(name.ToLower().Contains(search.ToLower()))
// {
// searchedPlants.Add((PlantType)i);
// }
//}
// keyword-based search
// name-based search
if (plantInfo.name.ToLower().Contains(search.ToLower()))
{
searchedPlants.Add((PlantType)plantInfo.seedType);
}
}
__instance.ShowPlants(searchedPlants);
return false;
}
return true;
}
private static List<int> GetIngredients(int theSeedType)
{
List<int> ingredientPairs = new();
Il2CppSystem.Array mixData = MixData.data.Cast<Il2CppSystem.Array>();
int rows = mixData.GetLength(0);
int columns = mixData.GetLength(1);
for(int i = 0; i < rows; i++)
{
for(int j = 0; j < columns; j++)
{
if(ContainsFormula(theSeedType))
{
if (mixData.GetValue(i, j).Unbox<int>() == theSeedType)
{
if (!ingredientPairs.Contains(i))
{
ingredientPairs.Add(i);
}
if (!ingredientPairs.Contains(j))
{
ingredientPairs.Add(j);
}
}
}
else
{
return ingredientPairs;
}
}
}
return ingredientPairs;
}
private static bool ContainsFormula(int theSeedType)
{
bool contains = false;
Il2CppSystem.Array mixData = MixData.data.Cast<Il2CppSystem.Array>();
int rows = mixData.GetLength(0);
int columns = mixData.GetLength(1);
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
if (mixData.GetValue(i, j).Unbox<int>() == theSeedType)
{
contains = true;
return contains;
}
}
}
return contains;
}
}
}

View file

@ -0,0 +1,68 @@
using HarmonyLib;
using Il2Cpp;
using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore;
using System.Text.RegularExpressions;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;
using static PvZ_Fusion_Translator.FileLoader;
namespace PvZ_Fusion_Translator.Patches.GameObjects
{
[HarmonyPatch(typeof(AlmanacPlantWindow))]
public static class AlmanacPlantWindow_Patch
{
[HarmonyPatch(nameof(AlmanacPlantWindow.UpdateText))]
[HarmonyPostfix]
private static void UpdateText(AlmanacPlantWindow __instance)
{
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);
bool hasAlmanacFont = false;
TMP_FontAsset almanacFontAsset = null;
if (FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage + "_Almanac") || FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage))
{
almanacFontAsset = FontStore.LoadTMPFontAlmanac(currentLanguage);
hasAlmanacFont = true;
}
TMP_FontAsset fontAsset = (hasAlmanacFont) ? FontStore.LoadTMPFontAlmanac(Utils.Language.ToString()) : FontStore.LoadTMPFont(Utils.Language.ToString());
AlmanacPlantBank.PlantData plantData = JsonUtility.FromJson<AlmanacPlantBank.PlantData>(json);
foreach (AlmanacPlantBank.PlantInfo plantInfo in plantData.plants)
{
if (plantInfo.seedType == (int)__instance.currentPlantType)
{
foreach (TextMeshProUGUI text in __instance.showedPlantName)
{
text.autoSizeTextContainer = false;
text.text = $"{Utils.RemoveSizeTags(plantInfo.name)} ({plantInfo.seedType})";
text.font = fontAsset;
text.fontSizeMax = 21;
}
__instance.showedPlantIntroduce.text = Utils.RemoveSizeTags(plantInfo.info) + "\n\n" + Utils.RemoveSizeTags(plantInfo.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();
float textHeight = __instance.showedPlantIntroduce.preferredHeight;
__instance.plantTextContent.sizeDelta = new Vector2(__instance.plantTextContent.sizeDelta.x, textHeight);
}
}
}
}
}

View file

@ -0,0 +1,34 @@
using HarmonyLib;
using Il2Cpp;
using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore;
using System.Text.RegularExpressions;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;
using static PvZ_Fusion_Translator.FileLoader;
using static PvZ_Fusion_Translator.Utils;
namespace PvZ_Fusion_Translator.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,68 @@
using HarmonyLib;
using Il2Cpp;
using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore;
using System.Text.RegularExpressions;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;
using static PvZ_Fusion_Translator.FileLoader;
namespace PvZ_Fusion_Translator.Patches.GameObjects
{
[HarmonyPatch(typeof(AlmanacZombieWindow))]
public static class AlmanacZombieWindow_Patch
{
[HarmonyPatch(nameof(AlmanacZombieWindow.UpdateText))]
[HarmonyPostfix]
private static void UpdateText(AlmanacZombieWindow __instance)
{
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");
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;
}
TMP_FontAsset fontAsset = (hasAlmanacFont) ? FontStore.LoadTMPFontAlmanac(Utils.Language.ToString()) : FontStore.LoadTMPFont(Utils.Language.ToString());
ZombieAlmanacData zombieData = JsonUtility.FromJson<ZombieAlmanacData>(json);
foreach (ZombieInfo zombieInfo in zombieData.zombies)
{
if (zombieInfo.theZombieType == __instance.currentZombieType)
{
foreach (TextMeshProUGUI text in __instance.showedZombieName)
{
text.autoSizeTextContainer = false;
text.text = $"{Utils.RemoveSizeTags(zombieInfo.name)} ({(int)zombieInfo.theZombieType})";
text.font = fontAsset;
text.fontSizeMax = 21;
}
__instance.showedZombieIntroduce.text = Utils.RemoveSizeTags(zombieInfo.info) + "\n\n" + Utils.RemoveSizeTags(zombieInfo.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();
float textHeight = __instance.showedZombieIntroduce.preferredHeight;
__instance.zombieTextContent.sizeDelta = new Vector2(__instance.zombieTextContent.sizeDelta.x, textHeight);
}
}
}
}
}

View file

@ -0,0 +1,52 @@
using HarmonyLib;
using Il2Cpp;
using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore;
using UnityEngine;
using System.Text.RegularExpressions;
using Unity.VisualScripting;
namespace PvZ_Fusion_Translator.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

@ -3,6 +3,7 @@ using Il2Cpp;
using Il2CppTMPro; using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore; using PvZ_Fusion_Translator.AssetStore;
using UnityEngine; using UnityEngine;
using static MelonLoader.MelonLogger;
namespace PvZ_Fusion_Translator.Patches.GameObjects namespace PvZ_Fusion_Translator.Patches.GameObjects
{ {
@ -13,112 +14,27 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
[HarmonyPostfix] [HarmonyPostfix]
private static void Awake(BaseMenu __instance) private static void Awake(BaseMenu __instance)
{ {
Transform mainTransform = __instance.transform; TranslateBaseMenu(__instance, "Level");
if (mainTransform != null) 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")); List<Transform> children = levels.GetComponentsInChildren<Transform>(true).ToList();
StringStore.TranslateTextTransform(mainTransform.Find("Switich")); foreach (Transform child in children)
Transform levelTransform = mainTransform.Find("Level");
if (levelTransform != null)
{ {
StringStore.TranslateTextTransform(levelTransform.Find("Nextpage")); if (child.name == "Nextpage" || child.name == "LastPage" || child.name == "BackToIndex")
StringStore.TranslateTextTransform(levelTransform.Find("LastPage")); {
StringStore.TranslateTextTransform(child);
}
} }
Transform customLevelTransform = mainTransform.Find("CustomLevel"); StringStore.TranslateTextTransform(__instance.transform.Find("Goback"));
if (customLevelTransform != null) StringStore.TranslateTextTransform(__instance.transform.Find("Switich"));
{
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"));
}
foreach (TextMeshProUGUI txt in mainTransform.GetComponentsInChildren<TextMeshProUGUI>())
{
txt.text = StringStore.TranslateText(txt.text);
}
}
} }
} }
} }

View file

@ -0,0 +1,19 @@
using HarmonyLib;
using Il2Cpp;
using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore;
using UnityEngine;
namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects
{
//[HarmonyPatch(typeof(BackToIndex))]
//public class BackToIndex_Patch
// {
// [HarmonyPostfix]
// [HarmonyPatch(nameof(BackToIndex.Awake))]
// public static void Awake(BackToIndex __instance)
// {
// StringStore.TranslateTextTransform(__instance.transform.GetChild(0));
// }
//}
}

View file

@ -13,8 +13,8 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects
[HarmonyPatch(nameof(ExploreMakeZombieButton.Start))] [HarmonyPatch(nameof(ExploreMakeZombieButton.Start))]
public static void Start(ExploreMakeZombieButton __instance) public static void Start(ExploreMakeZombieButton __instance)
{ {
__instance.sceneText.text = Utils.GetZombieNameFromAlmanac(__instance.theZombieType); //__instance.sceneText.text = Utils.GetZombieNameFromAlmanac(__instance.theZombieType);
__instance.sceneText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); //__instance.sceneText.font = FontStore.LoadTMPFont(Utils.Language.ToString());
} }
} }
} }

View file

@ -13,11 +13,14 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects
[HarmonyPatch(nameof(NormalBtn.OnMouseUpAsButton))] [HarmonyPatch(nameof(NormalBtn.OnMouseUpAsButton))]
public static void OnMouseUpAsButton(NormalBtn __instance) public static void OnMouseUpAsButton(NormalBtn __instance)
{ {
Transform banTransform = __instance.transform.GetChild(0); if(__instance.transform.childCount > 0)
if (banTransform != null)
{ {
banTransform.GetComponent<TextMeshPro>().text = StringStore.TranslateText(banTransform.GetComponent<TextMeshPro>().text); Transform banTransform = __instance.transform.GetChild(0);
} if (banTransform != null)
{
banTransform.GetComponent<TextMeshPro>().text = StringStore.TranslateText(banTransform.GetComponent<TextMeshPro>().text);
}
}
} }
} }
} }

View file

@ -0,0 +1,23 @@
//using HarmonyLib;
//using Il2Cpp;
//using Il2CppTMPro;
//using PvZ_Fusion_Translator.AssetStore;
//using UnityEngine;
//using UnityEngine.UI;
//namespace PvZ_Fusion_Translator.Patches.GameObjects
//{
// [HarmonyPatch(typeof(UIBtn))]
// public static class UIBtn_Patch
// {
// [HarmonyPatch(nameof(UIBtn.Awake))]
// [HarmonyPostfix]
// private static void Postfix_Awake(UIBtn __instance)
// {
// if(__instance.TryGetComponent<BackToIndex>(out BackToIndex component))
// {
// Utils.ConvertButtonText(__instance.transform.parent, component.name);
// }
// }
// }
//}

View file

@ -4,96 +4,42 @@ using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore; using PvZ_Fusion_Translator.AssetStore;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using UnityEngine.UIElements;
namespace PvZ_Fusion_Translator.Patches.GameObjects namespace PvZ_Fusion_Translator.Patches.GameObjects
{ {
[HarmonyPatch(typeof(UIButton))] [HarmonyPatch(typeof(UIButton))]
public static class UIButton_Patch public static class UIButton_Patch
{ {
[HarmonyPatch(nameof(UIButton.Start))] [HarmonyPatch(typeof(UIButton), nameof(UIButton.Start))]
[HarmonyPostfix] [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 TMP_FontAsset font = FontStore.LoadTMPFont(Utils.Language.ToString());
if (__instance.transform.childCount >= 2)
{
TextMeshProUGUI text = __instance.transform.GetChild(0).GetComponent<TextMeshProUGUI>();
TextMeshProUGUI textShadow = __instance.transform.GetChild(1).GetComponent<TextMeshProUGUI>();
text.text = StringStore.TranslateText(text.text, false); foreach (TextMeshProUGUI text in __instance.transform.GetComponentsInChildren<TextMeshProUGUI>())
textShadow.text = StringStore.TranslateText(textShadow.text, false);
text.font = FontStore.LoadTMPFont(Utils.Language.ToString());
textShadow.font = FontStore.LoadTMPFont(Utils.Language.ToString());
}
else
{ {
// Convert and translate legacy Text components if (__instance.transform.name == "Goback")
Text[] textComponents = __instance.GetComponentsInChildren<Text>(true);
TextMeshProUGUI[] textMeshComponents = __instance.GetComponentsInChildren<TextMeshProUGUI>(true);
foreach (Text textComponent in textComponents)
{ {
if (textComponent != null && !string.IsNullOrEmpty(textComponent.text)) text.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 = StringStore.TranslateText(text.text);
text.font = font;
} }
} }
catch (Exception) { } else
}
[HarmonyPatch(nameof(UIButton.OnMouseUpAsButton))]
[HarmonyPostfix]
public static void Postfix_OnMouseUpAsButton(UIButton __instance)
{
try
{ {
if (__instance.transform.childCount >= 2) StringStore.TranslateTextTransform(__instance.transform);
if(__instance.transform.name == "Goback")
{ {
if(__instance.name == "EditMode") foreach(TextMeshProUGUI text in __instance.transform.GetComponentsInChildren<TextMeshProUGUI>())
{ {
TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); text.text = StringStore.TranslateText("合上");
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;
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>();
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());
} }
} }
} }
catch (Exception) { }
} }
} }
} }

View file

@ -14,7 +14,7 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
[HarmonyPatch(nameof(NoticeMenu.Awake))] [HarmonyPatch(nameof(NoticeMenu.Awake))]
private static void Pre_Awake(NoticeMenu __instance) 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>(); TextMeshProUGUI contentText = contentObject.GetComponent<TextMeshProUGUI>();
File.WriteAllText(Path.Combine(FileLoader.GetAssetDir(FileLoader.AssetType.Dumps), "changelog.txt"), contentText.text); File.WriteAllText(Path.Combine(FileLoader.GetAssetDir(FileLoader.AssetType.Dumps), "changelog.txt"), contentText.text);

View file

@ -4,6 +4,7 @@ using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore; using PvZ_Fusion_Translator.AssetStore;
using static PvZ_Fusion_Translator.Patches.Managers.TravelMgr_Patch; using static PvZ_Fusion_Translator.Patches.Managers.TravelMgr_Patch;
using UnityEngine; using UnityEngine;
using MelonLoader;
namespace PvZ_Fusion_Translator.Patches.GameObjects namespace PvZ_Fusion_Translator.Patches.GameObjects
{ {
@ -16,7 +17,9 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
{ {
foreach (TravelBuffOptionButton button in __instance.options) foreach (TravelBuffOptionButton button in __instance.options)
{ {
button.introduce.text = translatedTravelBuffs[buffLinks[button.buffType]][button.buffIndex]; List<string> buffSet = translatedTravelBuffs[buffLinks[button.buffType]];
string buffText = (button.buffIndex < buffSet.Count && button.show != null) ? buffSet[button.buffIndex] : StringStore.TranslateText(button.introduce.text);
button.introduce.text = buffText;
} }
} }
} }

View file

@ -1,6 +1,7 @@
using HarmonyLib; using HarmonyLib;
using Il2Cpp; using Il2Cpp;
using Il2CppTMPro; using Il2CppTMPro;
using MelonLoader;
using PvZ_Fusion_Translator.AssetStore; using PvZ_Fusion_Translator.AssetStore;
using static PvZ_Fusion_Translator.Patches.Managers.TravelMgr_Patch; using static PvZ_Fusion_Translator.Patches.Managers.TravelMgr_Patch;
@ -14,8 +15,8 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
private static void SetBuff(TravelBuffOptionButton __instance) private static void SetBuff(TravelBuffOptionButton __instance)
{ {
List<string> buffSet = translatedTravelBuffs[buffLinks[__instance.buffType]]; List<string> buffSet = translatedTravelBuffs[buffLinks[__instance.buffType]];
string buffText = (__instance.buffIndex < buffSet.Count) ? buffSet[__instance.buffIndex] : StringStore.TranslateText(__instance.introduce.text); string buffText = (__instance.buffIndex < buffSet.Count && __instance.show != null) ? buffSet[__instance.buffIndex] : StringStore.TranslateText(__instance.introduce.text);
__instance.introduce.text = buffText;
} }
[HarmonyPatch(nameof(TravelBuffOptionButton.Awake))] [HarmonyPatch(nameof(TravelBuffOptionButton.Awake))]
@ -23,8 +24,8 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
private static void Awake(TravelBuffOptionButton __instance) private static void Awake(TravelBuffOptionButton __instance)
{ {
List<string> buffSet = translatedTravelBuffs[buffLinks[__instance.buffType]]; List<string> buffSet = translatedTravelBuffs[buffLinks[__instance.buffType]];
string buffText = (__instance.buffIndex < buffSet.Count) ? buffSet[__instance.buffIndex] : StringStore.TranslateText(__instance.introduce.text); string buffText = (__instance.buffIndex < buffSet.Count && __instance.show != null) ? buffSet[__instance.buffIndex] : StringStore.TranslateText(__instance.introduce.text);
__instance.introduce.text = buffText;
} }
[HarmonyPatch(nameof(TravelBuffOptionButton.OnAnimOver))] [HarmonyPatch(nameof(TravelBuffOptionButton.OnAnimOver))]
@ -32,8 +33,8 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
private static void OnAnimOver(TravelBuffOptionButton __instance) private static void OnAnimOver(TravelBuffOptionButton __instance)
{ {
List<string> buffSet = translatedTravelBuffs[buffLinks[__instance.buffType]]; List<string> buffSet = translatedTravelBuffs[buffLinks[__instance.buffType]];
string buffText = (__instance.buffIndex < buffSet.Count) ? buffSet[__instance.buffIndex] : StringStore.TranslateText(__instance.introduce.text); string buffText = (__instance.buffIndex < buffSet.Count && __instance.show != null) ? buffSet[__instance.buffIndex] : StringStore.TranslateText(__instance.introduce.text);
__instance.introduce.text = buffText;
} }
} }
} }

View file

@ -19,7 +19,7 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
if(__instance.currentSelect != null) if(__instance.currentSelect != null)
{ {
var buffList = translatedTravelBuffs[buffLinks[(BuffType)__instance.currentSelect.theBuffType]]; var buffList = translatedTravelBuffs[buffLinks[(BuffType)__instance.currentSelect.theBuffType]];
if(__instance.currentSelect.theBuffNumber < buffList.Count) if(__instance.currentSelect.theBuffNumber < buffList.Count && __instance.currentSelect.theBuffNumber > -1)
{ {
text.text = buffList[__instance.currentSelect.theBuffNumber]; text.text = buffList[__instance.currentSelect.theBuffNumber];
} }
@ -50,7 +50,15 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
{ {
if (__instance.currentSelect != null) if (__instance.currentSelect != null)
{ {
text.text = translatedTravelBuffs[buffLinks[(BuffType)__instance.currentSelect.theBuffType]][__instance.currentSelect.theBuffNumber]; var buffList = translatedTravelBuffs[buffLinks[(BuffType)__instance.currentSelect.theBuffType]];
if (__instance.currentSelect.theBuffNumber < buffList.Count && __instance.currentSelect.theBuffNumber > -1)
{
text.text = buffList[__instance.currentSelect.theBuffNumber];
}
else
{
text.text = StringStore.TranslateText(text.text);
}
} }
} }
foreach (var textMesh in __instance.points) foreach (var textMesh in __instance.points)

View file

@ -14,13 +14,13 @@ namespace PvZ_Fusion_Translator.Patches.Managers
[HarmonyPostfix] [HarmonyPostfix]
private static void InitNameAndInfoFromJson(AlmanacMgrZombie __instance) private static void InitNameAndInfoFromJson(AlmanacMgrZombie __instance)
{ {
#if MULTI_LANGUAGE #if MULTI_LANGUAGE
string currentLanguage = Utils.Language.ToString(); string currentLanguage = Utils.Language.ToString();
string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language);
#else #else
string almanacDir = almanacDir = GetAssetDir(AssetType.Almanac); string almanacDir = almanacDir = GetAssetDir(AssetType.Almanac);
string currentLanguage = "English"; string currentLanguage = "English";
#endif #endif
string path = Path.Combine(almanacDir, "ZombieStringsTranslate.json"); string path = Path.Combine(almanacDir, "ZombieStringsTranslate.json");
string moddedPath = Path.Combine(almanacDir, "ModdedZombiesTranslate.json"); string moddedPath = Path.Combine(almanacDir, "ModdedZombiesTranslate.json");
@ -30,13 +30,13 @@ namespace PvZ_Fusion_Translator.Patches.Managers
return; return;
} }
#if OBFUSCATE #if OBFUSCATE
if (CheckSumStore.IsModified(path)) if (CheckSumStore.IsModified(path))
{ {
Log.LogError("File {0} was modified!", path); Log.LogError("File {0} was modified!", path);
return; return;
} }
#endif #endif
string json; string json;
json = File.ReadAllText(path); json = File.ReadAllText(path);
@ -49,19 +49,19 @@ namespace PvZ_Fusion_Translator.Patches.Managers
hasAlmanacFont = true; hasAlmanacFont = true;
} }
#if MULTI_LANGUAGE #if MULTI_LANGUAGE
TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage);
#else #else
TMP_FontAsset fontAsset = FontStore.LoadTMPFont(); TMP_FontAsset fontAsset = FontStore.LoadTMPFont();
#endif #endif
TextMeshPro component = __instance.info.GetComponent<TextMeshPro>(); TextMeshPro component = __instance.info.GetComponent<TextMeshPro>();
TextMeshPro component2 = __instance.zombieName.GetComponent<TextMeshPro>(); TextMeshPro component2 = __instance.zombieName.GetComponent<TextMeshPro>();
TextMeshPro component3 = __instance.zombieName.transform.GetChild(0).GetComponent<TextMeshPro>(); TextMeshPro component3 = __instance.zombieName.transform.GetChild(0).GetComponent<TextMeshPro>();
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 (zombieInfo.theZombieType == __instance.theZombieType) if (zombieInfo.theZombieType == __instance.theZombieType)
{ {
@ -86,9 +86,9 @@ namespace PvZ_Fusion_Translator.Patches.Managers
string moddedJson; string moddedJson;
moddedJson = File.ReadAllText(moddedPath); moddedJson = File.ReadAllText(moddedPath);
AlmanacMgrZombie.ZombieAlmanacData moddedZombieData = JsonUtility.FromJson<AlmanacMgrZombie.ZombieAlmanacData>(moddedJson); ZombieAlmanacData moddedZombieData = JsonUtility.FromJson<ZombieAlmanacData>(moddedJson);
foreach (AlmanacMgrZombie.ZombieInfo zombieInfo in moddedZombieData.zombies) foreach (ZombieInfo zombieInfo in moddedZombieData.zombies)
{ {
if (zombieInfo.theZombieType == __instance.theZombieType) if (zombieInfo.theZombieType == __instance.theZombieType)
{ {
@ -125,4 +125,4 @@ namespace PvZ_Fusion_Translator.Patches.Managers
return true; return true;
} }
} }
} }

View file

@ -7,170 +7,170 @@ using static PvZ_Fusion_Translator.FileLoader;
namespace PvZ_Fusion_Translator.Patches.Managers namespace PvZ_Fusion_Translator.Patches.Managers
{ {
[HarmonyPatch(typeof(AlmanacPlantBank))] [HarmonyPatch(typeof(AlmanacPlantBank))]
public static partial class AlmanacPlantBank_Patch public static partial class AlmanacPlantBank_Patch
{ {
[HarmonyPatch(nameof(AlmanacPlantBank.InitNameAndInfoFromJson))] [HarmonyPatch(nameof(AlmanacPlantBank.InitNameAndInfoFromJson))]
[HarmonyPostfix] [HarmonyPostfix]
private static void InitNameAndInfoFromJson(Il2Cpp.AlmanacPlantBank __instance) private static void InitNameAndInfoFromJson(Il2Cpp.AlmanacPlantBank __instance)
{ {
#if MULTI_LANGUAGE #if MULTI_LANGUAGE
string currentLanguage = Utils.Language.ToString(); string currentLanguage = Utils.Language.ToString();
string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language);
#else #else
string almanacDir = GetAssetDir(AssetType.Almanac); string almanacDir = GetAssetDir(AssetType.Almanac);
string currentLanguage = "English"; string currentLanguage = "English";
#endif #endif
string path = Path.Combine(almanacDir, "LawnStringsTranslate.json"); string path = Path.Combine(almanacDir, "LawnStringsTranslate.json");
string moddedPath = Path.Combine(almanacDir, "ModdedPlantsTranslate.json"); string moddedPath = Path.Combine(almanacDir, "ModdedPlantsTranslate.json");
if (!File.Exists(path)) if (!File.Exists(path))
{ {
Log.LogError($"LawnStringsTranslate.json file not found at path: {path}"); Log.LogError($"LawnStringsTranslate.json file not found at path: {path}");
return; return;
} }
#if OBFUSCATE #if OBFUSCATE
if (CheckSumStore.IsModified(path)) if (CheckSumStore.IsModified(path))
{ {
Log.LogError("File {0} was modified!", path); Log.LogError("File {0} was modified!", path);
return; return;
} }
#endif #endif
string json; string json;
json = File.ReadAllText(path); 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;
}
#if MULTI_LANGUAGE bool hasAlmanacFont = false;
TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); TMP_FontAsset almanacFontAsset = null;
#else 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);
#else
TMP_FontAsset fontAsset = FontStore.LoadTMPFont(); TMP_FontAsset fontAsset = FontStore.LoadTMPFont();
#endif #endif
TextMeshPro component = __instance.introduce.GetComponent<TextMeshPro>(); TextMeshPro component = __instance.introduce.GetComponent<TextMeshPro>();
TextMeshPro component2 = __instance.plantName.GetComponent<TextMeshPro>(); TextMeshPro component2 = __instance.plantName.GetComponent<TextMeshPro>();
TextMeshPro component3 = __instance.plantName.transform.GetChild(0).GetComponent<TextMeshPro>(); TextMeshPro component3 = __instance.plantName.transform.GetChild(0).GetComponent<TextMeshPro>();
TextMeshPro component4 = __instance.cost.GetComponent<TextMeshPro>(); TextMeshPro component4 = __instance.cost.GetComponent<TextMeshPro>();
AlmanacPlantBank.PlantData plantData = JsonUtility.FromJson<AlmanacPlantBank.PlantData>(json); AlmanacPlantBank.PlantData plantData = JsonUtility.FromJson<AlmanacPlantBank.PlantData>(json);
foreach (AlmanacPlantBank.PlantInfo plantInfo in plantData.plants) foreach (AlmanacPlantBank.PlantInfo plantInfo in plantData.plants)
{ {
if (plantInfo.seedType == __instance.theSeedType && !string.IsNullOrEmpty(plantInfo.name)) if (plantInfo.seedType == __instance.theSeedType && !string.IsNullOrEmpty(plantInfo.name))
{ {
component.autoSizeTextContainer = false; component.autoSizeTextContainer = false;
component.text = plantInfo.info + "\n\n" + plantInfo.introduce; component.text = plantInfo.info + "\n\n" + plantInfo.introduce;
component.overflowMode = TextOverflowModes.Page; component.overflowMode = TextOverflowModes.Page;
// fix dimensions for cost text // fix dimensions for cost text
component.rectTransform.offsetMax = new Vector2(component.rectTransform.offsetMax.x, 27.3839f); component.rectTransform.offsetMax = new Vector2(component.rectTransform.offsetMax.x, 27.3839f);
component.rectTransform.offsetMin = new Vector2(component.rectTransform.offsetMin.x, -29.3079f); component.rectTransform.offsetMin = new Vector2(component.rectTransform.offsetMin.x, -29.3079f);
component.rectTransform.sizeDelta = new Vector2(component.rectTransform.sizeDelta.x, 50.917f); 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); 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; component2.text = plantInfo.name;
component2.autoSizeTextContainer = true;
component3.text = Utils.RemoveColorTags(plantInfo.name ?? string.Empty); component3.text = Utils.RemoveColorTags(plantInfo.name ?? string.Empty);
component3.autoSizeTextContainer = true; component3.autoSizeTextContainer = true;
component4.text = plantInfo.cost; component4.text = plantInfo.cost;
if (hasAlmanacFont) if (hasAlmanacFont)
{ {
component.font = almanacFontAsset; component.font = almanacFontAsset;
component4.font = almanacFontAsset; component4.font = almanacFontAsset;
} }
else else
{ {
component.font = fontAsset; component.font = fontAsset;
component4.font = fontAsset; component4.font = fontAsset;
} }
component2.font = fontAsset; component2.font = fontAsset;
component3.font = fontAsset; component3.font = fontAsset;
} }
} }
if (File.Exists(moddedPath)) if (File.Exists(moddedPath))
{ {
string moddedJson; string moddedJson;
moddedJson = File.ReadAllText(moddedPath); moddedJson = File.ReadAllText(moddedPath);
AlmanacPlantBank.PlantData moddedPlantData = JsonUtility.FromJson<AlmanacPlantBank.PlantData>(moddedJson); AlmanacPlantBank.PlantData moddedPlantData = JsonUtility.FromJson<AlmanacPlantBank.PlantData>(moddedJson);
foreach (AlmanacPlantBank.PlantInfo plantInfo in moddedPlantData.plants) foreach (AlmanacPlantBank.PlantInfo plantInfo in moddedPlantData.plants)
{ {
if (plantInfo.seedType == __instance.theSeedType && !string.IsNullOrEmpty(plantInfo.name)) if (plantInfo.seedType == __instance.theSeedType && !string.IsNullOrEmpty(plantInfo.name))
{ {
component.autoSizeTextContainer = false; component.autoSizeTextContainer = false;
component.text = plantInfo.info + "\n\n" + plantInfo.introduce; component.text = plantInfo.info + "\n\n" + plantInfo.introduce;
component.overflowMode = TextOverflowModes.Page; component.overflowMode = TextOverflowModes.Page;
// fix dimensions for cost text // fix dimensions for cost text
component.rectTransform.offsetMax = new Vector2(component.rectTransform.offsetMax.x, 27.3839f); component.rectTransform.offsetMax = new Vector2(component.rectTransform.offsetMax.x, 27.3839f);
component.rectTransform.offsetMin = new Vector2(component.rectTransform.offsetMin.x, -29.3079f); component.rectTransform.offsetMin = new Vector2(component.rectTransform.offsetMin.x, -29.3079f);
component.rectTransform.sizeDelta = new Vector2(component.rectTransform.sizeDelta.x, 50.917f); 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); 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; component2.text = plantInfo.name;
component2.autoSizeTextContainer = true;
component3.text = Utils.RemoveColorTags(plantInfo.name ?? string.Empty); component3.text = Utils.RemoveColorTags(plantInfo.name ?? string.Empty);
component3.autoSizeTextContainer = true; component3.autoSizeTextContainer = true;
component4.text = plantInfo.cost; component4.text = plantInfo.cost;
if (hasAlmanacFont) if (hasAlmanacFont)
{ {
component.font = almanacFontAsset; component.font = almanacFontAsset;
component4.font = almanacFontAsset; component4.font = almanacFontAsset;
} }
else else
{ {
component.font = fontAsset; component.font = fontAsset;
component4.font = fontAsset; component4.font = fontAsset;
} }
component2.font = fontAsset; component2.font = fontAsset;
component3.font = fontAsset; component3.font = fontAsset;
} }
} }
} }
return; return;
} }
[HarmonyPatch(nameof(AlmanacPlantBank.OnMouseDown))] [HarmonyPatch(nameof(AlmanacPlantBank.OnMouseDown))]
[HarmonyPrefix] [HarmonyPrefix]
private static bool OnMouseDown(AlmanacPlantBank __instance) private static bool OnMouseDown(AlmanacPlantBank __instance)
{ {
TextMeshPro component = __instance.introduce.GetComponent<TextMeshPro>(); TextMeshPro component = __instance.introduce.GetComponent<TextMeshPro>();
if (component != null) if (component != null)
{ {
component.pageToDisplay = component.pageToDisplay > component.m_pageNumber ? 1 : component.pageToDisplay + 1; component.pageToDisplay = component.pageToDisplay > component.m_pageNumber ? 1 : component.pageToDisplay + 1;
return false; return false;
} }
return true; return true;
} }
[HarmonyPatch(nameof(AlmanacPlantBank.PVPInit))] [HarmonyPatch(nameof(AlmanacPlantBank.PVPInit))]
[HarmonyPostfix] [HarmonyPostfix]
private static void PVPInit(Il2Cpp.AlmanacPlantBank __instance) private static void PVPInit(Il2Cpp.AlmanacPlantBank __instance)
{ {
TextMeshPro component = __instance.introduce.GetComponent<TextMeshPro>(); TextMeshPro component = __instance.introduce.GetComponent<TextMeshPro>();
if (component != null) if (component != null)
{ {
component.autoSizeTextContainer = false; component.autoSizeTextContainer = false;
} }
Transform banTransform = __instance.transform.FindChild("Ban").GetChild(0); Transform banTransform = __instance.transform.FindChild("Ban").GetChild(0);
if (banTransform != null) if (banTransform != null)
@ -178,5 +178,23 @@ namespace PvZ_Fusion_Translator.Patches.Managers
banTransform.GetComponent<TextMeshPro>().text = StringStore.TranslateText(banTransform.GetComponent<TextMeshPro>().text); banTransform.GetComponent<TextMeshPro>().text = StringStore.TranslateText(banTransform.GetComponent<TextMeshPro>().text);
} }
} }
}
[HarmonyPatch(nameof(AlmanacPlantBank.Start))]
[HarmonyPostfix]
public static void Post_Start(AlmanacPlantBank __instance)
{
GameObject skinTextObj = __instance.skinButton.transform.GetChild(0).gameObject;
GameObject skinShadowTextObj = UnityEngine.Object.Instantiate(skinTextObj, parent: __instance.skinButton.transform);
TextMeshPro skinShadowText = skinShadowTextObj.GetComponent<TextMeshPro>();
skinShadowText.text = StringStore.TranslateText("换肤_S");
skinShadowText.sortingOrder -= 2;
skinShadowTextObj.transform.Translate(new Vector3(0.015f, -0.015f, 0));
skinTextObj.transform.Translate(new Vector3(-0.022f, 0));
skinShadowTextObj.transform.Translate(new Vector3(-0.022f, 0));
__instance.skinButton.transform.localScale /= 1.75f;
__instance.skinButton.transform.Translate(new Vector3(-0.075f, -0.15f, 0));
__instance.skinButton.transform.GetChild(1).Translate(new Vector3(0.35f, 0));
__instance.skinButton.transform.GetChild(2).Translate(new Vector3(-0.35f, 0));
}
}
} }

View file

@ -0,0 +1,28 @@
using HarmonyLib;
using Il2Cpp;
using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace PvZ_Fusion_Translator.Patches.Managers
{
[HarmonyPatch(typeof(GameAPP))]
public static class GameAPP_Patch
{
[HarmonyPatch(nameof(GameAPP.Update))]
[HarmonyPrefix]
private static bool Update(GameAPP __instance)
{
if(EventSystem.current.currentSelectedGameObject != null)
{
if (EventSystem.current.currentSelectedGameObject.TryGetComponent<TMP_InputField>(out TMP_InputField field))
{
__instance.MusicUpdate();
return false;
}
}
return true;
}
}
}

View file

@ -2,88 +2,47 @@
using Il2Cpp; using Il2Cpp;
using Il2CppTMPro; using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore; using PvZ_Fusion_Translator.AssetStore;
using System.Text.RegularExpressions;
using UnityEngine;
namespace PvZ_Fusion_Translator.Patches.Managers namespace PvZ_Fusion_Translator.Patches.Managers
{ {
[HarmonyPatch(typeof(OppositeBuffManager))] [HarmonyPatch(typeof(OppositeBuffManager))]
public static class OppositeBuffManager_Patch public static class OppositeBuffManager_Patch
{ {
#if TESTING public static Dictionary<BuffType, string> buffLinks = TravelMgr_Patch.buffLinks;
[HarmonyPatch(nameof(OppositeBuffManager.InitBuffPool))] public static Dictionary<string, List<string>> translatedTravelBuffs = TravelMgr_Patch.translatedTravelBuffs;
[HarmonyPostfix] public static string badPattern = @"^但(.*)";
private static void InitBuffPool(OppositeBuffManager __instance) public static string badFormat = StringStore.translationStringRegex.ContainsKey(badPattern) ? StringStore.translationStringRegex[badPattern] : "But, {0}";
{ public static TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString());
foreach(TextMeshProUGUI text in __instance.textA_bad)
{
string stripText = text.text.Replace("但", "");
string translatedText = StringStore.TranslateText(stripText);
string replacementText = StringStore.translationString["但"] + translatedText;
text.text = replacementText;
}
foreach(TextMeshProUGUI text in __instance.textA_good)
{
text.text = StringStore.TranslateText(text.text);
}
foreach(TextMeshProUGUI text in __instance.textB_bad) [HarmonyPatch(nameof(OppositeBuffManager.Awake))]
{ [HarmonyPostfix]
string stripText = text.text.Replace("但", ""); private static void Awake(OppositeBuffManager __instance)
string translatedText = StringStore.TranslateText(stripText); {
string replacementText = StringStore.translationString["但"] + translatedText; TranslateOppositeText(__instance.textA_bad, BuffType.Debuff, __instance.buffA.theDebuffID, true);
text.text = replacementText; TranslateOppositeText(__instance.textA_good, __instance.buffA.theOptionType, __instance.buffA.theOptionID);
} TranslateOppositeText(__instance.textB_bad, BuffType.Debuff, __instance.buffB.theDebuffID, true);
foreach(TextMeshProUGUI text in __instance.textB_good) TranslateOppositeText(__instance.textB_good, __instance.buffB.theOptionType, __instance.buffB.theOptionID);
{ }
text.text = StringStore.TranslateText(text.text);
}
}
[HarmonyPatch(nameof(OppositeBuffManager.SetText), new Type[] { typeof(TextMeshProUGUI), typeof(BuffType), typeof(int)})] public static void TranslateOppositeText(Il2CppSystem.Collections.Generic.List<TextMeshProUGUI> textList, BuffType buffType, int buffIndex, bool isBad = false)
[HarmonyPostfix] {
private static void SetText(OppositeBuffManager __instance) string buff = translatedTravelBuffs[buffLinks[buffType]][buffIndex];
{
foreach(TextMeshProUGUI text in __instance.textA_bad)
{
string stripText = text.text.Replace("但", "");
string translatedText = StringStore.TranslateText(stripText);
string replacementText = StringStore.translationString["但"] + translatedText;
text.text = replacementText;
}
foreach(TextMeshProUGUI text in __instance.textA_good)
{
text.text = StringStore.TranslateText(text.text);
}
foreach(TextMeshProUGUI text in __instance.textB_bad) foreach(var text in textList)
{ {
string stripText = text.text.Replace("但", ""); if(isBad)
string translatedText = StringStore.TranslateText(stripText); {
string replacementText = StringStore.translationString["但"] + translatedText; text.text = string.Format(badFormat, buff);
text.text = replacementText; }
} else
foreach(TextMeshProUGUI text in __instance.textB_good) {
{ text.text = buff;
text.text = StringStore.TranslateText(text.text); }
}
}
#endif
[HarmonyPatch(nameof(OppositeBuffManager.SetText), new Type[] { typeof(TextMeshProUGUI), typeof(BuffType), typeof(int)})] text.font = fontAsset;
[HarmonyPostfix] }
private static void SetText(OppositeBuffManager __instance, ref TextMeshProUGUI text) }
{ }
StringStore.TranslateTextUI(text);
}
[HarmonyPatch(nameof(OppositeBuffManager.Awake))]
[HarmonyPostfix]
private static void Awake(OppositeBuffManager __instance)
{
StringStore.TranslateTextUI(__instance.textA_bad[0]);
StringStore.TranslateTextUI(__instance.textA_bad[1]);
StringStore.TranslateTextUI(__instance.textB_bad[0]);
StringStore.TranslateTextUI(__instance.textB_bad[1]);
}
}
} }

View file

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
@ -13,7 +13,7 @@
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Configurations>Debug;DebugEnglish;ReleaseMulti;ReleaseEnglish;DebugTesting;ReleaseOther;DebugObfuscate;ReleaseObfuscate</Configurations> <Configurations>Debug;DebugEnglish;ReleaseMulti;ReleaseEnglish;DebugTesting;ReleaseOther;DebugObfuscate;ReleaseObfuscate</Configurations>
<GamePath>D:\PvZ Fusion\Game Files</GamePath> <GamePath>C:\Users\rainb\Desktop\PC_PVZ-Fusion_3.2.1</GamePath>
<Platforms>AnyCPU;ARM64;x64</Platforms> <Platforms>AnyCPU;ARM64;x64</Platforms>
</PropertyGroup> </PropertyGroup>
@ -401,8 +401,17 @@
<Compile Include="ModFeatures.cs" /> <Compile Include="ModFeatures.cs" />
<Compile Include="AssetStore\AudioStore.cs" /> <Compile Include="AssetStore\AudioStore.cs" />
<Compile Include="Patches\GameObjects\AbyssBuffMenu_Patch.cs" /> <Compile Include="Patches\GameObjects\AbyssBuffMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\AlmanacZombieWindow_Patch.cs" />
<Compile Include="Patches\GameObjects\AlmanacZombieMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\AlmanacPlantMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\AlmanacPlantWindow_Patch.cs" />
<Compile Include="Patches\GameObjects\Almanac_Patch.cs" />
<Compile Include="Patches\Managers\GameAPP_Patch.cs" />
<Compile Include="Patches\Managers\OppositeBuffManager_Patch.cs" />
<Compile Include="Patches\GameObjects\ButtonObjects\ExploreMakeSceneButton_Patch.cs" /> <Compile Include="Patches\GameObjects\ButtonObjects\ExploreMakeSceneButton_Patch.cs" />
<Compile Include="Patches\GameObjects\ButtonObjects\ExploreMakeZombieButton_Patch.cs" /> <Compile Include="Patches\GameObjects\ButtonObjects\ExploreMakeZombieButton_Patch.cs" />
<Compile Include="Patches\GameObjects\ButtonObjects\BackToIndex_Patch.cs" />
<Compile Include="Patches\GameObjects\ButtonObjects\UIBtn_Patch.cs" />
<Compile Include="Patches\GameObjects\ExploreMakeMenu_Patch.cs" /> <Compile Include="Patches\GameObjects\ExploreMakeMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\AbyssSelectBuffWindow_Patch.cs" /> <Compile Include="Patches\GameObjects\AbyssSelectBuffWindow_Patch.cs" />
<Compile Include="Patches\GameObjects\SpriteRenderer_Patch.cs" /> <Compile Include="Patches\GameObjects\SpriteRenderer_Patch.cs" />
@ -491,7 +500,6 @@
<Compile Include="Patches\Managers\InGameUI_Patch.cs" /> <Compile Include="Patches\Managers\InGameUI_Patch.cs" />
<Compile Include="Patches\Managers\IZBottomMenu_Patch.cs" /> <Compile Include="Patches\Managers\IZBottomMenu_Patch.cs" />
<Compile Include="Patches\OtherManagers\MenuText_Patch.cs" /> <Compile Include="Patches\OtherManagers\MenuText_Patch.cs" />
<Compile Include="Patches\Managers\OppositeBuffManager_Patch.cs" />
<Compile Include="Patches\GameObjects\ButtonObjects\OptionBtn_Patch.cs" /> <Compile Include="Patches\GameObjects\ButtonObjects\OptionBtn_Patch.cs" />
<Compile Include="Patches\GameObjects\ButtonObjects\OptLanguageBtn_Patch.cs" /> <Compile Include="Patches\GameObjects\ButtonObjects\OptLanguageBtn_Patch.cs" />
<Compile Include="Patches\GameObjects\ButtonObjects\PauseMenu_Btn_Patch.cs" /> <Compile Include="Patches\GameObjects\ButtonObjects\PauseMenu_Btn_Patch.cs" />
@ -521,5 +529,6 @@
<Target Name="PostBuild" AfterTargets="PostBuildEvent"> <Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="COPY &quot;$(TargetPath)&quot; &quot;$(GamePath)\Mods\&quot;" /> <Exec Command="COPY &quot;$(TargetPath)&quot; &quot;$(GamePath)\Mods\&quot;" />
<Exec Command="COPY &quot;$(TargetPath)&quot; &quot;$(GamePath)\Translation Builds\&quot;" /> <Exec Command="COPY &quot;$(TargetPath)&quot; &quot;$(GamePath)\Translation Builds\&quot;" />
<Exec Command="COPY &quot;$(TargetPath)&quot; &quot;C:\Users\rainb\Documents\GitHub\PVZF-Translation\&quot;" />
</Target> </Target>
</Project> </Project>

View file

@ -80,15 +80,27 @@ namespace PvZ_Fusion_Translator
Process.Start(new ProcessStartInfo(website) { UseShellExecute = true }); Process.Start(new ProcessStartInfo(website) { UseShellExecute = true });
} }
public static string RemoveColorTags(string text) public static string RemoveColorTags(string text)
{ {
if (string.IsNullOrEmpty(text)) if (string.IsNullOrEmpty(text))
return text ?? string.Empty; return text ?? string.Empty;
// Remove opening color tags like <color=#FF0000> // Remove opening color tags like <color=#FF0000>
string withoutOpenTags = Regex.Replace(text, @"<color=[^>]+>", string.Empty, RegexOptions.IgnoreCase); string withoutOpenTags = Regex.Replace(text, @"<color=[^>]+>", string.Empty, RegexOptions.IgnoreCase);
// Remove closing color tags like </color> // Remove closing color tags like </color>
string withoutCloseTags = Regex.Replace(withoutOpenTags, @"</color>", string.Empty, RegexOptions.IgnoreCase); string withoutCloseTags = Regex.Replace(withoutOpenTags, @"</color>", string.Empty, RegexOptions.IgnoreCase);
return withoutCloseTags;
}
public static string RemoveSizeTags(string text)
{
if (string.IsNullOrEmpty(text))
return text ?? string.Empty;
// Remove opening color tags like <color=#FF0000>
string withoutOpenTags = Regex.Replace(text, @"<size=[^>]+>", string.Empty, RegexOptions.IgnoreCase);
// Remove closing color tags like </color>
string withoutCloseTags = Regex.Replace(withoutOpenTags, @"</size>", string.Empty, RegexOptions.IgnoreCase);
return withoutCloseTags; return withoutCloseTags;
} }
@ -203,39 +215,39 @@ namespace PvZ_Fusion_Translator
return thePlantName; return thePlantName;
} }
public static string GetZombieNameFromAlmanac(ZombieType theZombieType) public static string GetZombieNameFromAlmanac(ZombieType theZombieType)
{ {
string json; string json;
string theZombieName = ""; string theZombieName = "";
string currentLanguage = Utils.Language.ToString(); string currentLanguage = Utils.Language.ToString();
string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language);
string path = Path.Combine(almanacDir, "ZombieStringsTranslate.json"); string path = Path.Combine(almanacDir, "ZombieStringsTranslate.json");
if (!File.Exists(path)) if (!File.Exists(path))
{ {
Log.LogError($"ZombieStringsTranslate.json file not found at path: {path}"); Log.LogError($"ZombieStringsTranslate.json file not found at path: {path}");
Log.LogError("Zombie name could not be found!"); Log.LogError("Zombie name could not be found!");
theZombieName = ""; theZombieName = "";
} }
else else
{ {
json = File.ReadAllText(path); 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) if ((int)zombieInfo.theZombieType == (int)theZombieType)
{ {
theZombieName = zombieInfo.name; theZombieName = zombieInfo.name;
} }
} }
} }
return theZombieName; return theZombieName;
} }
public static Dictionary<int, KeyValuePair<int, string>> plantIndices = new Dictionary<int, KeyValuePair<int, string>>(); public static Dictionary<int, KeyValuePair<int, string>> plantIndices = new Dictionary<int, KeyValuePair<int, string>>();
public static void RegisterPlantIndices() public static void RegisterPlantIndices()
{ {