diff --git a/.gitignore b/.gitignore index 2e74c83..b70a132 100644 --- a/.gitignore +++ b/.gitignore @@ -1,368 +1,11 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. -## -## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore - -# User-specific files -*.rsuser -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Mono auto generated files -mono_crash.* - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -[Ww][Ii][Nn]32/ -[Aa][Rr][Mm]/ -[Aa][Rr][Mm]64/ -bld/ -[Bb]in/ -[Oo]bj/ -[Oo]ut/ -[Ll]og/ -[Ll]ogs/ - -# Visual Studio 2015/2017 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# Visual Studio 2017 auto generated files -Generated\ Files/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUnit -*.VisualState.xml -TestResult.xml -nunit-*.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# Benchmark Results -BenchmarkDotNet.Artifacts/ - -# .NET Core -project.lock.json -project.fragment.lock.json -artifacts/ - -# ASP.NET Scaffolding -ScaffoldingReadMe.txt - -# StyleCop -StyleCopReport.xml - -# Files built by Visual Studio -*_i.c -*_p.c -*_h.h -*.ilk -*.meta -*.obj -*.iobj -*.pch -*.pdb -*.ipdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*_wpftmp.csproj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# Visual Studio Trace Files -*.e2e - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# AxoCover is a Code Coverage Tool -.axoCover/* -!.axoCover/settings.json - -# Coverlet is a free, cross platform Code Coverage Tool -coverage*.json -coverage*.xml -coverage*.info - -# Visual Studio code coverage results -*.coverage -*.coveragexml - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# Note: Comment the next line if you want to checkin your web deploy settings, -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# NuGet Symbol Packages -*.snupkg -# The packages folder can be ignored because of Package Restore -**/[Pp]ackages/* -# except build/, which is used as an MSBuild target. -!**/[Pp]ackages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/[Pp]ackages/repositories.config -# NuGet v3's project.json files produces more ignorable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt -*.appx -*.appxbundle -*.appxupload - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!?*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -orleans.codegen.cs - -# Including strong name files can present a security risk -# (https://github.com/github/gitignore/pull/2483#issue-259490424) -#*.snk - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm -ServiceFabricBackup/ -*.rptproj.bak - -# SQL Server files -*.mdf -*.ldf -*.ndf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings -*.rptproj.rsuser -*- [Bb]ackup.rdl -*- [Bb]ackup ([0-9]).rdl -*- [Bb]ackup ([0-9][0-9]).rdl - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat -node_modules/ - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) -*.vbw - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# CodeRush personal settings -.cr/personal - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc - -# Cake - Uncomment if you are using it -# tools/** -# !tools/packages.config - -# Tabs Studio -*.tss - -# Telerik's JustMock configuration file -*.jmconfig - -# BizTalk build output -*.btp.cs -*.btm.cs -*.odx.cs -*.xsd.cs - -# OpenCover UI analysis results -OpenCover/ - -# Azure Stream Analytics local run output -ASALocalRun/ - -# MSBuild Binary and Structured Log -*.binlog - -# NVidia Nsight GPU debugger configuration file -*.nvuser - -# MFractors (Xamarin productivity tool) working folder -.mfractor/ - -# Local History for Visual Studio -.localhistory/ - -# BeatPulse healthcheck temp database -healthchecksdb - -# Backup folder for Package Reference Convert tool in Visual Studio 2017 -MigrationBackup/ - -# Ionide (cross platform F# VS Code tools) working folder -.ionide/ - -# Fody - auto-generated XML schema - -FodyWeavers.xsd -PvZ-Fusion-Blooms-master/MelonLoader/PvZ Fusion Translator \[MelonLoader\].csproj - -PvZ-Fusion-Translator 2.zip -MelonLoader/PvZ Fusion Translator \[MelonLoader].csproj +################################################################################ +# This .gitignore file was automatically created by Microsoft(R) Visual Studio. +################################################################################ + +/.vs/BepInEx/copilot-chat/bff105b7/sessions +/.vs +/bin +/obj +/MelonLoader/obj +/BepInEx/obj/Debug/net6.0 +/BepInEx/obj diff --git a/BepInEx/AssetStore/AudioStore.cs b/BepInEx/AssetStore/AudioStore.cs index 862cb09..46ff120 100644 --- a/BepInEx/AssetStore/AudioStore.cs +++ b/BepInEx/AssetStore/AudioStore.cs @@ -40,29 +40,36 @@ namespace PvZ_Fusion_Translator__BepInEx_ } public static void LoadAudios() { - if (!Directory.Exists(customAudioPath)) - Directory.CreateDirectory(customAudioPath); - - string[] audioFiles = Directory.GetFiles(customAudioPath, "*", SearchOption.AllDirectories); - var ovrClip = audioFiles.SingleOrDefault(f => Path.GetFileNameWithoutExtension(f) == "REPLACE_ALL"); - if (ovrClip == null) + try { - foreach (string file in audioFiles) - { - if (!allowedExts.Contains(Path.GetExtension(file))) - continue; + if (!Directory.Exists(customAudioPath)) + Directory.CreateDirectory(customAudioPath); - AudioClip clip = AudioImportLib.BepInEx.API.LoadAudioClip(file); + string[] audioFiles = Directory.GetFiles(customAudioPath, "*", SearchOption.AllDirectories); + var ovrClip = audioFiles.SingleOrDefault(f => Path.GetFileNameWithoutExtension(f) == "REPLACE_ALL"); + if (ovrClip == null) + { + foreach (string file in audioFiles) + { + if (!allowedExts.Contains(Path.GetExtension(file))) + continue; + + AudioClip clip = AudioImportLib.BepInEx.API.LoadAudioClip(file); + AudioClips.Add(clip.name, clip); + Log.LogInfo("Added Override: " + clip.name); + } + } + else + { + AudioClip clip = AudioImportLib.BepInEx.API.LoadAudioClip(ovrClip); AudioClips.Add(clip.name, clip); + overrideEnabled = true; Log.LogInfo("Added Override: " + clip.name); } } - else + catch (Exception ex) { - AudioClip clip = AudioImportLib.BepInEx.API.LoadAudioClip(ovrClip); - AudioClips.Add(clip.name, clip); - overrideEnabled = true; - Log.LogInfo("Added Override: " + clip.name); + Log.LogError($"Error loading audio clips: {ex.Message}"); } } diff --git a/BepInEx/AssetStore/FontStore.cs b/BepInEx/AssetStore/FontStore.cs index a3e3092..9fb8409 100644 --- a/BepInEx/AssetStore/FontStore.cs +++ b/BepInEx/AssetStore/FontStore.cs @@ -4,169 +4,169 @@ using System.IO; namespace PvZ_Fusion_Translator__BepInEx_.AssetStore { - public static class FontStore - { - internal static Dictionary fontAssetDict = []; - internal static Dictionary fontAssetDictSecondary = []; + public static class FontStore + { + internal static Dictionary fontAssetDict = []; + internal static Dictionary fontAssetDictSecondary = []; - internal static void Init() - { - string fontsDir = Path.Combine(Core.Instance.modsDirectory, "[Custom Fonts]"); + internal static void Init() + { + string fontsDir = Path.Combine(Core.Instance.modsDirectory, "[Custom Fonts]"); - #if MULTI_LANGUAGE - foreach (string file in Directory.GetFiles(fontsDir)) - { - string fileName = Path.GetFileNameWithoutExtension(file); - string fileExtension = Path.GetExtension(file); +#if MULTI_LANGUAGE + foreach (string file in Directory.GetFiles(fontsDir)) + { + string fileName = Path.GetFileNameWithoutExtension(file); + string fileExtension = Path.GetExtension(file); - if (fileExtension == ".ttf" || fileExtension == ".otf") - { - if (!fileName.EndsWith("_Almanac") && !fileName.EndsWith("_Fallback")) - { - string fontPath = Path.Combine("PvZ_Fusion_Translator", "[Custom Fonts]", fileName + fileExtension); + if (fileExtension == ".ttf" || fileExtension == ".otf") + { + if (!fileName.EndsWith("_Almanac") && !fileName.EndsWith("_Fallback")) + { + string fontPath = Path.Combine("PvZ_Fusion_Translator", "[Custom Fonts]", fileName + fileExtension); - TMP_FontAsset fontAsset = FontHandler.LoadTMPFont(fontPath, true); - fontAsset.name = fileName; - fontAssetDict.Add(fileName, fontAsset); + TMP_FontAsset fontAsset = FontHandler.LoadTMPFont(fontPath, true); + fontAsset.name = fileName; + fontAssetDict.Add(fileName, fontAsset); - Log.LogInfo($"Font for language '{fileName}' loaded"); - } - } - } - - InitFallback(); - #else + Log.LogInfo($"Font for language '{fileName}' loaded"); + } + } + } + + InitFallback(); +#else string defaultFontDir = Path.Combine("PvZ_Fusion_Translator", "[Custom Fonts]", "English.ttf"); TMP_FontAsset defaultFont = FontHandler.LoadTMPFont(defaultFontDir, true); fontAssetDict.Add("English", defaultFont); - #endif - } +#endif + } - internal static void InitFallback() - { - string fontsDir = Path.Combine(Core.Instance.modsDirectory, "[Custom Fonts]"); - foreach (string file in Directory.GetFiles(fontsDir)) - { - string fileName = Path.GetFileNameWithoutExtension(file); - string fileExtension = Path.GetExtension(file); + internal static void InitFallback() + { + string fontsDir = Path.Combine(Core.Instance.modsDirectory, "[Custom Fonts]"); + foreach (string file in Directory.GetFiles(fontsDir)) + { + string fileName = Path.GetFileNameWithoutExtension(file); + string fileExtension = Path.GetExtension(file); - if (fileExtension == ".ttf" || fileExtension == ".otf") - { - if (fileName.EndsWith("_Almanac") || fileName.EndsWith("_Fallback")) - { - string fallbackPath = Path.Combine("PvZ_Fusion_Translator", "[Custom Fonts]", fileName + fileExtension); - TMP_FontAsset fallbackFont = FontHandler.LoadTMPFont(fallbackPath, true); - fallbackFont.name = fileName; + if (fileExtension == ".ttf" || fileExtension == ".otf") + { + if (fileName.EndsWith("_Almanac") || fileName.EndsWith("_Fallback")) + { + string fallbackPath = Path.Combine("PvZ_Fusion_Translator", "[Custom Fonts]", fileName + fileExtension); + TMP_FontAsset fallbackFont = FontHandler.LoadTMPFont(fallbackPath, true); + fallbackFont.name = fileName; - string fileNameLanguage = fileName.Replace("_Fallback", "").Replace("_Almanac", ""); + string fileNameLanguage = fileName.Replace("_Fallback", "").Replace("_Almanac", ""); - if (fontAssetDictSecondary.ContainsKey(fileNameLanguage)) - { - if (fileName.EndsWith("_Fallback")) - { - fontAssetDictSecondary.Add(fileNameLanguage + "_Almanac", fontAssetDictSecondary[fileNameLanguage]); - fontAssetDictSecondary.Remove(fileNameLanguage); - } - else - { - fontAssetDictSecondary.Add(fileNameLanguage + "_Fallback", fontAssetDictSecondary[fileNameLanguage]); - fontAssetDictSecondary.Remove(fileNameLanguage); - } - fontAssetDictSecondary.Add(fileName, fallbackFont); - } - else - fontAssetDictSecondary.Add(fileNameLanguage, fallbackFont); + if (fontAssetDictSecondary.ContainsKey(fileNameLanguage)) + { + if (fileName.EndsWith("_Fallback")) + { + fontAssetDictSecondary.Add(fileNameLanguage + "_Almanac", fontAssetDictSecondary[fileNameLanguage]); + fontAssetDictSecondary.Remove(fileNameLanguage); + } + else + { + fontAssetDictSecondary.Add(fileNameLanguage + "_Fallback", fontAssetDictSecondary[fileNameLanguage]); + fontAssetDictSecondary.Remove(fileNameLanguage); + } + fontAssetDictSecondary.Add(fileName, fallbackFont); + } + else + fontAssetDictSecondary.Add(fileNameLanguage, fallbackFont); - // Log.LogInfo($"Fallback font for language '{fileNameLanguage}' loaded"); - } - } - } - AddFallback(); - } + // Log.LogInfo($"Fallback font for language '{fileNameLanguage}' loaded"); + } + } + } + AddFallback(); + } - public static void AddFallback() - { - foreach (var lang in fontAssetDict.Keys) - { - if (fontAssetDict[lang].fallbackFontAssetTable == null) - { - fontAssetDict[lang].fallbackFontAssetTable = new Il2CppSystem.Collections.Generic.List(); - } + public static void AddFallback() + { + foreach (var lang in fontAssetDict.Keys) + { + if (fontAssetDict[lang].fallbackFontAssetTable == null) + { + fontAssetDict[lang].fallbackFontAssetTable = new Il2CppSystem.Collections.Generic.List(); + } - if (fontAssetDictSecondary.ContainsKey(lang)) - { - fontAssetDict[lang].fallbackFontAssetTable.Add(fontAssetDictSecondary[lang]); - Log.LogInfo("Fallback font for language '" + lang + "' added"); - continue; - } - if (fontAssetDictSecondary.ContainsKey(lang + "_Almanac")) - { - fontAssetDict[lang].fallbackFontAssetTable.Add(fontAssetDictSecondary[lang + "_Almanac"]); - Log.LogInfo("Fallback font for language '" + lang + "' added"); - continue; - } - if (fontAssetDictSecondary.ContainsKey(lang + "_Fallback")) - { - fontAssetDict[lang].fallbackFontAssetTable.Add(fontAssetDictSecondary[lang + "_Fallback"]); - Log.LogInfo("Fallback font for language '" + lang + "' added"); - continue; - } - } - } + if (fontAssetDictSecondary.ContainsKey(lang)) + { + fontAssetDict[lang].fallbackFontAssetTable.Add(fontAssetDictSecondary[lang]); + Log.LogInfo("Fallback font for language '" + lang + "' added"); + continue; + } + if (fontAssetDictSecondary.ContainsKey(lang + "_Almanac")) + { + fontAssetDict[lang].fallbackFontAssetTable.Add(fontAssetDictSecondary[lang + "_Almanac"]); + Log.LogInfo("Fallback font for language '" + lang + "' added"); + continue; + } + if (fontAssetDictSecondary.ContainsKey(lang + "_Fallback")) + { + fontAssetDict[lang].fallbackFontAssetTable.Add(fontAssetDictSecondary[lang + "_Fallback"]); + Log.LogInfo("Fallback font for language '" + lang + "' added"); + continue; + } + } + } - #if MULTI_LANGUAGE - public static TMP_FontAsset LoadTMPFont(string language) - { - if (fontAssetDict.TryGetValue(language, out TMP_FontAsset font)) - { - TMP_FontAsset fontAsset = font; - if (fontAsset.fallbackFontAssetTable != null) - { - // Log.LogInfo("Fallback font for language '" + language + "' loaded. The name of the FB Font is" + fontAsset.fallbackFontAssetTable[0].name); - } - return fontAsset; - } - return fontAssetDict.GetValueOrDefault("English"); - } - #else +#if MULTI_LANGUAGE + public static TMP_FontAsset LoadTMPFont(string language) + { + if (fontAssetDict.TryGetValue(language, out TMP_FontAsset font)) + { + TMP_FontAsset fontAsset = font; + if (fontAsset.fallbackFontAssetTable != null) + { + // Log.LogInfo("Fallback font for language '" + language + "' loaded. The name of the FB Font is" + fontAsset.fallbackFontAssetTable[0].name); + } + return fontAsset; + } + return fontAssetDict.GetValueOrDefault("English"); + } +#else public static TMP_FontAsset LoadTMPFont() { TMP_FontAsset defaultFont = fontAssetDict["English"]; return defaultFont; } - #endif +#endif - public static TMP_FontAsset LoadTMPFontAlmanac(string language) - { - if (fontAssetDictSecondary.ContainsKey(language)) - { - if (fontAssetDictSecondary.TryGetValue(language, out TMP_FontAsset almanacAsset)) - { - return almanacAsset; - } - } - if (fontAssetDictSecondary.ContainsKey(language + "_Almanac")) - { - if (fontAssetDictSecondary.TryGetValue(language + "_Almanac", out TMP_FontAsset almanacAsset)) - { - return almanacAsset; - } - } + public static TMP_FontAsset LoadTMPFontAlmanac(string language) + { + if (fontAssetDictSecondary.ContainsKey(language)) + { + if (fontAssetDictSecondary.TryGetValue(language, out TMP_FontAsset almanacAsset)) + { + return almanacAsset; + } + } + if (fontAssetDictSecondary.ContainsKey(language + "_Almanac")) + { + if (fontAssetDictSecondary.TryGetValue(language + "_Almanac", out TMP_FontAsset almanacAsset)) + { + return almanacAsset; + } + } - return fontAssetDict.GetValueOrDefault("English"); - } + return fontAssetDict.GetValueOrDefault("English"); + } - #if MULTI_LANGUAGE - public static void Reload() - { - // Get the current language - string currentLanguage = Utils.Language.ToString(); +#if MULTI_LANGUAGE + public static void Reload() + { + // Get the current language + string currentLanguage = Utils.Language.ToString(); - // Load the font for the current language - _ = LoadTMPFont(currentLanguage); - } - #endif + // Load the font for the current language + _ = LoadTMPFont(currentLanguage); + } +#endif - } -} + } +} \ No newline at end of file diff --git a/BepInEx/AssetStore/StringStore.cs b/BepInEx/AssetStore/StringStore.cs index 96b398e..a94c6e2 100644 --- a/BepInEx/AssetStore/StringStore.cs +++ b/BepInEx/AssetStore/StringStore.cs @@ -1252,7 +1252,7 @@ namespace PvZ_Fusion_Translator__BepInEx_.AssetStore }; } - static TextMeshProUGUI ConvertToTextMeshPro(UnityEngine.UI.Text oldText, TMP_FontAsset fontAsset, bool isLog = false) + public static TextMeshProUGUI ConvertToTextMeshPro(UnityEngine.UI.Text oldText, TMP_FontAsset fontAsset, bool isLog = false) { if (oldText == null) { diff --git a/BepInEx/AssetStore/TextureStore.cs b/BepInEx/AssetStore/TextureStore.cs index de42ff0..1be856c 100644 --- a/BepInEx/AssetStore/TextureStore.cs +++ b/BepInEx/AssetStore/TextureStore.cs @@ -9,6 +9,8 @@ namespace PvZ_Fusion_Translator__BepInEx_.AssetStore { internal static Dictionary textureDict = []; + internal static Dictionary spriteDict = []; + internal static void Init() => FileLoader.LoadTextures(); internal static void Reload() diff --git a/BepInEx/Core.cs b/BepInEx/Core.cs index 57e7cd6..6df672c 100644 --- a/BepInEx/Core.cs +++ b/BepInEx/Core.cs @@ -21,7 +21,7 @@ public class Core : BasePlugin private static DateTime? dtStartToast; private static string toast_txt; - public static ManualLogSource Log; + public new static ManualLogSource Log; public static Core Instance { get; private set; } public static MonoBehaviour MonoInstance { get; private set; } diff --git a/BepInEx/Dependencies/AudioImportLib.BepInEx.dll b/BepInEx/Dependencies/AudioImportLib.BepInEx.dll new file mode 100644 index 0000000..2e87423 Binary files /dev/null and b/BepInEx/Dependencies/AudioImportLib.BepInEx.dll differ diff --git a/BepInEx/FileLoader.cs b/BepInEx/FileLoader.cs index 3effd03..df35c67 100644 --- a/BepInEx/FileLoader.cs +++ b/BepInEx/FileLoader.cs @@ -18,6 +18,7 @@ namespace PvZ_Fusion_Translator__BepInEx_ Strings, Dumps, Almanac, + Sprites } public static string GetAssetDir(AssetType assetType, Utils.LanguageEnum? language = null) @@ -91,7 +92,7 @@ namespace PvZ_Fusion_Translator__BepInEx_ Log.LogInfo("Strings loaded successfully."); } - + internal static void LoadTextures() { @@ -101,7 +102,8 @@ namespace PvZ_Fusion_Translator__BepInEx_ if (Utils.customTextures) { LoadCustomTextures(); - } else + } + else { LoadDefaultTextures(); } @@ -183,13 +185,13 @@ namespace PvZ_Fusion_Translator__BepInEx_ foreach (string filepath in Directory.EnumerateFiles(textureDefaultDir, "*.png", SearchOption.AllDirectories)) { - #if OBFUSCATE +#if OBFUSCATE if (CheckSumStore.IsModified(filepath)) { Log.LogError("File {0} was modified!" , filepath); continue; } - #endif +#endif Texture2D texture2D = Utils.LoadImage(filepath); TextureStore.textureDict[Path.GetFileNameWithoutExtension(filepath)] = filepath; @@ -279,9 +281,11 @@ namespace PvZ_Fusion_Translator__BepInEx_ File.WriteAllText(Path.Combine(dumpDir, "ZombieStrings.json"), ZombieStrings); Dictionary achievementsList = new Dictionary(); - foreach (Il2CppSystem.Collections.Generic.KeyValuePair> entry in AchievementClip.achievementsText) + foreach (var entry in AchievementClip.achievementsText) { - achievementsList.Add(entry.Key, new AchievementObject(entry.Key, entry.Value.Item1, entry.Value.Item2)); + var key = entry.Key; + var value = entry.Value; + achievementsList.Add(key, new AchievementObject(key, value.Item1, value.Item2)); } File.WriteAllText(Path.Combine(dumpDir, "AchievementsText.json"), JsonSerializer.Serialize(achievementsList, new JsonSerializerOptions { @@ -290,7 +294,7 @@ namespace PvZ_Fusion_Translator__BepInEx_ })); } -#if DEBUG +//#if DEBUG public static void DumpUntranslatedStrings(string text) { string dumpDir = GetAssetDir(AssetType.Dumps); @@ -320,7 +324,7 @@ namespace PvZ_Fusion_Translator__BepInEx_ File.WriteAllText(jsonFile, JsonSerializer.Serialize(untranslatedStrings, options)); } } -#endif +//#endif #if MULTI_LANGUAGE internal static void LoadLanguage() diff --git a/BepInEx/FontHandler.cs b/BepInEx/FontHandler.cs index d91d970..44869f9 100644 --- a/BepInEx/FontHandler.cs +++ b/BepInEx/FontHandler.cs @@ -6,40 +6,40 @@ using UnityEngine; namespace PvZ_Fusion_Translator__BepInEx_ { - public static class FontHandler - { - public static Font LoadFont(this string pathFromModsFolder, bool throwException) - { - string fontFilePath = Path.Combine(Paths.PluginPath, pathFromModsFolder); - if (!File.Exists(fontFilePath)) - { - if (throwException) - Log.LogWarning($"Font not found at path: '{fontFilePath}'."); - return null; - } + public static class FontHandler + { + public static Font LoadFont(this string pathFromModsFolder, bool throwException) + { + string fontFilePath = Path.Combine(Paths.PluginPath, pathFromModsFolder); + if (!File.Exists(fontFilePath)) + { + if (throwException) + Log.LogWarning($"Font not found at path: '{fontFilePath}'."); + return null; + } - Font font = new Font(); - Font.Internal_CreateFontFromPath(font, fontFilePath); // Default size, adjust as needed - return font; - } + Font font = new Font(); + Font.Internal_CreateFontFromPath(font, fontFilePath); // Default size, adjust as needed + return font; + } - public static TMP_FontAsset ConvertToTMP(this Font font) - { - TMP_FontAsset fontAsset = TMP_FontAsset.CreateFontAsset(font); - if (fontAsset == null) - { - Log.LogWarning($"Failed to create TMP_FontAsset from font '{font.name}'."); - return null; - } - return fontAsset; - } + public static TMP_FontAsset ConvertToTMP(this Font font) + { + TMP_FontAsset fontAsset = TMP_FontAsset.CreateFontAsset(font); + if (fontAsset == null) + { + Log.LogWarning($"Failed to create TMP_FontAsset from font '{font.name}'."); + return null; + } + return fontAsset; + } - public static TMP_FontAsset LoadTMPFont(this string pathFromModsFolder, bool throwException) - { - Font font = pathFromModsFolder.LoadFont(throwException); - if (font == null) - return null; - return font.ConvertToTMP(); - } - } + public static TMP_FontAsset LoadTMPFont(this string pathFromModsFolder, bool throwException) + { + Font font = pathFromModsFolder.LoadFont(throwException); + if (font == null) + return null; + return font.ConvertToTMP(); + } + } } \ No newline at end of file diff --git a/BepInEx/Patches/BaseTextObjects/InGameText_Patch.cs b/BepInEx/Patches/BaseTextObjects/InGameText_Patch.cs index 623f0f2..0efa9b2 100644 --- a/BepInEx/Patches/BaseTextObjects/InGameText_Patch.cs +++ b/BepInEx/Patches/BaseTextObjects/InGameText_Patch.cs @@ -17,13 +17,13 @@ namespace PvZ_Fusion_Translator__BepInEx_.Patches.BaseTextObjects private static void ShowText(InGameText __instance) { - #if MULTI_LANGUAGE - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - #else +#if MULTI_LANGUAGE + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); +#else TMP_FontAsset fontAsset = FontStore.LoadTMPFont(); - #endif - - foreach (TextMeshProUGUI txt in __instance.textMeshes) +#endif + + foreach (TextMeshProUGUI txt in __instance.textMeshes) { txt.text = StringStore.TranslateText(txt.text, true); txt.font = fontAsset; diff --git a/BepInEx/Patches/BaseTextObjects/TextMeshPro_Patch.cs b/BepInEx/Patches/BaseTextObjects/TextMeshPro_Patch.cs index 3703680..588eb70 100644 --- a/BepInEx/Patches/BaseTextObjects/TextMeshPro_Patch.cs +++ b/BepInEx/Patches/BaseTextObjects/TextMeshPro_Patch.cs @@ -18,9 +18,11 @@ namespace PvZ_Fusion_Translator__BepInEx_.Patches.BaseTextObjects __instance = StringStore.TranslateText(__instance); __instance.autoSizeTextContainer = false; return; + } else if (!(__instance.transform.name.Contains("AlmanacZombie") || __instance.transform.name.Contains("AlmanacPlant"))) + { + __instance = StringStore.TranslateText(__instance); + __instance.autoSizeTextContainer = true; } - __instance = StringStore.TranslateText(__instance); - __instance.autoSizeTextContainer = true; } } } diff --git a/BepInEx/Patches/GameObjects/BaseMenu_Patch.cs b/BepInEx/Patches/GameObjects/BaseMenu_Patch.cs index a769ae6..229e80e 100644 --- a/BepInEx/Patches/GameObjects/BaseMenu_Patch.cs +++ b/BepInEx/Patches/GameObjects/BaseMenu_Patch.cs @@ -108,7 +108,12 @@ namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects foreach(TextMeshProUGUI txt in mainTransform.GetComponentsInChildren()) { +#if DEBUG + FileLoader.DumpUntranslatedStrings(txt.text); txt.text = StringStore.TranslateText(txt.text); +#else + txt.text = StringStore.TranslateText(txt.text, true); +#endif } } } diff --git a/BepInEx/Patches/GameObjects/Board_Patch.cs b/BepInEx/Patches/GameObjects/Board_Patch.cs new file mode 100644 index 0000000..12ee2c0 --- /dev/null +++ b/BepInEx/Patches/GameObjects/Board_Patch.cs @@ -0,0 +1,27 @@ +using HarmonyLib; +using TMPro; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(Board))] + public static class Board_Patch + { + [HarmonyPatch(nameof(Board.Update))] + [HarmonyPostfix] + private static void Update(Board __instance) + { + foreach (SpriteRenderer spriteRenderer in __instance.GetComponentsInChildren()) + { + if (spriteRenderer.sprite != null) + { + if (TextureStore.spriteDict.ContainsKey(spriteRenderer.sprite.name) && spriteRenderer.drawMode != SpriteDrawMode.Sliced) + { + spriteRenderer.drawMode = SpriteDrawMode.Sliced; + } + } + } + } + } +} diff --git a/BepInEx/Patches/GameObjects/ButtonObjects/UIButton_Patch.cs b/BepInEx/Patches/GameObjects/ButtonObjects/UIButton_Patch.cs new file mode 100644 index 0000000..c79f69f --- /dev/null +++ b/BepInEx/Patches/GameObjects/ButtonObjects/UIButton_Patch.cs @@ -0,0 +1,73 @@ +using HarmonyLib; +using System; +using TMPro; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using UnityEngine; +using UnityEngine.UI; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.ButtonObjects +{ + [HarmonyPatch(typeof(UIButton))] + public static class UIButton_Patch + { + [HarmonyPatch(nameof(UIButton.Start))] + [HarmonyPostfix] + private static void Postfix_Start(UIButton __instance) + { + try + { + // Convert and translate legacy Text components + Text[] textComponents = __instance.GetComponentsInChildren(true); + TextMeshProUGUI[] textMeshComponents = __instance.GetComponentsInChildren(true); + foreach (Text textComponent in textComponents) + { + 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; + } + } + } + } + + // Also handle TMP components directly under the button + if (__instance.transform.childCount >= 2) + { + TextMeshProUGUI text = __instance.transform.GetChild(0).GetComponent(); + TextMeshProUGUI textShadow = __instance.transform.GetChild(1).GetComponent(); + + StringStore.TranslateTextUI(text, false); + StringStore.TranslateTextUI(textShadow, false); + text.autoSizeTextContainer = textShadow.autoSizeTextContainer = true; + } + } + catch (Exception) { } + } + + [HarmonyPatch(nameof(UIButton.OnMouseUpAsButton))] + [HarmonyPostfix] + public static void Postfix_OnMouseUpAsButton(UIButton __instance) + { + try + { + if (__instance.transform.childCount >= 2) + { + TextMeshProUGUI text = __instance.transform.GetChild(0).GetComponent(); + TextMeshProUGUI textShadow = __instance.transform.GetChild(1).GetComponent(); + + StringStore.TranslateTextUI(text, false); + StringStore.TranslateTextUI(textShadow, false); + text.autoSizeTextContainer = textShadow.autoSizeTextContainer = true; + } + } + catch (Exception) { } + } + } +} diff --git a/BepInEx/Patches/GameObjects/CrisisZombieWindow_Patch.cs b/BepInEx/Patches/GameObjects/CrisisZombieWindow_Patch.cs new file mode 100644 index 0000000..1c37071 --- /dev/null +++ b/BepInEx/Patches/GameObjects/CrisisZombieWindow_Patch.cs @@ -0,0 +1,37 @@ +using HarmonyLib; + +using TMPro; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using UnityEngine; +using System.Text.RegularExpressions; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(CrisisZombieWindow))] + public static class CrisisZombieWindow_Patch + { + [HarmonyPatch(nameof(CrisisZombieWindow.Start))] + [HarmonyPostfix] + private static void Start(CrisisZombieWindow __instance) + { + Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + TextMeshProUGUI introduceText = introduceTransform.GetComponent(); + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } + + [HarmonyPatch(nameof(CrisisZombieWindow.SetZombieType))] + [HarmonyPostfix] + private static void SetZombieType(CrisisZombieWindow __instance) + { + Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + TextMeshProUGUI introduceText = introduceTransform.GetComponent(); + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } + } +} diff --git a/BepInEx/Patches/GameObjects/FruitNinjaSelectWindow_Patch.cs b/BepInEx/Patches/GameObjects/FruitNinjaSelectWindow_Patch.cs new file mode 100644 index 0000000..26d193a --- /dev/null +++ b/BepInEx/Patches/GameObjects/FruitNinjaSelectWindow_Patch.cs @@ -0,0 +1,37 @@ +using HarmonyLib; + +using TMPro; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using UnityEngine; +using System.Text.RegularExpressions; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(FruitNinjaSelectWindow))] + public static class FruitNinjaSelectWindow_Patch + { + [HarmonyPatch(nameof(FruitNinjaSelectWindow.SetType))] + [HarmonyPostfix] + private static void SetType(FruitNinjaSelectWindow __instance) + { + Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + TextMeshProUGUI introduceText = introduceTransform.GetComponent(); + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } + + [HarmonyPatch(nameof(FruitNinjaSelectWindow.OnAnimOver))] + [HarmonyPostfix] + private static void OnAnimOver(FruitNinjaSelectWindow __instance) + { + Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + TextMeshProUGUI introduceText = introduceTransform.GetComponent(); + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } + } +} diff --git a/BepInEx/Patches/GameObjects/MainMenu_Patch.cs b/BepInEx/Patches/GameObjects/MainMenu_Patch.cs index 36bbd6b..ce3296d 100644 --- a/BepInEx/Patches/GameObjects/MainMenu_Patch.cs +++ b/BepInEx/Patches/GameObjects/MainMenu_Patch.cs @@ -11,14 +11,15 @@ namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects private static bool _warningShown = false; [HarmonyPostfix] - [HarmonyPatch(nameof(MainMenu.FixedUpdate))] - private static void FixedUpdate(MainMenu __instance) - { - if (_warningShown || NoticeMenu.Instance == null) - return; - - WarningStore.WarningReload(Utils.Language, NoticeMenu.Instance); - _warningShown = true; - } + [HarmonyPatch("AnimOver")] + private static void AnimOver(MainMenu __instance) + { + bool flag = _warningShown || NoticeMenu.Instance == null; + if (!flag) + { + WarningStore.WarningReload(Utils.Language, NoticeMenu.Instance); + _warningShown = true; + } + } } } \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/MinorObjects/Jigsaw_Patch.cs b/BepInEx/Patches/GameObjects/MinorObjects/Jigsaw_Patch.cs new file mode 100644 index 0000000..23fc6a7 --- /dev/null +++ b/BepInEx/Patches/GameObjects/MinorObjects/Jigsaw_Patch.cs @@ -0,0 +1,32 @@ +using HarmonyLib; +// using Il2Cpp; +using TMPro; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; + + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects +{ + [HarmonyPatch(typeof(JigsawClip))] + public static class JigsawClip_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(JigsawClip.Awake))] + private static void Postfix_Awake(JigsawClip __instance) + { + if (!__instance || !__instance.description) return; + + StringStore.TranslateTextUI(__instance.description); + } + [HarmonyPostfix] + [HarmonyPatch(nameof(JigsawClip.Update))] + private static void Postfix_Update(JigsawClip __instance) + { + if (!__instance || !__instance.description) return; + + if (__instance.description.text != StringStore.TranslateText(__instance.description.text)) + { + StringStore.TranslateTextUI(__instance.description); + } + } + } +} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/MinorObjects/Plant_Patch.cs b/BepInEx/Patches/GameObjects/MinorObjects/Plant_Patch.cs index b332cf4..bf90a0b 100644 --- a/BepInEx/Patches/GameObjects/MinorObjects/Plant_Patch.cs +++ b/BepInEx/Patches/GameObjects/MinorObjects/Plant_Patch.cs @@ -6,19 +6,45 @@ using UnityEngine; namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects { - [HarmonyPatch(typeof(Plant))] - public static class Plant_Patch - { - [HarmonyPostfix] - [HarmonyPatch(nameof(Plant.UpdateHealthText))] - private static void UpdateHealthText(Plant __instance) - { - Transform healthTransform = __instance.transform.Find("health"); - if (healthTransform != null) - { - StringStore.TranslateTextTransform(__instance.transform); - } - } - } + [HarmonyPatch(typeof(Plant))] + public static class Plant_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(Plant.Awake))] + private static void Awake(Plant __instance) + { + if (!(__instance.thePlantType == PlantType.SuperMachineNut || __instance.thePlantType == PlantType.MachineNut)) + return; + __instance.healthSlider.healthText.text = __instance.healthSlider.healthTextShadow.text = ChangeHPText(__instance.healthSlider.healthTextShadow.text); + } + + [HarmonyPostfix] + [HarmonyPatch(nameof(Plant.UpdateText))] + private static void Update(Plant __instance) + { + if (!(__instance.thePlantType == PlantType.SuperMachineNut || __instance.thePlantType == PlantType.MachineNut)) + return; + if (__instance.thePlantHealth < __instance.thePlantMaxHealth) + return; + __instance.healthSlider.healthText.text = __instance.healthSlider.healthTextShadow.text = ChangeHPText(__instance.healthSlider.healthTextShadow.text); + } + + static string ChangeHPText(string originalText) + { + var regex = new Regex(@"(\d+)\d\d\d/(\d)000"); + if (regex.IsMatch(originalText)) + { + var match = regex.Match(originalText); + int groupCount = match.Groups.Count; + + List dynamicParts = new List(); + + for (int i = 1; i < groupCount; i++) + dynamicParts.Add(match.Groups[i].Value); + return originalText = string.Format("{0}k/{1}k", [.. dynamicParts]); + } + return originalText; + } + } } #endif \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/MinorObjects/TrainingDummy_Patch.cs b/BepInEx/Patches/GameObjects/MinorObjects/TrainingDummy_Patch.cs new file mode 100644 index 0000000..8aa1766 --- /dev/null +++ b/BepInEx/Patches/GameObjects/MinorObjects/TrainingDummy_Patch.cs @@ -0,0 +1,16 @@ +using HarmonyLib; + + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects +{ + [HarmonyPatch(typeof(TrainingDummy), nameof(TrainingDummy.UpdateHealthText))] + public static class TrainingDummy_Patch + { + [HarmonyPostfix] + public static void UpdateHealthText(TrainingDummy __instance) + { + Zombie_Patch.TranslateHpUI(__instance.healthText); + Zombie_Patch.TranslateHpUI(__instance.healthTextShadow); + } + } +} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/MinorObjects/UltimateChomper_Patch.cs b/BepInEx/Patches/GameObjects/MinorObjects/UltimateChomper_Patch.cs new file mode 100644 index 0000000..41ec1f9 --- /dev/null +++ b/BepInEx/Patches/GameObjects/MinorObjects/UltimateChomper_Patch.cs @@ -0,0 +1,17 @@ +using HarmonyLib; + +using PvZ_Fusion_Translator__BepInEx_.AssetStore; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects +{ + [HarmonyPatch(typeof(UltimateChomper), nameof(UltimateChomper.UpdateText))] + public static class UltimateChomper_Patch + { + [HarmonyPostfix] + public static void UpdateText(UltimateChomper __instance) + { + StringStore.TranslateText(__instance.killingText); + StringStore.TranslateText(__instance.killingTextShadow); + } + } +} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/MinorObjects/Zombie_Patch.cs b/BepInEx/Patches/GameObjects/MinorObjects/Zombie_Patch.cs index 355aa74..5b23409 100644 --- a/BepInEx/Patches/GameObjects/MinorObjects/Zombie_Patch.cs +++ b/BepInEx/Patches/GameObjects/MinorObjects/Zombie_Patch.cs @@ -1,12 +1,100 @@ -using System; +using HarmonyLib; + +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using System.Text.RegularExpressions; +using UnityEngine; +using TMPro; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects { - class Zombie_Patch + [HarmonyPatch(typeof(Zombie))] + public static class Zombie_Patch { + private static Dictionary HPStrings = new Dictionary() + { + { "最后一击:(\\d+)\nDPS:(.+)$", "Last damage: {0}\nDPS: {1}" }, + { "^HP:(\\d+)/(\\d+)\n\\D+(\\d+)/(\\d+)\n\\D+(\\d+)/(\\d+)$", "HP: {0}/{1}\nType 1 armor: {2}/{3}\nType 2 armor: {4}/{5}" }, + { "^HP:(\\d+)/(\\d+)\n\\D+(\\d+)/(\\d+)$", "HP: {0}/{1}\nType 1 armor: {2}/{3}" }, + { "^HP:(\\d+)/(\\d+)$", "HP: {0}/{1}" }, + }; + + public static void LoadHPStrings() + { + foreach (var hp in HPStrings) + if (StringStore.translationStringRegex.ContainsKey(hp.Key)) + HPStrings[hp.Key] = StringStore.translationStringRegex[hp.Key]; + } + + [HarmonyPatch(nameof(Zombie.Start))] + [HarmonyPostfix] + public static void Start(Zombie __instance) + { + TranslateHpUI(__instance.healthText); + TranslateHpUI(__instance.healthTextShadow); + if (__instance.theFirstArmorHealth == 0 && __instance.theSecondArmorHealth != 0) + { + __instance.healthText.text = __instance.healthText.text.Replace("Type 1", "Type 2"); + __instance.healthTextShadow.text = __instance.healthText.text.Replace("Type 1", "Type 2"); + } + if (__instance.healthText.transform.rotation != Quaternion.Euler(0, 0, 0)) + __instance.healthText.transform.rotation = Quaternion.Euler(0f, 0f, 0f); + } + + [HarmonyPatch(nameof(Zombie.Update))] + [HarmonyPrefix] + public static void Update(Zombie __instance) + { + if (__instance.theZombieType == ZombieType.TrainingDummy || !Board.Instance.showZombieHealth) + return; + TranslateHpUI(__instance.healthText); + TranslateHpUI(__instance.healthTextShadow); + if (__instance.theFirstArmorHealth == 0 && __instance.theSecondArmorHealth != 0) + { + __instance.healthText.text = __instance.healthText.text.Replace("Type 1", "Type 2"); + __instance.healthTextShadow.text = __instance.healthText.text.Replace("Type 1", "Type 2"); + } + if (__instance.healthText.transform.rotation != Quaternion.Euler(0f, 0f, 0f)) + __instance.healthText.transform.rotation = Quaternion.Euler(0f, 0f, 0f); + } + + public static void TranslateHpUI(TextMeshPro textTMP) + { + if (textTMP) + { + string origText = textTMP.text; + string translatedText = TranslateHPText(origText); + textTMP.text = translatedText == origText ? origText : translatedText; + textTMP.autoSizeTextContainer = false; + if (translatedText != origText) + textTMP.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + } + + public static string TranslateHPText(string originalText) + { + foreach (var entry in HPStrings) + { + var regex = new Regex(entry.Key); + if (regex.IsMatch(originalText)) + { + var match = regex.Match(originalText); + int groupCount = match.Groups.Count; + + List dynamicParts = new List(); + + for (int i = 1; i < groupCount; i++) + { + string groupValue = match.Groups[i].Value; + string translatedValue = StringStore.translationString.ContainsKey(groupValue) + ? StringStore.translationString[groupValue] + : groupValue; + dynamicParts.Add(translatedValue); + } + return originalText = string.Format(entry.Value, [.. dynamicParts]); + } + } + return originalText; + } } -} +} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/RogueCardWindow_Patch.cs b/BepInEx/Patches/GameObjects/RogueCardWindow_Patch.cs new file mode 100644 index 0000000..ef600fd --- /dev/null +++ b/BepInEx/Patches/GameObjects/RogueCardWindow_Patch.cs @@ -0,0 +1,37 @@ +using HarmonyLib; + +using TMPro; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using UnityEngine; +using System.Text.RegularExpressions; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(RogueCardWindow))] + public static class RogueCardWindow_Patch + { + [HarmonyPatch(nameof(RogueCardWindow.InitCard))] + [HarmonyPostfix] + private static void InitCard(RogueCardWindow __instance) + { + Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + TextMeshProUGUI introduceText = introduceTransform.GetComponent(); + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } + + [HarmonyPatch(nameof(RogueCardWindow.OnAnimOver))] + [HarmonyPostfix] + private static void OnAnimOver(RogueCardWindow __instance) + { + Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + TextMeshProUGUI introduceText = introduceTransform.GetComponent(); + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } + } +} diff --git a/BepInEx/Patches/GameObjects/RogueStartMenu_Patch.cs b/BepInEx/Patches/GameObjects/RogueStartMenu_Patch.cs new file mode 100644 index 0000000..114180e --- /dev/null +++ b/BepInEx/Patches/GameObjects/RogueStartMenu_Patch.cs @@ -0,0 +1,45 @@ +using HarmonyLib; +// using Il2Cpp; +using TMPro; +// using MelonLoader; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using UnityEngine; +using UnityEngine.TextCore.Text; +using UnityEngine.UI; +// using static MelonLoader.MelonLogger; +// using static BepInEx.BepInEx; +using static System.Net.Mime.MediaTypeNames; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + + [HarmonyPatch(typeof(RogueStartMenu))] + public static class RogueStartMenu_Patch + { + [HarmonyPatch(nameof(RogueStartMenu.SetLeader))] + [HarmonyPostfix] + private static void SetLeader(RogueStartMenu __instance) + { + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + } + + [HarmonyPatch(nameof(RogueStartMenu.EnterGame))] + [HarmonyPostfix] + private static void EnterGame(RogueStartMenu __instance) + { + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + } + } +} diff --git a/BepInEx/Patches/GameObjects/ShootingMenu_Patch.cs b/BepInEx/Patches/GameObjects/ShootingMenu_Patch.cs new file mode 100644 index 0000000..dee2e81 --- /dev/null +++ b/BepInEx/Patches/GameObjects/ShootingMenu_Patch.cs @@ -0,0 +1,25 @@ +using HarmonyLib; + +using TMPro; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(ShootingMenu))] + public static class ShootingMenu_Patch + { + [HarmonyPatch(nameof(ShootingMenu.Update))] + [HarmonyPostfix] + private static void Update(ShootingMenu __instance) + { + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + } + } +} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/ShootingSelectWindow_Patch.cs b/BepInEx/Patches/GameObjects/ShootingSelectWindow_Patch.cs new file mode 100644 index 0000000..0685b2e --- /dev/null +++ b/BepInEx/Patches/GameObjects/ShootingSelectWindow_Patch.cs @@ -0,0 +1,73 @@ +using HarmonyLib; +// using Il2Cpp; +using TMPro; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using UnityEngine; +using System.Text.RegularExpressions; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(ShootingSelectWindow))] + public static class ShootingSelectWindow_Patch + { + [HarmonyPatch(nameof(ShootingSelectWindow.InitPlantType))] + [HarmonyPostfix] + private static void InitCard(ShootingSelectWindow __instance) + { + Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + TextMeshProUGUI introduceText = introduceTransform.GetComponent(); + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } + + [HarmonyPatch(nameof(ShootingSelectWindow.OnAnimOver))] + [HarmonyPostfix] + private static void OnAnimOver(ShootingSelectWindow __instance) + { + Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + TextMeshProUGUI introduceText = introduceTransform.GetComponent(); + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } + + [HarmonyPatch(nameof(ShootingSelectWindow.SetUpgradePlantTypes))] + [HarmonyPostfix] + private static void SetUpgradePlantTypes(ShootingSelectWindow __instance) + { + Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + TextMeshProUGUI introduceText = introduceTransform.GetComponent(); + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } + + [HarmonyPatch(nameof(ShootingSelectWindow.GetMaxIndexInRoutes))] + [HarmonyPostfix] + private static void GetMaxIndexInRoutes(ShootingSelectWindow __instance) + { + Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + TextMeshProUGUI introduceText = introduceTransform.GetComponent(); + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } + + [HarmonyPatch(nameof(ShootingSelectWindow.Start))] + [HarmonyPostfix] + private static void Start(ShootingSelectWindow __instance) + { + Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + TextMeshProUGUI introduceText = introduceTransform.GetComponent(); + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } + } +} diff --git a/BepInEx/Patches/GameObjects/TowerOption_Patch.cs b/BepInEx/Patches/GameObjects/TowerOption_Patch.cs new file mode 100644 index 0000000..a985f83 --- /dev/null +++ b/BepInEx/Patches/GameObjects/TowerOption_Patch.cs @@ -0,0 +1,21 @@ +using HarmonyLib; + +using TMPro; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(TowerOption))] + public static class TowerOption_Patch + { + [HarmonyPatch(nameof(TowerOption.Start))] + [HarmonyPostfix] + private static void Postfix_Start(TowerOption __instance) + { + //TextMeshProUGUI[] allTexts = __instance.GetComponentsInChildren(true); + __instance.introduce.text = StringStore.TranslateText(__instance.introduce.text); + __instance.introduce.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + } +} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/TravelLookBuff_Patch.cs b/BepInEx/Patches/GameObjects/TravelLookBuff_Patch.cs new file mode 100644 index 0000000..4bd18bd --- /dev/null +++ b/BepInEx/Patches/GameObjects/TravelLookBuff_Patch.cs @@ -0,0 +1,45 @@ +using System; +using HarmonyLib; + +using TMPro; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(TravelLookBuff))] + public static class TravelLookBuff_Patch + { + private static void TranslateTexts(TravelLookBuff instance) + { + instance.introduce.text = StringStore.TranslateText(instance.introduce.text); + + Transform transform = instance.rectTransform.transform; + var component1 = transform.GetChild(0).GetComponent(); + var component2 = transform.GetChild(1).GetComponent(); + + if (component1 != null) component1.text = StringStore.TranslateText(component1.text); + if (component2 != null) component2.text = StringStore.TranslateText(component2.text); + } + + [HarmonyPatch(nameof(TravelLookBuff.SetBuff))] + [HarmonyPostfix] + private static void SetBuff(TravelLookBuff __instance) => TranslateTexts(__instance); + + [HarmonyPatch(nameof(TravelLookBuff.OnMouseUpAsButton))] + [HarmonyPostfix] + private static void OnMouseUpAsButton(TravelLookBuff __instance) => TranslateTexts(__instance); + + [HarmonyPatch(nameof(TravelLookBuff.Clear))] + [HarmonyPostfix] + private static void Clear(TravelLookBuff __instance) => TranslateTexts(__instance); + + [HarmonyPatch(nameof(TravelLookBuff.SetText), new Type[] { typeof(string) })] + [HarmonyPostfix] + private static void SetText_String(TravelLookBuff __instance) => TranslateTexts(__instance); + + [HarmonyPatch(nameof(TravelLookBuff.SetText), new Type[] { typeof(bool), typeof(int) })] + [HarmonyPostfix] + private static void SetText_Bool(TravelLookBuff __instance) => TranslateTexts(__instance); + } +} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/TravelLookMenu_Patch.cs b/BepInEx/Patches/GameObjects/TravelLookMenu_Patch.cs new file mode 100644 index 0000000..1d37f17 --- /dev/null +++ b/BepInEx/Patches/GameObjects/TravelLookMenu_Patch.cs @@ -0,0 +1,34 @@ +using HarmonyLib; + +using TMPro; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(TravelLookMenu))] + public static class TravelLookMenu_Patch + { + [HarmonyPatch(nameof(TravelLookMenu.Start))] + [HarmonyPostfix] + private static void Postfix_Start(TravelLookMenu __instance) + { + Transform quitButtonTransform = __instance.transform.Find("Quit"); + if (quitButtonTransform != null) + { + TextMeshProUGUI[] allTexts = quitButtonTransform.GetComponentsInChildren(true); + + foreach (var textComp in allTexts) + { + if (textComp != null && textComp.text == StringStore.TranslateText("关闭")) + { + textComp.text = StringStore.TranslateText("关闭_close"); + + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + textComp.font = fontAsset; + } + } + } + } + } +} \ No newline at end of file diff --git a/BepInEx/Patches/Managers/AlmanacPlantBank_Patch.cs b/BepInEx/Patches/Managers/AlmanacPlantBank_Patch.cs index c645bd9..5fac5f6 100644 --- a/BepInEx/Patches/Managers/AlmanacPlantBank_Patch.cs +++ b/BepInEx/Patches/Managers/AlmanacPlantBank_Patch.cs @@ -1,181 +1,250 @@ -using HarmonyLib; -using System.IO; -using TMPro; +using System.IO; +using HarmonyLib; +using Il2CppInterop.Runtime; +using PvZ_Fusion_Translator__BepInEx_; using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using TMPro; using UnityEngine; using static PvZ_Fusion_Translator__BepInEx_.FileLoader; namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers { - [HarmonyPatch(typeof(AlmanacPlantBank))] - public static partial class AlmanacPlantBank_Patch - { - [HarmonyPatch(nameof(AlmanacPlantBank.InitNameAndInfoFromJson))] - [HarmonyPostfix] - private static void InitNameAndInfoFromJson(AlmanacPlantBank __instance) - { - #if MULTI_LANGUAGE - string currentLanguage = Utils.Language.ToString(); - string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); - #else + [HarmonyPatch(typeof(AlmanacPlantBank))] + public static partial class AlmanacPlantBank_Patch + { + [HarmonyPatch(nameof(AlmanacPlantBank.InitNameAndInfoFromJson))] + [HarmonyPostfix] + private static void InitNameAndInfoFromJson(AlmanacPlantBank __instance) + { +#if MULTI_LANGUAGE + string currentLanguage = Utils.Language.ToString(); + string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); +#else string almanacDir = GetAssetDir(AssetType.Almanac); string currentLanguage = "English"; - #endif - string path = Path.Combine(almanacDir, "LawnStringsTranslate.json"); - string moddedPath = Path.Combine(almanacDir, "ModdedPlantsTranslate.json"); +#endif + string path = Path.Combine(almanacDir, "LawnStringsTranslate.json"); + string moddedPath = Path.Combine(almanacDir, "ModdedPlantsTranslate.json"); - if (!File.Exists(path)) - { - Log.LogError($"LawnStringsTranslate.json file not found at path: {path}"); - return; - } - - #if OBFUSCATE - if (CheckSumStore.IsModified(path)) - { - Log.LogError("File {0} was modified!", path); - return; - } - #endif - - 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; - } - - #if MULTI_LANGUAGE - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); - #else - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(); - #endif - - TextMeshPro component = __instance.introduce.GetComponent(); - TextMeshPro component2 = __instance.plantName.GetComponent(); - TextMeshPro component3 = __instance.plantName.transform.GetChild(0).GetComponent(); - TextMeshPro component4 = __instance.cost.GetComponent(); - - AlmanacPlantBank.PlantData plantData = JsonUtility.FromJson(json); - - foreach (AlmanacPlantBank.PlantInfo plantInfo in plantData.plants) - { - if (plantInfo.seedType == __instance.theSeedType) - { - 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; - - component3.text = Utils.RemoveColorTags(plantInfo.name); - component3.autoSizeTextContainer = true; - - component4.text = plantInfo.cost; - - if (hasAlmanacFont) - { - component.font = almanacFontAsset; - component4.font = almanacFontAsset; - } - else - { - component.font = fontAsset; - component4.font = fontAsset; - } - component2.font = fontAsset; - component3.font = fontAsset; - } - } - - if (File.Exists(moddedPath)) - { - string moddedJson; - moddedJson = File.ReadAllText(moddedPath); - - AlmanacPlantBank.PlantData moddedPlantData = JsonUtility.FromJson(moddedJson); - - foreach (AlmanacPlantBank.PlantInfo plantInfo in moddedPlantData.plants) - { - if (plantInfo.seedType == __instance.theSeedType) - { - 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; - - component3.text = Utils.RemoveColorTags(plantInfo.name); - component3.autoSizeTextContainer = true; - - component4.text = plantInfo.cost; - - if (hasAlmanacFont) - { - component.font = almanacFontAsset; - component4.font = almanacFontAsset; - } - else - { - component.font = fontAsset; - component4.font = fontAsset; - } - component2.font = fontAsset; - component3.font = fontAsset; - } - } - } - - foreach (TextMeshPro textMeshPro in __instance.GetComponentsInChildren()) + TranslateTextAlmanac(__instance); + if (!File.Exists(path)) { - textMeshPro.text = StringStore.TranslateText(textMeshPro.text); + return; } +#if OBFUSCATE + if (CheckSumStore.IsModified(path)) + { + return; + } +#endif + + string 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 + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); +#else + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(); +#endif + + TextMeshPro component = __instance.introduce.GetComponent(); + TextMeshPro component2 = __instance.plantName.GetComponent(); + TextMeshPro component3 = __instance.plantName.transform.GetChild(0).GetComponent(); + TextMeshPro component4 = __instance.cost.GetComponent(); + TextMeshPro component5 = __instance.introduce.GetComponentInChildren(); +#if DEBUG + Log.LogWarning($"Introduce text: {component?.text}"); + Log.LogWarning($"Plant name: {component2?.text}"); +#endif + component.text = Utils.RemoveColorTags(component.text); + + AlmanacPlantBank.PlantData plantData = JsonUtility.FromJson(json); + + foreach (AlmanacPlantBank.PlantInfo plantInfo in plantData.plants) + { + if (plantInfo.seedType == __instance.theSeedType) + { +#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; + + 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; + + component3.text = Utils.RemoveColorTags(plantInfo.name); + component3.autoSizeTextContainer = true; + + component4.text = plantInfo.cost; + + if (hasAlmanacFont) + { + component.font = almanacFontAsset; + component4.font = almanacFontAsset; + } + else + { + component.font = fontAsset; + component4.font = fontAsset; + } + component2.font = fontAsset; + component3.font = fontAsset; + TranslateTextAlmanac(__instance); + } + } + + if (File.Exists(moddedPath)) + { + string moddedJson = File.ReadAllText(moddedPath); + AlmanacPlantBank.PlantData moddedPlantData = JsonUtility.FromJson(moddedJson); + + foreach (AlmanacPlantBank.PlantInfo plantInfo in moddedPlantData.plants) + { + if (plantInfo.seedType == __instance.theSeedType) + { + component.autoSizeTextContainer = false; + component.text = plantInfo.info + "\n\n" + plantInfo.introduce; + component.overflowMode = TextOverflowModes.Page; + + 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; + + component3.text = Utils.RemoveColorTags(plantInfo.name); + component3.autoSizeTextContainer = true; + + component4.text = plantInfo.cost; + + if (hasAlmanacFont) + { + component.font = almanacFontAsset; + component4.font = almanacFontAsset; + } + else + { + component.font = fontAsset; + component4.font = fontAsset; + } + component2.font = fontAsset; + component3.font = fontAsset; + } + } + } + + foreach (TextMeshPro text in __instance.introduce.GetComponentsInChildren()) + { + if (text != null) + { + string originalText = text.text; + text.text = StringStore.TranslateText(text.text); + } + } + TranslateTextAlmanac(__instance); return; - } + } - [HarmonyPatch(nameof(AlmanacPlantBank.OnMouseDown))] - [HarmonyPrefix] - private static bool OnMouseDown(AlmanacPlantBank __instance) - { - TextMeshPro component = __instance.introduce.GetComponent(); - if (component != null) - { - component.pageToDisplay = component.pageToDisplay > component.m_pageNumber ? 1 : component.pageToDisplay + 1; - return false; - } - return true; - } + [HarmonyPatch(nameof(AlmanacPlantBank.OnMouseDown))] + [HarmonyPrefix] + private static bool OnMouseDown(AlmanacPlantBank __instance) + { + TranslateTextAlmanac(__instance); + TextMeshPro component = __instance.introduce.GetComponent(); + if (component != null) + { + component.pageToDisplay = component.pageToDisplay > component.m_pageNumber ? 1 : component.pageToDisplay + 1; + return false; + } + return true; + } - [HarmonyPatch(nameof(AlmanacPlantBank.PVPInit))] - [HarmonyPostfix] - private static void PVPInit(AlmanacPlantBank __instance) - { - TextMeshPro component = __instance.introduce.GetComponent(); - if (component != null) - { - component.autoSizeTextContainer = false; - } - } - } + // 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) + { + + string currentLanguage = Utils.Language.ToString(); + __instance.introduce.text = StringStore.TranslateText(__instance.introduce.text); + __instance.introduce.font = FontStore.LoadTMPFont(currentLanguage); + TextMeshPro textMeshProComponent = __instance.introduce.GetComponent(); + foreach (TextMeshPro text in __instance.introduce.GetComponentsInChildren()) + { + if (text != null) + { + string originalText = text.text; + text.text = StringStore.TranslateText(text.text); + text.font = FontStore.LoadTMPFont(currentLanguage); + } + } + // IDK why this is needed, but put it here to avoid issues + foreach (TextMeshProUGUI text in __instance.introduce.GetComponentsInChildren()) + { + if (text != null) + { + string originalText = text.text; + text.text = StringStore.TranslateText(text.text); + text.font = FontStore.LoadTMPFont(currentLanguage); + } + } + // IDK why this is needed, but put it here to avoid issues + foreach (TMPro.TMP_Text text in __instance.introduce.GetComponentsInChildren()) + { + if (text != null) + { + string originalText = text.text; + text.text = StringStore.TranslateText(text.text); + text.font = FontStore.LoadTMPFont(currentLanguage); + } + } + __instance.plantName.text = StringStore.TranslateText(__instance.plantName.text); + __instance.plantName.transform.GetChild(0).GetComponent().text = StringStore.TranslateText(__instance.plantName.transform.GetChild(0).GetComponent().text); + __instance.plantName.font = FontStore.LoadTMPFont(currentLanguage); + __instance.plantName.transform.GetChild(0).GetComponent().font = FontStore.LoadTMPFont(currentLanguage); + __instance.cost.text = StringStore.TranslateText(__instance.cost.text); + __instance.cost.font = FontStore.LoadTMPFont(currentLanguage); + } + + [HarmonyPatch(nameof(AlmanacPlantBank.PVPInit))] + [HarmonyPostfix] + private static void PVPInit(AlmanacPlantBank __instance) + { + TranslateTextAlmanac(__instance); + TextMeshPro component = __instance.introduce.GetComponent(); + if (component != null) + { + string originalText = component.text; + component.autoSizeTextContainer = false; + component.text = StringStore.TranslateText(component.text); + __instance.introduce.GetComponent().text = component.text; + } + + Transform banTransform = __instance.transform.FindChild("Ban").GetChild(0); + if (banTransform != null) + { + TextMeshPro banText = banTransform.GetComponent(); + string originalBanText = banText.text; + banText.text = StringStore.TranslateText(banText.text); + } + } + } } \ No newline at end of file diff --git a/BepInEx/Patches/Managers/ChessManager_Patch.cs b/BepInEx/Patches/Managers/ChessManager_Patch.cs new file mode 100644 index 0000000..34098ff --- /dev/null +++ b/BepInEx/Patches/Managers/ChessManager_Patch.cs @@ -0,0 +1,38 @@ +using HarmonyLib; + +using TMPro; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using UnityEngine; +using UnityEngine.TextCore.Text; +using UnityEngine.UI; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers +{ + [HarmonyPatch(typeof(ChessManager))] + public static class ChessManager_Patch + { + [HarmonyPatch(nameof(ChessManager.Start))] + [HarmonyPostfix] + private static void Postfix_Start(ChessManager __instance) + { + __instance.textMesh.text = StringStore.TranslateText(__instance.textMesh.text); + __instance.textMesh.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + + [HarmonyPatch(nameof(ChessManager.Update))] + [HarmonyPostfix] + private static void Postfix_Update(ChessManager __instance) + { + __instance.textMesh.text = StringStore.TranslateText(__instance.textMesh.text); + __instance.textMesh.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + + [HarmonyPatch(nameof(ChessManager.UpdateText))] + [HarmonyPostfix] + private static void Postfix_UpdateText(ChessManager __instance) + { + __instance.textMesh.text = StringStore.TranslateText(__instance.textMesh.text); + __instance.textMesh.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + } +} diff --git a/BepInEx/Patches/Managers/DrawCardManager_Patch.cs b/BepInEx/Patches/Managers/DrawCardManager_Patch.cs new file mode 100644 index 0000000..8331d4e --- /dev/null +++ b/BepInEx/Patches/Managers/DrawCardManager_Patch.cs @@ -0,0 +1,45 @@ +using HarmonyLib; +using TMPro; +using System.Collections.Generic; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers +{ + [HarmonyPatch(typeof(DrawCardManager))] + public static class DrawCardManager_Patch + { + // Dùng chung xử lý cập nhật text + private static void TranslateAndApplyFont(Il2CppSystem.Collections.Generic.List texts) + { + if (texts == null || texts.Count == 0) return; + + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var textComponent in texts) + { + if (textComponent == null) continue; + + string translatedText = StringStore.TranslateText(textComponent.text); + textComponent.text = translatedText; + textComponent.font = fontAsset; + } + } + + [HarmonyPostfix] + [HarmonyPatch(nameof(DrawCardManager.UpdateText))] + private static void Postfix_UpdateText(DrawCardManager __instance) + { + __instance.upName = StringStore.TranslateText(__instance.upName); + TranslateAndApplyFont(__instance.texts); + } + + [HarmonyPostfix] + [HarmonyPatch(nameof(DrawCardManager.Update))] + private static void Postfix_Update(DrawCardManager __instance) + { + __instance.upName = StringStore.TranslateText(__instance.upName); + TranslateAndApplyFont(__instance.texts); + } + } +} diff --git a/BepInEx/Patches/Managers/IZEMgr_Patch.cs b/BepInEx/Patches/Managers/IZEMgr_Patch.cs index 16d57be..b78a9f7 100644 --- a/BepInEx/Patches/Managers/IZEMgr_Patch.cs +++ b/BepInEx/Patches/Managers/IZEMgr_Patch.cs @@ -6,12 +6,12 @@ using UnityEngine; namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers { - [HarmonyPatch(typeof(IZEMgr))] + [HarmonyPatch(typeof(IZBottomMenu))] public static class IZEMgr_Patch { - [HarmonyPatch(nameof(IZEMgr.Start))] + [HarmonyPatch(nameof(IZBottomMenu.ChangeString))] [HarmonyPostfix] - public static void Start(IZEMgr __instance) + public static void Start(IZBottomMenu __instance) { TextMeshProUGUI[] array = [ diff --git a/BepInEx/Patches/Managers/InGameUI_Patch.cs b/BepInEx/Patches/Managers/InGameUI_Patch.cs new file mode 100644 index 0000000..be59ae8 --- /dev/null +++ b/BepInEx/Patches/Managers/InGameUI_Patch.cs @@ -0,0 +1,33 @@ +using HarmonyLib; + +using TMPro; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers +{ + [HarmonyPatch(typeof(InGameUI))] + public static class InGameUI_Patch + { + [HarmonyPatch(nameof(InGameUI.Start))] + [HarmonyPostfix] + private static void Start(InGameUI __instance) + { + TextMeshProUGUI[] array = new TextMeshProUGUI[] + { + __instance.transform.GetChild(4).GetComponent(), + __instance.transform.GetChild(4).GetChild(0).GetComponent(), + __instance.transform.GetChild(5).GetComponent(), + __instance.transform.GetChild(5).GetChild(0).GetComponent(), + __instance.transform.GetChild(6).GetComponent(), + __instance.transform.GetChild(6).GetChild(0).GetComponent() + }; + TextMeshProUGUI[] array2 = array; + for (int i = 0; i < array2.Length; i++) + { + + array2[i] = StringStore.TranslateText(array2[i]); + array2[i].text = array2[i].text.Replace("\n", " "); + } + } + } +} diff --git a/BepInEx/PvZ Fusion Translator [BepInEx].csproj b/BepInEx/PvZ Fusion Translator [BepInEx].csproj index fb2d6cc..e47b5b0 100644 --- a/BepInEx/PvZ Fusion Translator [BepInEx].csproj +++ b/BepInEx/PvZ Fusion Translator [BepInEx].csproj @@ -13,7 +13,7 @@ https://nuget.samboy.dev/v3/index.json PvZ_Fusion_Translator__BepInEx_ - C:\Users\rainb\Desktop\PC_PVZ-Fusion_2.5.1-BepInEx + D:\PvZ Fusion\BepInEx Game Files Debug;DebugEnglish;ReleaseMulti;ReleaseEnglish;DebugTesting;ReleaseOther;DebugObfuscate;ReleaseObfuscate;DebugMulti AnyCPU;x64 @@ -21,6 +21,7 @@ + diff --git a/PvZ Fusion Translator.sln b/PvZ Fusion Translator.sln index 24282e5..7403b07 100644 --- a/PvZ Fusion Translator.sln +++ b/PvZ Fusion Translator.sln @@ -10,6 +10,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution README.md = README.md EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PvZ Fusion Translator [BepInEx]", "BepInEx\PvZ Fusion Translator [BepInEx].csproj", "{395E60A0-A884-61F2-EF18-BC94BB7D9C69}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -86,6 +88,54 @@ Global {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseOther|ARM64.Build.0 = ReleaseOther|ARM64 {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseOther|x64.ActiveCfg = ReleaseOther|x64 {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseOther|x64.Build.0 = ReleaseOther|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.Debug|Any CPU.Build.0 = Debug|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.Debug|ARM64.Build.0 = Debug|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.Debug|x64.ActiveCfg = Debug|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.Debug|x64.Build.0 = Debug|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugEnglish|Any CPU.ActiveCfg = DebugEnglish|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugEnglish|Any CPU.Build.0 = DebugEnglish|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugEnglish|ARM64.ActiveCfg = DebugEnglish|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugEnglish|ARM64.Build.0 = DebugEnglish|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugEnglish|x64.ActiveCfg = DebugEnglish|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugEnglish|x64.Build.0 = DebugEnglish|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugObfuscate|Any CPU.ActiveCfg = DebugObfuscate|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugObfuscate|Any CPU.Build.0 = DebugObfuscate|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugObfuscate|ARM64.ActiveCfg = DebugObfuscate|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugObfuscate|ARM64.Build.0 = DebugObfuscate|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugObfuscate|x64.ActiveCfg = DebugObfuscate|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugObfuscate|x64.Build.0 = DebugObfuscate|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugTesting|Any CPU.ActiveCfg = DebugTesting|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugTesting|Any CPU.Build.0 = DebugTesting|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugTesting|ARM64.ActiveCfg = DebugTesting|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugTesting|ARM64.Build.0 = DebugTesting|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugTesting|x64.ActiveCfg = DebugTesting|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugTesting|x64.Build.0 = DebugTesting|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseEnglish|Any CPU.ActiveCfg = ReleaseEnglish|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseEnglish|Any CPU.Build.0 = ReleaseEnglish|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseEnglish|ARM64.ActiveCfg = ReleaseEnglish|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseEnglish|ARM64.Build.0 = ReleaseEnglish|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseEnglish|x64.ActiveCfg = ReleaseEnglish|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseEnglish|x64.Build.0 = ReleaseEnglish|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseMulti|Any CPU.ActiveCfg = ReleaseMulti|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseMulti|Any CPU.Build.0 = ReleaseMulti|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseMulti|ARM64.ActiveCfg = ReleaseMulti|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseMulti|ARM64.Build.0 = ReleaseMulti|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseMulti|x64.ActiveCfg = ReleaseMulti|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseMulti|x64.Build.0 = ReleaseMulti|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseObfuscate|Any CPU.ActiveCfg = ReleaseObfuscate|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseObfuscate|Any CPU.Build.0 = ReleaseObfuscate|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseObfuscate|ARM64.ActiveCfg = ReleaseObfuscate|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseObfuscate|ARM64.Build.0 = ReleaseObfuscate|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseObfuscate|x64.ActiveCfg = ReleaseObfuscate|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseObfuscate|x64.Build.0 = ReleaseObfuscate|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseOther|Any CPU.ActiveCfg = ReleaseOther|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseOther|Any CPU.Build.0 = ReleaseOther|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseOther|ARM64.ActiveCfg = ReleaseOther|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseOther|ARM64.Build.0 = ReleaseOther|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseOther|x64.ActiveCfg = ReleaseOther|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseOther|x64.Build.0 = ReleaseOther|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE