From 400fe3d3cb5165dc9cad7b09cf56affe5ea681da Mon Sep 17 00:00:00 2001 From: Teyliu Date: Sat, 19 Apr 2025 11:44:12 -0500 Subject: [PATCH] INIT --- .gitignore | 1 + PvZ-Fusion-Blooms-master/.gitattributes | 63 + PvZ-Fusion-Blooms-master/.gitignore | 363 +++++ .../BepInEx/AssetStore/CheckSumStore.cs | 115 ++ .../BepInEx/AssetStore/FontStore.cs | 143 ++ .../BepInEx/AssetStore/StringStore.cs | 327 ++++ .../BepInEx/AssetStore/TextureStore.cs | 63 + .../BepInEx/AssetStore/WarningStore.cs | 154 ++ PvZ-Fusion-Blooms-master/BepInEx/Core.cs | 125 ++ .../BepInEx/FileLoader.cs | 344 ++++ .../BepInEx/FontHandler.cs | 45 + PvZ-Fusion-Blooms-master/BepInEx/Log.cs | 25 + .../BepInEx/ModFeatures.cs | 79 + .../BaseTextObjects/InGameText_Patch.cs | 25 + .../BaseTextObjects/TMP_InputField_Patch.cs | 23 + .../BaseTextObjects/TextMeshProUGUI_Patch.cs | 77 + .../BaseTextObjects/TextMeshPro_Patch.cs | 27 + .../ButtonObjects/Advanture_Btn_Patch.cs | 102 ++ .../GameObjects/ButtonObjects/EveBtn_Patch.cs | 41 + .../ButtonObjects/InGameBtn_Patch.cs | 34 + .../ButtonObjects/OptLanguageBtn_Patch.cs | 213 +++ .../ButtonObjects/OptionBtn_Patch.cs | 68 + .../ButtonObjects/PVPPotBtn_Patch.cs | 41 + .../ButtonObjects/PauseMenu_Btn_Patch.cs | 13 + .../Patches/GameObjects/Close_Patch.cs | 48 + .../GameObjects/CustomSettings_Patch.cs | 23 + .../Patches/GameObjects/CustomSun_Patch.cs | 44 + .../Patches/GameObjects/GardenPlant_Patch.cs | 23 + .../Patches/GameObjects/Help__Patch.cs | 31 + .../GameObjects/MinorObjects/DY_Patch.cs | 16 + .../MinorObjects/LanternUmbrella_Patch.cs | 17 + .../MinorObjects/MagnetBox_Patch.cs | 16 + .../MinorObjects/MagnetInterface_Patch.cs | 16 + .../GameObjects/MinorObjects/Money_Patch.cs | 17 + .../GameObjects/MinorObjects/Plant_Patch.cs | 21 + .../MinorObjects/PlayerName_Patch.cs | 16 + .../MinorObjects/SelectYourPlants_Patch.cs | 20 + .../GameObjects/MinorObjects/Zombie_Patch.cs | 21 + .../Patches/GameObjects/TravelBuff_Patch.cs | 17 + .../GameObjects/TravelRefresh_Patch.cs | 47 + .../Patches/GameObjects/TravelStore_Patch.cs | 38 + .../Patches/GameObjects/UIDifficulty_Patch.cs | 22 + .../Patches/GameObjects/UIZombieNum_Patch.cs | 21 + .../Managers/AlmanacMgrZombie_Patch.cs | 97 ++ .../Patches/Managers/AlmanacMgr_Patch.cs | 99 ++ .../Patches/Managers/DifficultyMgr_Patch.cs | 17 + .../Patches/Managers/EndlessMgr_Patch.cs | 27 + .../BepInEx/Patches/Managers/IZEMgr_Patch.cs | 26 + .../Patches/Managers/InGameUIMgr_Patch.cs | 32 + .../Managers/OppositeBuffManager_Patch.cs | 28 + .../Patches/Managers/TravelBuffMgr_Patch.cs | 26 + .../Patches/Managers/TravelMenuMgr_Patch.cs | 50 + .../BepInEx/Patches/Managers/UIMgr_Patch.cs | 17 + .../OtherManagers/AchievementClip_Patch.cs | 63 + .../Patches/OtherManagers/GardenUI_Patch.cs | 17 + .../Patches/OtherManagers/MenuText_Patch.cs | 21 + .../Patches/OtherManagers/ThanksMenu_Patch.cs | 27 + .../PvZ Fusion Translator [BepInEx].csproj | 381 +++++ PvZ-Fusion-Blooms-master/BepInEx/Utils.cs | 128 ++ .../MelonLoader/AssetStore/AudioStore.cs | 181 +++ .../MelonLoader/AssetStore/CheckSumStore.cs | 858 ++++++++++ .../MelonLoader/AssetStore/FontStore.cs | 170 ++ .../MelonLoader/AssetStore/StringStore.cs | 1404 +++++++++++++++++ .../MelonLoader/AssetStore/TextureStore.cs | 67 + .../MelonLoader/AssetStore/WarningStore.cs | 180 +++ PvZ-Fusion-Blooms-master/MelonLoader/Core.cs | 109 ++ .../MelonLoader/FileLoader.cs | 359 +++++ .../MelonLoader/FontHandler.cs | 43 + PvZ-Fusion-Blooms-master/MelonLoader/Log.cs | 24 + .../MelonLoader/ModFeatures.cs | 78 + .../BaseTextObjects/InGameText_Patch.cs | 33 + .../BaseTextObjects/TMP_InputField_Patch.cs | 23 + .../BaseTextObjects/TextMeshProUGUI_Patch.cs | 77 + .../BaseTextObjects/TextMeshPro_Patch.cs | 27 + .../ButtonObjects/AbyssBuffButton_Patch.cs | 24 + .../ButtonObjects/AbyssButton_Patch.cs | 26 + .../ButtonObjects/Advanture_Btn_Patch.cs | 103 ++ .../ButtonObjects/BaseMenu_Patch.cs | 111 ++ .../GameObjects/ButtonObjects/EveBtn_Patch.cs | 42 + .../ButtonObjects/InGameBtn_Patch.cs | 35 + .../ButtonObjects/OptLanguageBtn_Patch.cs | 212 +++ .../ButtonObjects/OptionBtn_Patch.cs | 69 + .../ButtonObjects/PVPPotBtn_Patch.cs | 42 + .../ButtonObjects/PauseMenu_Btn_Patch.cs | 15 + .../ButtonObjects/SaveMenuBtn_Patch.cs | 24 + .../Patches/GameObjects/Close_Patch.cs | 52 + .../GameObjects/CustomSettings_Patch.cs | 24 + .../Patches/GameObjects/CustomSun_Patch.cs | 45 + .../Patches/GameObjects/GardenPlant_Patch.cs | 24 + .../GameObjects/MinorObjects/DY_Patch.cs | 17 + .../MinorObjects/LanternUmbrella_Patch.cs | 18 + .../MinorObjects/MagnetBox_Patch.cs | 17 + .../MinorObjects/MagnetInterface_Patch.cs | 17 + .../GameObjects/MinorObjects/Money_Patch.cs | 18 + .../GameObjects/MinorObjects/Plant_Patch.cs | 24 + .../MinorObjects/PlayerName_Patch.cs | 17 + .../MinorObjects/SelectYourPlants_Patch.cs | 21 + .../GameObjects/MinorObjects/Zombie_Patch.cs | 12 + .../GameObjects/NoticePauseMenu_Patch.cs | 32 + .../Patches/GameObjects/TravelBuff_Patch.cs | 18 + .../GameObjects/TravelRefresh_Patch.cs | 53 + .../Patches/GameObjects/TravelStore_Patch.cs | 38 + .../Patches/GameObjects/UIDifficulty_Patch.cs | 30 + .../Patches/GameObjects/UIZombieNum_Patch.cs | 29 + .../Managers/AbyssDevelopMenu_Patch.cs | 19 + .../Patches/Managers/AbyssMenu2_Patch.cs | 74 + .../Patches/Managers/AbyssMenu_Patch.cs | 26 + .../Managers/AlmanacMgrZombie_Patch.cs | 101 ++ .../Managers/AlmanacPlantBank_Patch.cs | 108 ++ .../Managers/CustomLevelShower_Patch.cs | 23 + .../Patches/Managers/DifficultyMgr_Patch.cs | 18 + .../Patches/Managers/EndlessMgr_Patch.cs | 27 + .../Patches/Managers/IZEMgr_Patch.cs | 28 + .../Patches/Managers/InGameUIMgr_Patch.cs | 33 + .../Managers/OppositeBuffManager_Patch.cs | 89 ++ .../Patches/Managers/SaveMenu_Patch.cs | 23 + .../Patches/Managers/TravelBuffMgr_Patch.cs | 25 + .../Patches/Managers/TravelMenuMgr_Patch.cs | 51 + .../Patches/Managers/UIMgr_Patch.cs | 22 + .../OtherManagers/AchievementClip_Patch.cs | 70 + .../Patches/OtherManagers/GardenUI_Patch.cs | 22 + .../Patches/OtherManagers/MenuText_Patch.cs | 23 + .../Patches/OtherManagers/ThanksMenu_Patch.cs | 23 + PvZ-Fusion-Blooms-master/MelonLoader/Utils.cs | 132 ++ .../PvZ Fusion Translator.sln | 146 ++ PvZ-Fusion-Blooms-master/README.md | 34 + 126 files changed, 10000 insertions(+) create mode 100644 PvZ-Fusion-Blooms-master/.gitattributes create mode 100644 PvZ-Fusion-Blooms-master/.gitignore create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/AssetStore/CheckSumStore.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/AssetStore/FontStore.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/AssetStore/StringStore.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/AssetStore/TextureStore.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/AssetStore/WarningStore.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Core.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/FileLoader.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/FontHandler.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Log.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/ModFeatures.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/BaseTextObjects/InGameText_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/BaseTextObjects/TMP_InputField_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/BaseTextObjects/TextMeshProUGUI_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/BaseTextObjects/TextMeshPro_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/Advanture_Btn_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/EveBtn_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/InGameBtn_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/OptionBtn_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/PVPPotBtn_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/PauseMenu_Btn_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/Close_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/CustomSettings_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/CustomSun_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/GardenPlant_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/Help__Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/DY_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/LanternUmbrella_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/MagnetBox_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/MagnetInterface_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/Money_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/Plant_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/PlayerName_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/SelectYourPlants_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/Zombie_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/TravelBuff_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/TravelRefresh_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/TravelStore_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/UIDifficulty_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/UIZombieNum_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/AlmanacMgrZombie_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/AlmanacMgr_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/DifficultyMgr_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/EndlessMgr_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/IZEMgr_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/InGameUIMgr_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/OppositeBuffManager_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/TravelBuffMgr_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/TravelMenuMgr_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/UIMgr_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/OtherManagers/AchievementClip_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/OtherManagers/GardenUI_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/OtherManagers/MenuText_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Patches/OtherManagers/ThanksMenu_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/PvZ Fusion Translator [BepInEx].csproj create mode 100644 PvZ-Fusion-Blooms-master/BepInEx/Utils.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/AudioStore.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/CheckSumStore.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/FontStore.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/StringStore.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/TextureStore.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/WarningStore.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Core.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/FileLoader.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/FontHandler.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Log.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/ModFeatures.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/BaseTextObjects/InGameText_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/BaseTextObjects/TMP_InputField_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/BaseTextObjects/TextMeshProUGUI_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/BaseTextObjects/TextMeshPro_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/AbyssBuffButton_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/AbyssButton_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/Advanture_Btn_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/BaseMenu_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/EveBtn_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/InGameBtn_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/OptionBtn_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/PVPPotBtn_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/PauseMenu_Btn_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/SaveMenuBtn_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/Close_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/CustomSettings_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/CustomSun_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/GardenPlant_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/DY_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/LanternUmbrella_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/MagnetBox_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/MagnetInterface_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/Money_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/Plant_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/PlayerName_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/SelectYourPlants_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/Zombie_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/NoticePauseMenu_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/TravelBuff_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/TravelRefresh_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/TravelStore_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/UIDifficulty_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/UIZombieNum_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/AbyssDevelopMenu_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/AbyssMenu2_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/AbyssMenu_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/AlmanacMgrZombie_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/AlmanacPlantBank_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/CustomLevelShower_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/DifficultyMgr_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/EndlessMgr_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/IZEMgr_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/InGameUIMgr_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/OppositeBuffManager_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/SaveMenu_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/TravelBuffMgr_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/TravelMenuMgr_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/UIMgr_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/OtherManagers/AchievementClip_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/OtherManagers/GardenUI_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/OtherManagers/MenuText_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Patches/OtherManagers/ThanksMenu_Patch.cs create mode 100644 PvZ-Fusion-Blooms-master/MelonLoader/Utils.cs create mode 100644 PvZ-Fusion-Blooms-master/PvZ Fusion Translator.sln create mode 100644 PvZ-Fusion-Blooms-master/README.md diff --git a/.gitignore b/.gitignore index 8a30d25..48d8dca 100644 --- a/.gitignore +++ b/.gitignore @@ -396,3 +396,4 @@ FodyWeavers.xsd # JetBrains Rider *.sln.iml +PvZ-Fusion-Blooms-master/MelonLoader/PvZ Fusion Translator \[MelonLoader\].csproj diff --git a/PvZ-Fusion-Blooms-master/.gitattributes b/PvZ-Fusion-Blooms-master/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/PvZ-Fusion-Blooms-master/.gitignore b/PvZ-Fusion-Blooms-master/.gitignore new file mode 100644 index 0000000..9491a2f --- /dev/null +++ b/PvZ-Fusion-Blooms-master/.gitignore @@ -0,0 +1,363 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/BepInEx/AssetStore/CheckSumStore.cs b/PvZ-Fusion-Blooms-master/BepInEx/AssetStore/CheckSumStore.cs new file mode 100644 index 0000000..db01c11 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/AssetStore/CheckSumStore.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Security.Cryptography; +using System.Text.Encodings.Web; +using System.Text.Json; +using static PvZ_Fusion_Translator__BepInEx_.FileLoader; + +namespace PvZ_Fusion_Translator__BepInEx_.AssetStore +{ + public static class CheckSumStore + { + private static Dictionary modifiedCheckSums = new Dictionary(); + + private static Dictionary checkSums = new Dictionary() + { + }; + + static string GetCheckSum(string filename) + { + using (var md5 = SHA256.Create()) + { + byte[] bytes = md5.ComputeHash(File.ReadAllBytes(filename)); + return Convert.ToBase64String(bytes); + } + } + + public static void SaveCheckSum() + { + string stringDir = GetAssetDir(AssetType.Dumps); + if (!Directory.Exists(stringDir)) + { + Directory.CreateDirectory(stringDir); + } + string checkSumString = JsonSerializer.Serialize(checkSums, new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping + }); + File.WriteAllText(Path.Combine(stringDir, "MD5.json"), checkSumString); + } + + public static void SaveModifiedChecksum() + { + string stringDir = GetAssetDir(AssetType.Dumps); + if (!Directory.Exists(stringDir)) + { + Directory.CreateDirectory(stringDir); + } + string modifiedCheckSumString = JsonSerializer.Serialize(modifiedCheckSums, new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping + }); + File.WriteAllText(Path.Combine(stringDir, "Modified_MD5.json"), modifiedCheckSumString); + } + + public static bool IsModified(string filepath) + { + string fileName = Path.GetFileNameWithoutExtension(filepath); + string directory = Path.GetDirectoryName(filepath); + string slicedFilePath = directory.Substring(directory.IndexOf("PvZ_Fusion_Translator\\") + "PvZ_Fusion_Translator\\".Length); + string slicedKey = Path.Combine(slicedFilePath, fileName); + + #if DEBUG + if (!checkSums.ContainsKey(slicedKey)) + { + checkSums.Add(slicedKey, GetCheckSum(filepath)); + SaveCheckSum(); + modifiedCheckSums.Add(slicedKey, GetCheckSum(filepath)); + SaveModifiedChecksum(); + } + else + { + if ((checkSums[slicedKey] != GetCheckSum(filepath))) + { + checkSums[slicedKey] = GetCheckSum(filepath); + modifiedCheckSums.Add(slicedKey, GetCheckSum(filepath)); + SaveModifiedChecksum(); + } + } + #elif RELEASE + if (!checkSums.ContainsKey(slicedKey) | (checkSums[slicedKey] != GetCheckSum(filepath))) + { + return true; + } + #endif + return false; + } + + #if MELON + public static void ConvertMD5Json() + { + string stringDir = GetAssetDir(AssetType.Dumps); + if (!Directory.Exists(stringDir)) + { + Directory.CreateDirectory(stringDir); + } + string checksumDumpPath = Path.Combine(stringDir, "MD5.json"); + string checksumConvertPath = Path.Combine(stringDir, "MD5Convert.txt"); + string json = File.ReadAllText(checksumDumpPath); + Dictionary dictionary = DeserializeObject>(json); + + using StreamWriter writer = new StreamWriter(checksumConvertPath); + foreach (var kvp in dictionary) + { + string checksumKey = kvp.Key.Replace("\\", "\\\\"); + writer.WriteLine($"{{ \"{kvp.Key}\" , \"{kvp.Value}\" }},"); + } + + Log.LogDebug($"MD5.json converted to MD5Convert.json at {checksumConvertPath}"); + } + #endif + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/AssetStore/FontStore.cs b/PvZ-Fusion-Blooms-master/BepInEx/AssetStore/FontStore.cs new file mode 100644 index 0000000..1788ede --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/AssetStore/FontStore.cs @@ -0,0 +1,143 @@ +using PvZ_Fusion_Translator; +using System.Collections.Generic; +using System.IO; +using TMPro; + +namespace PvZ_Fusion_Translator__BepInEx_.AssetStore +{ + public static class FontStore + { + internal static Dictionary fontAssetDict = []; + internal static Dictionary fontAssetDictSecondary = []; + + internal static void Init() + { + string fontsDir = Path.Combine(Core.Instance.modsDirectory, "[Custom Fonts]"); + foreach (string file in Directory.GetFiles(fontsDir)) + { + string fileName = Path.GetFileNameWithoutExtension(file); + string fileExtension = Path.GetExtension(file); + + if (fileExtension == ".ttf" || fileExtension == ".otf") + { + if (!fileName.EndsWith("_Almanac") && !fileName.EndsWith("_Fallback")) + { + string fontPath = Path.Combine("PvZ_Fusion_Translator", "[Custom Fonts]", fileName + fileExtension); + + TMP_FontAsset fontAsset = FontHandler.LoadTMPFont(fontPath, true); + fontAsset.name = fileName; + fontAssetDict.Add(fileName, fontAsset); + + Log.LogInfo($"Font for language '{fileName}' loaded"); + } + } + } + InitFallback(); + } + + internal static void InitFallback() + { + string fontsDir = Path.Combine(Core.Instance.modsDirectory, "[Custom Fonts]"); + foreach (string file in Directory.GetFiles(fontsDir)) + { + string fileName = Path.GetFileNameWithoutExtension(file); + string fileExtension = Path.GetExtension(file); + + if (fileExtension == ".ttf" || fileExtension == ".otf") + { + if (fileName.EndsWith("_Almanac") || fileName.EndsWith("_Fallback")) + { + string fallbackPath = Path.Combine("PvZ_Fusion_Translator", "[Custom Fonts]", fileName + fileExtension); + TMP_FontAsset fallbackFont = FontHandler.LoadTMPFont(fallbackPath, true); + fallbackFont.name = fileName; + + string fileNameLanguage = fileName.Replace("_Fallback", "").Replace("_Almanac", ""); + + if (fontAssetDictSecondary.ContainsKey(fileNameLanguage)) + { + if (fileName.EndsWith("_Fallback")) + { + fontAssetDictSecondary.Add(fileNameLanguage + "_Almanac", fontAssetDictSecondary[fileNameLanguage]); + fontAssetDictSecondary.Remove(fileNameLanguage); + } + else + { + fontAssetDictSecondary.Add(fileNameLanguage + "_Fallback", fontAssetDictSecondary[fileNameLanguage]); + fontAssetDictSecondary.Remove(fileNameLanguage); + } + fontAssetDictSecondary.Add(fileName, fallbackFont); + } + else + fontAssetDictSecondary.Add(fileNameLanguage, fallbackFont); + } + } + } + AddFallback(); + } + + public static void AddFallback() + { + foreach (var lang in fontAssetDict.Keys) + { + if (fontAssetDict[lang].fallbackFontAssetTable == null) + { + fontAssetDict[lang].fallbackFontAssetTable = new Il2CppSystem.Collections.Generic.List(); + } + + if (fontAssetDictSecondary.ContainsKey(lang)) + { + fontAssetDict[lang].fallbackFontAssetTable.Add(fontAssetDictSecondary[lang]); + Log.LogInfo("Fallback font for language '" + lang + "' added"); + continue; + } + if (fontAssetDictSecondary.ContainsKey(lang + "_Almanac")) + { + fontAssetDict[lang].fallbackFontAssetTable.Add(fontAssetDictSecondary[lang + "_Almanac"]); + Log.LogInfo("Fallback font for language '" + lang + "' added"); + continue; + } + if (fontAssetDictSecondary.ContainsKey(lang + "_Fallback")) + { + fontAssetDict[lang].fallbackFontAssetTable.Add(fontAssetDictSecondary[lang + "_Fallback"]); + Log.LogInfo("Fallback font for language '" + lang + "' added"); + continue; + } + } + } + public static TMP_FontAsset LoadTMPFont(string language) + { + if (fontAssetDict.TryGetValue(language, out TMP_FontAsset font)) + { + return font; + } + return fontAssetDict.GetValueOrDefault("English"); + } + public static TMP_FontAsset LoadTMPFontAlmanac(string language) + { + if (fontAssetDictSecondary.ContainsKey(language)) + { + if (fontAssetDictSecondary.TryGetValue(language, out TMP_FontAsset almanacAsset)) + { + return almanacAsset; + } + } + if (fontAssetDictSecondary.ContainsKey(language + "_Almanac")) + { + if (fontAssetDictSecondary.TryGetValue(language + "_Almanac", out TMP_FontAsset almanacAsset)) + { + return almanacAsset; + } + } + return fontAssetDict.GetValueOrDefault("English"); + } + + public static void Reload() + { + // Get the current language + string currentLanguage = Utils.Language.ToString(); + + // Load the font for the current language + _ = LoadTMPFont(currentLanguage); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/AssetStore/StringStore.cs b/PvZ-Fusion-Blooms-master/BepInEx/AssetStore/StringStore.cs new file mode 100644 index 0000000..33726a5 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/AssetStore/StringStore.cs @@ -0,0 +1,327 @@ +using System.Collections.Generic; +using System.Text.RegularExpressions; +using TMPro; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.AssetStore +{ + public static class StringStore + { + internal static Dictionary stringsDict = []; + public static Dictionary translationStringRegex = new() + { + {"Test", "Test" } + }; + + public static Dictionary translationString = new() + { + {"Test", "Test" } + }; + + public static Dictionary> patchesStore = new() + { + { "Difficulty", new Dictionary + { + { "English" , "Difficulty:" }, + { "French" , "Difficulté:" }, + { "Italian" , "Difficoltà:" }, + { "German" , "Schwierigkeit:" }, + { "Spanish" , "Dificultad:" }, + { "Portuguese" , "Dificuldade:" }, + { "Filipino" , "Ang Hirap:" }, + { "Vietnamese" , "Độ Khó:" }, + { "Indonesian" , "Kesulitan:" }, + { "Russian" , "Сложность:" }, + { "Japanese" , "困難:" }, + { "Korean", "난이도:" }, + { "Javanese" , "Kesulitan:" }, + // { "Ukrainian" , "Складність:" }, + // { "Slovak" , "Náročnosť:" }, + } + }, + { "Zombies", new Dictionary + { + { "English" , "Zombies:" }, + { "French" , "Les Zombies:" }, + { "Italian" , "Zombi:" }, + { "German" , "Zombies:" }, + { "Spanish" , "Zombis:" }, + { "Portuguese" , "Zumbis:" }, + { "Filipino" , "Mga Zombie:" }, + { "Vietnamese" , "Thây Ma:" }, + { "Indonesian" , "Zombi:" }, + { "Russian" , "Зомби:" }, + { "Japanese" , "ゾンビ:" }, + { "Korean", "좀비:" }, + { "Javanese" , "Mayit:" }, + // { "Ukrainian" , "Зомбі:" }, + // { "Slovak" , "Zombíci:"} + } + } + + }; + + internal static void Init() + { + FileLoader.LoadStrings(); + } + + internal static void Reload() + { + translationString.Clear(); + translationStringRegex.Clear(); + FileLoader.LoadStrings(); + } + + public static TextMeshPro TranslateText(TextMeshPro originalTMP, bool isLog = false) + { + string currentLanguage = Utils.Language.ToString(); + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); + + string translatedText = TranslateText(originalTMP.text); + originalTMP.font = fontAsset; + originalTMP.text = translatedText; + + return originalTMP; + } + + public static TextMeshProUGUI TranslateText(TextMeshProUGUI originalTMP, bool isLog = false) + { + string currentLanguage = Utils.Language.ToString(); + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); + + string translatedText = TranslateText(originalTMP.text); + originalTMP.font = fontAsset; + originalTMP.text = translatedText; + + return originalTMP; + } + + public static string TranslateText(string originalText, bool isLog = false) + { + string text = DoTranslateText(originalText, false); + string checkText; + #if DEBUG + Regex regex = new("\\p{IsCJKUnifiedIdeographs}+"); + Match match = regex.Match(text); + + if(match.Success) + { + // Log.LogDebug("Untranslated String: " + match.Value); + // FileLoader.DumpUntranslatedStrings(text); + } + #endif + checkText = text; + return checkText; + } + + 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 (translationString.ContainsKey(originalText)) + { + if (isLog) + Log.LogDebug($"Text '{originalText} found in translationString"); + return translationString[originalText]; + } + + // Regex-based dynamic translation + foreach (var entry in translationStringRegex) + { + var regex = new Regex(entry.Key); + if (regex.IsMatch(originalText)) + { + // Extract dynamic parts from the original text + var match = regex.Match(originalText); + int groupCount = match.Groups.Count; + + if (isLog) + Log.LogDebug("Text found in translationStringRegex {0}: {1}", match, groupCount); + + // List to hold formatted dynamic parts + List dynamicParts = []; + + // Loop through each group and determine its translation + for (int i = 1; i < groupCount; i++) + { + string groupValue = match.Groups[i].Value; + string translatedValue = translationString.ContainsKey(groupValue) + ? translationString[groupValue] + : groupValue; + dynamicParts.Add(translatedValue); + } + + // Format the output string with dynamic parts + return string.Format(entry.Value, [.. dynamicParts]); + } + } + + if (isLog) + Log.LogDebug($"Text '{originalText}' not translated"); + return originalText; + } + + private static TextAlignmentOptions TextAnchorToTMPAlignment(TextAnchor anchor) + { + return anchor switch + { + TextAnchor.UpperLeft => TextAlignmentOptions.TopLeft, + TextAnchor.UpperCenter => TextAlignmentOptions.Top, + TextAnchor.UpperRight => TextAlignmentOptions.TopRight, + TextAnchor.MiddleLeft => TextAlignmentOptions.MidlineLeft, + TextAnchor.MiddleCenter => TextAlignmentOptions.Center, + TextAnchor.MiddleRight => TextAlignmentOptions.MidlineRight, + TextAnchor.LowerLeft => TextAlignmentOptions.BottomLeft, + TextAnchor.LowerCenter => TextAlignmentOptions.Bottom, + TextAnchor.LowerRight => TextAlignmentOptions.BottomRight, + _ => TextAlignmentOptions.Center + }; + } + + static TextMeshProUGUI ConvertToTextMeshPro(UnityEngine.UI.Text oldText, TMP_FontAsset fontAsset, bool isLog = false) + { + if (oldText == null) + { + Log.LogError("UnityEngine.UI.Text component is null."); + return null; + } + + if (fontAsset == null) + { + Log.LogError("TMP_FontAsset is null. Conversion cannot proceed."); + return null; + } + + GameObject textObject = oldText.gameObject; + + // Preserve text content and settings + string originalText = oldText.text; + originalText = TranslateText(originalText, isLog); + TextAnchor alignment = oldText.alignment; + Color color = oldText.color; + + // Remove old Text component + UnityEngine.Object.DestroyImmediate(oldText); + + // Add TextMeshProUGUI component + TextMeshProUGUI newTMP = textObject.AddComponent(); + if (newTMP == null) + { + Log.LogError($"Failed to add TextMeshProUGUI to object: {textObject.name}"); + return null; + } + + // Configure TextMeshProUGUI + newTMP.text = originalText; + newTMP.color = color; + newTMP.alignment = TextAnchorToTMPAlignment(alignment); + newTMP.font = fontAsset; + + return newTMP; + } + + public static void TranslateTextTransform(Transform baseTransform, bool isAutoTextContainer = false, bool isLog = false) + { + if (!baseTransform) return; + + string currentLanguage = Utils.Language.ToString(); + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); + + if (fontAsset == null) + { + Log.LogError($"Font for language '{currentLanguage}' not found. Translation aborted."); + return; + } + + // Local function for processing transforms + void ProcessTextTransform(Transform textTransform) + { + if (!textTransform) return; + + // Handle TextMeshPro components + TextMeshPro textTMP = textTransform.GetComponent(); + if (textTMP) + { + textTMP.text = TranslateText(textTMP.text, isLog); + textTMP.autoSizeTextContainer = isAutoTextContainer; + textTMP.font = fontAsset; + } + + TextMeshProUGUI textTMPUGUI = textTransform.GetComponent(); + if (textTMPUGUI) + { + textTMPUGUI.text = TranslateText(textTMPUGUI.text, isLog); + textTMPUGUI.enableAutoSizing = isAutoTextContainer; + textTMPUGUI.font = fontAsset; + } + + // Handle UnityEngine.UI.Text components + UnityEngine.UI.Text textUI = textTransform.GetComponent(); + if (textUI) + { + ConvertToTextMeshPro(textUI, fontAsset, isLog); + } + } + + // Process specific text paths + ProcessTextTransform(baseTransform.Find("text")); + ProcessTextTransform(baseTransform.Find("text1")); + + Transform shadowTransform = baseTransform.Find("text/shadow"); + if (shadowTransform) ProcessTextTransform(shadowTransform); + + shadowTransform = baseTransform.Find("text1/shadow"); + if (shadowTransform) ProcessTextTransform(shadowTransform); + } + + public static void TranslateTextUI(TextMeshPro textTMP, bool? isAutoTextContainer = null, bool isLog = false) + { + string currentLanguage = Utils.Language.ToString(); + if (textTMP) + { + textTMP.text = TranslateText(textTMP.text, isLog); + if (isAutoTextContainer!=null) textTMP.autoSizeTextContainer = isAutoTextContainer.Value; + textTMP.font = FontStore.LoadTMPFont(currentLanguage); + } + } + public static void TranslateTextUI(TextMeshProUGUI textTMP, bool? isAutoTextContainer = null, bool isLog = false) + { + string currentLanguage = Utils.Language.ToString(); + if (textTMP) + { + string origText = textTMP.text; + + textTMP.text = TranslateText(origText, isLog) == "" ? origText : TranslateText(origText, isLog); + if (isAutoTextContainer != null) textTMP.autoSizeTextContainer = isAutoTextContainer.Value; + if (origText != textTMP.text) + textTMP.font = FontStore.LoadTMPFont(currentLanguage); + } + } + + public static void TranslateTextUI(TMP_InputField TextInput) + { + string currentLanguage = Utils.Language.ToString(); + if (TextInput) + { + string oriText = TextInput.m_Text; + TextInput.m_Text = TranslateText(oriText); + TextInput.m_OriginalText = TranslateText(oriText); + TextInput.fontAsset = FontStore.LoadTMPFont(currentLanguage); + } + } + + public static void LogAll() + { + Log.LogInfo("Logging all StringStore entries."); + Log.LogInfo("Regex Entries: {0}", translationStringRegex.Count); + Log.LogInfo("String Entries: {0}", translationString.Count); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/AssetStore/TextureStore.cs b/PvZ-Fusion-Blooms-master/BepInEx/AssetStore/TextureStore.cs new file mode 100644 index 0000000..c4b1fa0 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/AssetStore/TextureStore.cs @@ -0,0 +1,63 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.AssetStore +{ + public static class TextureStore + { + internal static Dictionary textureDict = []; + + internal static void Init() => FileLoader.LoadTextures(); + + internal static void Reload() + { + textureDict.Clear(); + RestoreTextures(); + FileLoader.LoadDefaultTextures(); + FileLoader.LoadTextures(); + } + + public static IEnumerator ReplaceTexturesCoroutine() + { + while (true) + { + ReplaceTextures(); + yield return new WaitForSeconds(0.5f); // Adjust this interval as needed + } + } + + public static void ReplaceTextures() + { + Texture2D[] textures = Resources.FindObjectsOfTypeAll(); + foreach (Texture2D texture in textures) + { + if (texture.name.StartsWith("replaced_")) + continue; + + Utils.TryReplaceTexture2D(texture); + } + } + + public static void RestoreTextures() + { + Texture2D[] textures = Resources.FindObjectsOfTypeAll(); + foreach (Texture2D texture in textures) + { + if (texture != null) + { + texture.name = texture.name.Replace("replaced_", ""); + } + } + } + + public static void LogAll() + { + Log.LogInfo("Logging all TextureStore entries."); + foreach (KeyValuePair entry in textureDict) + { + Log.LogInfo("TextureDict Entry: " + entry.Key + " | " + entry.Value); + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/AssetStore/WarningStore.cs b/PvZ-Fusion-Blooms-master/BepInEx/AssetStore/WarningStore.cs new file mode 100644 index 0000000..3e1cdaa --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/AssetStore/WarningStore.cs @@ -0,0 +1,154 @@ +using System.Collections.Generic; +using TMPro; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.AssetStore +{ + public static class WarningStore + { + private static Dictionary warningMessages = new() + { + { "English", ("The only valid source of this translation is from this community:\n" + + "discord.gg/DPAC5ZVJ8T. If you got this anywhere else like \n" + + "Plants Hybrid and superhybrid.online, they stole it.\n" + + "Stray away from other sources as they may contain viruses.\n" + + "Please visit our community for future updates.", + "Okay! Got it.") }, + { "French", ("La seule source valide pour cette traduction provient de cette\n" + + "communauté :discord.gg/DPAC5ZVJ8T. Si vous l'avez obtenue \n" + + "ailleurs, comme Plants Hybrid ou superhybrid.online, ils l'ont volée.\n" + + "Évitez les autres sources, car elles peuvent contenir des virus.\n" + + "Veuillez visiter notre communauté pour les mises à jour futures.", + "D'accord !") }, + { "Italian", ("L'unica fonte valida di questa traduzione è questa community:\n" + + "discord.gg/DPAC5ZVJ8T. Se l'hai ottenuta altrove, come \n" + + "Plants Hybrid e superhybrid.online, l'hanno rubata.\n" + + "Evita altre fonti, potrebbero contenere virus.\n" + + "Visita la nostra community per aggiornamenti futuri.", + "Va bene! Ho capito.") }, + { "German", ("Die einzige gültige Quelle für diese Übersetzung stammt aus\n" + + "dieser Community: discord.gg/DPAC5ZVJ8T. Wenn Sie diese \n" + + "irgendwo anders gefunden haben, z. B. bei Plants Hybrid oder \n" + + "superhybrid.online, dann haben sie sie gestohlen.\n" + + "Meiden Sie andere Quellen, da diese Viren enthalten könnten.\n" + + "Bitte besuchen Sie unsere Community für zukünftige Updates.", + "Okay, verstanden!") }, + { "Spanish", ("La única fuente válida de esta traducción proviene de esta\n" + + "comunidad: discord.gg/DPAC5ZVJ8T. Si la obtuvo en cualquier\n" + + "otro lugar como Plants Hybrid o superhybrid.online, la robaron.\n" + + "Manténgase alejado de otras fuentes, ya que podrían contener virus.\n" + + "Por favor, visite nuestra comunidad para futuras actualizaciones.", + "¡Entendido!") }, + { "Portuguese", ("O lugar original e seguro dessa tradução vem daqui:\n" + + "discord.gg/DPAC5ZVJ8T. Se você baixou ela de qualquer \n" + + "lugar como Plants Hybrid ou superhybrid.online, eles\n" + + "roubaram. Evite baixar deles, pode conter vírus.\n" + + "Por favor, visite nossa comunidade para atualizações futuras.", + "Okay, entendido.") }, + { "Filipino", ("Ang tanging opisyal na source ng pagsasaling ito ay mula\n" + + "lamang dito: discord.gg/DPAC5ZVJ8T. Kung nakuha nmo ito kahit \n" + + "saan pa tulad ng Plants Hybrid at superhybrid.online, ito ay ninakaw. \n" + + "Lumayo sa ibang source dahil posibleng may kasamang virus.\n" + + "Paki-bisita ang aming komunidad para sa mga darating na update." , + "Naiintindihan!") }, + { "Vietnamese", ("Nguồn duy nhất hợp lệ của bản dịch này là từ cộng\n" + + "đồng này: discord.gg/DPAC5ZVJ8T. Nếu bạn nhận \n" + + "được nó ở bất cứ nơi nào khác như Plants Hybrid \n" + + "hoặc superhybrid.online, họ đã ăn cắp nó.\n" + + "Tránh xa các nguồn khác vì chúng có thể chứa \n" + + "virus. Hãy ghé thăm cộng đồng của chúng tôi để \n" + + "cập nhật trong tương lai.", + "Đồng ý!") }, + { "Indonesian", ("Satu-satunya sumber resmi dari terjemahan ini adalah \n" + + "komunitas kami: discord.gg/DPAC5ZVJ8T. Jika Anda \n" + + "mendapatkannya dari sumber lain seperti Plants Hybrid \n" + + "dan superhybrid.online, mereka mencurinya. \n" + + "Jauhi sumber lain karena mungkin ada virus.\n" + + "Silakan kunjungi komunitas kami untuk pembaruan berikutnya.", + "Oke! Mengerti.") }, + { "Russian", ("Единственный проверенный источник этого перевода —\n" + + "сообщество discord.gg/DPAC5ZVJ8T.\n" + + "Или же его замена https://t.me/nekoshkindom\n" + + "Если вы скачали этот мод где-либо ещё, возможно он содержит вирусы.\n" + + "Программист перевода: LancerX0.\n" + + "Переводчик: Nekosha.", "Хорошо!") }, + { "Japanese", ("この翻訳の唯一の有効なソースは、このコミュニティからです:\n" + + "discord.gg/DPAC5ZVJ8T.Plants Hybridやsuperhybrid.online、\n" + + "YoutubeのBlue Flyが作っているもの、他のどこかでこれを入手した場合、\n" + + "彼らはそれを盗んだことになります。ウイルスが含まれている可能性があるので、\n" + + "他のソースからは離れてください。今後のアップデートについては、\n私たちのコミュニティをご覧ください。", + "了解しました!") }, + { "Korean", ("이 번역은 Bloom(discord.gg/DPAC5ZVJ8T)에서만\n" + + "제공됩니다. Bloom 디스코드 이외의 다른서드 파티 사이트, \n" + + "예를 들어 Plants Hybrid 및 superhybrid.online, 또는\n" + + "유튜브 Blue Fly등에서 제공하는 파일은 무단으로 재배포된 것이며,\n" + + "이런 사이트들에는 바이러스가 포함되어 있을 가능성이 높습니다. \n향후 업데이트를 위해 저희 디스코드를 방문해 주세요.", + "확인") }, + { "Javanese" , ("Sumber mung sing sah kanggo terjemahan iki saka komunitas iki:\n" + + "discord.gg/DPAC5ZVJ8T. Yen sampeyan nemokake iki ing papan\n" + + "liya kaya Plants Hybrid lan superhybrid.online, iku dicolong.\n" + + "Aja nyedhaki sumber liya amarga bisa ngandhut virus. Mangga\n" + + "ngunjungi komunitas kita kanggo nganyari ing mangsa ngarep.", + "Oke! Ngertos.") }, + }; + + public static (string, string) GetWarningMessage(Utils.LanguageEnum language) + { + if (warningMessages.TryGetValue(language.ToString(), out var message)) + { + + return message; + } + else + { + return warningMessages["English"]; // Default to English if language code is not found + } + } + + public static void WarningLoad() + { + GameAPP.theGameStatus = -2; + GameObject gameObject = UnityEngine.Object.Instantiate(Resources.Load("UI/MainMenu/HelpMenu"), GameAPP.canvas.transform); + gameObject.name = "WarningMessage"; + TextMeshProUGUI warning = gameObject.transform.GetChild(0).GetChild(0).GetComponent(); + TextMeshProUGUI warningShadow = gameObject.transform.GetChild(0).GetChild(1).GetComponent(); + Transform button = gameObject.transform.GetChild(1); + warning.transform.position = new Vector3(0.7f, 0.4f, 0f); + warningShadow.transform.position = new Vector3(0.7f, 0.4f, 0f); + + var (warningMessage, okayButton) = WarningStore.GetWarningMessage(Utils.Language); + + warning.text = warningMessage; + warningShadow.text = warningMessage; + warning.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + warningShadow.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + + button.GetComponent().buttonNumber = 10; + button.GetChild(0).GetComponent().text = okayButton; + button.GetChild(0).GetComponent().font = FontStore.LoadTMPFont(Utils.Language.ToString()); + button.GetChild(1).GetComponent().text = okayButton; + gameObject.SetActive(false); + gameObject.SetActive(true); + } + + public static bool isWarningMessageLoaded = false; + + public static void WarningReload(Utils.LanguageEnum language) + { + // Log.LogInfo("Current Language is " + Utils.OldLanguage); + // Log.LogInfo("Changed Language to " + language); + + if (Utils.OldLanguage.ToString() == language.ToString() && Utils.OldLanguage.ToString() != "English") + { + return; + } + if (!isWarningMessageLoaded) + { + WarningLoad(); + isWarningMessageLoaded = true; + } + + return; + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Core.cs b/PvZ-Fusion-Blooms-master/BepInEx/Core.cs new file mode 100644 index 0000000..30dedf4 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Core.cs @@ -0,0 +1,125 @@ +using BepInEx; +using BepInEx.Configuration; +using BepInEx.Unity.IL2CPP; +using BepInEx.Unity.IL2CPP.Utils; +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using System; +using System.IO; +using System.Reflection; +using UnityEngine; + +[BepInPlugin(MyPluginInfo.PLUGIN_GUID, MyPluginInfo.PLUGIN_NAME, MyPluginInfo.PLUGIN_VERSION)] +[BepInProcess("PlantsVsZombiesRH.exe")] +public class Core : BasePlugin +{ + public string modsDirectory => Path.Combine(Paths.PluginPath, "PvZ_Fusion_Translator"); + + private static DateTime dtStart; + private static DateTime? dtStartToast; + private static string toast_txt; + public static Core Instance { get; private set; } + public static MonoBehaviour MonoInstance { get; private set; } + + private Coroutine replaceTextureRoutine = null; + + public ConfigEntry configDefaultTextures; + public ConfigEntry configDefaultAudio; + public ConfigEntry configLanguage; + + public override void Load() + { + Instance = this; + MonoInstance = AddComponent(); + Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly()); + LoadConfig(); + + FileLoader.LoadLanguage(); + + // AudioStore.Init(); + TextureStore.Init(); + StringStore.Init(); + FontStore.Init(); + + InitCoroutine(); + } + + public override bool Unload() + { + if (replaceTextureRoutine != null) + { + MonoInstance.StopCoroutine(replaceTextureRoutine); + Log.LogDebug("Coroutine Stopped"); + } + FileLoader.SaveLanguage(); + + #if OBFUSCATE && !RELEASE + CheckSumStore.ConvertMD5Json(); + #endif + + return true; + } + public void InitCoroutine() + { + if (replaceTextureRoutine != null) return; + replaceTextureRoutine = MonoInstance.StartCoroutine(TextureStore.ReplaceTexturesCoroutine()); + Log.LogDebug("Coroutine Started"); + } + public static void ShowToast(string message) + { + toast_txt = message; + dtStartToast = DateTime.Now; + } + + public void Update() + { + #if DEBUG + ModFeatures.OnLateUpdate(); + #endif + + if (Input.GetKeyDown(KeyCode.Insert)) + { + Utils.OpenSaveDirectory(); + } + + if (Input.GetKeyDown(KeyCode.Delete)) + { + Utils.OpenTrello(); + } + } + + public void OnGUI() + { + #if DEBUG + if (dtStartToast != null) + { + GUI.Button(new Rect(10f, 10f, 200f, 20f), "\n" + toast_txt + "\n"); + TimeSpan? timeSpan = DateTime.Now - dtStartToast; + TimeSpan t = new TimeSpan(0, 0, 2); + if (timeSpan > t) + { + dtStartToast = null; + } + } + #endif + } + + private void LoadConfig() + { + string mainCategory = "PvZ_Fusion_Translator"; + configDefaultTextures = Config.Bind(new ConfigDefinition(mainCategory, "DefaultTextures"), false, new ConfigDescription("Use Default Textures + Translation Textures", new AcceptableValueList(true, false))); + configDefaultAudio = Config.Bind(new ConfigDefinition(mainCategory, "DefaultAudio"), false, new ConfigDescription("Use Default Audio", new AcceptableValueList(true, false))); + configLanguage = Config.Bind(new ConfigDefinition(mainCategory, "Language"), "English", new ConfigDescription("Load the Game in this Language", new AcceptableValueList("English", "French", "Italian", "German", "Spanish", "Portuguese", "Indonesian", "Vietnamese", "Javanese", "Russian", "Japanese", "Korean"))); + } +} + +public class UnityCoroutineHelper : MonoBehaviour +{ + public static UnityCoroutineHelper Instance { get; private set; } + + public void Awake() + { + Instance = this; + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/BepInEx/FileLoader.cs b/PvZ-Fusion-Blooms-master/BepInEx/FileLoader.cs new file mode 100644 index 0000000..b3640cf --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/FileLoader.cs @@ -0,0 +1,344 @@ +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using PvZ_Fusion_Translator__BepInEx_.Patches.OtherManagers; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text.Encodings.Web; +using System.Text.Json; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_ +{ + internal static class FileLoader + { + internal enum AssetType + { + Textures, + Strings, + Dumps, + Almanac, + } + + public static string GetAssetDir(AssetType assetType, Utils.LanguageEnum? language = null) + { + string languagePath = language.HasValue ? ("Localization" + Path.DirectorySeparatorChar + language.ToString()) : string.Empty; + return Path.Combine(Core.Instance.modsDirectory, languagePath, assetType.ToString()); + } + + internal static void LoadStrings() => LoadStrings(Utils.Language); + internal static void LoadStrings(Utils.LanguageEnum language) + { + string stringDir = GetAssetDir(AssetType.Strings, Utils.Language); + if (!Directory.Exists(stringDir)) + { + Directory.CreateDirectory(stringDir); + } + try + { + foreach (string filepath in Directory.EnumerateFiles(stringDir, "*.json", SearchOption.AllDirectories)) + { + + #if OBFUSCATE + if (CheckSumStore.IsModified(filepath)) + { + Log.LogError("File {0} was modified!" , filepath); + continue; + } + #endif + + string fileName = Path.GetFileNameWithoutExtension(filepath); + StringStore.stringsDict[fileName] = filepath; + #if DEBUG + Log.LogInfo("Loading File : " + filepath); + #endif + string jsonString = File.ReadAllText(filepath); + if (fileName.EndsWith("_strings")) + { + Dictionary dictionary = JsonSerializer.Deserialize>(jsonString); + foreach (var (key, value) in dictionary) + { + StringStore.translationString[key] = value; + } + } + else if (fileName.EndsWith("_regexs")) + { + Dictionary dictionary = JsonSerializer.Deserialize>(jsonString); + foreach (var (key, value) in dictionary) + { + StringStore.translationStringRegex[key] = value; + } + } + } + SaveStrings(); + #if DEBUG + DumpJson(); + #endif + } + catch (Exception e) + { + Log.LogError("Error loading string."); + Log.LogError(e.GetType() + " " + e.Message); + } + Log.LogInfo("Strings loaded successfully."); + } + + public static bool loadDefaultTextures = Core.Instance.configDefaultTextures.Value; + internal static void LoadTextures() + { + // Default or Custom Texturse -> English Textures -> Localized Textures + try + { + if (loadDefaultTextures == true) + { + LoadDefaultTextures(); + } + else + { + LoadCustomTextures(); + } + } + catch (Exception e) + { + Log.LogError("Error loading texture setting."); + Log.LogError($"{e.GetType()} {e.Message}"); + } + + if (Utils.Language != Utils.LanguageEnum.English) + { + LoadLocalizedTextures(Utils.LanguageEnum.English); + } + LoadLocalizedTextures(Utils.Language); + + Log.LogInfo("Textures loaded successfully."); + } + + internal static void LoadLocalizedTextures(Utils.LanguageEnum? language = null) + { + string textureDir = GetAssetDir(AssetType.Textures, language); + + if (!Directory.Exists(textureDir)) + { + Directory.CreateDirectory(textureDir); + } + try + { + foreach (string filepath in Directory.EnumerateFiles(textureDir, "*.png", SearchOption.AllDirectories)) + { + if (filepath.Contains("[Custom Textures]", StringComparison.OrdinalIgnoreCase) && loadDefaultTextures) + { + continue; + } + + #if OBFUSCATE + if (CheckSumStore.IsModified(filepath)) + { + Log.LogError("File {0} was modified!" , filepath); + continue; + } + #endif + + #if DEBUG + Log.LogDebug("Loading File : " + filepath); + #endif + + Texture2D texture2D = Utils.LoadImage(filepath); + TextureStore.textureDict[Path.GetFileNameWithoutExtension(filepath)] = filepath; + } + } + + catch (Exception e) + { + Log.LogError("Error loading Texture."); + Log.LogError(e.GetType() + " " + e.Message); + } + } + + internal static void LoadDefaultTextures() + { + string textureDefaultDir = Path.Combine(Core.Instance.modsDirectory, AssetType.Dumps.ToString(), "Default Textures [Do Not Remove]"); + if (!Directory.Exists(textureDefaultDir)) + { + Directory.CreateDirectory(textureDefaultDir); + } + try + { + foreach (string filepath in Directory.EnumerateFiles(textureDefaultDir, "*.png", SearchOption.AllDirectories)) + { + #if OBFUSCATE + if (CheckSumStore.IsModified(filepath)) + { + Log.LogError("File {0} was modified!" , filepath); + continue; + } + #endif + + Texture2D texture2D = Utils.LoadImage(filepath); + TextureStore.textureDict[Path.GetFileNameWithoutExtension(filepath)] = filepath; + } + } + + catch (Exception e) + { + Log.LogError("Error loading Texture."); + Log.LogError(e.GetType() + " " + e.Message); + } + } + + internal static void LoadCustomTextures() + { + string texturePackDir = Path.Combine(Core.Instance.modsDirectory, "[Custom Textures]"); + + if (!Directory.Exists(texturePackDir)) + { + Directory.CreateDirectory(texturePackDir); + } + try + { + foreach (string filepath in Directory.EnumerateFiles(texturePackDir, "*.png", SearchOption.AllDirectories)) + { + #if OBFUSCATE + if (CheckSumStore.IsModified(filepath)) + { + Log.LogError("File {0} was modified!" , filepath); + continue; + } + #endif + + Texture2D texture2D = Utils.LoadImage(filepath); + TextureStore.textureDict[Path.GetFileNameWithoutExtension(filepath)] = filepath; + } + } + + catch (Exception e) + { + Log.LogError("Error loading Texture."); + Log.LogError(e.GetType() + " " + e.Message); + } + } + + internal static void SaveStrings() + { + string stringDir = GetAssetDir(AssetType.Strings, Utils.Language); + if (!Directory.Exists(stringDir)) + { + Directory.CreateDirectory(stringDir); + } + + string translationStringRegex = JsonSerializer.Serialize(StringStore.translationStringRegex, new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping + }); + + File.WriteAllText(Path.Combine(stringDir, "translation_regexs.json"), translationStringRegex); + + string translationString = JsonSerializer.Serialize(StringStore.translationString, new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping + }); + + File.WriteAllText(Path.Combine(stringDir, "translation_strings.json"), translationString); + } + + #if DEBUG + public static void DumpJson() + { + string dumpDir = GetAssetDir(AssetType.Dumps); + + if (!Directory.Exists(dumpDir)) + { + Directory.CreateDirectory(dumpDir); + } + string LawnStrings = Resources.Load("LawnStrings").text; + string ZombieStrings = Resources.Load("ZombieStrings").text; + File.WriteAllText(Path.Combine(dumpDir, "LawnStrings.json"), LawnStrings); + File.WriteAllText(Path.Combine(dumpDir, "ZombieStrings.json"), ZombieStrings); + + Dictionary achievementsList = new Dictionary(); + foreach (Il2CppSystem.Collections.Generic.KeyValuePair> entry in AchievementClip.achievementsText) + { + achievementsList.Add(entry.Key, new AchievementObject(entry.Key, entry.Value.Item1, entry.Value.Item2)); + } + File.WriteAllText(Path.Combine(dumpDir, "AchievementsText.json"), JsonSerializer.Serialize(achievementsList, new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping + })); + } + #endif + + #if DEBUG && MELON + public static void DumpUntranslatedStrings(string text) + { + string dumpDir = GetAssetDir(AssetType.Dumps); + string jsonFile = Path.Combine(dumpDir, "UntranslatedStrings.json"); + + if (!Directory.Exists(dumpDir)) + { + Directory.CreateDirectory(dumpDir); + } + + if (!File.Exists(jsonFile)) + { + File.WriteAllText(jsonFile, "{}"); // Initialize empty JSON object + } + + string json = File.ReadAllText(jsonFile); + JObject untranslatedStrings = JObject.Parse(json); + + if (!untranslatedStrings.ContainsKey(text)) + { + untranslatedStrings[text] = text; + File.WriteAllText(jsonFile, untranslatedStrings.ToString()); + } + } + #endif + + internal static void LoadLanguage() + { + try + { + // Load the language preference as a string and parse it into the enum + string languageName = Core.Instance.configLanguage.Value; + if (Enum.TryParse(languageName, out Utils.LanguageEnum loadedLanguage)) + { + Utils.Language = loadedLanguage; + } + else + { + Log.LogWarning($"Invalid language '{languageName}' found in preferences. Falling back to English."); + Utils.Language = Utils.LanguageEnum.English; // Default fallback + } + Log.LogWarning($"Loaded language {languageName}"); + } + catch (Exception e) + { + Log.LogError("Error loading language setting."); + Log.LogError($"{e.GetType()} {e.Message}"); + } + Log.LogInfo($"Language has been loaded: {Utils.Language}"); + } + + internal static void SaveLanguage() + { + try + { + // Save the current language as a string + if (Core.Instance.Config.TryGetEntry("PvZ_Fusion_Translator", "Language", out var languageEntry)) + { + languageEntry.Value = Utils.Language.ToString(); + } + + // Ensure changes are written to the config file + // MelonPreferences.Save(); + } + catch (Exception e) + { + Log.LogError("Error saving language setting."); + Log.LogError($"{e.GetType()} {e.Message}"); + } + // Log.LogInfo($"Language has been saved: {Utils.Language}"); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/FontHandler.cs b/PvZ-Fusion-Blooms-master/BepInEx/FontHandler.cs new file mode 100644 index 0000000..af30ac7 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/FontHandler.cs @@ -0,0 +1,45 @@ +using BepInEx; +using PvZ_Fusion_Translator__BepInEx_; +using System.IO; +using TMPro; +using UnityEngine; + +namespace PvZ_Fusion_Translator +{ + public static class FontHandler + { + public static Font LoadFont(this string pathFromModsFolder, bool throwException) + { + string fontFilePath = Path.Combine(Paths.PluginPath, pathFromModsFolder); + if (!File.Exists(fontFilePath)) + { + if (throwException) + Log.LogWarning($"Font not found at path: '{fontFilePath}'."); + return null; + } + + Font font = new Font(); + Font.Internal_CreateFontFromPath(font, fontFilePath); // Default size, adjust as needed + return font; + } + + public static TMP_FontAsset ConvertToTMP(this Font font) + { + TMP_FontAsset fontAsset = TMP_FontAsset.CreateFontAsset(font); + if (fontAsset == null) + { + Log.LogWarning($"Failed to create TMP_FontAsset from font '{font.name}'."); + return null; + } + return fontAsset; + } + + public static TMP_FontAsset LoadTMPFont(this string pathFromModsFolder, bool throwException) + { + Font font = pathFromModsFolder.LoadFont(throwException); + if (font == null) + return null; + return font.ConvertToTMP(); + } + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Log.cs b/PvZ-Fusion-Blooms-master/BepInEx/Log.cs new file mode 100644 index 0000000..b9407bf --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Log.cs @@ -0,0 +1,25 @@ +using BepInEx.Logging; + +namespace PvZ_Fusion_Translator__BepInEx_ +{ + internal static class Log + { + private static readonly ManualLogSource Logger = BepInEx.Logging.Logger.CreateLogSource("PvZ_Fusion_Translator"); + + public static void LogDebug(object txt) => Logger.LogDebug(txt); + public static void LogDebug(string txt) => Logger.LogDebug(txt); + public static void LogDebug(string txt, params object[] args) => Logger.LogDebug(string.Format(txt, args)); + + public static void LogInfo(object txt) => Logger.LogInfo(txt); + public static void LogInfo(string txt) => Logger.LogInfo(txt); + public static void LogInfo(string txt, params object[] args) => Logger.LogInfo(string.Format(txt, args)); + + public static void LogWarning(object txt) => Logger.LogWarning(txt); + public static void LogWarning(string txt) => Logger.LogWarning(txt); + public static void LogWarning(string txt, params object[] args) => Logger.LogWarning(string.Format(txt, args)); + + public static void LogError(object txt) => Logger.LogError(txt); + public static void LogError(string txt) => Logger.LogError(txt); + public static void LogError(string txt, params object[] args) => Logger.LogError(string.Format(txt, args)); + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/BepInEx/ModFeatures.cs b/PvZ-Fusion-Blooms-master/BepInEx/ModFeatures.cs new file mode 100644 index 0000000..12d47fc --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/ModFeatures.cs @@ -0,0 +1,79 @@ +#if DEBUG +using System; +using System.Collections.Generic; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_ +{ + public static class ModFeatures + { + public enum ModType + { + ReloadStrings, + ReloadTextures, + } + + private class ModFeature + { + public string Name { get; private set; } + public ModType ModType { get; private set; } + public KeyCode KeyCode { get; private set; } + public bool IsActive { get; set; } + + public ModFeature(string name, ModType modType, KeyCode keyCode, bool defaultValue = false) + { + Name = name; + ModType = modType; + KeyCode = keyCode; + IsActive = defaultValue; + } + + public void ToggleFeature() + { + if (ModType == ModType.ReloadStrings) + { + StringStore.Reload(); + Core.ShowToast("Strings Reloaded!"); + return; + } + + if (ModType == ModType.ReloadTextures) + { + TextureStore.Reload(); + Core.ShowToast("Textures Reloaded!"); + return; + } + } + } + + private static readonly Dictionary featureLists = new() + { + { ModType.ReloadStrings, new ModFeature("Reload Strings", ModType.ReloadStrings, KeyCode.Home, true) }, + { ModType.ReloadTextures, new ModFeature("Reload Textures", ModType.ReloadTextures, KeyCode.End, true) }, + }; + + public static void ToggleFeature(ModType modType) + { + if (!featureLists.ContainsKey(modType)) + return; + + featureLists[modType].ToggleFeature(); + } + + public static void OnLateUpdate() + { + foreach (var feature in featureLists.Values) + { + if (feature.KeyCode != KeyCode.None && Enum.IsDefined(typeof(KeyCode), feature.KeyCode)) + { + if (Input.GetKeyDown(feature.KeyCode)) + { + feature.ToggleFeature(); + } + } + } + } + } +} +#endif \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/BaseTextObjects/InGameText_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/BaseTextObjects/InGameText_Patch.cs new file mode 100644 index 0000000..16d22cf --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/BaseTextObjects/InGameText_Patch.cs @@ -0,0 +1,25 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using System; +using TMPro; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.BaseTextObjects +{ + [HarmonyPatch(typeof(InGameText))] + public static class InGameText_Patch + { + [HarmonyPatch(nameof(InGameText.EnableText), new Type[] { typeof(string), typeof(float), typeof(bool) })] + [HarmonyPrefix] + private static void EnableText(InGameText __instance, ref string text) => text = StringStore.TranslateText(text, true); + + [HarmonyPatch(nameof(InGameText.EnableText), new Type[] { typeof(string), typeof(float), typeof(bool) })] + [HarmonyPostfix] + private static void EnableText(InGameText __instance) + { + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + __instance.t.text = StringStore.TranslateText(__instance.t.text, true); + __instance.t.font = fontAsset; + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/BaseTextObjects/TMP_InputField_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/BaseTextObjects/TMP_InputField_Patch.cs new file mode 100644 index 0000000..ff6f318 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/BaseTextObjects/TMP_InputField_Patch.cs @@ -0,0 +1,23 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using TMPro; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.BaseTextObjects +{ + [HarmonyPatch(typeof(TMP_InputField))] + public static class TMP_InputField_Patch + { + [HarmonyPatch(nameof(TMP_InputField.OnEnable))] + [HarmonyPostfix] + private static void OnEnable(TMP_InputField __instance) + { + if (!string.IsNullOrEmpty(__instance.text)) + { + string text = StringStore.TranslateText(__instance.text); + __instance.m_Text = StringStore.TranslateText(text); + __instance.m_OriginalText = StringStore.TranslateText(text); + __instance.m_TextComponent.text = StringStore.TranslateText(text); + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/BaseTextObjects/TextMeshProUGUI_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/BaseTextObjects/TextMeshProUGUI_Patch.cs new file mode 100644 index 0000000..c7f9d29 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/BaseTextObjects/TextMeshProUGUI_Patch.cs @@ -0,0 +1,77 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using TMPro; +using UnityEngine.UI; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.BaseTextObjects +{ + [HarmonyPatch(typeof(TextMeshProUGUI))] + public static class TextMeshProUGUI_Patch + { + [HarmonyPatch(nameof(TextMeshProUGUI.OnEnable))] + [HarmonyPostfix] + private static void OnEnable(TextMeshProUGUI __instance) + { + if (!string.IsNullOrEmpty(__instance.text)) + { + __instance = StringStore.TranslateText(__instance); + __instance.autoSizeTextContainer = false; + + if (__instance.name.StartsWith("LevelName")) + { + __instance.text = __instance.text.Replace("\n", " "); + } + if ((__instance.transform.parent != null) && (__instance.transform.parent.name.StartsWith("Window"))) + { + __instance.fontSizeMin = 10; + __instance.fontSize = 12; + } + + // __instance.ForceMeshUpdate(); + } + } + + [HarmonyPatch(nameof(TextMeshProUGUI.Awake))] + [HarmonyPostfix] + private static void Awake(TextMeshProUGUI __instance) + { + if (!string.IsNullOrEmpty(__instance.text)) + { + __instance = StringStore.TranslateText(__instance); + __instance.autoSizeTextContainer = false; + + if (__instance.name.StartsWith("LevelName")) + { + __instance.text = __instance.text.Replace("\n", " "); + } + if ((__instance.transform.parent != null) && (__instance.transform.parent.name.StartsWith("Window"))) + { + __instance.fontSizeMin = 10; + __instance.fontSize = 12; + } + + if (__instance.text == "Полный Хаос" && __instance.transform.parent.parent.Find("Image").GetComponent().activeSprite.name == "Present") + { + __instance.text += "\nБесконечно"; + } + + // __instance.ForceMeshUpdate(); + } + } + } + [HarmonyPatch(typeof(TMP_SubMeshUI))] + public static class TMP_SubMeshUI_Patch + { + [HarmonyPatch(nameof(TMP_SubMeshUI.OnEnable))] + [HarmonyPostfix] + public static void OnEnable(TMP_SubMeshUI __instance) + { + if (!string.IsNullOrEmpty(__instance.textComponent.text)) + { + string text = StringStore.TranslateText(__instance.textComponent.text); + __instance.m_TextComponent.text = StringStore.TranslateText(text); + __instance.textComponent.text = StringStore.TranslateText(text); + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/BaseTextObjects/TextMeshPro_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/BaseTextObjects/TextMeshPro_Patch.cs new file mode 100644 index 0000000..2620cf5 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/BaseTextObjects/TextMeshPro_Patch.cs @@ -0,0 +1,27 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using TMPro; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.BaseTextObjects +{ + [HarmonyPatch(typeof(TextMeshPro))] + public static class TextMeshPro_Patch + { + [HarmonyPatch(nameof(TextMeshPro.OnEnable))] + [HarmonyPostfix] + private static void OnEnable(TextMeshPro __instance) + { + if (!string.IsNullOrEmpty(__instance.text)) + { + if (__instance.transform.parent.name.StartsWith("AlmanacHelp")) + { + __instance = StringStore.TranslateText(__instance); + __instance.autoSizeTextContainer = false; + return; + } + __instance = StringStore.TranslateText(__instance); + __instance.autoSizeTextContainer = true; + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/Advanture_Btn_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/Advanture_Btn_Patch.cs new file mode 100644 index 0000000..e0273cf --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/Advanture_Btn_Patch.cs @@ -0,0 +1,102 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using TMPro; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.ButtonObjects +{ + [HarmonyPatch(typeof(Advanture_Btn))] + public static class Advanture_Btn_Patch + { + [HarmonyPatch(nameof(Advanture_Btn.Start))] + [HarmonyPostfix] + private static void Start(Advanture_Btn __instance) + { + StringStore.TranslateTextTransform(__instance.transform, true); + Transform parentTransform = __instance.transform.parent.transform; + if (__instance.name == "Goback") + { + Transform backgroundTransform = parentTransform.Find("Background"); + backgroundTransform.Find("Name").GetComponent().autoSizeTextContainer = true; + backgroundTransform.Find("Shadow").GetComponent().autoSizeTextContainer = true; + } + + Transform levelTransform = parentTransform.Find("Levels"); + if (levelTransform != null) + { + + StringStore.TranslateTextTransform(levelTransform.Find("Nextpage")); + StringStore.TranslateTextTransform(levelTransform.Find("LastPage")); + + Transform pageMiniGamesTransform = levelTransform.transform.Find("PageMiniGames"); + if (pageMiniGamesTransform != null) + { + StringStore.TranslateTextTransform(pageMiniGamesTransform.Find("BackToIndex")); + StringStore.TranslateTextTransform(pageMiniGamesTransform.Find("Nextpage")); + StringStore.TranslateTextTransform(pageMiniGamesTransform.Find("LastPage")); + } + + Transform pageUnlockChallengeTransform = levelTransform.transform.Find("PageUnlockChallenge"); + if (pageUnlockChallengeTransform != null) + { + StringStore.TranslateTextTransform(pageUnlockChallengeTransform.Find("BackToIndex")); + } + + Transform pageFlagChallengeTransform = levelTransform.transform.Find("PageFlagChallenge"); + if (pageFlagChallengeTransform != null) + { + StringStore.TranslateTextTransform(pageFlagChallengeTransform.Find("BackToIndex")); + } + + Transform pageTravelExperienceTransform = levelTransform.transform.Find("PageTravelExperience"); + if (pageTravelExperienceTransform != null) + { + StringStore.TranslateTextTransform(pageTravelExperienceTransform.Find("BackToIndex")); + } + + Transform pageGardenProtectionTransform = levelTransform.transform.Find("PageGardenProtection"); + if (pageGardenProtectionTransform != null) + { + StringStore.TranslateTextTransform(pageGardenProtectionTransform.Find("BackToIndex")); + } + + Transform pageNormalTravelTransform = levelTransform.transform.Find("PageNormalTravel"); + if (pageNormalTravelTransform != null) + { + StringStore.TranslateTextTransform(pageNormalTravelTransform.Find("BackToIndex")); + } + + Transform pageRandomLevelTransform = levelTransform.transform.Find("PageRandomLevel"); + if (pageRandomLevelTransform != null) + { + StringStore.TranslateTextTransform(pageRandomLevelTransform.Find("BackToIndex")); + } + + Transform pageUltimateExperienceTransform = levelTransform.transform.Find("PageUltimateExprience"); + if (pageUltimateExperienceTransform != null) + { + StringStore.TranslateTextTransform(pageUltimateExperienceTransform.Find("BackToIndex")); + } + + Transform pageAdvantureLevelTransform = levelTransform.transform.Find("PageAdvantureLevel"); + if (pageAdvantureLevelTransform != null) + { + StringStore.TranslateTextTransform(pageAdvantureLevelTransform.Find("BackToIndex")); + StringStore.TranslateTextTransform(pageAdvantureLevelTransform.Find("Nextpage")); + StringStore.TranslateTextTransform(pageAdvantureLevelTransform.Find("LastPage")); + } + + Transform pageScaryPotTransform = levelTransform.transform.Find("PageScaryPot"); + if (pageScaryPotTransform != null) + { + StringStore.TranslateTextTransform(pageScaryPotTransform.Find("BackToIndex")); + StringStore.TranslateTextTransform(pageScaryPotTransform.Find("Nextpage")); + StringStore.TranslateTextTransform(pageScaryPotTransform.Find("LastPage")); + } + } + + StringStore.TranslateTextTransform(parentTransform.Find("CameraSize")); + StringStore.TranslateTextTransform(parentTransform.Find("CanvasSize")); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/EveBtn_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/EveBtn_Patch.cs new file mode 100644 index 0000000..466ce64 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/EveBtn_Patch.cs @@ -0,0 +1,41 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using TMPro; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.ButtonObjects +{ + [HarmonyPatch(typeof(EveBtn))] + public static class EveBtn_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(EveBtn.OnMouseUp))] + private static void OnMouseUp(EveBtn __instance) + { + Transform sceneText = __instance.transform.FindChild("text"); + if(sceneText != null) + { + TextMeshProUGUI sceneTextTMP = sceneText.transform.GetComponent(); + if(sceneTextTMP != null) + { + sceneTextTMP.text = StringStore.TranslateText(sceneTextTMP.text); + } + } + Transform sceneTextShadow = sceneText.transform.FindChild("text2"); + if(sceneTextShadow != null) + { + TextMeshProUGUI sceneTextShadowTMP = sceneTextShadow.transform.GetComponent(); + if (sceneTextShadowTMP != null) + { + sceneTextShadowTMP.text = StringStore.TranslateText(sceneTextShadowTMP.text); + } + } + + if (__instance.name.Equals("Balanced")) + { + __instance.gameObject.SetActive(false); + __instance.gameObject.SetActive(true); + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/InGameBtn_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/InGameBtn_Patch.cs new file mode 100644 index 0000000..a8d8e65 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/InGameBtn_Patch.cs @@ -0,0 +1,34 @@ +using HarmonyLib; +using TMPro; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.ButtonObjects +{ + [HarmonyPatch(typeof(InGameBtn))] + public static class InGameBtn_Patch + { + [HarmonyPatch(nameof(InGameBtn.Update))] + [HarmonyPostfix] + private static void Update(InGameBtn __instance) + { + Transform sceneText = __instance.transform.FindChild("SceneText"); + if(sceneText != null) + { + TextMeshProUGUI sceneTextTMP = sceneText.transform.GetComponent(); + if(sceneTextTMP != null) + { + sceneTextTMP = AssetStore.StringStore.TranslateText(sceneTextTMP); + } + Transform sceneTextShadow = sceneText.transform.FindChild("SceneText"); + if(sceneTextShadow != null) + { + TextMeshProUGUI sceneTextShadowTMP = sceneTextShadow.transform.GetComponent(); + if (sceneTextShadowTMP != null) + { + sceneTextShadowTMP = AssetStore.StringStore.TranslateText(sceneTextShadowTMP); + } + } + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs new file mode 100644 index 0000000..016c90d --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs @@ -0,0 +1,213 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using TMPro; +using UnityEngine; +using Object = UnityEngine.Object; + +public class OptionButtonData +{ + public OptionBtn Button { get; set; } + public Vector3 Position { get; set; } + public Utils.LanguageEnum? Language { get; set; } // Null if it's the "Next" button + public bool IsNextButton { get; set; } +} + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.ButtonObjects +{ + internal class OptLanguageBtn_Patch + { + public static Dictionary LanguageBtnDict = new(); + private static bool buttonsCreated = false; + private static OptionBtn cachedTemplateButton; + + private const float startX = 4.3241f + 2.56f; + private const float startY = 2.7769f; + private const float ySpacing = 1.2505f; + + private static List AvailableLanguages; + private const int LanguagesPerPage = 5; + private static int currentPage = 0; + private static OptionBtn[] buttonSlots = new OptionBtn[6]; // 5 language buttons + 1 next button + + public static void CreateLanguageButtons(OptionBtn templateButton) + { + if (buttonsCreated) return; + buttonsCreated = true; + cachedTemplateButton = templateButton; + + AvailableLanguages = Enum.GetValues(typeof(Utils.LanguageEnum)) + .Cast() + .Where(lang => lang != Utils.LanguageEnum.LANG_END) + .ToList(); + + for (int i = 0; i < 6; i++) + { + var newButton = Object.Instantiate(templateButton, templateButton.transform.parent); + newButton.optionType = 80 + i; + + float yPos = startY - i * ySpacing; + Vector3 pos = new(startX, yPos); + newButton.transform.position = pos; + + buttonSlots[i] = newButton; + + LanguageBtnDict[newButton.GetInstanceID()] = new OptionButtonData + { + Button = newButton, + Position = pos + }; + } + + UpdatePage(); + } + + private static void UpdatePage() + { + int startIndex = currentPage * LanguagesPerPage; + int langCount = AvailableLanguages.Count; + + for (int i = 0; i < 5; i++) + { + var btn = buttonSlots[i]; + var data = LanguageBtnDict[btn.GetInstanceID()]; + + if (startIndex + i < langCount) + { + var lang = AvailableLanguages[startIndex + i]; + data.Language = lang; + data.IsNextButton = false; + btn.gameObject.SetActive(true); + UpdateButtonText(btn, lang.ToString()); + } + else + { + data.Language = null; + data.IsNextButton = false; + btn.gameObject.SetActive(false); + } + } + + // "Next" button always visible at index 5 + var nextBtn = buttonSlots[5]; + var nextData = LanguageBtnDict[nextBtn.GetInstanceID()]; + nextData.Language = null; + nextData.IsNextButton = true; + nextBtn.gameObject.SetActive(true); + UpdateButtonText(nextBtn, "Next"); + } + + public static void UpdateButtonText(OptionBtn button, string languageName) + { + TMP_FontAsset defaultAsset = FontStore.LoadTMPFont("English"); + + for (int i = 0; i < 3; i++) + { + Transform textTransform = button.transform.GetChild(i); + if (textTransform != null) + { + if (i == 0) textTransform.gameObject.SetActive(false); + + TextMeshProUGUI text = textTransform.GetComponent(); + if (text != null) + { + if (i == 0) + { + text.text = ""; + text.color = Color.red; + } + else + { + text.text = languageName; + } + text.fontSize = 16; + text.font = defaultAsset; + text.autoSizeTextContainer = false; + } + } + } + } + + private static void FlashMessage(OptionBtn button, string message) + { + var child = button.transform.GetChild(0); + if (child != null) + { + var text = child.GetComponent(); + if (text != null) + { + text.text = message; + } + child.gameObject.SetActive(true); + + Task.Delay(1000).ContinueWith(_ => + { + if (button != null && child != null && child.gameObject.activeSelf) + { + child.gameObject.SetActive(false); + } + }); + } + } + + [HarmonyPatch(typeof(OptionBtn))] + public static class OptLangBtn_Patch + { + [HarmonyPatch(nameof(OptionBtn.Awake))] + [HarmonyPostfix] + private static void Awake(OptionBtn __instance) + { + if (!buttonsCreated || cachedTemplateButton == null) + { + buttonsCreated = false; + CreateLanguageButtons(__instance); + } + } + + [HarmonyPatch("OnMouseUpAsButton")] + [HarmonyPrefix] + private static void OnMouseUpAsButton(OptionBtn __instance) + { + if (LanguageBtnDict.TryGetValue(__instance.GetInstanceID(), out var btnData)) + { + if (btnData.IsNextButton) + { + currentPage = (currentPage + 1) % (int)Math.Ceiling((float)AvailableLanguages.Count / LanguagesPerPage); + UpdatePage(); + return; + } + + if (btnData.Language is Utils.LanguageEnum selectedLang) + { + string currentLang = Utils.Language.ToString(); + + if (currentLang == selectedLang.ToString()) + { + FlashMessage(btnData.Button, "Already Selected!"); + } + else + { + Utils.ChangeLanguage(selectedLang.ToString()); + Debug.Log($"Language changed to: {selectedLang}"); + FlashMessage(btnData.Button, "Language Changed!"); + } + } + } + } + + [HarmonyPatch(nameof(OptionBtn.Update))] + [HarmonyPostfix] + private static void Update(OptionBtn __instance) + { + if (LanguageBtnDict.TryGetValue(__instance.GetInstanceID(), out var btnData)) + { + btnData.Button.transform.position = btnData.Position; + } + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/OptionBtn_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/OptionBtn_Patch.cs new file mode 100644 index 0000000..2aef1a5 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/OptionBtn_Patch.cs @@ -0,0 +1,68 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using TMPro; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.ButtonObjects +{ + [HarmonyPatch(typeof(OptionBtn))] + public static class OptionBtn_Patch + { + [HarmonyPatch(nameof(OptionBtn.Awake))] + [HarmonyPostfix] + private static void Awake(OptionBtn __instance) + { + Transform text_1Transform = __instance.transform.GetChild(0)?.transform; + if (text_1Transform != null) + { + TextMeshProUGUI text_1 = text_1Transform.GetComponent(); + text_1 = StringStore.TranslateText(text_1); + text_1.autoSizeTextContainer = false; + } + + Transform textTransform = __instance.transform.GetChild(1)?.transform; + if (textTransform != null) + { + TextMeshProUGUI text = textTransform.GetComponent(); + text = StringStore.TranslateText(text); + text.autoSizeTextContainer = false; + } + + Transform text2Transform = __instance.transform.GetChild(2)?.transform; + if (text2Transform != null) + { + TextMeshProUGUI text2 = text2Transform.GetComponent(); + text2 = StringStore.TranslateText(text2); + text2.autoSizeTextContainer = false; + } + } + + [HarmonyPatch("OnMouseUpAsButton")] + [HarmonyPostfix] + private static void OnMouseUpAsButtonPostfix(OptionBtn __instance) + { + Transform text_1Transform = __instance.transform.GetChild(0)?.transform; + if (text_1Transform != null) + { + TextMeshProUGUI text_1 = text_1Transform.GetComponent(); + text_1 = StringStore.TranslateText(text_1); + text_1.autoSizeTextContainer = false; + } + + Transform textTransform = __instance.transform.GetChild(1)?.transform; + if (textTransform != null) + { + TextMeshProUGUI text = textTransform.GetComponent(); + text = StringStore.TranslateText(text); + text.autoSizeTextContainer = false; + } + + Transform text2Transform = __instance.transform.GetChild(2)?.transform; + if (text2Transform != null) + { + TextMeshProUGUI text2 = text2Transform.GetComponent(); + text2 = StringStore.TranslateText(text2); + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/PVPPotBtn_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/PVPPotBtn_Patch.cs new file mode 100644 index 0000000..4ade853 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/PVPPotBtn_Patch.cs @@ -0,0 +1,41 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using TMPro; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.ButtonObjects +{ + [HarmonyPatch(typeof(PVPPotBtn))] + public class PVPPotBtn_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(PVPPotBtn.OnMouseUpAsButton))] + public static void OnMouseUpAsButton(PVPPotBtn __instance) + { + Transform sceneText = __instance.transform.FindChild("text"); + if(sceneText != null) + { + TextMeshProUGUI sceneTextTMP = sceneText.transform.GetComponent(); + if(sceneTextTMP != null) + { + sceneTextTMP.text = StringStore.TranslateText(sceneTextTMP.text); + } + } + Transform sceneTextShadow = sceneText.transform.FindChild("text_1"); + if(sceneTextShadow != null) + { + TextMeshProUGUI sceneTextShadowTMP = sceneTextShadow.transform.GetComponent(); + if (sceneTextShadowTMP != null) + { + sceneTextShadowTMP.text = StringStore.TranslateText(sceneTextShadowTMP.text); + } + } + + if (__instance.name.Equals("ChangeBg_3") || __instance.name.Equals("ChangeBg_4")) + { + __instance.gameObject.SetActive(false); + __instance.gameObject.SetActive(true); + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/PauseMenu_Btn_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/PauseMenu_Btn_Patch.cs new file mode 100644 index 0000000..be33173 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/ButtonObjects/PauseMenu_Btn_Patch.cs @@ -0,0 +1,13 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.ButtonObjects +{ + [HarmonyPatch(typeof(PauseMenu_Btn))] + public static class PauseMenu_Btn_Patch + { + [HarmonyPatch(nameof(PauseMenu_Btn.Start))] + [HarmonyPostfix] + private static void Start(PauseMenu_Btn __instance) => StringStore.TranslateTextTransform(__instance.transform); + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/Close_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/Close_Patch.cs new file mode 100644 index 0000000..13c7e54 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/Close_Patch.cs @@ -0,0 +1,48 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using TMPro; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(Close))] + public static class Close_Patch + { + [HarmonyPatch(nameof(Close.Start))] + [HarmonyPostfix] + private static void Close_Start(Close __instance) + { + TextMeshPro closeText = __instance.transform.GetChild(0).GetComponent(); + closeText.text = "合上"; + closeText = StringStore.TranslateText(closeText); + closeText.autoSizeTextContainer = true; + + Transform AlmanacTransform = __instance.transform.parent.transform; + + Transform nameTransform = AlmanacTransform.Find("Name"); + if (nameTransform != null) + { + TextMeshPro nameTMP = nameTransform.transform.GetComponent(); + if (nameTMP) + { + nameTMP = StringStore.TranslateText(nameTMP); + nameTMP.autoSizeTextContainer = true; + } + + Transform nameShadowTransform = nameTransform.Find("NameShadow"); + if (nameShadowTransform) + { + TextMeshPro nameShadowTMP = nameShadowTransform.transform.GetComponent(); + if (nameShadowTMP) + { + nameShadowTMP = StringStore.TranslateText(nameShadowTMP); + nameShadowTMP.autoSizeTextContainer = true; + } + } + } + StringStore.TranslateTextTransform(AlmanacTransform.Find("Back"), true); + StringStore.TranslateTextTransform(AlmanacTransform.Find("NextPage")); + StringStore.TranslateTextTransform(AlmanacTransform.Find("LastPage")); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/CustomSettings_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/CustomSettings_Patch.cs new file mode 100644 index 0000000..47f3f27 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/CustomSettings_Patch.cs @@ -0,0 +1,23 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(CustomSettings))] + public static class CustomSettings_Patch + { + [HarmonyPatch(nameof(CustomSettings.Awake))] + [HarmonyPostfix] + private static void Awake(CustomSettings __instance) + { + __instance.textMesh = StringStore.TranslateText(__instance.textMesh); + } + + [HarmonyPatch(nameof(CustomSettings.ChangeText))] + [HarmonyPostfix] + private static void ChangeText(CustomSettings __instance) + { + __instance.textMesh = StringStore.TranslateText(__instance.textMesh); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/CustomSun_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/CustomSun_Patch.cs new file mode 100644 index 0000000..2909545 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/CustomSun_Patch.cs @@ -0,0 +1,44 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using TMPro; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(CustomSun))] + public static class CustomSun_Patch + { + [HarmonyPatch(nameof(CustomSun.Awake))] + [HarmonyPostfix] + private static void Awake(CustomSun __instance) + { + if (__instance.inputField.gameObject.activeSelf) + { + string oriTextSun = __instance.inputField.m_Text; + __instance.inputField.gameObject.SetActive(false); + __instance.inputField.m_Text = StringStore.TranslateText(oriTextSun); + __instance.inputField.m_OriginalText = StringStore.TranslateText(oriTextSun); + __instance.inputField.gameObject.SetActive(true); + } + + if (__instance.setFlags.gameObject.activeSelf) + { + string oriTextFlags = __instance.setFlags.m_Text; + __instance.setFlags.gameObject.SetActive(false); + __instance.setFlags.m_Text = StringStore.TranslateText(oriTextFlags); + __instance.setFlags.m_OriginalText = StringStore.TranslateText(oriTextFlags); + __instance.setFlags.gameObject.SetActive(true); + } + + Transform lookZombieTransform = __instance.lookZombie.transform.GetChild(0).transform; + if (lookZombieTransform != null) + { + TextMeshProUGUI lookZombieTMP = lookZombieTransform.GetComponent(); + if (lookZombieTMP != null) + { + lookZombieTMP = StringStore.TranslateText(lookZombieTMP); + } + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/GardenPlant_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/GardenPlant_Patch.cs new file mode 100644 index 0000000..8f6bc29 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/GardenPlant_Patch.cs @@ -0,0 +1,23 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(GardenPlant))] + public static class GardenPlant_Patch + { + [HarmonyPatch(nameof(GardenPlant.Update))] + [HarmonyPostfix] + private static void Update(GardenPlant __instance) + { + __instance.infoText = StringStore.TranslateText(__instance.infoText); + } + + [HarmonyPatch(nameof(GardenPlant.UpdateInfo))] + [HarmonyPostfix] + private static void UpdateInfo(GardenPlant __instance) + { + __instance.infoText = StringStore.TranslateText(__instance.infoText); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/Help__Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/Help__Patch.cs new file mode 100644 index 0000000..688d057 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/Help__Patch.cs @@ -0,0 +1,31 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using TMPro; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(Help_))] + public class Help__Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(Help_.Start))] + private static void Start(Help_ __instance) + { + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + Transform warningTransform = __instance.transform.GetChild(0); + Transform warningTextTransform = warningTransform.FindChild("文字"); + Transform warningTextShadowTransform = warningTransform.FindChild("文字2"); + Transform[] array = [warningTextTransform, warningTextShadowTransform]; + + for (int i = 0; i < array.Length; i++) + { + if (array[i] != null) + { + array[i].GetComponent().text = StringStore.TranslateText(array[i].GetComponent().text); + array[i].GetComponent().font = fontAsset; + } + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/DY_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/DY_Patch.cs new file mode 100644 index 0000000..365e37d --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/DY_Patch.cs @@ -0,0 +1,16 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects +{ + [HarmonyPatch(typeof(DY))] + public static class DY_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(DY.Update))] + private static void Update(DY __instance) + { + __instance.TextMeshPro.text = StringStore.TranslateText(__instance.TextMeshPro.text); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/LanternUmbrella_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/LanternUmbrella_Patch.cs new file mode 100644 index 0000000..0de0d08 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/LanternUmbrella_Patch.cs @@ -0,0 +1,17 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects +{ + [HarmonyPatch(typeof(LanternUmbrella))] + public class LanternUmbrella_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(LanternUmbrella.Update))] + private static void Update(LanternUmbrella __instance) + { + __instance.energyText = StringStore.TranslateText(__instance.energyText); + __instance.energyTextShadow = StringStore.TranslateText(__instance.energyTextShadow); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/MagnetBox_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/MagnetBox_Patch.cs new file mode 100644 index 0000000..1b1342f --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/MagnetBox_Patch.cs @@ -0,0 +1,16 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects +{ + [HarmonyPatch(typeof(MagnetBox))] + public class MagnetBox_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(MagnetBox.Update))] + private static void Update(MagnetBox __instance) + { + StringStore.TranslateTextTransform(__instance.transform); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/MagnetInterface_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/MagnetInterface_Patch.cs new file mode 100644 index 0000000..cc61fda --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/MagnetInterface_Patch.cs @@ -0,0 +1,16 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects +{ + [HarmonyPatch(typeof(MagnetInterface))] + public class MagnetInterface_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(MagnetInterface.Update))] + private static void Update(MagnetInterface __instance) + { + StringStore.TranslateTextTransform(__instance.transform); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/Money_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/Money_Patch.cs new file mode 100644 index 0000000..198146c --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/Money_Patch.cs @@ -0,0 +1,17 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects +{ + [HarmonyPatch(typeof(Money))] + public static class Money_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(Money.Update))] + private static void Update(Money __instance) + { + __instance.beanCount.text = StringStore.TranslateText(__instance.beanCount.text); + __instance.beanCount2.text = StringStore.TranslateText(__instance.beanCount2.text); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/Plant_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/Plant_Patch.cs new file mode 100644 index 0000000..29e17ad --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/Plant_Patch.cs @@ -0,0 +1,21 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects +{ + [HarmonyPatch(typeof(Plant))] + public static class Plant_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(Plant.UpdateHealthText))] + private static void UpdateHealthText(Plant __instance) + { + Transform healthTransform = __instance.transform.Find("health"); + if (healthTransform != null) + { + StringStore.TranslateTextTransform(__instance.transform); + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/PlayerName_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/PlayerName_Patch.cs new file mode 100644 index 0000000..68622f2 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/PlayerName_Patch.cs @@ -0,0 +1,16 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects +{ + [HarmonyPatch(typeof(PlayerName))] + public static class PlayerName_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(PlayerName.Update))] + private static void Update(PlayerName __instance) + { + __instance.textMesh.text = StringStore.TranslateText(__instance.textMesh.text); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/SelectYourPlants_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/SelectYourPlants_Patch.cs new file mode 100644 index 0000000..51923bd --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/SelectYourPlants_Patch.cs @@ -0,0 +1,20 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects +{ + [HarmonyPatch(typeof(SelectYourPlants))] + public static class SelectYourPlants_Patch + { + [HarmonyPatch(nameof(SelectYourPlants.Awake))] + [HarmonyPostfix] + private static void Awake(SelectYourPlants __instance) + { + __instance.TextMeshProUGUI = StringStore.TranslateText(__instance.TextMeshProUGUI); + __instance.TextMeshProUGUI.autoSizeTextContainer = true; + + __instance.TextMeshProUGUI2 = StringStore.TranslateText(__instance.TextMeshProUGUI2); + __instance.TextMeshProUGUI2.autoSizeTextContainer = true; + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/Zombie_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/Zombie_Patch.cs new file mode 100644 index 0000000..185db33 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/MinorObjects/Zombie_Patch.cs @@ -0,0 +1,21 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects +{ + [HarmonyPatch(typeof(Zombie))] + public static class Zombie_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(Zombie.UpdateHealthText))] + private static void UpdateHealthText(Zombie __instance) + { + Transform healthTransform = __instance.transform.Find("health"); + if (healthTransform != null) + { + StringStore.TranslateTextTransform(__instance.transform); + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/TravelBuff_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/TravelBuff_Patch.cs new file mode 100644 index 0000000..3ce739b --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/TravelBuff_Patch.cs @@ -0,0 +1,17 @@ +using HarmonyLib; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(TravelBuff))] + public static class TravelBuff_Patch + { + [HarmonyPatch(nameof(TravelBuff.OnMouseUpAsButton))] + [HarmonyPostfix] + private static void OnMouseUpAsButton() + { + if (TravelBuffMgr.Instance == null) return; + TravelBuffMgr.Instance.text = AssetStore.StringStore.TranslateText(TravelBuffMgr.Instance.text); + TravelBuffMgr.Instance.text2 = AssetStore.StringStore.TranslateText(TravelBuffMgr.Instance.text2); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/TravelRefresh_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/TravelRefresh_Patch.cs new file mode 100644 index 0000000..f932d7a --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/TravelRefresh_Patch.cs @@ -0,0 +1,47 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using TMPro; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(TravelRefresh))] + public static class TravelRefresh_Patch + { + [HarmonyPatch(nameof(TravelRefresh.Update))] + [HarmonyPostfix] + private static void Update(TravelRefresh __instance) + { + TextMeshProUGUI pointsText = __instance.transform.GetChild(0).GetComponent(); + pointsText = StringStore.TranslateText(pointsText); + pointsText.autoSizeTextContainer = true; + + Transform TravelMenuTransform = __instance.transform.parent.transform; + Transform refreshTransform = TravelMenuTransform.Find("Refresh2").transform.Find("bank"); + if (refreshTransform != null) + { + Transform text_1Transform = refreshTransform.Find("text_1"); + if (text_1Transform != null) + { + TextMeshProUGUI text_1 = text_1Transform.GetComponent(); + if (text_1) + { + text_1 = StringStore.TranslateText(text_1); + text_1.autoSizeTextContainer = true; + } + } + + Transform text_2Transform = refreshTransform.Find("text_2"); + if (text_2Transform != null) + { + TextMeshProUGUI text_2 = text_2Transform.GetComponent(); + if (text_2) + { + text_2 = StringStore.TranslateText(text_2); + text_2.autoSizeTextContainer = true; + } + } + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/TravelStore_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/TravelStore_Patch.cs new file mode 100644 index 0000000..1d7052b --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/TravelStore_Patch.cs @@ -0,0 +1,38 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using System; +using TMPro; +using UnityEngine; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(TravelStore))] + internal class TravelStore_Patch + { + [HarmonyPatch(nameof(TravelStore.Update))] + [HarmonyPostfix] + private static void Update(TravelStore __instance) + { + foreach (TextMeshProUGUI text in __instance.introduces) + { + text.text = StringStore.TranslateText(text.text); + } + + Transform moneyTransform = __instance.transform.Find("Money"); + if (moneyTransform != null) + { + StringStore.TranslateTextTransform(moneyTransform); + } + } + + [HarmonyPatch(nameof(TravelStore.SetText), new Type[] { typeof(string)})] + [HarmonyPostfix] + private static void ShowText(TravelStore __instance) + { + foreach (TextMeshProUGUI text in __instance.introduces) + { + text.text = StringStore.TranslateText(text.text); + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/UIDifficulty_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/UIDifficulty_Patch.cs new file mode 100644 index 0000000..a74e5f3 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/UIDifficulty_Patch.cs @@ -0,0 +1,22 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using TMPro; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(UIDifficulty))] + public static class UIDifficulty_Patch + { + [HarmonyPatch(nameof(UIDifficulty.Update))] + [HarmonyPostfix] + private static void Update(UIDifficulty __instance) + { + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + string difficultyText = StringStore.patchesStore["Difficulty"][Utils.Language.ToString()]; + + __instance.t.text = string.Format(difficultyText + " {0}", GameAPP.difficulty); + __instance.t.autoSizeTextContainer = false; + __instance.t.font = fontAsset; + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/UIZombieNum_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/UIZombieNum_Patch.cs new file mode 100644 index 0000000..6fe701e --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/GameObjects/UIZombieNum_Patch.cs @@ -0,0 +1,21 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using TMPro; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects +{ + [HarmonyPatch(typeof(UIZombieNum))] + public static class UIZombieNum_Patch + { + [HarmonyPatch(nameof(UIZombieNum.Update))] + [HarmonyPostfix] + private static void Update(UIZombieNum __instance) + { + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + string zombieText = StringStore.patchesStore["Zombies"][Utils.Language.ToString()]; + + __instance.t.text = string.Format(zombieText + " {0}", Board.Instance.enermyCount); + __instance.t.font = fontAsset; + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/AlmanacMgrZombie_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/AlmanacMgrZombie_Patch.cs new file mode 100644 index 0000000..364736c --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/AlmanacMgrZombie_Patch.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using HarmonyLib; +using TMPro; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using static PvZ_Fusion_Translator__BepInEx_.FileLoader; +using UnityEngine; +using System.IO; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers +{ + [HarmonyPatch(typeof(AlmanacMgrZombie))] + public static partial class AlmanacMgrZombie_Patch + { + [HarmonyPatch(nameof(AlmanacMgrZombie.InitNameAndInfoFromJson))] + [HarmonyPrefix] + private static bool InitNameAndInfoFromJson(AlmanacMgrZombie __instance) + { + string currentLanguage = Utils.Language.ToString(); + string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); + string path = Path.Combine(almanacDir, "ZombieStringsTranslate.json"); + + if (!File.Exists(path)) + { + Log.LogError($"ZombieStringsTranslate.json file not found at path: {path}"); + return true; + } + + #if OBFUSCATE + if (CheckSumStore.IsModified(path)) + { + Log.LogError("File {0} was modified!", path); + return true; + } + #endif + + string json; + json = File.ReadAllText(path); + + bool hasAlmanacFont = false; + TMP_FontAsset almanacFontAsset = null; + if (FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage + "_Almanac") || FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage)) + { + almanacFontAsset = FontStore.LoadTMPFontAlmanac(currentLanguage); + hasAlmanacFont = true; + } + + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); + + TextMeshPro component = __instance.info.GetComponent(); + TextMeshPro component2 = __instance.zombieName.GetComponent(); + TextMeshPro component3 = __instance.zombieName.transform.GetChild(0).GetComponent(); + + AlmanacMgrZombie.ZombieAlmanacData zombieData = JsonUtility.FromJson(json); + + foreach (AlmanacMgrZombie.ZombieInfo zombieInfo in zombieData.zombies) + { + if (zombieInfo.theZombieType == __instance.theZombieType) + { + component.text = zombieInfo.info + "\n\n" + zombieInfo.introduce; + component.overflowMode = TextOverflowModes.Page; + component2.text = zombieInfo.name; + component2.autoSizeTextContainer = true; + component3.text = Utils.RemoveColorTags(zombieInfo.name); + component3.autoSizeTextContainer = true; + + if (hasAlmanacFont) + component.font = almanacFontAsset; + else + component.font = fontAsset; + component2.font = fontAsset; + component3.font = fontAsset; + + return false; + } + } + + return true; + } + + [HarmonyPatch(nameof(AlmanacMgrZombie.OnMouseDown))] + [HarmonyPrefix] + private static bool OnMouseDown(AlmanacMgrZombie __instance) + { + TextMeshPro component = __instance.info.GetComponent(); + if (component != null) + { + component.pageToDisplay = component.pageToDisplay > component.m_pageNumber ? 1 : component.pageToDisplay + 1; + return false; + } + return true; + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/AlmanacMgr_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/AlmanacMgr_Patch.cs new file mode 100644 index 0000000..24f421c --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/AlmanacMgr_Patch.cs @@ -0,0 +1,99 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using System.IO; +using TMPro; +using UnityEngine; +using static PvZ_Fusion_Translator__BepInEx_.FileLoader; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers +{ + [HarmonyPatch(typeof(AlmanacMgr))] + public static partial class AlmanacMgr_Patch + { + [HarmonyPatch(nameof(AlmanacMgr.InitNameAndInfoFromJson))] + [HarmonyPrefix] + private static bool InitNameAndInfoFromJson(AlmanacMgr __instance) + { + string currentLanguage = Utils.Language.ToString(); + string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); + string path = Path.Combine(almanacDir, "LawnStringsTranslate.json"); + + if (!File.Exists(path)) + { + Log.LogError($"LawnStringsTranslate.json file not found at path: {path}"); + return true; + } + + #if OBFUSCATE + if (CheckSumStore.IsModified(path)) + { + Log.LogError("File {0} was modified!", path); + return true; + } + #endif + + string json; + json = File.ReadAllText(path); + + bool hasAlmanacFont = false; + TMP_FontAsset almanacFontAsset = null; + if (FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage + "_Almanac") || FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage)) + { + almanacFontAsset = FontStore.LoadTMPFontAlmanac(currentLanguage); + hasAlmanacFont = true; + } + + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); + + TextMeshPro component = __instance.info.GetComponent(); + TextMeshPro component2 = __instance.plantName.GetComponent(); + TextMeshPro component3 = __instance.plantName.transform.GetChild(0).GetComponent(); + TextMeshPro component4 = __instance.cost.GetComponent(); + + AlmanacMgr.PlantData plantData = JsonUtility.FromJson(json); + + foreach (AlmanacMgr.PlantInfo plantInfo in plantData.plants) + { + if (plantInfo.seedType == __instance.theSeedType) + { + component.text = plantInfo.info + "\n\n" + plantInfo.introduce; + component.overflowMode = TextOverflowModes.Page; + component2.text = plantInfo.name; + component2.autoSizeTextContainer = true; + component3.text = Utils.RemoveColorTags(plantInfo.name); + component3.autoSizeTextContainer = true; + component4.text = plantInfo.cost; + + if (hasAlmanacFont) + { + component.font = almanacFontAsset; + component4.font = almanacFontAsset; + } + else + { + component.font = fontAsset; + component4.font = fontAsset; + } + component2.font = fontAsset; + component3.font = fontAsset; + return false; + } + } + + return true; + } + + [HarmonyPatch(nameof(AlmanacMgr.OnMouseDown))] + [HarmonyPrefix] + private static bool OnMouseDown(AlmanacMgr __instance) + { + TextMeshPro component = __instance.info.GetComponent(); + if (component != null) + { + component.pageToDisplay = component.pageToDisplay > component.m_pageNumber ? 1 : component.pageToDisplay + 1; + return false; + } + return true; + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/DifficultyMgr_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/DifficultyMgr_Patch.cs new file mode 100644 index 0000000..b24a68c --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/DifficultyMgr_Patch.cs @@ -0,0 +1,17 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers +{ + [HarmonyPatch(typeof(DifficultyMgr))] + public static class DifficultyMgr_Patch + { + [HarmonyPatch(nameof(DifficultyMgr.Update))] + [HarmonyPostfix] + private static void DifficultyMgr_Update(DifficultyMgr __instance) + { + __instance.t = StringStore.TranslateText(__instance.t); + __instance.t.autoSizeTextContainer = false; + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/EndlessMgr_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/EndlessMgr_Patch.cs new file mode 100644 index 0000000..06ad56b --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/EndlessMgr_Patch.cs @@ -0,0 +1,27 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using TMPro; +using UnityEngine; + + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers +{ + [HarmonyPatch(typeof(EndlessMgr))] + public static class EndlessMgr_Patch + { + [HarmonyPatch(nameof(EndlessMgr.Awake))] + [HarmonyPostfix] + private static void Awake(EndlessMgr __instance) + { + Transform textTransform = __instance.transform.GetChild(2); + if (textTransform != null && textTransform.gameObject.activeSelf) + { + TextMeshProUGUI textTMP = textTransform.GetComponent(); + if (textTMP != null) + { + textTMP = StringStore.TranslateText(textTMP); + } + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/IZEMgr_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/IZEMgr_Patch.cs new file mode 100644 index 0000000..bdaa085 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/IZEMgr_Patch.cs @@ -0,0 +1,26 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using TMPro; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers +{ + [HarmonyPatch(typeof(IZEMgr))] + public static class IZEMgr_Patch + { + [HarmonyPatch(nameof(IZEMgr.Start))] + [HarmonyPostfix] + public static void Start(IZEMgr __instance) + { + TextMeshProUGUI[] array = + [ + __instance.transform.GetChild(0).GetComponent(), + __instance.transform.GetChild(0).GetChild(0).GetComponent(), + ]; + for (int i = 0; i < array.Length; i++) + { + array[i] = StringStore.TranslateText(array[i]); + array[i].text = array[i].text.Replace("\n", " "); + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/InGameUIMgr_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/InGameUIMgr_Patch.cs new file mode 100644 index 0000000..ba07abc --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/InGameUIMgr_Patch.cs @@ -0,0 +1,32 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using TMPro; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers +{ + [HarmonyPatch(typeof(InGameUIMgr))] + public static class InGameUIMgr_Patch + { + [HarmonyPatch(nameof(InGameUIMgr.Start))] + [HarmonyPostfix] + private static void Start(InGameUIMgr __instance) + { + TextMeshProUGUI[] array = new TextMeshProUGUI[] + { + __instance.transform.GetChild(4).GetComponent(), + __instance.transform.GetChild(4).GetChild(0).GetComponent(), + __instance.transform.GetChild(5).GetComponent(), + __instance.transform.GetChild(5).GetChild(0).GetComponent(), + __instance.transform.GetChild(6).GetComponent(), + __instance.transform.GetChild(6).GetChild(0).GetComponent() + }; + TextMeshProUGUI[] array2 = array; + for (int i = 0; i < array2.Length; i++) + { + + array2[i] = StringStore.TranslateText(array2[i]); + array2[i].text = array2[i].text.Replace("\n", " "); + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/OppositeBuffManager_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/OppositeBuffManager_Patch.cs new file mode 100644 index 0000000..c14bb28 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/OppositeBuffManager_Patch.cs @@ -0,0 +1,28 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using System; +using TMPro; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers +{ + [HarmonyPatch(typeof(OppositeBuffManager))] + public static class OppositeBuffManager_Patch + { + [HarmonyPatch(nameof(OppositeBuffManager.SetText), new Type[] { typeof(TextMeshProUGUI), typeof(BuffType), typeof(int)})] + [HarmonyPostfix] + private static void SetText(OppositeBuffManager __instance, ref TextMeshProUGUI text) + { + StringStore.TranslateTextUI(text); + } + + [HarmonyPatch(nameof(OppositeBuffManager.Awake))] + [HarmonyPostfix] + private static void Awake(OppositeBuffManager __instance) + { + StringStore.TranslateTextUI(__instance.textA_bad[0]); + StringStore.TranslateTextUI(__instance.textA_bad[1]); + StringStore.TranslateTextUI(__instance.textB_bad[0]); + StringStore.TranslateTextUI(__instance.textB_bad[1]); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/TravelBuffMgr_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/TravelBuffMgr_Patch.cs new file mode 100644 index 0000000..ef3d77f --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/TravelBuffMgr_Patch.cs @@ -0,0 +1,26 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using System; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers +{ + [HarmonyPatch(typeof(TravelBuffMgr))] + public static class TravelBuffMgr_Patch + { + [HarmonyPatch(nameof(TravelBuffMgr.Awake))] + [HarmonyPostfix] + private static void Awake(TravelBuffMgr __instance) + { + __instance.text = StringStore.TranslateText(__instance.text); + __instance.text2 = StringStore.TranslateText(__instance.text2); + } + + [HarmonyPatch(nameof(TravelBuffMgr.ShowText), new Type[] { typeof(int), typeof(int) })] + [HarmonyPostfix] + private static void ShowText(TravelBuffMgr __instance) + { + __instance.text = StringStore.TranslateText(__instance.text); + __instance.text2 = StringStore.TranslateText(__instance.text2); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/TravelMenuMgr_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/TravelMenuMgr_Patch.cs new file mode 100644 index 0000000..7be6b1e --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/TravelMenuMgr_Patch.cs @@ -0,0 +1,50 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using TMPro; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers +{ + [HarmonyPatch(typeof(TravelMenuMgr))] + public static class TravelMenuMgr_Patch + { + [HarmonyPatch(nameof(TravelMenuMgr.Start))] + [HarmonyPostfix] + private static void Start(TravelMenuMgr __instance) + { + foreach(TextMeshProUGUI text in __instance.textMesh) + { + text.text = StringStore.TranslateText(text.text); + } + foreach(TextMeshProUGUI text in __instance.textMeshShadow) + { + text.text = StringStore.TranslateText(text.text); + } + } + [HarmonyPatch(nameof(TravelMenuMgr.SetText))] + [HarmonyPostfix] + private static void SetText(TravelMenuMgr __instance) + { + foreach(TextMeshProUGUI text in __instance.textMesh) + { + text.text = StringStore.TranslateText(text.text); + } + foreach(TextMeshProUGUI text in __instance.textMeshShadow) + { + text.text = StringStore.TranslateText(text.text); + } + } + [HarmonyPatch(nameof(TravelMenuMgr.SetRichText), [typeof(int), typeof(int), typeof(TextMeshProUGUI), typeof(string)])] + [HarmonyPostfix] + private static void SetRichText(TravelMenuMgr __instance) + { + foreach(TextMeshProUGUI text in __instance.textMesh) + { + text.text = StringStore.TranslateText(text.text); + } + foreach(TextMeshProUGUI text in __instance.textMeshShadow) + { + text.text = StringStore.TranslateText(text.text); + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/UIMgr_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/UIMgr_Patch.cs new file mode 100644 index 0000000..347dac5 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/Managers/UIMgr_Patch.cs @@ -0,0 +1,17 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers +{ + [HarmonyPatch(typeof(UIMgr))] + public class UIMgr_Patch + { + [HarmonyPatch(nameof(UIMgr.EnterMainMenu))] + [HarmonyPostfix] + private static void EnterMainMenu(UIMgr __instance) + { + // Log.LogInfo("Entered Main Menu"); + WarningStore.WarningReload(Utils.Language); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/OtherManagers/AchievementClip_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/OtherManagers/AchievementClip_Patch.cs new file mode 100644 index 0000000..2ad7705 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/OtherManagers/AchievementClip_Patch.cs @@ -0,0 +1,63 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using System.Collections.Generic; +using System.IO; +using System.Text.Json; +using TMPro; +using static PvZ_Fusion_Translator__BepInEx_.FileLoader; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.OtherManagers +{ + [HarmonyPatch(typeof(AchievementClip))] + public static class AchievementClip_Patch + { + [HarmonyPatch(nameof(AchievementClip.Start))] + [HarmonyPostfix] + private static void Start(AchievementClip __instance) + { + string currentLanguage = Utils.Language.ToString(); + string achievementDir = GetAssetDir(AssetType.Almanac, Utils.Language); + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); + string path = Path.Combine(achievementDir, "AchievementsTextTranslate.json"); + + #if OBFUSCATE + if (CheckSumStore.IsModified(path)) + { + Log.LogError("File {0} was modified!", path); + return; + } + #endif + + if (!File.Exists(path)) return; + + string json; + json = File.ReadAllText(path); + Dictionary achievementsTexts = JsonSerializer.Deserialize>(json); + + TextMeshProUGUI text1 = __instance.introduce.transform.GetChild(1).GetComponent(); + TextMeshProUGUI text2 = __instance.introduce.transform.GetChild(2).GetComponent(); + TextMeshProUGUI name1 = __instance.image.transform.GetChild(0).GetComponent(); + + text1.text = achievementsTexts[__instance._index].Name; + text1.font = fontAsset; + text2.text = achievementsTexts[__instance._index].Name; + text2.font = fontAsset; + name1.text = achievementsTexts[__instance._index].Text; + name1.font = fontAsset; + } + } + + public class AchievementObject + { + public Achievement achievement { get; set; } + public string Name { get; set; } + public string Text { get; set; } + + public AchievementObject(Achievement achievement = Achievement.Welcome, string name = "", string text = "") + { + this.achievement = achievement; + Name = name; + Text = text; + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/OtherManagers/GardenUI_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/OtherManagers/GardenUI_Patch.cs new file mode 100644 index 0000000..9d923a0 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/OtherManagers/GardenUI_Patch.cs @@ -0,0 +1,17 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.OtherManagers +{ + [HarmonyPatch(typeof(GardenUI))] + public static class GardenUI_Patch + { + [HarmonyPatch(nameof(GardenUI.Update))] + [HarmonyPostfix] + public static void Update(GardenUI __instance) + { + __instance.currentPageText = StringStore.TranslateText(__instance.currentPageText, false); + __instance.currentPageText2 = StringStore.TranslateText(__instance.currentPageText2, false); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/OtherManagers/MenuText_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/OtherManagers/MenuText_Patch.cs new file mode 100644 index 0000000..8f32307 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/OtherManagers/MenuText_Patch.cs @@ -0,0 +1,21 @@ +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using System; +using TMPro; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.OtherManagers +{ + [HarmonyPatch(typeof(MenuText))] + public static class MenuText_Patch + { + [HarmonyPatch(nameof(MenuText.UpdateText), new Type[] { typeof(string) })] + [HarmonyPostfix] + private static void UpdateTextPatch(MenuText __instance) + { + TextMeshProUGUI text_1 = __instance.transform.GetChild(0).Find("text1").GetComponent(); + text_1.text = StringStore.TranslateText(text_1.text); + TextMeshProUGUI text = __instance.transform.GetChild(0).Find("text").GetComponent(); + text.text = StringStore.TranslateText(text_1.text); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Patches/OtherManagers/ThanksMenu_Patch.cs b/PvZ-Fusion-Blooms-master/BepInEx/Patches/OtherManagers/ThanksMenu_Patch.cs new file mode 100644 index 0000000..1928d36 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Patches/OtherManagers/ThanksMenu_Patch.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TMPro; +using HarmonyLib; +using PvZ_Fusion_Translator__BepInEx_.AssetStore; + +namespace PvZ_Fusion_Translator__BepInEx_.Patches.OtherManagers +{ + [HarmonyPatch(typeof(ThanksMenu))] + public class ThanksMenu_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(ThanksMenu.Update))] + private static void Update(ThanksMenu __instance) + { + TextMeshProUGUI textTransform = __instance.transform.GetChild(0).GetComponent(); + if (textTransform != null) + { + textTransform.text = StringStore.TranslateText(textTransform.text); + textTransform.autoSizeTextContainer = true; + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/BepInEx/PvZ Fusion Translator [BepInEx].csproj b/PvZ-Fusion-Blooms-master/BepInEx/PvZ Fusion Translator [BepInEx].csproj new file mode 100644 index 0000000..f5c02f0 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/PvZ Fusion Translator [BepInEx].csproj @@ -0,0 +1,381 @@ + + + + net6.0 + PvZ_Fusion_Translator__BepInEx_ + BepInEx Port of PvZ Fusion Translator + 1.0.0 + true + latest + + https://api.nuget.org/v3/index.json; + https://nuget.bepinex.dev/v3/index.json; + https://nuget.samboy.dev/v3/index.json + + PvZ_Fusion_Translator__BepInEx_ + C:\Users\Estudio\Documents\LHC G\PVZF-Translation\PC_PVZ-Fusion_2.3 + AnyCPU;x64 + Debug;Release;DebugObfuscate;ReleaseObfuscate + + + + + + + + + + $(GamePath)\BepInEx\core\0Harmony.dll + + + $(GamePath)\BepInEx\core\AsmResolver.dll + + + $(GamePath)\BepInEx\core\AsmResolver.DotNet.dll + + + $(GamePath)\BepInEx\core\AsmResolver.PE.dll + + + $(GamePath)\BepInEx\core\AsmResolver.PE.File.dll + + + $(GamePath)\BepInEx\interop\Assembly-CSharp.dll + + + $(GamePath)\BepInEx\core\AssetRipper.CIL.dll + + + $(GamePath)\BepInEx\core\AssetRipper.Primitives.dll + + + $(GamePath)\BepInEx\core\BepInEx.Core.dll + + + $(GamePath)\BepInEx\core\BepInEx.Preloader.Core.dll + + + $(GamePath)\BepInEx\core\BepInEx.Unity.Common.dll + + + $(GamePath)\BepInEx\core\BepInEx.Unity.IL2CPP.dll + + + $(GamePath)\BepInEx\core\Cpp2IL.Core.dll + + + $(GamePath)\BepInEx\core\Disarm.dll + + + $(GamePath)\BepInEx\core\Gee.External.Capstone.dll + + + $(GamePath)\BepInEx\core\Iced.dll + + + $(GamePath)\BepInEx\core\Il2CppInterop.Common.dll + + + $(GamePath)\BepInEx\core\Il2CppInterop.Generator.dll + + + $(GamePath)\BepInEx\core\Il2CppInterop.HarmonySupport.dll + + + $(GamePath)\BepInEx\core\Il2CppInterop.Runtime.dll + + + $(GamePath)\BepInEx\interop\Il2CppMono.Security.dll + + + $(GamePath)\BepInEx\interop\Il2Cppmscorlib.dll + + + $(GamePath)\BepInEx\interop\Il2CppSystem.dll + + + $(GamePath)\BepInEx\interop\Il2CppSystem.Configuration.dll + + + $(GamePath)\BepInEx\interop\Il2CppSystem.Core.dll + + + $(GamePath)\BepInEx\interop\Il2CppSystem.Xml.dll + + + $(GamePath)\BepInEx\core\LibCpp2IL.dll + + + $(GamePath)\BepInEx\core\Mono.Cecil.dll + + + $(GamePath)\BepInEx\core\Mono.Cecil.Mdb.dll + + + $(GamePath)\BepInEx\core\Mono.Cecil.Pdb.dll + + + $(GamePath)\BepInEx\core\Mono.Cecil.Rocks.dll + + + $(GamePath)\BepInEx\core\MonoMod.RuntimeDetour.dll + + + $(GamePath)\BepInEx\core\MonoMod.Utils.dll + + + $(GamePath)\BepInEx\core\SemanticVersioning.dll + + + $(GamePath)\BepInEx\core\StableNameDotNet.dll + + + $(GamePath)\BepInEx\interop\Unity.2D.Animation.Runtime.dll + + + $(GamePath)\BepInEx\interop\Unity.Burst.dll + + + $(GamePath)\BepInEx\interop\Unity.Burst.Unsafe.dll + + + $(GamePath)\BepInEx\interop\Unity.Collections.dll + + + $(GamePath)\BepInEx\interop\Unity.Collections.LowLevel.ILSupport.dll + + + $(GamePath)\BepInEx\interop\Unity.InternalAPIEngineBridge.001.dll + + + $(GamePath)\BepInEx\interop\Unity.Mathematics.dll + + + $(GamePath)\BepInEx\interop\Unity.RenderPipeline.Universal.ShaderLibrary.dll + + + $(GamePath)\BepInEx\interop\Unity.RenderPipelines.Core.Runtime.dll + + + $(GamePath)\BepInEx\interop\Unity.RenderPipelines.Universal.Runtime.dll + + + $(GamePath)\BepInEx\interop\Unity.TextMeshPro.dll + + + $(GamePath)\BepInEx\interop\Unity.VisualScripting.Core.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.AccessibilityModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.AIModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.AndroidJNIModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.AnimationModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.AssetBundleModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.AudioModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.ClothModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.ClusterInputModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.ClusterRendererModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.ContentLoadModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.CoreModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.CrashReportingModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.DirectorModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.DSPGraphModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.GameCenterModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.GIModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.GridModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.HotReloadModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.ImageConversionModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.IMGUIModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.InputLegacyModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.InputModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.JSONSerializeModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.LocalizationModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.ParticleSystemModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.PerformanceReportingModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.Physics2DModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.PhysicsModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.ProfilerModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.PropertiesModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.ScreenCaptureModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.SharedInternalsModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.SpriteMaskModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.SpriteShapeModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.StreamingModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.SubstanceModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.SubsystemsModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.TerrainModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.TerrainPhysicsModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.TextCoreFontEngineModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.TextCoreTextEngineModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.TextRenderingModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.TilemapModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.TLSModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.UI.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.UIElementsModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.UIModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.UmbraModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.UnityAnalyticsCommonModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.UnityAnalyticsModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.UnityConnectModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.UnityCurlModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.UnityTestProtocolModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.UnityWebRequestAssetBundleModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.UnityWebRequestAudioModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.UnityWebRequestModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.UnityWebRequestTextureModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.UnityWebRequestWWWModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.VehiclesModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.VFXModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.VideoModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.VirtualTexturingModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.VRModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.WindModule.dll + + + $(GamePath)\BepInEx\interop\UnityEngine.XRModule.dll + + + $(GamePath)\BepInEx\core\WasmDisassembler.dll + + + $(GamePath)\BepInEx\interop\__Generated.dll + + + + + + + + diff --git a/PvZ-Fusion-Blooms-master/BepInEx/Utils.cs b/PvZ-Fusion-Blooms-master/BepInEx/Utils.cs new file mode 100644 index 0000000..6dcaf4b --- /dev/null +++ b/PvZ-Fusion-Blooms-master/BepInEx/Utils.cs @@ -0,0 +1,128 @@ +using PvZ_Fusion_Translator__BepInEx_.AssetStore; +using System; +using System.Diagnostics; +using System.IO; +using System.Text.RegularExpressions; +using UnityEngine; +using UnityEngine.Experimental.Rendering; + +namespace PvZ_Fusion_Translator__BepInEx_ +{ + public class Utils + { + internal static bool TryReplaceTexture2D(Texture2D ogTexture) + { + if (ogTexture != null) + { + if (TextureStore.textureDict.TryGetValue(ogTexture.name, out string texturePath)) + { + try + { + ImageConversion.LoadImage(ogTexture, File.ReadAllBytes(texturePath)); + + Log.LogDebug("OK! Replaced Texture " + ogTexture.name); + + ogTexture.name = "replaced_" + ogTexture.name; + return true; + } + catch (Exception ex) + { + Log.LogError("Failed to replace texture: " + ogTexture.name + " at path: " + texturePath); + Log.LogError(ex.ToString()); + } + } + } + return false; + } + + internal static Texture2D LoadImage(string path) + { + if (!File.Exists(path)) + { + throw new FileNotFoundException($"The image file at path '{path}' does not exist."); + } + + byte[] array = File.ReadAllBytes(path); + Texture2D texture2D = new(2, 2, GraphicsFormat.R8G8B8A8_UNorm, TextureCreationFlags.None, 1, IntPtr.Zero, null); + ImageConversion.LoadImage(texture2D, array); + return texture2D; + } + + public static Color HexToColor(string hex) + { + + hex = hex.Replace("#", ""); + + float r = int.Parse(hex.Substring(0, 2), System.Globalization.NumberStyles.HexNumber) / 255f; + float g = int.Parse(hex.Substring(2, 2), System.Globalization.NumberStyles.HexNumber) / 255f; + float b = int.Parse(hex.Substring(4, 2), System.Globalization.NumberStyles.HexNumber) / 255f; + + return new Color(r, g, b); + } + + public static void OpenSaveDirectory() + { + string saveDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "AppData", "LocalLow", "LanPiaoPiao", "PlantsVsZombiesRH"); + Process.Start("explorer.exe", saveDirectory); + } + + public static void OpenTrello() + { + string website = "https://trello.com/b/DcdT1kUp"; + Process.Start(new ProcessStartInfo(website) { UseShellExecute = true }); + } + + public static string RemoveColorTags(string text) + { + return Regex.Replace(text, @"]+>", ""); + } + + internal static void ChangeLanguage(string language) + { + OldLanguage = Language; + + if (Enum.TryParse(language, out Utils.LanguageEnum lang)) + { + Utils.Language = lang; + } + else + { + // Handle invalid language string + Log.LogError($"Invalid language string: {language}"); + } + + WarningStore.isWarningMessageLoaded = false; + FontStore.Reload(); + StringStore.Reload(); + TextureStore.Reload(); + FileLoader.SaveLanguage(); + } + + public static Utils.LanguageEnum OldLanguage; + public static Utils.LanguageEnum Language; + public enum LanguageEnum + { + // first column + English, + French, + Italian, + German, + Spanish, + Portuguese, + + // second column + Javanese, //Filipino, + Vietnamese, + Indonesian, + Russian, + Japanese, + Korean, + + // third column + // Ukrainian, + // Slovak, + + LANG_END + } + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/AudioStore.cs b/PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/AudioStore.cs new file mode 100644 index 0000000..b87032b --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/AudioStore.cs @@ -0,0 +1,181 @@ +using HarmonyLib; +using MelonLoader; +using MelonLoader.Utils; +using System.Reflection; +using UnityEngine; + +namespace PvZ_Fusion_Translator.AssetStore +{ + internal class AudioStore + { + public static Dictionary AudioClips = []; + public static Dictionary AudioClipNames = []; + + public static bool LogSounds; + + private static bool overrideEnabled; + private static readonly string customAudioPath = Path.Combine(MelonEnvironment.ModsDirectory, "PvZ_Fusion_Translator", "[Custom Audios]"); + private static readonly string[] allowedExts = [".wav", ".mp3", ".ogg"]; + + #if AUDIO_TESTING + public Canvas Canvas { get; set; } + public RectTransform songRectTransform { get; private set; } + #endif + + public static void Init() + { + bool loadCustomAudio = MelonPreferences.GetEntryValue("PvZ_Fusion_Translator", "DefaultAudio"); + if (loadCustomAudio) + { + return; + } + else + { + LoadAudios(); + } + } + public static void LoadAudios() + { + if (!Directory.Exists(customAudioPath)) + Directory.CreateDirectory(customAudioPath); + + var category = MelonPreferences.CreateCategory("Audio Replace", ""); + category.CreateEntry("LogSounds", false); + LogSounds = category.GetEntry("LogSounds").Value; + MelonPreferences.Save(); + + string[] audioFiles = Directory.GetFiles(customAudioPath, "*", SearchOption.AllDirectories); + var ovrClip = audioFiles.SingleOrDefault(f => Path.GetFileNameWithoutExtension(f) == "REPLACE_ALL"); + if (ovrClip == null) + { + foreach (string file in audioFiles) + { + if (!allowedExts.Contains(Path.GetExtension(file))) + continue; + + AudioClip clip = AudioImportLib.API.LoadAudioClip(file); + AudioClips.Add(clip.name, clip); + Log.LogInfo("Added Override: " + clip.name); + } + } + else + { + AudioClip clip = AudioImportLib.API.LoadAudioClip(ovrClip); + AudioClips.Add(clip.name, clip); + overrideEnabled = true; + Log.LogInfo("Added Override: " + clip.name); + } + + Type audioSourceType = typeof(AudioSource); + string sourceMethodName = "Play"; + MethodInfo prefixMethod = typeof(AudioStore).GetMethod("AudioPlayPatch", BindingFlags.Static | BindingFlags.Public); + if (prefixMethod == null) + { + Log.LogError($"Couldn't find method named \"AudioPlayPatch\" in type <{typeof(Core)}>."); + return; + } + _ = Core.Instance.HarmonyInstance.Patch(AccessTools.Method(audioSourceType, sourceMethodName), new HarmonyMethod(prefixMethod)); + Core.Instance.HarmonyInstance.Patch(AccessTools.Method(audioSourceType, sourceMethodName, [typeof(ulong)]), new HarmonyMethod(prefixMethod)); + } + + #if AUDIO_TESTING + public static void InitializeCanvas() + { + + Transform canvasTransform; + + if (canvas != null) return; // Prevent duplicate canvas creation + + canvas = new GameObject("AudioSourceCanvas").AddComponent(); + canvas.renderMode = RenderMode.ScreenSpaceOverlay; + + CanvasScaler scaler = canvas.gameObject.AddComponent(); + scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; + scaler.referenceResolution = new Vector2(1920, 1080); + + canvas.gameObject.AddComponent(); + + // Add a RectTransform for positioning text + GameObject songTextObject = new GameObject("SongText"); + songTextObject.transform.SetParent(canvas.transform); + + songRectTransform = songTextObject.AddComponent(); + songRectTransform.anchorMin = new Vector2(1, 1); // Top-right corner + songRectTransform.anchorMax = new Vector2(1, 1); + songRectTransform.pivot = new Vector2(1, 1); + songRectTransform.anchoredPosition = new Vector2(-20, -20); // Adjust margin + + // Add a TextMeshPro component for the text + var textComponent = songTextObject.AddComponent(); + textComponent.alignment = TextAlignmentOptions.Right; + textComponent.fontSize = 24; + textComponent.color = Color.white; + textComponent.text = "Current Song: None"; // Placeholder + } + + + public static void AudioSources() + { + if (!Directory.Exists(customAudioPath)) + Directory.CreateDirectory(customAudioPath); + string path = Path.Combine(customAudioPath, "audio_source.json"); + if (!File.Exists(path)) + { + Log.LogError($"LawnStringsTranslate.json file not found at path: {path}"); + return; + } + string json; + json = File.ReadAllText(path); + + AudioClipNames = JsonSerializer.Deserialize>(json); + } + + public static (string, string) GetAudioSource(string clipName) + { + if (AudioClipNames.TryGetValue(clipName, out var audioSource)) + { + return audioSource; + } + else + { + return ("Music", "Source Unknown"); + } + } + + + public static void UpdateAudioSourceText(string clipName, string sourceName) + { + if (songRectTransform == null) InitializeCanvas(); + + var textComponent = songRectTransform.GetComponent(); + if (textComponent != null) + { + textComponent.text = $"Current Song: {clipName}\nSource: {sourceName}"; + } + } + #endif + + + public static void AudioPlayPatch(AudioSource __instance) + { + if (__instance.clip == null) + return; + + if (LogSounds) + MelonLogger.Msg($"Playing \"{__instance.clip.name}\" from object \"{__instance.gameObject.name}\""); + + string audioClipName = overrideEnabled ? "REPLACE_ALL" : __instance.clip.name; + if (AudioClips.TryGetValue(audioClipName, out AudioClip replaceClip)) + { + __instance.pitch = 1; + __instance.clip = replaceClip; + } + + #if AUDIO_TESTING + // Update the displayed audio source + var (name, source) = GetAudioSource(__instance.clip.name); + UpdateAudioSourceText(name, source); + #endif + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/CheckSumStore.cs b/PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/CheckSumStore.cs new file mode 100644 index 0000000..fc9ce51 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/CheckSumStore.cs @@ -0,0 +1,858 @@ +#if OBFUSCATE +using System.Security.Cryptography; +using System.Text.Encodings.Web; +using System.Text.Json; +using static Newtonsoft.Json.JsonConvert; +using static PvZ_Fusion_Translator.FileLoader; +namespace PvZ_Fusion_Translator.AssetStore +{ + internal class CheckSumStore + { + private static Dictionary modifiedCheckSums = new Dictionary(); + + private static Dictionary checkSums = new Dictionary() + { + #if !RELEASE || RELEASE + { "Dumps\\Default Textures [Do Not Remove]\\Almanac_CloseButton" , "G/++rbb7GMZv51CxHKdVINtAji/x9zyyhlcbCCWyP2s=" }, + { "Dumps\\Default Textures [Do Not Remove]\\Almanac_CloseButtonHighlight" , "nNygYVELdiLcY0xbk0I1uX92NRazxns+I1u7p0M/e4w=" }, + { "Dumps\\Default Textures [Do Not Remove]\\Almanac_GroundDay" , "pExENxFbAGfBzLByFps1SX9AN1H6cL0QQK0jOFn3qu8=" }, + { "Dumps\\Default Textures [Do Not Remove]\\Almanac_GroundNight" , "n3LXi5yONzLVTc0eNStQtLdlcEsihCi5iImxbB7rMdY=" }, + { "Dumps\\Default Textures [Do Not Remove]\\Almanac_GroundNightPool" , "fe6efxJzsAn3i75Wg7WrCyAFVQhMKXnzh+uThkCJXV4=" }, + { "Dumps\\Default Textures [Do Not Remove]\\Almanac_GroundPool" , "yKlIHtnBPI8tiUnlRCHYcCnqwarpiuzfOj4H3yGn40o=" }, + { "Dumps\\Default Textures [Do Not Remove]\\Almanac_GroundRoof" , "cYTj11LkhWuJxO8j4h+s6+AG4JtgfZ2jfL4P/rWzGfc=" }, + { "Dumps\\Default Textures [Do Not Remove]\\Almanac_Imitater" , "9BD3A5dWXxgklYK4TTQ/G7d8A8OtZHgZrnq3hIrSlDY=" }, + { "Dumps\\Default Textures [Do Not Remove]\\Almanac_IndexBack" , "KqSOHoWk3g/Vd1vtwL1X5X33ft8TkxHnupydPB/f8lI=" }, + { "Dumps\\Default Textures [Do Not Remove]\\Almanac_IndexButton" , "GWE8iGEa9rVJW3TGG0j2la9VwlxrJ/LfnLu0OMKxMZg=" }, + { "Dumps\\Default Textures [Do Not Remove]\\Almanac_IndexButtonHighlight" , "kbz2ezXWjIGUC7Q0k3cagXMuRLpnU7l4xGiX7WdSMJE=" }, + { "Dumps\\Default Textures [Do Not Remove]\\Almanac_PlantCard" , "lLnAYniK6sDgRW62t1Q/GGh9zIWkBOia+oFzntBBjx8=" }, + { "Dumps\\Default Textures [Do Not Remove]\\Almanac_ZombieBack" , "r3fcC00ZRR8vQUTsPRj339mQZi4/pFcL4rewSbRtM7E=" }, + { "Dumps\\Default Textures [Do Not Remove]\\Almanac_ZombieCard" , "Fp2qKy2IpiEkA1hZrgXgrxyOA6hteIEQ8sqPrOkaaI4=" }, + { "Dumps\\Default Textures [Do Not Remove]\\Almanac_ZombieWindow" , "mRlpQuXwIiUhKwkZXcK8sDZ6aQKnl43Y5Pbw5NMsKmk=" }, + { "Dumps\\Default Textures [Do Not Remove]\\Almanac_ZombieWindow2" , "GPvh5nRvUqJMjRHwhqC4SUUB3BUKfCgTk6AWO8eGq/M=" }, + { "Dumps\\Default Textures [Do Not Remove]\\CursorClick" , "r7q8kCmXo9FHCC00VPswxjsGba2OMpE4UzBByode7KI=" }, + { "Dumps\\Default Textures [Do Not Remove]\\CursorDefault" , "xUv6VFWl/tzVsUa5heAlzlOyFjdzXsX9kT7EobZTIFQ=" }, + { "Dumps\\Default Textures [Do Not Remove]\\garden_new" , "jkDprxF6ApST91S4TzAGyzj2MC9umC8XCaasbstkBt8=" }, + { "Dumps\\Default Textures [Do Not Remove]\\MainMenu" , "e2lbkFcEN6hqwDk3A0SHZJu7PwEcol1u/QZtvpq71gc=" }, + { "Dumps\\Default Textures [Do Not Remove]\\MainMenutravel" , "fvORSzOzZ6sNDHL3qC/eA7tExSe/TsLIBswcuuFgFZ4=" }, + { "Dumps\\Default Textures [Do Not Remove]\\plant" , "ophzSlF5tmOXKn/2lHZUYiE4pMibPTqBvfQMnuBSzb8=" }, + { "Dumps\\Default Textures [Do Not Remove]\\Present" , "YHoZLVSxMkA8c2u2RCP1tJbFFZZxeulpuGTGp7AtpWA=" }, + { "Dumps\\Default Textures [Do Not Remove]\\PresentOpen" , "TL+KhicnGWIIOcEyMdTErS1SyBO5citeF37g3CxRiuo=" }, + { "Dumps\\Default Textures [Do Not Remove]\\PresentOpenZ" , "Ij60phw5j3rhjwMyGiVUOuvp0lelEJqtYQHEECc6l14=" }, + { "Dumps\\Default Textures [Do Not Remove]\\PresentZ" , "fZF3EH0YB37P7j1LBJN9jIwniyCy1Oe2Tw2BsSGc4iA=" }, + { "Dumps\\Default Textures [Do Not Remove]\\SeedBank" , "BjG7XCi4XIPZO+NHAgksjgSUoO3JPJrL7BGFEWNaQ0A=" }, + { "Dumps\\Default Textures [Do Not Remove]\\SeedChooser_Background" , "RB2fot78wqAGxeIIBuG8ZEnytADs/yxhdh3Jre74nMo=" }, + { "Dumps\\Default Textures [Do Not Remove]\\SeedChooser_Button" , "/KtMBXY5AmPsmt98HVMAuoDrocKr7s/+g7/6wfMJIxY=" }, + { "Dumps\\Default Textures [Do Not Remove]\\SeedChooser_Button2" , "JYwHTIvcmX8NS1wxlb7u1nMPG4BRA2mgm6R2IM/9NXk=" }, + { "Dumps\\Default Textures [Do Not Remove]\\SeedChooser_Button2_Glow" , "NRov8DgO5+9rqTXQASV8izLAp302/o5ufZgVrvb7aig=" }, + { "Dumps\\Default Textures [Do Not Remove]\\SeedChooser_Button_Disabled" , "nvfQ1CN+p9h1rUqVhOOLAlCmsdehs2qgVz6kmWERGkU=" }, + { "Dumps\\Default Textures [Do Not Remove]\\SeedChooser_Button_Glow" , "Wg8LhHovWpNtScBLZbhcjgqQcr4C2pehb3QS2bpmO1Y=" }, + { "Dumps\\Default Textures [Do Not Remove]\\seedfog" , "SN9MPqY76N6ucf+vzs22J+2Bs23+1Tl56f7GrT3Z9Yc=" }, + { "Dumps\\Default Textures [Do Not Remove]\\seedlinkage" , "kqQiioaMU/fAv9+eTzdzV7KizreB80Qio2e9cyWtaOY=" }, + { "Dumps\\Default Textures [Do Not Remove]\\seedp" , "i7wDlTSmSBueQ2sCWU7usRbfGoncupi6+plQrjv9A8w=" }, + { "Dumps\\Default Textures [Do Not Remove]\\SeedPacketSilhouette" , "AVSM7MUReK4oLDUajmkWjQqT577of/ZhaAepDOQk54o=" }, + { "Dumps\\Default Textures [Do Not Remove]\\SeedPacket_Larger" , "C7ZuQNW+xi8YNyYtz09aAXOYP/t56u01WwgYo7FT0Tc=" }, + { "Dumps\\Default Textures [Do Not Remove]\\SeedPacket_Night" , "YVCLQ3WeIUjevo0Wtf2xAOnDGAAzjl44bRHS1T5ProE=" }, + { "Dumps\\Default Textures [Do Not Remove]\\SeedPacket_Other" , "kiidD0VdJ/U0xYxtM7f9uvUYsK2VHFIZU3750doVtHc=" }, + { "Dumps\\Default Textures [Do Not Remove]\\SeedPacket_Pool" , "8MQOevWJrWgIsnWhYi2xt61yxoJARcINzSYzRG7yrnM=" }, + { "Dumps\\Default Textures [Do Not Remove]\\seedroof" , "zluDS1sgaJ4iHXt4PfJ3tqi+LVduGKB9+WLdWZZH0ik=" }, + { "Dumps\\Default Textures [Do Not Remove]\\seeds" , "JNHpZfk3qR+yWd4fhWsdNF+JxtfTOjTAKxLs61X0+co=" }, + { "Dumps\\Default Textures [Do Not Remove]\\SelectorScreen_almanac_shadow" , "SdZZ5VOq567+489ffjHcTbgWj3KjI01YKZgdUGj9yis=" }, + { "Dumps\\Default Textures [Do Not Remove]\\SelectorScreen_Flower3" , "kIzmQGfYT3nCObTtM+C6F7WgE8oCj4M+Qq2II0n2IXw=" }, + { "Dumps\\Default Textures [Do Not Remove]\\SelectorScreen_Leaf1" , "OwGYCIlBbK5j1dZxBjHlPkvswRy+QHgYVXvmOYoMt6E=" }, + { "Dumps\\Default Textures [Do Not Remove]\\SelectorScreen_Leaf2" , "0ea/nJV5ziIA2Aher2Exfgz6lDuGDjqHf6Ra/bsmMrg=" }, + { "Dumps\\Default Textures [Do Not Remove]\\SelectorScreen_Leaf3" , "nzELmsj1XUXJmOhMLixHLBzW5TGhZCkwoAOaRpRJlYw=" }, + { "Dumps\\Default Textures [Do Not Remove]\\SelectorScreen_Leaf4" , "pXEZUhFqr2KC1pCQLB6MwwJhBM5ZI2teGOvYPgr011U=" }, + { "Dumps\\Default Textures [Do Not Remove]\\SelectorScreen_Leaf5" , "SeX0iGZoN8ZbhKZSkonw9I7MS3lBVHVqzko1hX80LUg=" }, + { "Dumps\\Default Textures [Do Not Remove]\\SelectorScreen_Leaves" , "Fny+WEQ2N1yzFhdAPhR/zoK0P2HY4GDckluVL6u6Kz0=" }, + { "Dumps\\Default Textures [Do Not Remove]\\ShovelBank" , "Pas2yhjcl+HVwsIm68o9PRjAR72y5lTQm85e2vuYgBE=" }, + + // English + { "Localization\\English\\Textures\\Game\\FinalWave" , "0O9Esd6GUDRmYE9NtcuIvmRzZU6RKUeR4U6Xiy5qi6o=" }, + { "Localization\\English\\Textures\\Game\\FlagMeterLevelProgress" , "CzuBH4sm7Nid4zloZF3i0bpNcA9ILPhrmOxVYI4IggA=" }, + { "Localization\\English\\Textures\\Game\\HugeWave" , "n9O7b5CuD9Yu+ccecqsmm4ofp10MAw6eoZmIxnX8WwM=" }, + { "Localization\\English\\Textures\\Game\\StartPlant" , "IIz47Bh/4MjFKaZaHx5PAxz97YukBkSqHv8nnN7tMLM=" }, + { "Localization\\English\\Textures\\Game\\StartReady" , "lhaXbwp0oHTrX1JFyJE8hnabkzj4bgNyWdFDMn32cbo=" }, + { "Localization\\English\\Textures\\Game\\StartSet" , "WPtmG9W8kFZQthgaycm6P17wmnqWW55CnU2JjsOGJkU=" }, + { "Localization\\English\\Textures\\Logo\\标题合集" , "IfcPnZSGmfNl1jdd4RiGaD2o3XHs/K0R7HKKLzcFftE=" }, + { "Localization\\English\\Textures\\Menu\\NewAdv" , "6UYMHlQ5SdT+gX7cJLy0iwyCXdxblrjdNe2l/OCeDcc=" }, + { "Localization\\English\\Textures\\Menu\\options_menuback" , "OGZ6SNFo8RbpPqWaO88qCzPm7r8Mv1WzUee9BlZDwFE=" }, + { "Localization\\English\\Textures\\Menu\\SelectorScreen_Adventure_button" , "7PPDxa4AOg4Q/ioviwKYKx2ftu82+zlvJdbeqWlGaBQ=" }, + { "Localization\\English\\Textures\\Menu\\SelectorScreen_Adventure_highlight" , "+Drt7kOZRfinB9t8BsklSl8Np6NxDPJ21XvYuVoiwbY=" }, + { "Localization\\English\\Textures\\Menu\\SelectorScreen_Almanac" , "Th6/Pun/NEn6797dnzdq8XnCqY9/oIORszG6K3xSFbo=" }, + { "Localization\\English\\Textures\\Menu\\SelectorScreen_AlmanacHighlight" , "hp6y9BUvolJ0bQdU1FY1Oyt57fizZFx8Q3zXYR4t/BI=" }, + { "Localization\\English\\Textures\\Menu\\SelectorScreen_Challenges_button" , "LDMp8hCkHDSIrN9F92K93txxjFZ69qKyfG429oRyGfc=" }, + { "Localization\\English\\Textures\\Menu\\SelectorScreen_Challenges_highlight" , "rSB360yGYMYQyNUJYb2xMCgGmSFAl7plLTr1BDMA8W8=" }, + { "Localization\\English\\Textures\\Menu\\SelectorScreen_Challenge_button" , "0DWLUXJ5RYKci+loCThNfHEpk7tKV08vifffcK8owNg=" }, + { "Localization\\English\\Textures\\Menu\\SelectorScreen_Challenge_highlight" , "AXW4pkVR9twu7/SJYvqScPeNswIoefGCBJXDf7SsXFA=" }, + { "Localization\\English\\Textures\\Menu\\SelectorScreen_Help1" , "bwLeNCc4/VtLyocaVQhB++/7t2l4ngYQg+3r95RSMDs=" }, + { "Localization\\English\\Textures\\Menu\\SelectorScreen_Help2" , "B7p5vi9AyiidPL4nvBTVdL+WhUbsKzHEIHyWWAut1KU=" }, + { "Localization\\English\\Textures\\Menu\\SelectorScreen_Options1" , "TJEiHNySrGFxBP85FeP3hl4TcLCVjX1VXYt0navnK04=" }, + { "Localization\\English\\Textures\\Menu\\SelectorScreen_Options2" , "SehcWmqt2cxQhPlcJqUKGeRyl0VgxGymyrVKLyGH9LA=" }, + { "Localization\\English\\Textures\\Menu\\SelectorScreen_Quit1" , "zbJL06XIJDi1PjiR52BZCmNSYaRCWLb13owTgv9hVw0=" }, + { "Localization\\English\\Textures\\Menu\\SelectorScreen_Quit2" , "diLLwcdEED5M+H4Y35Rnyu+W+R6FU7qVDs7DteLWFtw=" }, + { "Localization\\English\\Textures\\Menu\\SelectorScreen_Vasebreaker_button" , "9JoXGZoVFEVUJR+s/mEye3rkTIYwGLZCiajp12bAP/g=" }, + { "Localization\\English\\Textures\\Menu\\SelectorScreen_vasebreaker_highlight" , "b2xzl7F7FEkFZpxGKwEwasmF5BkxaZJArAhcnPQ+Ng4=" }, + { "Localization\\English\\Textures\\Menu\\SelectorScreen_WoodSign1" , "RhYg1ymYR4mEqL0do6dIqRxts+BG9GlB4d5dc+gMjsU=" }, + { "Localization\\English\\Textures\\Menu\\SelectorScreen_WoodSign2" , "aV7MGtWrsnh5O2ikBof66Y4n+w9xhbQbkOObNP2GysY=" }, + { "Localization\\English\\Textures\\Menu\\SelectorScreen_WoodSign2_press" , "bov/KzSszIVUaDK3x1AFJZU5kbiBArl+tBybTxi7cS4=" }, + { "Localization\\English\\Textures\\Menu\\SelectorScreen_ZenGarden" , "8x4Y+E/DvSPrr1sY1k3trPVtqLrRuUUVWktfLIx5qTI=" }, + { "Localization\\English\\Textures\\Menu\\SelectorScreen_ZenGardenHighlight" , "ldiEJGQVyYvquwZuPy/aYNf+Am24dG6iILuw/1k3dNQ=" }, + { "Localization\\English\\Textures\\Menu\\SZW" , "2FoSx111GS6QF3dQoUlqhsbVbDSB0MrnUFKilgsIyzo=" }, + { "Localization\\English\\Textures\\Menu\\thanks" , "bffGVtPUS70M8mNXyKDE9aU+XqGMLITegGGOaPMVL84=" }, + { "Localization\\English\\Textures\\Menu\\travel" , "vy+5i0dx1+DIECxAsVv/co8gIwM9zk8djIKCHbG9ykI=" }, + { "Localization\\English\\Textures\\Menu\\钥匙经典" , "PAPsrNZRY9UetFgFnEwZKdN1TgNbCrU7ZtaPZVzBxvg=" }, + { "Localization\\English\\Textures\\Particles\\Doom" , "FqBUBeIvzyyXL+cqO4Fi6CKI5gZW5QXfHYPTOYoeteM=" }, + { "Localization\\English\\Textures\\Particles\\ExplosionPowie" , "cuikfX+3LOtSw3EPB6DnjANO5bKkoYCMdWSm+StmW70=" }, + { "Localization\\English\\Textures\\Particles\\ExplosionSpudow" , "4pJ/gZsuKRsAbUL1YWsaaJC9NxrzhqUiQe6glK07ydU=" }, + { "Localization\\English\\Textures\\Particles\\guang" , "kh0dcDxOXgh8+Eq1TmKdJug5PdR+nzZrK5iS5Nkw7Gw=" }, + { "Localization\\English\\Textures\\Particles\\Sproing" , "WtzrUuUsjp/GmOfoHApij3VLMn+Tr5qUZ6GGqqhUyD0=" }, + { "Localization\\English\\Textures\\Particles\\SunExplosionPowie" , "3bSjOYpanuLnsl58oYUzOAXt94nony6Drq8qdpfRSGQ=" }, + + { "Localization\\English\\Strings\\translation_regexs" , "rjxlsJwClOAJERCe9XmYJB1q+TX6h0p5zDHqCyu/9wE=" }, + { "Localization\\English\\Strings\\translation_strings" , "zsQF+z4URSZY7yuqTfuOIdc/sfcq6g1Hi6ZeedfBFS4=" }, + + { "Localization\\English\\Almanac\\LawnStringsTranslate" , "7BFCUmTVKh5MdefAGxiqgbVtWHcyq9Jg/e8jCWcGI2A=" }, + { "Localization\\English\\Almanac\\ZombieStringsTranslate" , "4KU0HKBDqw5VPbvDqzByDS4nGSG0UAHZ6ek7iv0FOUA=" }, + { "Localization\\English\\Almanac\\AchievementsTextTranslate" , "Y0rNgt02JEkiv/jacilOR0NgACVjqyWpQNQrF9t9PIs=" }, + + // French + { "Localization\\French\\Strings\\translation_regexs" , "Pv4R3N7SkRz8Ksp9DkHR+xMn3Tv7+t57FAwEYDveH4U=" }, + { "Localization\\French\\Strings\\translation_strings" , "atzVMZyXEHG93wcM7Uqz0tTHsWK+dxc1csQxLhHF5wA=" }, + + { "Localization\\French\\Textures\\Game\\FinalWave" , "VTTPmIlVoXW7tU/sQyTlZZq2dy3qOlVs7cmPQYd2PMU=" }, + { "Localization\\French\\Textures\\Game\\FlagMeterLevelProgress" , "DVG5/OyuPfwy7dNOE8NCKmqZK0tKpwsr7As0df3c+0Y=" }, + { "Localization\\French\\Textures\\Game\\StartPlant" , "RkTaTLEoVW4TnXBg+UL3YlG+sdqg+WhP934sTpLlzzk=" }, + { "Localization\\French\\Textures\\Game\\StartReady" , "8/MDcBU6dbIHN1vESmyp27QWxIbifrZZn4IDxKldW3c=" }, + { "Localization\\French\\Textures\\Game\\StartSet" , "8+doc0lYZ2a3W3qpbMSeRturIOWpmyhHw9COvM4Ctkk=" }, + { "Localization\\French\\Textures\\Menu\\NewAdv" , "4noYYWThghcWgV9BCO4WJjEGqHg+SblIoCoCKgTXdAo=" }, + { "Localization\\French\\Textures\\Menu\\SelectorScreen_Adventure_button" , "ZRxJ77hv8I2NmSiK6LTDgnOG9obBh+ueMa3R/NDCd5I=" }, + { "Localization\\French\\Textures\\Menu\\SelectorScreen_Adventure_highlight" , "MoCVUnQ+U8HdUtA4haA7Cx3CmlC/hvVuvYc9bakMtW0=" }, + { "Localization\\French\\Textures\\Menu\\SelectorScreen_Almanac" , "8txwE7D0UbRCH0hzukyZBACcCn1f9yiXLvhzBIkfKCg=" }, + { "Localization\\French\\Textures\\Menu\\SelectorScreen_AlmanacHighlight" , "WoiG0xkTP5oLEYBWOwnf+kkvbY3jD/xTVYgjBQ6/RLQ=" }, + { "Localization\\French\\Textures\\Menu\\SelectorScreen_Challenges_button" , "3NEwHpNoT1jEl+4gDpOYQ/9osW9rvdfdmiJ0ALIV8Uw=" }, + { "Localization\\French\\Textures\\Menu\\SelectorScreen_Challenges_highlight" , "RD2hIoFhO7AU6nmtrp5iJwjptYy6ociYKGUJxNsYHd0=" }, + { "Localization\\French\\Textures\\Menu\\SelectorScreen_Challenge_button" , "eQO5Wj2FOU2kLRMmI6Hhp3lir/hmYhOGrct5dL6utI0=" }, + { "Localization\\French\\Textures\\Menu\\SelectorScreen_Challenge_highlight" , "3cetfrmDbZHx1uumNbBApG5p8I2T8spnrqVhPqSxkI8=" }, + { "Localization\\French\\Textures\\Menu\\SelectorScreen_Help1" , "2yINgPeQqUy6b/mzw/2mFfTxWUlzQrJoYC4Yz/VoGy0=" }, + { "Localization\\French\\Textures\\Menu\\SelectorScreen_Help2" , "aaUDGQU1+0ltVD4OF2Luc/6pXK7LZ4B5jL9BtSNRnjo=" }, + { "Localization\\French\\Textures\\Menu\\SelectorScreen_Options1" , "Lpt1mXltCSkn+9BeMOT+CzTxcQ7cwUtFem+I1tWHdqE=" }, + { "Localization\\French\\Textures\\Menu\\SelectorScreen_Options2" , "MNNGXO8AboJJf9tMKXLpIB6j1foAj6bcHopNhHcpRVo=" }, + { "Localization\\French\\Textures\\Menu\\SelectorScreen_Quit1" , "6NILc8MqiGcQ3ttSKGfDOEOgvUnIUNO/DWBIeNi4/pM=" }, + { "Localization\\French\\Textures\\Menu\\SelectorScreen_Quit2" , "rwTFCgy3kNLCcBM5J6EjguUP4NuvfkDNJjks94eaP/g=" }, + { "Localization\\French\\Textures\\Menu\\SelectorScreen_Vasebreaker_button" , "UYwa4CPhRF8CiWro6Y22GfFQOlk8xCQ6Mldkgk4Jn0c=" }, + { "Localization\\French\\Textures\\Menu\\SelectorScreen_vasebreaker_highlight" , "MzBfCyymyT0E4mGUdhps7O6IHJdHtwNtGoi3kRAS8Ok=" }, + { "Localization\\French\\Textures\\Menu\\SelectorScreen_WoodSign1" , "T2Ci2ItAeYw0hMbOP87XJefKbaye8Fhv5tN4H3V7TFg=" }, + { "Localization\\French\\Textures\\Menu\\SelectorScreen_WoodSign2" , "KnPecN+vhvShgMagZGtPKPzMLcc+N3Kqsrlt51YiKRU=" }, + { "Localization\\French\\Textures\\Menu\\SelectorScreen_WoodSign2_press" , "v2L4jFj8hcIeJzle9LA0OLcCKwXXYdPVBucdslPTlF8=" }, + { "Localization\\French\\Textures\\Menu\\SelectorScreen_ZenGarden" , "ngbC53eTpHs9VaU1qViFJeJVCNhoZcvojiFpeqrXjMc=" }, + { "Localization\\French\\Textures\\Menu\\SelectorScreen_ZenGardenHighlight" , "F/nkF7zPU6FyWpOaxMim7/NbS6mH23er3ihfF2tVUSk=" }, + { "Localization\\French\\Textures\\Menu\\SZW" , "Z0uAEbNYk36lyCsPXGXnmjO0L3C1E68aA54stVpbYYs=" }, + { "Localization\\French\\Textures\\Menu\\thanks" , "bzYfnWlAyBzLCflijFAld5m0LBmzDS5vyCbUJs+cn0U=" }, + { "Localization\\French\\Textures\\Menu\\travel" , "Ca4e7HNOAXOUzKQAw+1+H1JRI14D1yLEn5cdXHmFcMo=" }, + { "Localization\\French\\Textures\\Menu\\钥匙经典" , "E+VDMHWhhtf9MwVo8SB9b2eDTE1v3u5Wd5DxoM935fo=" }, + { "Localization\\French\\Textures\\Particles\\Doom" , "q/QV2mCopjFnbwQUUTvoPtcyGV/UAwuxjB9v+GDm3OE=" }, + { "Localization\\French\\Textures\\Particles\\ExplosionPowie" , "mqTy7LXjfh1v7kEtwHzIckWjm/4P97dCs4CbyvzOESU=" }, + { "Localization\\French\\Textures\\Particles\\ExplosionSpudow" , "zFpkHlUNR9jWL/H8FQWy8habmtvu2wtMi/PpClRax2c=" }, + { "Localization\\French\\Textures\\Particles\\Sproing" , "FSStD7Lw1uNrSHqZkZCKrY+hcA6O1DOMKe/6R+jqNdk=" }, + + { "Localization\\French\\Almanac\\LawnStringsTranslate" , "sjZ1qRYGKM3sKMimzIlfmd3e2T5gIV38wy3bU75pLjU=" }, + { "Localization\\French\\Almanac\\ZombieStringsTranslate" , "k6XiNRnACedQuAMhh2CHx9jwMfPEJTbG/UZpubs7EM8=" }, + { "Localization\\French\\Almanac\\AchievementsTextTranslate" , "cFzYB+rYT5//+JpvEHa8Or97RYJZdAI0zK3Pr0Fw9hU=" }, + + // Italian + { "Localization\\Italian\\Strings\\translation_regexs" , "Fr7kZcK4cwoN6WsCARX06Od+PkzCv/FTetj7ME0cIok=" }, + { "Localization\\Italian\\Strings\\translation_strings" , "gXM9MZ66TBCflwXl3hMvH46U70kU2w3i4o0EQAd6Xp8=" }, + + { "Localization\\Italian\\Textures\\Game\\FinalWave" , "J7mSpIXvwo0JbrS8RLLWr8jS5KwRcMoDT6aSIVykhiU=" }, + { "Localization\\Italian\\Textures\\Game\\FlagMeterLevelProgress" , "pwnHiUlgXSYUhEXhBWe1XUeeWfYTb0oTY9/UlerGPuU=" }, + { "Localization\\Italian\\Textures\\Game\\StartPlant" , "6OqWQtc8U0Qm8qyhkdhgOmLhR3yGVnLOFhZ6ZrDIjy4=" }, + { "Localization\\Italian\\Textures\\Game\\StartReady" , "3QPcKBCGX8TLM8xCqCDJqY0uCsRg0vUxGzmTkvfXujM=" }, + { "Localization\\Italian\\Textures\\Game\\StartSet" , "VS5T89S8Do4xqRwxSBt9kjV9o/minfu3M//piKAJVkQ=" }, + { "Localization\\Italian\\Textures\\Menu\\NewAdv" , "UEsXovFnKuglsJ9S59cnJjDnhfDyTAXtLtVEnw9oOD8=" }, + { "Localization\\Italian\\Textures\\Menu\\options_menuback" , "WjWI+u05cf2sNThCp2EaWE58r2HwXRIP1gfwvwNo84k=" }, + { "Localization\\Italian\\Textures\\Menu\\SelectorScreen_Adventure_button" , "s4XJiAhMaWGMpyzt/fGQG/dESF2XeQQ9x+1FQWyLkiU=" }, + { "Localization\\Italian\\Textures\\Menu\\SelectorScreen_Adventure_highlight" , "NrVoP4kXJ8zaw9/cdm2oRPo08C3oCa24xCO23d11UBo=" }, + { "Localization\\Italian\\Textures\\Menu\\SelectorScreen_Almanac" , "cOdUtbMj5hqPyHoYfORNboSUikAGyoNtKO7DicYANRI=" }, + { "Localization\\Italian\\Textures\\Menu\\SelectorScreen_AlmanacHighlight" , "ComYfg7rKwHPcmZENPfQP5T9TFQ0ARRmVye2nGAc+3A=" }, + { "Localization\\Italian\\Textures\\Menu\\SelectorScreen_Challenges_button" , "DMY8d7mlP2ZmBHZz6BjYM1SEFlkFWp9VuIbB7+bMVwk=" }, + { "Localization\\Italian\\Textures\\Menu\\SelectorScreen_Challenges_highlight" , "/OvCfFYFwlvf+DefR1/XYIAQ7djymbF4EK1kiLJzXHU=" }, + { "Localization\\Italian\\Textures\\Menu\\SelectorScreen_Challenge_button" , "0XDQd6EaJkRSnYezFxhMFFAse/i2ZlRVmW+Fn9kSWnY=" }, + { "Localization\\Italian\\Textures\\Menu\\SelectorScreen_Challenge_highlight" , "UfKNb+QqlwzBdu1eORqEeDB9lVVKmGMpqRSExUAUAak=" }, + { "Localization\\Italian\\Textures\\Menu\\SelectorScreen_Help1" , "RoyqJT79KbODd3PfK28pDvvnhcps9XVDxNNT1GjXu38=" }, + { "Localization\\Italian\\Textures\\Menu\\SelectorScreen_Help2" , "UQdoBeSlI04NXh+VYjUyN9l3gT5p/CDRAU1jUsFqerU=" }, + { "Localization\\Italian\\Textures\\Menu\\SelectorScreen_Options1" , "3ebMHMsiekRjU3Rnc5t+yIkeHNpyZi8/Oulst4WWacg=" }, + { "Localization\\Italian\\Textures\\Menu\\SelectorScreen_Options2" , "PFlm0Sdy/1Kajr32uINpR6i7YXQ54a8dq0+OI0R8zec=" }, + { "Localization\\Italian\\Textures\\Menu\\SelectorScreen_Quit1" , "bPWwEE74Tdb583NcXB8e5W/meXVvmwuWkuajv+/R5Ro=" }, + { "Localization\\Italian\\Textures\\Menu\\SelectorScreen_Quit2" , "vBdX54EEKdZkJgiFcCQPtzRPoj0NSKTq7UA7rWDSTBg=" }, + { "Localization\\Italian\\Textures\\Menu\\SelectorScreen_Vasebreaker_button" , "ZPkJ309XC1P5w3x4IPhItEeLd5WVlU0mIaBoHX3b5Bg=" }, + { "Localization\\Italian\\Textures\\Menu\\SelectorScreen_vasebreaker_highlight" , "8VuUajuH7+8MJqROk/3XFQOEx541qi89ykuQCNaJ+L0=" }, + { "Localization\\Italian\\Textures\\Menu\\SelectorScreen_ZenGarden" , "1tP+grtgWPu5HtvUa2ox+9assN+Wgj63wBkJoskr6K8=" }, + { "Localization\\Italian\\Textures\\Menu\\SelectorScreen_ZenGardenHighlight" , "sZuiY1fbj5mg0TXaMok/qJFwoYf3+OxkN+Bk3pbTjs8=" }, + { "Localization\\Italian\\Textures\\Menu\\SZW" , "6cXREWl13sjqgdz3Zf5kT1N7bCoIc7LyrHg3WNMVTyE=" }, + { "Localization\\Italian\\Textures\\Menu\\thanks" , "I2nKJztoIdeVy/CyGYN/r/DB+Gvv3geaFxOdtMdf3ao=" }, + { "Localization\\Italian\\Textures\\Particles\\Doom" , "8E+/HlnnJa52eoBgLYjMyjBCsb5bhc/rTnsJKs2hucA=" }, + { "Localization\\Italian\\Textures\\Particles\\ExplosionPowie" , "u2bgHV+XPb4gSz8CagwJdbKWszej9uoIcbM1Z5GRto8=" }, + { "Localization\\Italian\\Textures\\Particles\\ExplosionSpudow" , "CciMCMupOdEov98dK59e2wF2izCwW8jpBkwQE/EV/JY=" }, + { "Localization\\Italian\\Textures\\Particles\\Sproing" , "nYlKAmcK0rADsk4KS7FaQ3FZBfl+IGQuXb7O1GCML6Y=" }, + + { "Localization\\Italian\\Almanac\\LawnStringsTranslate" , "npd2sE+VJ46XdwqP4cx+Jg7/mgxFiUUgpxEKxDrBUKk=" }, + { "Localization\\Italian\\Almanac\\ZombieStringsTranslate" , "GEhXXOMNHS12b+dR5Q6cxYrORjjyywpkPEKB3QzCn+I=" }, + { "Localization\\Italian\\Almanac\\AchievementsTextTranslate" , "Z4YUscuIUlrlLiaYWHTEvNjztVt291fLjJjkfc/lYBE=" }, + + // German + { "Localization\\German\\Strings\\translation_regexs" , "v3wwSqcUG/g71BrZXhYkpxDYebHeO52n1I8QjjlOuUw=" }, + { "Localization\\German\\Strings\\translation_strings" , "LGDwWtGeEnEvv31TnvXdkVUEs5od34WPNQ0od7WKy60=" }, + + { "Localization\\German\\Textures\\Game\\FinalWave" , "+MHS0Xz4nzGw+0knMtj5vJYSxaaT0KH/g8DWXUOv788=" }, + { "Localization\\German\\Textures\\Game\\FlagMeterLevelProgress" , "M0XScRnevh24JLXF48cG2GecSHlbP4vGUerW0xk63OA=" }, + { "Localization\\German\\Textures\\Game\\StartPlant" , "ab42rVDpP/bDtBjg9LvrfVmEf3E2Bry1pwOnMo8vF+A=" }, + { "Localization\\German\\Textures\\Game\\StartReady" , "7vV3VLAlAKbjXTBzaxlN+ulcOimET/gMvohDzyjFXoI=" }, + { "Localization\\German\\Textures\\Game\\StartSet" , "nNyPtyTiTsCPalXr/MgQob6EEb8kgyPZjMWmbXu3YFw=" }, + { "Localization\\German\\Textures\\Menu\\NewAdv" , "Lx7kxZzwBLios8g7raYwDDPcz2X48SshJaWuklBYUDc=" }, + { "Localization\\German\\Textures\\Menu\\options_menuback" , "WjWI+u05cf2sNThCp2EaWE58r2HwXRIP1gfwvwNo84k=" }, + { "Localization\\German\\Textures\\Menu\\SelectorScreen_Adventure_button" , "8NsCGe3aSbZ00AJFlELTtD1hOJlu+RojAAvvD77ICpw=" }, + { "Localization\\German\\Textures\\Menu\\SelectorScreen_Adventure_highlight" , "LcyIKu9BsVtJapQUrpkdefPiA+JTYkak3fg87Tx45JU=" }, + { "Localization\\German\\Textures\\Menu\\SelectorScreen_Almanac" , "JrkVQQByD5XSa77HI5+MVGkrc+3nTDyKEP+Kuij6gPo=" }, + { "Localization\\German\\Textures\\Menu\\SelectorScreen_AlmanacHighlight" , "zUlJJqGxLiwafOpBogGO+zX621Q3EnetL+u5vROt6JQ=" }, + { "Localization\\German\\Textures\\Menu\\SelectorScreen_Challenges_button" , "SWZKSjn8ytu5outezry04hHXcTmQD+f6KlWn4nlIZCA=" }, + { "Localization\\German\\Textures\\Menu\\SelectorScreen_Challenges_highlight" , "9S0JmpQLSGprElTl2MzQoSuT+Eemhj7vaQ20lwi8Ynw=" }, + { "Localization\\German\\Textures\\Menu\\SelectorScreen_Challenge_button" , "VRVyZIq8PBKunX8767vh70F/SA85Cifao+kvi7HMIHE=" }, + { "Localization\\German\\Textures\\Menu\\SelectorScreen_Challenge_highlight" , "WIH6pTlcbWqOMk+H2OYsBft0jVBwYT7hhWiiWaZzT8s=" }, + { "Localization\\German\\Textures\\Menu\\SelectorScreen_Help1" , "t9KLP/pCP5dWxWp7nAPjon/4224sE+yY2sX+MhqRJ1Q=" }, + { "Localization\\German\\Textures\\Menu\\SelectorScreen_Help2" , "KZ7sZ8Q9Jus9Su3Tu3FLWmWJssq/RPnuOO/eQ7HgaXI=" }, + { "Localization\\German\\Textures\\Menu\\SelectorScreen_Options1" , "nqTlln74GhHYs6GKAqcsoS7AzDnOD1jOjvfBBzMOEyo=" }, + { "Localization\\German\\Textures\\Menu\\SelectorScreen_Options2" , "xtg2c+bnhPszl8u8BTma6O/xMxiZ/asBAA5jRCbWtek=" }, + { "Localization\\German\\Textures\\Menu\\SelectorScreen_Quit1" , "xyxc8phjdNVui7E7RHFSSlu8OGIXw8HW2QpBCrKokmQ=" }, + { "Localization\\German\\Textures\\Menu\\SelectorScreen_Quit2" , "PBuRnBbzOk257Jm2i3ISLoz3oeDzy6LNurXaf9LKV2E=" }, + { "Localization\\German\\Textures\\Menu\\SelectorScreen_Vasebreaker_button" , "92BwDgaXMJZXqrcCxdIm8XcZai1NuGH0amcno5E2uU0=" }, + { "Localization\\German\\Textures\\Menu\\SelectorScreen_vasebreaker_highlight" , "YzxTyUcR2OvQ1ctFTKq3kd47A0tgiXp/kPQC/hgdom4=" }, + { "Localization\\German\\Textures\\Menu\\SelectorScreen_WoodSign1" , "T0wrDENK1CD3OgeosDNa4ab28lsSi9JmM7v8wbxB4bs=" }, + { "Localization\\German\\Textures\\Menu\\SelectorScreen_WoodSign2" , "9SZQ6SvrqFn5kPXbF1JD7F5uMfvGyV0xkar2qCvb2UM=" }, + { "Localization\\German\\Textures\\Menu\\SelectorScreen_WoodSign2_press" , "jJD+LiAoEzsnPJeUFt2Gpf+e2P8JjKpnfLDDPh6Zcho=" }, + { "Localization\\German\\Textures\\Menu\\SelectorScreen_ZenGarden" , "5Z6wqSVe04hmNHCPdPrDlJrXqgblhY6OG843O19GVmw=" }, + { "Localization\\German\\Textures\\Menu\\SelectorScreen_ZenGardenHighlight" , "z6YuoHbmClwoKeBjsLa0wypSdcB3QrEh2wzzYnDk6Ek=" }, + { "Localization\\German\\Textures\\Menu\\SZW" , "op9D5nHLxn/WZ/TVVaeji8hj9qRQl1DeuHZF/rj/ZMA=" }, + { "Localization\\German\\Textures\\Menu\\thanks" , "myLBgPcIux3cNkPd833r01ZqJsCqBTty31xJE68ZD28=" }, + { "Localization\\German\\Textures\\Menu\\travel" , "ASg2t1qO64hqGJMqDTQ8da8KotTKpkGtzKIaKuO1MqU=" }, + { "Localization\\German\\Textures\\Menu\\钥匙经典" , "KuqwMj6aedb2J7e8rVQpMa5Ie97lAFbGuwGFZq3POJo=" }, + { "Localization\\German\\Textures\\Particles\\Doom" , "rY5dss0ZrDcUHYVTddyesRpU+r0HoF5eiBM4iDMhHhY=" }, + { "Localization\\German\\Textures\\Particles\\ExplosionPowie" , "Gu4iuRPXhL3KAlUjBjbBOpjPthKXlViQ+8lw2sreTNY=" }, + { "Localization\\German\\Textures\\Particles\\ExplosionSpudow" , "z0h6r4O2FdV1r4CbGVd4nmEpGHZeo8dM2wV9suiZq8o=" }, + { "Localization\\German\\Almanac\\AchievementsTextTranslate" , "12tsG4qJrdtX0dxUOa532CyrC+cF403BfFg3fsjRO+I=" }, + { "Localization\\German\\Almanac\\LawnStringsTranslate" , "Vqqn/gcnY7SIPEVbIxSBi6DXSVBwMyVCQvhOs4KCoJQ=" }, + { "Localization\\German\\Almanac\\ZombieStringsTranslate" , "RlBdepGFFohgICk5idOkRFo9t8FxUuiMw4hoo6eYs0Y=" }, + + // Spanish + { "Localization\\Spanish\\Strings\\translation_regexs" , "4QFp251QrntXDcXjGrGYje8gvuKNHAxVp4FfLm0uHI4=" }, + { "Localization\\Spanish\\Strings\\translation_strings" , "BT+eTs1l2eWCDb+5CGgJJmjyAGqTulKOh2VuDIkwxTE=" }, + + { "Localization\\Spanish\\Textures\\Game\\FinalWave" , "fcYpg8VM7fWplgQdj87NOj5jtGgCPzvW4c2fJOUiJIs=" }, + { "Localization\\Spanish\\Textures\\Game\\FlagMeterLevelProgress" , "4MdtfTqEleDpziEenobp9O5cP3L/nZk18gdT9xW2O9c=" }, + { "Localization\\Spanish\\Textures\\Game\\HugeWave" , "n9O7b5CuD9Yu+ccecqsmm4ofp10MAw6eoZmIxnX8WwM=" }, + { "Localization\\Spanish\\Textures\\Game\\StartPlant" , "s7phwlweOMyWGCtCtFoLSMSC/VQSxFPVoB9T+RZQyhk=" }, + { "Localization\\Spanish\\Textures\\Game\\StartReady" , "DRI5gg//9pDb5dOaR0PhlBzuhP2lryhT6aeklSCUTxY=" }, + { "Localization\\Spanish\\Textures\\Game\\StartSet" , "eiX7QvBlF+EcJrXsOxqOkzu0VF/6hb04uNRRHRA/RMA=" }, + { "Localization\\Spanish\\Textures\\Logo\\标题合集" , "zt6CxJgEU+kegWGRKzQKwJynE91Nbpk9hgSby2zHW/o=" }, + { "Localization\\Spanish\\Textures\\Menu\\MainMenu" , "ZTaVNrPrxtSad5bo89RQVNXxaprYLZuGsl6dvuAoJR4=" }, + { "Localization\\Spanish\\Textures\\Menu\\MainMenutravel" , "w7iF3kfdiOg8EdbPKZlfxfObZXSAdqAMzfDMtM+4Dd8=" }, + { "Localization\\Spanish\\Textures\\Menu\\NewAdv" , "itgAdOEzcDj7sUA11u4xX3BwY7vssEdui606FpUUrEk=" }, + { "Localization\\Spanish\\Textures\\Menu\\options_menuback" , "OGZ6SNFo8RbpPqWaO88qCzPm7r8Mv1WzUee9BlZDwFE=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_Adventure_button" , "yE5gPHXKy3xnVBFtSTC0zjhfl0tCrc6sHPK8AiiO/s0=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_Adventure_highlight" , "gwHOCHLV9NAvvChiQt5X95UOLaStVZogt4DWAokvACg=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_Almanac" , "xfqV6GfWdsrPhlVIduoQ6x5QWnci7DRO0E8qC6lItDA=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_AlmanacHighlight" , "a7NCRdhsKTG4/8CLniWG2j/3MbUh68YmT1QJWAVNCDI=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_Challenges_button" , "LDMp8hCkHDSIrN9F92K93txxjFZ69qKyfG429oRyGfc=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_Challenges_highlight" , "rSB360yGYMYQyNUJYb2xMCgGmSFAl7plLTr1BDMA8W8=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_Challenge_button" , "OT8c2V3GBYxsCMO2nHs7+DbKkdHupmjujVexo/jm1us=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_Challenge_highlight" , "utQuQr3NQGeGxfmtc3CC7s86/jTGH3SipAkDrAXVbxY=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_Help1" , "+W/tytQsNLMSqPE3QnC43MgqBsU0H9XNrjk4RHundLA=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_Help2" , "WNPFp01iipCzzArymTAcu4VLz5E+Hcm/bnjMZZ0eQ60=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_LevelNumbers" , "ES369OPOoW1RsrCvYQbKaUt0GF3zXXgUd3ZPnjDWXhc=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_Options1" , "zOkXmvvFsyjLO/nq0Dgl88rTSrJWwBPMp6QiAobyqMw=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_Options2" , "MycGypHA2qhq7cgAk97vlPX1gfxmeXoMxQ0FaKwQpkA=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_Quit1" , "jtBCpgu/bShFN1ykigQtCjLb+U9aABHugP/8ezHmYxU=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_Quit2" , "bbTsQCx08UTWFdM/0csjqYB8rSvCJJm3hZMWSDFmeI4=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_Store" , "6gVEuBsk1/udDoEATm2tgmWMCkdme0+oxngcJAKrmP4=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_StoreHighlight" , "grdusCpWrRqZfBuNB1Dj7bKFzyQk3xFReAqoAEKYFhY=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_Vasebreaker_button" , "s6uGdZuYk0R0xmSa8KsCsZAziQC3F6AWyZaL+vqPi2Y=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_vasebreaker_highlight" , "5iaDwlH8qBI3YyWWjyJ/azvzoOMuThRgYykZeAu55/I=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_WoodSign1" , "EzxodXEKdnZDB+CRtpfAMzlGaoqBoXhO79UprQAErmw=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_WoodSign2" , "vibMNgMtv+f43drQs5FWDYv/WaUn6VC3RVZv0qioywc=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_WoodSign2_press" , "esQplw+1F5GBRJA2KPKbZWTQvPEpQp+d2oyym7Bz2OQ=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_ZenGarden" , "6TrN8Qb2J40RES+YBsBdk9b9A1yy81/+0ZCGSfOqmQM=" }, + { "Localization\\Spanish\\Textures\\Menu\\SelectorScreen_ZenGardenHighlight" , "zr7f1egwQiGj+qJiAM11sWpvRVgGkj1E3q2Tpa6t82Y=" }, + { "Localization\\Spanish\\Textures\\Menu\\SZW" , "zXZkY8n4Xa4BRXd2P7CrPeV/oyoImKa3aHZN0AQxrDA=" }, + { "Localization\\Spanish\\Textures\\Menu\\thanks" , "a38UKni0HkBOxxZOz8YLEuRomcdqRxH+cUxIiZv+57s=" }, + { "Localization\\Spanish\\Textures\\Menu\\travel" , "gyGKFv33M2THt9HsNOGXrzayuTk2O6eW7SpR+gq+6Ac=" }, + { "Localization\\Spanish\\Textures\\Menu\\钥匙经典" , "2x/0/QLjwKGhOFxClKDi+wmB+d0n3/B9Y48pW8Kr/uc=" }, + { "Localization\\Spanish\\Textures\\Particles\\Sproing" , "WtzrUuUsjp/GmOfoHApij3VLMn+Tr5qUZ6GGqqhUyD0=" }, + + { "Localization\\Spanish\\Almanac\\LawnStringsTranslate" , "EyMLq+zINvouAEcKNy8fPEu0YIJ98NSLqpMs1NX/U1Y=" }, + { "Localization\\Spanish\\Almanac\\ZombieStringsTranslate" , "tVcpi3GfFH/0aqsaeCuzszFYi6s1IxzO6Zw7wnB0flU=" }, + { "Localization\\Spanish\\Almanac\\AchievementsTextTranslate" , "9PRacAZIbZjZZfc6/qoAggpiW2yZfKjWY7C4im+a2xg=" }, + + // Portuguese + { "Localization\\Portuguese\\Strings\\translation_regexs" , "rzeZrvBSmqIGxLs/jHRAJycnkaoKthMidVOItF2PrbY=" }, + { "Localization\\Portuguese\\Strings\\translation_strings" , "j+vbHq7c9x5Rarc0yFX5eSQmHHtdXsgRqpCxJ9SGKi4=" }, + + { "Localization\\Portuguese\\Textures\\Game\\FinalWave" , "MK0QFrw4Fco5s9xq+8quKs1Li+SinkQuh2OxfZA4gqo=" }, + { "Localization\\Portuguese\\Textures\\Game\\FlagMeterLevelProgress" , "YnkJry/FceiULgkq9RJleesNqgLp/SeKiE5MJA7Kplk=" }, + { "Localization\\Portuguese\\Textures\\Game\\HugeWave" , "jRqYPyzJm7kTbLeaSosHlGLWoUjF1mWqtVNdwtAcvuY=" }, + { "Localization\\Portuguese\\Textures\\Game\\StartPlant" , "7IkydSAOydpjYX1+LSb+Fpt0M0KRmVcwdvjGgXJYMKg=" }, + { "Localization\\Portuguese\\Textures\\Game\\StartReady" , "xoyag2YhVyujDnM/xAq9Xtym8HGKl/h1GCda1mfM3PM=" }, + { "Localization\\Portuguese\\Textures\\Game\\StartSet" , "92OXIRhqJJhmdtb0W/WMNVi1t5hdEzpiwzfX/7p4vRI=" }, + { "Localization\\Portuguese\\Textures\\Logo\\标题合集" , "Ac0MlmlulBOa2w5peHxP7KhJFPAGObirxua3kWLlstY=" }, + { "Localization\\Portuguese\\Textures\\Menu\\MainMenu" , "LNnYLNOJryrvG5XIO+ObgE3Nohxjo9n07UjaGjfVHSQ=" }, + { "Localization\\Portuguese\\Textures\\Menu\\MainMenutravel" , "ZwjI2ybianrOFPEfrLP/38t6y4QB7D6B8hAfr7fvSQ8=" }, + { "Localization\\Portuguese\\Textures\\Menu\\NewAdv" , "gxMOlYYsojAuEQkjdLIM46dkx4ssCH+ncPdK3QBlAFk=" }, + { "Localization\\Portuguese\\Textures\\Menu\\options_menuback" , "OGZ6SNFo8RbpPqWaO88qCzPm7r8Mv1WzUee9BlZDwFE=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_Adventure_button" , "6yGbPdJMpbrmHUm9VSCVKHQxJ1sy0YgM42EhxRr1FLQ=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_Adventure_highlight" , "rdyOJvSoNOHM6uNuL6ehbayGUaOUE/CWs8ZzbzOCafs=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_Almanac" , "+5i+4oc5FJDlzzC86ewxR6aaGt2pB6snfvsCpJGL3gw=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_AlmanacHighlight" , "NBmzBkLDe+lMK/wxbV3p2L2hhByBUBP8onsYXO8Pxnk=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_Challenges_button" , "mAy8FXDBpR1tsmwAkNvYB+kg8KKZLxmOtVP3d3DWiJ0=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_Challenges_highlight" , "jbM14CqEIK+GnRKoKUna7P78p4c74g8NNPEbp01f0VY=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_Challenge_button" , "TXWmZyG1TjBnem8kcFVv93RfUnYHf8CqV1n5BQyTGLo=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_Challenge_highlight" , "qUrCJfUYlEO32SCoPx89AzteV5hba2xzEjqCcNI2cJo=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_Flower3" , "KQThbd2XxKVgA/b9DE8RKwYoNRGTCvOOlGfIlmdnNFI=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_Help1" , "gJxez2SDkvOvUtS7q3E6xlnQWWWeG28KaXJSG5pqqeg=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_Help2" , "FHAsPhSc3efXrwoZuiN3APOgXJQNf45znFcaoyZ7ZBE=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_LevelNumbers" , "ES369OPOoW1RsrCvYQbKaUt0GF3zXXgUd3ZPnjDWXhc=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_Options1" , "FQKd+uBul2bwIcr6nmNq1N3X25C8MRgjyGBy26OuR3g=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_Options2" , "xZN/+5sa+0b2eDmS7WV2rw/IV6zglPmF9qan62eJHAg=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_Quit1" , "dLesJNU0+2/ep6cJnQBA2iUEgIOtve2ozeK9lBher/8=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_Quit2" , "hvq+IpGRu+1Kvjz7g8797qjUIkMx8q3qcMyvJDnhMP4=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_Store" , "WuaJyUo+GX7vDJ+R+MA6XRKF39j7lNZYOMCy+8wNzYE=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_StoreHighlight" , "bDeLuhI74R/OTEAAqiIkJJfVyywn4s80lTrgGFNTzLA=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_Survival_button" , "mAy8FXDBpR1tsmwAkNvYB+kg8KKZLxmOtVP3d3DWiJ0=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_Survival_highlight" , "jbM14CqEIK+GnRKoKUna7P78p4c74g8NNPEbp01f0VY=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_Vasebreaker_button" , "1mherm3clK7CvLh9GpVqMII32w+w54mKZE7Z9fkkZZo=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_vasebreaker_highlight" , "3PVn0DR/33yNI2bjQnDDSSiFRUI+q+1j5lfk/R6JgxI=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_WoodSign1" , "EqYk1lM+BEqgaAqOJXF2HRPkYTgc9j2iMyjcd7/w/Vg=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_WoodSign2" , "0iGZDDOUZGqqbMV0CNnjMPVNbNXmvyrJlDIkJ0SV2jE=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_WoodSign2_press" , "r2YuP2O+mEVhGmapNpFRX8NTx1uY43oaU7kgZyzUhok=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_ZenGarden" , "Ga88gKhsCeLtSoTYheuB6aPx5s34u9SqicGbLI/G6Ng=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SelectorScreen_ZenGardenHighlight" , "0xCUMxGOkVjkgU+fzmlzzSzC+acBGxKhmMjXT+idOk0=" }, + { "Localization\\Portuguese\\Textures\\Menu\\SZW" , "UVGfrlWecM6jEtNJPqjZ+zI66w3euAdOMNl1EPfKpxo=" }, + { "Localization\\Portuguese\\Textures\\Menu\\thanks" , "eHFnd+JUF/r6YRbpTtjmbs6Pywp92asO6TD/rLmO6Eg=" }, + { "Localization\\Portuguese\\Textures\\Menu\\travel" , "qmw+h5LBEWpIGaSe3HZF0XYUScF2VnGQxKWoD4cR2Pw=" }, + { "Localization\\Portuguese\\Textures\\Menu\\钥匙经典" , "g1DKaF3XxYSuiROmemzDz5C2cUcAQ7jPzuoV+nbC/Tw=" }, + { "Localization\\Portuguese\\Textures\\Particles\\Doom" , "FqBUBeIvzyyXL+cqO4Fi6CKI5gZW5QXfHYPTOYoeteM=" }, + { "Localization\\Portuguese\\Textures\\Particles\\ExplosionPowie" , "PHe2TsElYp9UvabT8sxF38JZc+4Hiz78HJyqH/Tzt3M=" }, + { "Localization\\Portuguese\\Textures\\Particles\\ExplosionSpudow" , "Hc/nhkiBIHrZzgdX8+zPYBVoGgNj8177Eqn/S/CvhUs=" }, + { "Localization\\Portuguese\\Textures\\Particles\\guang" , "zpzEG5fPPVYI3tf4DXE0hu3j5BlwIPSAKgcbpr/0wlw=" }, + { "Localization\\Portuguese\\Textures\\Particles\\Sproing" , "WtzrUuUsjp/GmOfoHApij3VLMn+Tr5qUZ6GGqqhUyD0=" }, + { "Localization\\Portuguese\\Textures\\Particles\\SunExplosionPowie" , "Cx5JShdk8H2FKNujBTOylSR0708YuufHqWUZiV+sG6c=" }, + + { "Localization\\Portuguese\\Almanac\\LawnStringsTranslate" , "WilEedYB6brtG2gExyru8VCIPjYiH8KOvCZ3dXkSaUc=" }, + { "Localization\\Portuguese\\Almanac\\ZombieStringsTranslate" , "ihC0adgxNlZjMrbLFMrYbprM2fY5Po4GfxaGvLJiDaU=" }, + { "Localization\\Portuguese\\Almanac\\AchievementsTextTranslate" , "2gd4zJcz6giTsKjIyjIca3DkWOipeedtbQpX26AJnkE=" }, + + // Javanese + { "Localization\\Javanese\\Strings\\translation_regexs" , "ci3jGT0t5FHqstahiDanSlnoXjHtfNLKD1JV2ZmbARQ=" }, + { "Localization\\Javanese\\Strings\\translation_strings" , "r84OFD0SmodV4abyygiyDmwPcfDZTPPvZ5XA+sYHAIA=" }, + { "Localization\\Javanese\\Textures\\Game\\FinalWave" , "ZuqUOUgNV8tNZ0vzyn0ME2VOYbD1TuksAP900r94QP8=" }, + { "Localization\\Javanese\\Textures\\Game\\FlagMeterLevelProgress" , "bZUyDcbcLtz+uG7pnXncJEgBQn6dkE0HUuO0py5Qqtg=" }, + { "Localization\\Javanese\\Textures\\Game\\HugeWave" , "yNfz9nK3LRYy307H6xe9fbIkBM1WryMNkpUpX/AjaY8=" }, + { "Localization\\Javanese\\Textures\\Game\\StartPlant" , "vx2ZKMq6MPzgi/wQkTCHS3q2MKGfDSV/nR0Y6wcV1RM=" }, + { "Localization\\Javanese\\Textures\\Game\\StartReady" , "U/G1MHSRD5N3XYuLz4aj5DAnj2OSIL7lTLSakoTd8o8=" }, + { "Localization\\Javanese\\Textures\\Game\\StartSet" , "uX5YiWkb7Fh5TmEJAyj5llaUEPIv8HoIgtLhQ4cenMo=" }, + { "Localization\\Javanese\\Textures\\Logo\\标题合集" , "uAh1wGHTmqL+eelty5vhYB6aeXxyt0j4PMXgyDsWg6c=" }, + { "Localization\\Javanese\\Textures\\Menu\\MainMenu" , "OZ1gfSCjvhys6N8eeM0OZKX/z/FDLtX6HW3MA/UqgLs=" }, + { "Localization\\Javanese\\Textures\\Menu\\MainMenutravel" , "V7dmKMS/Ta7LUobEgFudX3hVXCs8GBulEYJUIkvn+do=" }, + { "Localization\\Javanese\\Textures\\Menu\\NewAdv" , "y9AUQwwNxsOnkPM5LY5DT80cQ/X6WmNsGmzzo1VZdyY=" }, + { "Localization\\Javanese\\Textures\\Menu\\options_menuback" , "OGZ6SNFo8RbpPqWaO88qCzPm7r8Mv1WzUee9BlZDwFE=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_Adventure_button" , "5nPBRgfdFD0RWQ8j26FXzQBN630hSr+VRyKXr/9ALAM=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_Adventure_highlight" , "39n+opclWXQEDzKDrsg2r0B5ZtCx7eMcryp13eJvZ1A=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_Almanac" , "MAucz/pmIdNnun4hLfp0PDrjESlsAZ/iL49NCYl6feQ=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_AlmanacHighlight" , "Fea3OWEPntAYCFCP1DK0lrqQByQTQJ7TNWhS1wRfk3I=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_Challenges_button" , "xdoeNs/98lT4BKon8Bcwk7m1S+fGbLeHgZISD9qVt1A=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_Challenges_highlight" , "91z8WbCI7XptpUtaN7mJ1BWz+0JNRMYNbDcoxzb7YhA=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_Challenge_button" , "6W1spOrj4FB/SgOb8851XRMAnXoudOjNyl6z4Egw/rs=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_Challenge_highlight" , "2MhlockgUB7+YVxv096GrbPItf5IVWtuAiv/o65Dx3E=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_Help1" , "TrxevH4mjIf4iCFdUXk/Skwq7Asg1dxteTGzqOjQk6o=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_Help2" , "s8i2Ca+iB8CGihGdlzqFxZ8PYO7tdm4ODH3GiSqIyMA=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_Options1" , "JmwncgGiBynAVjnGkPd0EKXh+MYkUhbpy7H90MYnfTE=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_Options2" , "FBzi7WpQje1t1uadDIjcDCwVe994I+ICfmdx96NqrM4=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_Quit1" , "N4yS6t5+p52vU93MbHeLgFik9uureOGgJFL8G4FwKho=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_Quit2" , "NPtds1JqdvoLtHiAYxzyeM4RyvcrcYLu1HMSnO3252g=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_StartAdventure_Button1" , "fIaIRMLy8g56ifWSPZmKH6CCQLia550aovyHGJIRUBQ=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_StartAdventure_Highlight" , "n0+5ijqYlRWC/3l2JSqtZPnMDbFp7TLSeZefohaEqg8=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_Store" , "6JxQIrwb++ekCR47/hQKyahxmMt0ntFDa8A6qETcs3M=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_StoreHighlight" , "8SnyShbhGdphCX4dqfWjuoQIZvlnpDsT7a9mrS6RLEs=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_Survival_button" , "/mMMNvV2V0X7oSVyKWhLryEO7Bo+eCgDiHozjd4I3/I=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_Survival_highlight" , "pNX/YY+qV9RmVt2dcXLTZ+magOEhQNxtxYCUQ4a+S4A=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_Vasebreaker_button" , "IlFeFIlDFW5QAMWwRrgwt9kvStq7pJXNYnWfa3o3zmo=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_vasebreaker_highlight" , "aHyZVtF7SxvC8i5Cvj6eARj4+YrB64TZ5njk9whfdgk=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_WoodSign1" , "aJ7MmKsDxiIuExTTP+b26x548jJC9PR2l5An3/Xdlv4=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_WoodSign2" , "5G3x/AWLBZY10RKKdlll4yD9YFzTNqke1GJuTQk0nCo=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_WoodSign2_press" , "S6vvweA+KTaP0m90S3lu8oitt0/kfc/XasW740bkeGs=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_ZenGarden" , "kgnex+VH/1wjfCM0gLUPRQ16Nb/jeBOBwz7Uz+tBrKU=" }, + { "Localization\\Javanese\\Textures\\Menu\\SelectorScreen_ZenGardenHighlight" , "cHufQXgZze8hFwdw5M1gzd/kgtMrFQGIaforUAQeVUk=" }, + { "Localization\\Javanese\\Textures\\Menu\\SZW" , "kJM+ICVWg9rIbVDkhX63KdViIjnVYH4IGC8rqvmnAQI=" }, + { "Localization\\Javanese\\Textures\\Menu\\thanks" , "UPSssI3shIEOMFKQKhRALT2SHpmBTMgHmxpBbRJmPIM=" }, + { "Localization\\Javanese\\Textures\\Menu\\travel" , "s0AOJiMph12ZnPEYyXZ66EbfBHl8xlwhHh70nlW3kkU=" }, + { "Localization\\Javanese\\Textures\\Menu\\钥匙经典" , "5VCHANL1SD1xv+QsPdIDIGeq1Ksw2Q0O9Z5fH1ilCBE=" }, + { "Localization\\Javanese\\Textures\\Particles\\Doom" , "OE2mWsoMv7SEqRWQJWzJ+A/5gQXeRtogIph28cHJyLI=" }, + { "Localization\\Javanese\\Textures\\Particles\\ExplosionPowie" , "P2jrh7tf2d/9EWHoMScwpkpm9ZSvd+ZACEJqSzen7lw=" }, + { "Localization\\Javanese\\Textures\\Particles\\ExplosionSpudow" , "PXVMwcdcn2pL3mN7O3JEMFvI78XGb/POvZ3Sh26bbOw=" }, + { "Localization\\Javanese\\Textures\\Particles\\guang" , "fWG+wb2CZqaSsaLhiscKXHpqWiyG7Z2qXtHhBzumlSU=" }, + { "Localization\\Javanese\\Textures\\Particles\\Sproing" , "+CRy8k+5wzAdG5wVPM3sTYny3hCmPURD42qnTOIv898=" }, + { "Localization\\Javanese\\Textures\\Particles\\SunExplosionPowie" , "ifNQQNn0abUE11stJvwS5wZQm2Y9kPhQx7bXtF0EnCs=" }, + + { "Localization\\Javanese\\Almanac\\LawnStringsTranslate" , "5JgLhxOJA5v4dmZIlUuj5IhDJAijMQov7xNm4mhcKTw=" }, + { "Localization\\Javanese\\Almanac\\ZombieStringsTranslate" , "XpsMKQ0tZON0zeC0NAjZZqC/4SgSBFieYpDBMit2WFo=" }, + { "Localization\\Javanese\\Almanac\\AchievementsTextTranslate" , "g+5/ND/fdGs4fX7mX88GFp1vdI5lAicu4UcOhjLWoO8=" }, + + // Vietnamese + { "Localization\\Vietnamese\\Strings\\translation_regexs" , "jkmDo2/shz/L1entNc/VMTHSwITTe1lDSWkXwu21HY0=" }, + { "Localization\\Vietnamese\\Strings\\translation_strings" , "DEcePF0ruVJLmtTWVL6cgpg6R14ha8loB7E1sEf6r1M=" }, + + { "Localization\\Vietnamese\\Textures\\Game\\FinalWave" , "Ut9Z9amTQgL3Pdcza22zTjKANBKZ9iGQGwuiV9yia90=" }, + { "Localization\\Vietnamese\\Textures\\Game\\FlagMeterLevelProgress" , "4pMjKlDTK/eLQtYWZy1yjgAsDizgOQLZZcA6lYdDbqA=" }, + { "Localization\\Vietnamese\\Textures\\Game\\StartPlant" , "Vu7L6nDEl62NmhpQF+79hPc/Os3iJogr1N3DGUPv/Nw=" }, + { "Localization\\Vietnamese\\Textures\\Game\\StartReady" , "z3YlFfGkneA4LSSqqtlpnwNLJq3h7gwtl1ZvcxdgUxE=" }, + { "Localization\\Vietnamese\\Textures\\Game\\StartSet" , "snzA81WMzGmssVb862bG95eMRmDGn8t3tBEtj0M/OL4=" }, + { "Localization\\Vietnamese\\Textures\\Logo\\标题合集" , "xqL8p6JTWYSMJmWxxOsA6ToA9bdeA1PrFSWsfarm2uw=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\NewAdv" , "HgyAiO6/YX6jfqzcfW08m/EeXqFRsaGQlIv09U3kHyM=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\options_menuback" , "OGZ6SNFo8RbpPqWaO88qCzPm7r8Mv1WzUee9BlZDwFE=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\SelectorScreen_Adventure_button" , "vkeO+XAUZURjHfog5dqM2EWmx4Q/Hkgm2lxKWWuEn84=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\SelectorScreen_Adventure_highlight" , "bmw+kDo75C0h/xHg7U01xvGQqzjHBjgOvYjuZDLdOU8=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\SelectorScreen_Almanac" , "1gsF1/5A/Wwg7X7NmYVvJi3vaavEqbAMDy96vLCElf0=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\SelectorScreen_AlmanacHighlight" , "Euqlx4l5PGWP/VDni40lyo6XONI7UH+jjT9NGbIdaSI=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\SelectorScreen_Challenges_button" , "anKXed+ijHNf2PnlyRHOdnPNHujFsjwehPuS096dDS8=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\SelectorScreen_Challenges_highlight" , "Fva/m+l9o97nj/niIO3eXfVP+I9hCK+Mhm0nrB/ZgBw=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\SelectorScreen_Challenge_button" , "wSZkmGAeFCCEj0US6ZJaJACCwRuj6Tj5JNirlbkmCcc=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\SelectorScreen_Challenge_highlight" , "NFH6cDojgh8QeUFF9EMBi+yBVCj2Pi20Up1qQH3EycU=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\SelectorScreen_Help1" , "Y3CrU9B+tdD80MgmCUoWmpvmByahXIvI5tzUjPZZlQ4=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\SelectorScreen_Help2" , "lYbzNUtHudgFvpoEaIQZ420RBmFJmxjrwNmVrq1V1KA=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\SelectorScreen_Options1" , "PmdPi4VkTI/Dlal5s82jQ3xay2F9xA5n5pfcz0ad4bk=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\SelectorScreen_Options2" , "31itkFsIYHeaNMjwiHXiOkeC4pA4onVejVbvMR9dhS4=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\SelectorScreen_Quit1" , "AuhF4Z+C9UE6huKECVBDMRSs1sUEOCsX2yJRPFJ19do=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\SelectorScreen_Quit2" , "JsbRYVZk+KV1870Nt8rlWb6Le2YLKXU8Gc8NXMCfg3o=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\SelectorScreen_Vasebreaker_button" , "GXlUgJI9mP+YYqwBU/e+0LeFh9VsCgRLepK3yYLd5JA=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\SelectorScreen_vasebreaker_highlight" , "U5t2Fhn17ahAzH7h+nkgpEpEVf7qBBoGfHd3d9tYnVY=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\SelectorScreen_WoodSign1" , "2xGQ6lS/KxIwjmv3iu5cWBPGucSLBqcT7bdp8KCDC80=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\SelectorScreen_WoodSign2" , "nMB8AT0nDCBG0aHPxmTKIvVNMvhVm8wli2zU22edZR8=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\SelectorScreen_WoodSign2_press" , "QhWvlqpFpjF0GYW3LTRaF7hjogvFH0CjtIGZNS1Q0rc=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\SelectorScreen_ZenGarden" , "2PjsUHvJWhcAdG/Wq6xydshRL0ufXkj61IQ1QBnAcjo=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\SelectorScreen_ZenGardenHighlight" , "xQ3G4RgOY+/pR4ZjmPkY92Ei/qURxbSmXF3dEGpkuYU=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\SZW" , "0Rfvp6ZzoeqC0CN53g7VD1VjqTNY6pRbZyfJhPk16s8=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\thanks" , "9+56vhTLNddtzyzVQfaKvf7pUwBwQQYYleVVh8j2P2Q=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\travel" , "Vz1TbErS6YBlJK3xGVltUi+M2wLINDwv675IfMYK774=" }, + { "Localization\\Vietnamese\\Textures\\Menu\\钥匙经典" , "3vVVP4TSpnN+GhcKIorkVC6NiSXU90gQUhUFkp5JV9k=" }, + { "Localization\\Vietnamese\\Textures\\Particles\\Doom" , "wGdj1YC7DgQ9gO+0qOUM3GvWkZvmSmFcdZPRuC0xWg4=" }, + { "Localization\\Vietnamese\\Textures\\Particles\\ExplosionPowie" , "NLVTBUV+qnJSN8iDyN0/X5mCLuMf/gNf0eqQSNgyR/4=" }, + { "Localization\\Vietnamese\\Textures\\Particles\\ExplosionSpudow" , "87XKk/0oU6tGGyCe1/2KzBHucjYc6fpEl6C5MQGz1bI=" }, + { "Localization\\Vietnamese\\Textures\\Particles\\guang" , "4hMjrrMrOOkLgHlLzuIieJGzwy/SzmY/JI6KDKxA9EU=" }, + { "Localization\\Vietnamese\\Textures\\Particles\\Sproing" , "Kt9TlS9eDVObwbNh9iy00bB5WjXufKPZv7i+mxUG9mw=" }, + { "Localization\\Vietnamese\\Textures\\Particles\\SunExplosionPowie" , "DGdHTnCA+6ovq0sE5TwBEayKAuF5cb+MEOv8xX5hmFU=" }, + + { "Localization\\Vietnamese\\Almanac\\LawnStringsTranslate" , "CM3FWxA/MKhudP9bRjsTNY0ozLJ1K0nOVs/awEvOrnA=" }, + { "Localization\\Vietnamese\\Almanac\\ZombieStringsTranslate" , "yFHjQbsTxaw621AXaHzJLDulElVB1YlKI+nUxvjJuus=" }, + { "Localization\\Vietnamese\\Almanac\\AchievementsTextTranslate" , "Pyeukawk/N5uiUBKDs/erVzIzA+uqZZhtP2amyCKKdY=" }, + + // Indonesian + { "Localization\\Indonesian\\Strings\\translation_regexs" , "4hmtjqn06LLDtClO8mlg13blxXj1hPwWdaSjygj7/2I=" }, + { "Localization\\Indonesian\\Strings\\translation_strings" , "qc4bxqtaJeZBI6nxL4jnf+VpQu/xpJKs/89IYfDcNC8=" }, + { "Localization\\Indonesian\\Textures\\Game\\FinalWave" , "EKjMvK+krWb8AEnvhL02z4ETUR4GEbtEspU8xTL0XJY=" }, + { "Localization\\Indonesian\\Textures\\Game\\FlagMeterLevelProgress" , "bZUyDcbcLtz+uG7pnXncJEgBQn6dkE0HUuO0py5Qqtg=" }, + { "Localization\\Indonesian\\Textures\\Game\\HugeWave" , "kHSyCA4DjKiacui1Z2Vij0VSKr3UqI7FeiZp6MiYeRI=" }, + { "Localization\\Indonesian\\Textures\\Game\\StartPlant" , "lraovY3Nx09xinbn9lF3g5OQPBmBzwkCS9EX3PeKrKA=" }, + { "Localization\\Indonesian\\Textures\\Game\\StartReady" , "WwJG+GIHjqZ/3PWlt7MmATmn8gegir5JdWLHSDOyONk=" }, + { "Localization\\Indonesian\\Textures\\Game\\StartSet" , "wnAy+G4MWwVp11UL9OovumPhS+bFoIw188yt7djqd5o=" }, + { "Localization\\Indonesian\\Textures\\Logo\\标题合集" , "i+dOUq/gv+NF4PbSsElYnsoi8WnrHFgTMCA+lEXwH9E=" }, + { "Localization\\Indonesian\\Textures\\Menu\\FlagMeterLevelProgress" , "CzuBH4sm7Nid4zloZF3i0bpNcA9ILPhrmOxVYI4IggA=" }, + { "Localization\\Indonesian\\Textures\\Menu\\MainMenu" , "OZ1gfSCjvhys6N8eeM0OZKX/z/FDLtX6HW3MA/UqgLs=" }, + { "Localization\\Indonesian\\Textures\\Menu\\MainMenutravel" , "V7dmKMS/Ta7LUobEgFudX3hVXCs8GBulEYJUIkvn+do=" }, + { "Localization\\Indonesian\\Textures\\Menu\\NewAdv" , "y9AUQwwNxsOnkPM5LY5DT80cQ/X6WmNsGmzzo1VZdyY=" }, + { "Localization\\Indonesian\\Textures\\Menu\\options_menuback" , "OGZ6SNFo8RbpPqWaO88qCzPm7r8Mv1WzUee9BlZDwFE=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_Adventure_button" , "IZnCr7uu/muNeugOXMVymHMd5wJ+nfANiohpPnXKleo=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_Adventure_highlight" , "qiAu0iMOKYUs9XDLgZ7LgVd+KiR0Xn0t0jtVNmjl2Yw=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_Almanac" , "MAucz/pmIdNnun4hLfp0PDrjESlsAZ/iL49NCYl6feQ=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_AlmanacHighlight" , "Fea3OWEPntAYCFCP1DK0lrqQByQTQJ7TNWhS1wRfk3I=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_Challenges_button" , "BTltkx67dDWnRIL/TaXUKcUYiQFT01zF0IicWldAV+E=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_Challenges_highlight" , "GCd2qh/rfLbLserDnSzPekRvxIS6W9q+FeNWfkEqTcg=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_Challenge_button" , "6W1spOrj4FB/SgOb8851XRMAnXoudOjNyl6z4Egw/rs=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_Challenge_highlight" , "2MhlockgUB7+YVxv096GrbPItf5IVWtuAiv/o65Dx3E=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_Help1" , "F3na7RpFGvO8bF5lvQbvJanJQmUqPEO5+vkKo4Cx220=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_Help2" , "imagpCvSovqC6SkeR3BAJqH1u9ssin0C6jwIhx0wGpc=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_Options1" , "DMwpZW09/p4CFkgsAqMPExEXzQYOb1TAWKURN4LOYc4=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_Options2" , "s6wcmSMPErvL/4QuRE7ZYWtCg6Nl6A3FeVL1pK8cOrQ=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_Quit1" , "fNNNbsaNEYP3bl3KwlypWIDZNCpm4wVDYUDsjzBw1zU=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_Quit2" , "Qm2506IHHfwXKMkqS3gS39hjjZnV3AP2IHJlOrhYpCI=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_Store" , "6gVEuBsk1/udDoEATm2tgmWMCkdme0+oxngcJAKrmP4=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_StoreHighlight" , "grdusCpWrRqZfBuNB1Dj7bKFzyQk3xFReAqoAEKYFhY=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_Survival_button" , "0DWLUXJ5RYKci+loCThNfHEpk7tKV08vifffcK8owNg=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_Survival_highlight" , "AXW4pkVR9twu7/SJYvqScPeNswIoefGCBJXDf7SsXFA=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_Vasebreaker_button" , "Q24q+w0RftOK+HcQTDvjG5xDpIEYMdecJyGTNGoh9+U=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_vasebreaker_highlight" , "S2IYcVmWghuxAVeaV67EnZ1ZjxyLuEmqLRhknUAQ9dQ=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_WoodSign1" , "aJ7MmKsDxiIuExTTP+b26x548jJC9PR2l5An3/Xdlv4=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_WoodSign2" , "h5NWhUBnM+ro6J6xs7UDPEmT6055qZP49ppF4wIxePw=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_WoodSign2_press" , "tu3PiZyJK6CcwaV78aQpqXcE5aLaHA9rPpgzMAbcEAk=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_ZenGarden" , "MAMBtit0msOsty3zZ1yczih8NsF+4nA7fw7BkYMjCk0=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SelectorScreen_ZenGardenHighlight" , "B17BIhLDvt00Opiag4nqg9a6SvClVr3LlCjzMLI00iY=" }, + { "Localization\\Indonesian\\Textures\\Menu\\SZW" , "OWT6LXWuE7Tr3nH6wYMuUfh1+K9y4TRqtb570pm7veU=" }, + { "Localization\\Indonesian\\Textures\\Menu\\thanks" , "APJpvesl3m2b09ru53RG0MJWcbpia+teT/SnPrnO55E=" }, + { "Localization\\Indonesian\\Textures\\Menu\\travel" , "YP1AGn+G7iYrZ5NQy08TbVxMjFfH7HzdyAMJtwEQ5L4=" }, + { "Localization\\Indonesian\\Textures\\Menu\\钥匙经典" , "5VCHANL1SD1xv+QsPdIDIGeq1Ksw2Q0O9Z5fH1ilCBE=" }, + { "Localization\\Indonesian\\Textures\\Particles\\Doom" , "8vtJfi6ngoltUJQbyCLvp0RnoRZbbVN+piV6lwR8KgU=" }, + { "Localization\\Indonesian\\Textures\\Particles\\ExplosionPowie" , "mmL5xtnIBT3ffswqXHMiz0rXmbj85rCmiWGNnzQq1oM=" }, + { "Localization\\Indonesian\\Textures\\Particles\\ExplosionSpudow" , "PXVMwcdcn2pL3mN7O3JEMFvI78XGb/POvZ3Sh26bbOw=" }, + { "Localization\\Indonesian\\Textures\\Particles\\guang" , "fWG+wb2CZqaSsaLhiscKXHpqWiyG7Z2qXtHhBzumlSU=" }, + { "Localization\\Indonesian\\Textures\\Particles\\Sproing" , "+CRy8k+5wzAdG5wVPM3sTYny3hCmPURD42qnTOIv898=" }, + { "Localization\\Indonesian\\Textures\\Particles\\SunExplosionPowie" , "ifNQQNn0abUE11stJvwS5wZQm2Y9kPhQx7bXtF0EnCs=" }, + + { "Localization\\Indonesian\\Almanac\\LawnStringsTranslate" , "E/P7S2V3xWCnG/DZfW8shpV1ieJUvPf07U/TyJ9LPok=" }, + { "Localization\\Indonesian\\Almanac\\ZombieStringsTranslate" , "twHrylFgPp+RBQ6l10+QHIxgs/mI7p8lRC9etNsAKSU=" }, + { "Localization\\Indonesian\\Almanac\\AchievementsTextTranslate" , "eRZlZgKN2EtZV9BWYOPHPZHBuhLiHzYC3f/wDcwFnR4=" }, + + // Russian + { "Localization\\Russian\\Strings\\translation_regexs" , "6ASIdaFZLLTSdckI4evzynZY3CtCfTuG/BS0ENft/9I=" }, + { "Localization\\Russian\\Strings\\translation_strings" , "mRs9Kx+QyCO5PUScMWyr1P1f3cIMscK0pWjVP4iinL8=" }, + + { "Localization\\Russian\\Textures\\Game\\FinalWave" , "IOhfHr8EBtJYfpWWtELBUtmJNoxv1TdBFrhEfFPshVc=" }, + { "Localization\\Russian\\Textures\\Game\\FlagMeterLevelProgress" , "bGKyk8MpfsaYt95/NQ8kboA0Uxt6ay5PoL0l0RHZ/+M=" }, + { "Localization\\Russian\\Textures\\Game\\HugeWave" , "w1dq1brhzL0eGwj9GJS0vQZDgYVbWjDxRBx60xToKBc=" }, + { "Localization\\Russian\\Textures\\Game\\StartPlant" , "PIOtRaWW0ZdFMNBgyA3Ca4H4rMSLMvfXFvaY/ZZ/oEo=" }, + { "Localization\\Russian\\Textures\\Game\\StartReady" , "zUT1GiCxMDAPlxCyuYPmmztGxDCVdtjiB7C2+Qffpkg=" }, + { "Localization\\Russian\\Textures\\Game\\StartSet" , "ut3aHNTGhzVBNlvHTFIuyj+6SED8Pu9rOpIWKI0V8MQ=" }, + { "Localization\\Russian\\Textures\\Logo\\标题合集" , "qocM9muRdJBmjrs9yTHTknMLWX27aPY7AdMMdLIzd7c=" }, + { "Localization\\Russian\\Textures\\Menu\\NewAdv" , "PIDRlOMsgrLxpp51rWt//B2cBdmNKKEYTvuMUN0wFvI=" }, + { "Localization\\Russian\\Textures\\Menu\\options_menuback" , "HZfWszRsYXntilq2RRoQg6cYPNF7Api0ppAHYJ46wy4=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_Adventure_button" , "UGbQ44kL1zXnsJcAr4vrZZu0hDSTEbtdKM2shtebg4w=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_Adventure_highlight" , "drv1AX+e4D/mA+1IqymPQ5RllTfRatuI+a2/2YJD+GE=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_Almanac" , "BdotPdigckPxfrORVW5EJucskfLdK06icpH+Q8mS9fs=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_AlmanacHighlight" , "XoTbNX+410xOdf6MX3BZiVlzD3MsWaqpF8KXZyxduXo=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_Challenges_button" , "pcno2qw/DBMHX3VzGUHErYSAiQyGWseDJGjwHWZI//w=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_Challenges_highlight" , "Bi5w/0q4C9CpWCjZGLLTHQek530srsp0/Kom4W29IG8=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_Challenge_button" , "kfAEG09yl5h6dV0vHmPl6o72+Wu3kzvBXtyw62E1puk=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_Challenge_highlight" , "VvP4urY9+U0EPEa19fByOzOX4yKuNzD7eLTuxlEBW2M=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_Help1" , "jFKhKseKeZ+y1b1lLYBqfsM5GRGv6JVUa+Jo8sb9p0I=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_Help2" , "c1xqKGKKyJhznB5vZpT8FkiSD/luKAEOVH7ZSr/rpp8=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_Options1" , "BirUdLzY2B3sedbxZ1eqTwSo/l2UW+obPk+oZhhiSUw=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_Options2" , "SLSw+97otiN10CyE6nX6QqHmiOjQR8aYuBUveZ8Lx9c=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_Quit1" , "B5L16JYjqNJSD5pA9vhEq/C4gzFkz7VYnzcORjOytxA=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_Quit2" , "+7s74lMPYaJu+U+572MRvmOolp33Q5xmu/TMOmRvlZc=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_StartAdventure_Button1" , "f+NFEqcMvJj20nysVA7mlGmFkJZAmmef+Gi8yUvwses=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_StartAdventure_Highlight" , "f+NFEqcMvJj20nysVA7mlGmFkJZAmmef+Gi8yUvwses=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_Store" , "N+M6I8pUzeEaetRaE1Wjh2j4g7a1uwrBnqR+7zbsxxQ=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_StoreHighlight" , "QiFOWjJqdoRZMbXfTuKJwTdm5a3E6vm0rGkXwMaMCYs=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_Vasebreaker_button" , "ta02SAcbm7ErKiwz4vpZzrtuptJComb4X2DAwx8GiJw=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_vasebreaker_highlight" , "28+kPzJUSqm5KKrUlA5GOAy5+q//1bknEniSze/Bb6M=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_WoodSign1" , "8CV21tQ/HxANofuuTatQO1Ul8zXQYwo1rfzU6iozCiU=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_WoodSign2" , "bG6o/CpJPm9XBfWq/m3f1cquTAOr5fbwRNtx7XEPcqg=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_WoodSign2_press" , "v7BbNSzfQIVYLVrYSOIO2i1NbplOiQjYyQcR4rR8OJw=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_ZenGarden" , "WsYKxhTcuqTFT9jbeOne+W3/opToTbzZFnq7uGulJfQ=" }, + { "Localization\\Russian\\Textures\\Menu\\SelectorScreen_ZenGardenHighlight" , "aGRi1WWchHxPisQdbkX9xmsALia6I1jo8JpysSHb4BQ=" }, + { "Localization\\Russian\\Textures\\Menu\\SZW" , "eaqxoi1/FlIyUCfEpJnFgl1xoSwqP1XRHFIaobQzD1A=" }, + { "Localization\\Russian\\Textures\\Menu\\thanks" , "Juq3A9M9V/jScckNECv+JB2U7W+y6YivxELZV/nN3JE=" }, + { "Localization\\Russian\\Textures\\Menu\\travel" , "8lXVCidvQOeh8y9kG7xN51Ch9VyL8ThZah/OI1RxN6c=" }, + { "Localization\\Russian\\Textures\\Menu\\钥匙经典" , "wwcruWy65C8iXjA+SY1dvx/hrSQ/KvVkX4OOOZ6lS/s=" }, + { "Localization\\Russian\\Textures\\Particles\\Doom" , "OWddkj4pnY9xmSIuQIL0vb6F091j8UY2PEC4tZ6P3p8=" }, + { "Localization\\Russian\\Textures\\Particles\\ExplosionPowie" , "KbPmKOHVvOH9njUEBWb6SJPEdGOLbpAG0CpliNyUefA=" }, + { "Localization\\Russian\\Textures\\Particles\\ExplosionSpudow" , "k1C6TaoPE0ZRw79UAjDwlRaLjf4Q/b2N6JM9SN1I5fc=" }, + { "Localization\\Russian\\Textures\\Particles\\guang" , "+Xd4hpZk2VEhgHr9HATWRhjEbg4WlmXkh5DA+gXevIs=" }, + { "Localization\\Russian\\Textures\\Particles\\Sproing" , "i33iY8w5LR7Kdqf2vVQ7UmE9SrWZ+5AGepTy5QINyHE=" }, + { "Localization\\Russian\\Textures\\Particles\\SunExplosionPowie" , "BCXJtvwnDvIzc7cFnxN3wxR7t2o1rqa6hulW54PJLrc=" }, + + { "Localization\\Russian\\Almanac\\LawnStringsTranslate" , "NwYjBl+2v0brh38S4AJpHHWDK/1hCJ5VVqY+Cf5jYkU=" }, + { "Localization\\Russian\\Almanac\\ZombieStringsTranslate" , "ejVysCnTehbMFkjAXN7n7NqWespRHmv5cXYM0hMlK0U=" }, + { "Localization\\Russian\\Almanac\\AchievementsTextTranslate" , "ST45TjReYXrBOfT3r2YeDakJm1SN/jtH/5z0Qp6Ms4c=" }, + + // Japanese + { "Localization\\Japanese\\Strings\\translation_regexs" , "YXerYuvclj9na6pQOefuVfJVER28OAb2EkG/kMLqrGQ=" }, + { "Localization\\Japanese\\Strings\\translation_strings" , "hXi0RiHTbzptiAHqko0CRwDDWW9zoRSdQpOXpd4U3BI=" }, + + { "Localization\\Japanese\\Textures\\Game\\FinalWave" , "tyOrI4m+7b595JZufjhesTYXqiSWuNg4Dlm0fN/ZzVg=" }, + { "Localization\\Japanese\\Textures\\Game\\FlagMeterLevelProgress" , "J8Gnugo3MCdQCFNaw91nOWKiYEJltD7EpScPvgJjVdQ=" }, + { "Localization\\Japanese\\Textures\\Game\\StartPlant" , "8+rIjUEkUtyYRsu9ZHsM6B26fT87U6BYHtjhef+sZSc=" }, + { "Localization\\Japanese\\Textures\\Game\\StartReady" , "G0wx/YkdgSZju5xUluqrq554u7ywOGxRPjQwfEEHwSo=" }, + { "Localization\\Japanese\\Textures\\Game\\StartSet" , "4jSRsYZN+mA3pMZQtjtxxo7z8PYpjyM4Ja1coeOERmQ=" }, + { "Localization\\Japanese\\Textures\\Menu\\NewAdv" , "9CgysaFPLkL+h3CB5zLiUxj7Z7xSZCTQKFr/pAvjW4I=" }, + { "Localization\\Japanese\\Textures\\Menu\\options_menuback" , "KcUX62UuqoR0UKas1yijEQP56fWbagBIpSwFIr4df+k=" }, + { "Localization\\Japanese\\Textures\\Menu\\SelectorScreen_Adventure_button" , "nqJjYCKTGCWuIHwSSRDpsJkPK7quA/4UgfX+EZsadsI=" }, + { "Localization\\Japanese\\Textures\\Menu\\SelectorScreen_Adventure_highlight" , "/oarc88nswGdHzRI7+ol5XUH8pqEudTJ/l4mtWr6ugw=" }, + { "Localization\\Japanese\\Textures\\Menu\\SelectorScreen_Almanac" , "GsHU22IdE1GMx+6eDcJoQ/+LJDJwLG3sovrPion7/68=" }, + { "Localization\\Japanese\\Textures\\Menu\\SelectorScreen_AlmanacHighlight" , "7aHSIocT5JbGVTh7addi0+WrON9G6LPv2xmuDy/tPRg=" }, + { "Localization\\Japanese\\Textures\\Menu\\SelectorScreen_Challenges_button" , "ljfdR00zwozWSwI85JwzGAGQgjXL1sCNpr/+juvcx0M=" }, + { "Localization\\Japanese\\Textures\\Menu\\SelectorScreen_Challenges_highlight" , "hkii/10+OmfcVLNOB3ATpI5iHpPhw7mgiVRAs+kDsHc=" }, + { "Localization\\Japanese\\Textures\\Menu\\SelectorScreen_Challenge_button" , "tf/14faCSFk7b9vFFn64FAAUpLGZVmfInI4K0Qmx9aM=" }, + { "Localization\\Japanese\\Textures\\Menu\\SelectorScreen_Challenge_highlight" , "1ZC0zr0P3WkXzKvZ17YwkLID/6YYdTx9PZQimMSos6o=" }, + { "Localization\\Japanese\\Textures\\Menu\\SelectorScreen_Help1" , "8OR4iqxkdQ3PsxbobY+JaN/w0lXNc2A+Kbec/VJ/QVY=" }, + { "Localization\\Japanese\\Textures\\Menu\\SelectorScreen_Help2" , "i60mg9eK5WzjUA0iZfQtvDWq7HImRV14xNqfLzFmELo=" }, + { "Localization\\Japanese\\Textures\\Menu\\SelectorScreen_Options1" , "YJZBgCXj/ZH4F8zPo+t4dAGmGMSiDAcybs2xuu1LTiw=" }, + { "Localization\\Japanese\\Textures\\Menu\\SelectorScreen_Options2" , "yIbcIgBPjVP3JKNiF6dBPdJ90Yd+fKC+99KUjTfHOqQ=" }, + { "Localization\\Japanese\\Textures\\Menu\\SelectorScreen_Quit1" , "hkDaVb8qUDLKPp1MIyGY6x4teZAVev56kjJ7KihPMss=" }, + { "Localization\\Japanese\\Textures\\Menu\\SelectorScreen_Quit2" , "Tx8u8J/YpKF0lEd436EJfOMzXVzSWlsWDHBh5s73MU0=" }, + { "Localization\\Japanese\\Textures\\Menu\\SelectorScreen_Vasebreaker_button" , "hn9D4J0aBhdrM23YNrZJXd2qbQrePLru5gCYBR34xgo=" }, + { "Localization\\Japanese\\Textures\\Menu\\SelectorScreen_vasebreaker_highlight" , "+RQ4US+xJ23ieUzvO3sBzHJBEmCz5wZz7Gv6UmFjtdk=" }, + { "Localization\\Japanese\\Textures\\Menu\\SelectorScreen_WoodSign1" , "78kL8cLZGoQdNcZjPbXFAkhN9A0zyCun8ieAOUvva3k=" }, + { "Localization\\Japanese\\Textures\\Menu\\SelectorScreen_WoodSign2" , "Fkn7CvIOoeB8QrUUtj2HySgUg5ZR+zvry6jythPN2BY=" }, + { "Localization\\Japanese\\Textures\\Menu\\SelectorScreen_WoodSign2_press" , "S2xZmAOn82/7uJ0q5Ej4tc59cheMme02Eb/CBjQjULI=" }, + { "Localization\\Japanese\\Textures\\Menu\\SelectorScreen_ZenGarden" , "AE/8V2mkM15VErDDjg0g497fF4S3GYdSDRi9pDq0S+Q=" }, + { "Localization\\Japanese\\Textures\\Menu\\SelectorScreen_ZenGardenHighlight" , "KiN9KORVPhugq/laYeo+78CNeNW3CEVpVmi2J2WTNT8=" }, + { "Localization\\Japanese\\Textures\\Menu\\SZW" , "4jkQn+T+/oceMqVHefAyo7G/8LQ/3jZuF41rnEaFVy8=" }, + { "Localization\\Japanese\\Textures\\Menu\\thanks" , "aoTr0qV9HPJLz4WImY9FpU6mbB6Jy2WfOeXULgDWdlc=" }, + { "Localization\\Japanese\\Textures\\Menu\\travel" , "MwowpcnQ4BXqoE6I8n2iP6ZzmVSMNaUpyBkPIkaI2hE=" }, + { "Localization\\Japanese\\Textures\\Menu\\钥匙经典" , "FeQQRbKmP9uOZ37BtcHNjWH46zSe1tCrexTrnWcKX50=" }, + { "Localization\\Japanese\\Textures\\Particles\\Doom" , "x/jlt63Ryze1+Dhjm9A1M65LkwrpuN0tTwn6wq7OtPg=" }, + { "Localization\\Japanese\\Textures\\Particles\\ExplosionPowie" , "uEPr3YXyamejZGcJ9QYxkQ6GOnqK3Ddv5HsgBJCIyl0=" }, + { "Localization\\Japanese\\Textures\\Particles\\ExplosionSpudow" , "4wZzRVJGrKmZDuJXuA8O/0mvLJS08DrhfWiRk6Arb/M=" }, + { "Localization\\Japanese\\Textures\\Particles\\Sproing" , "pKet1LadsHBdq8mOR3IOtOngBHyfxdFLp2hipu8I4ZU=" }, + + { "Localization\\Japanese\\Almanac\\LawnStringsTranslate" , "D4riwyc3qc5fWLhnspeXCgCip2cb5k1/t0PlEPJ7wdY=" }, + { "Localization\\Japanese\\Almanac\\ZombieStringsTranslate" , "AzhgHGtIesVnO8aGJnpnY/C8+5eua2Z3wN887spfz7U=" }, + { "Localization\\Japanese\\Almanac\\AchievementsTextTranslate" , "PAk0G69Abd/8mqXxsrg1dChYjb3/Hmgp2UD9fqVnqXw=" }, + + // Korean + { "Localization\\Korean\\Strings\\translation_regexs" , "zWV/cHF92F+GrFwlSkGXyep2jqBDG5LAiGwyDtcG2rU=" }, + { "Localization\\Korean\\Strings\\translation_strings" , "qXdtfjxdZcK4Oe6ptsZd3Vg4rIavfM06ZkmMfmR8G1M=" }, + + { "Localization\\Korean\\Textures\\Game\\FinalWave" , "7I9i/6CVcPOhoL2n3/NUNOedbaIyQqlsj5U+jVQauu4=" }, + { "Localization\\Korean\\Textures\\Game\\FlagMeterLevelProgress" , "yMpBQDYecmFimlzSnsO8vdyEPp0Q6O5lAg0DWFS1m6M=" }, + { "Localization\\Korean\\Textures\\Game\\StartPlant" , "yGZNl/ELOvk/XqMp5pIhwrSLkAa/T+2pWcYb/tVC8CY=" }, + { "Localization\\Korean\\Textures\\Game\\StartReady" , "aNTSN8/FwAmu63eHs7wzdoDCnw3h3KWQ4SCiPtBoTdQ=" }, + { "Localization\\Korean\\Textures\\Game\\StartSet" , "PcrGZLSUL2xrPGTMzZJBc/xC05UdlWoCeHP8vNm8BjQ=" }, + { "Localization\\Korean\\Textures\\Menu\\NewAdv" , "LidoBW/vXZhokFRjg8MRy7daY4wehQ9vd3dBLwTsFLU=" }, + { "Localization\\Korean\\Textures\\Menu\\SelectorScreen_Adventure_button" , "XvILct+pOLn9Ke3VvtlZPo4Zpob6wgAaNwb5w1+i3z0=" }, + { "Localization\\Korean\\Textures\\Menu\\SelectorScreen_Adventure_highlight" , "WTyEd+cIWl3fBF1guKAQuMvDdMDwFnsgyZXoklVRTdg=" }, + { "Localization\\Korean\\Textures\\Menu\\SelectorScreen_Almanac" , "7DLBjkU41YWjh6up42n+2DU+UU4jzBcuCyIjoIQhK1E=" }, + { "Localization\\Korean\\Textures\\Menu\\SelectorScreen_AlmanacHighlight" , "1oUnvwRL6Jr+AwwXJKAB/jcmpWl+0UP69js6vIKZ9uY=" }, + { "Localization\\Korean\\Textures\\Menu\\SelectorScreen_Challenges_button" , "qoPxgGKWuHKCg3pEmvkauWfmXFZWR0spWcoK6AvLysc=" }, + { "Localization\\Korean\\Textures\\Menu\\SelectorScreen_Challenges_highlight" , "840p+IAAw8KPwkoNmvcWcOWwhpTzTtcLixzWr+MunS0=" }, + { "Localization\\Korean\\Textures\\Menu\\SelectorScreen_Challenge_button" , "FwlC3AOwWWeiqereusDpkRatqnKKN3c/xq5iPAhVo5Q=" }, + { "Localization\\Korean\\Textures\\Menu\\SelectorScreen_Challenge_highlight" , "RZPSyMMXOr7W5aOWcr5xSR9XiANkWWVk6/OUnxxpUpI=" }, + { "Localization\\Korean\\Textures\\Menu\\SelectorScreen_Help1" , "Akybqv0glw81aMYpGoosQ3PR7Ukhq+cD+ZlEUkLC5Yw=" }, + { "Localization\\Korean\\Textures\\Menu\\SelectorScreen_Help2" , "6RZFnrYjpZM932niXc1qmRtAJm97GlDHzh3Q9c1u5b0=" }, + { "Localization\\Korean\\Textures\\Menu\\SelectorScreen_Options1" , "D7hYM4ZPRbA395EUkLhG4jf7lfJqSUalp7oZJQ9/BEs=" }, + { "Localization\\Korean\\Textures\\Menu\\SelectorScreen_Options2" , "1Z3SHvyiFsK7Wy9I2tFONcVYjF50Ho4L2+CbePFqng8=" }, + { "Localization\\Korean\\Textures\\Menu\\SelectorScreen_Quit1" , "eD9BNRKQU7qei+eAsCSIidMwvwEhuBLPcpZkb/Q/Ag8=" }, + { "Localization\\Korean\\Textures\\Menu\\SelectorScreen_Quit2" , "scNdtWjkMrgtwBdXiS809HfOY+2+ycPqUAgH6RcFOfk=" }, + { "Localization\\Korean\\Textures\\Menu\\SelectorScreen_Vasebreaker_button" , "QPWZp3PBXeJK8y9Pu7euFoRNVsywdr5tCC6gOsKmlL8=" }, + { "Localization\\Korean\\Textures\\Menu\\SelectorScreen_vasebreaker_highlight" , "VGJtLoUZ4+EYlQUMHSOAUFYPwFr30w5/NLyl0G4Ba2Q=" }, + { "Localization\\Korean\\Textures\\Menu\\SelectorScreen_WoodSign1" , "CPf6iaNv3ftvdOMQwm/gJ8hXE/13KeS+GHzEBl6DrpM=" }, + { "Localization\\Korean\\Textures\\Menu\\SelectorScreen_WoodSign2" , "8Lr0ONZOInR+ZHz9ZQHHdr6e4jkARbxkDIm181Q/yWM=" }, + { "Localization\\Korean\\Textures\\Menu\\SelectorScreen_WoodSign2_press" , "8JALSm+TKjNzIAtOd6DXJjkjc0bqEBXhPqlTO6sKZ0c=" }, + { "Localization\\Korean\\Textures\\Menu\\SelectorScreen_ZenGarden" , "b8bJJeKpQJhesrxy3c3JconWq1RJkMwkOBOi1JcKkUA=" }, + { "Localization\\Korean\\Textures\\Menu\\SelectorScreen_ZenGardenHighlight" , "CwZAzOBJFFY9AG2tvPN58JggPNNEws9zEbcgMlsWEpc=" }, + { "Localization\\Korean\\Textures\\Menu\\SZW" , "ONrElpWA/7WkJq833t+slKToiieJtZhbz2dv2QSuQB0=" }, + { "Localization\\Korean\\Textures\\Menu\\thanks" , "HYnZf9x5uNG5tu5jga94X9+rILjt40bnKSR1qjkXF8M=" }, + { "Localization\\Korean\\Textures\\Menu\\travel" , "T/ngmCI6ilQ6k/pV2XZloY5OICc0bbKz0iwg/mcXpPw=" }, + { "Localization\\Korean\\Textures\\Menu\\钥匙经典" , "iO5Z+/6R8Pz1GoIh+TX5KWkCFJsOxfYYrMSV//9UJ34=" }, + { "Localization\\Korean\\Textures\\Particles\\Doom" , "FqBUBeIvzyyXL+cqO4Fi6CKI5gZW5QXfHYPTOYoeteM=" }, + { "Localization\\Korean\\Textures\\Particles\\ExplosionPowie" , "cuikfX+3LOtSw3EPB6DnjANO5bKkoYCMdWSm+StmW70=" }, + { "Localization\\Korean\\Textures\\Particles\\ExplosionSpudow" , "4pJ/gZsuKRsAbUL1YWsaaJC9NxrzhqUiQe6glK07ydU=" }, + { "Localization\\Korean\\Textures\\Particles\\guang" , "kh0dcDxOXgh8+Eq1TmKdJug5PdR+nzZrK5iS5Nkw7Gw=" }, + { "Localization\\Korean\\Textures\\Particles\\Sproing" , "WtzrUuUsjp/GmOfoHApij3VLMn+Tr5qUZ6GGqqhUyD0=" }, + { "Localization\\Korean\\Textures\\Particles\\SunExplosionPowie" , "3bSjOYpanuLnsl58oYUzOAXt94nony6Drq8qdpfRSGQ=" }, + + { "Localization\\Korean\\Almanac\\LawnStringsTranslate" , "KRMiSTM91FoCR9sTGJU6hvsh0+sBMyHfqXwTSSea27M=" }, + { "Localization\\Korean\\Almanac\\ZombieStringsTranslate" , "xHI2LAW0JSEZN010GZPhPB60N0Csfbev2Mk5RwWFYyQ=" }, + { "Localization\\Korean\\Almanac\\AchievementsTextTranslate" , "J4/ZjY7vFNvwsMBx5eIwP7syuLD/+D7OaTY+YbUnq6s=" }, + + // Custom Textures + { "[Custom Textures]\\Almanac_GroundDay" , "ruvrVDVaICj+5PzN5FIcLTma+GtTb2AuKkHA42jTVBw=" }, + { "[Custom Textures]\\Almanac_GroundNight" , "uwrsmHM/IFY1n+AkYYmgEhoWRoaefOjP6sQMCWLtJ2s=" }, + { "[Custom Textures]\\Almanac_GroundNightPool" , "MQrZAvJDWs7k0c8cQjeNp5WNfB1Yns54Wqib63Glhsg=" }, + { "[Custom Textures]\\Almanac_GroundPool" , "fgHaxsX/KUXzAuRTLE7itRtmjPJ8YPo01Sy6Y2O5XWU=" }, + { "[Custom Textures]\\Almanac_PlantCard" , "1Spu2IG3EoCLn0MhAwMxydN2E8xcffFVfnKGk0KowLY=" }, + { "[Custom Textures]\\Almanac_ZombieBack" , "PUxcz+EA7ehsPkyA3gsicvaANh+7vX56yKbrCNFd8cI=" }, + { "[Custom Textures]\\Almanac_ZombieCard" , "S3QeUIrxZ3BJiovEyHBz0AYIoVzT2mQ1JA5hN3Ke8B0=" }, + { "[Custom Textures]\\Almanac_ZombieWindow" , "0JHTUpc1HdZ8/s/4NVKnchFmyrUaXgTgv3kUwS18zKo=" }, + { "[Custom Textures]\\Almanac_ZombieWindow2" , "NA9+T0M/4BihrNsGQVQCyxX2IO8xuyIKCm1PT6aB/vc=" }, + { "[Custom Textures]\\CursorClick" , "cELLXJkEQM+ULhcuL3GXdJ6Lw9iJF0grx3NuSfI3iGE=" }, + { "[Custom Textures]\\CursorDefault" , "AfBSPF65+ZXswrGKH5NRB/b5oa4WR5vuIet3xQ9/hqc=" }, + { "[Custom Textures]\\plant" , "JqOyre0JXBHjvWqUafUaBEfym62ZVhte6sP68TDn4xQ=" }, + { "[Custom Textures]\\SeedChooser_Background" , "RBVMr9F/IJiTVV9G9iZyUQguN6c+fQGb1BUoyuAKbyY=" }, + { "[Custom Textures]\\seedfog" , "l4gO/839bvGY3zk1/JPHPrZiD5sqVq0dCnCflUr/ilQ=" }, + { "[Custom Textures]\\seedp" , "amr82tmtplngahLPlu4wdPlq5adTKqUMXZoZ9qJ6u1U=" }, + { "[Custom Textures]\\SeedPacketSilhouette" , "W6vow+euXzdwjAufkJuRtdaIEiEPmbeeOkOHiQBNmHA=" }, + { "[Custom Textures]\\SeedPacket_Larger" , "+TZxcpkpyz49vmlkTAYyohpQuneLwrw1eJdYpbN6wAs=" }, + { "[Custom Textures]\\SeedPacket_Night" , "0pv9hCIOuoj9wfH2FP18kNwLkYUz0wuxVs3zl3OiHC0=" }, + { "[Custom Textures]\\SeedPacket_Other" , "Y/xlegVxGFn6Dt1nsDAEFSnslM3lyQ6WyCSl7RfwA5k=" }, + { "[Custom Textures]\\SeedPacket_Pool" , "4m5EDn8xfUtrZ/qENCISIRbZVQEjgk9UN1//AelB1Tw=" }, + { "[Custom Textures]\\seedroof" , "z9o/8qUJkgtys4WmPRvCt/wJz056+0Fjvfvk6pHwbLo=" }, + + { "Localization\\Spanish\\Textures\\[Custom Textures]\\CursorClick" , "4sKy7/xqFJqS/HVR1jUgMNvcPQdv6argIePfdcRhoIk=" }, + { "Localization\\Spanish\\Textures\\[Custom Textures]\\CursorDefault" , "zuNjht1GXgF/fOKCnW7KnOOaccjHRDB9m6giJvkKz1Q=" }, + { "Localization\\Spanish\\Textures\\[Custom Textures]\\garden_new" , "siziOyP+M2D5mI5ugtsjNI1O+zKcRqlHBDGrnSU1EV4=" }, + { "Localization\\Spanish\\Textures\\[Custom Textures]\\Present" , "glh2PeOuG8W1jQBiX8Xh0/4owPMGxFFXdOIc2siZ8Uo=" }, + { "Localization\\Spanish\\Textures\\[Custom Textures]\\PresentOpen" , "9DQZ4GIEeqoATt6MA55HEvQrBueZ3FN9raMdqOIhOUI=" }, + { "Localization\\Spanish\\Textures\\[Custom Textures]\\PresentOpenZ" , "BORx+RuCJUu8FLzDqdZcBFKFzMDbKB0KDZIkk4SnEmM=" }, + { "Localization\\Spanish\\Textures\\[Custom Textures]\\PresentZ" , "3VQDMgCU5gz1uGzQzRSatXOHd50q9nHozgkicb9wEQU=" }, + { "Localization\\Spanish\\Textures\\[Custom Textures]\\SeedBank" , "ffJswlQikAaPhUily+jKz59tjUUsysRTyPetub7pVw4=" }, + { "Localization\\Spanish\\Textures\\[Custom Textures]\\SeedChooser_Background" , "Z3jzRdTSxhpLU9HqeYhcDz+CfP1SerwzYteBh2gEX8M=" }, + { "Localization\\Spanish\\Textures\\[Custom Textures]\\seeds" , "Yaqa1lY4mMxmksslr1WjcV3vYAwrcLT6AVVHEvHS6Mw=" }, + { "Localization\\Spanish\\Textures\\[Custom Textures]\\SelectorScreen_Leaf1" , "wAoIJKiNxAuEkhFW9QjUAXCbdQmq0Q5DtztG+1VWjig=" }, + { "Localization\\Spanish\\Textures\\[Custom Textures]\\SelectorScreen_Leaf2" , "hRe+ceHzLid2ltXXaJsfLg3YHkb0xSwvgFh62XqUnpg=" }, + { "Localization\\Spanish\\Textures\\[Custom Textures]\\SelectorScreen_Leaf3" , "sU5tHuXpjZGsDd0I5BMPmsHj0W4flayrCEhr36iudp8=" }, + { "Localization\\Spanish\\Textures\\[Custom Textures]\\SelectorScreen_Leaf4" , "UnezQl5tm4gUZ3DwYCzRM85siS2dZWuo0HHx09fc/LU=" }, + { "Localization\\Spanish\\Textures\\[Custom Textures]\\SelectorScreen_Leaf5" , "a73hDOb3r3gZAgpklCB2EkFjUaUbKJBXKhGT3tYosP0=" }, + { "Localization\\Spanish\\Textures\\[Custom Textures]\\SelectorScreen_Leaves" , "ll3lRI+y441evcV9CJoFufhI5VQeC2eIew9AFSW8xEU=" }, + { "Localization\\Spanish\\Textures\\[Custom Textures]\\ShovelBank" , "DUCNzvvDjIp8Kr8Clyx4eWwApiHiD8RmP+W05Mre+fI=" }, + + { "Localization\\Portuguese\\Textures\\[Custom Textures]\\Almanac_GroundDay" , "HqSlvHQOonZvcid0jFZAj7az/P8uwKXZMT4Ukwyc8j0=" }, + { "Localization\\Portuguese\\Textures\\[Custom Textures]\\Almanac_GroundNight" , "qt947+pENaA91x4lYAYsNLcR6Xd6I1vNh/USyk45arw=" }, + { "Localization\\Portuguese\\Textures\\[Custom Textures]\\Almanac_GroundNightPool" , "A92M4I2N2OfpN/y4R40ATVBrI2U+StgZQjIr0iVCEeU=" }, + { "Localization\\Portuguese\\Textures\\[Custom Textures]\\Almanac_GroundPool" , "AmrvO/C5ggUeHr5+WOh16GWJ0jM1nXR+Vj/A87CRZ3U=" }, + { "Localization\\Portuguese\\Textures\\[Custom Textures]\\Almanac_GroundRoof" , "ftdvDcMiDrdIBIoOTcxU6b9qT+GmPEkH2+tG2HA8blk=" }, + { "Localization\\Portuguese\\Textures\\[Custom Textures]\\Almanac_PlantCard" , "1Spu2IG3EoCLn0MhAwMxydN2E8xcffFVfnKGk0KowLY=" }, + { "Localization\\Portuguese\\Textures\\[Custom Textures]\\Almanac_ZombieBack" , "PUxcz+EA7ehsPkyA3gsicvaANh+7vX56yKbrCNFd8cI=" }, + { "Localization\\Portuguese\\Textures\\[Custom Textures]\\Almanac_ZombieCard" , "S3QeUIrxZ3BJiovEyHBz0AYIoVzT2mQ1JA5hN3Ke8B0=" }, + { "Localization\\Portuguese\\Textures\\[Custom Textures]\\Almanac_ZombieWindow" , "0JHTUpc1HdZ8/s/4NVKnchFmyrUaXgTgv3kUwS18zKo=" }, + { "Localization\\Portuguese\\Textures\\[Custom Textures]\\Almanac_ZombieWindow2" , "NA9+T0M/4BihrNsGQVQCyxX2IO8xuyIKCm1PT6aB/vc=" }, + { "Localization\\Portuguese\\Textures\\[Custom Textures]\\plant" , "Q5VaxJhSrv/z55FH7YmLBovhYV3zLux887J0IdOpwnc=" }, + { "Localization\\Portuguese\\Textures\\[Custom Textures]\\SeedChooser_Background" , "jnVWbr791bRlpO5CYQ5ZC2WPH4d7j8O4ODW41hA88nk=" }, + { "Localization\\Portuguese\\Textures\\[Custom Textures]\\seedfog" , "fyjLtioDqCumbQuOl+4jgUYFqK+cATeOzoNl1qgRttI=" }, + { "Localization\\Portuguese\\Textures\\[Custom Textures]\\seedp" , "8qE/ZB7wdjFq6bNr6jWeCsVhhUD+JWORmpXryejDmjI=" }, + { "Localization\\Portuguese\\Textures\\[Custom Textures]\\SeedPacketSilhouette" , "W6vow+euXzdwjAufkJuRtdaIEiEPmbeeOkOHiQBNmHA=" }, + { "Localization\\Portuguese\\Textures\\[Custom Textures]\\SeedPacket_Larger" , "TtCGi5F02Qx/ix9OXY86bMNjHCdch1E7De9wMTp3JIs=" }, + { "Localization\\Portuguese\\Textures\\[Custom Textures]\\SeedPacket_Night" , "3QSOoNwMue9tK30JgCea/K2pGDlDv+Ibhp0NKRoZHN0=" }, + { "Localization\\Portuguese\\Textures\\[Custom Textures]\\SeedPacket_Other" , "7tjrV9SIzPaSEpMspdF7tKANXMu6ggeuj4XSy/UVACM=" }, + { "Localization\\Portuguese\\Textures\\[Custom Textures]\\SeedPacket_Pool" , "U4zfEwx/0mUqIgUYvuQ10T+tWTqJ54V3RUJiA1+FJts=" }, + { "Localization\\Portuguese\\Textures\\[Custom Textures]\\seedroof" , "1W6A3m32iSQZ5WhJHK11tys1OQOvYLgdNGlUOe7wgnY=" }, + + { "Localization\\Javanese\\Textures\\[Custom Textures]\\Almanac_IndexBack" , "S8wmWen4Za178Mkwwu8DJkKvvB2c2CRJbaRjIW/zvhw=" }, + { "Localization\\Javanese\\Textures\\[Custom Textures]\\Almanac_PlantCard" , "O2UWyplpXK69pTFXYDSA5KiRyKAZ22LCDN71GIb5ZDg=" }, + { "Localization\\Javanese\\Textures\\[Custom Textures]\\Almanac_ZombieBack" , "L91uR40W1iPLqBd+ouENStDe9RN+xUOZtbF048MiD1U=" }, + { "Localization\\Javanese\\Textures\\[Custom Textures]\\Almanac_ZombieCard" , "3QvRtOtCpI6sqh26+Zbr9vTR9RB8oSXy4m7iS2snZUI=" }, + { "Localization\\Javanese\\Textures\\[Custom Textures]\\Almanac_ZombieWindow" , "+LHsQLlwsYWEVS11F+SustquGoxjbGiyrs58XwyeYMw=" }, + { "Localization\\Javanese\\Textures\\[Custom Textures]\\Almanac_ZombieWindow2" , "e51IJA1bz9dDEvmXtO6CeL6/M6KMXDvojCbTz2MtnLk=" }, + { "Localization\\Javanese\\Textures\\[Custom Textures]\\garden_new" , "WxH9rTrIHkmQeu0ALKfFuI6JvXo1uKQlwvgIc72+lhI=" }, + { "Localization\\Javanese\\Textures\\[Custom Textures]\\plant" , "ZkLNZASMXf7P0621AH2sFm3rbulCrs7otMLrrxiaqsA=" }, + { "Localization\\Javanese\\Textures\\[Custom Textures]\\SeedBank" , "+5f20e56ArqQ3Mt2BXtpSM2vO7SV+mWOzIBalIEh4Ew=" }, + { "Localization\\Javanese\\Textures\\[Custom Textures]\\SeedChooser_Background" , "kjv++O/zFxvPVoObxFTLXsH2MIp3zae4UJ8zu8kVOhY=" }, + { "Localization\\Javanese\\Textures\\[Custom Textures]\\SeedChooser_Button" , "9d5FghH0XRShLwjivvcKtVqmlOQLZC/RqfT+Urv8PJo=" }, + { "Localization\\Javanese\\Textures\\[Custom Textures]\\SeedChooser_Button_Disabled" , "iTsQO62+/80kG4jELlTnB/AXA8wvQKnqCgvQS4pDVlY=" }, + { "Localization\\Javanese\\Textures\\[Custom Textures]\\SeedChooser_Button_Glow" , "cFJCF740SGrFKt7c5OOAcRSVdW5ZZ6sBuE+T3JSwgOU=" }, + { "Localization\\Javanese\\Textures\\[Custom Textures]\\seedfog" , "JFjRJErflXFgxgxXXGHr6fjLaVIpoYSS0hlWa5Fi09c=" }, + { "Localization\\Javanese\\Textures\\[Custom Textures]\\seedlinkage" , "3IAYdQXkrWvDMBpg5Zw4ZRU39zuY9OAd3lVhwp07aMk=" }, + { "Localization\\Javanese\\Textures\\[Custom Textures]\\seedp" , "oaPa7rvvRy+pP3yUvA82hSNJ9/LQIZ+RVGPfCYvaLUg=" }, + { "Localization\\Javanese\\Textures\\[Custom Textures]\\SeedPacketSilhouette" , "ca+mkPyRnAjVIZZRieUCHFV2t3qiJnX2YQnd/z3iTvs=" }, + { "Localization\\Javanese\\Textures\\[Custom Textures]\\SeedPacket_Larger" , "mFoaC4FBXiufdw/aG0SCLlxzpE1umDx3robELsUPhi8=" }, + { "Localization\\Javanese\\Textures\\[Custom Textures]\\SeedPacket_Night" , "KZEvxdx4nQnrYVPv8FY4DbVDAQBCjlllMnxXQHJ1gkE=" }, + { "Localization\\Javanese\\Textures\\[Custom Textures]\\SeedPacket_Other" , "EP7WPPrYdZvxAhRig/FBJWHEw67amJuOO9JO0Kqzh14=" }, + { "Localization\\Javanese\\Textures\\[Custom Textures]\\SeedPacket_Pool" , "8eLUx9OWZORq3ItJcbQltcsyc6oPAW9PThEHoul/LY0=" }, + { "Localization\\Javanese\\Textures\\[Custom Textures]\\seedroof" , "HhNxpjbMgvt2FZdZZ7kfl546x6+5B4B97DgSH80wkMg=" }, + + { "Localization\\Indonesian\\Textures\\[Custom Textures]\\Almanac_IndexBack" , "DagukR2bViPz88Iu2B5w4QDMs4ykui/BYdk+lyaTK2o=" }, + { "Localization\\Indonesian\\Textures\\[Custom Textures]\\Almanac_PlantCard" , "O2UWyplpXK69pTFXYDSA5KiRyKAZ22LCDN71GIb5ZDg=" }, + { "Localization\\Indonesian\\Textures\\[Custom Textures]\\Almanac_ZombieBack" , "L91uR40W1iPLqBd+ouENStDe9RN+xUOZtbF048MiD1U=" }, + { "Localization\\Indonesian\\Textures\\[Custom Textures]\\Almanac_ZombieCard" , "3QvRtOtCpI6sqh26+Zbr9vTR9RB8oSXy4m7iS2snZUI=" }, + { "Localization\\Indonesian\\Textures\\[Custom Textures]\\Almanac_ZombieWindow" , "+LHsQLlwsYWEVS11F+SustquGoxjbGiyrs58XwyeYMw=" }, + { "Localization\\Indonesian\\Textures\\[Custom Textures]\\Almanac_ZombieWindow2" , "e51IJA1bz9dDEvmXtO6CeL6/M6KMXDvojCbTz2MtnLk=" }, + { "Localization\\Indonesian\\Textures\\[Custom Textures]\\garden_new" , "WxH9rTrIHkmQeu0ALKfFuI6JvXo1uKQlwvgIc72+lhI=" }, + { "Localization\\Indonesian\\Textures\\[Custom Textures]\\plant" , "ZkLNZASMXf7P0621AH2sFm3rbulCrs7otMLrrxiaqsA=" }, + { "Localization\\Indonesian\\Textures\\[Custom Textures]\\SeedBank" , "+5f20e56ArqQ3Mt2BXtpSM2vO7SV+mWOzIBalIEh4Ew=" }, + { "Localization\\Indonesian\\Textures\\[Custom Textures]\\SeedChooser_Background" , "kjv++O/zFxvPVoObxFTLXsH2MIp3zae4UJ8zu8kVOhY=" }, + { "Localization\\Indonesian\\Textures\\[Custom Textures]\\SeedChooser_Button" , "9d5FghH0XRShLwjivvcKtVqmlOQLZC/RqfT+Urv8PJo=" }, + { "Localization\\Indonesian\\Textures\\[Custom Textures]\\SeedChooser_Button_Disabled" , "iTsQO62+/80kG4jELlTnB/AXA8wvQKnqCgvQS4pDVlY=" }, + { "Localization\\Indonesian\\Textures\\[Custom Textures]\\SeedChooser_Button_Glow" , "cFJCF740SGrFKt7c5OOAcRSVdW5ZZ6sBuE+T3JSwgOU=" }, + { "Localization\\Indonesian\\Textures\\[Custom Textures]\\seedfog" , "JFjRJErflXFgxgxXXGHr6fjLaVIpoYSS0hlWa5Fi09c=" }, + { "Localization\\Indonesian\\Textures\\[Custom Textures]\\seedlinkage" , "3IAYdQXkrWvDMBpg5Zw4ZRU39zuY9OAd3lVhwp07aMk=" }, + { "Localization\\Indonesian\\Textures\\[Custom Textures]\\seedp" , "oaPa7rvvRy+pP3yUvA82hSNJ9/LQIZ+RVGPfCYvaLUg=" }, + { "Localization\\Indonesian\\Textures\\[Custom Textures]\\SeedPacket_Larger" , "mFoaC4FBXiufdw/aG0SCLlxzpE1umDx3robELsUPhi8=" }, + { "Localization\\Indonesian\\Textures\\[Custom Textures]\\SeedPacket_Night" , "KZEvxdx4nQnrYVPv8FY4DbVDAQBCjlllMnxXQHJ1gkE=" }, + { "Localization\\Indonesian\\Textures\\[Custom Textures]\\SeedPacket_Other" , "EP7WPPrYdZvxAhRig/FBJWHEw67amJuOO9JO0Kqzh14=" }, + { "Localization\\Indonesian\\Textures\\[Custom Textures]\\SeedPacket_Pool" , "8eLUx9OWZORq3ItJcbQltcsyc6oPAW9PThEHoul/LY0=" }, + { "Localization\\Indonesian\\Textures\\[Custom Textures]\\seedroof" , "HhNxpjbMgvt2FZdZZ7kfl546x6+5B4B97DgSH80wkMg=" }, + #endif + }; + + static string GetCheckSum(string filename) + { + using (var md5 = SHA256.Create()) + { + byte[] bytes = md5.ComputeHash(File.ReadAllBytes(filename)); + return Convert.ToBase64String(bytes); + } + } + + public static void SaveCheckSum() + { + string stringDir = GetAssetDir(AssetType.Dumps); + if (!Directory.Exists(stringDir)) + { + Directory.CreateDirectory(stringDir); + } + string checkSumString = JsonSerializer.Serialize(checkSums, new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping + }); + File.WriteAllText(Path.Combine(stringDir, "MD5.json"), checkSumString); + } + + public static void SaveModifiedChecksum() + { + string stringDir = GetAssetDir(AssetType.Dumps); + if (!Directory.Exists(stringDir)) + { + Directory.CreateDirectory(stringDir); + } + string modifiedCheckSumString = JsonSerializer.Serialize(modifiedCheckSums, new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping + }); + File.WriteAllText(Path.Combine(stringDir, "Modified_MD5.json"), modifiedCheckSumString); + } + + public static bool IsModified(string filepath) + { + string fileName = Path.GetFileNameWithoutExtension(filepath); + string directory = Path.GetDirectoryName(filepath); + string slicedFilePath = directory.Substring(directory.IndexOf("PvZ_Fusion_Translator\\") + "PvZ_Fusion_Translator\\".Length); + string slicedKey = Path.Combine(slicedFilePath, fileName); + + #if DEBUG + if (!checkSums.ContainsKey(slicedKey)) + { + checkSums.Add(slicedKey, GetCheckSum(filepath)); + SaveCheckSum(); + modifiedCheckSums.Add(slicedKey, GetCheckSum(filepath)); + SaveModifiedChecksum(); + } + else + { + if ((checkSums[slicedKey] != GetCheckSum(filepath))) + { + checkSums[slicedKey] = GetCheckSum(filepath); + modifiedCheckSums.Add(slicedKey, GetCheckSum(filepath)); + SaveModifiedChecksum(); + } + } + #elif RELEASE + if (!checkSums.ContainsKey(slicedKey) | (checkSums[slicedKey] != GetCheckSum(filepath))) + { + return true; + } + #endif + return false; + } + + public static void ConvertMD5Json() + { + string stringDir = GetAssetDir(AssetType.Dumps); + if (!Directory.Exists(stringDir)) + { + Directory.CreateDirectory(stringDir); + } + string checksumDumpPath = Path.Combine(stringDir, "MD5.json"); + string checksumConvertPath = Path.Combine(stringDir, "MD5Convert.txt"); + string json = File.ReadAllText(checksumDumpPath); + Dictionary dictionary = DeserializeObject>(json); + + using StreamWriter writer = new StreamWriter(checksumConvertPath); + foreach (var kvp in dictionary) + { + string checksumKey = kvp.Key.Replace("\\", "\\\\"); + writer.WriteLine($"{{ \"{kvp.Key}\" , \"{kvp.Value}\" }},"); + } + + Log.LogDebug($"MD5.json converted to MD5Convert.json at {checksumConvertPath}"); + } + } +} +#endif \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/FontStore.cs b/PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/FontStore.cs new file mode 100644 index 0000000..75d5b03 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/FontStore.cs @@ -0,0 +1,170 @@ +using Il2CppTMPro; + +namespace PvZ_Fusion_Translator.AssetStore +{ + public static class FontStore + { + internal static Dictionary fontAssetDict = []; + internal static Dictionary fontAssetDictSecondary = []; + + internal static void Init() + { + string fontsDir = Path.Combine(Core.Instance.modsDirectory, "[Custom Fonts]"); + + #if MULTI_LANGUAGE + foreach (string file in Directory.GetFiles(fontsDir)) + { + string fileName = Path.GetFileNameWithoutExtension(file); + string fileExtension = Path.GetExtension(file); + + if (fileExtension == ".ttf" || fileExtension == ".otf") + { + if (!fileName.EndsWith("_Almanac") && !fileName.EndsWith("_Fallback")) + { + string fontPath = Path.Combine("PvZ_Fusion_Translator", "[Custom Fonts]", fileName + fileExtension); + + TMP_FontAsset fontAsset = FontHandler.LoadTMPFont(fontPath, true); + fontAsset.name = fileName; + fontAssetDict.Add(fileName, fontAsset); + + Log.LogInfo($"Font for language '{fileName}' loaded"); + } + } + } + + InitFallback(); + #else + string defaultFontDir = Path.Combine("PvZ_Fusion_Translator", "[Custom Fonts]", "English.ttf"); + + TMP_FontAsset defaultFont = FontHandler.LoadTMPFont(defaultFontDir, true); + fontAssetDict.Add("English", defaultFont); + #endif + } + + internal static void InitFallback() + { + string fontsDir = Path.Combine(Core.Instance.modsDirectory, "[Custom Fonts]"); + foreach (string file in Directory.GetFiles(fontsDir)) + { + string fileName = Path.GetFileNameWithoutExtension(file); + string fileExtension = Path.GetExtension(file); + + if (fileExtension == ".ttf" || fileExtension == ".otf") + { + if (fileName.EndsWith("_Almanac") || fileName.EndsWith("_Fallback")) + { + string fallbackPath = Path.Combine("PvZ_Fusion_Translator", "[Custom Fonts]", fileName + fileExtension); + TMP_FontAsset fallbackFont = FontHandler.LoadTMPFont(fallbackPath, true); + fallbackFont.name = fileName; + + string fileNameLanguage = fileName.Replace("_Fallback", "").Replace("_Almanac", ""); + + if (fontAssetDictSecondary.ContainsKey(fileNameLanguage)) + { + if (fileName.EndsWith("_Fallback")) + { + fontAssetDictSecondary.Add(fileNameLanguage + "_Almanac", fontAssetDictSecondary[fileNameLanguage]); + fontAssetDictSecondary.Remove(fileNameLanguage); + } + else + { + fontAssetDictSecondary.Add(fileNameLanguage + "_Fallback", fontAssetDictSecondary[fileNameLanguage]); + fontAssetDictSecondary.Remove(fileNameLanguage); + } + fontAssetDictSecondary.Add(fileName, fallbackFont); + } + else + fontAssetDictSecondary.Add(fileNameLanguage, fallbackFont); + + // Log.LogInfo($"Fallback font for language '{fileNameLanguage}' loaded"); + } + } + } + AddFallback(); + } + + public static void AddFallback() + { + foreach (var lang in fontAssetDict.Keys) + { + if (fontAssetDict[lang].fallbackFontAssetTable == null) + { + fontAssetDict[lang].fallbackFontAssetTable = new Il2CppSystem.Collections.Generic.List(); + } + + if (fontAssetDictSecondary.ContainsKey(lang)) + { + fontAssetDict[lang].fallbackFontAssetTable.Add(fontAssetDictSecondary[lang]); + Log.LogInfo("Fallback font for language '" + lang + "' added"); + continue; + } + if (fontAssetDictSecondary.ContainsKey(lang + "_Almanac")) + { + fontAssetDict[lang].fallbackFontAssetTable.Add(fontAssetDictSecondary[lang + "_Almanac"]); + Log.LogInfo("Fallback font for language '" + lang + "' added"); + continue; + } + if (fontAssetDictSecondary.ContainsKey(lang + "_Fallback")) + { + fontAssetDict[lang].fallbackFontAssetTable.Add(fontAssetDictSecondary[lang + "_Fallback"]); + Log.LogInfo("Fallback font for language '" + lang + "' added"); + continue; + } + } + } + + #if MULTI_LANGUAGE + public static TMP_FontAsset LoadTMPFont(string language) + { + if (fontAssetDict.TryGetValue(language, out TMP_FontAsset font)) + { + TMP_FontAsset fontAsset = font; + if (fontAsset.fallbackFontAssetTable != null) + { + // Log.LogInfo("Fallback font for language '" + language + "' loaded. The name of the FB Font is" + fontAsset.fallbackFontAssetTable[0].name); + } + return fontAsset; + } + return fontAssetDict.GetValueOrDefault("English"); + } + #else + public static TMP_FontAsset LoadTMPFont() + { + TMP_FontAsset defaultFont = fontAssetDict["English"]; + return defaultFont; + } + #endif + + public static TMP_FontAsset LoadTMPFontAlmanac(string language) + { + if (fontAssetDictSecondary.ContainsKey(language)) + { + if (fontAssetDictSecondary.TryGetValue(language, out TMP_FontAsset almanacAsset)) + { + return almanacAsset; + } + } + if (fontAssetDictSecondary.ContainsKey(language + "_Almanac")) + { + if (fontAssetDictSecondary.TryGetValue(language + "_Almanac", out TMP_FontAsset almanacAsset)) + { + return almanacAsset; + } + } + + return fontAssetDict.GetValueOrDefault("English"); + } + + #if MULTI_LANGUAGE + public static void Reload() + { + // Get the current language + string currentLanguage = Utils.Language.ToString(); + + // Load the font for the current language + _ = LoadTMPFont(currentLanguage); + } + #endif + + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/StringStore.cs b/PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/StringStore.cs new file mode 100644 index 0000000..119864c --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/StringStore.cs @@ -0,0 +1,1404 @@ +using Il2CppTMPro; +using System.Text.RegularExpressions; +using UnityEngine; + +namespace PvZ_Fusion_Translator.AssetStore +{ + public static class StringStore + { + internal static Dictionary stringsDict = []; + + public static Dictionary translationStringRegex = new() + { + #if !RELEASE && !OBFUSCATE + // UI + { @"-------Main UI" , "Main UI-------" }, + { @"主菜单(.*)" , "Main Menu{0}" }, + { @"^(\d+)轮" , "{0} Flags" }, + { @"^开发人员名单\s+", "Credits\r\nProgram, Director: 蓝飘飘fly\r\nAnimation: 蓝飘飘fly\r\nArtist, Visual Director: 机鱼吐司\r\nVideo Editor: 梦珞\r\nAnimation Helper: 射命丸文\r\nArt Helper: 蓝蝶" }, + { @"第(\d+)已完成" , "Level {0} Completed" }, + { @"^确定退出吗?\s+" , "Are you sure you want to exit?\r\nProgress will not be saved!\r\nExcept for Survival Mode." }, + { @"下一阶段:(\d+)分(\d+)秒\s+当前水分:(\d+)/100\s+当前成长阶段:(\d+)/2\s+成长值:(\d+)/100" , "Cooldown: {0}:{1}\nHydration: {2}/100\nStage: {3}/2\nFavorability: {4}/100" }, + + // UI - Buttons + { @"-------UI - Buttons" , "UI - Buttons-------" }, + { @"查看([^\s:]+)" , "View {0}" }, + { @"返回([^\s:]+)" , "Back to {0}" }, + { @"回到([^\s:]+)" , "Back to {0}" }, + + // UI - Playing + { @"-------UI - Playing" , "UI - Playing-------" }, + { @"快捷键:(\d+)" , "Hotkey: {0}" }, + { @"场上敌人数量:(\d+)" , "Zombies: {0}" }, + { @"难度:(\d+)" , "Difficulty: {0}" }, + + // UI - Adventure Mode + { @"-------UI - Adventure Mode" , "UI - Adventure Mode-------" }, + { @"^第(\d+)关" , "Level {0}" }, + { @"^冒险模式(:)?(?:第)?(\d+)(?:关)?" , "Adventure Mode: Level {1}" }, + + // UI - Challenge Mode + { @"-------UI - Challenge Mode" , "UI - Challenge Mode-------" }, + //// Advanced + // { @"^超级([^\s+])(:|\n)?(挑战关卡|挑战)?([\d]*)?" , "{0} {2}" }, + { @"^超级([^\s:]+)(:?挑战1?)" , "Fusion Challenge: {0}" }, + { @"^超级随机:(无尽|模仿)" , "Odyssey Gacha\n{0}" }, // {0} = "无尽" or "模仿" + //// Ten-Flag + // { @"^十旗挑战([\s\n]*?(?:[\s:]))([^\s:]+)" , "Ten-Flag\n{1}" }, + { @"^十旗挑战:([^\s]+)" , "Ten-Flag: {0}" }, + { @"^十旗挑战\s([^\s]+)" , "Ten-Flag\n{0}" }, + //// Odyssey + { @"^旅行体验(:)?(?:第)?(\d+)(?:关)?" , "Odyssey\nDemo {1}" }, + //// Mini Games + { @"^经典塔防(\d+)?" , "ZombiesTD {0}" }, + // { @"^经典塔防([\s\n]*?(?:[\s:]))([^\s:]+)" , "ZombiesTD{0}{1}" }, + //// Garden Defense + { @"^花园保卫战(\d+)?" , "Garden Defense {0}" }, + + // UI - Puzzle Mode + { @"-------UI - Puzzle Mode" , "UI - Puzzle Mode-------" }, + { @"^决战([^\s]+)!" , "Ultimate Battle:\n{0}" }, + + // UI - Survival Mode + { @"-------UI - Survival Mode" , "UI - Survival Mode-------" }, + { @"^黑夜:([^\s]+)" , "Night\n{0}" }, + { @"^白天:([^\s]+)" , "Day\n{0}" }, + { @"^泳池:([^\s]+)" , "Pool\n{0}" }, + { @"^浓雾:([^\s]+)" , "Fog\n{0}" }, + { @"^屋顶:([^\s]+)" , "Roof\n{0}" }, + { @"^生存(模式)?(:)([^\s]+)" , "Survival {0} \n{2}" }, + + // UI - Odyssey Mode + { @"-------UI - Odyssey Mode" , "UI - Odyssey Mode-------" }, + { @"^1,([^\s]+)" , "1. {0}" }, + { @"^2,([^\s]+)" , "2. {0}" }, + { @"^3,([^\s]+)" , "3. {0}" }, + { @"^1、([^\s]+)" , "1. {0}" }, + { @"^2、([^\s]+)" , "2. {0}" }, + { @"^3、([^\s]+)" , "3. {0}" }, + { @"^([^\s]+)1、([^\s]+)<\/color>" , "{0}1. {1}" }, + { @"^([^\s]+)2、([^\s]+)<\/color>" , "{0}2. {1}" }, + { @"^([^\s]+)3、([^\s]+)<\/color>" , "{0}3. {1}" }, + { @"^选择(\d+)" , "Select {0}" }, + + // UI - Level Editor + { @"-------UI - Level Editor" , "UI - Level Editor-------" }, + { @"^设置([^\s]+)数" , " Set {0}" }, + { @"^允许([^\s]+)" , "{0} - On" }, + { @"^禁用([^\s]+)" , "{0} - Off" }, + { @"^目标场景:(6路)?([^\s]*)" , "Scene: {0} {1}" }, + { @"^Scene: (6路)?([^\s]+)" , "Scene: {0} {1}" }, + { @"^自定义关卡使用条款,开发者在此声明:\s+" , "Custom Level Terms of Use, Developer's Statement:\r\nCustom levels are created by players themselves. If a map violates laws or regulations, or infringes on the rights of others, please immediately exit and delete the level. Playing the level implies that the player agrees to bear any risks and responsibilities associated with using custom levels." }, + { @"^地图编辑器使用条款,开发者在此声明:\s+" , "Map Editor Terms of Use, Developer's Statement:\r\nThe editor is only for normal level creation use. Any behavior that violates laws and regulations or infringes on the rights of others is strictly prohibited. Players agree to assume the risks and responsibilities associated with using the editor." }, + { @"^按Tab切换鼠标位置格子类型\s+" , "Press Tab to switch the mouse grid type.\r\nHold A or D and move the mouse to switch to grass or dirt.\r\nPress C to save; the saved level will take effect in Custom Level." }, + { @"^保存关卡完毕!前往自定义关卡游玩\s+" , "Level saved successfully! Go to Custom Level to play it.\r\nYou can also share the levels you created with your friends to challenge them.\r\nThe location of the level file is as here:\r\nC:\\Users\\[Your Username]\\AppData\\LocalLow\\LanPiaoPiao\\PlantsVsZombiesRH\\CustomBlock.json" }, + { @"^保存成功,前往我是僵尸的自定义关卡游玩\s+" , "Level saved successfully! Go to Custom Level of I, Zombie to play it.\r\nThe zombies that can be used in the level is the zombies that are currently on the loadout, and the initial Sun is the Sun currently on the level.\r\nThe name of the file level is CustomIZ.json." }, + // UI - Almanac + { @"^图鉴————(.*)" , "The Suburban Almanac — {0}" }, + + // UI - Settings + { @"-------UI - Settings" , "UI - Settings-------" }, + { @"当前大小:([^\s]+)" , "Current Zoom: {0}" }, + { @"UI高度匹配:([^\s]+)" , "UI Height Match: {0}" }, + { @"当前设置:([^\s]+)" , "Current: {0}" }, + { @"切换全屏(\d+)\*(\d+)" , "Screen Mode" }, + + // Strings - Playing + //// Notifications + { @"-------Strings - Playing" , "Strings - Playing-------" }, + { @"升级需要(\d+)金币" , "Upgrade requires {0} Coins." }, + { @"第(\d+)页" , "Page {0}" }, + // Strings - ZombiesTD 5 + { @"^干得好!\s+下一个任务:(\d+)旗" , "Mission Completed\nNext Mission: Flag {0}"}, + { @"^任务失败!\s+下一个任务:(\d+)旗" , "Mission Failed\nNext Mission: Flag {0}"}, + { @"^任务目标:在(\d+)秒内击杀(\d+)个僵尸\s+任务奖励:究极加农炮x1" , "Current Mission: Kill {1} zombies within {0} seconds.\nCompletion Reward: Cob-livion Cannon x1" }, + { @"^任务目标:在(\d+)秒内击杀(\d+)个僵尸\s+任务奖励:解锁全部究极植物" , "Current Mission: Kill {1} zombies within {0} seconds.\nCompletion Reward: Unlock all Odyssey Fusions" }, + + { @"-------Strings - Others" , "Strings - Others-------" }, + // { @"HP:(\d+)/(\d+)\s+一类:(\d+)/(\d+)" , "HP: {0}/{1}\nArmor: {2}/{3}" }, + // { @"HP:(\d+)/(\d+)\s+二类:(\d+)/(\d+)" , "HP: {0}/{1}\nArmor: {2}/{3}" }, + { @"^HP:(\d+)/(\d+)\s+([^\s+])类:(\d+)/(\d+)" , "HP: {0}/{1}\nArmor: {3}/{4}" }, + { @"^HP:(\d+)/(\d+)" , "HP: {0}/{1}" }, + // { @"平衡性调整(([^\s]+))" , "Balance Adjustment ({0})" }, + { @"旅行:守护 (\d+)轮已经完成" , "Odyssey: Last Stand | {0} Rounds Completed"}, + + { @"-------Strings - New Update" , "Strings - New Update-------" }, + { @"^余额不足,购买需要:(\d+)" , "Insufficient Balance: ${0} Needed"}, + { @"^砸罐子(\d+)" , "Vasebreaker {0}" }, + { @"^作战植物已达上限(\d+)/(\d+)" , "Max Amount of Plants in Combat Reached: {0}/{1}" }, + { @"^参战植物数量增加到(\d+)" , "Number of Plants in Combat Increased to {0}." }, + { @"^距离植物休息完毕还有(\d+)秒" , "Time Until Recharged: {0} Seconds" }, + { @"^补给已到达,参战植物数量增加到(\d+)" , "Reinforcements Are Here! Plants in Combat Increased to {0}." }, + { @"^请按左中右的顺序放置以下植物\s+([^\s]+),([^\s]+),([^\s]+)" , "Please place the following plants in order\n{0}, {1}, {2}" }, + { @"^当前分数:(\d+)" , "Current Points: {0}" }, + { @"^本次消耗分数:(\d+)" , "Reroll Cost: {0}" }, + { @"^生存模式:旅行 (\\d+)轮已经完成" , "Odyssey: Survival | {0} Rounds Completed" }, + { @"^旅行:轮回 (\d+)轮已经完成" , "Odyssey: Reincarnation | {0} Rounds Completed"}, + { @"^旅行:炼狱 (\d+)轮已经完成" , "Odyssey: Purgatory | {0} Rounds Completed"}, + { @"^升级植物需要消耗(\d+)点阳光" , "Upgrading Requires {0} Sun" }, + { @"^生存(模式)?(:)([^\\s]+) (\\d+)轮已经完成" , "Survival: {2} | {3} Flags Completed" }, + { @"^升级植物需要消耗(\d+)阳光" , "Upgrading Requires {0} Sun" }, + + { @"^制作组名单:\s+制作人:蓝飘飘fly\s+策划:蓝飘飘fly、机鱼\s+" , " " }, // Credits:\nProgram, Director: 蓝飘飘fly\nAnimation: 蓝飘飘fly\nArtist, Visual Director: 机鱼吐司\nVideo Editor: 梦珞\nAnimation Helper: 射命丸文\nArt Helper: 蓝蝶\n\nThanks to the following friends for their help:\nBeichuang Yaowang, Lue ND, MC-Da Mai, Submarine Weiwei Fan, Rongying, Sheming Wanwen, Apostle, Tip Yangshan Muyan, Xiaohuangji, Yunyao Yoke, Zhuang Buchun + { @"^快捷键一览:\s+1:铲子\s+" , " "}, // Shortcut keys: \n1: Shovel\tQ: Show Plant Health\n2: Gloves\tW: Show Zombie Health\n3: Time Stop\tE: Coffee Bean\n4: Mallet\tP: Switch Kirov SFX\n\t\tV: Switch Gloves + + { @"-------Strings - New Update v2" , "Strings - New Update 2.3.1-------" }, + { @"^红温\s+效果:僵尸受到的伤害增加50%,且死亡时对小范围内僵尸造成100点伤害并施加红温效果\s+" , "Enflamed\nZombies take 50% more damage, and upon death, they deal 100 damage to nearby zombies and apply the Enflamed debuff.\n\nCryo System\nZombies start with a Cryo Points cap of 100. When the accumulated Cryo Points reaches the cap, the zombie will be frozen for 4 seconds, then the cap increases by 100, up to a maximum of 400.\n\nTangled\nEach time Tangled is applied, it deals extra max HP percentage damage based on the zombie’s current Tangle Value:\n6~10: 1%, 11~15: 3%, 16~29: 5%, 30+: 100%\n\nPoison Value\nA zombie’s Poison Value cap is 5. When it reaches 5, any further accumulation will put the zombie in a poisoned state, losing HP every second equal to 20 × Poison Value. If the Poison Value is at 5 and the zombie is hit by a Garlic Butter projectile, this cap will be removed.\n\nLumos Level\nPlanterns provides 1 Lumos Level to all tiles in a 3x3 area. There is no cap on a tile’s Lumos Level.\n\nMagnetic System\nWhen a magnetic plant is within a 3x3 range of another magnetic plant, they are considered to be in the same Magnetic System." }, + { @"^坚果台球(\d+)?" , "Wall-nut Billiards {0}" }, + { @"^旅行冒险:第(\d+)关" , "Odyssey Adventure: Level {0}" }, + { @"^剩余积分:(\d+)点" , "Remaining Points: {0}" }, + { @"^但(.*)" , "Odyssey Negative Modifier | {0}" }, + { @"^成功击败领袖,获得(\d+)积分" , "Supreme Zombie successfully defeated. You have earned {0} Points." }, + { @"^大招需要(\d+)金币" , "Using the Ultimate requires {0} Coins." }, + + + { @"-------Outdated Regex Below" , "You Can Safely Ignore or Delete-------"}, + #endif + }; + + public static Dictionary translationString = new() + { + #if !RELEASE && !OBFUSCATE + // UI - Main Menu + { "-------UI - Main Menu" , "UI - Main Menu-------" }, + { "游戏完全免费,点击这里关注作者蓝飘飘fly,获取最新更新动态" , "The game will always be free————click here to follow the author LanPiaoPiaoFly!" }, + { "点击这里关注画师机鱼吐司" , "Click here to follow the artist Gfishtus!" }, + // { "屋顶测试版(上半)" , " " }, // discord.gg/FTfz45NGxh + { "屋顶测试版(中)" , " " }, + { "设置" , "Settings" }, + + // UI - Settings + { "-------UI - Settings" , "UI - Settings-------" }, + { "手机版可能导致画质降低\n重启恢复" , "Click to change to Windowed Mode or Fullscreen." }, + // { "一键通关泳池版本" , "Clear Pool Levels" }, + { "一键通关冒险模式" , "Clear\nAdventure Levels" }, + { "一键通关所有关卡" , "Clear All levels" }, + { "重置所有关卡" , "Reset All Levels" }, + { "再按一次确定" , "Press Again" }, + { "调整相机投影大小" , "Camera Zoom" }, + { "修改画布匹配" , "Canvas Size" }, + // { "诸神是否需要手套" , "Does 'The Gods' need Gloves?" }, + { "诸神移动植物方式" , "The Gods: Playing Method"}, + { "当前方式:用手套" , "Current: Manual\nUse Gloves" }, + { "当前方式:点击即可" , "Current: Automatic\nUse Click" }, + { "关卡内教学" , "Level Tutorials"}, + { "大麦植物变色" , "Barley Color Changes" }, + { "关闭" , "Disabled" }, + { "开启" , "Enabled" }, + + // UI - Buttons + { "-------UI - Buttons" , "UI - Buttons-------" }, + { "其它" , "Other" }, + { "确定" , "OK" }, + { "接受" , "Accept" }, + { "返回" , "Return" }, + { "合上" , "Close" }, + { "取消" , "Cancel" }, + { "暂停" , "Pause" }, + { "退出" , "Exit"}, + { "下一页" , "Next" }, + { "上一页" , "Previous" }, + { "再次尝试" , "Try Again" }, + { "游戏结束" , "Game Over" }, + { "回到索引" , "Return to Index" }, + { "重新开始这一轮\n(生存模式专用)" , "Restart the Round\n(Survival Mode Only)" }, // Game Over + { "选卡界面" , "Plant Select" }, // Equal Exchange + + // UI - Other + + { "挑战" , "Challenge" }, + + // UI - Plant Select + { "-------UI - Plant Select" , "UI - Plant Select-------" }, + { "选择你的植物" , "Choose Your Plants" }, + { "一起摇滚吧!" , "Let's Rock!" }, + { "重选上次卡牌" , "Select Previous Loadout" }, + + // UI - Playing + { "-------UI - Playing" , "UI - Playing-------" }, + { "开始战斗" , "Start Round" }, + { "时停" , "Slow Mode" }, + + // UI - Options + { "-------UI - Options" , "UI - Options-------" }, + { "主菜单" , "Main Menu" }, + { "查看图鉴" , "Open Almanac" }, + { "重新开始" , "Restart" }, + { "确定重新开始吗?" , "Are you sure\nyou want to restart?" }, + { "返回游戏" , "Resume" }, // Resume + { "音乐" , "BGM" }, + { "音效" , "SFX" }, + { "简单模式" , "Easy Mode" }, + { "普通模式" , "Casual Mode" }, + { "正常模式" , "Normal Mode" }, + { "困难模式" , "Veteran Mode" }, + { "极难模式" , "Merciless Mode" }, + { "你确定?" , "Are You Sure?" }, + { "游戏速度" , "Game Speed" }, + + // UI - I, Zombie + { "-------UI - I, Zombie" , "UI - I, Zombie-------" }, + { "开启斗蛐蛐" , "Start Fight" }, + { "自选僵尸卡牌" , "Pick Zombies"}, + { "一键全选", "Quick Select" }, + { "保存为自定义阵容" , "Save for Custom Level"}, + { "自选植物卡牌" , "Pick Plants" }, + { "平衡性调整(开)" , "Balance Adjustment - On" }, + { "平衡性调整(关)" , "Balance Adjustment - Off" }, + { "全自动斗蛐蛐" , "Automatic Fight" }, + { "填充随机植物" , "Random Fill" }, + { "加载植物阵容" , "Load Plant Setup" }, + { "保存植物阵容" , "Save Plant Setup" }, + { "开始/关闭出怪" , "On/Off Spawn" }, + + // UI - Back to _ // UI - Almanac + { "-------UI - Back to _" , "UI - Back to _-------" }, + { "索引" , "Index" }, + { "植物" , "Plants" }, + { "僵尸" , "Zombies" }, + { "菜单" , "Menu" }, + + // UI - Almanac + { "-------UI - Almanac" , "UI - Almanac-------" }, + { "更多" , "Other" }, + { "超级" , "Adv."}, + { "究极" , "Odys." }, + + // UI - Zen Garden + { "-------UI - Zen Garden" , "UI - Zen Garden-------" }, + { "禅境花园" , "Zen Garden" }, + { "帮助" , "Info" }, + { "将植物挪到最下面一行为花园保卫战的出战区,使用培养的植物战斗吧!\n使用手套可以融合植物,但只能融合长大以后的植物\n快捷键123456等为对应左上角的道具" , "Fully grown plants in the bottom row of the first page are used for Garden Defense.\nUse the Gloves to fuse fully grown plants.\nUse (1-7) as Hotkeys for the Garden Tools." }, + { "请先将手推车中的植物放下" , "Please put down the plant in your Wheelbarrow first."}, + { "你确定要移除该植物吗" , "Are you sure you want to remove this plant?"}, + + // UI - Level Editor + { "-------UI - Level Editor" , "UI - Level Editor-------" }, + { "修改格子只对大地图有效" , "Grid modification is only\neffective for Large Maps." }, + { "请选择禁用的植物" , "Choose Plants to Disable" }, + { "阳光" , "Starting Sun" }, + { "旗帜" , "Flags" }, + { "前往设置僵尸" , "Set Zombies" }, + { "坚不可摧" , "Last Stand" }, + { "旅行植物" , "Odyssey Plants" }, + { "旅行词条" , "Odyssey Modifiers" }, + { "更换场景" , "Change Scene" }, + { "保存关卡" , "Save Level" }, + { "大地图" , "Large Map" }, + { "6路" , "6 Lane" }, + { "绿幕" , "Green Screen" }, + { "加入出怪(Q)" , "Add (Q)" }, + { "移除出怪(W)" , "Remove (W)" }, + { "允许排山倒海" , "Column Planting - On" }, + { "禁用排山倒海" , "Column Planting - Off" }, + { "允许种子雨" , "Seed Rain - On" }, + { "禁用种子雨" , "Seed Rain - Off" }, + { "允许胆小菇之梦" , "Scaredy's Dream - On" }, + { "禁用胆小菇之梦" , "Scaredy's Dream - Off" }, + { "允许超级随机" , "Advanced Gacha - On" }, + { "禁用超级随机" , "Advanced Gacha - Off" }, + + // UI - Large Maps + { "-------UI - Large Maps" , "UI - Large Maps-------" }, + { "切换鼠标反转" , "Invert Mouse" }, + { "更改屏幕缩放" , "Zoom" }, + { "切换小地图" , "Minimap" }, + { "可以优化性能" , "Impacts Performance" }, + + // UI - Modes + { "-------UI - Modes" , "UI - Modes-------" }, + { "冒险模式" , "Adventure Mode" }, + { "挑战模式" , "Challenge Mode" }, + { "解谜模式" , "Puzzle Mode" }, + { "生存模式" , "Survival Mode" }, + + // UI - Challenge Mode + { "-------UI - Challenge Mode" , "UI - Challenge Mode-------" }, + { "高级挑战" , "Fusion Challenge" }, + { "十旗挑战" , "Ten-Flag\nChallenge" }, + { "迷你游戏" , "Mini Games" }, + { "花园保卫战" , "Garden Defense" }, + + // UI - Fusion Challenge + { "-------UI - Fusion Challenge" , "UI - Fusion Challenge-------" }, + { "挑战关卡" , "Challenge" }, + { "超级樱桃射手\n挑战关卡" , " Explod-o-shooter\nChallenge" }, + { "樱桃射手" , "Explod-o-shooter" }, + { "超级大嘴花\n挑战关卡" , "Chewzilla\nChallenge" }, + { "大嘴花" , "Chewzilla" }, + { "超级魅惑菇\n挑战关卡" , "Charm-shroom\nChallenge" }, + { "魅惑菇" , "Charm-shroom" }, + { "超级大喷菇\n挑战关卡" , "Doomberg-shroom\nChallenge" }, + { "大喷菇" , "Doomberg-shroom" }, + { "超级火炬\n挑战关卡" , "Infernowood\nChallenge" }, + { "火炬" , "Infernowood" }, + { "超级窝草\n挑战关卡" , "Krakerberus\nChallenge" }, + { "窝草" , "Krakerberus" }, + { "超级南瓜\n挑战关卡" , "Bloverthorn Pumpkin\nChallenge" }, + { "南瓜" , "Bloverthorn Pumpkin" }, + { "超级杨桃\n挑战关卡" , "Stardrop\nChallenge" }, + { "杨桃" , "Stardrop" }, + { "超级投手\n挑战关卡" , "Salad-pult\nChallenge" }, + { "投手" , "Salad-pult" }, + { "超级伞\n挑战关卡" , "Alchemist Umbrella\nChallenge" }, + { "伞" , "Alchemist Umbrella" }, + + // UI - Ten Flag Challenge + { "-------UI - Ten-Flag Challenge" , "UI - Ten-Flag Challenge-------" }, + // Ten-Flag Day + // Ten-Flag Night + // Ten-Flag Pool + // Ten-Flag Fog + // Ten-Flag Roof + { "随机僵尸" , "Zombie Gacha" }, + { "植物僵尸" , "Zombotany" }, + { "黑夜舞会" , "Night Disco" }, + // Ten-Flag Scaredy's Dream + { "随机植物" , "Plant Gacha" }, + { "等价交换" , "Equal Exchange" }, + { "全员随机" , "Multi Gacha" }, + { "随机植物VS随机僵尸" , "Plant Gacha vs Zombie Gacha" }, // In-Game + + // UI - Mini Games + { "-------UI - Mini Games" , "UI - Mini Games-------" }, + { "胆小菇之梦" , "Scaredy's Dream" }, // Custom Level + { "撑杆舞会" , "Pole Vaulting\nDisco" }, + { "合理密植" , "Compact\nPlanting" }, + { "二爷战争" , "Newspaper\nWar" }, + { "泳池激斗" , "Pool Battle" }, + // ZombiesTD 1 + // ZombiesTD 2 + { "套娃" , "Matryoshka" }, + { "全是套娃" , "Matryoshka" }, // In-Game + { "排山倒海" , "Columns Like\nYou See 'Em" }, + { "镜像" , "Mirrors Like\nYou See 'Em" }, + { "你看,他们像镜子一样" , "Mirrors Like You See 'Em" }, // In-Game + { "种子雨" , "It's Raining\nSeeds" }, // Custom Level + { "谁能笑到最后" , "Last Stand" }, + { "空袭" , "Air Raid" }, + { "10.0版本前瞻\n超级预览版" , "Advanced Challenge\n12-Lane Day" }, + { "10.1版本前瞻\n超级预览版" , "Advanced Challenge\n12-Lane Pool" }, + { "超级白天" , "Advanced Challenge: 12-Lane Day" }, // In-Game + { "超级泳池" , "Advanced Challenge: 12-Lane Pool" }, // In-Game + // ZombiesTD 3 + { "关卡编辑器" , "Level Editor" }, + { "自定义关卡" , "Custom Level" }, + { "艺术就是爆炸" , "True Art is\n an Explosion!" }, + { "跳跳舞会" , "Pogo Party!" }, + { "巨人之怒" , "Attack on\nGargantuar!" }, + { "祖玛保龄球" , "Zum-nut!" }, + { "严肃窝瓜" , "Squash Showdown!"}, + { "魅惑坚果" , "Hypno-tism!" }, + { "保卫吸金磁" , "Protect the \nGold Magnet" }, + { "合理密植2" , "Compact Planting 2" }, + + // UI - Puzzle + { "-------UI - Puzzle" , "UI - Puzzle-------" }, + { "我是僵尸!" , "I, Zombie" }, + { "我也是僵尸!" , "I, Zombie Too" }, + { "你能吃了它吗!" , "All You\nCan Quaff" }, + { "雷区!" , "Mine Field" }, + { "完全傻了!" , "Totally Nuts" }, + // Ultimate Battle: Day + { "卑鄙的低矮植物!" , "Huff 'n Puff" }, + { "QQ弹弹!" , "Extra Bouncy" }, + { "当代女大学生!" , "Mushroom's\nDay Out" }, + { "胆小菇前传!" , "Scaredy-shroom\nPrequel" }, + { "冰冻关卡!" , "Frozen Level" }, + // Ultimate Battle: Night + { "初见泳池!" , "First Look\nat the Pool" }, + { "三三得九!" , "3 Times 3\nEquals 9" }, + { "嗯?" , "Hmmm?" }, + { "尸愁之路!" , "Rough Road" }, + { "严肃火炬!" , "Forest Fire" }, + { "决战泳池!" , "Ultimate Battle:\nPool" }, + { "你是僵尸!" , "U, Zombie" }, // In-Game + { "你是僵尸" , "U, Zombie" }, + { "你也是僵尸!" , "U, Zombie Too" }, + { "看星星!" , "Seeing Stars" }, + { "万磁王!" , "Magneto" }, + { "十面埋伏!" , "Absolute Ambush" }, + { "马奇诺防线!" , "Maginot Line" }, + { "攻守兼备!" , "The Best Defense\nis a Good Offense" }, + { "势不可挡!" , "Unstoppable" }, + { "自定义!" , "Custom Level" }, // I Zombie + + // UI - Survival + { "-------UI - Survival" , "UI - Survival-------" }, + { "困难" , "Hard" }, + { "无尽" , "Endless" }, + { "(困难)" , "(Hard)" }, + { "(无尽)" , "(Endless)" }, + { "白天(困难)" , "Day (Hard)" }, + { "黑夜(困难)" , "Night (Hard)" }, + { "泳池(困难)" , "Pool (Hard)" }, + { "浓雾(困难)" , "Fog (Hard)" }, + { "屋顶(困难)" , "Roof (Hard)" }, + { "泳池(无尽)" , "Pool (Endless)" }, + { "白天(无尽)" , "Day (Endless)" }, + { "黑夜(无尽)" , "Night (Endless)" }, + { "浓雾(无尽)" , "Fog (Endless)" }, + { "屋顶(无尽)" , "Roof (Endless)" }, + { "白天" , "Day" }, + { "黑夜" , "Night" }, + { "泳池" , "Pool" }, + { "旅行" , "Odyssey" }, + { "浓雾" , "Fog" }, + { "屋顶" , "Roof" }, + { "无尽塔防" , "Endless\nZombiesTD" }, + + // UI - Odyssey Mode + { "-------UI - Odyssey Mode" , "UI - Odyssey Mode-------"}, + { "究极模式" , "The Odyssey" }, + { "--- OM - Category" , "OM - Category ---"}, + { "旅行模式" , "Odyssey Mode" }, + { "随机模式" , "Odyssey Gacha" }, // Category + { "旅行体验" , "Odyssey Demo" }, + // Mini Games + { "--- OM - Odyssey Mode" , "OM - Odyssey Mode ---" }, + { "旅行:生存" , "Odyssey\nSurvival" }, + { "旅行:守护" , "Odyssey\nLast Stand" }, + // { "旅行:炼狱" , "Odyssey\nPurgatory" }, + { "--- OM - Odyssey Gacha" , "OM - Odyssey Gacha ---" }, + { "随机塔防" , "Randomized\nZombiesTD" }, + { "超级随机" , "Odyssey Gacha" }, // Level + { "十旗挑战\n究极随机" , "Odyssey Gacha\n12-Lane" }, // 12-Lane + { "等价交换2" , "Equal Exchange 2" }, + { "超级传送带" , "Arsenal Delivery" }, + { "大麦之战" , "Barley Battle!" }, + // Odyssey Gacha - Endless + { "模仿" , "Imitater" }, + { "真正的超级随机" , "Odyssey Gacha\nUnleashed" }, + { "大麦之战2\n拆拆乐" , "Barley Battle 2!\nFission" }, + { "大麦之战2:拆拆乐" , "Barley Battle 2! Fission" }, + // Odyssey Demo + { "--- OM - Mini Games" , "OM - Mini Games ---" }, + { "诸神" , "The Gods" }, + { "诸神:升级" , "The Gods: Trial of Ascension" }, // In-Game + { "诸神2" , "The Gods 2" }, + { "诸神:末世重生" , "The Gods: Trial of Rebirth" }, // In-Game + { "末世重生" , "The Gods 2" }, // Ten-Flag String + // ZombiesTD 4 + { "阳光保龄球" , "Solar-nut Bowling" }, + // ZombiesTD 5 + { "诸神3" , "The Gods 3" }, + { "诸神:坚如磐石" , "The Gods: Trial of Endurance" }, + { "黑曜石巨人的复仇" , "Abyssal Gargantuar's\n Vengeance" }, + { "黑曜石武装巨人的复仇" , "Abyssal Gargantuar's Vengeance"}, + { "诸神:全军出击" , "The Gods\nPantheon" }, + + // UI - Odyssey Gameplay + { "-------UI - Odyssey Gameplay" , "UI - Odyssey Gameplay-------" }, + { "刷新选项" , "Reroll" }, + { "放弃增益" , "Skip" }, + { "增益" , "Modifiers" }, + { "当前增益" , "Current Modifiers" }, + + // Strings - Adventure Mode + { "-------Strings - Adventure Mode" , "Strings - Adventure Mode-------" }, + { "--- AM - Old Version" , "AM - Old Version ---" }, + { "试试把豌豆种到向日葵上面" , "Try planting Peashooters on top of Sunflowers." }, + { "手里拿着植物时可以融合的植物会发光" , "Plants eligible for fusion will glow when you're holding another plant." }, + { "坚果融合后可以回满血哦" , "When Wall-nuts are fused, their Toughness is restored." }, + { "手套可以自由移动或融合植物" , "Gloves can be used to move or fuse plants manually." }, + { "礼盒可开出基础植物,亦可作为任意基础植物进行融合" , "Plant Giftbox can spawn basic plants.\nIt can also be used as any basic plant for fusion." }, + { "僵尸掉落的铁桶可以放到豌豆射手和坚果墙上" , "The buckets dropped by zombies \ncan be placed on the Peashooters and Wall-Nuts." }, + { "高坚果作为紫卡只能放在坚果墙上" , "Tall-nuts can only be planted on top of existing Wall-nuts." }, + { "一个格子里可以放3个小喷菇" , "You can stack upto three Puff-shrooms in one grid." }, + { "小秘密:小喷菇+向日葵=阳光菇" , "Try to use Sun-shrooms instead of Sunflowers in this map.\nFusion Formula: Puff-shrooms + Sunflower = Sun-shroom" }, + { "肥料可用于给植物回血,更多用法自行探索" , "Fertilizer can be used to restore plants' Toughness.\nThere are other uses you can explore." }, + { "毁灭大喷菇要手动点击哦" , "You can make a Soot-shroom by fusing a Fume-shroom and Doom-shroom.\nTo make Soot-shroom attack, you need to click it manually." }, + { "橄榄帽可以放到高坚果上" , "Football Helmets can be placed on Tall-Nuts." }, + { "忧郁菇作为紫卡只能放在大喷菇上" , "Gloom-shrooms can only be planted on top of existing Fume-shrooms." }, + { "听说了吗?有的睡莲头上会长植物" , "Have you heard that Lily Pad can have plants grow on their heads?" }, + { "传说有些僵尸被刺红温了更容易受伤" , "Legend has it that some zombies are \nmore vulnerable to damage when they look red...\nTry fusing a Scorchweed to inflict the Enflamed debuff." }, + { "地刺王作为紫卡只能放在地刺上" , "Spikerocks can only be planted on top of existing Spikeweed." }, + { "海光菇的效率似乎比阳光菇还要高" , "Sea Sun-shroom, when fully grown, can release 50 Suns per output.\nTry planting a couple or more to boost your efficiency." }, + { "猫尾草作为紫卡只能放在睡莲上" , "Cattail can only be planted on top of existing Lily Pads." }, + { "路灯花会为周围3*3范围格子提供1点光照等级" , "Plantern can provide 1 Lumos Level in a 3x3 Grid."}, + { "光系植物随着所在格子的光照等级增加而变强" , "Lumos plants become stronger as the Lumos Level of the grid they are on increases." }, + { "木锤会送一只僵尸归西" , "The Mallet can send a group of zombies towards their doom." }, + { "试试将磁力菇吸到的物体放到磁力南瓜或磁力杨桃上" , "Try placing the objects attracted by the Magnet-shroom\nonto the Pumpkin Lure or Starlure." }, + { "注意到磁力菇边上白色的线了吗,将他们都连起来" , "Did you notice the white lines next to the Magnet-shroom? Connect them all together\n to strengthen some of your Magnet-shroom fusions." }, + { "使用金盏花赚钱!对金银植物使用咖啡豆吧!花钱也送阳光!" , "Use Marigolds to earn money!\nUse Coffee Beans on Gold and Silver Plants!\nSpending Coins earns you Sun!" }, + { "--- AM - New Version" , "AM - New Version ---" }, + // Level 1 + { "--- AM - Level 1" , "AM - Level 1 ---" }, + { "欢迎来到植物大战僵尸融合版。" , "Welcome to Plants vs. Zombies Fusion" }, + { "这里有着许多有趣的新植物和新玩法。" , "There are many interesting new plants and new ways to play here." }, + { "让我们先从资源获取开始吧!" , "Let’s start with resource acquisition!" }, + { "请先种下一株向日葵。" , "Please plant a Sunflower first." }, + { "向日葵是很重要的生产植物,未来的阳光资源都靠她了!\n现在,试着把豌豆种到向日葵上" , "Sunflowers are very important Sun producers.\nNow try planting a Peashooter on top of the Sunflower." }, + { "很好,你已经学会了融合版最基础的操作!\n现在试试融合一个机枪射手!在豌豆上不断种豌豆就好!" , "Very good, you have learned the most basic operation of PvZ Fusion!\nNow try to fuse a Gatling Pea! Just keep planting Peashooters on top of another Pea." }, + { "干得不错!种植更多的植物,抵御僵尸的入侵吧!" , "Good job! Grow more plants to resist the invasion of zombies!" }, + // Level 4 + { "--- AM - Level 4" , "AM - Level 4 ---" }, + { "恭喜你解锁了手套,这是非常重要的道具" , "Congratulations on unlocking the Gloves, this is a very important item." }, + { "使用手套可以挪动植物,也可以使用手套挪动植物进行融合" , "You can use the Gloves to move plants somewhere else, or move a plant over another plant to initialize fusion." }, + { "现在试试将这个双子向日葵移动到坚果后面去" , "Now try moving the Twin Sunflowers behind the Cherry-nut." }, + { "你已经学会使用手套了!种植更多的植物,抵御僵尸的入侵吧!" , "You've learned how to use the Gloves! Grow more plants to resist the invasion of zombies!" }, + // Level 7 + { "--- AM - Level 7" , "AM - Level 7 ---" }, + { "礼盒,能开出全部的基础植物" , "The Plant Giftbox can produce all basic plants." }, + { "现在试试将礼盒放到这个双发射手上" , "Now try putting the Plant Giftbox on this Repeater." }, + { "你已经学会了如何使用礼盒!让我们进行下一步吧!" , "You've learned how to use the Plant Giftbox! Let’s move on to the next step!" }, + { "注意看1路有一个樱桃读报僵尸!用樱桃坚果防御他的子弹吧!" , "Pay attention to the Cherryshooter Newspaper Zombie on the first row!\nDefend against his bullets with Cherry-nuts!" }, + { "干得好!种植更多的植物,抵御僵尸的入侵吧!" , "Well done! Grow more plants to resist the zombie invasion!" }, + // Level 8 + { "--- AM - Level 8" , "AM - Level 8 ---" }, + { "你是否想过把僵尸的装备放到植物身上?" , "Have you ever thought about putting zombie equipment on plants?" }, + { "击败1路这个铁桶坚果僵尸!注意不要使用樱桃炸弹和大嘴花!" , "Defeat this Buck-nut Zombie by using peas! Be careful not to use Cherry Bombs and Chompers!" }, + { "点击僵尸掉落的铁桶,放到豌豆射手或者坚果墙上吧!" , "Click on the Iron Bucket dropped by the zombie and place it on the Peashooter or Wall-nut!" }, + { "铁系植物!你前期的好伙伴!" , "It's an Iron plant! A good partner in the early stage!" }, + { "种植更多的植物,抵御僵尸的入侵吧!" , "Excellent! Grow more plants to resist the zombie invasion!" }, + // Level 10 + { "--- AM - Level 10" , "AM - Level 10 ---" }, + { "小喷菇是黑夜里十分重要的植物" , "The Puff-shroom is a very important plant in this dark night..." }, + { "往小喷菇聚落里面融合可以直接得到3个小喷菇的融合体" , "You can get a fusion of 3 Puff-shrooms by fusing into a Puff-shroom stack." }, + // Level 13 + { "--- AM - Level 13" , "AM - Level 13 ---" }, + { "你解锁了肥料,定期在地图左上角出现" , "You unlocked the Fertilizer, which appears periodically in the upper left corner of the map." }, + { "肥料可以让阳光菇立即长大" , "Fertilizers can make the Sun-shroom grow immediately." }, + { "可以让大嘴花立即吞咽" , "It also enables Chomper and its fusions to swallow instantly, allowing them to eat another zombie right away." }, + { "总之肥料总是可以让植物进入下一阶段" , "In short, the Fertilizer always allows plants to progress to the next stage." }, + { "这里有一个坚果墙,试试给他肥料会有什么效果" , "Here's a Wall-nut, try giving it a Fertilizer to see what happens." }, + { "肥料可以充当紫卡的作用,直接升级一些植物" , "Fertilizers can act as a purple card, directly upgrading certain plants." }, + { "现在试试用肥料点击这个大嘴坚果" , "Now try using Fertilizer on this Chomp-nut." }, + { "肥料可以给植物回满血" , "Fertilizer can fully restore a plant's Toughness." }, + // Level 15 + { "--- AM - Level 15" , "AM - Level 15 ---" }, + { "让我们来看看寒冰系的新功能:冻结值" , "Let's take a look at the mechanics of the Cryo System: Cryo Points" }, + { "寒冰类植物的攻击都会附带冻结值\n当冻结值满时僵尸会被冻结并清空冻结值,冻结的僵尸受到寒冰类子弹的伤害都将x4" , "Ice-type plants' attacks will add Cryo Points to the Cryo Value. \r\nWhen the Cryo Value is full, zombies will be inflicted with the Frozen debuff and the Cryo Value will be reset. \r\nFrozen zombies will take x4 damage from ice-type projectiles." }, + { "僵尸的冻结值上限会随着冻结次数的增加而增加" , "The Cryo Value threshold of zombies will increase with each Frozen debuff inflicted.\r\n The first threshold is 100 Cryo Points, the next will be 200, then 300, then 400.\r\n The max threshold is 400 Cryo Points." }, + // Level 22 + { "--- AM - Level 22" , "AM - Level 22 ---" }, + { "水草子弹是水路中最强大的子弹" , "Kelps are the most powerful bullets in the water lanes." }, + { "让我们来看看这个一百万血的机械海豚僵尸是怎么被轻松干掉的" , "Let's see how this one million health Zombarine is easily taken down." }, + { "水草子弹命中水里的僵尸会造成额外的百分比伤害\n击中30次以上会直接秒杀僵尸!" , "Kelps deal additional percentage damage to zombies in the water.\r\nHitting more than 30 times will instantly kill the zombie!" }, + // Level 24 + { "--- AM - Level 24" , "AM - Level 24 ---" }, + { "让我们来看看僵尸的一种新状态:红温" , "Let's take a look at the mechanics of a new zombie debuff: Enflamed." }, + { "当僵尸处于红温状态时会额外受到50%的伤害" , "When a zombie is inflicted with the Enflamed debuff, it will take an additional 50% damage." }, + { "红温的僵尸死亡时会对附近的僵尸造成100点伤害并传递红温效果" , "When an Enflamed zombie dies, it will deal 100 damage to nearby zombies and spread the Enflamed debuff." }, + // Level 30 + { "--- AM - Level 30" , "AM - Level 30 ---" }, + { "路灯花在这里发挥着比原版更强大的作用" , "The Plantern plays a more powerful role here than in the original version." }, + { "让我们来看看路灯花的新系统:光照系统" , "Let's take a look at the new system for the Plantern: the Lumos System." }, + { "路灯花会以自己为中心3x3范围的格子提供1点光照等级" , "The Plantern provides 1 Lumos Level in a 3x3 grid centered around itself." }, + { "路灯花的融合植物在路灯花的影响下会变得更加强大" , "The fused plants of the Plantern become even stronger under its influence." }, + { "光照越高,植物就越强,一般的光系植物在3点光照等级达到最强状态" , "The higher the Lumos Level, the stronger the plant. Most light-based plants reach their maximum strength at 3 Lumos Levels." }, + { "光系植物在路灯花的影响下会变得更加强大,种植更多的植物,抵御僵尸的入侵吧!" , "Plantern-based fusions become even stronger under the influence of the Plantern.\nPlant more to fend off the zombie invasion!" }, + // Level 35 + { "--- AM - Level 35" , "AM - Level 35 ---" }, + { "让我们来看看磁力菇带来的新系统\n磁力系统" , "Let's take a look at the new system brought by the Magnet-shroom: the Magnetic System." }, + { "如果一株磁性植物周围8格有另一株磁性植物\n则称两个植物处于同一个磁力系统中,并且中间会有白线连接" , "If a magnetic plant has another magnetic plant within the 8 surrounding tiles, \r\nthey are considered to be in the same magnetic system, and a white line will connect them." }, + { "同一个磁力系统中的植物是可以无限多的\n只需任意一株植物满足要求都可以纳入系统中" , "Plants within the same magnetic system can be unlimited in number. \r\nAs long as any plant meets the requirements, it can be included in the system." }, + { "只要磁力链没有断开,都看成在是同一个磁力系统中" , "As long as the magnetic chain remains unbroken, all plants are considered to be in the same magnetic system." }, + { "但是如果没有相连,那就是另一个磁力系统" , "However, if they are not connected, they belong to a different magnetic system." }, + { "你可以在中间补充一些植物将两个系统连起来" , "You can place plants in between to connect the two systems." }, + { "部分植物如超级杨桃等会受到磁力系统的影响\n种植更多的植物,抵御僵尸的入侵吧!" , "Some plants, such as Stardrop, will be buffed by the magnetic system. \r\nPlant more to defend against the zombie invasion!" }, + // Level 42 + { "--- AM - Level 42" , "AM - Level 42 ---" }, + { "让我们来看看金盏花带来的新系统\n金钱系统" , "Let’s take a look at the new system brought by Marigold: the Money System." }, + { "种植金盏花会在屏幕左下角启用钱币" , "Planting Marigolds will activate coins in the bottom-left corner of the screen." }, + { "赚的钱可以对银植物升级\n点击屏幕左下角的咖啡豆,对卷心菜使用吧" , "The money earned can be used to upgrade Silver Plants.\r\nClick on the coffee bean (or use the hotkey) in the bottom-left corner of the screen to use it on the Cabbage-Pult." }, + { "升级时植物会释放一次大招,给予金植物也可以释放大招\n同时每次花钱都能赠送阳光!" , "When upgrading, plants will unleash an ultimate, and Golden Plants can also unleash their ultimate.\r\nAdditionally, every time you spend money, you will receive Sun as a bonus!\r\nEach 500 coins spent will give 25 Suns." }, + { "在金盆上给植物释放大招时会根据花费联动其他金盆上的植物释放大招\n现在试试给金玉米投手释放大招" , "When releasing an ultimate on the Golden Pot,\r\nit will trigger the ultimates of other plants on nearby Golden Pots based on the cost.\r\nNow, let's try using the ultimate on the Golden Kernel!" }, + + // Strings - Advanced Challenge + { "-------Strings - Advanced Challenge" , "Strings - Advanced Challenge-------" }, + { "豌豆+樱桃+樱桃" , "Unlock Explod-o-shooter when you finish the challenge.\nFusion Formula: Peashooter + Cherry Bomb + Cherry Bomb" }, + { "豌豆+坚果+大嘴花" , "Unlock Chewzilla when you finish the challenge.\nFusion Formula: Peashooter + Wall-Nut + Chomper" }, + { "大喷菇+胆小菇+魅惑菇" , "Unlock Charm-shroom when you finish the challenge.\nFusion Formula: Fume-shroom + Scaredy-shroom + Hypno-shroom" }, + { "火炬+辣椒+辣椒" , "Unlock Infernowood when you finish the challenge.\nFusion Formula: Torchwood + Jalapeno + Jalapeno" }, + { "水草+窝瓜+三线" , "Unlock Krakerberus when you finish the challenge.\nFusion Formula: Tangle Kelp + Squash + Threepeater" }, + { "大喷菇+寒冰菇+毁灭菇" , "Unlock Doomberg-shroom when you finish the challenge.\nFusion Formula: Fume-shroom + Ice-shroom + Doom-shroom" }, + { "杨桃+路灯花+磁力菇" , "Unlock Stardrop when you finish the challenge.\nFusion Formula: Starfruit + Plantern + Magnet-shroom" }, + { "仙人掌+南瓜+三叶草" , "Unlock Bloverthorn Pumpkin when you finish the challenge.\nFusion Formula: Cactus + Pumpkin + Blover" }, + { "西瓜+卷心菜+玉米" , "Unlock Salad-pult when you finish the challenge.\nFusion Formula: Cabbage-pult + Kernel-pult + Melon-pult" }, + { "金伞+大蒜或金蒜+伞" , "Unlock Alchemist Umbrella when you finish the challenge.\nFusion Formula:\nGolden Umbrella + Garlic OR Golden Garlic + Umbrella Leaf" }, + + // Strings - Odyssey Demo + { "-------Strings - Odyssey Demo" , "Strings - Odyssey Demo-------" }, + { "小心你没见过的僵尸!" , "Let's do a showcase of the first five Odyssey Plants of the game!\nBe careful of new zombies that you haven't seen before..." }, // Odyssey Demo 6 + { "超级樱桃射手+樱桃机枪射手" , "Fusion Formula: Explod-o-shooter + Gatling Cherry" }, + { "火爆窝瓜+窝炬" , "Fusion Formula: Spicy Squash + Infernowood" }, + { "火爆窝瓜+超级火炬" , "Fusion Formula: Spicy Squash + Infernowood" }, + { "魅惑菇+魅惑菇" , "Fusion Formula: Hypno-shroom + Hypno-shroom" }, + { "超级大喷菇+寒冰魅惑菇" , "Fusion Formula: Frostveil-shroom + Doomberg-shroom" }, + { "超级大嘴花+樱桃大嘴花" , "Fusion Formula: Chewzilla + Cherry Chomper" }, + { "超级杨桃+磁力仙人掌" , "Fusion Formula: Stardrop + Magnethorn" }, + { "超级大喷菇+寒冰忧郁菇" , "Fusion Formula: Doomberg-shroom + Snowgloom-shroom" }, + { "超级南瓜+磁力三叶草" , "Fusion Formula: Bloverthorn Pumpkin + Magblover" }, + { "超级投手+蒜瓜" , "Fusion Formula: Salad-pult + Garlic-pult" }, + { "寒冰加农炮+寒冰毁灭菇" , "Fusion Formula: Cryo Cannon + Cryodoom-shroom" }, + { "超级伞+菜伞" , "Fusion Formula: Alchemist Umbrella + Umbrella Kale" }, + { "三线+火爆辣椒x3" , "Fusion Formula: Threepeater + Jalapeno x3" }, + { "超级魅惑菇+磁力魅惑菇" , "Fusion Formula: Charm-shroom + Charm Magnet" }, + + // Strings - Mini Games + { "-------Strings - Mini Games" , "Strings - Mini Games-------" }, + { "这一关只能种植或融合小喷菇!" , "In this level, you can only grow or fuse Puff-shrooms." }, // Compact Planting + { "击败僵尸以获取阳光" , "Zombies will only move on the darkened soil, so plan your\ndefenses accordingly. You can only obtain Sun by defeating zombies." }, // ZombiesTD + { "这关手套没有冷却,请放心使用" , "The Glove's cooldown is reduced to 0. Use it effectively to win this mini-game." }, // The Gods + { "右键拖拽移动屏幕,滚轮缩放屏幕" , "Hold your right mouse key and drag to move the screen.\n Use your scroll wheel to zoom in or zoom out." }, // Preview 10.0 + { "向狙击豌豆售卖机枪来获得奖励" , "Drag over a Gatling Pea on top of a Sniper Pea to spawn another Sniper Pea." }, // ZombiesTD 3 + { "无法抓取下半部分植物" , "You can only grab plants from the top half of the lawn." }, // Mirrors Like You See 'Em + { "只能在上半地图放植物" , "You can only place plants on the upper half of the lawn." }, // Mirrors Like You See 'Em + { "保护你的吸金磁" , "Protect your Gold Magnet from the zombies.\nIf the plant is destroyed, the game will end." }, // Protect The Gold Magnet + { "使用豌豆、双发、裂荚、机枪来传递胆小菇的子弹", "Use your Scaredy-shroom to make your Peashooters, Repeaters,\nSplit Peas and Gatling Pea shoot peas. When your peas hit other\nprojectile-firing plants, they will also fire their projectiles at a constant rate." }, // Scaredy's Dream + + // Strings - Garden Defense + { "-------Strings - Garden Defense" , "Strings - Garden Defense-------" }, + { "使用花园中第1页第4行的植物参战!" , "Only the plants in the 1st page, 4th row of your Zen Garden \ncan be used in this mode.\nTake care of your plants and they will return the favor in your lawn!" }, + + // Strings - Odyssey Mode + { "-------Strings - Odyssey Mode" , "Strings - Odyssey Mode-------" }, + //// Unlocks + { "解锁究极樱桃战神,超级大嘴花+樱桃大嘴花" , "Unlock Cherrizilla: Chewzilla + Cherry Chomper" }, + { "解锁究极樱桃机枪,樱桃机枪+超级樱桃射手" , "Unlock Gatling Cherrybomber: Gatling Cherry + Explod-o-shooter" }, + { "解锁究极大喷菇,超级大喷菇+寒冰魅惑菇" , "Unlock Doominator-shroom: Doomberg-shroom + Frostveil-shroom" }, + { "解锁究极窝炬,超级火炬+火爆窝瓜" , "Unlock Squashed Infernowood: Spicy Squash + Infernowood" }, + { "解锁究极杨桃,超级杨桃+磁力仙人掌" , "Unlock Magnetar: Stardrop + Magnethorn" }, + { "解锁究极忧郁菇,超级大喷菇+寒冰忧郁菇" , "Unlock Oblivion-shroom: Doomberg-shroom + Snowgloom-shroom" }, + { "解锁究极高坚果,寒冰高坚果+火焰高坚果" , "Unlock Obsidian Tall-nut: Frost Tall-nut + Scorch Tall-nut"}, + { "解锁究极投手,超级投手+蒜瓜" , "Unlock Wither-pult: Salad-pult + Garlic-pult" }, + { "解锁究极加农炮,寒冰加农炮+寒冰毁灭菇" , "Unlock Cob-livion Cannon: Cryo Cannon + Cryodoom-shroom"}, + { "解锁究极魅惑菇,超级魅惑菇+魅惑磁力菇" , "Unlock Charmatron-shroom: Charm-shroom + Charm Magnet" }, + { "解锁究极炮台,机枪炮台+黑曜石辣椒" , "Unlock Titan Apeacalypse Turret: Titan Pea Turret + Frostburnt Jalapeno" }, + //// Advanced Buffs + { "撒豆成兵:魅帝召唤间隔从30秒减为10秒,并解锁亚种魅后菇" , "Empress-shroom: Summon Interval → 10 Seconds | Enchantress-shroom Subspecies Unlocked" }, + { "精兵强将:魅帝能召唤究极僵尸" , "Empress-shroom: Can now summon Ultimate Zombies" }, + { "枕戈待旦:毁灭机枪不再需要休息,并解锁亚种毁灭机枪胆小菇" , "Gatling Doom: No more rest between every attack | Gatling Frenzy-shroom Subspecies Unlocked" }, + { "核能威慑:毁灭机枪每轮都能发射大子弹" , "Gatling Doom: Can now fire bullets of doom between every attack" }, + { "妙手回春:阳光帝果每次都能回满血" , "Twin Solar-nut: Can now restore to full health instead of 1500 each time" }, + { "无关痛痒:阳光帝果单次受伤降为10点" , "Twin Solar-nut: Toughness reduces by 10 for each hit instead of 50" }, + { "尸愁之路:玄钢地刺王伤害x5,并解锁亚种玄钢坚果" , "Spikesidian: Damage multiplied by 5 | Obsidian Spike-nut Subspecies Unlocked" }, + { "百炼成钢:玄钢地刺王现在获得95%减伤" , "Spikesidian: Gains 95% DMG Reduction" }, + { "熠熠生辉:单个阳光提供的阳光量大幅增加" , "Each Sun now gives double the value" }, + { "极速战备:手套冷却速度翻倍" , "Glove's cooldown is halved" }, + { "强力打击:植物的攻击力增加20%" , "Plants' Damage is increased by 20%" }, + { "精准打击:僵尸受到的伤害增加20%" , "Zombies' receive 20% more damage" }, + { "腐化:僵尸每受到一次伤害,下次受到的伤害增加5%" , "Each time a Zombie is damaged, the next instance of damage to it is increased by 5%" }, + { "全副武装:开启在游戏过程中自选卡牌的功能" , "You now have to option to re-pick your Plant Loadout during the game" }, + { "合理投资:词条刷新次数+2" , "Modifier reroll times + 2" }, + { "怒火攻心:红温增伤幅度从50%增至150%,并且火焰豌豆类会对僵尸附加红温效果" , "Enflamed damage multiplier → 150%, and ignited peas can now inflict the debuff" }, + { "至极手速:手套挪动植物不再消耗冷却" , "Moving plants no longer has a cooldown" }, + { "势如破竹:冰锥的可以无限穿透,小冰机和小光机的攻击力增加50%" , "Gatling Icicle-shroom & Sunburst-shroom: Icicles Pierce Infinitely | 50% Increased Damage" }, + { "冻彻心扉:冰锥的对冻结的单位造成伤害提升至10倍,并解锁亚种阳光机枪小喷菇" , "Gatling Icicle-shroom: Increased damage to Frozen zombies by 10 times | Gatling Sunburst-shroom Subspecies Unlocked" }, + { "斗转星移:所有的流星冷却缩短为原来的1/2,且场上每多一个究极杨桃则伤害提升150" , "All Meteors' attack cooldowns are halved | DMG increased by 150 for every Magnetar in the field | Gravitron Subspecies Unlocked" }, + { "灯火通明:全场光照等级+4" , "Adds 4 Lumos Levels for the entire field" }, + { "三位一体:激光南瓜的僚机增加至3个" , "Laser Pumpkin: Wingmen Amount → 3" }, + { "连锁反应:激光南瓜与丑壳在同一磁力系统中时也享受丑壳效果,并解锁亚种樱桃南瓜" , "Laser Pumpkin: Inherits Joker Pumpkin's effects when in the same Magnetic System | Blast Pumpkin Subspecies Unlocked" }, + { "人工智能:绿宝石伞现在可以自动开大,并解锁亚种红宝石伞" , "Midas Umbrella: Activates ultimate automatically if zombies are near. 7.5 seconds cooldown | Aegis Umbrella Subspecies Unlocked" }, + { "弹射起步:绿宝石伞可以让子弹弹到前方其他绿宝石伞上并叠加伤害(无上限)" , "Midas Umbrella: Now bounce bullets with other Midas Umbrella" }, + { "聚光盆:获得3000阳光然后使你的阳光翻倍" , "Gain 3000 Sun, then double your total amount of Sun after" }, + { "运斤如风:锤子冷却降低为6秒" , "Mallet's cooldown is reduced to 6 seconds" }, + { "全息制冷:卡牌冷却减半" , "Plants' recharge are halved" }, + { "致命一击:僵尸受到超过1800伤害(计算减伤之后)时额外受到1800伤害" , "Zombies take an additional 1800 damage when they take more than 1800 damage (after damage reduction)" }, + { "拆分:使用手套点击植物后可以拆解植物,有强制20秒的拆解冷却" , "Clicking on the same plant when you have it on your Gloves will disassemble it | 20 seconds cooldown" }, + { "肉身成圣:魅惑僵尸获得1000%啃咬伤害加成和80%减伤" , "Charmed Zombies gain 1000% bite damage bonus and 80% damage reduction"}, + { "百步穿杨:浴火三线的子弹可以无限穿透" , "Phoenix Threepeater: Bullets can now pierce infinitely"}, + { "复制中心:模仿者冷却时间大幅降低" , "Imitater's recharge is greatly reduced" }, + { "连连看:两株相同植物一上一下时获得50%伤害加成和50%伤害减免" , "When two identical plants are placed one above the other, they gain a 50% damage bonus and a 50% damage reduction"}, + { "特制弹药:魔法猫尾草的僚机攻击力x3" , "Magicat Nettle: Wingman deals 3x more DMG" }, + { "一针见血:魔法猫尾草的基础攻击力x5" , "Magicat Nettle: Basic attack deals 5x more DMG" }, + { "我是传奇:究极樱桃战神和究极高坚果同时在场时,战神的攻击变成范围伤害,血量不再有上限,究高额外获得90%伤害减免" , "When Cherrizilla and Obsidian Tall-nut are both present, Cherrizilla's attack deals AoE damage and no longer has a max Toughness cap, and Obsidian Tall-Nut gains a 90% DMG Reduction" }, + { "真正的樱桃炸弹:植物的爆炸樱桃子弹在接下来的3轮内升级为纯粹的樱桃爆炸" , "True Cherry Bomb: Plant's Cherry Bomb Bullets upgrades to Cherry Bomb Explosions for the next 3 rounds" }, + { "真正的毁灭菇:植物的毁灭菇子弹在接下来的3轮内升级为纯粹的毁灭菇爆炸" , "True Doom-shroom: Plant's Doom Bullets upgrades to Doom-shroom Explosions for the next 3 rounds" }, + { "可控核聚变:所有毁灭菇爆炸不留弹坑" , "Calamity-shroom: ALL Doom-shroom explosions no longer leave a crater" }, + { "人多势众:幻灭菇爆炸时召唤额外的魅惑巨人僵尸和魅惑冰车" , "Calamity-shroom: Now spawns extra Charmed Gargantuars and Zombonis when it explodes" }, + //// Ultimate Buffs + { "湮灭一击:究极樱桃战神能斩杀血量低于自己的僵尸" , "Cherrizilla: Can now kill zombies with less health than itself" }, + { "泰坦之躯:究极樱桃战神获得200%治疗加成,且单次受伤不超过500" , "Cherrizilla: 200% healing bonus and zombie damage is capped at 500" }, + { "力大砖飞:植物的爆炸樱桃子弹伤害x3" , "Gatling Cherrybomber: Cherry bomb bullets now deal 3x more DMG" }, + { "快速填装:降低究极樱桃机枪的攻击间隔至1秒" , "Gatling Cherrybomber: Attack Interval → 1 Second" }, + { "凛风刺骨:究极大喷菇的攻击力x3" , "Doominator-shroom: Fumes now deal 3x more DMG" }, + { "三尺之寒:提升究极大喷菇的冻结速度为3倍" , "Doominator-shroom: Increased freezing speed by 3 times" }, + { "事半功倍:降低究极窝炬生成窝瓜需要的子弹数至10" , "Squashed Infernowood: Bullets required to spawn a Spicy Squash → 10" }, + { "好事成双:究极窝炬每次可以生成两个窝瓜" , "Squashed Infernowood: Now spawns two Spicy Squash at a time" }, + { "流星雨:降低究极杨桃的攻击间隔至0.5秒" , "Magnetar: Attack Interval → 0.5 Seconds" }, + { "众星之力:究极杨桃的子弹基础攻击力翻倍并且攻击力不再有上限" , "Magnetar: Base damage is doubled and limiter (120) is removed" }, + { "万籁俱寂:究极忧郁菇亡语伤害增加到1000000" , "Oblivion-shroom: Damage on Death → 1,000,000" }, + { "以爆制爆:究极忧郁菇免疫爆炸,每吸收10000点爆炸伤害将释放毁灭菇爆炸" , "Oblivion-shroom: Now absorbs explosion damage. When 10,000 damage is absorbed, a Doom-shroom explosion is released" }, + { "见者有份:究极投手散射概率提升至100%" , "Wither-pult: Spread-fire is now a 100% chance"}, + { "瓜熟蒂落:究极投手附带瓜盆效果" , "Wither-pult: Melon Pot's traits are now inherited" }, + { "中心爆破:究极大炮的中心点爆炸伤害x4" , "Cob-livion Cannon: Main Blast damage is multiplied by 4" }, + { "兵贵神速:究极大炮的装填时间降为原来的1/3" , "Cob-livion Cannon: Reload Time → 12 Seconds" }, + { "冰淬火炼:黑曜石高坚果受到寒冰菇效果回血10000,火爆辣椒效果回满血" , "Obsidian Tall-nut: Recovers 10,000 HP when affected by Ice-shrooms, and recover full HP when affected by Jalapeno" }, + { "两肋插刀:黑曜石高坚果会代替左右两株植物受伤" , "Obsidian Tall-nut: Can now absorb the damage directed to the two plants on its left and right" }, + { "普度众生:究极魅惑菇子弹的魅惑血量阈值从50%提高到100%" , "Charmatron-shroom: Charm HP threshold increased from 50% to 100%" }, + { "永动机:究极魅惑菇永远处于高能状态,且攻击间隔缩短至1秒" , "Charmatron-shroom: Now always in a fully-charged state | Attack Interval → 1 Second" }, + { "阻冲之:究极炮塔的攻击力和击退强度大幅提高" , "Titan Apeacalypse Turret: Attack Power and Knockback Massively Increased" }, + { "狂战士:究极炮塔血量越低防御力越高,当血量低于100时免疫低于100的伤害" , "Titan Apeacalypse Turret: Lower Health → Higher Defense | Immune to damage below 100" }, + // Other + { "获得5000阳光" , "Gain 5000 Sun" }, + + // Odyssey Gacha + { "-------Strings - Odyssey Gacha" , "Strings - Odyssey Gacha-------" }, + { "抓取植物后点击自身即可拆解" , "When holding a fused plant, clicking on it again will disassemble it." }, + + // Strings - Playing + { "-------Strings - Playing" , "Strings - Playing-------" }, + //// More Zombies + { "更多的僵尸要来了" , "More zombies are coming..." }, + { "更多的僵尸要来了!" , "More zombies are coming..." }, + { "一大波僵尸正在接近!" , "A HUGE WAVE OF ZOMBIES IS APPROACHING" }, + //// Ineligible Fusions + { "通关挑战模式解锁配方" , "This fusion has not been unlocked yet.\n Complete its Advanced Challenge first in Challenge Mode." }, + { "该配方仅旅行模式可用" , "This fusion is only available in Odyssey Mode." }, + { "不能在陆地上融合!" , "This cannot be fused on land." }, + { "不能在水上融合!" , "This cannot be fused on water." }, + { "只能融合小喷菇!" , "Only fusions involving Puff-shrooms can be done." }, // Compact Planting + { "旅行到下一场景时抽取" , "This Odyssey fusion has not been unlocked yet.\n Unlock it by completing 3 rounds of a map and \nchoosing it in the Modifier Selection." }, + { "进入下一轮时抽取" , "This Odyssey fusion subspecies has not been unlocked yet.\nUnlock it by completing 1 round and choosing the Modifier that unlocks it." }, + { "这一关不能融合!" , "Fusions are not allowed in this game mode." }, // The Gods + //// Notification + { "你为你的卡库新增了一种卡牌" , "A new plant is available in Plant Select." }, + { "你为你的花园找到了一株植物" , "You've found a new plant for your Zen Garden."}, + { "花园放不下更多的植物了" , "There is no more room for more plants in your Zen Garden." }, + { "无法抓取梯子下的植物" , "You can't move plants that are laddered." }, + { "拆解需要500阳光" , "Fission requires 500 Sun in order to activate."}, + { "该模式不能移动需要保护的植物" , "You cannot move plants that need to be protected on this mode." }, // ZombiesTD 4 and 5 + //// Coffee Bean + { "咖啡豆对这株植物似乎没有效果" , "The Coffee Bean has no effect on this plant." }, + //// Ultimate + { "大招需要一份咖啡豆" , "This ultimate requires 1 Coffee Bean." }, + { "大招需要两份咖啡豆" , "This ultimate requires 2 Coffee Beans." }, + { "大招需要三份咖啡豆" , "This ultimate requires 3 Coffee Beans." }, + { "大招需要四份咖啡豆" , "This ultimate requires 4 Coffee Beans." }, + { "大招需要五份咖啡豆" , "This ultimate requires 5 Coffee Beans." }, + { "大招需要六份咖啡豆" , "This ultimate requires 6 Coffee Beans." }, + { "大招需要七份咖啡豆" , "This ultimate requires 7 Coffee Beans." }, + { "大招需要八份咖啡豆" , "This ultimate requires 8 Coffee Beans." }, + { "大招需要九份咖啡豆" , "This ultimate requires 9 Coffee Beans." }, + { "大招需要十份咖啡豆" , "This ultimate requires 10 Coffee Beans." }, + + // Strings - ZombiesTD 4 + { "-------Strings - ZombiesTD 4" , "Strings - ZombiesTD 4" }, + { "保护你的胆小菇" , "Protect your Shivery-shroom from the zombies. If the plant is destroyed, the game will end." }, + { "你证明了你的实力,为了迎接血量不断增加的僵尸,现在可以使用究极植物了" , "You've proven your worth, now you can use the Odyssey Plants." }, + + // Strings - ZombiesTD 5 + { "-------Strings - ZombiesTD 5" , "Strings - ZombiesTD 5" }, + { "保护你的超级保龄球坚果" , "Protect your Mecha-nuts from the zombies. If the plants are destroyed, the game will end." }, + //// Missions + { "当前任务:融合一个超级大喷菇\n任务奖励:手套无cd" , "Current Mission: Fuse a Doomberg-shroom\nCompletion Reward: Instant Gloves" }, + { "任务目标:存储5000阳光\n任务奖励:樱桃南瓜x2+究极忧郁菇x1" , "Current Mission: Have 5000 Total Sun\nCompletion Reward: Blast Pumpkin x2 & Oblivion-shroom x1" }, + { "任务目标:击败地图右侧出现的武装巨人!\n任务奖励:究极樱桃战神x2" , "Current Mission: Kill the Armed Gargantuar\nCompletion Reward: Cherrizilla x2" }, + { "任务目标:种植8个究极投手(已开放究极投手配方)\n任务奖励:究极忧郁菇*6" , "Current Mission: Plant 8 Wither-pults (Wither-pult Unlocked)\nCompletion Reward: Oblivion-shroom x6" }, + { "任务目标:击杀地图右侧出现的武装巨人\n任务奖励:究极加农炮x1" , "Current Mission: Kill the Armed Gargantuars\nCompletion Reward: Cob-livion Cannon x1" }, + { "任务目标:种植6个樱桃机枪射手\n任务奖励:解锁究极樱桃射手配方以及他的两个词条" , "Current Mission: Plant 6 Gatling Cherry\nCompletion Reward: Unlock Gatling Cherrybomber and its 2 Modifiers" }, + { "【僵尸血量获得大幅提升】任务目标:献祭你的全部究极加农炮\n任务奖励:解锁全部旅行词条" , "Zombies' HP have been greatly increased\nFinal Mission: Shovel ALL your Cob-livion Cannons\nCompletion Reward: Unlock all Odyssey Modifiers" }, + { "已经完成全部任务,解锁全部旅行词条,祝你好运!" , "All missions have been completed. The full strength of the Odyssey Fusions as well as its Modifiers\nis at your disposal. Good luck!" }, + + // Strings - NEW UPDATE + { "-------Strings - New Update" , "Strings - 2.2-------"}, + { "Player" , " " }, + { "冒险二周目戴夫选卡" , "Dave Picks Cards on\nAdventure NG+"}, + { "毁灭菇特效" , "Doom-shroom Visual Effect" }, + { "选卡" , "Selects Cards" }, + { "不选卡" , "Does Not Select Cards" }, + { "开启特效" , "Turned On" }, + { "关闭特效" , "Turned Off" }, + { "草坪" , "Lawn" }, + { "商店" , "Shop" }, + { "你确定要出售该植物吗" , "Are you sure you want to sell this plant?" }, + { "你确定要购买该植物吗" , "Are you sure you want to buy this plant?" }, + { "点击图鉴文本框即可翻页" , "Click on the text box to turn the page." }, + { "按下鼠标左键返回" , "Click anywhere to return." }, + { "点击任意位置返回" , "Click anywhere to return." }, + { "普通僵尸" , "Normal Zombies" }, + { "究极僵尸" , "Odyssey Zombies" }, + { "砸罐子" , "Vasebreaker" }, + { "连锁反应" , "Chain Reaction" }, + { "僵王博士的复仇" , "Dr. Zomboss' Revenge" }, + { "蹦极闪电战" , "Bungee Blitz" }, + { "宝石迷阵" , "Beghouled" }, + { "看星星" , "Seeing Stars" }, + { "诸神:花园保卫战" , "The Gods: Garden Defense" }, + { "使用花园中2~4行植物参战,相同类型的植物只能使用一株" , "Use the plants from the 2nd to 4th rows of the 1st Page of your Zen Garden\nto participate in this mini game. Only one plant of the same type can be used." }, + { "完成75次配对以赢得游戏" , "Complete 75 matches to finish this mini game." }, + { "词条" , "Modifiers" }, + { "配方已更新" , "Formulae Changed" }, + { "立即冷却手套完毕" , "The Gloves are instantly recharged." }, + { "通关冒险模式45关后解锁" , "Unlocked after completing Level 45 in Adventure Mode" }, + { "没有配对的植物了" , "There are no more plants left to make matches with." }, + + { "在三线射手上放置融合洋芋" , "Place the Jicamagic on top of the Threepeater." }, + { "双发射手" , "Repeater" }, + { "三线射手" , "Threepeater" }, + { "在磁力菇上放置融合洋芋" , "Place the Jicamagic on top of the Magnet-shroom." }, + { "小丑南瓜" , "Joker Pumpkin" }, + { "磁力菇" , "Magnet-shroom" }, + { "樱桃南瓜" , "Pump-Kaboom" }, + { "在中间的大嘴花上放置融合洋芋" , "Place the Jicamagic on top of the middle Chomper." }, + { "请按左中右的顺序放置以下植物\n大嘴花,大嘴花,大嘴花" , "Please place the following plants in order\nChomper, Chomper, Chomper"}, + + { "探索模式" , "Fusion Showcase" }, + { "机枪炮塔" , "Titan Pea Turret" }, + { "机枪炮台" , "Titan Pea Turret" }, // In-Game + { "更多的土豆雷" , "Explod-o-tato Mine" }, + { "南瓜武装" , "Titan Pumpkin\nBunker" }, + { "土豆小喷菇" , "Nugget-shroom" }, + { "土豆胆小菇" , "Spuddy-shroom" }, + { "巨型大嘴花" , "Titan Chomper Maw" }, + { "蒜喷菇" , "Foul-shroom" }, + { "魅惑三叶草" , "Hypnoblover" }, + { "樱桃火炬" , "Boomwood" }, + + { "传送带" , "Conveyor Belt" }, + { "已开启全部词条" , "Odyssey Modifiers - On" }, + { "未开启全部词条" , "Odyssey Modifiers - Off" }, + { "当前词条" , "Current Modifiers" }, + { "词条中可以自选开启某种词条" , "Modifiers in the Menu to select which Odyssey Modifiers to activate." }, + + // Strings - Dr. Zomboss' Revenge + { "锤子已解锁" , "Wooden Mallet Unlocked" }, + { "手套已解锁" , "Gloves Unlocked" }, + + { "进度(测试版)" , "Achievements" }, + { "植物大战僵尸融合版" , "PvZ Fusion"}, + + { "猫瓜+香蒲" , "Fusion Formula: Neko Squash + Cattail" }, + { "机枪炮台+黑曜石辣椒" , "Fusion Formula: Titan Pea Turret + Frostburnt Jalapeno" }, + + { "旅行挑战" , "Odyssey: Challenges" }, + { "旅行:炼狱" , "Odyssey\nPurgatory"}, + { "此模式难度极高,且锁定难度!祝你好运!" , "The difficulty in this mode is locked to the highest difficulty. Good luck!" }, // Odyssey: Purgatory + { "炼狱" , "Purgatory" }, + { "3旗前临时解锁《真正的毁灭菇》《真正的樱桃炸弹》词条", "Unlock the True Doom-shroom and True Cherry Bomb Modifiers before the 3 flags." }, // Purgatory + { "炼狱随机模式" , "Purgatory\nGacha" }, + { "群贤毕至" , "The Cream of\nthe Crop" }, + + // Strings - ZombiesTD6 + + { "当前任务:融合2个超级火炬\n任务奖励:4樱桃机枪", "Current Mission: Fuse 2 Infernowood\nCompletion Reward: 2 Gatling Cherry" }, + { "任务目标:融合4个火炮\n任务奖励:浴火三线x2" , "Current Mission: Fuse 4 Pyro Cannon\nCompletion Reward: 2 Phoenix Threepeater" }, + { "任务目标:融合4个焦黑三线\n任务奖励:浴火三线的配方和他的两个词条" , "Current Mission: Fuse 4 Scorched Threepeater\nCompletion Reward: Phoenix Threepeater Fusion and its Modifiers Unlocked" }, + { "任务目标:存储5000阳光\n任务奖励:连连看词条和模仿者减cd词条" , "Current Mission: Have 5000 Sun\nCompletion Reward: Unlocks the following Modifiers: Imitator CD Reduced & Identical Plants Modifier\n(When two identical plants are placed one above the other, they gain a 50% damage bonus and a 50% damage reduction)" }, + { "任务目标:合成8个寒冰机枪\n任务奖励:手套无cd+究极窝炬+他的两个词条" , "Current Mission: Fuse 8 Gatling Snow\nCompletion Reward: Gloves No CD, Squashed Infernowood, and its Modifiers Unlocked" }, + { "你已经完成全部任务,祝你好运!" , "You have completed all missions! Good luck!" }, + + { "旅行游戏" , "Odyssey: Mini Games" }, + { "诸神4" , "The Gods 4" }, + { "诸神:逆流而上" , "The Gods: Trial of Valor" }, // In-Game + { "僵尸对战" , "Zombie Battle" }, + { "按V键切换僵尸手套来挪动僵尸" , "Press V to Toggle Zombie Gloves to move Zombies." }, + { "单枪匹马" , "Solitary Spear" }, + { "冰天雪地" , "ZombiesTD 6" }, + { "塔防:冰天雪地" , "ZombiesTD: A World of Ice and Snow" }, + { "旅行:轮回" , "Odyssey\nReincarnation" }, + { "随机融合模式" , "Odyssey Gacha\nFusion Mode" }, + { "随机融合模式2" , "Odyssey Gacha\nFusion Mode 2" }, + { "随机:升级" , "Odyssey Gacha\nUpgrade" }, + { "点击射手、投手来操控(按WASD)(僵尸显血由W调整为R)\n使用手套点击植物点击自己来升级,融合时重置植物等级,但会返还升级消耗的阳光\n阳光来源为铲植物或者击杀僵尸,礼盒前期不会开强力植物,会随关卡进程逐步解锁\n卡槽中的4个空位不定期刷新,可用于直接购买植物" , "Control attack plants with WASD (Zombie Health Display: R). Use Gloves to click a plant, \nthen click again to upgrade. Fusing resets plant level but refunds Sun. Get Sun by \nshoveling plants or killing zombies. Plant Giftbox unlocks \nstronger plants as you progress. The 4 empty card slots refresh \nperiodically for direct plant purchases."}, + + { "旅行冒险(敬请期待)" , "Odyssey: Adventure" }, + + // Odyssey + + { "免费刷新" , "Free Reroll" }, + { "消耗分数刷新" , "Reroll (Costs Points)" }, + { "分数不够" , "Not Enough Points" }, + // Solitary Spear Strings + { "WASD控制植物移动,Q植物显血,R僵尸显血\n植物碰撞道具箱视为拾取道具" , "Use WASD to move the plant. Q will show the plant's health. R will show the zombie's health.\nColliding with a Giftbox will give you a buff." }, // Solitary Spear + { "随机道具箱已刷新" , "A Giftbox has been refreshed." }, // Solitary Spear + { "获得10%生命偷取,持续15秒!" , "Gain 10% lifesteal for 15 seconds!" }, + { "植物血量已满" , "Toughness Fully Restored!" }, + { "僵尸军团前来助阵!", "The Zombie reinforcements have come to help!" }, + { "僵尸受到伤害x2,持续15秒!" , "Zombies take 2x damage for 15 seconds!" }, + { "意外之喜!" , "What a pleasant surprise!" }, + { "寒冰菇支援!" , "Ice-shroom has come to assist!" }, + { "大荒星陨!" , "A star falls on your lawn!" }, + { "火爆辣椒支援!" , "Jalapeno has come to assist!" }, + { "坚果保龄球!" , "Giant-nut has come to assist!" }, + + // Purgatory + { "机枪读报愤怒的时候会无视植物" , "Gatling Cherry Newspaper Zombie: Ability to walk through plants when its newspaper's broken" }, + { "机枪读报免疫减速和黄油" , "Gatling Cherry Newspaper Zombie: Immunity to Slow and Butter" }, + { "被黑橄榄攻击的植物在短时间内无法回血" , "Giga Rubgy-nut Zombie: Plants bitten by it won't recover Toughness for a short time" }, + { "被黑橄榄攻击的植物在短时间内受到的伤害x3" , "Giga Rubgy-nut Zombie: Plants bitten by it will take 3x more damage for a short time" }, + { "超级机械海豚的移动速度翻倍" , "Sharkmarine: Movement speed is now doubled" }, + { "超级机械海豚获得50%伤害减免" , "Sharkmarine: Gains 50% Damage Reduction" }, + { "基洛夫免疫三叶草效果,且飞行速度加快" , "Kirov Zomppelin: Immunity to Blovers | Increased Movement Speed" }, + { "基洛夫的僚机血量大幅增加" , "Kirov Zomppelin: Drones' HP Greatly Increased" }, + { "丑跳一定爆炸,且蓄力时间大幅降低" , "Pogo King Clown: Will always explode regardless of its state, and its charging time is reduced" }, + { "被小丑爆炸影响的小丑类僵尸会变成丑跳" , "Pogo King Clown: Jack-in-the-Box Zombies affected by the explosion will turn into Pogo King Clowns" }, + { "三叉戟伤害x5" , "Giga-trident Zombie: Tridents deal 5x more damage" }, + { "三叉戟僵尸现在随机挑选目标攻击" , "Giga-trident Zombie: Now target random plants to attack" }, + { "白舞王现在能召唤白色撑杆舞王僵尸" , "Superstar Zombie: Can now summon Super Dancing Zombies" }, + { "白舞王遇到植物不会停下" , "Superstar Zombie: Will now phase through plants when charging" }, + { "尸王死亡的爆炸伤害不可被小丑南瓜等免疫" , "Undying Wraith: Explosion damage will now ignore immunities by Joker Pumpkins and other relevant plants" }, + { "尸王的冲刺间隔降低,且攻击力大幅增加" , "Undying Wraith: Sprint Interval Reduced | Attack Power Greatly Increased" }, + { "三叉戟冲车免疫减速和黄油" , "Trident Hwacha: Immunity to Slow and Butter" }, + { "损失场上一半的植物" , "Lose half of the plants on the field" }, + { "令你的阳光数除以10" , "Your current Sun will be divided by 10" }, + { "令你阳光归零" , "Lose all the Sun you currently have." }, + { "所有僵尸的血量翻倍" , "Double the health of all zombies" }, + { "每一波出现的僵尸数量最大值增加到100" , "Increase the maximum limit of zombies per wave to 100" }, + { "每关都会出现舞王冰车,且死亡时额外召唤一个白舞王" , "Michael Zomboni: Spawns Every Round | Spawns Superstar Zombies when it dies" }, + { "舞王冰车的移动速度大幅增加" , "Michael Zomboni: Increased Movement Speed" }, + { "黑曜石巨人出现时也会出现究极三叉戟僵尸" , "Abyssal Gargantuar: Also spawns Pozeidon when it appears" }, + { "黑曜石巨人死亡时会召唤僵王博士" , "Abyssal Gargantuar: Spawns Dr. Zomboss when it dies" }, + { "黑曜石巨人出现时也会出现究极机械坚果僵尸" , "Abyssal Gargantuar: Also spawns an Ultra Mecha-nut Zombie when it appears" }, + { "黑曜石巨人出现时也会出现黑橄榄将军" , "Abyssal Gargantuar: Also spawns a Giga Football Striker when it appears" }, + { "黑曜石巨人出现时也会出现究极裂空机甲" , "Abyssal Gargantuar: Also spawns a Zomppelin Skystrider when it appears" }, + { "黑曜石巨人出现时也会出现究极白舞台车僵尸" , "Abyssal Gargantuar: Also spawns a Jackson Worldwide when it appears" }, + { "黑曜石巨人出现时也会出现究极读报僵尸" , "Abyssal Gargantuar: Also spawns a Professor Cherryz when it appears" }, + + { "-------Strings - New Update v2" , "Strings - 2.2.1-------"}, + { "融合版唯一官方:\r\n哔哩哔哩up主-蓝飘飘fly\r\n\r\n一切外部渠道如233乐园等均为盗版!因盗版带来的一切损失由玩家自行承担!", "The Official source of PvZ Fusion is only on the author, 蓝飘飘fly's Bilibili\nThe only valid source of this translation is from this community:\ndiscord.gg/DPAC5ZVJ8T.\n\nStray away from other sources as they may contain viruses.\nPlease visit our community for future updates." }, + { "烈焰爆竹" , "Bamboom" }, + { "临时词条已失效" , "The temporary Modifier has expired." }, + + { "-------Strings - New Update v3" , "Strings - 2.2.1-------"}, + { "太阳神流星特效" , "Helios Cabbage Visual Effect" }, + { "游戏机制" , "Game Mechanics" }, + { "机制" , "Game Mechanics" }, + { "切换图鉴样式" , "Switch View" }, + { "强究" , "Strong" }, + { "弱究" , "Weak" }, + { "地刺坚果" , "Spike-nut" }, + { "海妖菇" , "Titan Kraken-shroom" }, + { "在中间的海蘑菇上放置融合洋芋" , "Place the Jicamagic on the Sea-shroom in the middle." }, + { "水草, 海蘑菇, 水草" , "Tangle Kelp, Sea-shroom, Tangle Kelp" }, + { "选择" , "Select" }, + { "诸神5" , "The Gods 5" }, + { "诸神:阳光普照" , "The Gods: Trial of the Sun" }, + { "随机:福祸相依" , "Odyssey Gacha\nBlessings and Curses" }, + { "旅行冒险" , "Odyssey: Adventure" }, + { "购买" , "Buy" }, + { "刷新" , "Reroll" }, + { "购买成功\t\t\t\t\t\t\t\t\t\t购买成功", "\n\nPurchase Successful" }, + { "从中选择10个植物" , "Select 10 plants among the selection." }, + { "必须选10个\t\t\t\t\t\t\t\t\t\t\t\t必须选10个" , "\n\nYou must select 10 plants." }, + { "弱究可用" , "Initially Selected" }, + { "放弃增益\n(获得1000积分)" , "Skip Selection\n(Gain 1000 Points)" }, + { "已达最大刷新次数\t\t\t\t\t\t\t\t\t\t已达最大刷新次数" , "\n\nMax amount of Rerolls reached." }, + { "一键通关\n冒险模式和旅行冒险" , "Clear All\nAdventure (Normal and Odyssey)" }, + { "旧版平衡(关)" , "Legacy Adjustment - On" }, + { "旧版平衡(开)" , "Legacy Adjustment - Off" }, + { "PVP砸罐子" , "Vasebreaker PVP" }, + { "挑\n战\n者\n\n\n\n主\n播" , "C\nH\nA\nL\nL\nE\nN\nG\nE\nR\n\n\nS\nT\nR\nE\nA\nM\nE\nR" }, + { "挑\n战\n者\n\n\n\n擂\n主" , "C\nH\nA\nL\nL\nE\nN\nG\nE\nR\n\n\nR\nE\nC\nO\nR\nD\n\n\nH\nO\nL\nD\nE\nR" }, + { "切换背景" , "Switch Background" }, + { "清除僵尸(Y)" , "Clear Zombies (Y)" }, + { "清除植物(U)" , "Clear Plants (U)" }, + { "未开启右键放罐(I)" , "Right Click To Place \nVases (I) - Disabled" }, + { "未开启随机卡槽(O)" , "Randomize Plants\n in Slots (O) - Disabled" }, + { "已开启右键放罐(I)" , "Right Click To Place \nVases (I) - Enabled" }, + { "已开启随机卡槽(O)" , "Randomize Plants\n in Slots (O) - Enabled" }, + { "炼狱随机2" , "Purgatory\nGacha 2" }, + { "每轮只能使用一次" , "This can only be used once per round."}, + { "该配方仅旅行生存系列可用" , "This fusion is only available in Odyssey." }, + { "闪电洋葱不能死亡" , "You must protect your Electronion from the zombies. If it dies, the game ends." }, + { "球杆力度大幅增加" , "The power of the cue stick has been greatly increased." }, + { "推进旅行冒险解锁" , "Unlock this fusion by completing its Odyssey - Adventure level." }, + { "请选择你要购买的词条\t\t\t\t\t\t\t\t\t\t请选择你要购买的词条" , "Please select the Modifier you want to purchase." }, + { "购买的词条" , "Purchased Modifiers" }, + { "该配方需要抽取" , "This fusion must be bought first in the Modifier Shop before it can be used." }, + { "坚如磐石" , "The Gods 3" }, + { "究极随机" , "Odyssey Gacha - 12 Lane" }, + { "超级随机模式" , "Ten Flag: Odyssey Gacha" }, + { "积分不足\t\t\t\t\t\t\t\t\t\t积分不足" , "You have insufficient points." }, + { "未选取此植物" , "This Weak Odyssey Fusion was not selected in the Initial Selection Phase. You can't fuse this plant." }, + + { "排山倒海:一种种一列" , "Enable Column Planting" }, + { "解锁究极卷心菜,阳光卷心菜+金卷心菜" , "Unlock Helios Cabbage: Solar-pult + Golden Cabbage" }, + { "解锁究极南瓜,超级南瓜+磁力三叶草" , "Unlock Laser Pumpkin: Bloverthorn Pumpkin + Magblover" }, + { "妙手回春:阳光帝果召唤消耗降低至200阳光", "Twin Solar-nut: The cost of spawning a Giant Solar-nut is reduced to 200 Sun" }, + { "势如破竹:冰锥可以无限穿透,小冰机和小光机的攻击力增加50%" , "Gatling Icicle-shroom: Ice cones can pierce infinitely | Gatling Icicle/Sunburst-shroom DMG +50%" }, + { "冻彻心扉:冰锥对冻结的单位造成伤害提升至10倍,并解锁亚种阳光机枪小喷菇" , "Gatling Icicle-shroom: Ice cones DMG to Frozen zombies x10 | Gatling Sunburst-shroom Subspecies Unlocked" }, + { "斗转星移:所有的流星冷却缩短为原来的1/2,且场上每多一个究极杨桃则提升300基础伤害" , "Meteor Cooldowns Halved | Each Magnetar increases the damage of a Meteor by 300" }, + { "多多益善:升级金盆的消耗不会超过8000", "Radiant Pot: Upgrade costs from Silver Pots to Golden Pots will not exceed 8000" }, + { "等价交换:金币数超出上限的部分将转化为阳光,转化率为2:1", "Radiant Pot: Gold coins exceeding the maximum amount will be converted into half the Sun" }, + { "弹射起步:绿宝石伞可以让子弹弹到前方其他绿宝石伞上并叠加伤害(无上限),且伤害增幅从75%增加到125%" , "Midas Umbrella: Now bounce bullets with other Midas Umbrella, buffing its damage | Damage buff increased from 75% to 125%" }, + { "聚光盆:获得3000阳光然后使你的阳光翻倍,并使阳光上限增加到10万" , "Gain 3000 Sun, then double your total Sun | Sun Limit increased to 100,000" }, + { "可控核聚变:所有毁灭菇爆炸不留弹坑,并解锁亚种贪欲菇" , "Calamity-shroom: Doom-shroom explosions no longer leave craters | Avarice-shroom Subspecies Unlocked" }, + { "大富翁:基于当前金钱数量增加摇钱火炬的子弹伤害比例,每1000增加2%", "Tycoon Torch: 2% Damage increase to Tycoon Torched bullets for every 1000 coins you have" }, + { "好运连连:摇钱三线火炬的子弹附带火焰豌豆一样的溅射效果" , "Tycoon Torch: Bullets that pass through it gain a Splash effect like flaming peas" }, + { "过载:僵尸一段时间没有受到攻击后,下次受到的伤害大幅增加" , "After a period of time without being attacked, the next time a zombie is attacked, the damage it takes is greatly increased" }, + + { "星神合一:当场上有至少10个究极杨桃大帝和10个究极太阳神卷心菜,大帝将会牵引太阳神陨星,太阳神召唤的小太阳不会消失且伤害翻倍,且持续召唤普通流星" , "When there are at least 10 Magnetars and 10 Helios Cabbages on the field, the Magnetar will summon the Helios Meteor instead, while Helios' summoned Mini Sun will not disappear and will also continue to summon ordinary Meteors." }, + { "量子护盾:仙萤伞能量上限x10,回复速度x20,治疗速度x2" , "Tesla Umbrella: Energy Limit x10 | Recovery Speed x20 | Healing Speed x2" }, + { "高能射线:仙萤伞的普通攻击的倍率增加至300%,爆炸倍率增加至1000%,间隔降低为2秒" , "Tesla Umbrella: Normal Attack Multiplier → 300% | Explosion Multiplier → 1000% | Attack Interval → 2 Seconds" }, + { "窝红温了:究极窝炬没有位置生产窝瓜时将会直接燃烧一整行的僵尸" , "Squashed Infernowood: When there's no space to produce a Spicy Squash, ignite the lane instead" }, + { "金光闪闪:太阳神卷心菜的子弹获得阳光卷心菜子弹的效果" , "Helios Cabbage: Its projectiles gain the effect of Solar-pult's projectiles" }, + { "人造太阳:太阳神卷心菜召唤的小太阳伤害x3" , "Helios Cabbage: Its summoned Mini Sun will deal 3x more damage" }, + { "三位一体:究极南瓜的僚机增加至3个" , "Laser Pumpkin: Wingmen increased to 3" }, + { "镭射激光:究极南瓜的僚机攻击力x3" , "Laser Pumpkin: Wingmen damage multiplied by 3" }, + + { "究极三叉戟僵尸将会出现" , "Pozeidon will appear in the next round" }, + { "究极机械坚果僵尸将会出现" , "Ultra Mecha-nut will appear in the next round" }, + { "黑橄榄将军将会出现" , "Giga Football Striker will appear in the next round"}, + { "究极裂空机甲将会出现" , "Skystrider Mecha will appear in the next round"}, + { "究极白舞台车僵尸将会出现" , "Jackson Worldwide will appear in the next round"}, + { "究极读报僵尸将会出现" , "Professor Cherryz will appear in the next round"}, + { "蹦极有概率空投究极僵尸,且额外获得90%减伤" , "Bungee Jumpers have a chance to drop an Ultimate Zombie and will gain 90% DMG Reduction"}, + { "究极小丑僵尸将会出现" , "Queen Jill-in-the-Box will appear in the next round"}, + + // Strings - No Clue + { "-------Strings - No Clue" , "Strings - No Clue-------"}, + { "错误:尝试生成不存在的植物!" , "Error: Attempting to spawn a plant that doesn't exist." }, + { "错误:尝试生成不存在的植物!用豌豆代替" , "Error: Attempting to spawn a plant that doesn't exist. Use Peashooters instead." }, + { "错误:尝试生成不存在的种植预览!" , "Error: Trying to generate a planting preview that doesn't exist." }, + { "已解锁全部植物" , "All Plants Unlocked" }, + { "数据异常" , "Data Anomalies" }, + { "模式" , "Mode" }, + { "需要" , "Required" }, + { "不需要" , "Not Required" }, + { "轮已经完成" , "The round is completed." }, + { "究极植物" , "Odyssey Plants"}, + { "究极词条" , "Odyssey Modifiers"}, + { "笨蛋:梦珞" , " ??? Where" }, + { "是否抽取一种究极植物" , " ??? Where" }, + { ":" , ": " }, + { "敬请期待" , "Stay Tuned!" }, + // Testing + { "¥" , "$" }, + + // None Of This Shit Works! + { "-------Translation Doesn't Work" , "Needs Patching-------" }, + { "植物掉落阳光数" , "Sun Drop Multiplier" }, + { "僵尸血量倍率" , "Zombie HP Multiplier" }, + + { "-------Outdated Strings Below" , "You Can Safely Ignore or Delete-------"}, + #endif + }; + + public static Dictionary> patchesStore = new() + { + { "Difficulty", new Dictionary + { + { "English" , "Difficulty:" }, + { "French" , "Difficulté:" }, + { "Italian" , "Difficoltà:" }, + { "German" , "Schwierigkeit:" }, + { "Spanish" , "Dificultad:" }, + { "Portuguese" , "Dificuldade:" }, + { "Filipino" , "Ang Hirap:" }, + { "Vietnamese" , "Độ Khó:" }, + { "Indonesian" , "Kesulitan:" }, + { "Russian" , "Сложность:" }, + { "Japanese" , "困難:" }, + { "Korean", "난이도:" }, + { "Javanese" , "Kesulitan:" }, + // { "Ukrainian" , "Складність:" }, + // { "Slovak" , "Náročnosť:" }, + } + }, + { "Zombies", new Dictionary + { + { "English" , "Zombies:" }, + { "French" , "Les Zombies:" }, + { "Italian" , "Zombi:" }, + { "German" , "Zombies:" }, + { "Spanish" , "Zombis:" }, + { "Portuguese" , "Zumbis:" }, + { "Filipino" , "Mga Zombie:" }, + { "Vietnamese" , "Thây Ma:" }, + { "Indonesian" , "Zombi:" }, + { "Russian" , "Зомби:" }, + { "Japanese" , "ゾンビ:" }, + { "Korean", "좀비:" }, + { "Javanese" , "Mayit:" }, + // { "Ukrainian" , "Зомбі:" }, + // { "Slovak" , "Zombíci:"} + } + } + + }; + + internal static void Init() + { + FileLoader.LoadStrings(); + } + + internal static void Reload() + { + translationString.Clear(); + translationStringRegex.Clear(); + FileLoader.LoadStrings(); + } + + public static TextMeshPro TranslateText(TextMeshPro originalTMP, bool isLog = false) + { + #if MULTI_LANGUAGE + string currentLanguage = Utils.Language.ToString(); + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); + #else + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(); + #endif + + string translatedText = TranslateText(originalTMP.text); + originalTMP.font = fontAsset; + originalTMP.text = translatedText; + + return originalTMP; + } + + public static TextMeshProUGUI TranslateText(TextMeshProUGUI originalTMP, bool isLog = false) + { + #if MULTI_LANGUAGE + string currentLanguage = Utils.Language.ToString(); + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); + #else + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(); + #endif + + string translatedText = TranslateText(originalTMP.text); + originalTMP.font = fontAsset; + originalTMP.text = translatedText; + + return originalTMP; + } + + public static string TranslateText(string originalText, bool isLog = false) + { + string text = DoTranslateText(originalText, false); + string checkText; + #if DEBUG + Regex regex = new("\\p{IsCJKUnifiedIdeographs}+"); + Match match = regex.Match(text); + + if(match.Success) + { + // Log.LogDebug("Untranslated String: " + match.Value); + FileLoader.DumpUntranslatedStrings(text); + } + #endif + checkText = text; + + return checkText; + + } + + 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 (translationString.ContainsKey(originalText)) + { + if (isLog) + Log.LogDebug($"Text '{originalText} found in translationString"); + return translationString[originalText]; + } + + // Regex-based dynamic translation + foreach (var entry in translationStringRegex) + { + var regex = new Regex(entry.Key); + if (regex.IsMatch(originalText)) + { + // Extract dynamic parts from the original text + var match = regex.Match(originalText); + int groupCount = match.Groups.Count; + + if (isLog) + Log.LogDebug("Text found in translationStringRegex {0}: {1}", match, groupCount); + + // List to hold formatted dynamic parts + List dynamicParts = []; + + // Loop through each group and determine its translation + for (int i = 1; i < groupCount; i++) + { + string groupValue = match.Groups[i].Value; + string translatedValue = translationString.ContainsKey(groupValue) + ? translationString[groupValue] + : groupValue; + dynamicParts.Add(translatedValue); + } + + // Format the output string with dynamic parts + return string.Format(entry.Value, [.. dynamicParts]); + } + } + + if (isLog) + Log.LogDebug($"Text '{originalText}' not translated"); + return originalText; + } + + private static TextAlignmentOptions TextAnchorToTMPAlignment(TextAnchor anchor) + { + return anchor switch + { + TextAnchor.UpperLeft => TextAlignmentOptions.TopLeft, + TextAnchor.UpperCenter => TextAlignmentOptions.Top, + TextAnchor.UpperRight => TextAlignmentOptions.TopRight, + TextAnchor.MiddleLeft => TextAlignmentOptions.MidlineLeft, + TextAnchor.MiddleCenter => TextAlignmentOptions.Center, + TextAnchor.MiddleRight => TextAlignmentOptions.MidlineRight, + TextAnchor.LowerLeft => TextAlignmentOptions.BottomLeft, + TextAnchor.LowerCenter => TextAlignmentOptions.Bottom, + TextAnchor.LowerRight => TextAlignmentOptions.BottomRight, + _ => TextAlignmentOptions.Center + }; + } + + static TextMeshProUGUI ConvertToTextMeshPro(UnityEngine.UI.Text oldText, TMP_FontAsset fontAsset, bool isLog = false) + { + if (oldText == null) + { + Log.LogError("UnityEngine.UI.Text component is null."); + return null; + } + + if (fontAsset == null) + { + Log.LogError("TMP_FontAsset is null. Conversion cannot proceed."); + return null; + } + + // Log.LogInfo($"Converting UnityEngine.UI.Text: {oldText.name}"); + + GameObject textObject = oldText.gameObject; + + // Preserve text content and settings + string originalText = oldText.text; + originalText = TranslateText(originalText, isLog); + TextAnchor alignment = oldText.alignment; + Color color = oldText.color; + + // Remove old Text component + UnityEngine.Object.DestroyImmediate(oldText); + + // Add TextMeshProUGUI component + TextMeshProUGUI newTMP = textObject.AddComponent(); + if (newTMP == null) + { + Log.LogError($"Failed to add TextMeshProUGUI to object: {textObject.name}"); + return null; + } + + // Configure TextMeshProUGUI + newTMP.text = originalText; + newTMP.color = color; + newTMP.alignment = TextAnchorToTMPAlignment(alignment); + newTMP.font = fontAsset; + + // Log.LogInfo($"Successfully converted {textObject.name} to TextMeshProUGUI."); + + return newTMP; + } + + public static void TranslateTextTransform(Transform baseTransform, bool isAutoTextContainer = false, bool isLog = false) + { + if (!baseTransform) return; + + #if MULTI_LANGUAGE + string currentLanguage = Utils.Language.ToString(); + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); + #else + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(); + #endif + + if (fontAsset == null) + { + #if MULTI_LANGUAGE + Log.LogError($"Font for language '{currentLanguage}' not found. Translation aborted."); + #else + Log.LogError("Font not found. Translation aborted."); + #endif + return; + } + + // Local function for processing transforms + void ProcessTextTransform(Transform textTransform) + { + if (!textTransform) return; + + // Handle TextMeshPro components + TextMeshPro textTMP = textTransform.GetComponent(); + if (textTMP) + { + textTMP.text = TranslateText(textTMP.text, isLog); + textTMP.autoSizeTextContainer = isAutoTextContainer; + textTMP.font = fontAsset; + } + + TextMeshProUGUI textTMPUGUI = textTransform.GetComponent(); + if (textTMPUGUI) + { + textTMPUGUI.text = TranslateText(textTMPUGUI.text, isLog); + textTMPUGUI.enableAutoSizing = isAutoTextContainer; + textTMPUGUI.font = fontAsset; + } + + // Handle UnityEngine.UI.Text components + UnityEngine.UI.Text textUI = textTransform.GetComponent(); + if (textUI) + { + ConvertToTextMeshPro(textUI, fontAsset, isLog); + } + } + + // Process specific text paths + ProcessTextTransform(baseTransform.Find("text")); + ProcessTextTransform(baseTransform.Find("text1")); + // ProcessTextTransform(baseTransform.Find("text2")); + + Transform shadowTransform = baseTransform.Find("text/shadow"); + if (shadowTransform) ProcessTextTransform(shadowTransform); + + shadowTransform = baseTransform.Find("text1/shadow"); + if (shadowTransform) ProcessTextTransform(shadowTransform); + + #if TESTING + Transform childTransform = baseTransform.GetChild(0); + if (childTransform) ProcessTextTransform(childTransform); + #endif + } + + public static void TranslateTextUI(TextMeshPro textTMP, bool? isAutoTextContainer = null, bool isLog = false) + { + string currentLanguage = Utils.Language.ToString(); + if (textTMP) + { + textTMP.text = TranslateText(textTMP.text, isLog); + if (isAutoTextContainer!=null) textTMP.autoSizeTextContainer = isAutoTextContainer.Value; + textTMP.font = FontStore.LoadTMPFont(currentLanguage); + } + } + public static void TranslateTextUI(TextMeshProUGUI textTMP, bool? isAutoTextContainer = null, bool isLog = false) + { + string currentLanguage = Utils.Language.ToString(); + if (textTMP) + { + string origText = textTMP.text; + + textTMP.text = TranslateText(origText, isLog) == "" ? origText : TranslateText(origText, isLog); + if (isAutoTextContainer != null) textTMP.autoSizeTextContainer = isAutoTextContainer.Value; + if (origText != textTMP.text) + textTMP.font = FontStore.LoadTMPFont(currentLanguage); + } + } + + public static void TranslateTextUI(TMP_InputField TextInput) + { + string currentLanguage = Utils.Language.ToString(); + if (TextInput) + { + string oriText = TextInput.m_Text; + TextInput.m_Text = TranslateText(oriText); + TextInput.m_OriginalText = TranslateText(oriText); + TextInput.fontAsset = FontStore.LoadTMPFont(currentLanguage); + } + } + + public static void LogAll() + { + Log.LogInfo("Logging all StringStore entries."); + Log.LogInfo("Regex Entries: {0}", translationStringRegex.Count); + Log.LogInfo("String Entries: {0}", translationString.Count); + } + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/TextureStore.cs b/PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/TextureStore.cs new file mode 100644 index 0000000..1a5504a --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/TextureStore.cs @@ -0,0 +1,67 @@ +using MelonLoader; +using System.Collections; +using UnityEngine; + +namespace PvZ_Fusion_Translator.AssetStore +{ + public static class TextureStore + { + internal static Dictionary textureDict = []; + + internal static void Init() => FileLoader.LoadTextures(); + + internal static void Reload() + { + textureDict.Clear(); + #if MULTI_LANGUAGE + RestoreTextures(); + #endif + FileLoader.LoadDefaultTextures(); + FileLoader.LoadTextures(); + } + + public static IEnumerator ReplaceTexturesCoroutine() + { + while (true) + { + ReplaceTextures(); + yield return new WaitForSeconds(0.5f); // Adjust this interval as needed + } + } + + public static void ReplaceTextures() + { + Texture2D[] textures = Resources.FindObjectsOfTypeAll(); + foreach (Texture2D texture in textures) + { + if (texture.name.StartsWith("replaced_")) + continue; + + Utils.TryReplaceTexture2D(texture); + } + } + + #if MULTI_LANGUAGE + public static void RestoreTextures() + { + Texture2D[] textures = Resources.FindObjectsOfTypeAll(); + foreach (Texture2D texture in textures) + { + if (texture != null) + { + texture.name = texture.name.Replace("replaced_", ""); + } + } + } + #endif + + public static void LogAll() + { + Log.LogInfo("Logging all TextureStore entries."); + foreach (KeyValuePair entry in textureDict) + { + Log.LogInfo("TextureDict Entry: " + entry.Key + " | " + entry.Value); + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/WarningStore.cs b/PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/WarningStore.cs new file mode 100644 index 0000000..194268f --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/AssetStore/WarningStore.cs @@ -0,0 +1,180 @@ +using Il2Cpp; +using Il2CppTMPro; +using UnityEngine; + +namespace PvZ_Fusion_Translator.AssetStore +{ + public static class WarningStore + { + #if MULTI_LANGUAGE + private static Dictionary warningMessages = new() + { + { "English", ("The only valid source of this translation is from this community:\n" + + "discord.gg/DPAC5ZVJ8T. If you got this anywhere else like \n" + + "Plants Hybrid and superhybrid.online, they stole it.\n" + + "Stray away from other sources as they may contain viruses.\n" + + "Please visit our community for future updates.", + "Okay! Got it.") }, + { "French", ("La seule source valide pour cette traduction provient de cette\n" + + "communauté :discord.gg/DPAC5ZVJ8T. Si vous l'avez obtenue \n" + + "ailleurs, comme Plants Hybrid ou superhybrid.online, ils l'ont volée.\n" + + "Évitez les autres sources, car elles peuvent contenir des virus.\n" + + "Veuillez visiter notre communauté pour les mises à jour futures.", + "D'accord !") }, + { "Italian", ("L'unica fonte valida di questa traduzione è questa community:\n" + + "discord.gg/DPAC5ZVJ8T. Se l'hai ottenuta altrove, come \n" + + "Plants Hybrid e superhybrid.online, l'hanno rubata.\n" + + "Evita altre fonti, potrebbero contenere virus.\n" + + "Visita la nostra community per aggiornamenti futuri.", + "Va bene! Ho capito.") }, + { "German", ("Die einzige gültige Quelle für diese Übersetzung stammt aus\n" + + "dieser Community: discord.gg/DPAC5ZVJ8T. Wenn Sie diese \n" + + "irgendwo anders gefunden haben, z. B. bei Plants Hybrid oder \n" + + "superhybrid.online, dann haben sie sie gestohlen.\n" + + "Meiden Sie andere Quellen, da diese Viren enthalten könnten.\n" + + "Bitte besuchen Sie unsere Community für zukünftige Updates.", + "Okay, verstanden!") }, + { "Spanish", ("La única fuente válida de esta traducción proviene de esta\n" + + "comunidad: discord.gg/DPAC5ZVJ8T. Si la obtuvo en cualquier\n" + + "otro lugar como Plants Hybrid o superhybrid.online, la robaron.\n" + + "Manténgase alejado de otras fuentes, ya que podrían contener virus.\n" + + "Por favor, visite nuestra comunidad para futuras actualizaciones.", + "¡Entendido!") }, + { "Portuguese", ("O lugar original e seguro dessa tradução vem daqui:\n" + + "discord.gg/DPAC5ZVJ8T. Se você baixou ela de qualquer \n" + + "lugar como Plants Hybrid ou superhybrid.online, eles\n" + + "roubaram. Evite baixar deles, pode conter vírus.\n" + + "Por favor, visite nossa comunidade para atualizações futuras.", + "Okay, entendido.") }, + { "Filipino", ("Ang tanging opisyal na source ng pagsasaling ito ay mula\n" + + "lamang dito: discord.gg/DPAC5ZVJ8T. Kung nakuha nmo ito kahit \n" + + "saan pa tulad ng Plants Hybrid at superhybrid.online, ito ay ninakaw. \n" + + "Lumayo sa ibang source dahil posibleng may kasamang virus.\n" + + "Paki-bisita ang aming komunidad para sa mga darating na update." , + "Naiintindihan!") }, + { "Vietnamese", ("Nguồn duy nhất hợp lệ của bản dịch này là từ cộng\n" + + "đồng này: discord.gg/DPAC5ZVJ8T. Nếu bạn nhận \n" + + "được nó ở bất cứ nơi nào khác như Plants Hybrid \n" + + "hoặc superhybrid.online, họ đã ăn cắp nó.\n" + + "Tránh xa các nguồn khác vì chúng có thể chứa \n" + + "virus. Hãy ghé thăm cộng đồng của chúng tôi để \n" + + "cập nhật trong tương lai.", + "Đồng ý!") }, + { "Indonesian", ("Satu-satunya sumber resmi dari terjemahan ini adalah \n" + + "komunitas kami: discord.gg/DPAC5ZVJ8T. Jika Anda \n" + + "mendapatkannya dari sumber lain seperti Plants Hybrid \n" + + "dan superhybrid.online, mereka mencurinya. \n" + + "Jauhi sumber lain karena mungkin ada virus.\n" + + "Silakan kunjungi komunitas kami untuk pembaruan berikutnya.", + "Oke! Mengerti.") }, + { "Russian", ("Единственный проверенный источник этого перевода —\n" + + "сообщество discord.gg/DPAC5ZVJ8T.\n" + + "Или же его замена https://t.me/nekoshkindom\n" + + "Если вы скачали этот мод где-либо ещё, возможно он содержит вирусы.\n" + + "Программист перевода: LancerX0.\n" + + "Переводчик: Nekosha.", "Хорошо!") }, + { "Japanese", ("この翻訳の唯一の有効なソースは、このコミュニティからです:\n" + + "discord.gg/DPAC5ZVJ8T.Plants Hybridやsuperhybrid.online、\n" + + "YoutubeのBlue Flyが作っているもの、他のどこかでこれを入手した場合、\n" + + "彼らはそれを盗んだことになります。ウイルスが含まれている可能性があるので、\n" + + "他のソースからは離れてください。今後のアップデートについては、\n私たちのコミュニティをご覧ください。", + "了解しました!") }, + { "Korean", ("이 번역은 Bloom(discord.gg/DPAC5ZVJ8T)에서만\n" + + "제공됩니다. Bloom 디스코드 이외의 다른서드 파티 사이트, \n" + + "예를 들어 Plants Hybrid 및 superhybrid.online, 또는\n" + + "유튜브 Blue Fly등에서 제공하는 파일은 무단으로 재배포된 것이며,\n" + + "이런 사이트들에는 바이러스가 포함되어 있을 가능성이 높습니다. \n향후 업데이트를 위해 저희 디스코드를 방문해 주세요.", + "확인") }, + { "Javanese" , ("Sumber mung sing sah kanggo terjemahan iki saka komunitas iki:\n" + + "discord.gg/DPAC5ZVJ8T. Yen sampeyan nemokake iki ing papan\n" + + "liya kaya Plants Hybrid lan superhybrid.online, iku dicolong.\n" + + "Aja nyedhaki sumber liya amarga bisa ngandhut virus. Mangga\n" + + "ngunjungi komunitas kita kanggo nganyari ing mangsa ngarep.", + "Oke! Ngertos.") }, + // { "OTHER" , ("A única fonte válida dessa tradução é desta\ncomunidade: discord.gg/DPAC5ZVJ8T. Se você obteve \nisso em qualquer lugar como Plants Hybrid\ne superhybrid.online,ou Blue Fly do Youtube,\nelses roubaram. Fique longe de sites falsos. Por favor,\nvisite nossa comunidade para futuras atualizações.", "¡Okei! Entendido.") } + // { "OTHER" , ("Ang translation na ito ay galing dito lamang:\ndiscord.gg/DPAC5ZVJ8T. Pag nakuha niyo ito sa iba pa\nkagaya ng Plants Hybrid o superhybrid.online, anumang\nginawagawa ng Blue Fly mula sa Youtube, o anumang\nSub2Unlock links, scam sila. MAG INGAT dahil\nkasi baka may virus 'jan. Join kayo sa discord namin!\nFilipino Translation by ColinPogi" , "Tayo magsi-laro!") } + }; + #else + public static string warningMessage = "La única fuente válida de esta traducción proviene de esta\ncomunidad: discord.gg/DPAC5ZVJ8T. Si la obtuvo en cualquier\notro lugar como Plants Hybrid o superhybrid.online, la robaron.\nManténgase alejado de otras fuentes, ya que podrían contener virus.\nPor favor, visite nuestra comunidad para futuras actualizaciones."; + public static string okayButton = "¡Entendido!"; + #endif + + #if MULTI_LANGUAGE + public static (string, string) GetWarningMessage(Utils.LanguageEnum language) + { + if (warningMessages.TryGetValue(language.ToString(), out var message)) + { + + return message; + } + else + { + return warningMessages["English"]; // Default to English if language code is not found + } + } + #endif + + public static void WarningLoad() + { + GameAPP.theGameStatus = -2; + GameObject gameObject = UnityEngine.Object.Instantiate(Resources.Load("UI/MainMenu/NoticePauseMenu"), GameAPP.canvas.transform); + gameObject.name = "WarningMessage"; + TextMeshProUGUI warning = gameObject.transform.GetChild(0).GetChild(0).GetComponent(); + TextMeshProUGUI warningShadow = gameObject.transform.GetChild(0).GetChild(1).GetComponent(); + Transform button = gameObject.transform.GetChild(1); + warning.transform.position = new Vector3(0.7f, 0.4f, 0f); + warningShadow.transform.position = new Vector3(0.7f, 0.4f, 0f); + + #if MULTI_LANGUAGE + var (warningMessage, okayButton) = WarningStore.GetWarningMessage(Utils.Language); + #endif + + warning.text = warningMessage; + warningShadow.text = warningMessage; + warning.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + warningShadow.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + + button.GetComponent().buttonNumber = 10; + button.GetChild(0).GetComponent().text = okayButton; + button.GetChild(0).GetComponent().font = FontStore.LoadTMPFont(Utils.Language.ToString()); + button.GetChild(1).GetComponent().text = okayButton; + gameObject.SetActive(false); + gameObject.SetActive(true); + } + + #if MULTI_LANGUAGE + + public static bool isWarningMessageLoaded = false; + + public static void WarningReload(Utils.LanguageEnum language) + { + // Log.LogInfo("Current Language is " + Utils.OldLanguage); + // Log.LogInfo("Changed Language to " + language); + + if (Utils.OldLanguage.ToString() == language.ToString() && Utils.OldLanguage.ToString() != "English") + { + return; + } + if (!isWarningMessageLoaded) + { + WarningLoad(); + isWarningMessageLoaded = true; + } + + return; + } + #else + + public static bool isWarningMessageLoaded = false; + + public static void WarningReload() + { + if (!WarningStore.isWarningMessageLoaded) + { + WarningStore.WarningLoad(); + WarningStore.isWarningMessageLoaded = true; + } + } + #endif + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Core.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Core.cs new file mode 100644 index 0000000..d218420 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Core.cs @@ -0,0 +1,109 @@ +using MelonLoader; +using MelonLoader.Utils; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; + +[assembly: MelonInfo(typeof(PvZ_Fusion_Translator.Core), "PvZ Fusion Translator", "231.0.0", "dynaslash / arifrios1st / lancerx0", null)] +[assembly: MelonGame("LanPiaoPiao", "PlantsVsZombiesRH")] + +namespace PvZ_Fusion_Translator +{ + public class Core : MelonMod + { + private static DateTime dtStart; + private static DateTime? dtStartToast; + private static string toast_txt; + public static Core Instance { get; private set; } + + object replaceTextureRoutine = null; + + public override void OnEarlyInitializeMelon() => dtStart = DateTime.Now; + + public override void OnInitializeMelon() + { + base.OnInitializeMelon(); + Instance = this; + Config(); + #if MULTI_LANGUAGE + FileLoader.LoadLanguage(); + #endif + TextureStore.Init(); + StringStore.Init(); + AudioStore.Init(); + FontStore.Init(); + } + + public override void OnLateInitializeMelon() + { + dtStart = DateTime.Now; + replaceTextureRoutine = MelonCoroutines.Start(TextureStore.ReplaceTexturesCoroutine()); + } + + public override void OnDeinitializeMelon() + { + MelonCoroutines.Stop(replaceTextureRoutine); + #if MULTI_LANGUAGE + FileLoader.SaveLanguage(); + #endif + #if OBFUSCATE && !RELEASE + CheckSumStore.ConvertMD5Json(); + #endif + } + + public static void ShowToast(string message) + { + toast_txt = message; + dtStartToast = new DateTime?(DateTime.Now); + } + + public override void OnLateUpdate() + { + #if DEBUG + ModFeatures.OnLateUpdate(); + #endif + + if (Input.GetKeyDown(KeyCode.Insert)) + { + Utils.OpenSaveDirectory(); + } + + if (Input.GetKeyDown(KeyCode.Delete)) + { + Utils.OpenTrello(); + } + } + + public override void OnGUI() + { + #if DEBUG + if (dtStartToast != null) + { + GUI.Button(new Rect(10f, 10f, 200f, 20f), "\n" + toast_txt + "\n"); + TimeSpan? timeSpan = DateTime.Now - dtStartToast; + TimeSpan t = new(0, 0, 0, 2); + if (timeSpan > t) + { + dtStartToast = null; + } + } + #endif + } + + public String modsDirectory => Path.Combine(MelonEnvironment.ModsDirectory, "PvZ_Fusion_Translator"); + + public MelonPreferences_Entry configDefaultTextures; + public MelonPreferences_Entry configDefaultAudio; + public MelonPreferences_Entry configLanguage; + + private void Config() + { + var category = MelonPreferences.CreateCategory("PvZ_Fusion_Translator", "Fusion Translator Settings"); + + configDefaultTextures = category.CreateEntry("DefaultTextures", false); + configDefaultAudio = category.CreateEntry("DefaultAudio", false); + configLanguage = category.CreateEntry("Language", "English"); + + MelonPreferences.Save(); + } + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/FileLoader.cs b/PvZ-Fusion-Blooms-master/MelonLoader/FileLoader.cs new file mode 100644 index 0000000..7209d3f --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/FileLoader.cs @@ -0,0 +1,359 @@ +using Il2Cpp; +using MelonLoader; +using Newtonsoft.Json.Linq; +using PvZ_Fusion_Translator.AssetStore; +using PvZ_Fusion_Translator.Patches.OtherManagers; +using System.Text.Encodings.Web; +using System.Text.Json; +using UnityEngine; + +namespace PvZ_Fusion_Translator +{ + internal static class FileLoader + { + internal enum AssetType + { + Textures, + Strings, + Dumps, + Almanac, + } + + public static string GetAssetDir(AssetType assetType, Utils.LanguageEnum? language = null) + { + string languagePath = language.HasValue ? ("Localization" + Path.DirectorySeparatorChar + language.ToString()) : string.Empty; + return Path.Combine(Core.Instance.modsDirectory, languagePath, assetType.ToString()); + } + // private static string GetAssetDir(AssetType assetType) => Path.Combine(Core.Instance.modsDirectory, assetType.ToString()); + + #if MULTI_LANGUAGE + internal static void LoadStrings() => LoadStrings(Utils.Language); + + internal static void LoadStrings(Utils.LanguageEnum language) + #else + internal static void LoadStrings(bool isLog = false) + #endif + { + #if MULTI_LANGUAGE + string stringDir = GetAssetDir(AssetType.Strings, Utils.Language); + #else + string stringDir = GetAssetDir(AssetType.Strings); + #endif + if (!Directory.Exists(stringDir)) + { + Directory.CreateDirectory(stringDir); + } + try + { + foreach (string filepath in Directory.EnumerateFiles(stringDir, "*.json", SearchOption.AllDirectories)) + { + + #if OBFUSCATE + if (CheckSumStore.IsModified(filepath)) + { + Log.LogError("File {0} was modified!" , filepath); + continue; + } + #endif + + string fileName = Path.GetFileNameWithoutExtension(filepath); + StringStore.stringsDict[fileName] = filepath; + #if DEBUG + Log.LogInfo("Loading File : " + filepath); + #endif + string jsonString = File.ReadAllText(filepath); + if (fileName.EndsWith("_strings")) + { + Dictionary dictionary = System.Text.Json.JsonSerializer.Deserialize>(jsonString); + foreach (var (key, value) in dictionary) + { + StringStore.translationString[key] = value; + } + } + else if (fileName.EndsWith("_regexs")) + { + Dictionary dictionary = System.Text.Json.JsonSerializer.Deserialize>(jsonString); + foreach (var (key, value) in dictionary) + { + StringStore.translationStringRegex[key] = value; + } + } + } + SaveStrings(); + DumpJson(); + } + catch (Exception e) + { + Log.LogError("Error loading string."); + Log.LogError(e.GetType() + " " + e.Message); + } + Log.LogInfo("Strings loaded successfully."); + } + + public static bool loadDefaultTextures = MelonPreferences.GetEntryValue("PvZ_Fusion_Translator", "DefaultTextures"); + internal static void LoadTextures() + { + // Default or Custom Texturse -> English Textures -> Localized Textures + try + { + + if (loadDefaultTextures == true) + { + LoadDefaultTextures(); + } + else + { + LoadCustomTextures(); + } + } + catch (Exception e) + { + Log.LogError("Error loading texture setting."); + Log.LogError($"{e.GetType()} {e.Message}"); + } + + #if MULTI_LANGUAGE + if (Utils.Language != Utils.LanguageEnum.English) + { + LoadLocalizedTextures(Utils.LanguageEnum.English); + } + LoadLocalizedTextures(Utils.Language); + #else + LoadLocalizedTextures(); + #endif + + Log.LogInfo("Textures loaded successfully."); + } + + internal static void LoadLocalizedTextures(Utils.LanguageEnum? language = null) + { + string textureDir = GetAssetDir(AssetType.Textures, language); + + if (!Directory.Exists(textureDir)) + { + Directory.CreateDirectory(textureDir); + } + try + { + foreach (string filepath in Directory.EnumerateFiles(textureDir, "*.png", SearchOption.AllDirectories)) + { + if (filepath.Contains("[Custom Textures]", StringComparison.OrdinalIgnoreCase) && loadDefaultTextures) + { + continue; + } + + #if OBFUSCATE + if (CheckSumStore.IsModified(filepath)) + { + Log.LogError("File {0} was modified!" , filepath); + continue; + } + #endif + + #if DEBUG + Log.LogDebug("Loading File : " + filepath); + #endif + + Texture2D texture2D = Utils.LoadImage(filepath); + TextureStore.textureDict[Path.GetFileNameWithoutExtension(filepath)] = filepath; + } + } + + catch (Exception e) + { + Log.LogError("Error loading Texture."); + Log.LogError(e.GetType() + " " + e.Message); + } + } + + internal static void LoadDefaultTextures() + { + string textureDefaultDir = Path.Combine(Core.Instance.modsDirectory, AssetType.Dumps.ToString(), "Default Textures [Do Not Remove]"); + if (!Directory.Exists(textureDefaultDir)) + { + Directory.CreateDirectory(textureDefaultDir); + } + try + { + foreach (string filepath in Directory.EnumerateFiles(textureDefaultDir, "*.png", SearchOption.AllDirectories)) + { + + #if OBFUSCATE + if (CheckSumStore.IsModified(filepath)) + { + Log.LogError("File {0} was modified!" , filepath); + continue; + } + #endif + + Texture2D texture2D = Utils.LoadImage(filepath); + TextureStore.textureDict[Path.GetFileNameWithoutExtension(filepath)] = filepath; + } + } + + catch (Exception e) + { + Log.LogError("Error loading Texture."); + Log.LogError(e.GetType() + " " + e.Message); + } + } + + internal static void LoadCustomTextures() + { + string texturePackDir = Path.Combine(Core.Instance.modsDirectory, "[Custom Textures]"); + + if (!Directory.Exists(texturePackDir)) + { + Directory.CreateDirectory(texturePackDir); + } + try + { + foreach (string filepath in Directory.EnumerateFiles(texturePackDir, "*.png", SearchOption.AllDirectories)) + { + #if OBFUSCATE + if (CheckSumStore.IsModified(filepath)) + { + Log.LogError("File {0} was modified!" , filepath); + continue; + } + #endif + + Texture2D texture2D = Utils.LoadImage(filepath); + TextureStore.textureDict[Path.GetFileNameWithoutExtension(filepath)] = filepath; + } + } + + catch (Exception e) + { + Log.LogError("Error loading Texture."); + Log.LogError(e.GetType() + " " + e.Message); + } + } + + internal static void SaveStrings() + { + #if MULTI_LANGUAGE + string stringDir = GetAssetDir(AssetType.Strings, Utils.Language); + #else + string stringDir = GetAssetDir(AssetType.Strings); + #endif + if (!Directory.Exists(stringDir)) + { + Directory.CreateDirectory(stringDir); + } + + string translationStringRegex = System.Text.Json.JsonSerializer.Serialize(StringStore.translationStringRegex, new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping + }); + + File.WriteAllText(Path.Combine(stringDir, "translation_regexs.json"), translationStringRegex); + + string translationString = System.Text.Json.JsonSerializer.Serialize(StringStore.translationString, new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping + }); + + File.WriteAllText(Path.Combine(stringDir, "translation_strings.json"), translationString); + } + + public static void DumpJson() + { + string dumpDir = GetAssetDir(AssetType.Dumps); + + if (!Directory.Exists(dumpDir)) + { + Directory.CreateDirectory(dumpDir); + } + string LawnStrings = Resources.Load("LawnStrings").text; + string ZombieStrings = Resources.Load("ZombieStrings").text; + File.WriteAllText(Path.Combine(dumpDir, "LawnStrings.json"), LawnStrings); + File.WriteAllText(Path.Combine(dumpDir, "ZombieStrings.json"), ZombieStrings); + + Dictionary achievementsList = new Dictionary(); + foreach (Il2CppSystem.Collections.Generic.KeyValuePair> entry in AchievementClip.achievementsText) + { + achievementsList.Add(entry.Key, new AchievementObject(entry.Key, entry.Value.Item1, entry.Value.Item2)); + } + File.WriteAllText(Path.Combine(dumpDir, "AchievementsText.json"), JsonSerializer.Serialize(achievementsList, new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping + })); + } + + #if DEBUG + public static void DumpUntranslatedStrings(string text) + { + string dumpDir = GetAssetDir(AssetType.Dumps); + string jsonFile = Path.Combine(dumpDir, "UntranslatedStrings.json"); + + if (!Directory.Exists(dumpDir)) + { + Directory.CreateDirectory(dumpDir); + } + + if (!File.Exists(jsonFile)) + { + File.WriteAllText(jsonFile, "{}"); // Initialize empty JSON object + } + + string json = File.ReadAllText(jsonFile); + JObject untranslatedStrings = JObject.Parse(json); + + if (!untranslatedStrings.ContainsKey(text)) + { + untranslatedStrings[text] = text; + File.WriteAllText(jsonFile, untranslatedStrings.ToString()); + } + } + #endif + + #if MULTI_LANGUAGE + internal static void LoadLanguage() + { + try + { + // Load the language preference as a string and parse it into the enum + string languageName = MelonPreferences.GetEntryValue("PvZ_Fusion_Translator", "Language"); + if (Enum.TryParse(languageName, out Utils.LanguageEnum loadedLanguage)) + { + Utils.Language = loadedLanguage; + } + else + { + Log.LogWarning($"Invalid language '{languageName}' found in preferences. Falling back to English."); + Utils.Language = Utils.LanguageEnum.English; // Default fallback + } + Log.LogWarning($"Loaded language {languageName}"); + } + catch (Exception e) + { + Log.LogError("Error loading language setting."); + Log.LogError($"{e.GetType()} {e.Message}"); + } + Log.LogInfo($"Language has been loaded: {Utils.Language}"); + } + + internal static void SaveLanguage() + { + try + { + // Save the current language as a string + MelonPreferences.SetEntryValue("PvZ_Fusion_Translator", "Language", Utils.Language.ToString()); + + // Ensure changes are written to the config file + // MelonPreferences.Save(); + } + catch (Exception e) + { + Log.LogError("Error saving language setting."); + Log.LogError($"{e.GetType()} {e.Message}"); + } + // Log.LogInfo($"Language has been saved: {Utils.Language}"); + } + #endif + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/FontHandler.cs b/PvZ-Fusion-Blooms-master/MelonLoader/FontHandler.cs new file mode 100644 index 0000000..a2cad5a --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/FontHandler.cs @@ -0,0 +1,43 @@ +using Il2CppTMPro; +using MelonLoader.Utils; +using UnityEngine; + +namespace PvZ_Fusion_Translator +{ + public static class FontHandler + { + public static Font LoadFont(this string pathFromModsFolder, bool throwException) + { + string fontFilePath = Path.Combine(MelonEnvironment.ModsDirectory, pathFromModsFolder); + if (!File.Exists(fontFilePath)) + { + if (throwException) + Log.LogWarning($"Font not found at path: '{fontFilePath}'."); + return null; + } + Font font = new(); + Font.Internal_CreateFontFromPath(font, fontFilePath); + return font; + } + + public static TMP_FontAsset ConvertToTMP(this Font font) + { + TMP_FontAsset fontAsset = TMP_FontAsset.CreateFontAsset(font); + if (fontAsset == null) + { + Log.LogWarning($"Failed to create TMP_FontAsset from font '{font.name}'."); + return null; + } + return fontAsset; + } + + public static TMP_FontAsset LoadTMPFont(this string pathFromModsFolder, bool throwException) + { + Font font = pathFromModsFolder.LoadFont(throwException); + if (!font) + return null; + TMP_FontAsset fontAsset = font.ConvertToTMP(); + return fontAsset; + } + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Log.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Log.cs new file mode 100644 index 0000000..5389e6d --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Log.cs @@ -0,0 +1,24 @@ +using MelonLoader; +using System.Drawing; + +namespace PvZ_Fusion_Translator +{ + internal static class Log + { + public static void LogDebug(object txt) => Melon.Logger.Msg(Color.Gray, txt); + public static void LogDebug(string txt) => Melon.Logger.Msg(Color.Gray, txt); + public static void LogDebug(string txt, params object[] args) => Melon.Logger.Msg(Color.Gray, txt, args); + + public static void LogInfo(object txt) => Melon.Logger.Msg(Color.Blue, txt); + public static void LogInfo(string txt) => Melon.Logger.Msg(Color.Blue, txt); + public static void LogInfo(string txt, params object[] args) => Melon.Logger.Msg(Color.Blue, txt, args); + + public static void LogWarning(object txt) => Melon.Logger.Warning(txt); + public static void LogWarning(string txt) => Melon.Logger.Warning(txt); + public static void LogWarning(string txt, params object[] args) => Melon.Logger.Warning(txt, args); + + public static void LogError(object txt) => Melon.Logger.Error(txt); + public static void LogError(string txt) => Melon.Logger.Error(txt); + public static void LogError(string txt, params object[] args) => Melon.Logger.Error(txt, args); + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/ModFeatures.cs b/PvZ-Fusion-Blooms-master/MelonLoader/ModFeatures.cs new file mode 100644 index 0000000..0b4b53b --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/ModFeatures.cs @@ -0,0 +1,78 @@ +#if DEBUG +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator +{ + public static class ModFeatures + { + public enum ModType + { + ReloadStrings, + ReloadTextures, + } + + private class ModFeature + { + public string Name { get; private set; } + public ModType ModType { get; private set; } + public KeyCode KeyCode { get; private set; } + public bool IsActive { get; set; } + + public ModFeature(string Name, ModType ModType, KeyCode KeyCode, bool defaultValue = false) + { + this.Name = Name; + this.ModType = ModType; + this.KeyCode = KeyCode; + this.IsActive = defaultValue; + } + + public void ToggleFeature() + { + if (this.ModType == ModType.ReloadStrings) + { + StringStore.Reload(); + Core.ShowToast("Strings Reloaded!"); + return; + } + + if (this.ModType == ModType.ReloadTextures) + { + TextureStore.Reload(); + Core.ShowToast("Textures Reloaded!"); + return; + } + } + } + + private static Dictionary featureLists = new() + { + {ModType.ReloadStrings,new ModFeature("Reload Strings",ModType.ReloadStrings,KeyCode.Home, true)}, + {ModType.ReloadTextures,new ModFeature("Reload Textures",ModType.ReloadTextures,KeyCode.End, true)}, + }; + + + public static void ToggleFeature(ModType ModType) + { + if (!featureLists.ContainsKey(ModType)) + return; + + featureLists[ModType].ToggleFeature(); + } + + public static void OnLateUpdate() + { + foreach (var (type, feature) in featureLists) + { + if (feature.KeyCode != KeyCode.None && Enum.IsDefined(typeof(KeyCode), feature.KeyCode)) + { + if (Input.GetKeyDown(feature.KeyCode)) + { + feature.ToggleFeature(); + } + } + } + } + } +} +#endif \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/BaseTextObjects/InGameText_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/BaseTextObjects/InGameText_Patch.cs new file mode 100644 index 0000000..02257db --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/BaseTextObjects/InGameText_Patch.cs @@ -0,0 +1,33 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.BaseTextObjects +{ + [HarmonyPatch(typeof(InGameText))] + public static class InGameText_Patch + { + [HarmonyPatch(nameof(InGameText.ShowText), new Type[] { typeof(string), typeof(float), typeof(bool) })] + [HarmonyPrefix] + private static void ShowText(InGameText __instance, ref string text) => text = StringStore.TranslateText(text, true); + + [HarmonyPatch(nameof(InGameText.ShowText), new Type[] { typeof(string), typeof(float), typeof(bool) })] + [HarmonyPostfix] + private static void ShowText(InGameText __instance) + { + + #if MULTI_LANGUAGE + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + #else + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(); + #endif + + foreach (TextMeshProUGUI txt in __instance.textMeshes) + { + txt.text = StringStore.TranslateText(txt.text, true); + txt.font = fontAsset; + } + } + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/BaseTextObjects/TMP_InputField_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/BaseTextObjects/TMP_InputField_Patch.cs new file mode 100644 index 0000000..00d9589 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/BaseTextObjects/TMP_InputField_Patch.cs @@ -0,0 +1,23 @@ +using HarmonyLib; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.BaseTextObjects +{ + [HarmonyPatch(typeof(TMP_InputField))] + public static class TMP_InputField_Patch + { + [HarmonyPatch(nameof(TMP_InputField.OnEnable))] + [HarmonyPostfix] + private static void OnEnable(TMP_InputField __instance) + { + if (!string.IsNullOrEmpty(__instance.text)) + { + string text = StringStore.TranslateText(__instance.text); + __instance.m_Text = StringStore.TranslateText(text); + __instance.m_OriginalText = StringStore.TranslateText(text); + __instance.m_TextComponent.text = StringStore.TranslateText(text); + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/BaseTextObjects/TextMeshProUGUI_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/BaseTextObjects/TextMeshProUGUI_Patch.cs new file mode 100644 index 0000000..d231998 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/BaseTextObjects/TextMeshProUGUI_Patch.cs @@ -0,0 +1,77 @@ +using HarmonyLib; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine.UI; + +namespace PvZ_Fusion_Translator.Patches.BaseTextObjects +{ + [HarmonyPatch(typeof(TextMeshProUGUI))] + public static class TextMeshProUGUI_Patch + { + [HarmonyPatch(nameof(TextMeshProUGUI.OnEnable))] + [HarmonyPostfix] + private static void OnEnable(TextMeshProUGUI __instance) + { + if (!string.IsNullOrEmpty(__instance.text)) + { + __instance = StringStore.TranslateText(__instance); + __instance.autoSizeTextContainer = false; + + if (__instance.name.StartsWith("LevelName")) + { + __instance.text = __instance.text.Replace("\n", " "); + } + if (__instance.transform.parent != null && __instance.transform.parent.name.StartsWith("Window")) + { + __instance.fontSizeMin = 10; + __instance.fontSize = 12; + } + + // __instance.ForceMeshUpdate(); + } + } + + [HarmonyPatch(nameof(TextMeshProUGUI.Awake))] + [HarmonyPostfix] + private static void Awake(TextMeshProUGUI __instance) + { + if (!string.IsNullOrEmpty(__instance.text)) + { + __instance = StringStore.TranslateText(__instance); + __instance.autoSizeTextContainer = false; + + if (__instance.name.StartsWith("LevelName")) + { + __instance.text = __instance.text.Replace("\n", " "); + } + if (__instance.transform.parent != null && __instance.transform.parent.name.StartsWith("Window")) + { + __instance.fontSizeMin = 10; + __instance.fontSize = 12; + } + + if (__instance.text == "Полный Хаос" && __instance.transform.parent.parent.Find("Image").GetComponent().activeSprite.name == "Present") + { + __instance.text += "\nБесконечно"; + } + + // __instance.ForceMeshUpdate(); + } + } + } + [HarmonyPatch(typeof(TMP_SubMeshUI))] + public static class TMP_SubMeshUI_Patch + { + [HarmonyPatch(nameof(TMP_SubMeshUI.OnEnable))] + [HarmonyPostfix] + public static void OnEnable(TMP_SubMeshUI __instance) + { + if (!string.IsNullOrEmpty(__instance.textComponent.text)) + { + string text = StringStore.TranslateText(__instance.textComponent.text); + __instance.m_TextComponent.text = StringStore.TranslateText(text); + __instance.textComponent.text = StringStore.TranslateText(text); + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/BaseTextObjects/TextMeshPro_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/BaseTextObjects/TextMeshPro_Patch.cs new file mode 100644 index 0000000..6aa8151 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/BaseTextObjects/TextMeshPro_Patch.cs @@ -0,0 +1,27 @@ +using HarmonyLib; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.BaseTextObjects +{ + [HarmonyPatch(typeof(TextMeshPro))] + public static class TextMeshPro_Patch + { + [HarmonyPatch(nameof(TextMeshPro.OnEnable))] + [HarmonyPostfix] + private static void OnEnable(TextMeshPro __instance) + { + if (!string.IsNullOrEmpty(__instance.text)) + { + if (__instance.transform.parent.name.StartsWith("AlmanacHelp")) + { + __instance = StringStore.TranslateText(__instance); + __instance.autoSizeTextContainer = false; + return; + } + __instance = StringStore.TranslateText(__instance); + __instance.autoSizeTextContainer = true; + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/AbyssBuffButton_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/AbyssBuffButton_Patch.cs new file mode 100644 index 0000000..7e28372 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/AbyssBuffButton_Patch.cs @@ -0,0 +1,24 @@ +#if FIX +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects +{ + [HarmonyPatch(typeof(AbyssBuffButton))] + public static class AbyssBuffButton_Patch + { + [HarmonyPatch(nameof(AbyssBuffButton.Start))] + [HarmonyPostfix] + private static void Start(AbyssBuffButton __instance) + { + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + __instance.description.text = StringStore.TranslateText(__instance.description.text); + __instance.description.font = fontAsset; + } + } +} +#endif \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/AbyssButton_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/AbyssButton_Patch.cs new file mode 100644 index 0000000..45ac577 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/AbyssButton_Patch.cs @@ -0,0 +1,26 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects +{ + [HarmonyPatch(typeof(AbyssButton))] + public static class AbyssButton_Patch + { + [HarmonyPatch(nameof(AbyssButton.Start))] + [HarmonyPostfix] + private static void Start(AbyssButton __instance) + { + StringStore.TranslateTextTransform(__instance.transform, true); + Transform parentTransform = __instance.transform.parent.transform; + if (__instance.name == "Goback") + { + Transform backgroundTransform = parentTransform.Find("Background"); + backgroundTransform.Find("Name").GetComponent().autoSizeTextContainer = true; + backgroundTransform.Find("Shadow").GetComponent().autoSizeTextContainer = true; + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/Advanture_Btn_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/Advanture_Btn_Patch.cs new file mode 100644 index 0000000..a0a4216 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/Advanture_Btn_Patch.cs @@ -0,0 +1,103 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects +{ + [HarmonyPatch(typeof(Advanture_Btn))] + public static class Advanture_Btn_Patch + { + [HarmonyPatch(nameof(Advanture_Btn.Start))] + [HarmonyPostfix] + private static void Start(Advanture_Btn __instance) + { + StringStore.TranslateTextTransform(__instance.transform, true); + Transform parentTransform = __instance.transform.parent.transform; + if (__instance.name == "Goback") + { + Transform backgroundTransform = parentTransform.Find("Background"); + backgroundTransform.Find("Name").GetComponent().autoSizeTextContainer = true; + backgroundTransform.Find("Shadow").GetComponent().autoSizeTextContainer = true; + } + + Transform levelTransform = parentTransform.Find("Levels"); + if (levelTransform != null) + { + + StringStore.TranslateTextTransform(levelTransform.Find("Nextpage")); + StringStore.TranslateTextTransform(levelTransform.Find("LastPage")); + + Transform pageMiniGamesTransform = levelTransform.transform.Find("PageMiniGames"); + if (pageMiniGamesTransform != null) + { + StringStore.TranslateTextTransform(pageMiniGamesTransform.Find("BackToIndex")); + StringStore.TranslateTextTransform(pageMiniGamesTransform.Find("Nextpage")); + StringStore.TranslateTextTransform(pageMiniGamesTransform.Find("LastPage")); + } + + Transform pageUnlockChallengeTransform = levelTransform.transform.Find("PageUnlockChallenge"); + if (pageUnlockChallengeTransform != null) + { + StringStore.TranslateTextTransform(pageUnlockChallengeTransform.Find("BackToIndex")); + } + + Transform pageFlagChallengeTransform = levelTransform.transform.Find("PageFlagChallenge"); + if (pageFlagChallengeTransform != null) + { + StringStore.TranslateTextTransform(pageFlagChallengeTransform.Find("BackToIndex")); + } + + Transform pageTravelExperienceTransform = levelTransform.transform.Find("PageTravelExperience"); + if (pageTravelExperienceTransform != null) + { + StringStore.TranslateTextTransform(pageTravelExperienceTransform.Find("BackToIndex")); + } + + Transform pageGardenProtectionTransform = levelTransform.transform.Find("PageGardenProtection"); + if (pageGardenProtectionTransform != null) + { + StringStore.TranslateTextTransform(pageGardenProtectionTransform.Find("BackToIndex")); + } + + Transform pageNormalTravelTransform = levelTransform.transform.Find("PageNormalTravel"); + if (pageNormalTravelTransform != null) + { + StringStore.TranslateTextTransform(pageNormalTravelTransform.Find("BackToIndex")); + } + + Transform pageRandomLevelTransform = levelTransform.transform.Find("PageRandomLevel"); + if (pageRandomLevelTransform != null) + { + StringStore.TranslateTextTransform(pageRandomLevelTransform.Find("BackToIndex")); + } + + Transform pageUltimateExperienceTransform = levelTransform.transform.Find("PageUltimateExprience"); + if (pageUltimateExperienceTransform != null) + { + StringStore.TranslateTextTransform(pageUltimateExperienceTransform.Find("BackToIndex")); + } + + Transform pageAdvantureLevelTransform = levelTransform.transform.Find("PageAdvantureLevel"); + if (pageAdvantureLevelTransform != null) + { + StringStore.TranslateTextTransform(pageAdvantureLevelTransform.Find("BackToIndex")); + StringStore.TranslateTextTransform(pageAdvantureLevelTransform.Find("Nextpage")); + StringStore.TranslateTextTransform(pageAdvantureLevelTransform.Find("LastPage")); + } + + Transform pageScaryPotTransform = levelTransform.transform.Find("PageScaryPot"); + if (pageScaryPotTransform != null) + { + StringStore.TranslateTextTransform(pageScaryPotTransform.Find("BackToIndex")); + StringStore.TranslateTextTransform(pageScaryPotTransform.Find("Nextpage")); + StringStore.TranslateTextTransform(pageScaryPotTransform.Find("LastPage")); + } + } + + StringStore.TranslateTextTransform(parentTransform.Find("CameraSize")); + StringStore.TranslateTextTransform(parentTransform.Find("CanvasSize")); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/BaseMenu_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/BaseMenu_Patch.cs new file mode 100644 index 0000000..8bf8742 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/BaseMenu_Patch.cs @@ -0,0 +1,111 @@ +using HarmonyLib; +using Il2Cpp; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects +{ + [HarmonyPatch(typeof(BaseMenu))] + public static class BaseMenu_Patch + { + [HarmonyPatch(nameof(BaseMenu.Awake))] + [HarmonyPostfix] + private static void Awake(BaseMenu __instance) + { + Transform mainTransform = __instance.transform; + if (mainTransform != null) + { + StringStore.TranslateTextTransform(mainTransform.Find("Goback")); + StringStore.TranslateTextTransform(mainTransform.Find("Switich")); + + Transform levelTransform = mainTransform.Find("Level"); + if (levelTransform != null) + { + StringStore.TranslateTextTransform(levelTransform.Find("Nextpage")); + StringStore.TranslateTextTransform(levelTransform.Find("LastPage")); + } + + Transform customLevelTransform = mainTransform.Find("CustomLevel"); + if (customLevelTransform != null) + { + StringStore.TranslateTextTransform(customLevelTransform.Find("Nextpage")); + StringStore.TranslateTextTransform(customLevelTransform.Find("LastPage")); + } + + Transform levelsTransform = mainTransform.Find("Levels"); + if (levelsTransform != null) + { + + StringStore.TranslateTextTransform(levelsTransform.Find("Nextpage")); + StringStore.TranslateTextTransform(levelsTransform.Find("LastPage")); + + Transform pageMiniGamesTransform = levelsTransform.transform.Find("PageMiniGames"); + if (pageMiniGamesTransform != null) + { + StringStore.TranslateTextTransform(pageMiniGamesTransform.Find("BackToIndex")); + StringStore.TranslateTextTransform(pageMiniGamesTransform.Find("Nextpage")); + StringStore.TranslateTextTransform(pageMiniGamesTransform.Find("LastPage")); + } + + Transform pageUnlockChallengeTransform = levelsTransform.transform.Find("PageUnlockChallenge"); + if (pageUnlockChallengeTransform != null) + { + StringStore.TranslateTextTransform(pageUnlockChallengeTransform.Find("BackToIndex")); + } + + Transform pageFlagChallengeTransform = levelsTransform.transform.Find("PageFlagChallenge"); + if (pageFlagChallengeTransform != null) + { + StringStore.TranslateTextTransform(pageFlagChallengeTransform.Find("BackToIndex")); + } + + Transform pageTravelExperienceTransform = levelsTransform.transform.Find("PageTravelExperience"); + if (pageTravelExperienceTransform != null) + { + StringStore.TranslateTextTransform(pageTravelExperienceTransform.Find("BackToIndex")); + } + + Transform pageGardenProtectionTransform = levelsTransform.transform.Find("PageGardenProtection"); + if (pageGardenProtectionTransform != null) + { + StringStore.TranslateTextTransform(pageGardenProtectionTransform.Find("BackToIndex")); + } + + Transform pageNormalTravelTransform = levelsTransform.transform.Find("PageNormalTravel"); + if (pageNormalTravelTransform != null) + { + StringStore.TranslateTextTransform(pageNormalTravelTransform.Find("BackToIndex")); + } + + Transform pageRandomLevelTransform = levelsTransform.transform.Find("PageRandomLevel"); + if (pageRandomLevelTransform != null) + { + StringStore.TranslateTextTransform(pageRandomLevelTransform.Find("BackToIndex")); + } + + Transform pageUltimateExperienceTransform = levelsTransform.transform.Find("PageUltimateExprience"); + if (pageUltimateExperienceTransform != null) + { + StringStore.TranslateTextTransform(pageUltimateExperienceTransform.Find("BackToIndex")); + } + + Transform pageAdvantureLevelTransform = levelsTransform.transform.Find("PageAdvantureLevel"); + if (pageAdvantureLevelTransform != null) + { + StringStore.TranslateTextTransform(pageAdvantureLevelTransform.Find("BackToIndex")); + StringStore.TranslateTextTransform(pageAdvantureLevelTransform.Find("Nextpage")); + StringStore.TranslateTextTransform(pageAdvantureLevelTransform.Find("LastPage")); + } + + Transform pageScaryPotTransform = levelsTransform.transform.Find("PageScaryPot"); + if (pageScaryPotTransform != null) + { + StringStore.TranslateTextTransform(pageScaryPotTransform.Find("BackToIndex")); + StringStore.TranslateTextTransform(pageScaryPotTransform.Find("Nextpage")); + StringStore.TranslateTextTransform(pageScaryPotTransform.Find("LastPage")); + } + } + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/EveBtn_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/EveBtn_Patch.cs new file mode 100644 index 0000000..9ace4e0 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/EveBtn_Patch.cs @@ -0,0 +1,42 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects +{ + [HarmonyPatch(typeof(EveBtn))] + public static class EveBtn_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(EveBtn.OnMouseUp))] + private static void OnMouseUp(EveBtn __instance) + { + Transform sceneText = __instance.transform.FindChild("text"); + if(sceneText != null) + { + TextMeshProUGUI sceneTextTMP = sceneText.transform.GetComponent(); + if(sceneTextTMP != null) + { + sceneTextTMP.text = StringStore.TranslateText(sceneTextTMP.text); + } + } + Transform sceneTextShadow = sceneText.transform.FindChild("text2"); + if(sceneTextShadow != null) + { + TextMeshProUGUI sceneTextShadowTMP = sceneTextShadow.transform.GetComponent(); + if (sceneTextShadowTMP != null) + { + sceneTextShadowTMP.text = StringStore.TranslateText(sceneTextShadowTMP.text); + } + } + + if (__instance.name.Equals("Balanced")) + { + __instance.gameObject.SetActive(false); + __instance.gameObject.SetActive(true); + } + } + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/InGameBtn_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/InGameBtn_Patch.cs new file mode 100644 index 0000000..d645ee9 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/InGameBtn_Patch.cs @@ -0,0 +1,35 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects +{ + [HarmonyPatch(typeof(InGameBtn))] + public static class InGameBtn_Patch + { + [HarmonyPatch(nameof(InGameBtn.Update))] + [HarmonyPostfix] + private static void Update(InGameBtn __instance) + { + Transform sceneText = __instance.transform.FindChild("SceneText"); + if(sceneText != null) + { + TextMeshProUGUI sceneTextTMP = sceneText.transform.GetComponent(); + if(sceneTextTMP != null) + { + sceneTextTMP = AssetStore.StringStore.TranslateText(sceneTextTMP); + } + Transform sceneTextShadow = sceneText.transform.FindChild("SceneText"); + if(sceneTextShadow != null) + { + TextMeshProUGUI sceneTextShadowTMP = sceneTextShadow.transform.GetComponent(); + if (sceneTextShadowTMP != null) + { + sceneTextShadowTMP = AssetStore.StringStore.TranslateText(sceneTextShadowTMP); + } + } + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs new file mode 100644 index 0000000..b0c1e5f --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs @@ -0,0 +1,212 @@ +#if MULTI_LANGUAGE +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; +using Object = UnityEngine.Object; + +public class OptionButtonData +{ + public OptionBtn Button { get; set; } + public Vector3 Position { get; set; } + public Utils.LanguageEnum? Language { get; set; } // Null if it's the "Next" button + public bool IsNextButton { get; set; } +} + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects +{ + internal class OptLanguageBtn_Patch + { + public static Dictionary LanguageBtnDict = new(); + private static bool buttonsCreated = false; + private static OptionBtn cachedTemplateButton; + + private const float startX = 4.3241f + 2.56f; + private const float startY = 2.7769f; + private const float ySpacing = 1.2505f; + + private static List AvailableLanguages; + private const int LanguagesPerPage = 5; + private static int currentPage = 0; + private static OptionBtn[] buttonSlots = new OptionBtn[6]; // 5 language buttons + 1 next button + + public static void CreateLanguageButtons(OptionBtn templateButton) + { + if (buttonsCreated) return; + buttonsCreated = true; + cachedTemplateButton = templateButton; + + AvailableLanguages = Enum.GetValues(typeof(Utils.LanguageEnum)) + .Cast() + .Where(lang => lang != Utils.LanguageEnum.LANG_END) + .ToList(); + + for (int i = 0; i < 6; i++) + { + var newButton = Object.Instantiate(templateButton, templateButton.transform.parent); + newButton.optionType = 80 + i; + + float yPos = startY - i * ySpacing; + Vector3 pos = new(startX, yPos); + newButton.transform.position = pos; + + buttonSlots[i] = newButton; + + LanguageBtnDict[newButton.GetInstanceID()] = new OptionButtonData + { + Button = newButton, + Position = pos + }; + } + + UpdatePage(); + } + + private static void UpdatePage() + { + int startIndex = currentPage * LanguagesPerPage; + int langCount = AvailableLanguages.Count; + + for (int i = 0; i < 5; i++) + { + var btn = buttonSlots[i]; + var data = LanguageBtnDict[btn.GetInstanceID()]; + + if (startIndex + i < langCount) + { + var lang = AvailableLanguages[startIndex + i]; + data.Language = lang; + data.IsNextButton = false; + btn.gameObject.SetActive(true); + UpdateButtonText(btn, lang.ToString()); + } + else + { + data.Language = null; + data.IsNextButton = false; + btn.gameObject.SetActive(false); + } + } + + // "Next" button always visible at index 5 + var nextBtn = buttonSlots[5]; + var nextData = LanguageBtnDict[nextBtn.GetInstanceID()]; + nextData.Language = null; + nextData.IsNextButton = true; + nextBtn.gameObject.SetActive(true); + UpdateButtonText(nextBtn, "Next"); + } + + public static void UpdateButtonText(OptionBtn button, string languageName) + { + TMP_FontAsset defaultAsset = FontStore.LoadTMPFont("English"); + + for (int i = 0; i < 3; i++) + { + Transform textTransform = button.transform.GetChild(i); + if (textTransform != null) + { + if (i == 0) textTransform.gameObject.SetActive(false); + + TextMeshProUGUI text = textTransform.GetComponent(); + if (text != null) + { + if (i == 0) + { + text.text = ""; + text.color = Color.red; + } + else + { + text.text = languageName; + } + text.fontSize = 16; + text.font = defaultAsset; + text.autoSizeTextContainer = false; + } + } + } + } + + private static void FlashMessage(OptionBtn button, string message) + { + var child = button.transform.GetChild(0); + if (child != null) + { + var text = child.GetComponent(); + if (text != null) + { + text.text = message; + } + child.gameObject.SetActive(true); + + Task.Delay(1000).ContinueWith(_ => + { + if (button != null && child != null && child.gameObject.activeSelf) + { + child.gameObject.SetActive(false); + } + }); + } + } + + [HarmonyPatch(typeof(OptionBtn))] + public static class OptLangBtn_Patch + { + [HarmonyPatch(nameof(OptionBtn.Awake))] + [HarmonyPostfix] + private static void Awake(OptionBtn __instance) + { + if (!buttonsCreated || cachedTemplateButton == null) + { + buttonsCreated = false; + CreateLanguageButtons(__instance); + } + } + + [HarmonyPatch("OnMouseUpAsButton")] + [HarmonyPrefix] + private static void OnMouseUpAsButton(OptionBtn __instance) + { + if (LanguageBtnDict.TryGetValue(__instance.GetInstanceID(), out var btnData)) + { + if (btnData.IsNextButton) + { + currentPage = (currentPage + 1) % (int)Math.Ceiling((float)AvailableLanguages.Count / LanguagesPerPage); + UpdatePage(); + return; + } + + if (btnData.Language is Utils.LanguageEnum selectedLang) + { + string currentLang = Utils.Language.ToString(); + + if (currentLang == selectedLang.ToString()) + { + FlashMessage(btnData.Button, "Already Selected!"); + } + else + { + Utils.ChangeLanguage(selectedLang.ToString()); + Debug.Log($"Language changed to: {selectedLang}"); + FlashMessage(btnData.Button, "Language Changed!"); + } + } + } + } + + [HarmonyPatch(nameof(OptionBtn.Update))] + [HarmonyPostfix] + private static void Update(OptionBtn __instance) + { + if (LanguageBtnDict.TryGetValue(__instance.GetInstanceID(), out var btnData)) + { + btnData.Button.transform.position = btnData.Position; + } + } + } + } +} +#endif \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/OptionBtn_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/OptionBtn_Patch.cs new file mode 100644 index 0000000..e4d1e07 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/OptionBtn_Patch.cs @@ -0,0 +1,69 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects +{ + [HarmonyPatch(typeof(OptionBtn))] + public static class OptionBtn_Patch + { + [HarmonyPatch(nameof(OptionBtn.Awake))] + [HarmonyPostfix] + private static void Awake(OptionBtn __instance) + { + Transform text_1Transform = __instance.transform.GetChild(0)?.transform; + if (text_1Transform != null) + { + TextMeshProUGUI text_1 = text_1Transform.GetComponent(); + text_1 = StringStore.TranslateText(text_1); + text_1.autoSizeTextContainer = false; + } + + Transform textTransform = __instance.transform.GetChild(1)?.transform; + if (textTransform != null) + { + TextMeshProUGUI text = textTransform.GetComponent(); + text = StringStore.TranslateText(text); + text.autoSizeTextContainer = false; + } + + Transform text2Transform = __instance.transform.GetChild(2)?.transform; + if (text2Transform != null) + { + TextMeshProUGUI text2 = text2Transform.GetComponent(); + text2 = StringStore.TranslateText(text2); + text2.autoSizeTextContainer = false; + } + } + + [HarmonyPatch("OnMouseUpAsButton")] + [HarmonyPostfix] + private static void OnMouseUpAsButtonPostfix(OptionBtn __instance) + { + Transform text_1Transform = __instance.transform.GetChild(0)?.transform; + if (text_1Transform != null) + { + TextMeshProUGUI text_1 = text_1Transform.GetComponent(); + text_1 = StringStore.TranslateText(text_1); + text_1.autoSizeTextContainer = false; + } + + Transform textTransform = __instance.transform.GetChild(1)?.transform; + if (textTransform != null) + { + TextMeshProUGUI text = textTransform.GetComponent(); + text = StringStore.TranslateText(text); + text.autoSizeTextContainer = false; + } + + Transform text2Transform = __instance.transform.GetChild(2)?.transform; + if (text2Transform != null) + { + TextMeshProUGUI text2 = text2Transform.GetComponent(); + text2 = StringStore.TranslateText(text2); + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/PVPPotBtn_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/PVPPotBtn_Patch.cs new file mode 100644 index 0000000..375a287 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/PVPPotBtn_Patch.cs @@ -0,0 +1,42 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects +{ + [HarmonyPatch(typeof(PVPPotBtn))] + public class PVPPotBtn_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(PVPPotBtn.OnMouseUpAsButton))] + public static void OnMouseUpAsButton(PVPPotBtn __instance) + { + Transform sceneText = __instance.transform.FindChild("text"); + if(sceneText != null) + { + TextMeshProUGUI sceneTextTMP = sceneText.transform.GetComponent(); + if(sceneTextTMP != null) + { + sceneTextTMP.text = StringStore.TranslateText(sceneTextTMP.text); + } + } + Transform sceneTextShadow = sceneText.transform.FindChild("text_1"); + if(sceneTextShadow != null) + { + TextMeshProUGUI sceneTextShadowTMP = sceneTextShadow.transform.GetComponent(); + if (sceneTextShadowTMP != null) + { + sceneTextShadowTMP.text = StringStore.TranslateText(sceneTextShadowTMP.text); + } + } + + if (__instance.name.Equals("ChangeBg_3") || __instance.name.Equals("ChangeBg_4")) + { + __instance.gameObject.SetActive(false); + __instance.gameObject.SetActive(true); + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/PauseMenu_Btn_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/PauseMenu_Btn_Patch.cs new file mode 100644 index 0000000..501706f --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/PauseMenu_Btn_Patch.cs @@ -0,0 +1,15 @@ +using HarmonyLib; +using Il2Cpp; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects +{ + [HarmonyPatch(typeof(PauseMenu_Btn))] + public static class PauseMenu_Btn_Patch + { + [HarmonyPatch(nameof(PauseMenu_Btn.Start))] + [HarmonyPostfix] + private static void Start(PauseMenu_Btn __instance) => StringStore.TranslateTextTransform(__instance.transform); + } + +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/SaveMenuBtn_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/SaveMenuBtn_Patch.cs new file mode 100644 index 0000000..f9b16ac --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/ButtonObjects/SaveMenuBtn_Patch.cs @@ -0,0 +1,24 @@ +#if FIX +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects +{ + [HarmonyPatch(typeof(SaveMenuBtn))] + public static class SaveMenuBtn_Patch + { + [HarmonyPatch(nameof(SaveMenuBtn.OnMouseUpAsButton))] + [HarmonyPostfix] + private static void OnMouseUpAsButton(SaveMenuBtn __instance) + { + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + __instance.theName.text = StringStore.TranslateText(__instance.theName.text); + __instance.theName.font = fontAsset; + } + } +} +#endif \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/Close_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/Close_Patch.cs new file mode 100644 index 0000000..9845019 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/Close_Patch.cs @@ -0,0 +1,52 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.GameObjects +{ + [HarmonyPatch(typeof(Close))] + public static class Close_Patch + { + [HarmonyPatch(nameof(Close.Start))] + [HarmonyPostfix] + private static void Close_Start(Close __instance) + { + + TextMeshPro closeText = __instance.transform.GetChild(0).GetComponent(); + closeText.text = "合上"; + closeText = StringStore.TranslateText(closeText); + closeText.autoSizeTextContainer = true; + + Transform AlmanacTransform = __instance.transform.parent.transform; + + Transform nameTransform = AlmanacTransform.Find("Name"); + if (nameTransform != null) + { + TextMeshPro nameTMP = nameTransform.transform.GetComponent(); + if (nameTMP) + { + nameTMP = StringStore.TranslateText(nameTMP); + nameTMP.autoSizeTextContainer = true; + } + + Transform nameShadowTransform = nameTransform.Find("NameShadow"); + if (nameShadowTransform) + { + TextMeshPro nameShadowTMP = nameShadowTransform.transform.GetComponent(); + if (nameShadowTMP) + { + nameShadowTMP = StringStore.TranslateText(nameShadowTMP); + nameShadowTMP.autoSizeTextContainer = true; + } + } + } + + StringStore.TranslateTextTransform(AlmanacTransform.Find("Back"), true); + StringStore.TranslateTextTransform(AlmanacTransform.Find("NextPage")); + StringStore.TranslateTextTransform(AlmanacTransform.Find("LastPage")); + + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/CustomSettings_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/CustomSettings_Patch.cs new file mode 100644 index 0000000..cee9577 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/CustomSettings_Patch.cs @@ -0,0 +1,24 @@ +using HarmonyLib; +using Il2Cpp; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects +{ + [HarmonyPatch(typeof(CustomSettings))] + public static class CustomSettings_Patch + { + [HarmonyPatch(nameof(CustomSettings.Awake))] + [HarmonyPostfix] + private static void Awake(CustomSettings __instance) + { + __instance.textMesh = StringStore.TranslateText(__instance.textMesh); + } + + [HarmonyPatch(nameof(CustomSettings.ChangeText))] + [HarmonyPostfix] + private static void ChangeText(CustomSettings __instance) + { + __instance.textMesh = StringStore.TranslateText(__instance.textMesh); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/CustomSun_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/CustomSun_Patch.cs new file mode 100644 index 0000000..ab596b9 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/CustomSun_Patch.cs @@ -0,0 +1,45 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.GameObjects +{ + [HarmonyPatch(typeof(CustomSun))] + public static class CustomSun_Patch + { + [HarmonyPatch(nameof(CustomSun.Awake))] + [HarmonyPostfix] + private static void Awake(CustomSun __instance) + { + if (__instance.inputField.gameObject.activeSelf) + { + string oriTextSun = __instance.inputField.m_Text; + __instance.inputField.gameObject.SetActive(false); + __instance.inputField.m_Text = StringStore.TranslateText(oriTextSun); + __instance.inputField.m_OriginalText = StringStore.TranslateText(oriTextSun); + __instance.inputField.gameObject.SetActive(true); + } + + if (__instance.setFlags.gameObject.activeSelf) + { + string oriTextFlags = __instance.setFlags.m_Text; + __instance.setFlags.gameObject.SetActive(false); + __instance.setFlags.m_Text = StringStore.TranslateText(oriTextFlags); + __instance.setFlags.m_OriginalText = StringStore.TranslateText(oriTextFlags); + __instance.setFlags.gameObject.SetActive(true); + } + + Transform lookZombieTransform = __instance.lookZombie.transform.GetChild(0).transform; + if (lookZombieTransform != null) + { + TextMeshProUGUI lookZombieTMP = lookZombieTransform.GetComponent(); + if (lookZombieTMP != null) + { + lookZombieTMP = StringStore.TranslateText(lookZombieTMP); + } + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/GardenPlant_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/GardenPlant_Patch.cs new file mode 100644 index 0000000..679627a --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/GardenPlant_Patch.cs @@ -0,0 +1,24 @@ +using HarmonyLib; +using Il2Cpp; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects +{ + [HarmonyPatch(typeof(GardenPlant))] + public static class GardenPlant_Patch + { + [HarmonyPatch(nameof(GardenPlant.Update))] + [HarmonyPostfix] + private static void Update(GardenPlant __instance) + { + __instance.infoText = StringStore.TranslateText(__instance.infoText); + } + + [HarmonyPatch(nameof(GardenPlant.UpdateInfo))] + [HarmonyPostfix] + private static void UpdateInfo(GardenPlant __instance) + { + __instance.infoText = StringStore.TranslateText(__instance.infoText); + } + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/DY_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/DY_Patch.cs new file mode 100644 index 0000000..10b48b2 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/DY_Patch.cs @@ -0,0 +1,17 @@ +using HarmonyLib; +using Il2Cpp; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects +{ + [HarmonyPatch(typeof(DY))] + public static class DY_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(DY.Update))] + private static void Update(DY __instance) + { + __instance.TextMeshPro.text = StringStore.TranslateText(__instance.TextMeshPro.text); + } + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/LanternUmbrella_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/LanternUmbrella_Patch.cs new file mode 100644 index 0000000..d751354 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/LanternUmbrella_Patch.cs @@ -0,0 +1,18 @@ +using HarmonyLib; +using Il2Cpp; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects +{ +[HarmonyPatch(typeof(LanternUmbrella))] + public class LanternUmbrella_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(LanternUmbrella.Update))] + private static void Update(LanternUmbrella __instance) + { + __instance.energyText = StringStore.TranslateText(__instance.energyText); + __instance.energyTextShadow = StringStore.TranslateText(__instance.energyTextShadow); + } + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/MagnetBox_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/MagnetBox_Patch.cs new file mode 100644 index 0000000..ea419b4 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/MagnetBox_Patch.cs @@ -0,0 +1,17 @@ +using HarmonyLib; +using Il2Cpp; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects +{ + [HarmonyPatch(typeof(MagnetBox))] + public class MagnetBox_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(MagnetBox.Update))] + private static void Update(MagnetBox __instance) + { + StringStore.TranslateTextTransform(__instance.transform); + } + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/MagnetInterface_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/MagnetInterface_Patch.cs new file mode 100644 index 0000000..a46f208 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/MagnetInterface_Patch.cs @@ -0,0 +1,17 @@ +using HarmonyLib; +using Il2Cpp; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects +{ + [HarmonyPatch(typeof(MagnetInterface))] + public class MagnetInterface_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(MagnetInterface.Update))] + private static void Update(MagnetInterface __instance) + { + StringStore.TranslateTextTransform(__instance.transform); + } + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/Money_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/Money_Patch.cs new file mode 100644 index 0000000..12ede0d --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/Money_Patch.cs @@ -0,0 +1,18 @@ +using HarmonyLib; +using Il2Cpp; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects +{ + [HarmonyPatch(typeof(Money))] + public static class Money_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(Money.Update))] + private static void Update(Money __instance) + { + __instance.beanCount.text = StringStore.TranslateText(__instance.beanCount.text); + __instance.beanCount2.text = StringStore.TranslateText(__instance.beanCount2.text); + } + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/Plant_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/Plant_Patch.cs new file mode 100644 index 0000000..3aad6c8 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/Plant_Patch.cs @@ -0,0 +1,24 @@ +#if FIX +using HarmonyLib; +using Il2Cpp; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects +{ + [HarmonyPatch(typeof(Plant))] + public static class Plant_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(Plant.UpdateHealthText))] + private static void UpdateHealthText(Plant __instance) + { + Transform healthTransform = __instance.transform.Find("health"); + if (healthTransform != null) + { + StringStore.TranslateTextTransform(__instance.transform); + } + } + } +} +#endif \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/PlayerName_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/PlayerName_Patch.cs new file mode 100644 index 0000000..29efec6 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/PlayerName_Patch.cs @@ -0,0 +1,17 @@ +using HarmonyLib; +using Il2Cpp; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects +{ + [HarmonyPatch(typeof(PlayerName))] + public static class PlayerName_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(PlayerName.Update))] + private static void Update(PlayerName __instance) + { + __instance.textMesh.text = StringStore.TranslateText(__instance.textMesh.text); + } + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/SelectYourPlants_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/SelectYourPlants_Patch.cs new file mode 100644 index 0000000..073cc7b --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/SelectYourPlants_Patch.cs @@ -0,0 +1,21 @@ +using HarmonyLib; +using Il2Cpp; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects +{ + [HarmonyPatch(typeof(SelectYourPlants))] + public static class SelectYourPlants_Patch + { + [HarmonyPatch(nameof(SelectYourPlants.Awake))] + [HarmonyPostfix] + private static void Awake(SelectYourPlants __instance) + { + __instance.TextMeshProUGUI = StringStore.TranslateText(__instance.TextMeshProUGUI); + __instance.TextMeshProUGUI.autoSizeTextContainer = true; + + __instance.TextMeshProUGUI2 = StringStore.TranslateText(__instance.TextMeshProUGUI2); + __instance.TextMeshProUGUI2.autoSizeTextContainer = true; + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/Zombie_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/Zombie_Patch.cs new file mode 100644 index 0000000..222b54e --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/MinorObjects/Zombie_Patch.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects +{ + class Zombie_Patch + { + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/NoticePauseMenu_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/NoticePauseMenu_Patch.cs new file mode 100644 index 0000000..25af2b3 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/NoticePauseMenu_Patch.cs @@ -0,0 +1,32 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.GameObjects +{ + [HarmonyPatch(typeof(NoticeMenu))] + public class NoticePauseMenu_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(NoticeMenu.Start))] + private static void Start(NoticeMenu __instance) + { + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + Transform warningTransform = __instance.transform.GetChild(0); + Transform warningTextTransform = warningTransform.FindChild("文字"); + Transform warningTextShadowTransform = warningTransform.FindChild("文字2"); + Transform[] array = [warningTextTransform, warningTextShadowTransform]; + + for (int i = 0; i < array.Length; i++) + { + if (array[i] != null) + { + array[i].GetComponent().text = StringStore.TranslateText(array[i].GetComponent().text); + array[i].GetComponent().font = fontAsset; + } + } + } + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/TravelBuff_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/TravelBuff_Patch.cs new file mode 100644 index 0000000..a2bed2c --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/TravelBuff_Patch.cs @@ -0,0 +1,18 @@ +using HarmonyLib; +using Il2Cpp; + +namespace PvZ_Fusion_Translator.Patches.GameObjects +{ + [HarmonyPatch(typeof(TravelBuff))] + public static class TravelBuff_Patch + { + [HarmonyPatch(nameof(TravelBuff.OnMouseUpAsButton))] + [HarmonyPostfix] + private static void OnMouseUpAsButton() + { + if (TravelBuffMgr.Instance == null) return; + TravelBuffMgr.Instance.text = AssetStore.StringStore.TranslateText(TravelBuffMgr.Instance.text); + TravelBuffMgr.Instance.text2 = AssetStore.StringStore.TranslateText(TravelBuffMgr.Instance.text2); + } + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/TravelRefresh_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/TravelRefresh_Patch.cs new file mode 100644 index 0000000..20a2924 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/TravelRefresh_Patch.cs @@ -0,0 +1,53 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.GameObjects +{ + [HarmonyPatch(typeof(TravelRefresh))] + public static class TravelRefresh_Patch + { + [HarmonyPatch(nameof(TravelRefresh.Update))] + [HarmonyPostfix] + private static void Update(TravelRefresh __instance) + { + TextMeshProUGUI pointsText = __instance.transform.GetChild(0).GetComponent(); + pointsText = StringStore.TranslateText(pointsText); + pointsText.autoSizeTextContainer = true; + + + Transform TravelMenuTransform = __instance.transform.parent.transform; + + Transform refreshTransform = TravelMenuTransform.Find("Refresh2").transform.Find("bank"); + if (refreshTransform != null) + { + Transform text_1Transform = refreshTransform.Find("text_1"); + if (text_1Transform != null) + { + TextMeshProUGUI text_1 = text_1Transform.GetComponent(); + + if (text_1) + { + text_1 = StringStore.TranslateText(text_1); + text_1.autoSizeTextContainer = true; + } + } + + Transform text_2Transform = refreshTransform.Find("text_2"); + if (text_2Transform != null) + { + TextMeshProUGUI text_2 = text_2Transform.GetComponent(); + + if (text_2) + { + text_2 = StringStore.TranslateText(text_2); + text_2.autoSizeTextContainer = true; + } + } + } + + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/TravelStore_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/TravelStore_Patch.cs new file mode 100644 index 0000000..5c5b487 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/TravelStore_Patch.cs @@ -0,0 +1,38 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.GameObjects +{ + [HarmonyPatch(typeof(TravelStore))] + internal class TravelStore_Patch + { + [HarmonyPatch(nameof(TravelStore.Update))] + [HarmonyPostfix] + private static void Update(TravelStore __instance) + { + foreach (TextMeshProUGUI text in __instance.introduces) + { + text.text = StringStore.TranslateText(text.text); + } + + Transform moneyTransform = __instance.transform.Find("Money"); + if (moneyTransform != null) + { + StringStore.TranslateTextTransform(moneyTransform); + } + } + + [HarmonyPatch(nameof(TravelStore.SetText), new Type[] { typeof(string)})] + [HarmonyPostfix] + private static void ShowText(TravelStore __instance) + { + foreach (TextMeshProUGUI text in __instance.introduces) + { + text.text = StringStore.TranslateText(text.text); + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/UIDifficulty_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/UIDifficulty_Patch.cs new file mode 100644 index 0000000..ba0ddc0 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/UIDifficulty_Patch.cs @@ -0,0 +1,30 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects +{ + [HarmonyPatch(typeof(UIDifficulty))] + public static class UIDifficulty_Patch + { + [HarmonyPatch(nameof(UIDifficulty.Update))] + [HarmonyPostfix] + private static void Update(UIDifficulty __instance) + { + + #if MULTI_LANGUAGE + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + string difficultyText = StringStore.patchesStore["Difficulty"][Utils.Language.ToString()]; + __instance.t.text = string.Format(difficultyText + " {0}", GameAPP.difficulty); + #else + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(); + string difficultyText = StringStore.patchesStore["Difficulty"]["Spanish"]; + __instance.t.text = string.Format("Difficulty: {0}", GameAPP.difficulty); + #endif + + __instance.t.autoSizeTextContainer = false; + __instance.t.font = fontAsset; + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/UIZombieNum_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/UIZombieNum_Patch.cs new file mode 100644 index 0000000..399bafd --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/GameObjects/UIZombieNum_Patch.cs @@ -0,0 +1,29 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects +{ + [HarmonyPatch(typeof(UIZombieNum))] + public static class UIZombieNum_Patch + { + [HarmonyPatch(nameof(UIZombieNum.Update))] + [HarmonyPostfix] + private static void Update(UIZombieNum __instance) + { + + #if MULTI_LANGUAGE + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + string zombieText = StringStore.patchesStore["Zombies"][Utils.Language.ToString()]; + __instance.t.text = string.Format(zombieText + " {0}", Board.Instance.enermyCount); + #else + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(); + string zombieText = StringStore.patchesStore["Zombies"]["Spanish"]; + __instance.t.text = string.Format(zombieText + " {0}", Board.Instance.enermyCount); + #endif + + __instance.t.font = fontAsset; + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/AbyssDevelopMenu_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/AbyssDevelopMenu_Patch.cs new file mode 100644 index 0000000..a0f32d7 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/AbyssDevelopMenu_Patch.cs @@ -0,0 +1,19 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Managers +{ + [HarmonyPatch(typeof(AbyssDevelopMenu))] + public static class AbyssDevelopMenu_Patch + { + [HarmonyPatch(nameof(AbyssDevelopMenu.UpdateInfo))] + [HarmonyPostfix] + private static void UpdateInfo(AbyssDevelopMenu __instance) + { + __instance.currentMoney.text = StringStore.TranslateText(__instance.currentMoney.text); + __instance.upgradeTextInfo.text = StringStore.TranslateText(__instance.upgradeTextInfo.text); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/AbyssMenu2_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/AbyssMenu2_Patch.cs new file mode 100644 index 0000000..bbd5a58 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/AbyssMenu2_Patch.cs @@ -0,0 +1,74 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.Managers +{ + [HarmonyPatch(typeof(AbyssMenu2))] + public static class AbyssMenu2_Patch + { + [HarmonyPatch(nameof(AbyssMenu2.Start))] + [HarmonyPostfix] + private static void Start(AbyssMenu2 __instance) + { + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + __instance.buffCountText.text = StringStore.TranslateText(__instance.buffCountText.text); + __instance.buffCountText.font = fontAsset; + + __instance.money.text = StringStore.TranslateText(__instance.money.text); + __instance.money.font = fontAsset; + + __instance.refreshText.text = StringStore.TranslateText(__instance.refreshText.text); + __instance.refreshText.font = fontAsset; + + __instance.statistics.text = StringStore.TranslateText(__instance.statistics.text); + __instance.statistics.font = fontAsset; + + Transform buffTextTransform = __instance.transform.FindChild("BuffText").transform; + if (buffTextTransform != null) StringStore.TranslateTextTransform(buffTextTransform); + + Transform moneyTransform = __instance.transform.FindChild("Money").transform; + if (moneyTransform != null) StringStore.TranslateTextTransform(moneyTransform); + + Transform buffCountTextTransform = __instance.transform.FindChild("BuffCountText").transform; + if (buffCountTextTransform != null) StringStore.TranslateTextTransform(buffCountTextTransform); + + Transform refreshTextTransform = __instance.transform.FindChild("RefreshText").transform; + if (refreshTextTransform != null) StringStore.TranslateTextTransform(refreshTextTransform); + } + + [HarmonyPatch(nameof(AbyssMenu2.Awake))] + [HarmonyPostfix] + private static void Awake(AbyssMenu2 __instance) + { + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + __instance.buffCountText.text = StringStore.TranslateText(__instance.buffCountText.text); + __instance.buffCountText.font = fontAsset; + + __instance.money.text = StringStore.TranslateText(__instance.money.text); + __instance.money.font = fontAsset; + + __instance.refreshText.text = StringStore.TranslateText(__instance.refreshText.text); + __instance.refreshText.font = fontAsset; + + __instance.statistics.text = StringStore.TranslateText(__instance.statistics.text); + __instance.statistics.font = fontAsset; + + Transform buffTextTransform = __instance.transform.FindChild("BuffText").transform; + if (buffTextTransform != null) StringStore.TranslateTextTransform(buffTextTransform); + + Transform moneyTransform = __instance.transform.FindChild("Money").transform; + if (moneyTransform != null) StringStore.TranslateTextTransform(moneyTransform); + + Transform buffCountTextTransform = __instance.transform.FindChild("BuffCountText").transform; + if (buffCountTextTransform != null) StringStore.TranslateTextTransform(buffCountTextTransform); + + Transform refreshTextTransform = __instance.transform.FindChild("RefreshText").transform; + if (refreshTextTransform != null) StringStore.TranslateTextTransform(refreshTextTransform); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/AbyssMenu_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/AbyssMenu_Patch.cs new file mode 100644 index 0000000..aa48391 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/AbyssMenu_Patch.cs @@ -0,0 +1,26 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Managers +{ + [HarmonyPatch(typeof(AbyssMenu))] + public static class AbyssMenu_Patch + { + [HarmonyPatch(nameof(AbyssMenu.Awake))] + [HarmonyPostfix] + private static void Awake(AbyssMenu __instance) + { + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (TextMeshProUGUI txt in __instance.levelInfo) + { + txt.text = StringStore.TranslateText(txt.text, false); + txt.font = fontAsset; + } + + + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/AlmanacMgrZombie_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/AlmanacMgrZombie_Patch.cs new file mode 100644 index 0000000..2f1fcdf --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/AlmanacMgrZombie_Patch.cs @@ -0,0 +1,101 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; +using static PvZ_Fusion_Translator.FileLoader; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.Managers +{ + [HarmonyPatch(typeof(AlmanacMgrZombie))] + public static partial class AlmanacMgrZombie_Patch + { + [HarmonyPatch(nameof(AlmanacMgrZombie.InitNameAndInfoFromJson))] + [HarmonyPrefix] + private static bool InitNameAndInfoFromJson(AlmanacMgrZombie __instance) + { + #if MULTI_LANGUAGE + string currentLanguage = Utils.Language.ToString(); + string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); + #else + string almanacDir = almanacDir = GetAssetDir(AssetType.Almanac); + string currentLanguage = "English"; + #endif + string path = Path.Combine(almanacDir, "ZombieStringsTranslate.json"); + + if (!File.Exists(path)) + { + Log.LogError($"ZombieStringsTranslate.json file not found at path: {path}"); + return true; + } + + #if OBFUSCATE + if (CheckSumStore.IsModified(path)) + { + Log.LogError("File {0} was modified!", path); + return true; + } + #endif + + string json; + json = File.ReadAllText(path); + + bool hasAlmanacFont = false; + TMP_FontAsset almanacFontAsset = null; + if (FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage + "_Almanac") || FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage)) + { + almanacFontAsset = FontStore.LoadTMPFontAlmanac(currentLanguage); + hasAlmanacFont = true; + } + + #if MULTI_LANGUAGE + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); + #else + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(); + #endif + + TextMeshPro component = __instance.info.GetComponent(); + TextMeshPro component2 = __instance.zombieName.GetComponent(); + TextMeshPro component3 = __instance.zombieName.transform.GetChild(0).GetComponent(); + + AlmanacMgrZombie.ZombieAlmanacData zombieData = JsonUtility.FromJson(json); + + foreach (AlmanacMgrZombie.ZombieInfo zombieInfo in zombieData.zombies) + { + if (zombieInfo.theZombieType == __instance.theZombieType) + { + component.text = zombieInfo.info + "\n\n" + zombieInfo.introduce; + component.overflowMode = TextOverflowModes.Page; + component2.text = zombieInfo.name; + component2.autoSizeTextContainer = true; + component3.text = Utils.RemoveColorTags(zombieInfo.name); + component3.autoSizeTextContainer = true; + + if (hasAlmanacFont) + component.font = almanacFontAsset; + else + component.font = fontAsset; + component2.font = fontAsset; + component3.font = fontAsset; + + return false; + } + } + + return true; + } + + [HarmonyPatch(nameof(AlmanacMgrZombie.OnMouseDown))] + [HarmonyPrefix] + private static bool OnMouseDown(AlmanacMgrZombie __instance) + { + TextMeshPro component = __instance.info.GetComponent(); + if (component != null) + { + component.pageToDisplay = component.pageToDisplay > component.m_pageNumber ? 1 : component.pageToDisplay + 1; + return false; + } + return true; + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/AlmanacPlantBank_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/AlmanacPlantBank_Patch.cs new file mode 100644 index 0000000..0ed98c8 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/AlmanacPlantBank_Patch.cs @@ -0,0 +1,108 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; +using static PvZ_Fusion_Translator.FileLoader; + +namespace PvZ_Fusion_Translator.Patches.Managers +{ + [HarmonyPatch(typeof(AlmanacPlantBank))] + public static partial class AlmanacPlantBank_Patch + { + [HarmonyPatch(nameof(AlmanacPlantBank.InitNameAndInfoFromJson))] + [HarmonyPrefix] + private static bool InitNameAndInfoFromJson(Il2Cpp.AlmanacPlantBank __instance) + { + #if MULTI_LANGUAGE + string currentLanguage = Utils.Language.ToString(); + string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); + #else + string almanacDir = GetAssetDir(AssetType.Almanac); + string currentLanguage = "English"; + #endif + string path = Path.Combine(almanacDir, "LawnStringsTranslate.json"); + + if (!File.Exists(path)) + { + Log.LogError($"LawnStringsTranslate.json file not found at path: {path}"); + return true; + } + + #if OBFUSCATE + if (CheckSumStore.IsModified(path)) + { + Log.LogError("File {0} was modified!", path); + return true; + } + #endif + + string json; + json = File.ReadAllText(path); + + bool hasAlmanacFont = false; + TMP_FontAsset almanacFontAsset = null; + if (FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage + "_Almanac") || FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage)) + { + almanacFontAsset = FontStore.LoadTMPFontAlmanac(currentLanguage); + hasAlmanacFont = true; + } + + #if MULTI_LANGUAGE + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); + #else + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(); + #endif + + TextMeshPro component = __instance.introduce.GetComponent(); + TextMeshPro component2 = __instance.plantName.GetComponent(); + TextMeshPro component3 = __instance.plantName.transform.GetChild(0).GetComponent(); + TextMeshPro component4 = __instance.cost.GetComponent(); + + Il2Cpp.AlmanacPlantBank.PlantData plantData = JsonUtility.FromJson(json); + + foreach (Il2Cpp.AlmanacPlantBank.PlantInfo plantInfo in plantData.plants) + { + if (plantInfo.seedType == __instance.theSeedType) + { + component.text = plantInfo.info + "\n\n" + plantInfo.introduce; + component.overflowMode = TextOverflowModes.Page; + component2.text = plantInfo.name; + component2.autoSizeTextContainer = true; + component3.text = Utils.RemoveColorTags(plantInfo.name); + component3.autoSizeTextContainer = true; + component4.text = plantInfo.cost; + + if (hasAlmanacFont) + { + component.font = almanacFontAsset; + component4.font = almanacFontAsset; + } + else + { + component.font = fontAsset; + component4.font = fontAsset; + } + component2.font = fontAsset; + component3.font = fontAsset; + return false; + } + } + + return true; + } + + [HarmonyPatch(nameof(AlmanacPlantBank_Patch.OnMouseDown))] + [HarmonyPrefix] + private static bool OnMouseDown(Il2Cpp.AlmanacPlantBank __instance) + { + TextMeshPro component = __instance.introduce.GetComponent(); + if (component != null) + { + component.pageToDisplay = component.pageToDisplay > component.m_pageNumber ? 1 : component.pageToDisplay + 1; + return false; + } + return true; + } + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/CustomLevelShower_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/CustomLevelShower_Patch.cs new file mode 100644 index 0000000..8ed0487 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/CustomLevelShower_Patch.cs @@ -0,0 +1,23 @@ +#if FIX +using HarmonyLib; +using Il2Cpp; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.Managers +{ + [HarmonyPatch(typeof(CustomLevelShower))] + public static class CustomLevelShower_Patch + { + [HarmonyPatch(nameof(CustomLevelShower.Show))] + [HarmonyPostfix] + private static void Show(CustomLevelShower __instance) + { + foreach (Transform transform in __instance.pages) + { + StringStore.TranslateTextTransform(transform); + } + } + } +} +#endif \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/DifficultyMgr_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/DifficultyMgr_Patch.cs new file mode 100644 index 0000000..e494473 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/DifficultyMgr_Patch.cs @@ -0,0 +1,18 @@ +using HarmonyLib; +using Il2Cpp; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Managers +{ + [HarmonyPatch(typeof(DifficultyMgr))] + public static class DifficultyMgr_Patch + { + [HarmonyPatch(nameof(DifficultyMgr.Update))] + [HarmonyPostfix] + private static void DifficultyMgr_Update(DifficultyMgr __instance) + { + __instance.t = StringStore.TranslateText(__instance.t); + __instance.t.autoSizeTextContainer = false; + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/EndlessMgr_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/EndlessMgr_Patch.cs new file mode 100644 index 0000000..de57cbf --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/EndlessMgr_Patch.cs @@ -0,0 +1,27 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.Managers +{ + [HarmonyPatch(typeof(EndlessMgr))] + public static class EndlessMgr_Patch + { + [HarmonyPatch(nameof(EndlessMgr.Awake))] + [HarmonyPostfix] + private static void Awake(EndlessMgr __instance) + { + Transform textTransform = __instance.transform.GetChild(2); + if (textTransform != null && textTransform.gameObject.activeSelf) + { + TextMeshProUGUI textTMP = textTransform.GetComponent(); + if (textTMP != null) + { + textTMP = StringStore.TranslateText(textTMP); + } + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/IZEMgr_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/IZEMgr_Patch.cs new file mode 100644 index 0000000..53ae5f5 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/IZEMgr_Patch.cs @@ -0,0 +1,28 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.Managers +{ + [HarmonyPatch(typeof(IZEMgr))] + public static class IZEMgr_Patch + { + [HarmonyPatch(nameof(IZEMgr.Start))] + [HarmonyPostfix] + public static void Start(IZEMgr __instance) + { + TextMeshProUGUI[] array = + [ + __instance.transform.GetChild(0).GetComponent(), + __instance.transform.GetChild(0).GetChild(0).GetComponent(), + ]; + for (int i = 0; i < array.Length; i++) + { + array[i] = StringStore.TranslateText(array[i]); + array[i].text = array[i].text.Replace("\n", " "); + } + } + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/InGameUIMgr_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/InGameUIMgr_Patch.cs new file mode 100644 index 0000000..bb51b71 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/InGameUIMgr_Patch.cs @@ -0,0 +1,33 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Managers +{ + [HarmonyPatch(typeof(InGameUI))] + public static class InGameUIMgr_Patch + { + [HarmonyPatch(nameof(InGameUI.Start))] + [HarmonyPostfix] + private static void Start(InGameUI __instance) + { + TextMeshProUGUI[] array = new TextMeshProUGUI[] + { + __instance.transform.GetChild(4).GetComponent(), + __instance.transform.GetChild(4).GetChild(0).GetComponent(), + __instance.transform.GetChild(5).GetComponent(), + __instance.transform.GetChild(5).GetChild(0).GetComponent(), + __instance.transform.GetChild(6).GetComponent(), + __instance.transform.GetChild(6).GetChild(0).GetComponent() + }; + TextMeshProUGUI[] array2 = array; + for (int i = 0; i < array2.Length; i++) + { + + array2[i] = StringStore.TranslateText(array2[i]); + array2[i].text = array2[i].text.Replace("\n", " "); + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/OppositeBuffManager_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/OppositeBuffManager_Patch.cs new file mode 100644 index 0000000..5c254d9 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/OppositeBuffManager_Patch.cs @@ -0,0 +1,89 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Managers +{ + [HarmonyPatch(typeof(OppositeBuffManager))] + public static class OppositeBuffManager_Patch + { + #if TESTING + [HarmonyPatch(nameof(OppositeBuffManager.InitBuffPool))] + [HarmonyPostfix] + private static void InitBuffPool(OppositeBuffManager __instance) + { + foreach(TextMeshProUGUI text in __instance.textA_bad) + { + string stripText = text.text.Replace("但", ""); + string translatedText = StringStore.TranslateText(stripText); + string replacementText = StringStore.translationString["但"] + translatedText; + text.text = replacementText; + } + foreach(TextMeshProUGUI text in __instance.textA_good) + { + text.text = StringStore.TranslateText(text.text); + } + + foreach(TextMeshProUGUI text in __instance.textB_bad) + { + string stripText = text.text.Replace("但", ""); + string translatedText = StringStore.TranslateText(stripText); + string replacementText = StringStore.translationString["但"] + translatedText; + text.text = replacementText; + } + foreach(TextMeshProUGUI text in __instance.textB_good) + { + text.text = StringStore.TranslateText(text.text); + } + } + + [HarmonyPatch(nameof(OppositeBuffManager.SetText), new Type[] { typeof(TextMeshProUGUI), typeof(BuffType), typeof(int)})] + [HarmonyPostfix] + private static void SetText(OppositeBuffManager __instance) + { + foreach(TextMeshProUGUI text in __instance.textA_bad) + { + string stripText = text.text.Replace("但", ""); + string translatedText = StringStore.TranslateText(stripText); + string replacementText = StringStore.translationString["但"] + translatedText; + text.text = replacementText; + } + foreach(TextMeshProUGUI text in __instance.textA_good) + { + text.text = StringStore.TranslateText(text.text); + } + + foreach(TextMeshProUGUI text in __instance.textB_bad) + { + string stripText = text.text.Replace("但", ""); + string translatedText = StringStore.TranslateText(stripText); + string replacementText = StringStore.translationString["但"] + translatedText; + text.text = replacementText; + } + foreach(TextMeshProUGUI text in __instance.textB_good) + { + text.text = StringStore.TranslateText(text.text); + } + } + #endif + + [HarmonyPatch(nameof(OppositeBuffManager.SetText), new Type[] { typeof(TextMeshProUGUI), typeof(BuffType), typeof(int)})] + [HarmonyPostfix] + private static void SetText(OppositeBuffManager __instance, ref TextMeshProUGUI text) + { + StringStore.TranslateTextUI(text); + } + + [HarmonyPatch(nameof(OppositeBuffManager.Awake))] + [HarmonyPostfix] + private static void Awake(OppositeBuffManager __instance) + { + StringStore.TranslateTextUI(__instance.textA_bad[0]); + StringStore.TranslateTextUI(__instance.textA_bad[1]); + StringStore.TranslateTextUI(__instance.textB_bad[0]); + StringStore.TranslateTextUI(__instance.textB_bad[1]); + } + + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/SaveMenu_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/SaveMenu_Patch.cs new file mode 100644 index 0000000..26f94e4 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/SaveMenu_Patch.cs @@ -0,0 +1,23 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Managers +{ + [HarmonyPatch(typeof(SaveMenu))] + public static class SaveMenu_Patch + { + [HarmonyPatch(nameof(SaveMenu.Start))] + [HarmonyPostfix] + private static void Start(SaveMenu __instance) + { + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + __instance.title.text = StringStore.TranslateText(__instance.title.text); + __instance.title.font = fontAsset; + __instance.title_shadow.text = StringStore.TranslateText(__instance.title_shadow.text); + __instance.title_shadow.font = fontAsset; + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/TravelBuffMgr_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/TravelBuffMgr_Patch.cs new file mode 100644 index 0000000..26b6fd8 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/TravelBuffMgr_Patch.cs @@ -0,0 +1,25 @@ +using HarmonyLib; +using Il2Cpp; + +namespace PvZ_Fusion_Translator.Patches.Managers +{ + [HarmonyPatch(typeof(TravelBuffMgr))] + public static class TravelBuffMgr_Patch + { + [HarmonyPatch(nameof(TravelBuffMgr.Awake))] + [HarmonyPostfix] + private static void Awake(TravelBuffMgr __instance) + { + __instance.text = AssetStore.StringStore.TranslateText(__instance.text); + __instance.text2 = AssetStore.StringStore.TranslateText(__instance.text2); + } + + [HarmonyPatch(nameof(TravelBuffMgr.ShowText), new Type[] { typeof(int), typeof(int) })] + [HarmonyPostfix] + private static void ShowText(TravelBuffMgr __instance) + { + __instance.text = AssetStore.StringStore.TranslateText(__instance.text); + __instance.text2 = AssetStore.StringStore.TranslateText(__instance.text2); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/TravelMenuMgr_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/TravelMenuMgr_Patch.cs new file mode 100644 index 0000000..efb3636 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/TravelMenuMgr_Patch.cs @@ -0,0 +1,51 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Managers +{ + [HarmonyPatch(typeof(TravelMenuMgr))] + public static class TravelMenuMgr_Patch + { + [HarmonyPatch(nameof(TravelMenuMgr.Start))] + [HarmonyPostfix] + private static void Start(TravelMenuMgr __instance) + { + foreach(TextMeshProUGUI text in __instance.textMesh) + { + text.text = StringStore.TranslateText(text.text); + } + foreach(TextMeshProUGUI text in __instance.textMeshShadow) + { + text.text = StringStore.TranslateText(text.text); + } + } + [HarmonyPatch(nameof(TravelMenuMgr.SetText))] + [HarmonyPostfix] + private static void SetText(TravelMenuMgr __instance) + { + foreach(TextMeshProUGUI text in __instance.textMesh) + { + text.text = StringStore.TranslateText(text.text); + } + foreach(TextMeshProUGUI text in __instance.textMeshShadow) + { + text.text = StringStore.TranslateText(text.text); + } + } + [HarmonyPatch(nameof(TravelMenuMgr.SetRichText), [typeof(int), typeof(int), typeof(TextMeshProUGUI), typeof(string)])] + [HarmonyPostfix] + private static void SetRichText(TravelMenuMgr __instance) + { + foreach(TextMeshProUGUI text in __instance.textMesh) + { + text.text = StringStore.TranslateText(text.text); + } + foreach(TextMeshProUGUI text in __instance.textMeshShadow) + { + text.text = StringStore.TranslateText(text.text); + } + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/UIMgr_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/UIMgr_Patch.cs new file mode 100644 index 0000000..a04537f --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/Managers/UIMgr_Patch.cs @@ -0,0 +1,22 @@ +using HarmonyLib; +using Il2Cpp; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Managers +{ + [HarmonyPatch(typeof(UIMgr))] + public class UIMgr_Patch + { + [HarmonyPatch(nameof(UIMgr.EnterMainMenu))] + [HarmonyPostfix] + private static void EnterMainMenu(UIMgr __instance) + { + // Log.LogInfo("Entered Main Menu"); + #if MULTI_LANGUAGE + WarningStore.WarningReload(Utils.Language); + #else + WarningStore.WarningReload(); + #endif + } + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/OtherManagers/AchievementClip_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/OtherManagers/AchievementClip_Patch.cs new file mode 100644 index 0000000..2d2fdfd --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/OtherManagers/AchievementClip_Patch.cs @@ -0,0 +1,70 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using Newtonsoft.Json; +using PvZ_Fusion_Translator.AssetStore; +using static PvZ_Fusion_Translator.FileLoader; +using static PvZ_Fusion_Translator.Patches.Managers.AlmanacPlantBank_Patch; + +namespace PvZ_Fusion_Translator.Patches.OtherManagers +{ + [HarmonyPatch(typeof(AchievementClip))] + public static class AchievementClip_Patch + { + [HarmonyPatch(nameof(AchievementClip.Start))] + [HarmonyPostfix] + private static void Start(AchievementClip __instance) + { + #if MULTI_LANGUAGE + string currentLanguage = Utils.Language.ToString(); + string achievementDir = GetAssetDir(AssetType.Almanac, Utils.Language); + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); + #else + string achievementDir = GetAssetDir(AssetType.Almanac); + TMP_FontAsset fontAsset = FontStore.LoadTMPFont(); + #endif + string path = Path.Combine(achievementDir, "AchievementsTextTranslate.json"); + + #if OBFUSCATE + if (CheckSumStore.IsModified(path)) + { + Log.LogError("File {0} was modified!", path); + return; + } + #endif + + if (!File.Exists(path)) return; + + string json; + json = File.ReadAllText(path); + Dictionary achievementsTexts = new Dictionary(); + achievementsTexts = JsonConvert.DeserializeObject>(json); + + TextMeshProUGUI text1 = __instance.introduce.transform.GetChild(1).GetComponent(); + TextMeshProUGUI text2 = __instance.introduce.transform.GetChild(2).GetComponent(); + TextMeshProUGUI name1 = __instance.image.transform.GetChild(0).GetComponent(); + + + text1.text = achievementsTexts[__instance._index].Name; + text1.font = fontAsset; + text2.text = achievementsTexts[__instance._index].Name; + text2.font = fontAsset; + name1.text = achievementsTexts[__instance._index].Text; + name1.font = fontAsset; + } + } + + public class AchievementObject + { + public Achievement achievement { get; set; } + public string Name { get; set; } + public string Text { get; set; } + + public AchievementObject(Achievement achievement = Achievement.Welcome, string name = "", string text = "") + { + this.achievement = achievement; + Name = name; + Text = text; + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/OtherManagers/GardenUI_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/OtherManagers/GardenUI_Patch.cs new file mode 100644 index 0000000..1e4f3df --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/OtherManagers/GardenUI_Patch.cs @@ -0,0 +1,22 @@ +using HarmonyLib; +using Il2Cpp; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine; + +namespace PvZ_Fusion_Translator.Patches.OtherManagers +{ + [HarmonyPatch(typeof(GardenUI))] + public static class GardenUI_Patch + { + [HarmonyPatch(nameof(GardenUI.Update))] + [HarmonyPostfix] + public static void Update(GardenUI __instance) + { + __instance.currentPageText = StringStore.TranslateText(__instance.currentPageText, false); + __instance.currentPageText2 = StringStore.TranslateText(__instance.currentPageText2, false); + + // Transform PageText = __instance.transform.Find("PageText"); + // StringStore.TranslateTextTransform(PageText.transform); + } + } +} diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/OtherManagers/MenuText_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/OtherManagers/MenuText_Patch.cs new file mode 100644 index 0000000..be63d9f --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/OtherManagers/MenuText_Patch.cs @@ -0,0 +1,23 @@ +#if FIX +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.OtherManagers +{ + [HarmonyPatch(typeof(MenuText))] + public static class MenuText_Patch + { + [HarmonyPatch(nameof(MenuText.UpdateText), new Type[] { typeof(string) })] + [HarmonyPostfix] + private static void UpdateTextPatch(MenuText __instance) + { + TextMeshProUGUI text_1 = __instance.transform.GetChild(0).Find("text1").GetComponent(); + text_1.text = StringStore.TranslateText(text_1.text); + TextMeshProUGUI text = __instance.transform.GetChild(0).Find("text").GetComponent(); + text.text = StringStore.TranslateText(text_1.text); + } + } +} +#endif \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Patches/OtherManagers/ThanksMenu_Patch.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/OtherManagers/ThanksMenu_Patch.cs new file mode 100644 index 0000000..267a80b --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Patches/OtherManagers/ThanksMenu_Patch.cs @@ -0,0 +1,23 @@ +using HarmonyLib; +using Il2Cpp; +using Il2CppTMPro; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.OtherManagers +{ + [HarmonyPatch(typeof(ThanksMenu))] + public class ThanksMenu_Patch + { + [HarmonyPostfix] + [HarmonyPatch(nameof(ThanksMenu.Update))] + private static void Update(ThanksMenu __instance) + { + TextMeshProUGUI textTransform = __instance.transform.GetChild(0).GetComponent(); + if (textTransform != null) + { + textTransform.text = StringStore.TranslateText(textTransform.text); + textTransform.autoSizeTextContainer = true; + } + } + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/MelonLoader/Utils.cs b/PvZ-Fusion-Blooms-master/MelonLoader/Utils.cs new file mode 100644 index 0000000..ba06cad --- /dev/null +++ b/PvZ-Fusion-Blooms-master/MelonLoader/Utils.cs @@ -0,0 +1,132 @@ +using PvZ_Fusion_Translator.AssetStore; +using System.Diagnostics; +using System.Text.RegularExpressions; +using UnityEngine; +using UnityEngine.Experimental.Rendering; + +namespace PvZ_Fusion_Translator +{ + public class Utils + { + internal static bool TryReplaceTexture2D(Texture2D ogTexture) + { + if (ogTexture != null) + { + if (TextureStore.textureDict.TryGetValue(ogTexture.name, out string texturePath)) + { + try + { + ImageConversion.LoadImage(ogTexture, File.ReadAllBytes(texturePath)); + + Log.LogDebug("OK! Replaced Texture " + ogTexture.name); + + ogTexture.name = "replaced_" + ogTexture.name; + return true; + } + catch (Exception ex) + { + Log.LogError("Failed to replace texture: " + ogTexture.name + " at path: " + texturePath); + Log.LogError(ex.ToString()); + } + } + } + return false; + } + + internal static Texture2D LoadImage(string path) + { + if (!File.Exists(path)) + { + throw new FileNotFoundException($"The image file at path '{path}' does not exist."); + } + + byte[] array = File.ReadAllBytes(path); + Texture2D texture2D = new(2, 2, GraphicsFormat.R8G8B8A8_UNorm, TextureCreationFlags.None, 1, IntPtr.Zero, null); + ImageConversion.LoadImage(texture2D, array); + return texture2D; + } + + public static Color HexToColor(string hex) + { + + hex = hex.Replace("#", ""); + + float r = int.Parse(hex.Substring(0, 2), System.Globalization.NumberStyles.HexNumber) / 255f; + float g = int.Parse(hex.Substring(2, 2), System.Globalization.NumberStyles.HexNumber) / 255f; + float b = int.Parse(hex.Substring(4, 2), System.Globalization.NumberStyles.HexNumber) / 255f; + + return new Color(r, g, b); + } + + public static void OpenSaveDirectory() + { + string saveDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "AppData", "LocalLow", "LanPiaoPiao", "PlantsVsZombiesRH"); + Process.Start("explorer.exe", saveDirectory); + } + + public static void OpenTrello() + { + string website = "https://trello.com/b/DcdT1kUp"; + Process.Start(new ProcessStartInfo(website) { UseShellExecute = true }); + } + + public static string RemoveColorTags(string text) + { + return Regex.Replace(text, @"]+>", ""); + } + + #if MULTI_LANGUAGE + internal static void ChangeLanguage(string language) + { + OldLanguage = Language; + + if (Enum.TryParse(language, out Utils.LanguageEnum lang)) + { + Utils.Language = lang; + } + else + { + // Handle invalid language string + Log.LogError($"Invalid language string: {language}"); + } + + WarningStore.isWarningMessageLoaded = false; + FontStore.Reload(); + StringStore.Reload(); + TextureStore.Reload(); + FileLoader.SaveLanguage(); + } + #endif + + #if MULTI_LANGUAGE + public static Utils.LanguageEnum OldLanguage; + #endif + + public static Utils.LanguageEnum Language; + + public enum LanguageEnum + { + // first column + English, + French, + Italian, + German, + Spanish, + Portuguese, + + // second column + Javanese, //Filipino, + Vietnamese, + Indonesian, + Russian, + Japanese, + Korean, + + // third column + // Ukrainian, + // Slovak, + + LANG_END + } + } +} \ No newline at end of file diff --git a/PvZ-Fusion-Blooms-master/PvZ Fusion Translator.sln b/PvZ-Fusion-Blooms-master/PvZ Fusion Translator.sln new file mode 100644 index 0000000..d5172a2 --- /dev/null +++ b/PvZ-Fusion-Blooms-master/PvZ Fusion Translator.sln @@ -0,0 +1,146 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.10.35122.118 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PvZ Fusion Translator [MelonLoader]", "MelonLoader\PvZ Fusion Translator [MelonLoader].csproj", "{90AA30F8-EFE7-6E1A-3859-0EE79252222A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PvZ Fusion Translator [BepInEx]", "BepInEx\PvZ Fusion Translator [BepInEx].csproj", "{395E60A0-A884-61F2-EF18-BC94BB7D9C69}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}" + ProjectSection(SolutionItems) = preProject + README.md = README.md + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + DebugEnglish|Any CPU = DebugEnglish|Any CPU + DebugEnglish|ARM64 = DebugEnglish|ARM64 + DebugEnglish|x64 = DebugEnglish|x64 + DebugObfuscate|Any CPU = DebugObfuscate|Any CPU + DebugObfuscate|ARM64 = DebugObfuscate|ARM64 + DebugObfuscate|x64 = DebugObfuscate|x64 + DebugTesting|Any CPU = DebugTesting|Any CPU + DebugTesting|ARM64 = DebugTesting|ARM64 + DebugTesting|x64 = DebugTesting|x64 + ReleaseEnglish|Any CPU = ReleaseEnglish|Any CPU + ReleaseEnglish|ARM64 = ReleaseEnglish|ARM64 + ReleaseEnglish|x64 = ReleaseEnglish|x64 + ReleaseMulti|Any CPU = ReleaseMulti|Any CPU + ReleaseMulti|ARM64 = ReleaseMulti|ARM64 + ReleaseMulti|x64 = ReleaseMulti|x64 + ReleaseObfuscate|Any CPU = ReleaseObfuscate|Any CPU + ReleaseObfuscate|ARM64 = ReleaseObfuscate|ARM64 + ReleaseObfuscate|x64 = ReleaseObfuscate|x64 + ReleaseOther|Any CPU = ReleaseOther|Any CPU + ReleaseOther|ARM64 = ReleaseOther|ARM64 + ReleaseOther|x64 = ReleaseOther|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.Debug|Any CPU.ActiveCfg = Debug|x64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.Debug|Any CPU.Build.0 = Debug|x64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.Debug|ARM64.Build.0 = Debug|ARM64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.Debug|x64.ActiveCfg = Debug|x64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.Debug|x64.Build.0 = Debug|x64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.DebugEnglish|Any CPU.ActiveCfg = DebugEnglish|x64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.DebugEnglish|Any CPU.Build.0 = DebugEnglish|x64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.DebugEnglish|ARM64.ActiveCfg = DebugEnglish|ARM64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.DebugEnglish|ARM64.Build.0 = DebugEnglish|ARM64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.DebugEnglish|x64.ActiveCfg = DebugEnglish|x64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.DebugEnglish|x64.Build.0 = DebugEnglish|x64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.DebugObfuscate|Any CPU.ActiveCfg = Debug|x64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.DebugObfuscate|Any CPU.Build.0 = Debug|x64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.DebugObfuscate|ARM64.ActiveCfg = DebugObfuscate|ARM64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.DebugObfuscate|ARM64.Build.0 = DebugObfuscate|ARM64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.DebugObfuscate|x64.ActiveCfg = DebugObfuscate|x64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.DebugObfuscate|x64.Build.0 = DebugObfuscate|x64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.DebugTesting|Any CPU.ActiveCfg = DebugTesting|Any CPU + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.DebugTesting|Any CPU.Build.0 = DebugTesting|Any CPU + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.DebugTesting|ARM64.ActiveCfg = DebugTesting|ARM64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.DebugTesting|ARM64.Build.0 = DebugTesting|ARM64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.DebugTesting|x64.ActiveCfg = DebugTesting|x64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.DebugTesting|x64.Build.0 = DebugTesting|x64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseEnglish|Any CPU.ActiveCfg = ReleaseEnglish|Any CPU + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseEnglish|Any CPU.Build.0 = ReleaseEnglish|Any CPU + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseEnglish|ARM64.ActiveCfg = ReleaseEnglish|ARM64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseEnglish|ARM64.Build.0 = ReleaseEnglish|ARM64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseEnglish|x64.ActiveCfg = ReleaseEnglish|x64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseEnglish|x64.Build.0 = ReleaseEnglish|x64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseMulti|Any CPU.ActiveCfg = ReleaseMulti|Any CPU + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseMulti|Any CPU.Build.0 = ReleaseMulti|Any CPU + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseMulti|ARM64.ActiveCfg = ReleaseMulti|ARM64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseMulti|ARM64.Build.0 = ReleaseMulti|ARM64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseMulti|x64.ActiveCfg = ReleaseMulti|x64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseMulti|x64.Build.0 = ReleaseMulti|x64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseObfuscate|Any CPU.ActiveCfg = ReleaseObfuscate|Any CPU + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseObfuscate|Any CPU.Build.0 = ReleaseObfuscate|Any CPU + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseObfuscate|ARM64.ActiveCfg = ReleaseObfuscate|ARM64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseObfuscate|ARM64.Build.0 = ReleaseObfuscate|ARM64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseObfuscate|x64.ActiveCfg = ReleaseObfuscate|x64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseObfuscate|x64.Build.0 = ReleaseObfuscate|x64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseOther|Any CPU.ActiveCfg = ReleaseOther|Any CPU + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseOther|Any CPU.Build.0 = ReleaseOther|Any CPU + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseOther|ARM64.ActiveCfg = ReleaseOther|ARM64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseOther|ARM64.Build.0 = ReleaseOther|ARM64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseOther|x64.ActiveCfg = ReleaseOther|x64 + {90AA30F8-EFE7-6E1A-3859-0EE79252222A}.ReleaseOther|x64.Build.0 = ReleaseOther|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.Debug|Any CPU.ActiveCfg = Debug|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.Debug|Any CPU.Build.0 = Debug|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.Debug|ARM64.Build.0 = Debug|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.Debug|x64.ActiveCfg = Debug|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.Debug|x64.Build.0 = Debug|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugEnglish|Any CPU.ActiveCfg = Debug|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugEnglish|Any CPU.Build.0 = Debug|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugEnglish|ARM64.ActiveCfg = Debug|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugEnglish|ARM64.Build.0 = Debug|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugEnglish|x64.ActiveCfg = Debug|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugEnglish|x64.Build.0 = Debug|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugObfuscate|Any CPU.ActiveCfg = Debug|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugObfuscate|Any CPU.Build.0 = Debug|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugObfuscate|ARM64.ActiveCfg = DebugObfuscate|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugObfuscate|ARM64.Build.0 = DebugObfuscate|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugObfuscate|x64.ActiveCfg = DebugObfuscate|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugObfuscate|x64.Build.0 = DebugObfuscate|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugTesting|Any CPU.ActiveCfg = Debug|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugTesting|Any CPU.Build.0 = Debug|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugTesting|ARM64.ActiveCfg = Debug|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugTesting|ARM64.Build.0 = Debug|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugTesting|x64.ActiveCfg = Debug|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugTesting|x64.Build.0 = Debug|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseEnglish|Any CPU.ActiveCfg = Release|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseEnglish|Any CPU.Build.0 = Release|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseEnglish|ARM64.ActiveCfg = Release|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseEnglish|ARM64.Build.0 = Release|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseEnglish|x64.ActiveCfg = Release|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseEnglish|x64.Build.0 = Release|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseMulti|Any CPU.ActiveCfg = Release|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseMulti|Any CPU.Build.0 = Release|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseMulti|ARM64.ActiveCfg = Release|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseMulti|ARM64.Build.0 = Release|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseMulti|x64.ActiveCfg = Release|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseMulti|x64.Build.0 = Release|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseObfuscate|Any CPU.ActiveCfg = ReleaseObfuscate|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseObfuscate|Any CPU.Build.0 = ReleaseObfuscate|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseObfuscate|ARM64.ActiveCfg = ReleaseObfuscate|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseObfuscate|ARM64.Build.0 = ReleaseObfuscate|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseObfuscate|x64.ActiveCfg = ReleaseObfuscate|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseObfuscate|x64.Build.0 = ReleaseObfuscate|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseOther|Any CPU.ActiveCfg = Release|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseOther|Any CPU.Build.0 = Release|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseOther|ARM64.ActiveCfg = Release|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseOther|ARM64.Build.0 = Release|Any CPU + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseOther|x64.ActiveCfg = Release|x64 + {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseOther|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {ECF1E7B1-C1AD-41F5-BC76-4862410A89AA} + EndGlobalSection +EndGlobal diff --git a/PvZ-Fusion-Blooms-master/README.md b/PvZ-Fusion-Blooms-master/README.md new file mode 100644 index 0000000..bf3995a --- /dev/null +++ b/PvZ-Fusion-Blooms-master/README.md @@ -0,0 +1,34 @@ +# PvZ Fusion Translator +PvZ Fusion Translator is a **Melon Mod** that allows for an easier method of translating the in-game UI, the Almanac, and textures. + +# Installation +- Install [MelonLoader](https://melonwiki.xyz/#/modders/quickstart). +- Download and extract [AudioImportLib](https://thunderstore.io/c/bonelab/p/TrevTV/AudioImportLib/) to the `Mods` folder. +- [Download](https://github.com/Dynamixus/PvZ-Fusion-Translator/releases/latest) and extract everything to the `Mods` folder in your game's installation directory. + +# Build +- Edit `GamePath` in `PvZ Fusion Translator.csproj` to point to your game installation folder. +- Proceed to `Build`. +- The built mod will automatically replace the current mod installed in your `Mods` directory. + +# Translation +- Basic and regex string translation is available on the `Strings` folder. +- Texture replacements can be put inside the `Textures` folder, as long as the file is a `.PNG` file and the filename is an exact equivalent to an existing texture in the game. +- Almanac Translation can be done by editing the files in `Dumps` and putting the edited files in `Almanac`. Append `Translate` to the end of their file names (before the `.JSON`). + +# Audio Replacing +- Same with texture replacements, put your replacement audio in the `Audios` + +# Debug Features +- [Home] Reload Strings (Developer Build) +- [End] Reload Textures (Developer Build) + +# Credits +- [蓝飘飘fly](https://space.bilibili.com/3546619314178489) - Game Developer +- [ArifRios1st](https://github.com/ArifRios1st/PVZ-Hyper-Fusion-Mod) - OG Mod Developer +- [TrevTV/MelonLoader-AudioTools](https://github.com/TrevTV/MelonLoader-AudioTools) - Audio Replacer Developer + +# Contribution +If you'd like to contribute in any way, please join us on our [Discord](https://discord.gg/FTfz45NGxh). + +