3.7 code i forgot to push 😭

This commit is contained in:
SillyStar-Github 2026-07-06 05:16:02 -04:00
parent 44909e1df4
commit 25cfb74d38
48 changed files with 1053 additions and 424 deletions

15
.idea/.idea.PvZ Fusion Translator/.idea/.gitignore generated vendored Normal file
View file

@ -0,0 +1,15 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/.idea.PvZ Fusion Translator.iml
/contentModel.xml
/projectSettingsUpdater.xml
/modules.xml
# Editor-based HTTP Client requests
/httpRequests/
# Ignored default folder with query files
/queries/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View file

@ -0,0 +1 @@
PvZ Fusion Translator

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DiscordProjectSettings">
<option name="show" value="ASK" />
<option name="description" value="" />
<option name="applicationTheme" value="default" />
<option name="iconsTheme" value="default" />
<option name="button1Title" value="" />
<option name="button1Url" value="" />
<option name="button2Title" value="" />
<option name="button2Url" value="" />
<option name="customApplicationId" value="" />
</component>
</project>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View file

@ -1,4 +1,8 @@
using Il2CppTMPro; using Il2CppTMPro;
using MelonLoader;
using System.Reflection;
using UnityEngine;
using UnityEngine.TextCore.Text;
namespace PvZ_Fusion_Translator.AssetStore namespace PvZ_Fusion_Translator.AssetStore
{ {
@ -11,28 +15,24 @@ namespace PvZ_Fusion_Translator.AssetStore
{ {
string fontsDir = Path.Combine(Core.Instance.modsDirectory, "[Custom Fonts]"); string fontsDir = Path.Combine(Core.Instance.modsDirectory, "[Custom Fonts]");
AssetBundle assetBundle = Utils.GetAssetBundle(Path.Combine(fontsDir, "translation"));
#if MULTI_LANGUAGE #if MULTI_LANGUAGE
foreach (string file in Directory.GetFiles(fontsDir)) foreach (string file in assetBundle.GetAllAssetNames())
{ {
string fileName = Path.GetFileNameWithoutExtension(file); string fileName = Path.GetFileNameWithoutExtension(file);
string fileExtension = Path.GetExtension(file);
if (fileExtension == ".ttf" || fileExtension == ".otf") if (!fileName.EndsWith("_almanac") && !fileName.EndsWith("_fallback"))
{ {
if (!fileName.EndsWith("_Almanac") && !fileName.EndsWith("_Fallback")) TMP_FontAsset fontAsset = assetBundle.LoadAsset<TMP_FontAsset>(file);
{
string fontPath = Path.Combine("PvZ_Fusion_Translator", "[Custom Fonts]", fileName + fileExtension);
TMP_FontAsset fontAsset = FontHandler.LoadTMPFont(fontPath, true); fontAssetDict.Add(fileName, fontAsset);
fontAsset.name = fileName;
fontAssetDict.Add(fileName, fontAsset);
Log.LogInfo($"Font for language '{fileName}' loaded"); Log.LogInfo($"Font for language '{fileName}' loaded");
}
} }
} }
InitFallback(); InitFallback(assetBundle);
#else #else
string defaultFontDir = Path.Combine("PvZ_Fusion_Translator", "[Custom Fonts]", "English.ttf"); string defaultFontDir = Path.Combine("PvZ_Fusion_Translator", "[Custom Fonts]", "English.ttf");
@ -41,43 +41,38 @@ namespace PvZ_Fusion_Translator.AssetStore
#endif #endif
} }
internal static void InitFallback() internal static void InitFallback(AssetBundle assetBundle)
{ {
string fontsDir = Path.Combine(Core.Instance.modsDirectory, "[Custom Fonts]"); string fontsDir = Path.Combine(Core.Instance.modsDirectory, "[Custom Fonts]");
foreach (string file in Directory.GetFiles(fontsDir))
foreach (string file in assetBundle.GetAllAssetNames())
{ {
string fileName = Path.GetFileNameWithoutExtension(file); string fileName = Path.GetFileNameWithoutExtension(file);
string fileExtension = Path.GetExtension(file);
if (fileExtension == ".ttf" || fileExtension == ".otf") if (fileName.EndsWith("_almanac") || fileName.EndsWith("_fallback"))
{ {
if (fileName.EndsWith("_Almanac") || fileName.EndsWith("_Fallback")) TMP_FontAsset fallbackFont = assetBundle.LoadAsset<TMP_FontAsset>(file);
string fileNameLanguage = fileName.Replace("_fallback", "").Replace("_almanac", "");
if (fontAssetDictSecondary.ContainsKey(fileNameLanguage))
{ {
string fallbackPath = Path.Combine("PvZ_Fusion_Translator", "[Custom Fonts]", fileName + fileExtension); if (fileName.EndsWith("_Fallback"))
TMP_FontAsset fallbackFont = FontHandler.LoadTMPFont(fallbackPath, true);
fallbackFont.name = fileName;
string fileNameLanguage = fileName.Replace("_Fallback", "").Replace("_Almanac", "");
if (fontAssetDictSecondary.ContainsKey(fileNameLanguage))
{ {
if (fileName.EndsWith("_Fallback")) fontAssetDictSecondary.Add(fileNameLanguage + "_almanac", fontAssetDictSecondary[fileNameLanguage]);
{ fontAssetDictSecondary.Remove(fileNameLanguage);
fontAssetDictSecondary.Add(fileNameLanguage + "_Almanac", fontAssetDictSecondary[fileNameLanguage]);
fontAssetDictSecondary.Remove(fileNameLanguage);
}
else
{
fontAssetDictSecondary.Add(fileNameLanguage + "_Fallback", fontAssetDictSecondary[fileNameLanguage]);
fontAssetDictSecondary.Remove(fileNameLanguage);
}
fontAssetDictSecondary.Add(fileName, fallbackFont);
} }
else else
fontAssetDictSecondary.Add(fileNameLanguage, fallbackFont); {
fontAssetDictSecondary.Add(fileNameLanguage + "_fallback", fontAssetDictSecondary[fileNameLanguage]);
// Log.LogInfo($"Fallback font for language '{fileNameLanguage}' loaded"); fontAssetDictSecondary.Remove(fileNameLanguage);
}
fontAssetDictSecondary.Add(fileName, fallbackFont);
} }
else
fontAssetDictSecondary.Add(fileNameLanguage, fallbackFont);
// Log.LogInfo($"Fallback font for language '{fileNameLanguage}' loaded");
} }
} }
AddFallback(); AddFallback();
@ -98,15 +93,15 @@ namespace PvZ_Fusion_Translator.AssetStore
Log.LogInfo("Fallback font for language '" + lang + "' added"); Log.LogInfo("Fallback font for language '" + lang + "' added");
continue; continue;
} }
if (fontAssetDictSecondary.ContainsKey(lang + "_Almanac")) if (fontAssetDictSecondary.ContainsKey(lang + "_almanac"))
{ {
fontAssetDict[lang].fallbackFontAssetTable.Add(fontAssetDictSecondary[lang + "_Almanac"]); fontAssetDict[lang].fallbackFontAssetTable.Add(fontAssetDictSecondary[lang + "_almanac"]);
Log.LogInfo("Fallback font for language '" + lang + "' added"); Log.LogInfo("Fallback font for language '" + lang + "' added");
continue; continue;
} }
if (fontAssetDictSecondary.ContainsKey(lang + "_Fallback")) if (fontAssetDictSecondary.ContainsKey(lang + "_fallback"))
{ {
fontAssetDict[lang].fallbackFontAssetTable.Add(fontAssetDictSecondary[lang + "_Fallback"]); fontAssetDict[lang].fallbackFontAssetTable.Add(fontAssetDictSecondary[lang + "_fallback"]);
Log.LogInfo("Fallback font for language '" + lang + "' added"); Log.LogInfo("Fallback font for language '" + lang + "' added");
continue; continue;
} }
@ -116,7 +111,7 @@ namespace PvZ_Fusion_Translator.AssetStore
#if MULTI_LANGUAGE #if MULTI_LANGUAGE
public static TMP_FontAsset LoadTMPFont(string language) public static TMP_FontAsset LoadTMPFont(string language)
{ {
if (fontAssetDict.TryGetValue(language, out TMP_FontAsset font)) if (fontAssetDict.TryGetValue(language.ToLower(), out TMP_FontAsset font))
{ {
TMP_FontAsset fontAsset = font; TMP_FontAsset fontAsset = font;
if (fontAsset.fallbackFontAssetTable != null) if (fontAsset.fallbackFontAssetTable != null)
@ -125,7 +120,7 @@ namespace PvZ_Fusion_Translator.AssetStore
} }
return fontAsset; return fontAsset;
} }
return fontAssetDict.GetValueOrDefault("English"); return fontAssetDict.GetValueOrDefault("english");
} }
#else #else
public static TMP_FontAsset LoadTMPFont() public static TMP_FontAsset LoadTMPFont()
@ -144,15 +139,15 @@ namespace PvZ_Fusion_Translator.AssetStore
return almanacAsset; return almanacAsset;
} }
} }
if (fontAssetDictSecondary.ContainsKey(language + "_Almanac")) if (fontAssetDictSecondary.ContainsKey(language + "_almanac"))
{ {
if (fontAssetDictSecondary.TryGetValue(language + "_Almanac", out TMP_FontAsset almanacAsset)) if (fontAssetDictSecondary.TryGetValue(language + "_almanac", out TMP_FontAsset almanacAsset))
{ {
return almanacAsset; return almanacAsset;
} }
} }
return fontAssetDict.GetValueOrDefault("English"); return fontAssetDict.GetValueOrDefault("english");
} }
#if MULTI_LANGUAGE #if MULTI_LANGUAGE

View file

@ -1,6 +1,5 @@
using Il2CppSystem.Runtime.Remoting.Messaging; using Il2CppTMPro;
using Il2CppTMPro; using PvZ_Fusion_Translator.Patches.BaseTextObjects;
using System.Diagnostics;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using UnityEngine; using UnityEngine;
@ -90,17 +89,12 @@ namespace PvZ_Fusion_Translator.AssetStore
izTipCollectionString.Clear(); izTipCollectionString.Clear();
fsLevelTipDictionary.Clear(); fsLevelTipDictionary.Clear();
fsTipCollectionString.Clear(); fsTipCollectionString.Clear();
InGameText_Patch.currentText = "";
FileLoader.LoadStrings(); FileLoader.LoadStrings();
} }
public static TextMeshPro TranslateText(TextMeshPro originalTMP, bool isLog = false) public static TextMeshPro TranslateText(TextMeshPro originalTMP, bool isLog = false)
{ {
/*var frame = new StackTrace().GetFrame(1);
var method = frame.GetMethod();
var className = method.DeclaringType.Name;
Console.WriteLine($"TextMeshPro: {className}.{method.Name}");*/
#if MULTI_LANGUAGE #if MULTI_LANGUAGE
string currentLanguage = Utils.Language.ToString(); string currentLanguage = Utils.Language.ToString();
TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage);
@ -139,12 +133,6 @@ namespace PvZ_Fusion_Translator.AssetStore
public static string TranslateText(string originalText, bool isLog = false) public static string TranslateText(string originalText, bool isLog = false)
{ {
/*var frame = new StackTrace().GetFrame(1);
var method = frame.GetMethod();
var className = method.DeclaringType.Name;
Console.WriteLine($"string: {className}.{method.Name}");*/
string text = DoTranslateText(originalText, false); string text = DoTranslateText(originalText, false);
string checkText; string checkText;
#if DEBUG #if DEBUG
@ -183,9 +171,7 @@ namespace PvZ_Fusion_Translator.AssetStore
for (int i = 1; i < groupCount; i++) for (int i = 1; i < groupCount; i++)
{ {
string groupValue = match.Groups[i].Value; string groupValue = match.Groups[i].Value;
string translatedValue = translationString.ContainsKey(groupValue) string translatedValue = DoTranslateString(groupValue);
? translationString[groupValue]
: groupValue;
dynamicParts.Add(translatedValue); dynamicParts.Add(translatedValue);
} }
@ -232,7 +218,7 @@ namespace PvZ_Fusion_Translator.AssetStore
} }
} }
public static string DoTranslateText(string originalText, bool isLog = false) public static string DoTranslateString(string originalText, bool isLog = false)
{ {
if (string.IsNullOrEmpty(originalText)) if (string.IsNullOrEmpty(originalText))
{ {
@ -276,6 +262,73 @@ namespace PvZ_Fusion_Translator.AssetStore
return customLevelString[originalText]; return customLevelString[originalText];
} }
if (Utils.plantIndiceString.ContainsKey(originalText))
{
if(isLog)
{
Log.LogDebug($"Text '{originalText}' found in plantIndiceString");
}
return Utils.plantIndiceString[originalText];
}
return originalText;
}
public static string DoTranslateText(string originalText, bool isLog = false)
{
if (string.IsNullOrEmpty(originalText))
{
if (isLog)
Log.LogError("Text Null or Empty");
return string.Empty;
}
if (!Utils.CheckForUntranslatedText(originalText) && !(originalText).Contains("_")) return originalText;
if (translationString.ContainsKey(originalText))
{
if (isLog)
Log.LogDebug($"Text '{originalText} found in translationString");
return translationString[originalText];
}
if(izTipCollectionString.ContainsKey(originalText))
{
if(isLog)
{
Log.LogDebug($"Text '{originalText}' found in izTipCollectionString");
}
return izTipCollectionString[originalText];
}
if(fsTipCollectionString.ContainsKey(originalText))
{
if(isLog)
{
Log.LogDebug($"Text '{originalText}' found in fsTipCollectionString");
}
return fsTipCollectionString[originalText];
}
if(customLevelString.ContainsKey(originalText))
{
if(isLog)
{
Log.LogDebug($"Text '{originalText}' found in customLevelString");
}
return customLevelString[originalText];
}
if (Utils.plantIndiceString.ContainsKey(originalText))
{
if(isLog)
{
Log.LogDebug($"Text '{originalText}' found in plantIndiceString");
}
return Utils.plantIndiceString[originalText];
}
// Regex-based dynamic translation // Regex-based dynamic translation
foreach (var entry in translationStringRegex) foreach (var entry in translationStringRegex)
{ {
@ -296,9 +349,7 @@ namespace PvZ_Fusion_Translator.AssetStore
for (int i = 1; i < groupCount; i++) for (int i = 1; i < groupCount; i++)
{ {
string groupValue = match.Groups[i].Value; string groupValue = match.Groups[i].Value;
string translatedValue = translationString.ContainsKey(groupValue) string translatedValue = DoTranslateString(groupValue);
? translationString[groupValue]
: groupValue;
dynamicParts.Add(translatedValue); dynamicParts.Add(translatedValue);
} }

View file

@ -1,13 +1,8 @@
using Il2Cpp; using MelonLoader;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Utils; using MelonLoader.Utils;
using PvZ_Fusion_Translator.AssetStore; using PvZ_Fusion_Translator.AssetStore;
using PvZ_Fusion_Translator.Patches.Managers; using PvZ_Fusion_Translator.Patches.Managers;
using PvZ_Fusion_Translator.Patches.Modes.Odyssey;
using PvZ_Fusion_Translator.Patches.Modes.Super_Editor; using PvZ_Fusion_Translator.Patches.Modes.Super_Editor;
using System.Runtime.CompilerServices;
using System.Text.Json;
using UnityEngine; using UnityEngine;
using static PvZ_Fusion_Translator.FileLoader; using static PvZ_Fusion_Translator.FileLoader;
@ -21,6 +16,7 @@ namespace PvZ_Fusion_Translator
private static DateTime dtStart; private static DateTime dtStart;
private static DateTime? dtStartToast; private static DateTime? dtStartToast;
private static string toast_txt; private static string toast_txt;
public static bool isInitialized = false;
public static Core Instance { get; private set; } public static Core Instance { get; private set; }
object replaceTextureRoutine = null; object replaceTextureRoutine = null;
@ -32,8 +28,6 @@ namespace PvZ_Fusion_Translator
base.OnInitializeMelon(); base.OnInitializeMelon();
Instance = this; Instance = this;
//DllStore.Init(MelonLoader.InternalUtils.UnityInformationHandler.GameVersion);
Config(); Config();
#if MULTI_LANGUAGE #if MULTI_LANGUAGE
FileLoader.LoadLanguage(); FileLoader.LoadLanguage();
@ -42,9 +36,8 @@ namespace PvZ_Fusion_Translator
StringStore.Init(); StringStore.Init();
AudioStore.Init(); AudioStore.Init();
FontStore.Init(); FontStore.Init();
Utils.RegisterPlantIndices();
//Utils.RegisterRecipeLinks(); isInitialized = true;
} }
public override void OnLateInitializeMelon() public override void OnLateInitializeMelon()
@ -52,6 +45,7 @@ namespace PvZ_Fusion_Translator
dtStart = DateTime.Now; dtStart = DateTime.Now;
replaceTextureRoutine = MelonCoroutines.Start(TextureStore.ReplaceTexturesCoroutine()); replaceTextureRoutine = MelonCoroutines.Start(TextureStore.ReplaceTexturesCoroutine());
LoadTravelBuffs(); LoadTravelBuffs();
Utils.RegisterPlantIndices();
} }
public override void OnDeinitializeMelon() public override void OnDeinitializeMelon()

View file

@ -159,14 +159,14 @@ namespace PvZ_Fusion_Translator
if(plantAlmanacContent != null) if(plantAlmanacContent != null)
{ {
AlmanacPlantMenu_Patch.almanacJson = plantAlmanacContent; AlmanacPlantMenu_Patch.LoadPlantAlmanacData(plantAlmanacContent);
} }
else else
{ {
string path = Path.Combine(almanacDir, "LawnStringsTranslate.json"); string path = Path.Combine(almanacDir, "LawnStringsTranslate.json");
if(File.Exists(path)) if(File.Exists(path))
{ {
AlmanacPlantMenu_Patch.almanacJson = File.ReadAllText(path); AlmanacPlantMenu_Patch.LoadPlantAlmanacData(File.ReadAllText(path));
} }
} }
@ -199,6 +199,10 @@ namespace PvZ_Fusion_Translator
} }
} }
// load travel_buffs
LoadTravelBuffs();
// load abyss buffs // load abyss buffs
Patches.Modes.Abyss.AbyssBuffMenu_Patch.LoadAbyssBuffData(); Patches.Modes.Abyss.AbyssBuffMenu_Patch.LoadAbyssBuffData();
@ -259,6 +263,10 @@ namespace PvZ_Fusion_Translator
{ {
Patches.Modes.Abyss.AbyssBuffMenu_Patch.LoadAbyssBuffData(); Patches.Modes.Abyss.AbyssBuffMenu_Patch.LoadAbyssBuffData();
} }
else if (fileName.EndsWith("travel_buffs"))
{
LoadTravelBuffs();
}
} }
string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language);
@ -272,7 +280,7 @@ namespace PvZ_Fusion_Translator
if(File.Exists(plantAlmanacPath)) if(File.Exists(plantAlmanacPath))
{ {
AlmanacPlantMenu_Patch.almanacJson = File.ReadAllText(plantAlmanacPath); AlmanacPlantMenu_Patch.LoadPlantAlmanacData(File.ReadAllText(plantAlmanacPath));
} }
string zombieAlmanacPath = Path.Combine(almanacDir, "ZombieStringsTranslate.json"); string zombieAlmanacPath = Path.Combine(almanacDir, "ZombieStringsTranslate.json");
@ -429,6 +437,10 @@ namespace PvZ_Fusion_Translator
changelogText = changelogContent; changelogText = changelogContent;
} }
} }
else
{
changelogText = File.ReadAllText(changelogDir);
}
NoticePauseMenu_Patch.changelogText = changelogText; NoticePauseMenu_Patch.changelogText = changelogText;
} }
@ -441,14 +453,14 @@ namespace PvZ_Fusion_Translator
if (travelBuffsContent != null) if (travelBuffsContent != null)
{ {
TravelMgr_Patch.translatedTravelBuffs = TravelMgr_Patch.GenerateTranslatedTravelBuffs(travelBuffsContent); TravelMgr_Patch.GenerateTranslatedTravelBuffs(travelBuffsContent);
} }
else else
{ {
string travelBuffsPath = Path.Combine(GetAssetDir(AssetType.Strings, Utils.Language), "travel_buffs.json"); string travelBuffsPath = Path.Combine(GetAssetDir(AssetType.Strings, Utils.Language), "travel_buffs.json");
if (File.Exists(travelBuffsPath)) if (File.Exists(travelBuffsPath))
{ {
TravelMgr_Patch.translatedTravelBuffs = TravelMgr_Patch.GenerateTranslatedTravelBuffs(File.ReadAllText(travelBuffsPath)); TravelMgr_Patch.GenerateTranslatedTravelBuffs(File.ReadAllText(travelBuffsPath));
} }
} }
} }
@ -462,7 +474,7 @@ namespace PvZ_Fusion_Translator
string jsonString = File.ReadAllText(filepath); string jsonString = File.ReadAllText(filepath);
if (fileName.EndsWith("travel_buffs")) if (fileName.EndsWith("travel_buffs"))
{ {
TravelMgr_Patch.translatedTravelBuffs = TravelMgr_Patch.GenerateTranslatedTravelBuffs(jsonString); TravelMgr_Patch.GenerateTranslatedTravelBuffs(jsonString);
} }
} }
} }

View file

@ -1,5 +1,6 @@
using HarmonyLib; using HarmonyLib;
using Il2Cpp; using Il2Cpp;
using Il2CppCore;
using Il2CppAlmanacData; using Il2CppAlmanacData;
using Il2CppTMPro; using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore; using PvZ_Fusion_Translator.AssetStore;
@ -74,6 +75,7 @@ namespace PvZ_Fusion_Translator.Patches.BaseTextObjects
string godsGachaMatch = ""; string godsGachaMatch = "";
string superEditorPlantMatch = CheckSuperEditorPopup(originalText); string superEditorPlantMatch = CheckSuperEditorPopup(originalText);
string customLevelRegexMatch = CheckCustomLevelRegex(originalText); string customLevelRegexMatch = CheckCustomLevelRegex(originalText);
string qualityCheckMatch = CheckQualityUpgrade(originalText);
switch(godsGachaCheck) switch(godsGachaCheck)
{ {
@ -112,6 +114,10 @@ namespace PvZ_Fusion_Translator.Patches.BaseTextObjects
} }
} }
} }
else if(qualityCheckMatch != "")
{
txt.text = qualityCheckMatch;
}
else if(superEditorPlantMatch != "") else if(superEditorPlantMatch != "")
{ {
txt.text = superEditorPlantMatch; txt.text = superEditorPlantMatch;
@ -164,8 +170,10 @@ namespace PvZ_Fusion_Translator.Patches.BaseTextObjects
public static string nameAlreadyPlantedPattern = "场上已经有一个([^\\s]+)了"; public static string nameAlreadyPlantedPattern = "场上已经有一个([^\\s]+)了";
public static string upgradePathRemovedPattern = "已移除路线:([^\\s]+)"; public static string upgradePathRemovedPattern = "已移除路线:([^\\s]+)";
public static string lockedPlantPattern = "^([^\\s:]+)\\+([^\\s:]+)"; public static string lockedPlantPattern = "^([\\s\\S]+)\\+([\\S]+)$";
public static string multiLockedPlantPattern = "^或 ([^\\s:]+)\\+([^\\s:]+)"; public static string multiLockedPlantPattern = "^或 ([\\s\\S]+)\\+([\\S]+)$";
public static string qualityChangePattern = "诸神注视着你,并选中了一个他们喜欢的词条\n植物<color=green>【([\\S]+)】</color>的词条<color=yellow>【强化:([\\S]+)】</color>获得品质升级\n当前品质:([\\S]+)";
public static Dictionary<string, string> fallbackFStrs = new Dictionary<string, string>() public static Dictionary<string, string> fallbackFStrs = new Dictionary<string, string>()
{ {
@ -175,7 +183,8 @@ namespace PvZ_Fusion_Translator.Patches.BaseTextObjects
{ upgradePathRemovedPattern, "Upgrade Path removed for {0}" }, { upgradePathRemovedPattern, "Upgrade Path removed for {0}" },
{ @"([^\s]+)\((\d+)\)", "{0}({1})" }, { @"([^\s]+)\((\d+)\)", "{0}({1})" },
{ lockedPlantPattern, "{0} + {1}" }, { lockedPlantPattern, "{0} + {1}" },
{ multiLockedPlantPattern, "or {0} + {1}" } { multiLockedPlantPattern, "or {0} + {1}" },
{ qualityChangePattern, "The gods are watching you, and they have granted you an upgrade!\nThe <color=yellow>{1}</color> upgrade for <color=green>{0}</color> has been upgraded.\nCurrent Quality: {2}" }
}; };
public static int CheckGodsGachaPopup(string originalText) public static int CheckGodsGachaPopup(string originalText)
@ -205,13 +214,13 @@ namespace PvZ_Fusion_Translator.Patches.BaseTextObjects
switch(type) switch(type)
{ {
case 1: case 1:
res = TranslatePlantNameParts(originalText, namePlantedPattern); res = StringStore.TranslateText(originalText, namePlantedPattern);
break; break;
case 2: case 2:
res = TranslatePlantNameParts(originalText, nameUpgradedPattern); res = StringStore.TranslateText(originalText, nameUpgradedPattern);
break; break;
case 3: case 3:
res = TranslatePlantNameParts(originalText, nameAlreadyPlantedPattern); res = StringStore.TranslateText(originalText, nameAlreadyPlantedPattern);
break; break;
default: default:
break; break;
@ -269,7 +278,7 @@ namespace PvZ_Fusion_Translator.Patches.BaseTextObjects
if(Regex.IsMatch(originalText, upgradePathRemovedPattern)) if(Regex.IsMatch(originalText, upgradePathRemovedPattern))
{ {
res = TranslatePlantNameParts(originalText, upgradePathRemovedPattern); res = StringStore.TranslateText(originalText, upgradePathRemovedPattern);
} }
else if(Regex.IsMatch(originalText, "当前全部基础植物:(.*)")) else if(Regex.IsMatch(originalText, "当前全部基础植物:(.*)"))
{ {
@ -316,17 +325,14 @@ namespace PvZ_Fusion_Translator.Patches.BaseTextObjects
string firstLine = lines[0]; string firstLine = lines[0];
Match match = lockedPlantRegex.Match(firstLine); Match match = lockedPlantRegex.Match(firstLine);
GroupCollection groups = match.Groups; GroupCollection groups = match.Groups;
Log.LogDebug(Utils.plantIndiceStrings.ContainsKey(groups[1].Value)); if (Utils.plantIndiceString.ContainsKey(groups[1].Value) && Utils.plantIndiceString.ContainsKey(groups[2].Value))
Log.LogDebug(Utils.plantIndiceStrings.ContainsKey(groups[2].Value));
if (Utils.plantIndiceStrings.ContainsKey(groups[1].Value) && Utils.plantIndiceStrings.ContainsKey(groups[2].Value))
{ {
firstLine = TranslatePlantNameParts(firstLine, lockedPlantPattern); firstLine = StringStore.TranslateText(firstLine, lockedPlantPattern);
List<string> translatedLines = new List<string>() { firstLine }; List<string> translatedLines = new List<string>() { firstLine };
for(int i = 1; i < lines.Length; i++) for(int i = 1; i < lines.Length; i++)
{ {
string nextLine = lines[i]; string nextLine = lines[i];
Log.LogDebug(nextLine); string translatedNextLine = StringStore.TranslateText(nextLine, multiLockedPlantPattern);
string translatedNextLine = TranslatePlantNameParts(nextLine, multiLockedPlantPattern);
translatedLines.Add(translatedNextLine); translatedLines.Add(translatedNextLine);
} }
res = string.Join("\n", translatedLines); res = string.Join("\n", translatedLines);
@ -343,9 +349,9 @@ namespace PvZ_Fusion_Translator.Patches.BaseTextObjects
{ {
Match match = lockedPlantRegex.Match(originalText); Match match = lockedPlantRegex.Match(originalText);
GroupCollection groups = match.Groups; GroupCollection groups = match.Groups;
if (Utils.plantIndiceStrings.ContainsKey(groups[1].Value) && Utils.plantIndiceStrings.ContainsKey(groups[2].Value)) if (Utils.plantIndiceString.ContainsKey(groups[1].Value) && Utils.plantIndiceString.ContainsKey(groups[2].Value))
{ {
res = TranslatePlantNameParts(originalText, lockedPlantPattern); res = StringStore.TranslateText(originalText, lockedPlantPattern);
} }
else else
{ {
@ -371,5 +377,17 @@ namespace PvZ_Fusion_Translator.Patches.BaseTextObjects
} }
return res; return res;
} }
public static string CheckQualityUpgrade(string originalText)
{
string res = "";
if(Regex.IsMatch(originalText, qualityChangePattern))
{
res = StringStore.TranslateText(originalText, qualityChangePattern);
}
return res;
}
} }
} }

View file

@ -17,6 +17,10 @@ namespace PvZ_Fusion_Translator.Patches.BaseTextObjects
{ {
if (!string.IsNullOrEmpty(__instance.text)) if (!string.IsNullOrEmpty(__instance.text))
{ {
__instance.font = FontStore.LoadTMPFont(Utils.Language.ToString());
if (!Utils.CheckForUntranslatedText(__instance.text) && !(__instance.text).Contains("_")) return;
if(__instance.transform.parent != null) if(__instance.transform.parent != null)
{ {
if(__instance.transform.parent.name.Contains("DrawCardsText")) if(__instance.transform.parent.name.Contains("DrawCardsText"))

View file

@ -0,0 +1,91 @@
using HarmonyLib;
using Il2Cpp;
using Il2CppAlmanacData;
using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore;
using UnityEngine;
using System.Drawing;
using static Il2Cpp.AlmanacBuffMenu;
using static PvZ_Fusion_Translator.FileLoader;
using static PvZ_Fusion_Translator.Patches.Modes.Odyssey.TravelMgr_Patch;
using static PvZ_Fusion_Translator.Utils;
namespace PvZ_Fusion_Translator.Patches.GameObjects
{
[HarmonyPatch(typeof(AlmanacBuffMenu))]
public static class AlmanacBuffMenu_Patch
{
public static Dictionary<string, string> modifierNameDict = new Dictionary<string, string>()
{
{ "advancedBuffs", "COMMON_MODIFIER_TAG" },
{ "ultimateBuffs", "EPIC_MODIFIER_TAG" },
{ "debuffs", "ZOMBIE_MODIFIER_TAG" },
{ "unlocks", "UNLOCK_MODIFIER_TAG" },
{ "investmentBuffs", "INVEST_MODIFIER_TAG" }
};
public static Dictionary<string, string> fallbackNameDict = new Dictionary<string, string>()
{
{ "COMMON_MODIFIER_TAG", "Common Modifier" },
{ "EPIC_MODIFIER_TAG", "Epic Modifier" },
{ "ZOMBIE_MODIFIER_TAG", "Zombie Modifier" },
{ "UNLOCK_MODIFIER_TAG", "Unlock Modifier" },
{ "INVEST_MODIFIER_TAG", "Investment Modifier" }
};
public static string TranslateNameTag(string originalText)
{
string res = originalText;
string nameTag = modifierNameDict[originalText];
res = StringStore.translationString.ContainsKey(nameTag) ? StringStore.TranslateText(nameTag) : fallbackNameDict[nameTag];
return res;
}
[HarmonyPatch(nameof(AlmanacBuffMenu.Awake))]
[HarmonyPostfix]
public static void Post_Awake(AlmanacBuffMenu __instance)
{
foreach(AlmanacCardUI cardUI in __instance.cards)
{
AlmanacBuffMenu.CardInfo cardInfo = __instance.cardInfos[cardUI];
var buffData = FindBuffData(cardInfo.description);
if (buffData.Item1 == null || buffData.Item3 == null) continue;
string nameTag = TranslateNameTag(buffData.Item1);
cardUI.cost.text = $"{nameTag} #{buffData.Item2}";
}
Post_OnCardClick(__instance);
}
[HarmonyPatch(nameof(AlmanacBuffMenu.OnCardClick))]
[HarmonyPostfix]
public static void Post_OnCardClick(AlmanacBuffMenu __instance)
{
var buffData = FindBuffData(__instance.buffDescription.text);
if (buffData.Item1 == null || buffData.Item3 == null) return;
string nameTag = TranslateNameTag(buffData.Item1);
__instance.buffTitle.text = $"{nameTag} #{buffData.Item2}";
__instance.buffTitle.font = FontStore.LoadTMPFont(Utils.Language.ToString());
__instance.buffDescription.text = buffData.Item3 + "\n\n";
__instance.buffDescription.font = FontStore.LoadTMPFont(Utils.Language.ToString());
string colorHex = StringStore.translationString.ContainsKey("MOD_ALMANAC_COL") ? StringStore.TranslateText("MOD_ALMANAC_COL") : "#000000";
System.Drawing.Color descriptionColor = ColorTranslator.FromHtml(colorHex);
__instance.buffDescription.color = new UnityEngine.Color(descriptionColor.R / 255.0f, descriptionColor.G / 255.0f, descriptionColor.B / 255.0f);
__instance.buffDescription.fontSizeMax = 18;
__instance.buffDescription.margin = new Vector4(8, 4, 25, 0);
__instance.buffDescription.enableWordWrapping = true;
__instance.buffDescription.overflowMode = TextOverflowModes.ScrollRect;
Canvas.ForceUpdateCanvases();
__instance.buffDescription.ForceMeshUpdate();
}
}
}

View file

@ -1,10 +1,6 @@
using HarmonyLib; using HarmonyLib;
using Il2Cpp; using Il2Cpp;
using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore; using PvZ_Fusion_Translator.AssetStore;
using UnityEngine;
using System.Text.RegularExpressions;
using Unity.VisualScripting;
namespace PvZ_Fusion_Translator.Patches.GameObjects namespace PvZ_Fusion_Translator.Patches.GameObjects
{ {
@ -19,14 +15,14 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
__instance.cost.text = StringStore.TranslateText(__instance.cost.text); __instance.cost.text = StringStore.TranslateText(__instance.cost.text);
} }
[HarmonyPatch(nameof(AlmanacCardUI.OnPointerDown))] /*[HarmonyPatch(nameof(AlmanacCardUI.OnPointerDown))]
[HarmonyPostfix] [HarmonyPostfix]
public static void OnPointerDown(AlmanacCardUI __instance) public static void OnPointerDown(AlmanacCardUI __instance)
{ {
foreach(AlmanacCardUI almanacCardUI in __instance.menu.GetComponentsInChildren<AlmanacCardUI>()) foreach (AlmanacCardUI almanacCardUI in __instance.menu.GetComponentsInChildren<AlmanacCardUI>())
{ {
AlmanacCardUI_Patch.Awake(almanacCardUI); AlmanacCardUI_Patch.Awake(almanacCardUI);
} }
} }*/
} }
} }

View file

@ -2,7 +2,9 @@
using Il2Cpp; using Il2Cpp;
using Il2CppAlmanacData; using Il2CppAlmanacData;
using Il2CppTMPro; using Il2CppTMPro;
using MelonLoader.TinyJSON;
using PvZ_Fusion_Translator.AssetStore; using PvZ_Fusion_Translator.AssetStore;
using System.Text.Json;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Unity.Collections; using Unity.Collections;
using Unity.VisualScripting; using Unity.VisualScripting;
@ -18,6 +20,7 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
public static class AlmanacPlantMenu_Patch public static class AlmanacPlantMenu_Patch
{ {
public static string almanacJson = ""; public static string almanacJson = "";
public static Dictionary<int, Il2CppAlmanacData.PlantInfo> plantInfoDict = new();
[HarmonyPatch(nameof(AlmanacPlantMenu.Awake))] [HarmonyPatch(nameof(AlmanacPlantMenu.Awake))]
[HarmonyPostfix] [HarmonyPostfix]
@ -35,7 +38,7 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
} }
} }
foreach(AlmanacCardUI almanacCardUI in __instance.GetComponentsInChildren<AlmanacCardUI>()) foreach (AlmanacCardUI almanacCardUI in __instance.GetComponentsInChildren<AlmanacCardUI>())
{ {
AlmanacCardUI_Patch.Awake(almanacCardUI); AlmanacCardUI_Patch.Awake(almanacCardUI);
} }
@ -44,10 +47,7 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
AlmanacPlantWindow window = __instance.window; AlmanacPlantWindow window = __instance.window;
GameObject skinButton = window.skinButton; GameObject skinButton = window.skinButton;
GameObject skinTextObj = skinButton.transform.GetChild(0).gameObject; GameObject skinTextObj = skinButton.transform.Find("text_1").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.localScale /= 1.75f;
skinButton.transform.localPosition = new Vector3(0.0f, 111.345f, 0.0f); skinButton.transform.localPosition = new Vector3(0.0f, 111.345f, 0.0f);
skinButton.transform.GetChild(1).Translate(new Vector3(-0.35f, 0)); skinButton.transform.GetChild(1).Translate(new Vector3(-0.35f, 0));
@ -79,6 +79,10 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
{ {
searchedPlants.Add((PlantType)plantInfo.seedType); searchedPlants.Add((PlantType)plantInfo.seedType);
} }
else if ($"{plantInfo.seedType}".ToLower().StartsWith(search.ToLower()))
{
searchedPlants.Add((PlantType)plantInfo.seedType);
}
} }
__instance.ShowPlants(searchedPlants); __instance.ShowPlants(searchedPlants);
@ -88,5 +92,46 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
return true; return true;
} }
[HarmonyPatch(nameof(AlmanacPlantMenu.ShowPlants), argumentTypes: [typeof(Il2CppSystem.Func<PlantType, bool>)])]
[HarmonyPostfix]
public static void ShowPlants(AlmanacPlantMenu __instance, ref Func<PlantType, bool> condition)
{
foreach (AlmanacCardUI cardUI in __instance.cards)
{
AlmanacCardUI_Patch.Awake(cardUI);
}
}
[HarmonyPatch(nameof(AlmanacPlantMenu.ClassicMix))]
[HarmonyPostfix]
public static void ClassicMix(AlmanacPlantMenu __instance)
{
foreach (AlmanacCardUI cardUI in __instance.cards)
{
AlmanacCardUI_Patch.Awake(cardUI);
}
}
public static void LoadPlantAlmanacData(string json)
{
if (json == null) return;
almanacJson = json;
var plantData = JsonUtility.FromJson<Il2CppAlmanacData.AlmanacData>(almanacJson);
foreach (Il2CppAlmanacData.PlantInfo plantInfo in plantData.plants)
{
if(plantInfoDict.ContainsKey(plantInfo.seedType))
{
plantInfoDict[plantInfo.seedType] = plantInfo;
}
else
{
plantInfoDict.Add(plantInfo.seedType, plantInfo);
}
}
}
} }
} }

View file

@ -1,5 +1,6 @@
using HarmonyLib; using HarmonyLib;
using Il2Cpp; using Il2Cpp;
using Il2CppAlmanacData;
using Il2CppTMPro; using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore; using PvZ_Fusion_Translator.AssetStore;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
@ -34,35 +35,34 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
TMP_FontAsset fontAsset = (hasAlmanacFont) ? FontStore.LoadTMPFontAlmanac(Utils.Language.ToString()) : FontStore.LoadTMPFont(Utils.Language.ToString()); TMP_FontAsset fontAsset = (hasAlmanacFont) ? FontStore.LoadTMPFontAlmanac(Utils.Language.ToString()) : FontStore.LoadTMPFont(Utils.Language.ToString());
Il2CppAlmanacData.AlmanacData plantData = JsonUtility.FromJson<Il2CppAlmanacData.AlmanacData>(json); AlmanacData plantData = JsonUtility.FromJson<AlmanacData>(json);
foreach (Il2CppAlmanacData.PlantInfo plantInfo in plantData.plants) if(AlmanacPlantMenu_Patch.plantInfoDict.ContainsKey((int)__instance.currentPlantType))
{ {
if (plantInfo.seedType == (int)__instance.currentPlantType) PlantInfo plantInfo = AlmanacPlantMenu_Patch.plantInfoDict[(int)__instance.currentPlantType];
foreach (TextMeshProUGUI text in __instance.showedPlantName)
{ {
foreach (TextMeshProUGUI text in __instance.showedPlantName) text.autoSizeTextContainer = false;
{ text.text = $"{Utils.RemoveSizeTags(plantInfo.name)} ({plantInfo.seedType})";
text.autoSizeTextContainer = false; text.font = fontAsset;
text.text = $"{Utils.RemoveSizeTags(plantInfo.name)} ({plantInfo.seedType})"; text.fontSizeMax = 21;
text.font = fontAsset;
text.fontSizeMax = 21;
}
char[] toTrim = Environment.NewLine.ToCharArray();
__instance.showedPlantIntroduce.text = Utils.RemoveSizeTags(plantInfo.info) + "\n\n" + Utils.RemoveSizeTags(plantInfo.introduce) + "\n\n" + Utils.RemoveSizeTags(plantInfo.cost).TrimStart(toTrim) + "\n\n";
__instance.showedPlantIntroduce.font = fontAsset;
__instance.showedPlantIntroduce.fontSizeMax = 21;
__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);
} }
char[] toTrim = Environment.NewLine.ToCharArray();
__instance.showedPlantIntroduce.text = Utils.RemoveSizeTags(plantInfo.info) + "\n\n" + Utils.RemoveSizeTags(plantInfo.introduce) + "\n\n" + Utils.RemoveSizeTags(plantInfo.cost).TrimStart(toTrim) + "\n\n";
__instance.showedPlantIntroduce.font = fontAsset;
__instance.showedPlantIntroduce.fontSizeMax = 21;
__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

@ -18,12 +18,12 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
TranslateAlmanacMenu(__instance); TranslateAlmanacMenu(__instance);
} }
[HarmonyPatch(nameof(Almanac.OldAlmanac))] /*[HarmonyPatch(nameof(Almanac.OldAlmanac))]
[HarmonyPostfix] [HarmonyPostfix]
private static void OldAlmanac(Almanac __instance) private static void OldAlmanac(Almanac __instance)
{ {
TranslateAlmanacMenu(__instance); TranslateAlmanacMenu(__instance);
} }*/
[HarmonyPatch(nameof(Almanac.AnimSwitch))] [HarmonyPatch(nameof(Almanac.AnimSwitch))]
[HarmonyPostfix] [HarmonyPostfix]

View file

@ -35,6 +35,11 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
MainMenu_Patch.AnimOver(__instance); MainMenu_Patch.AnimOver(__instance);
} }
if(__instance.name.StartsWith("PlantDamageMenu"))
{
PlantDamageMenu_Patch.Awake(__instance);
}
TranslateBaseMenuTransform(__instance, "Level"); TranslateBaseMenuTransform(__instance, "Level");
TranslateBaseMenuTransform(__instance, "Levels"); TranslateBaseMenuTransform(__instance, "Levels");
TranslateBaseMenuTransform(__instance, "CustomLevel"); TranslateBaseMenuTransform(__instance, "CustomLevel");

View file

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HarmonyLib;
using Il2Cpp;
using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore;
using UnityEngine;
namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects
{
public static class LevelSaveEnter_Patch
{
public static void TranslateEnter(LevelSaveEnter __instance)
{
TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString());
__instance.text.text = StringStore.TranslateText(__instance.text.text);
__instance.text.font = fontAsset;
}
}
}

View file

@ -14,7 +14,6 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
[HarmonyPatch(typeof(LevelResultMenu))] [HarmonyPatch(typeof(LevelResultMenu))]
public static class LevelResultMenu_Patch public static class LevelResultMenu_Patch
{ {
[HarmonyPatch(nameof(LevelResultMenu.Awake))]
[HarmonyPatch(nameof(LevelResultMenu.Start))] [HarmonyPatch(nameof(LevelResultMenu.Start))]
[HarmonyPatch(nameof(LevelResultMenu.ShowResult))] [HarmonyPatch(nameof(LevelResultMenu.ShowResult))]
[HarmonyPostfix] [HarmonyPostfix]

View file

@ -45,12 +45,13 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
} }
} }
OptionBtn templateButton = newOptionsMenu.transform.Find("F").GetComponent<OptionBtn>(); OptionBtn templateButton = newOptionsMenu.transform.Find("Buttons/F").GetComponent<OptionBtn>();
OptLanguageBtn_Patch.OptLangBtn_Patch.Awake(templateButton); OptLanguageBtn_Patch.OptLangBtn_Patch.Awake(templateButton);
UIButton goBackButton = newOptionsMenu.transform.Find("Goback").GetComponent<UIButton>(); UIButton goBackButton = newOptionsMenu.transform.Find("Goback").GetComponent<UIButton>();
newOptionsMenu.transform.Find("F").gameObject.SetActive(false); newOptionsMenu.transform.Find("Buttons/F").gameObject.SetActive(false);
newOptionsMenu.transform.Find("Buttons").gameObject.SetActive(true);
foreach (TextMeshProUGUI text in newOptionsMenu.transform.Find("Background").GetComponentsInChildren<TextMeshProUGUI>()) foreach (TextMeshProUGUI text in newOptionsMenu.transform.Find("Background").GetComponentsInChildren<TextMeshProUGUI>())
{ {

View file

@ -6,6 +6,7 @@ using System.Threading.Tasks;
using HarmonyLib; using HarmonyLib;
using UnityEngine; using UnityEngine;
using Il2Cpp; using Il2Cpp;
using Il2CppCore;
using PvZ_Fusion_Translator.Patches.BaseTextObjects; using PvZ_Fusion_Translator.Patches.BaseTextObjects;
namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects

View file

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Il2Cpp;
using HarmonyLib;
using UnityEngine;
using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore;
using Unity.VisualScripting;
namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects
{
[HarmonyPatch(typeof(HealthSlider))]
public static class HealthSlider_Patch
{
public static TMP_FontAsset fontAsset = null;
[HarmonyPatch(nameof(HealthSlider.Start))]
[HarmonyPostfix]
public static void Post_Start(HealthSlider __instance)
{
if(!fontAsset)
{
fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString());
}
}
[HarmonyPatch(nameof(HealthSlider.UpdateText))]
[HarmonyPostfix]
public static void Post_UpdateText(HealthSlider __instance)
{
if(!fontAsset) fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString());
if (__instance.healthText.font != fontAsset) __instance.healthText.font = fontAsset;
foreach(TextMeshProUGUI txt in __instance.healthTextContainer.GetComponentsInChildren<TextMeshProUGUI>(true))
{
txt.text = StringStore.TranslateText(txt.text);
txt.font = fontAsset;
}
}
}
}

View file

@ -4,7 +4,7 @@ using PvZ_Fusion_Translator.AssetStore;
namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects
{ {
[HarmonyPatch(typeof(LanternUmbrella))] /*[HarmonyPatch(typeof(LanternUmbrella))]
public class LanternUmbrella_Patch public class LanternUmbrella_Patch
{ {
[HarmonyPostfix] [HarmonyPostfix]
@ -14,5 +14,5 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects
__instance.energyText = StringStore.TranslateText(__instance.energyText); __instance.energyText = StringStore.TranslateText(__instance.energyText);
__instance.energyTextShadow = StringStore.TranslateText(__instance.energyTextShadow); __instance.energyTextShadow = StringStore.TranslateText(__instance.energyTextShadow);
} }
} }*/
} }

View file

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Il2Cpp;
using UnityEngine;
using HarmonyLib;
using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore;
namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects
{
[HarmonyPatch(typeof(PumpinerChestMenu))]
public static class PumpinerChestMenu_Patch
{
[HarmonyPatch(nameof(PumpinerChestMenu.InitPlants))]
[HarmonyPostfix]
public static void Post_InitPlants(PumpinerChestMenu __instance)
{
Transform closeBtnTransform = __instance.transform.Find("SampleButton");
TextMeshProUGUI txt = closeBtnTransform.GetComponentInChildren<TextMeshProUGUI>();
txt.text = StringStore.TranslateText("合上");
}
}
}

View file

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HarmonyLib;
using Il2Cpp;
using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore;
using UnityEngine;
namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects
{
[HarmonyPatch(typeof(SpecialCard))]
public static class SpecialCard_Patch
{
[HarmonyPatch(nameof(SpecialCard.Awake))]
[HarmonyPatch(nameof(SpecialCard.Start))]
[HarmonyPatch(nameof(SpecialCard.ClickedEvent))]
[HarmonyPostfix]
public static void Post_Awake(SpecialCard __instance)
{
TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString());
foreach(TextMeshProUGUI txt in __instance.GetComponentsInChildren<TextMeshProUGUI>())
{
txt.text = StringStore.TranslateText(txt.text);
txt.font = fontAsset;
}
}
}
}

View file

@ -10,7 +10,7 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects
public static void UpdateHealthText(TrainingDummy __instance) public static void UpdateHealthText(TrainingDummy __instance)
{ {
Zombie_Patch.TranslateHpUI_T(__instance.healthText, __instance); Zombie_Patch.TranslateHpUI_T(__instance.healthText, __instance);
Zombie_Patch.TranslateHpUI_T(__instance.healthTextShadow, __instance); //Zombie_Patch.TranslateHpUI_T(__instance.healthTextShadow, __instance);
} }
} }
} }

View file

@ -4,7 +4,7 @@ using PvZ_Fusion_Translator.AssetStore;
namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects
{ {
[HarmonyPatch(typeof(UltimateChomper), nameof(UltimateChomper.UpdateText))] /*[HarmonyPatch(typeof(UltimateChomper), nameof(UltimateChomper.UpdateText))]
public static class UltimateChomper_Patch public static class UltimateChomper_Patch
{ {
[HarmonyPostfix] [HarmonyPostfix]
@ -13,5 +13,5 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects
StringStore.TranslateText(__instance.killingText); StringStore.TranslateText(__instance.killingText);
StringStore.TranslateText(__instance.killingTextShadow); StringStore.TranslateText(__instance.killingTextShadow);
} }
} }*/
} }

View file

@ -32,7 +32,7 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects
public static void Start(Zombie __instance) public static void Start(Zombie __instance)
{ {
TranslateHpUI(__instance.healthText, __instance); TranslateHpUI(__instance.healthText, __instance);
TranslateHpUI(__instance.healthTextShadow, __instance); //TranslateHpUI(__instance.healthTextShadow, __instance);
if (__instance.healthText.transform.rotation != Quaternion.Euler(0, 0, 0)) if (__instance.healthText.transform.rotation != Quaternion.Euler(0, 0, 0))
__instance.healthText.transform.rotation = Quaternion.Euler(0f, 0f, 0f); __instance.healthText.transform.rotation = Quaternion.Euler(0f, 0f, 0f);
@ -45,10 +45,10 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects
if (__instance.theZombieType == ZombieType.TrainingDummy || !Board.Instance.showZombieHealth) if (__instance.theZombieType == ZombieType.TrainingDummy || !Board.Instance.showZombieHealth)
return; return;
if (__instance.healthText == null || __instance.healthTextShadow == null) return; if (__instance.healthText == null) return;
TranslateHpUI(__instance.healthText, __instance); TranslateHpUI(__instance.healthText, __instance);
TranslateHpUI(__instance.healthTextShadow, __instance); //TranslateHpUI(__instance.healthTextShadow, __instance);
if (__instance.healthText.transform.rotation != Quaternion.Euler(0f, 0f, 0f)) if (__instance.healthText.transform.rotation != Quaternion.Euler(0f, 0f, 0f))
__instance.healthText.transform.rotation = Quaternion.Euler(0f, 0f, 0f); __instance.healthText.transform.rotation = Quaternion.Euler(0f, 0f, 0f);

View file

@ -10,26 +10,27 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
[HarmonyPatch(typeof(PlantDamageMenu))] [HarmonyPatch(typeof(PlantDamageMenu))]
public static class PlantDamageMenu_Patch public static class PlantDamageMenu_Patch
{ {
[HarmonyPatch(nameof(PlantDamageMenu.Awake))] public static void Awake(BaseMenu __instance)
[HarmonyPostfix]
private static void Awake(PlantDamageMenu __instance)
{ {
TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString());
foreach(TextMeshProUGUI text in __instance.GetComponentsInChildren<TextMeshProUGUI>()) foreach(TextMeshProUGUI text in __instance.GetComponentsInChildren<TextMeshProUGUI>())
{ {
text.text = StringStore.TranslateText(text.text); string originalKey = StringStore.translationString.FirstOrDefault(x => x.Value == text.text).Key;
text.text = StringStore.translationString.ContainsKey(originalKey + "_RM") ? StringStore.TranslateText(originalKey + "_RM") : StringStore.TranslateText(text.text);
text.font = fontAsset; text.font = fontAsset;
} }
} }
[HarmonyPatch(nameof(PlantDamageMenu.Awake))]
[HarmonyPatch(nameof(PlantDamageMenu.InitCards))] [HarmonyPatch(nameof(PlantDamageMenu.InitCards))]
[HarmonyPostfix] [HarmonyPostfix]
private static void InitCards(PlantDamageMenu __instance) public static void InitCards(PlantDamageMenu __instance)
{ {
TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString());
foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren<TextMeshProUGUI>()) foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren<TextMeshProUGUI>())
{ {
text.text = StringStore.TranslateText(text.text); string originalKey = StringStore.translationString.FirstOrDefault(x => x.Value == text.text).Key;
text.text = StringStore.translationString.ContainsKey(originalKey + "_RM") ? StringStore.TranslateText(originalKey + "_RM") : StringStore.TranslateText(text.text);
text.font = fontAsset; text.font = fontAsset;
} }
} }

View file

@ -21,12 +21,12 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
TranslatePlantDataMenu(__instance); TranslatePlantDataMenu(__instance);
} }
[HarmonyPatch(nameof(PlantDataMenu.Update))] /*[HarmonyPatch(nameof(PlantDataMenu.Update))]
[HarmonyPostfix] [HarmonyPostfix]
public static void Post_Update(PlantDataMenu __instance) public static void Post_Update(PlantDataMenu __instance)
{ {
TranslatePlantDataMenu(__instance); TranslatePlantDataMenu(__instance);
} }*/
[HarmonyPatch(nameof(PlantDataMenu.InitDataFromPlant))] [HarmonyPatch(nameof(PlantDataMenu.InitDataFromPlant))]
[HarmonyPostfix] [HarmonyPostfix]
@ -37,6 +37,8 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
public static void TranslatePlantDataMenu(PlantDataMenu __instance) public static void TranslatePlantDataMenu(PlantDataMenu __instance)
{ {
if (!__instance) return;
PlantType thePlantType = __instance.plant.thePlantType; PlantType thePlantType = __instance.plant.thePlantType;
string plantName = Utils.GetPlantNameFromAlmanac(thePlantType); string plantName = Utils.GetPlantNameFromAlmanac(thePlantType);

View file

@ -26,10 +26,10 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
public static void TranslateCreatePlayerSaveMenu() public static void TranslateCreatePlayerSaveMenu()
{ {
Transform createPlayerSaveMenuTransform = GameAPP.canvasUp.Find("CreatePlayerSaveMenu(Clone)"); Transform reNameMenuTransform = GameAPP.canvasUp.Find("ReNameMenu(Clone)");
if(createPlayerSaveMenuTransform.TryGetComponent<CreatePlayerSaveMenu>(out CreatePlayerSaveMenu createPlayerSaveMenu)) if(reNameMenuTransform.TryGetComponent<ReNameMenu>(out ReNameMenu reNameMenu))
{ {
createPlayerSaveMenu.title.text = StringStore.TranslateText(createPlayerSaveMenu.title.text); reNameMenu.title.text = StringStore.TranslateText(reNameMenu.title.text);
} }
} }
} }

View file

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HarmonyLib;
using UnityEngine;
using Il2Cpp;
using PvZ_Fusion_Translator.AssetStore;
namespace PvZ_Fusion_Translator.Patches.GameObjects
{
[HarmonyPatch(typeof(ReNameMenu))]
public static class ReNameMenu_Patch
{
[HarmonyPatch(nameof(ReNameMenu.SetTitle))]
[HarmonyPostfix]
public static void SetTitle(ReNameMenu __instance)
{
__instance.title.text = StringStore.TranslateText(__instance.title.text);
}
[HarmonyPatch(nameof(ReNameMenu.SetInputText))]
[HarmonyPostfix]
public static void SetInputText(ReNameMenu __instance)
{
__instance.input.text = StringStore.TranslateText(__instance.input.text);
}
}
}

View file

@ -6,7 +6,7 @@ using UnityEngine;
namespace PvZ_Fusion_Translator.Patches.GameObjects namespace PvZ_Fusion_Translator.Patches.GameObjects
{ {
[HarmonyPatch(typeof(ShootingMenu))] /*[HarmonyPatch(typeof(ShootingMenu))]
public static class ShootingMenu_Patch public static class ShootingMenu_Patch
{ {
[HarmonyPatch(nameof(ShootingMenu.Update))] [HarmonyPatch(nameof(ShootingMenu.Update))]
@ -21,5 +21,5 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
txt.font = fontAsset; txt.font = fontAsset;
} }
} }
} }*/
} }

View file

@ -7,7 +7,7 @@ using System.Text.RegularExpressions;
namespace PvZ_Fusion_Translator.Patches.GameObjects namespace PvZ_Fusion_Translator.Patches.GameObjects
{ {
[HarmonyPatch(typeof(ShootingSelectWindow))] /*[HarmonyPatch(typeof(ShootingSelectWindow))]
public static class ShootingSelectWindow_Patch public static class ShootingSelectWindow_Patch
{ {
[HarmonyPatch(nameof(ShootingSelectWindow.InitPlantType))] [HarmonyPatch(nameof(ShootingSelectWindow.InitPlantType))]
@ -69,5 +69,5 @@ namespace PvZ_Fusion_Translator.Patches.GameObjects
introduceText.text = StringStore.TranslateText(introduceText.text); introduceText.text = StringStore.TranslateText(introduceText.text);
introduceText.font = fontAsset; introduceText.font = fontAsset;
} }
} }*/
} }

View file

@ -2,6 +2,8 @@
using Il2Cpp; using Il2Cpp;
using Il2CppTMPro; using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore; using PvZ_Fusion_Translator.AssetStore;
using PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects;
using UnityEngine;
namespace PvZ_Fusion_Translator.Patches.Managers namespace PvZ_Fusion_Translator.Patches.Managers
{ {
@ -9,20 +11,27 @@ namespace PvZ_Fusion_Translator.Patches.Managers
public static class SaveMenu_Patch public static class SaveMenu_Patch
{ {
[HarmonyPatch(nameof(SaveMenu.Start))] [HarmonyPatch(nameof(SaveMenu.Start))]
[HarmonyPatch(nameof(SaveMenu.CreateLevelEnter))]
[HarmonyPatch(nameof(SaveMenu.InitLevelSaveEnters))]
[HarmonyPostfix] [HarmonyPostfix]
private static void Start(SaveMenu __instance) private static void Start(SaveMenu __instance)
{ {
TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString());
__instance.title.text = StringStore.TranslateText(__instance.title.text); __instance.menuTitle.text = StringStore.TranslateText(__instance.menuTitle.text);
__instance.title.font = fontAsset; __instance.menuTitle.font = fontAsset;
__instance.title_shadow.text = StringStore.TranslateText(__instance.title_shadow.text);
__instance.title_shadow.font = fontAsset;
foreach(SaveMenuBtn level in __instance.levels) foreach(LevelSaveEnter enter in __instance.GetComponentsInChildren<LevelSaveEnter>())
{ {
level.theName.text = StringStore.TranslateText(level.theName.text); LevelSaveEnter_Patch.TranslateEnter(enter);
} }
} }
[HarmonyPatch(nameof(SaveMenu.OnEditSelectedButtonClicked))]
[HarmonyPostfix]
private static void OnEditSelectedButtonClicked(SaveMenu __instance)
{
}
} }
} }

View file

@ -1,42 +1,61 @@
using System; using HarmonyLib;
using Il2Cpp;
using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Il2Cpp;
using HarmonyLib;
using UnityEngine; using UnityEngine;
using Il2CppTMPro; using UnityEngine.TextCore.Text;
using PvZ_Fusion_Translator.AssetStore;
namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey
{ {
[HarmonyPatch(typeof(MultipleChoiceMenu))] [HarmonyPatch(typeof(MultipleChoiceMenu))]
public static class MultipleChoiceMenu_Patch public static class MultipleChoiceMenu_Patch
{ {
public static TMP_FontAsset fontAsset => FontStore.LoadTMPFont(Utils.Language.ToString());
[HarmonyPatch(nameof(MultipleChoiceMenu.Awake))] [HarmonyPatch(nameof(MultipleChoiceMenu.Awake))]
[HarmonyPatch(nameof(MultipleChoiceMenu.UpdateWindow))]
[HarmonyPatch(nameof(MultipleChoiceMenu.Refresh))]
[HarmonyPatch(nameof(MultipleChoiceMenu.Cancel))] [HarmonyPatch(nameof(MultipleChoiceMenu.Cancel))]
[HarmonyPatch(nameof(MultipleChoiceMenu.Refresh))]
[HarmonyPatch(nameof(MultipleChoiceMenu.UpdateWindow))]
[HarmonyPatch(nameof(MultipleChoiceMenu.UpdateWindows))]
[HarmonyPostfix] [HarmonyPostfix]
public static void Awake(MultipleChoiceMenu __instance) public static void Awake(MultipleChoiceMenu __instance)
{ {
TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString());
foreach(BaseWindow window in __instance.windows) foreach(BaseWindow window in __instance.windows)
{ {
foreach(TextMeshProUGUI txt in window.GetComponentsInChildren<TextMeshProUGUI>()) TranslateWindowText(window.title);
TranslateWindowText(window.introduce);
}
foreach(TheButton button in __instance.GetComponentsInChildren<TheButton>())
{
foreach(TextMeshProUGUI txt in button.GetComponentsInChildren<TextMeshProUGUI>())
{ {
txt.text = StringStore.translationString.ContainsKey(txt.text + "_MC") ? StringStore.TranslateText(txt.text + "_MC") : StringStore.TranslateText(txt.text);
txt.font = fontAsset; txt.font = fontAsset;
if(StringStore.customLevelString.ContainsKey(txt.text))
{
txt.text = StringStore.customLevelString[txt.text];
}
else
{
txt.text = StringStore.translationString.ContainsKey(txt.text + "_MC") ? StringStore.TranslateText(txt.text + "_MC") : StringStore.TranslateText(txt.text);
}
} }
} }
} }
public static void TranslateWindowText(TextMeshProUGUI txt)
{
txt.font = fontAsset;
if(StringStore.customLevelString.ContainsKey(txt.text))
{
txt.text = StringStore.customLevelString[txt.text];
}
else if(Utils.GetPlantNameFromAlmanac(txt.text) != "")
{
txt.text = Utils.GetPlantNameFromAlmanac(txt.text);
}
else
{
txt.text = StringStore.translationString.ContainsKey(txt.text + "_MC") ? StringStore.TranslateText(txt.text + "_MC") : StringStore.TranslateText(txt.text);
}
}
} }
} }

View file

@ -7,7 +7,7 @@ using UnityEngine;
namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey
{ {
[HarmonyPatch(typeof(OppositeBuffManager))] /*[HarmonyPatch(typeof(OppositeBuffManager))]
public static class OppositeBuffManager_Patch public static class OppositeBuffManager_Patch
{ {
public static Dictionary<BuffType, string> buffLinks = TravelMgr_Patch.buffLinks; public static Dictionary<BuffType, string> buffLinks = TravelMgr_Patch.buffLinks;
@ -20,14 +20,14 @@ namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey
[HarmonyPostfix] [HarmonyPostfix]
private static void SetText(OppositeBuffManager __instance) private static void SetText(OppositeBuffManager __instance)
{ {
/*if (TravelMgr_Patch.travelBuffString.ContainsKey(__result)) *//*if (TravelMgr_Patch.travelBuffString.ContainsKey(__result))
{ {
__result = TravelMgr_Patch.travelBuffString[__result]; __result = TravelMgr_Patch.travelBuffString[__result];
} }
else if(TravelMgr_Patch.travelBuffString.ContainsKey(TravelMgr_Patch.RemoveBuffName(__result))) else if(TravelMgr_Patch.travelBuffString.ContainsKey(TravelMgr_Patch.RemoveBuffName(__result)))
{ {
__result = TravelMgr_Patch.travelBuffString[TravelMgr_Patch.RemoveBuffName(__result)]; __result = TravelMgr_Patch.travelBuffString[TravelMgr_Patch.RemoveBuffName(__result)];
}*/ }*//*
} }
public static void TranslateOppositeText(Il2CppSystem.Collections.Generic.List<TextMeshProUGUI> textList, Il2CppSystem.Object buff, bool isBad = false) public static void TranslateOppositeText(Il2CppSystem.Collections.Generic.List<TextMeshProUGUI> textList, Il2CppSystem.Object buff, bool isBad = false)
@ -48,5 +48,5 @@ namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey
text.font = fontAsset; text.font = fontAsset;
} }
} }
} }*/
} }

View file

@ -0,0 +1,19 @@
using HarmonyLib;
using Il2CppGameLevel;
using Il2Cpp;
using UnityEngine;
using Il2CppGameLevel.RogueShooting;
namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey
{
[HarmonyPatch(typeof(ShootingManager))]
public static class ShootingManager_Patch
{
[HarmonyPatch(nameof(ShootingManager.UpgradeBuff))]
[HarmonyPostfix]
public static void UpgradeBuff(ShootingManager __instance, ref MultipleChoiceMenu menu)
{
MultipleChoiceMenu_Patch.Awake(menu);
}
}
}

View file

@ -15,8 +15,7 @@ namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey
[HarmonyPostfix] [HarmonyPostfix]
public static void Start(SynergyDisplay __instance) public static void Start(SynergyDisplay __instance)
{ {
__instance.text1.text = TranslateInvestDisplay(__instance.text1.text); __instance.text.text = TranslateInvestDisplay(__instance.text.text);
__instance.text_shadow.text = Utils.RemoveColorTags(__instance.text1.text);
} }
public static string TranslateInvestDisplay(string originalText) public static string TranslateInvestDisplay(string originalText)

View file

@ -20,7 +20,14 @@ namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey
foreach(CustomButton_enterGame button in __instance.GetComponentsInChildren<CustomButton_enterGame>()) foreach(CustomButton_enterGame button in __instance.GetComponentsInChildren<CustomButton_enterGame>())
{ {
string plantName = Utils.GetPlantNameFromAlmanac(button.levelName.text); string plantName = Utils.GetPlantNameFromAlmanac(button.levelName.text);
button.levelName.text = (plantName != "") ? plantName : StringStore.TranslateText(button.levelName.text); if(Utils.Language == Utils.LanguageEnum.Arabic)
{
button.levelName.text = StringStore.TranslateText(button.levelName.text);
}
else
{
button.levelName.text = (plantName != "") ? plantName : StringStore.TranslateText(button.levelName.text);
}
} }
} }

View file

@ -17,6 +17,15 @@ namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey
[HarmonyPatch(typeof(TravelMgr))] [HarmonyPatch(typeof(TravelMgr))]
public static class TravelMgr_Patch public static class TravelMgr_Patch
{ {
public static readonly Dictionary<string, SortedDictionary<int, string>> templateTravelBuffs = new()
{
{ "advancedBuffs", new SortedDictionary<int, string>() },
{ "ultimateBuffs", new SortedDictionary<int, string>() },
{ "debuffs", new SortedDictionary<int, string>() },
{ "unlocks", new SortedDictionary<int, string>() },
{ "investmentBuffs", new SortedDictionary<int, string>() }
};
public static Dictionary<string, SortedDictionary<int, string>> dumpedTravelBuffs = new() public static Dictionary<string, SortedDictionary<int, string>> dumpedTravelBuffs = new()
{ {
{ "advancedBuffs", new SortedDictionary<int, string>() }, { "advancedBuffs", new SortedDictionary<int, string>() },
@ -70,35 +79,37 @@ namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey
public static void DumpTravelBuffs() public static void DumpTravelBuffs()
{ {
TravelMgr.Instance.GetPlantBuffUnlockCount(PlantType.DoomGatling); TravelMgr.Instance.GetPlantBuffUnlockCount(PlantType.DoomGatling);
dumpedTravelBuffs = new(templateTravelBuffs);
travelBuffString.Clear();
foreach (var pair in TravelDictionary.advancedBuffsText) foreach (var pair in TravelDictionary.advancedBuffsText)
{ {
dumpedTravelBuffs["advancedBuffs"].Add((int)pair.Key, pair.Value); Utils.TryAdd(dumpedTravelBuffs["advancedBuffs"], (int)pair.Key, pair.Value);
travelBuffString.Add(pair.Value, pair.Value); Utils.TryAdd(travelBuffString, pair.Value, pair.Value);
} }
foreach (var pair in TravelDictionary.ultimateBuffsText) foreach (var pair in TravelDictionary.ultimateBuffsText)
{ {
dumpedTravelBuffs["ultimateBuffs"].Add((int)pair.Key, pair.Value); Utils.TryAdd(dumpedTravelBuffs["ultimateBuffs"], (int)pair.Key, pair.Value);
travelBuffString.Add(pair.Value, pair.Value); Utils.TryAdd(travelBuffString, pair.Value, pair.Value);
} }
foreach (var pair in TravelDictionary.debuffData) foreach (var pair in TravelDictionary.debuffData)
{ {
dumpedTravelBuffs["debuffs"].Add((int)pair.Key, pair.Value.Item1); Utils.TryAdd(dumpedTravelBuffs["debuffs"], (int)pair.Key, pair.Value.Item1);
travelBuffString.Add(pair.Value.Item1, pair.Value.Item1); Utils.TryAdd(travelBuffString, pair.Value.Item1, pair.Value.Item1);
} }
foreach (var pair in TravelDictionary.unlocksText) foreach (var pair in TravelDictionary.unlocksText)
{ {
dumpedTravelBuffs["unlocks"].Add((int)pair.Key, pair.Value); Utils.TryAdd(dumpedTravelBuffs["unlocks"], (int)pair.Key, pair.Value);
travelBuffString.Add(pair.Value, pair.Value); Utils.TryAdd(travelBuffString, pair.Value, pair.Value);
} }
foreach (var pair in TravelMgr.InvestBuffsData) foreach (var pair in TravelMgr.InvestBuffsData)
{ {
dumpedTravelBuffs["investmentBuffs"].Add((int)pair.Key, pair.Value.GetDescription()); Utils.TryAdd(dumpedTravelBuffs["investmentBuffs"], (int)pair.Key, pair.Value.GetDescription());
travelBuffString.Add(pair.Value.GetDescription(), pair.Value.GetDescription()); Utils.TryAdd(travelBuffString, pair.Value.GetDescription(), pair.Value.GetDescription());
} }
File.WriteAllText(Path.Combine(GetAssetDir(AssetType.Dumps), "travel_buffs.json"), JsonSerializer.Serialize(dumpedTravelBuffs, new JsonSerializerOptions File.WriteAllText(Path.Combine(GetAssetDir(AssetType.Dumps), "travel_buffs.json"), JsonSerializer.Serialize(dumpedTravelBuffs, new JsonSerializerOptions
@ -121,17 +132,15 @@ namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey
} }
//System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, SortedDictionary<int, string>>>(travelBuffsContent); //System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, SortedDictionary<int, string>>>(travelBuffsContent);
public static Dictionary<string, SortedDictionary<int, string>> GenerateTranslatedTravelBuffs(string travelBuffsContent) public static void GenerateTranslatedTravelBuffs(string travelBuffsContent)
{ {
TravelMgr_Patch.DumpTravelBuffs(); if (!Core.isInitialized) return;
Dictionary<string, SortedDictionary<int, string>> travelBuffs = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, SortedDictionary<int, string>>>(travelBuffsContent); DumpTravelBuffs();
// save travel buffs Dictionary<string, SortedDictionary<int, string>> travelBuffs = JsonSerializer.Deserialize<Dictionary<string, SortedDictionary<int, string>>>(travelBuffsContent);
translatedTravelBuffs = travelBuffs;
string travelBuffsToSave = SerializeWithIndentation(travelBuffs); travelBuffString.Clear();
string stringDir = GetAssetDir(AssetType.Strings, Utils.Language);
File.WriteAllText(Path.Combine(stringDir, "travel_buffs.json"), travelBuffsToSave);
foreach(var i in travelBuffs) foreach(var i in travelBuffs)
{ {
@ -145,28 +154,14 @@ namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey
{ {
if (translatedBuffSet.ContainsKey(j.Key)) if (translatedBuffSet.ContainsKey(j.Key))
{ {
if(travelBuffString.ContainsKey(originalBuff)) Utils.TryAdd(travelBuffString, originalBuff, translatedBuffSet[j.Key]);
{
travelBuffString[originalBuff] = translatedBuffSet[j.Key];
}
else
{
travelBuffString.Add(originalBuff, translatedBuffSet[j.Key]);
}
} }
} }
else if(j.Value == RemoveBuffName(originalBuff)) else if(j.Value == RemoveBuffName(originalBuff))
{ {
if (translatedBuffSet.ContainsKey(j.Key)) if (translatedBuffSet.ContainsKey(j.Key))
{ {
if(travelBuffString.ContainsKey(originalBuff)) Utils.TryAdd(travelBuffString, originalBuff, translatedBuffSet[j.Key]);
{
travelBuffString[RemoveBuffName(originalBuff)] = translatedBuffSet[j.Key];
}
else
{
travelBuffString.Add(RemoveBuffName(originalBuff), translatedBuffSet[j.Key]);
}
} }
} }
@ -179,7 +174,9 @@ namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey
} }
} }
return travelBuffs; string travelBuffsToSave = SerializeWithIndentation(TravelMgr_Patch.translatedTravelBuffs);
string stringDir = GetAssetDir(AssetType.Strings, Utils.Language);
File.WriteAllText(Path.Combine(stringDir, "travel_buffs.json"), travelBuffsToSave);
} }
public static string MatchTravelBuff(string originalText) public static string MatchTravelBuff(string originalText)
@ -217,5 +214,46 @@ namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey
} }
return res; return res;
} }
public static ValueTuple<string, int, string> FindBuffData(string buffText)
{
ValueTuple<string, int, string> res = new();
foreach(var pair1 in translatedTravelBuffs)
{
foreach(var pair2 in pair1.Value)
{
if(buffText == pair2.Value)
{
res.Item1 = pair1.Key;
res.Item2 = pair2.Key;
}
}
}
foreach(var pair1 in dumpedTravelBuffs)
{
foreach(var pair2 in pair1.Value)
{
if(buffText == pair2.Value)
{
res.Item1 = pair1.Key;
res.Item2 = pair2.Key;
}
}
}
string finalBuffText = buffText;
if(travelBuffString.ContainsKey(buffText))
{
finalBuffText = travelBuffString[buffText];
}
else
{
finalBuffText = StringStore.TranslateText(buffText);
}
res.Item3 = finalBuffText;
return res;
}
} }
} }

View file

@ -0,0 +1,29 @@
/*using MelonLoader;
using HarmonyLib;
using UnityEngine;
using Il2Cpp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore;
using Il2CppGameLevel;
using PvZ_Fusion_Translator.Patches.Modes.Super_Editor.GameLevel.EventNodes;
namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor
{
[HarmonyPatch(typeof(CustomMenuPage_event))]
public static class CustomMenuPage_event_Patch
{
[HarmonyPatch(nameof(CustomMenuPage_event.InitializeNodeEditor))]
[HarmonyPostfix]
public static void InitializeNodeEditor(CustomMenuPage_event __instance)
{
RuntimeEventNodeEditor_Patch.Update(__instance.nodeEditor);
NodeInfoPanel_Patch.UpdatePanelContent(__instance.nodeInfoPanel);
}
}
}
*/

View file

@ -1,96 +1,47 @@
using Il2Cpp; using HarmonyLib;
using Il2CppGameLevel;
using HarmonyLib;
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Il2CppGameLevel.EventNodes; using Il2CppGameLevel.EventNodes;
using Il2CppTMPro; using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore; using PvZ_Fusion_Translator.AssetStore;
using PvZ_Fusion_Translator.Patches.BaseTextObjects;
using UnityEngine;
namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor.GameLevel.EventNodes namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor.GameLevel.EventNodes
{ {
[HarmonyPatch(typeof(RuntimeEventNodeEditor))] [HarmonyPatch(typeof(RuntimeEventNodeEditor))]
public static class RuntimeEventNodeEditor_Patch public static class RuntimeEventNodeEditor_Patch
{ {
[HarmonyPatch(nameof(RuntimeEventNodeEditor.AddNode))] public static TMP_FontAsset fontAsset => FontStore.LoadTMPFont(Utils.Language.ToString());
[HarmonyPostfix]
public static void AddNode(RuntimeEventNodeEditor __instance)
{
TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString());
foreach(var nodeUI in __instance.nodeUIs)
{
string nodeName = nodeUI.key;
RuntimeNodeUI node = nodeUI.Value;
foreach(TextMeshProUGUI txt in node.GetComponentsInChildren<TextMeshProUGUI>())
{
txt.text = StringStore.translationString.ContainsKey(txt.text + "_code") ? StringStore.TranslateText(txt.text + "_code") : StringStore.TranslateText(txt.text);
txt.font = fontAsset;
}
}
}
[HarmonyPatch(nameof(RuntimeEventNodeEditor.Update))] [HarmonyPatch(nameof(RuntimeEventNodeEditor.Update))]
[HarmonyPostfix] [HarmonyPostfix]
public static void Update(RuntimeEventNodeEditor __instance) public static void Update(RuntimeEventNodeEditor __instance)
{ {
TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); // translate the new screens (3.7)
TranslateFullTransform(__instance.nodeInfoPanel.transform);
foreach(var node in __instance.nodeUIs) TranslateFullTransform(__instance.attributePanel.transform);
TranslateFullTransform(__instance.canvas.transform);
if(__instance.TryGetComponent<EventNodeContextMenu>(out EventNodeContextMenu eventNodeContextMenu))
{ {
RuntimeNodeUI nodeUI = node.value; TranslateFullTransform(eventNodeContextMenu.transform);
}
}
if(nodeUI.Node.nodeType == "PlantTypeValueNode" || nodeUI.Node.nodeType == "SinglePlantTypeListNode") public static void TranslateFullTransform(Transform transform)
{
if (transform == null) return;
foreach(TextMeshProUGUI txt in transform.GetComponentsInChildren<TextMeshProUGUI>())
{
txt.text = RuntimeNodeUI_Patch.TranslateCodeText(txt.text);
txt.font = fontAsset;
}
foreach(TMP_InputField inputField in transform.GetComponentsInChildren<TMP_InputField>())
{
TMP_InputField_Patch.OnEnable(inputField);
foreach(TextMeshProUGUI txt in inputField.GetComponentsInChildren<TextMeshProUGUI>(true))
{ {
Transform buttonTransform = nodeUI.transform.Find("Header/ValueEditContainer/Button(Clone)/Label"); txt.text = RuntimeNodeUI_Patch.TranslateCodeText(txt.text);
TextMeshProUGUI txt = buttonTransform.GetComponent<TextMeshProUGUI>();
if (!txt.gameObject.name.Contains("Label")) continue;
if (!Utils.CheckForUntranslatedText(txt.text)) continue;
string plantName = "";
if(nodeUI.Node.nodeType == "PlantTypeValueNode")
{
plantName = Utils.GetPlantNameFromAlmanac(nodeUI.Node.GetPortValue<PlantType>(nodeUI.Node.GetOutputPorts()[0].portName, PlantType.Nothing));
}
else if(nodeUI.Node.nodeType == "SinglePlantTypeListNode")
{
SinglePlantTypeListNode tempNode = nodeUI.Node.TryCast<SinglePlantTypeListNode>();
plantName = Utils.GetPlantNameFromAlmanac(tempNode.plantType);
}
txt.text = (plantName != "") ? plantName : StringStore.TranslateText(txt.text);
txt.font = fontAsset;
}
else if(nodeUI.Node.nodeType == "ZombieTypeValueNode")
{
Transform buttonTransform = nodeUI.transform.Find("Header/ValueEditContainer/Button(Clone)/Label");
TextMeshProUGUI txt = buttonTransform.GetComponent<TextMeshProUGUI>();
if (!txt.gameObject.name.Contains("Label")) continue;
if (!Utils.CheckForUntranslatedText(txt.text)) continue;
string zombieName = Utils.GetZombieNameFromAlmanac(nodeUI.Node.GetPortValue<ZombieType>(nodeUI.Node.GetOutputPorts()[0].portName, ZombieType.Nothing));
txt.text = (zombieName != "") ? zombieName : StringStore.TranslateText(txt.text);
txt.font = fontAsset;
}
else if(nodeUI.Node.nodeType == "PlantTypeListStorageNode")
{
Transform dropdownTransform = nodeUI.transform.Find("Header/ValueEditContainer/Dropdown(Clone)");
if (!dropdownTransform) continue;
foreach(TextMeshProUGUI txt in dropdownTransform.GetComponentsInChildren<TextMeshProUGUI>())
{
if (!Utils.CheckForUntranslatedText(txt.text)) continue;
txt.text = StringStore.TranslateText(txt.text);
txt.font = fontAsset;
}
} }
} }
} }

View file

@ -1,12 +1,4 @@
using Il2Cpp; using HarmonyLib;
using Il2CppGameLevel;
using HarmonyLib;
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Il2CppGameLevel.EventNodes; using Il2CppGameLevel.EventNodes;
using Il2CppTMPro; using Il2CppTMPro;
using PvZ_Fusion_Translator.AssetStore; using PvZ_Fusion_Translator.AssetStore;
@ -18,99 +10,134 @@ namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor.GameLevel.EventNodes
public static class RuntimeNodeUI_Patch public static class RuntimeNodeUI_Patch
{ {
[HarmonyPatch(nameof(RuntimeNodeUI.Awake))] [HarmonyPatch(nameof(RuntimeNodeUI.Awake))]
[HarmonyPatch(nameof(RuntimeNodeUI.Initialize))]
[HarmonyPatch(nameof(RuntimeNodeUI.CreatePorts))]
[HarmonyPatch(nameof(RuntimeNodeUI.CreateTravelEntryEditUI), argumentTypes: [typeof(RectTransform), typeof(GetTravelEntryNode)])]
[HarmonyPatch(nameof(RuntimeNodeUI.CreateStringInputField))]
[HarmonyPatch(nameof(RuntimeNodeUI.CreatePorts))] [HarmonyPatch(nameof(RuntimeNodeUI.CreatePorts))]
[HarmonyPatch(nameof(RuntimeNodeUI.CreateValueEditUI))]
[HarmonyPatch(nameof(RuntimeNodeUI.GetPortUI))]
[HarmonyPatch(nameof(RuntimeNodeUI.UpdateDisplay))]
[HarmonyPatch(nameof(RuntimeNodeUI.UpdateSelectionVisual))]
[HarmonyPatch(nameof(RuntimeNodeUI.UpdateVisable))]
[HarmonyPostfix] [HarmonyPostfix]
public static void Awake(RuntimeNodeUI __instance) public static void Post_UpdateDisplay(RuntimeNodeUI __instance)
{ {
if (!__instance.isActiveAndEnabled) return; if (!__instance.isActiveAndEnabled) return;
if (__instance.Node == null) return;
TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString());
if(__instance.dropdownPrefab) __instance.titleText.text = TranslateCodeText(__instance.titleText.text);
{ __instance.titleText.font = fontAsset;
if(__instance.dropdownPrefab.TryGetComponent<TMP_Dropdown>(out TMP_Dropdown dropdown))
{
TMP_Dropdown_Patch.CreateDropdownList(dropdown);
}
}
if(__instance.valueInputField) foreach(TextMeshProUGUI txt in __instance.inputPortsContainer.GetComponentsInChildren<TextMeshProUGUI>())
{ {
TMP_InputField_Patch.OnEnable(__instance.valueInputField); txt.text = TranslateCodeText(txt.text);
foreach(TextMeshProUGUI txt in __instance.valueInputField.GetComponentsInChildren<TextMeshProUGUI>(true))
{
txt.text = StringStore.translationString.ContainsKey(txt.text + "_code") ? StringStore.TranslateText(txt.text + "_code") : StringStore.TranslateText(txt.text);
}
}
foreach(TextMeshProUGUI txt in __instance.GetComponentsInChildren<TextMeshProUGUI>())
{
txt.text = StringStore.translationString.ContainsKey(txt.text + "_code") ? StringStore.TranslateText(txt.text + "_code") : StringStore.TranslateText(txt.text);
txt.font = fontAsset; txt.font = fontAsset;
} }
}
[HarmonyPatch(nameof(RuntimeNodeUI.UpdateDisplay))] foreach(TextMeshProUGUI txt in __instance.outputPortsContainer.GetComponentsInChildren<TextMeshProUGUI>())
[HarmonyPostfix]
public static void UpdateDisplay(RuntimeNodeUI __instance)
{
if (!__instance.isActiveAndEnabled) return;
TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString());
if(__instance.Node.nodeType == "PlantTypeValueNode" || __instance.Node.nodeType == "SinglePlantTypeListNode")
{ {
foreach(TextMeshProUGUI txt in __instance.GetComponentsInChildren<TextMeshProUGUI>()) txt.text = TranslateCodeText(txt.text);
txt.font = fontAsset;
}
if (
__instance.GetComponentsInChildren<TMP_Dropdown>().Count == 0
&& __instance.GetComponentsInChildren<TMP_InputField>().Count == 0
&& __instance.Node.nodeType != "PlantTypeValueNode"
&& __instance.Node.nodeType != "SinglePlantTypeListNode"
&& __instance.Node.nodeType != "ZombieTypeValueNode"
) return;
if (__instance.Node != null)
{
if(__instance.Node.nodeType == "PlantTypeValueNode")
{ {
if(txt.gameObject.name.Contains("Label")) foreach(TextMeshProUGUI txt in __instance.GetComponentsInChildren<TextMeshProUGUI>())
{ {
string plantName = Utils.GetPlantNameFromAlmanac(__instance.Node.GetPortValue<PlantType>(__instance.Node.nodeName, PlantType.Nothing)); if(txt.gameObject.name.Contains("Label"))
txt.text = (plantName != "") ? plantName : StringStore.TranslateText(txt.text); {
txt.font = fontAsset; if (Utils.CheckForUntranslatedText(txt.text))
{
PlantTypeValueNode castedNode = __instance.Node.TryCast<PlantTypeValueNode>();
if (castedNode != null)
{
string portName = castedNode.value_PortName;
string plantName = Utils.GetPlantNameFromAlmanac(castedNode.value, removeTags: true);
txt.text = (plantName != "") ? plantName : StringStore.TranslateText(txt.text);
txt.font = fontAsset;
}
}
}
}
}
if(__instance.Node.nodeType == "SinglePlantTypeListNode")
{
foreach(TextMeshProUGUI txt in __instance.GetComponentsInChildren<TextMeshProUGUI>())
{
if (txt.gameObject.name.Contains("Label"))
{
if (Utils.CheckForUntranslatedText(txt.text))
{
SinglePlantTypeListNode castedNode = __instance.Node.TryCast<SinglePlantTypeListNode>();
if (castedNode != null)
{
string portName = castedNode.plantTypeList_PortName;
string plantName = Utils.GetPlantNameFromAlmanac(castedNode.plantType, removeTags: true);
txt.text = (plantName != "") ? plantName : StringStore.TranslateText(txt.text);
txt.font = fontAsset;
}
}
}
}
}
if(__instance.Node.nodeType == "ZombieTypeValueNode")
{
foreach(TextMeshProUGUI txt in __instance.GetComponentsInChildren<TextMeshProUGUI>())
{
if(txt.gameObject.name.Contains("Label"))
{
if(Utils.CheckForUntranslatedText(txt.text))
{
ZombieTypeValueNode castedNode = __instance.Node.TryCast<ZombieTypeValueNode>();
if(castedNode != null)
{
string portName = castedNode.value_PortName;
string zombieName = Utils.GetZombieNameFromAlmanac(castedNode.value, removeTags: true);
txt.text = (zombieName != "") ? zombieName : StringStore.TranslateText(txt.text);
txt.font = fontAsset;
}
}
}
} }
} }
} }
if(__instance.Node.nodeType == "ZombieTypeValueNode") if(__instance.GetComponentsInChildren<TMP_Dropdown>().Count > 0)
{ {
foreach(TextMeshProUGUI txt in __instance.GetComponentsInChildren<TextMeshProUGUI>()) foreach(TMP_Dropdown dropdown in __instance.GetComponentsInChildren<TMP_Dropdown>())
{
if(txt.gameObject.name.Contains("Label"))
{
string zombieName = Utils.GetZombieNameFromAlmanac(__instance.Node.GetPortValue<ZombieType>(__instance.Node.nodeName, ZombieType.Nothing));
txt.text = (zombieName != "") ? zombieName : StringStore.TranslateText(txt.text);
txt.font = fontAsset;
}
}
}
if(__instance.dropdownPrefab)
{
if(__instance.dropdownPrefab.TryGetComponent<TMP_Dropdown>(out TMP_Dropdown dropdown))
{ {
TMP_Dropdown_Patch.CreateDropdownList(dropdown); TMP_Dropdown_Patch.CreateDropdownList(dropdown);
} }
} }
if(__instance.valueInputField) if(__instance.GetComponentsInChildren<TMP_InputField>().Count > 0)
{ {
TMP_InputField_Patch.OnEnable(__instance.valueInputField); foreach(TMP_InputField inputField in __instance.GetComponentsInChildren<TMP_InputField>())
foreach(TextMeshProUGUI txt in __instance.valueInputField.GetComponentsInChildren<TextMeshProUGUI>(true))
{ {
txt.text = StringStore.translationString.ContainsKey(txt.text + "_code") ? StringStore.TranslateText(txt.text + "_code") : StringStore.TranslateText(txt.text); TMP_InputField_Patch.OnEnable(inputField);
foreach(TextMeshProUGUI txt in inputField.GetComponentsInChildren<TextMeshProUGUI>(true))
{
txt.text = TranslateCodeText(txt.text);
}
} }
} }
} }
[HarmonyPatch(nameof(RuntimeNodeUI.UpdateSelectionVisual))] public static string TranslateCodeText(string originalText)
[HarmonyPostfix]
public static void UpdateSelectionVisual(RuntimeNodeUI __instance)
{ {
UpdateDisplay(__instance); return StringStore.translationString.ContainsKey(originalText + "_code") ? StringStore.TranslateText(originalText + "_code") : StringStore.TranslateText(originalText);
} }
} }
} }

View file

@ -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>C:\Users\rainb\Desktop\PC_PVZ-Fusion_3.6.1</GamePath> <GamePath>C:\Users\rainb\Desktop\PC_PVZ-Fusion_3.7</GamePath>
<Platforms>AnyCPU;ARM64;x64</Platforms> <Platforms>AnyCPU;ARM64;x64</Platforms>
</PropertyGroup> </PropertyGroup>
@ -31,7 +31,6 @@
<ItemGroup> <ItemGroup>
<None Remove=".gitattributes" /> <None Remove=".gitattributes" />
<None Remove=".gitignore" /> <None Remove=".gitignore" />
<None Remove="Resources\ModUpdateUtil.exe" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -305,6 +304,9 @@
<Reference Include="Il2CppInterop.Common"> <Reference Include="Il2CppInterop.Common">
<HintPath>$(GamePath)\MelonLoader\net6\Il2CppInterop.Common.dll</HintPath> <HintPath>$(GamePath)\MelonLoader\net6\Il2CppInterop.Common.dll</HintPath>
</Reference> </Reference>
<Reference Include="Il2CppCore">
<HintPath>$(GamePath)\MelonLoader\Il2CppAssemblies\Il2CppCore.dll</HintPath>
</Reference>
</ItemGroup> </ItemGroup>
@ -404,19 +406,26 @@
<Compile Include="AssetStore\AudioStore.cs" /> <Compile Include="AssetStore\AudioStore.cs" />
<Compile Include="Patches\BaseTextObjects\TMP_Dropdown_Patch.cs" /> <Compile Include="Patches\BaseTextObjects\TMP_Dropdown_Patch.cs" />
<Compile Include="Patches\GameObjects\AlmanacCardUI_Patch.cs" /> <Compile Include="Patches\GameObjects\AlmanacCardUI_Patch.cs" />
<Compile Include="Patches\GameObjects\AlmanacBuffMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\AlmanacSelectMenu_Patch.cs" /> <Compile Include="Patches\GameObjects\AlmanacSelectMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\ButtonObjects\LevelSaveEnter_Patch.cs" />
<Compile Include="Patches\GameObjects\ConfirmMenu_Patch.cs" /> <Compile Include="Patches\GameObjects\ConfirmMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\LevelResultMenu_Patch.cs" /> <Compile Include="Patches\GameObjects\LevelResultMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\LoseMenu_Patch.cs" /> <Compile Include="Patches\GameObjects\LoseMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\MinorObjects\GameLose_Patch.cs" /> <Compile Include="Patches\GameObjects\MinorObjects\GameLose_Patch.cs" />
<Compile Include="Patches\GameObjects\MinorObjects\HealthSlider_Patch.cs" />
<Compile Include="Patches\GameObjects\MinorObjects\PumpinerChestMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\MinorObjects\SpecialCard_Patch.cs" />
<Compile Include="Patches\GameObjects\PlayerSaveMenu_Patch.cs" /> <Compile Include="Patches\GameObjects\PlayerSaveMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\PVPRandomManager_Patch.cs" /> <Compile Include="Patches\GameObjects\PVPRandomManager_Patch.cs" />
<Compile Include="Patches\GameObjects\GodShootingMenu_Patch.cs" /> <Compile Include="Patches\GameObjects\GodShootingMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\ButtonObjects\GodShootingLevelButton_Patch.cs" /> <Compile Include="Patches\GameObjects\ButtonObjects\GodShootingLevelButton_Patch.cs" />
<Compile Include="Patches\GameObjects\PlantDataMenu_Patch.cs" /> <Compile Include="Patches\GameObjects\PlantDataMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\ReNameMenu_Patch.cs" />
<Compile Include="Patches\GameObjects\WarningMenu_Patch.cs" /> <Compile Include="Patches\GameObjects\WarningMenu_Patch.cs" />
<Compile Include="Patches\Modes\Abyss\AbyssBuffMenu_Patch.cs" /> <Compile Include="Patches\Modes\Abyss\AbyssBuffMenu_Patch.cs" />
<Compile Include="Patches\Modes\Odyssey\MultipleChoiceMenu_Patch.cs" /> <Compile Include="Patches\Modes\Odyssey\MultipleChoiceMenu_Patch.cs" />
<Compile Include="Patches\Modes\Odyssey\ShootingManager_Patch.cs" />
<Compile Include="Patches\Modes\Odyssey\TravelAdvantureMenu_Patch.cs" /> <Compile Include="Patches\Modes\Odyssey\TravelAdvantureMenu_Patch.cs" />
<Compile Include="Patches\Modes\Odyssey\TravelInvestMenu_Patch.cs" /> <Compile Include="Patches\Modes\Odyssey\TravelInvestMenu_Patch.cs" />
<Compile Include="Patches\Modes\Odyssey\SynergyDisplay_Patch.cs" /> <Compile Include="Patches\Modes\Odyssey\SynergyDisplay_Patch.cs" />
@ -515,13 +524,14 @@
<Compile Include="Patches\Managers\SaveMenu_Patch.cs" /> <Compile Include="Patches\Managers\SaveMenu_Patch.cs" />
<Compile Include="Patches\Modes\Odyssey\TravelBuffOptionButton_Patch.cs" /> <Compile Include="Patches\Modes\Odyssey\TravelBuffOptionButton_Patch.cs" />
<Compile Include="Patches\Modes\Super Editor\CustomButton_enterGame_Patch.cs" /> <Compile Include="Patches\Modes\Super Editor\CustomButton_enterGame_Patch.cs" />
<Compile Include="Patches\Modes\Super Editor\CustomMenuPage_event_Patch_B.cs" />
<Compile Include="Patches\Modes\Super Editor\CustomOnlineMenu_Patch.cs" /> <Compile Include="Patches\Modes\Super Editor\CustomOnlineMenu_Patch.cs" />
<Compile Include="Patches\Modes\Super Editor\CustomMenuPage_shooting_Patch.cs" /> <Compile Include="Patches\Modes\Super Editor\CustomMenuPage_shooting_Patch.cs" />
<Compile Include="Patches\Modes\Super Editor\CustomLevelMenu_Patch.cs" /> <Compile Include="Patches\Modes\Super Editor\CustomLevelMenu_Patch.cs" />
<Compile Include="Patches\Modes\Super Editor\CustomMenuPage_page3_Patch.cs" /> <Compile Include="Patches\Modes\Super Editor\CustomMenuPage_page3_Patch.cs" />
<Compile Include="Patches\Modes\Super Editor\CustomMenuPage_initZombies_Patch.cs" /> <Compile Include="Patches\Modes\Super Editor\CustomMenuPage_initZombies_Patch.cs" />
<Compile Include="Patches\Modes\Super Editor\GameLevel\EventNodes\RuntimeNodeUI_Patch.cs" />
<Compile Include="Patches\Modes\Super Editor\GameLevel\EventNodes\RuntimeEventNodeEditor_Patch.cs" /> <Compile Include="Patches\Modes\Super Editor\GameLevel\EventNodes\RuntimeEventNodeEditor_Patch.cs" />
<Compile Include="Patches\Modes\Super Editor\GameLevel\EventNodes\RuntimeNodeUI_Patch.cs" />
<Compile Include="Patches\Modes\Super Editor\GameLevel\LevelManager_Patch.cs" /> <Compile Include="Patches\Modes\Super Editor\GameLevel\LevelManager_Patch.cs" />
<Compile Include="Patches\Modes\Super Editor\RhythmGame\RhythmGameChartEditorUI_Patch.cs" /> <Compile Include="Patches\Modes\Super Editor\RhythmGame\RhythmGameChartEditorUI_Patch.cs" />
<Compile Include="Patches\Modes\Super Editor\RhythmGame\RhythmGameManager_Patch.cs" /> <Compile Include="Patches\Modes\Super Editor\RhythmGame\RhythmGameManager_Patch.cs" />
@ -565,11 +575,11 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Resources\ModUpdateUtil.exe" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <Folder Include="Resources\" />
</ItemGroup> </ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent"> <Target Name="PostBuild" AfterTargets="PostBuildEvent">

View file

@ -10,6 +10,7 @@ using PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects;
using PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects; using PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects;
using PvZ_Fusion_Translator.Patches.Modes.Super_Editor; using PvZ_Fusion_Translator.Patches.Modes.Super_Editor;
using System.Diagnostics; using System.Diagnostics;
using System.Reflection;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Unity.Burst.Intrinsics; using Unity.Burst.Intrinsics;
using UnityEngine; using UnityEngine;
@ -115,13 +116,34 @@ namespace PvZ_Fusion_Translator
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 size tags like <color=#FF0000>
string withoutOpenTags = Regex.Replace(text, @"<size=[^>]+>", string.Empty, RegexOptions.IgnoreCase); string withoutOpenTags = Regex.Replace(text, @"<size=[^>]+>", string.Empty, RegexOptions.IgnoreCase);
// Remove closing color tags like </color> // Remove closing size tags like </color>
string withoutCloseTags = Regex.Replace(withoutOpenTags, @"</size>", string.Empty, RegexOptions.IgnoreCase); string withoutCloseTags = Regex.Replace(withoutOpenTags, @"</size>", string.Empty, RegexOptions.IgnoreCase);
return withoutCloseTags; return withoutCloseTags;
} }
public static string RemoveFormatTags(string text)
{
if (string.IsNullOrEmpty(text))
return text ?? string.Empty;
string withoutUnderlineTags = Regex.Replace(text, @"<u>", string.Empty, RegexOptions.IgnoreCase);
string withoutUnderlineCloseTags = Regex.Replace(withoutUnderlineTags, @"</u>", string.Empty, RegexOptions.IgnoreCase);
string withoutItalicTags = Regex.Replace(withoutUnderlineCloseTags, @"<i>", string.Empty, RegexOptions.IgnoreCase);
string withoutItalicCloseTags = Regex.Replace(withoutItalicTags, @"</i>", string.Empty, RegexOptions.IgnoreCase);
return withoutItalicCloseTags;
}
public static string RemoveAllTags(string text)
{
if (string.IsNullOrEmpty(text))
return text ?? string.Empty;
return RemoveColorTags(RemoveSizeTags(RemoveFormatTags(text)));
}
public static GameObject ConvertToTextMeshProUGUI(GameObject originalText, Transform parent, string name) public static GameObject ConvertToTextMeshProUGUI(GameObject originalText, Transform parent, string name)
{ {
GameObject newObj = new GameObject(name); GameObject newObj = new GameObject(name);
@ -152,7 +174,7 @@ namespace PvZ_Fusion_Translator
newGoBackText.color = color; newGoBackText.color = color;
} }
public static string GetPlantNameFromAlmanac(PlantType thePlantType, bool log = false) public static string GetPlantNameFromAlmanac(PlantType thePlantType, bool removeTags = false, bool log = false)
{ {
bool foundPlantName = false; bool foundPlantName = false;
string thePlantName = ""; string thePlantName = "";
@ -172,18 +194,20 @@ namespace PvZ_Fusion_Translator
thePlantName = ""; thePlantName = "";
} }
thePlantName = (removeTags) ? RemoveAllTags(thePlantName) : thePlantName;
return thePlantName; return thePlantName;
} }
public static string GetPlantNameFromAlmanac(string theOriginalPlantName, bool log = false) public static string GetPlantNameFromAlmanac(string theOriginalPlantName, bool removeTags = false, bool log = false)
{ {
bool foundPlantName = false; bool foundPlantName = false;
string thePlantName = ""; string thePlantName = "";
if(plantIndiceStrings.ContainsKey(theOriginalPlantName)) if(plantIndiceString.ContainsKey(theOriginalPlantName))
{ {
foundPlantName = true; foundPlantName = true;
thePlantName = plantIndiceStrings[theOriginalPlantName]; thePlantName = plantIndiceString[theOriginalPlantName];
} }
if (!foundPlantName) if (!foundPlantName)
@ -195,10 +219,12 @@ namespace PvZ_Fusion_Translator
thePlantName = ""; thePlantName = "";
} }
thePlantName = (removeTags) ? RemoveAllTags(thePlantName) : thePlantName;
return thePlantName; return thePlantName;
} }
public static string GetZombieNameFromAlmanac(ZombieType theZombieType) public static string GetZombieNameFromAlmanac(ZombieType theZombieType, bool removeTags = false)
{ {
string json; string json;
string theZombieName = ""; string theZombieName = "";
@ -216,16 +242,18 @@ namespace PvZ_Fusion_Translator
} }
} }
theZombieName = (removeTags) ? RemoveAllTags(theZombieName) : theZombieName;
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 Dictionary<string, string> plantIndiceStrings = new Dictionary<string, string>(); public static Dictionary<string, string> plantIndiceString = new Dictionary<string, string>();
public static void RegisterPlantIndices() public static void RegisterPlantIndices()
{ {
plantIndices = new Dictionary<int, KeyValuePair<int, string>>(); plantIndices = new Dictionary<int, KeyValuePair<int, string>>();
plantIndiceStrings = new Dictionary<string, string>(); plantIndiceString = new Dictionary<string, string>();
string originalJson; string originalJson;
string translatedJson; string translatedJson;
@ -241,38 +269,111 @@ namespace PvZ_Fusion_Translator
} }
else else
{ {
originalJson = File.ReadAllText(originalPath); try
translatedJson = AlmanacPlantMenu_Patch.almanacJson;
Il2CppAlmanacData.AlmanacData originalPlantData = JsonUtility.FromJson<Il2CppAlmanacData.AlmanacData>(originalJson);
Il2CppAlmanacData.AlmanacData translatedPlantData = JsonUtility.FromJson<Il2CppAlmanacData.AlmanacData>(translatedJson);
for (int i = 0; i < originalPlantData.plants.Count; i++)
{ {
Il2CppAlmanacData.PlantInfo originalPlantInfo = originalPlantData.plants[i]; originalJson = File.ReadAllText(originalPath);
if(!plantIndiceStrings.ContainsKey(originalPlantInfo.name)) translatedJson = AlmanacPlantMenu_Patch.almanacJson;
{ Il2CppAlmanacData.AlmanacData originalPlantData = JsonUtility.FromJson<Il2CppAlmanacData.AlmanacData>(originalJson);
plantIndiceStrings.Add(originalPlantInfo.name, originalPlantInfo.name); Il2CppAlmanacData.AlmanacData translatedPlantData = JsonUtility.FromJson<Il2CppAlmanacData.AlmanacData>(translatedJson);
}
Il2CppAlmanacData.PlantInfo translatedPlantInfo = null;
foreach (Il2CppAlmanacData.PlantInfo info in translatedPlantData.plants) foreach (Il2CppAlmanacData.PlantInfo originalPlantInfo in originalPlantData.plants)
{ {
if (info.seedType == originalPlantInfo.seedType) if(!plantIndiceString.ContainsKey(originalPlantInfo.name))
{ {
translatedPlantInfo = info; plantIndiceString.Add(originalPlantInfo.name, originalPlantInfo.name);
}
Il2CppAlmanacData.PlantInfo translatedPlantInfo = null;
foreach (Il2CppAlmanacData.PlantInfo info in translatedPlantData.plants)
{
if (info.seedType == originalPlantInfo.seedType)
{
translatedPlantInfo = info;
}
}
if (translatedPlantInfo != null)
{
if(translatedPlantInfo.name != null)
{
KeyValuePair<int, string> temp = new KeyValuePair<int, string>(translatedPlantInfo.seedType, translatedPlantInfo.name);
plantIndices.Add(originalPlantInfo.seedType, temp);
plantIndiceString[originalPlantInfo.name] = translatedPlantInfo.name;
}
} }
} }
}
if (translatedPlantInfo != null) catch (Exception e)
{ {
KeyValuePair<int, string> temp = new KeyValuePair<int, string>(translatedPlantInfo.seedType, translatedPlantInfo.name); Log.LogError(e);
plantIndices.Add(originalPlantInfo.seedType, temp);
plantIndiceStrings[originalPlantInfo.name] = translatedPlantInfo.name;
}
} }
} }
} }
public static void TryAdd<A, B>(Dictionary<A, B> dict, A key, B val)
{
if (dict.ContainsKey(key))
{
dict[key] = val;
}
else
{
dict.Add(key, val);
}
}
public static void TryAdd<A, B>(SortedDictionary<A, B> dict, A key, B val)
{
if (dict.ContainsKey(key))
{
dict[key] = val;
}
else
{
dict.Add(key, val);
}
}
public static AssetBundle GetAssetBundle(Assembly assembly, string assetBundlePath, bool log = false)
{
try
{
if (assembly != null)
{
Stream manifestResourceStream = assembly.GetManifestResourceStream($"PvZ_Fusion_Translator.Resources.{assetBundlePath}");
using (manifestResourceStream)
{
if (manifestResourceStream == null)
{
throw new Exception("Stream was null.");
}
byte[] array = new byte[manifestResourceStream.Length];
manifestResourceStream.Read(array, 0, array.Length);
AssetBundle assetBundle = AssetBundle.LoadFromMemory(array);
ArgumentNullException.ThrowIfNull(assetBundle, "assetBundle");
if(log)
{
Log.LogDebug($"AssetBundle {assetBundlePath} has successfully been loaded.");
}
return assetBundle;
}
}
throw new Exception($"AssetBundle {assetBundlePath} was null.");
}
catch (Exception value)
{
throw new ArgumentException($"Failed to load {assetBundlePath}. \n{value}");
}
}
public static AssetBundle GetAssetBundle(string path)
{
AssetBundle assetBundle = AssetBundle.LoadFromFile(path);
return assetBundle;
}
/*public static Dictionary<int, List<int>> recipeLinks = new Dictionary<int, List<int>>(); /*public static Dictionary<int, List<int>> recipeLinks = new Dictionary<int, List<int>>();
public static void RegisterRecipeLinks() public static void RegisterRecipeLinks()
@ -316,12 +417,13 @@ namespace PvZ_Fusion_Translator
} }
}*/ }*/
public static Regex untranslatedRegex = new("\\p{IsCJKUnifiedIdeographs}+");
public static bool CheckForUntranslatedText(string text) public static bool CheckForUntranslatedText(string text)
{ {
Regex regex = new("\\p{IsCJKUnifiedIdeographs}+"); try
try
{ {
Match match = regex.Match(text); Match match = untranslatedRegex.Match(text);
return match.Success; return match.Success;
} }
catch(Exception e) catch(Exception e)
@ -346,6 +448,7 @@ namespace PvZ_Fusion_Translator
confirmButton.clickEvent = new UnityEvent(); confirmButton.clickEvent = new UnityEvent();
confirmButton.clickEvent.AddListener(new Action(() => SwapLocalData())); confirmButton.clickEvent.AddListener(new Action(() => SwapLocalData()));
confirmButton.clickEvent.AddListener(new Action(() => CursorChange.SetDefaultCursor()));
confirmButton.clickEvent.AddListener(new Action(() => GameAPP.UIManager.Pop())); confirmButton.clickEvent.AddListener(new Action(() => GameAPP.UIManager.Pop()));
} }
@ -356,6 +459,7 @@ namespace PvZ_Fusion_Translator
ChangeLanguage(Utils.Language.ToString()); ChangeLanguage(Utils.Language.ToString());
string sourceMsg = "<size=10>" + (!(Utils.useLocal) ? "Translation Source:\nOnline" : "Translation Source:\nLocal"); string sourceMsg = "<size=10>" + (!(Utils.useLocal) ? "Translation Source:\nOnline" : "Translation Source:\nLocal");
OptLanguageBtn_Patch.FlashMessage(OptLanguageBtn_Patch.toggleSlots[2], sourceMsg, 0.1f, false); OptLanguageBtn_Patch.FlashMessage(OptLanguageBtn_Patch.toggleSlots[2], sourceMsg, 0.1f, false);
CursorChange.SetDefaultCursor();
} }
public static async Task<string> GetDataFromWeb(string url, bool isLog = true) public static async Task<string> GetDataFromWeb(string url, bool isLog = true)
@ -560,8 +664,8 @@ namespace PvZ_Fusion_Translator
// Slovak, // Slovak,
//Polish, //Polish,
//Turkish, //Turkish,
//Arabic, Arabic,
Romanian, Romanian,
LANG_END LANG_END
} }
@ -578,6 +682,7 @@ namespace PvZ_Fusion_Translator
{ LanguageEnum.Japanese, "日本語"}, { LanguageEnum.Japanese, "日本語"},
{ LanguageEnum.Korean, "한국어"}, { LanguageEnum.Korean, "한국어"},
{ LanguageEnum.Ukrainian, "українська"}, { LanguageEnum.Ukrainian, "українська"},
{ LanguageEnum.Arabic, "ﺔﻴﺑﺮﻌﻟا"},
{ LanguageEnum.Romanian, "Română"} { LanguageEnum.Romanian, "Română"}
}; };

View file

@ -1,7 +1,7 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 18
VisualStudioVersion = 17.10.35122.118 VisualStudioVersion = 18.7.11911.148 stable
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject