From c6851be43e285b08429ac5270cf27c697f803f59 Mon Sep 17 00:00:00 2001 From: Emik Date: Wed, 21 Oct 2026 19:34:57 +0200 Subject: [PATCH] Merge BepInEx and MelonLoader projects --- .gitignore | 541 ++++++-- .../.idea/material_theme_project_new.xml | 11 + BepInEx/AssetStore/AudioStore.cs | 179 --- BepInEx/AssetStore/CheckSumStore.cs | 862 ------------ BepInEx/AssetStore/FontStore.cs | 193 --- BepInEx/AssetStore/StringStore.cs | 411 ------ BepInEx/AssetStore/TextureStore.cs | 77 -- BepInEx/AssetStore/WarningStore.cs | 218 --- BepInEx/Core.cs | 185 --- .../Dependencies/AudioImportLib.BepInEx.dll | Bin 295936 -> 0 bytes BepInEx/FileLoader.cs | 382 ----- BepInEx/FontHandler.cs | 45 - BepInEx/Log.cs | 25 - BepInEx/ModFeatures.cs | 80 -- .../BaseTextObjects/InGameText_Patch.cs | 62 - .../BaseTextObjects/TMP_InputField_Patch.cs | 25 - .../BaseTextObjects/TextMeshProUGUI_Patch.cs | 97 -- .../BaseTextObjects/TextMeshPro_Patch.cs | 30 - .../GameObjects/AbyssBuffMenu_Patch.cs | 110 -- .../GameObjects/AbyssCheckInBag_Patch.cs | 28 - .../GameObjects/AbyssDevelopMenu_Patch.cs | 49 - .../Patches/GameObjects/AbyssMenu_Patch.cs | 49 - .../AbyssSelectBuffWindow_Patch.cs | 57 - .../GameObjects/AbyssSettlementMenu_Patch.cs | 55 - .../GameObjects/AbyssStoreMenu_Patch.cs | 17 - .../AdvantureEvolutionMenu_Patch.cs | 20 - .../GameObjects/AdvantureHelpMenu_Patch.cs | 20 - .../GameObjects/AdvantureMenu2_Patch.cs | 27 - .../GameObjects/AdvantureMenu_Patch.cs | 63 - .../GameObjects/AdvantureMissionMenu_Patch.cs | 55 - .../GameObjects/AdvantureStarMenu_Patch.cs | 60 - .../GameObjects/AlmanacPlantMenu_Patch.cs | 88 -- .../GameObjects/AlmanacPlantWindow_Patch.cs | 189 --- .../GameObjects/AlmanacZombieMenu_Patch.cs | 31 - .../GameObjects/AlmanacZombieWindow_Patch.cs | 187 --- BepInEx/Patches/GameObjects/Almanac_Patch.cs | 49 - BepInEx/Patches/GameObjects/BaseMenu_Patch.cs | 41 - BepInEx/Patches/GameObjects/Board_Patch.cs | 27 - .../ButtonObjects/AbyssBuffButton_Patch.cs | 53 - .../ButtonObjects/AbyssCheckSellMenu_Patch.cs | 25 - .../ButtonObjects/AbyssLevelEnter_Patch.cs | 18 - .../ButtonObjects/Advanture_Btn_Patch.cs | 26 - .../ButtonObjects/CustomLevelEnter_Patch.cs | 27 - .../ExploreMakeSceneButton_Patch.cs | 20 - .../ExploreMakeZombieButton_Patch.cs | 20 - .../ButtonObjects/InGameBtn_Patch.cs | 41 - .../ButtonObjects/MainMenu_Btn_Patch.cs | 32 - .../ButtonObjects/NormalBtn_Patch.cs | 26 - .../ButtonObjects/OptLanguageBtn_Patch.cs | 345 ----- .../ButtonObjects/OptionBtn_Patch.cs | 69 - .../ButtonObjects/PVPPotBtn_Patch.cs | 42 - .../ButtonObjects/PauseMenu_Btn_Patch.cs | 15 - .../ButtonObjects/SaveMenuBtn_Patch.cs | 24 - .../ButtonObjects/UIButton_Patch.cs | 85 -- BepInEx/Patches/GameObjects/Close_Patch.cs | 52 - .../GameObjects/CrisisZombieWindow_Patch.cs | 37 - .../GameObjects/CustomSettings_Patch.cs | 24 - .../Patches/GameObjects/CustomSun_Patch.cs | 45 - .../Patches/GameObjects/EveBuffMenu_Patch.cs | 37 - .../GameObjects/EveOptionWindow_Patch.cs | 49 - .../GameObjects/ExploreEnterWindow_Patch.cs | 66 - .../GameObjects/ExploreMakeMenu_Patch.cs | 79 -- .../Patches/GameObjects/ExploreMenu_Patch.cs | 48 - .../FruitNinjaSelectWindow_Patch.cs | 37 - .../GameObjects/GardenBagMenu_Patch.cs | 51 - .../Patches/GameObjects/GardenCard_Patch.cs | 24 - .../Patches/GameObjects/GardenPlant_Patch.cs | 28 - BepInEx/Patches/GameObjects/MainMenu_Patch.cs | 24 - .../MinorObjects/AbyssGoods_Patch.cs | 21 - .../GameObjects/MinorObjects/Brain_Patch.cs | 56 - .../GameObjects/MinorObjects/DY_Patch.cs | 18 - .../GameObjects/MinorObjects/Jigsaw_Patch.cs | 30 - .../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 | 48 - .../MinorObjects/PlayerName_Patch.cs | 17 - .../MinorObjects/SelectYourPlants_Patch.cs | 22 - .../MinorObjects/TrainingDummy_Patch.cs | 16 - .../MinorObjects/TreasureMoney_Patch.cs | 16 - .../MinorObjects/UIProgress2_Patch.cs | 17 - .../MinorObjects/UltimateChomper_Patch.cs | 17 - .../GameObjects/MinorObjects/Zombie_Patch.cs | 176 --- .../GameObjects/NoticePauseMenu_Patch.cs | 62 - .../Patches/GameObjects/OtherMenu_Patch.cs | 19 - .../GameObjects/PlantDamageMenu_Patch.cs | 36 - .../GameObjects/PlantInfoWindow_Patch.cs | 54 - .../GameObjects/PlayerShootingMenu_Patch.cs | 40 - .../GameObjects/PlayerShootingWindow_Patch.cs | 36 - .../GameObjects/RogueCardWindow_Patch.cs | 37 - .../GameObjects/RogueStartMenu_Patch.cs | 42 - .../Patches/GameObjects/SeedLibrary_Patch.cs | 36 - .../Patches/GameObjects/ShootingMenu_Patch.cs | 25 - .../GameObjects/ShootingSelectWindow_Patch.cs | 73 - .../GameObjects/SpriteRenderer_patch.cs | 25 - .../Patches/GameObjects/TowerOption_Patch.cs | 21 - .../GameObjects/TowerUpgradeMenu_Patch.cs | 39 - .../GameObjects/TravelBuffMenu_Patch.cs | 26 - .../TravelBuffOptionButton_Patch.cs | 41 - .../Patches/GameObjects/TravelBuff_Patch.cs | 18 - .../GameObjects/TravelLookBuff_Patch.cs | 63 - .../GameObjects/TravelLookMenu_Patch.cs | 46 - .../GameObjects/TravelRefresh_Patch.cs | 28 - .../Patches/GameObjects/TravelStore_Patch.cs | 70 - .../GameObjects/TreasureConfirmMenu_Patch.cs | 24 - .../TreasureEquipmentMenu_Patch.cs | 37 - .../GameObjects/TreasureEvacuateMenu_Patch.cs | 30 - .../GameObjects/TreasureMainMenu_Patch.cs | 24 - .../GameObjects/TreasureStoreMenu_Patch.cs | 24 - .../GameObjects/TreasureUpgradeMenu_Patch.cs | 61 - .../TreasureWarehouseMenu_Patch.cs | 63 - .../Patches/GameObjects/UIDifficulty_Patch.cs | 23 - .../Patches/GameObjects/UIZombieNum_Patch.cs | 29 - .../Patches/Managers/AbyssBuffData_Patch.cs | 125 -- .../Managers/AbyssDevelopMenu_Patch.cs | 18 - BepInEx/Patches/Managers/AbyssInfo_Patch.cs | 12 - BepInEx/Patches/Managers/AbyssMenu2_Patch.cs | 101 -- BepInEx/Patches/Managers/AbyssMenu_Patch.cs | 26 - .../Managers/AlmanacMgrZombie_Patch.cs | 145 -- .../Managers/AlmanacPlantBank_Patch.cs | 200 --- BepInEx/Patches/Managers/CanvasUpUI_Patch.cs | 34 - .../Patches/Managers/ChessManager_Patch.cs | 37 - .../Managers/CustomLevelShower_Patch.cs | 23 - .../Patches/Managers/DifficultyMgr_Patch.cs | 18 - .../Patches/Managers/DrawCardManager_Patch.cs | 61 - BepInEx/Patches/Managers/EndlessMgr_Patch.cs | 27 - BepInEx/Patches/Managers/GameAPP_Patch.cs | 27 - BepInEx/Patches/Managers/Garden_Patch.cs | 21 - .../Patches/Managers/IZBottomMenu_Patch.cs | 54 - BepInEx/Patches/Managers/InGameUIMgr_Patch.cs | 34 - BepInEx/Patches/Managers/InGameUI_Patch.cs | 78 -- .../Managers/OppositeBuffManager_Patch.cs | 48 - BepInEx/Patches/Managers/SaveMenu_Patch.cs | 28 - .../Patches/Managers/TowerManager_Patch.cs | 33 - .../Patches/Managers/TravelBuffMgr_Patch.cs | 27 - BepInEx/Patches/Managers/TravelMgr_Patch.cs | 103 -- .../Patches/Managers/TreasureManager_Patch.cs | 31 - BepInEx/Patches/Managers/UIMgr_Patch.cs | 22 - .../OtherManagers/AchievementClip_Patch.cs | 73 - .../Patches/OtherManagers/GardenUI_Patch.cs | 22 - .../Patches/OtherManagers/MenuText_Patch.cs | 23 - .../Patches/OtherManagers/ThanksMenu_Patch.cs | 23 - .../PvZ Fusion Translator [BepInEx].csproj | 614 -------- BepInEx/Utils.cs | 430 ------ MelonLoader/AssetStore/AudioStore.cs | 179 --- MelonLoader/AssetStore/CheckSumStore.cs | 858 ------------ MelonLoader/AssetStore/DllStore.cs | 115 -- MelonLoader/AssetStore/FontStore.cs | 150 -- MelonLoader/AssetStore/StringStore.cs | 637 --------- MelonLoader/AssetStore/TextureStore.cs | 67 - MelonLoader/AssetStore/WarningStore.cs | 234 ---- MelonLoader/Core.cs | 132 -- MelonLoader/FileLoader.cs | 1232 ----------------- MelonLoader/FontHandler.cs | 43 - MelonLoader/Log.cs | 25 - MelonLoader/ModFeatures.cs | 95 -- .../BaseTextObjects/InGameText_Patch.cs | 400 ------ .../BaseTextObjects/TMP_Dropdown_Patch.cs | 49 - .../BaseTextObjects/TMP_InputField_Patch.cs | 24 - .../BaseTextObjects/TextMeshProUGUI_Patch.cs | 110 -- .../BaseTextObjects/TextMeshPro_Patch.cs | 33 - .../GameObjects/AlmanacBuffMenu_Patch.cs | 100 -- .../GameObjects/AlmanacCardUI_Patch.cs | 28 - .../GameObjects/AlmanacPlantMenu_Patch.cs | 137 -- .../GameObjects/AlmanacPlantWindow_Patch.cs | 69 - .../GameObjects/AlmanacSelectMenu_Patch.cs | 56 - .../GameObjects/AlmanacZombieMenu_Patch.cs | 38 - .../GameObjects/AlmanacZombieWindow_Patch.cs | 77 -- .../Patches/GameObjects/Almanac_Patch.cs | 54 - .../Patches/GameObjects/BaseMenu_Patch.cs | 67 - .../Patches/GameObjects/Board_Patch.cs | 28 - .../ButtonObjects/Advanture_Btn_Patch.cs | 26 - .../ButtonObjects/BackToIndex_Patch.cs | 19 - .../ButtonObjects/CustomLevelEnter_Patch.cs | 27 - .../ExploreMakeSceneButton_Patch.cs | 20 - .../ExploreMakeZombieButton_Patch.cs | 20 - .../GodShootingLevelButton_Patch.cs | 27 - .../ButtonObjects/InGameBtn_Patch.cs | 41 - .../ButtonObjects/LevelSaveEnter_Patch.cs | 24 - .../ButtonObjects/MainMenu_Btn_Patch.cs | 37 - .../ButtonObjects/NormalBtn_Patch.cs | 26 - .../ButtonObjects/OptLanguageBtn_Patch.cs | 393 ------ .../ButtonObjects/OptionBtn_Patch.cs | 69 - .../ButtonObjects/PVPPotBtn_Patch.cs | 43 - .../ButtonObjects/PauseMenu_Btn_Patch.cs | 15 - .../ButtonObjects/SaveMenuBtn_Patch.cs | 24 - .../GameObjects/ButtonObjects/UIBtn_Patch.cs | 23 - .../ButtonObjects/UIButton_Patch.cs | 56 - .../Patches/GameObjects/Close_Patch.cs | 53 - .../Patches/GameObjects/ConfirmMenu_Patch.cs | 24 - .../GameObjects/CrisisZombieWindow_Patch.cs | 37 - .../GameObjects/CustomSettings_Patch.cs | 24 - .../Patches/GameObjects/CustomSun_Patch.cs | 46 - .../Patches/GameObjects/EveBuffMenu_Patch.cs | 38 - .../GameObjects/EveOptionWindow_Patch.cs | 50 - .../GameObjects/ExploreEnterWindow_Patch.cs | 73 - .../GameObjects/ExploreMakeMenu_Patch.cs | 72 - .../Patches/GameObjects/ExploreMenu_Patch.cs | 39 - .../FruitNinjaSelectWindow_Patch.cs | 37 - .../Patches/GameObjects/GardenPlant_Patch.cs | 29 - .../GameObjects/GardenStoreMenu_Patch.cs | 40 - .../GameObjects/GodShootingMenu_Patch.cs | 44 - .../GameObjects/LevelResultMenu_Patch.cs | 28 - .../Patches/GameObjects/LoseMenu_Patch.cs | 26 - .../Patches/GameObjects/MainMenu_Patch.cs | 109 -- .../GameObjects/MinorObjects/Brain_Patch.cs | 57 - .../GameObjects/MinorObjects/DY_Patch.cs | 17 - .../MinorObjects/GameLose_Patch.cs | 27 - .../MinorObjects/HealthSlider_Patch.cs | 45 - .../GameObjects/MinorObjects/Jigsaw_Patch.cs | 31 - .../MinorObjects/LanternUmbrella_Patch.cs | 18 - .../MinorObjects/MagnetBox_Patch.cs | 17 - .../MinorObjects/MagnetInterface_Patch.cs | 17 - .../GameObjects/MinorObjects/Money_Patch.cs | 19 - .../GameObjects/MinorObjects/Plant_Patch.cs | 47 - .../MinorObjects/PlayerName_Patch.cs | 17 - .../MinorObjects/PumpinerChestMenu_Patch.cs | 26 - .../MinorObjects/SelectYourPlants_Patch.cs | 22 - .../MinorObjects/SpecialCard_Patch.cs | 32 - .../MinorObjects/TrainingDummy_Patch.cs | 16 - .../MinorObjects/TreasureMoney_Patch.cs | 17 - .../MinorObjects/UIProgress2_Patch.cs | 17 - .../MinorObjects/UltimateChomper_Patch.cs | 17 - .../GameObjects/MinorObjects/Zombie_Patch.cs | 178 --- .../GameObjects/NoticePauseMenu_Patch.cs | 56 - .../Patches/GameObjects/OtherMenu_Patch.cs | 20 - .../GameObjects/PVPRandomManager_Patch.cs | 33 - .../PlantCardPackageBuilder_Patch.cs | 22 - .../GameObjects/PlantDamageMenu_Patch.cs | 38 - .../GameObjects/PlantDataMenu_Patch.cs | 94 -- .../GameObjects/PlantInfoWindow_Patch.cs | 56 - .../GameObjects/PlayerSaveMenu_Patch.cs | 36 - .../GameObjects/PlayerShootingMenu_Patch.cs | 40 - .../GameObjects/PlayerShootingWindow_Patch.cs | 37 - .../Patches/GameObjects/ReNameMenu_Patch.cs | 30 - .../GameObjects/RogueCardWindow_Patch.cs | 37 - .../GameObjects/RogueStartMenu_Patch.cs | 44 - .../Patches/GameObjects/SeedLibrary_Patch.cs | 58 - .../Patches/GameObjects/ShootingMenu_Patch.cs | 25 - .../GameObjects/ShootingSelectWindow_Patch.cs | 73 - .../GameObjects/SpriteRenderer_Patch.cs | 25 - .../Patches/GameObjects/TowerOption_Patch.cs | 21 - .../GameObjects/TowerUpgradeMenu_Patch.cs | 40 - .../Patches/GameObjects/UIDifficulty_Patch.cs | 21 - .../Patches/GameObjects/UIZombieNum_Patch.cs | 29 - .../Patches/GameObjects/WarningMenu_Patch.cs | 96 -- .../Managers/AbyssDevelopMenu_Patch.cs | 19 - .../Patches/Managers/AbyssMenu2_Patch.cs | 74 - .../Patches/Managers/AbyssMenu_Patch.cs | 26 - .../Managers/AlmanacMgrZombie_Patch.cs | 128 -- .../Managers/AlmanacPlantBank_Patch.cs | 200 --- .../Patches/Managers/CanvasUpUI_Patch.cs | 31 - .../Patches/Managers/ChessManager_Patch.cs | 38 - .../Managers/CustomLevelShower_Patch.cs | 23 - .../Patches/Managers/DifficultyMgr_Patch.cs | 19 - .../Patches/Managers/DrawCardManager_Patch.cs | 78 -- .../Patches/Managers/EndlessMgr_Patch.cs | 27 - MelonLoader/Patches/Managers/Garden_Patch.cs | 22 - .../Patches/Managers/IZBottomMenu_Patch.cs | 52 - .../Patches/Managers/InGameUI_Patch.cs | 87 -- .../Patches/Managers/PVPScareyPot_Patch.cs | 34 - .../Patches/Managers/SaveMenu_Patch.cs | 37 - MelonLoader/Patches/Managers/Screen_Patch.cs | 28 - .../Patches/Managers/TowerManager_Patch.cs | 28 - MelonLoader/Patches/Managers/UIMgr_Patch.cs | 19 - .../Patches/Modes/Abyss/AbyssBagMenu_Patch.cs | 30 - .../Modes/Abyss/AbyssBuffButton_Patch.cs | 54 - .../Modes/Abyss/AbyssBuffData_Patch.cs | 125 -- .../Modes/Abyss/AbyssBuffMenu_Patch.cs | 133 -- .../Modes/Abyss/AbyssCheckInBag_Patch.cs | 31 - .../Modes/Abyss/AbyssCheckSellMenu_Patch.cs | 26 - .../Modes/Abyss/AbyssDevelopMenu_Patch.cs | 48 - .../Patches/Modes/Abyss/AbyssGoods_Patch.cs | 22 - .../Patches/Modes/Abyss/AbyssInfo_Patch.cs | 12 - .../Modes/Abyss/AbyssLevelEnter_Patch.cs | 19 - .../Patches/Modes/Abyss/AbyssMenu2_Patch.cs | 104 -- .../Patches/Modes/Abyss/AbyssMenu_Patch.cs | 49 - .../Abyss/AbyssSelectBuffWindow_Patch.cs | 57 - .../Modes/Abyss/AbyssSettlementMenu_Patch.cs | 55 - .../Modes/Abyss/AbyssStoreMenu_Patch.cs | 24 - .../Modes/Harvest/GardenBagMenu_Patch.cs | 25 - .../Patches/Modes/Harvest/GardenCard_Patch.cs | 24 - .../Harvest/TreasureConfirmMenu_Patch.cs | 25 - .../Harvest/TreasureEquipmentMenu_Patch.cs | 38 - .../Harvest/TreasureEvacuateMenu_Patch.cs | 30 - .../Modes/Harvest/TreasureMainMenu_Patch.cs | 25 - .../Modes/Harvest/TreasureManager_Patch.cs | 31 - .../Modes/Harvest/TreasureStoreMenu_Patch.cs | 25 - .../Harvest/TreasureUpgradeMenu_Patch.cs | 63 - .../Harvest/TreasureWarehouseMenu_Patch.cs | 64 - .../Modes/Odyssey/MultipleChoiceMenu_Patch.cs | 61 - .../Odyssey/OppositeBuffManager_Patch.cs | 52 - .../Modes/Odyssey/ShootingManager_Patch.cs | 583 -------- .../Modes/Odyssey/SynergyDisplay_Patch.cs | 32 - .../Odyssey/TravelAdvantureMenu_Patch.cs | 48 - .../Modes/Odyssey/TravelBuffMenu_Patch.cs | 35 - .../Modes/Odyssey/TravelBuffMgr_Patch.cs | 27 - .../Odyssey/TravelBuffOptionButton_Patch.cs | 51 - .../Patches/Modes/Odyssey/TravelBuff_Patch.cs | 18 - .../Modes/Odyssey/TravelInvestMenu_Patch.cs | 32 - .../Modes/Odyssey/TravelLookBuff_Patch.cs | 70 - .../Modes/Odyssey/TravelLookMenu_Patch.cs | 46 - .../Patches/Modes/Odyssey/TravelMgr_Patch.cs | 367 ----- .../Modes/Odyssey/TravelRefresh_Patch.cs | 28 - .../Modes/Odyssey/TravelStoreWindow_Patch.cs | 93 -- .../Modes/Odyssey/TravelStore_Patch.cs | 96 -- .../Modes/Odyssey/TravelSynergyMenu_Patch.cs | 107 -- .../Starbound/AdvantureEvolutionMenu_Patch.cs | 77 -- .../Starbound/AdvantureHelpMenu_Patch.cs | 21 - .../Modes/Starbound/AdvantureMenu2_Patch.cs | 28 - .../Modes/Starbound/AdvantureMenu_Patch.cs | 64 - .../Starbound/AdvantureMissionMenu_Patch.cs | 56 - .../Starbound/AdvantureStarMenu_Patch.cs | 61 - .../CustomButton_enterGame_Patch.cs | 104 -- .../Super Editor/CustomLevelMenu_Patch.cs | 175 --- .../CustomMenuPage_event_Patch_B.cs | 29 - .../CustomMenuPage_initZombies_Patch.cs | 32 - .../CustomMenuPage_page3_Patch.cs | 34 - .../CustomMenuPage_shooting_Patch.cs | 65 - .../Super Editor/CustomOnlineMenu_Patch.cs | 80 -- .../RuntimeEventNodeEditor_Patch.cs | 49 - .../EventNodes/RuntimeNodeUI_Patch.cs | 143 -- .../GameLevel/LevelManager_Patch.cs | 280 ---- .../RhythmGameChartEditorUI_Patch.cs | 95 -- .../RhythmGame/RhythmGameManager_Patch.cs | 51 - .../OtherManagers/AchievementClip_Patch.cs | 71 - .../Patches/OtherManagers/GardenUI_Patch.cs | 22 - .../Patches/OtherManagers/MenuText_Patch.cs | 23 - .../Patches/OtherManagers/ThanksMenu_Patch.cs | 23 - ...PvZ Fusion Translator [MelonLoader].csproj | 596 -------- MelonLoader/Utils.cs | 704 ---------- PvZ Fusion Translator.sln | 146 -- PvZ Fusion Translator.sln.DotSettings.user | 6 + PvZ Fusion Translator.slnx | 7 + README.md | 1 - Source/AssetStore/AudioStore.cs | 166 +++ Source/AssetStore/DllStore.cs | 111 ++ Source/AssetStore/FontStore.cs | 117 ++ Source/AssetStore/StringStore.cs | 613 ++++++++ Source/AssetStore/TextureStore.cs | 55 + Source/AssetStore/WarningStore.cs | 285 ++++ Source/Core.cs | 276 ++++ Source/FileLoader.cs | 1142 +++++++++++++++ Source/FontHandler.cs | 43 + Source/Log.cs | 60 + Source/ModFeatures.cs | 97 ++ .../BaseTextObjects/InGameText_Patch.cs | 369 +++++ .../BaseTextObjects/TMP_Dropdown_Patch.cs | 49 + .../BaseTextObjects/TMP_InputField_Patch.cs | 20 + .../BaseTextObjects/TextMeshProUGUI_Patch.cs | 95 ++ .../BaseTextObjects/TextMeshPro_Patch.cs | 37 + .../GameObjects/AlmanacBuffMenu_Patch.cs | 98 ++ .../GameObjects/AlmanacCardUI_Patch.cs | 25 + .../GameObjects/AlmanacPlantMenu_Patch.cs | 94 ++ .../GameObjects/AlmanacPlantWindow_Patch.cs | 71 + .../GameObjects/AlmanacSelectMenu_Patch.cs | 40 + .../GameObjects/AlmanacZombieMenu_Patch.cs | 28 + .../GameObjects/AlmanacZombieWindow_Patch.cs | 80 ++ Source/Patches/GameObjects/Almanac_Patch.cs | 30 + Source/Patches/GameObjects/BaseMenu_Patch.cs | 48 + Source/Patches/GameObjects/Board_Patch.cs | 17 + .../ButtonObjects/Advanture_Btn_Patch.cs | 25 + .../ButtonObjects/BackToIndex_Patch.cs | 14 + .../ButtonObjects/CustomLevelEnter_Patch.cs | 25 + .../ExploreMakeSceneButton_Patch.cs | 18 + .../ExploreMakeZombieButton_Patch.cs | 15 + .../GodShootingLevelButton_Patch.cs | 25 + .../ButtonObjects/InGameBtn_Patch.cs | 35 + .../ButtonObjects/LevelSaveEnter_Patch.cs | 14 + .../ButtonObjects/MainMenu_Btn_Patch.cs | 25 + .../ButtonObjects/NormalBtn_Patch.cs | 21 + .../ButtonObjects/OptLanguageBtn_Patch.cs | 415 ++++++ .../ButtonObjects/OptionBtn_Patch.cs | 69 + .../ButtonObjects/PVPPotBtn_Patch.cs | 41 + .../ButtonObjects/PauseMenu_Btn_Patch.cs | 11 + .../ButtonObjects/SaveMenuBtn_Patch.cs | 18 + .../GameObjects/ButtonObjects/UIBtn_Patch.cs | 16 + .../ButtonObjects/UIButton_Patch.cs | 46 + Source/Patches/GameObjects/Close_Patch.cs | 50 + .../Patches/GameObjects/ConfirmMenu_Patch.cs | 18 + .../GameObjects/CrisisZombieWindow_Patch.cs | 30 + .../GameObjects/CustomSettings_Patch.cs | 18 + Source/Patches/GameObjects/CustomSun_Patch.cs | 42 + .../Patches/GameObjects/EveBuffMenu_Patch.cs | 25 + .../GameObjects/EveOptionWindow_Patch.cs | 33 + .../GameObjects/ExploreEnterWindow_Patch.cs | 56 + .../GameObjects/ExploreMakeMenu_Patch.cs | 59 + .../Patches/GameObjects/ExploreMenu_Patch.cs | 28 + .../FruitNinjaSelectWindow_Patch.cs | 30 + .../Patches/GameObjects/GardenPlant_Patch.cs | 22 + .../GameObjects/GardenStoreMenu_Patch.cs | 27 + .../GameObjects/GodShootingMenu_Patch.cs | 34 + .../GameObjects/LevelResultMenu_Patch.cs | 15 + Source/Patches/GameObjects/LoseMenu_Patch.cs | 14 + Source/Patches/GameObjects/MainMenu_Patch.cs | 103 ++ .../GameObjects/MinorObjects/Brain_Patch.cs | 48 + .../GameObjects/MinorObjects/DY_Patch.cs | 12 + .../MinorObjects/GameLose_Patch.cs | 20 + .../MinorObjects/HealthSlider_Patch.cs | 34 + .../GameObjects/MinorObjects/Jigsaw_Patch.cs | 27 + .../MinorObjects/LanternUmbrella_Patch.cs | 17 + .../MinorObjects/MagnetBox_Patch.cs | 11 + .../MinorObjects/MagnetInterface_Patch.cs | 11 + .../GameObjects/MinorObjects/Money_Patch.cs | 18 + .../GameObjects/MinorObjects/Plant_Patch.cs | 51 + .../MinorObjects/PlayerName_Patch.cs | 15 + .../MinorObjects/PumpinerChestMenu_Patch.cs | 16 + .../MinorObjects/SelectYourPlants_Patch.cs | 20 + .../MinorObjects/SpecialCard_Patch.cs | 21 + .../MinorObjects/TrainingDummy_Patch.cs | 12 + .../MinorObjects/TreasureMoney_Patch.cs | 12 + .../MinorObjects/UIProgress2_Patch.cs | 12 + .../MinorObjects/UltimateChomper_Patch.cs | 17 + .../GameObjects/MinorObjects/Zombie_Patch.cs | 184 +++ .../GameObjects/NoticePauseMenu_Patch.cs | 53 + Source/Patches/GameObjects/OtherMenu_Patch.cs | 15 + .../GameObjects/PVPRandomManager_Patch.cs | 22 + .../PlantCardPackageBuilder_Patch.cs | 17 + .../GameObjects/PlantDamageMenu_Patch.cs | 41 + .../GameObjects/PlantDataMenu_Patch.cs | 66 + .../GameObjects/PlantInfoWindow_Patch.cs | 43 + .../GameObjects/PlayerSaveMenu_Patch.cs | 22 + .../GameObjects/PlayerShootingMenu_Patch.cs | 35 + .../GameObjects/PlayerShootingWindow_Patch.cs | 30 + .../Patches/GameObjects/ReNameMenu_Patch.cs | 16 + .../GameObjects/RogueCardWindow_Patch.cs | 30 + .../GameObjects/RogueStartMenu_Patch.cs | 32 + .../Patches/GameObjects/SeedLibrary_Patch.cs | 48 + .../Patches/GameObjects/ShootingMenu_Patch.cs | 22 + .../GameObjects/ShootingSelectWindow_Patch.cs | 65 + .../GameObjects/SpriteRenderer_Patch.cs | 18 + .../Patches/GameObjects/TowerOption_Patch.cs | 18 + .../GameObjects/TowerUpgradeMenu_Patch.cs | 34 + .../Patches/GameObjects/UIDifficulty_Patch.cs | 17 + .../Patches/GameObjects/UIZombieNum_Patch.cs | 31 + .../Patches/GameObjects/WarningMenu_Patch.cs | 77 ++ .../Managers/AbyssDevelopMenu_Patch.cs | 17 + Source/Patches/Managers/AbyssMenu2_Patch.cs | 86 ++ Source/Patches/Managers/AbyssMenu_Patch.cs | 22 + .../Managers/AlmanacMgrZombie_Patch.cs | 95 ++ .../Managers/AlmanacPlantBank_Patch.cs | 191 +++ Source/Patches/Managers/CanvasUpUI_Patch.cs | 30 + Source/Patches/Managers/ChessManager_Patch.cs | 29 + .../Managers/CustomLevelShower_Patch.cs | 17 + .../Patches/Managers/DifficultyMgr_Patch.cs | 15 + .../Patches/Managers/DrawCardManager_Patch.cs | 64 + Source/Patches/Managers/EndlessMgr_Patch.cs | 22 + Source/Patches/Managers/Garden_Patch.cs | 18 + Source/Patches/Managers/IZBottomMenu_Patch.cs | 47 + Source/Patches/Managers/InGameUI_Patch.cs | 81 ++ Source/Patches/Managers/PVPScareyPot_Patch.cs | 27 + Source/Patches/Managers/SaveMenu_Patch.cs | 25 + Source/Patches/Managers/Screen_Patch.cs | 13 + Source/Patches/Managers/TowerManager_Patch.cs | 18 + Source/Patches/Managers/UIMgr_Patch.cs | 16 + .../Patches/Modes/Abyss/AbyssBagMenu_Patch.cs | 24 + .../Modes/Abyss/AbyssBuffButton_Patch.cs | 55 + .../Modes/Abyss/AbyssBuffData_Patch.cs | 127 ++ .../Modes/Abyss/AbyssBuffMenu_Patch.cs | 111 ++ .../Modes/Abyss/AbyssCheckInBag_Patch.cs | 15 + .../Modes/Abyss/AbyssCheckSellMenu_Patch.cs | 15 + .../Modes/Abyss/AbyssDevelopMenu_Patch.cs | 48 + .../Patches/Modes/Abyss/AbyssGoods_Patch.cs | 18 + Source/Patches/Modes/Abyss/AbyssInfo_Patch.cs | 5 + .../Modes/Abyss/AbyssLevelEnter_Patch.cs | 14 + .../Patches/Modes/Abyss/AbyssMenu2_Patch.cs | 88 ++ Source/Patches/Modes/Abyss/AbyssMenu_Patch.cs | 48 + .../Abyss/AbyssSelectBuffWindow_Patch.cs | 45 + .../Modes/Abyss/AbyssSettlementMenu_Patch.cs | 58 + .../Modes/Abyss/AbyssStoreMenu_Patch.cs | 22 + .../Modes/Harvest/GardenBagMenu_Patch.cs | 19 + .../Patches/Modes/Harvest/GardenCard_Patch.cs | 16 + .../Harvest/TreasureConfirmMenu_Patch.cs | 20 + .../Harvest/TreasureEquipmentMenu_Patch.cs | 32 + .../Harvest/TreasureEvacuateMenu_Patch.cs | 23 + .../Modes/Harvest/TreasureMainMenu_Patch.cs | 20 + .../Modes/Harvest/TreasureManager_Patch.cs | 26 + .../Modes/Harvest/TreasureStoreMenu_Patch.cs | 20 + .../Harvest/TreasureUpgradeMenu_Patch.cs | 54 + .../Harvest/TreasureWarehouseMenu_Patch.cs | 56 + .../Modes/Odyssey/MultipleChoiceMenu_Patch.cs | 46 + .../Odyssey/OppositeBuffManager_Patch.cs | 47 + .../Modes/Odyssey/ShootingManager_Patch.cs | 575 ++++++++ .../Modes/Odyssey/SynergyDisplay_Patch.cs | 19 + .../Odyssey/TravelAdvantureMenu_Patch.cs | 28 + .../Modes/Odyssey/TravelBuffMenu_Patch.cs | 24 + .../Modes/Odyssey/TravelBuffMgr_Patch.cs | 23 + .../Odyssey/TravelBuffOptionButton_Patch.cs | 35 + .../Patches/Modes/Odyssey/TravelBuff_Patch.cs | 19 + .../Modes/Odyssey/TravelInvestMenu_Patch.cs | 24 + .../Modes/Odyssey/TravelLookBuff_Patch.cs | 57 + .../Modes/Odyssey/TravelLookMenu_Patch.cs | 42 + .../Patches/Modes/Odyssey/TravelMgr_Patch.cs | 312 +++++ .../Modes/Odyssey/TravelRefresh_Patch.cs | 22 + .../Modes/Odyssey/TravelStoreWindow_Patch.cs | 81 ++ .../Modes/Odyssey/TravelStore_Patch.cs | 60 + .../Modes/Odyssey/TravelSynergyMenu_Patch.cs | 87 ++ .../Starbound/AdvantureEvolutionMenu_Patch.cs | 51 + .../Starbound/AdvantureHelpMenu_Patch.cs | 15 + .../Modes/Starbound/AdvantureMenu2_Patch.cs | 19 + .../Modes/Starbound/AdvantureMenu_Patch.cs | 43 + .../Starbound/AdvantureMissionMenu_Patch.cs | 41 + .../Starbound/AdvantureStarMenu_Patch.cs | 43 + .../CustomButton_enterGame_Patch.cs | 108 ++ .../Super Editor/CustomLevelMenu_Patch.cs | 164 +++ .../CustomMenuPage_event_Patch_B.cs | 17 + .../CustomMenuPage_initZombies_Patch.cs | 16 + .../CustomMenuPage_page3_Patch.cs | 22 + .../CustomMenuPage_shooting_Patch.cs | 33 + .../Super Editor/CustomOnlineMenu_Patch.cs | 70 + .../RuntimeEventNodeEditor_Patch.cs | 43 + .../EventNodes/RuntimeNodeUI_Patch.cs | 119 ++ .../GameLevel/LevelManager_Patch.cs | 317 +++++ .../RhythmGameChartEditorUI_Patch.cs | 66 + .../RhythmGame/RhythmGameManager_Patch.cs | 44 + .../OtherManagers/AchievementClip_Patch.cs | 63 + .../Patches/OtherManagers/GardenUI_Patch.cs | 12 + .../Patches/OtherManagers/MenuText_Patch.cs | 19 + .../Patches/OtherManagers/ThanksMenu_Patch.cs | 20 + Source/PvZ Fusion Translator.csproj | 64 + Source/Utils.cs | 668 +++++++++ 522 files changed, 12632 insertions(+), 25041 deletions(-) create mode 100644 .idea/.idea.PvZ Fusion Translator/.idea/material_theme_project_new.xml delete mode 100644 BepInEx/AssetStore/AudioStore.cs delete mode 100644 BepInEx/AssetStore/CheckSumStore.cs delete mode 100644 BepInEx/AssetStore/FontStore.cs delete mode 100644 BepInEx/AssetStore/StringStore.cs delete mode 100644 BepInEx/AssetStore/TextureStore.cs delete mode 100644 BepInEx/AssetStore/WarningStore.cs delete mode 100644 BepInEx/Core.cs delete mode 100644 BepInEx/Dependencies/AudioImportLib.BepInEx.dll delete mode 100644 BepInEx/FileLoader.cs delete mode 100644 BepInEx/FontHandler.cs delete mode 100644 BepInEx/Log.cs delete mode 100644 BepInEx/ModFeatures.cs delete mode 100644 BepInEx/Patches/BaseTextObjects/InGameText_Patch.cs delete mode 100644 BepInEx/Patches/BaseTextObjects/TMP_InputField_Patch.cs delete mode 100644 BepInEx/Patches/BaseTextObjects/TextMeshProUGUI_Patch.cs delete mode 100644 BepInEx/Patches/BaseTextObjects/TextMeshPro_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/AbyssBuffMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/AbyssCheckInBag_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/AbyssDevelopMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/AbyssMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/AbyssSelectBuffWindow_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/AbyssSettlementMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/AbyssStoreMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/AdvantureEvolutionMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/AdvantureHelpMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/AdvantureMenu2_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/AdvantureMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/AdvantureMissionMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/AdvantureStarMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/AlmanacPlantMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/AlmanacPlantWindow_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/AlmanacZombieMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/AlmanacZombieWindow_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/Almanac_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/BaseMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/Board_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/ButtonObjects/AbyssBuffButton_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/ButtonObjects/AbyssCheckSellMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/ButtonObjects/AbyssLevelEnter_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/ButtonObjects/Advanture_Btn_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/ButtonObjects/CustomLevelEnter_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/ButtonObjects/ExploreMakeSceneButton_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/ButtonObjects/ExploreMakeZombieButton_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/ButtonObjects/InGameBtn_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/ButtonObjects/MainMenu_Btn_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/ButtonObjects/NormalBtn_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/ButtonObjects/OptionBtn_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/ButtonObjects/PVPPotBtn_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/ButtonObjects/PauseMenu_Btn_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/ButtonObjects/SaveMenuBtn_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/ButtonObjects/UIButton_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/Close_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/CrisisZombieWindow_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/CustomSettings_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/CustomSun_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/EveBuffMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/EveOptionWindow_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/ExploreEnterWindow_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/ExploreMakeMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/ExploreMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/FruitNinjaSelectWindow_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/GardenBagMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/GardenCard_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/GardenPlant_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/MainMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/MinorObjects/AbyssGoods_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/MinorObjects/Brain_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/MinorObjects/DY_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/MinorObjects/Jigsaw_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/MinorObjects/LanternUmbrella_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/MinorObjects/MagnetBox_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/MinorObjects/MagnetInterface_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/MinorObjects/Money_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/MinorObjects/Plant_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/MinorObjects/PlayerName_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/MinorObjects/SelectYourPlants_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/MinorObjects/TrainingDummy_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/MinorObjects/TreasureMoney_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/MinorObjects/UIProgress2_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/MinorObjects/UltimateChomper_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/MinorObjects/Zombie_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/NoticePauseMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/OtherMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/PlantDamageMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/PlantInfoWindow_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/PlayerShootingMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/PlayerShootingWindow_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/RogueCardWindow_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/RogueStartMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/SeedLibrary_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/ShootingMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/ShootingSelectWindow_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/SpriteRenderer_patch.cs delete mode 100644 BepInEx/Patches/GameObjects/TowerOption_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/TowerUpgradeMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/TravelBuffMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/TravelBuffOptionButton_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/TravelBuff_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/TravelLookBuff_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/TravelLookMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/TravelRefresh_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/TravelStore_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/TreasureConfirmMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/TreasureEquipmentMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/TreasureEvacuateMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/TreasureMainMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/TreasureStoreMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/TreasureUpgradeMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/TreasureWarehouseMenu_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/UIDifficulty_Patch.cs delete mode 100644 BepInEx/Patches/GameObjects/UIZombieNum_Patch.cs delete mode 100644 BepInEx/Patches/Managers/AbyssBuffData_Patch.cs delete mode 100644 BepInEx/Patches/Managers/AbyssDevelopMenu_Patch.cs delete mode 100644 BepInEx/Patches/Managers/AbyssInfo_Patch.cs delete mode 100644 BepInEx/Patches/Managers/AbyssMenu2_Patch.cs delete mode 100644 BepInEx/Patches/Managers/AbyssMenu_Patch.cs delete mode 100644 BepInEx/Patches/Managers/AlmanacMgrZombie_Patch.cs delete mode 100644 BepInEx/Patches/Managers/AlmanacPlantBank_Patch.cs delete mode 100644 BepInEx/Patches/Managers/CanvasUpUI_Patch.cs delete mode 100644 BepInEx/Patches/Managers/ChessManager_Patch.cs delete mode 100644 BepInEx/Patches/Managers/CustomLevelShower_Patch.cs delete mode 100644 BepInEx/Patches/Managers/DifficultyMgr_Patch.cs delete mode 100644 BepInEx/Patches/Managers/DrawCardManager_Patch.cs delete mode 100644 BepInEx/Patches/Managers/EndlessMgr_Patch.cs delete mode 100644 BepInEx/Patches/Managers/GameAPP_Patch.cs delete mode 100644 BepInEx/Patches/Managers/Garden_Patch.cs delete mode 100644 BepInEx/Patches/Managers/IZBottomMenu_Patch.cs delete mode 100644 BepInEx/Patches/Managers/InGameUIMgr_Patch.cs delete mode 100644 BepInEx/Patches/Managers/InGameUI_Patch.cs delete mode 100644 BepInEx/Patches/Managers/OppositeBuffManager_Patch.cs delete mode 100644 BepInEx/Patches/Managers/SaveMenu_Patch.cs delete mode 100644 BepInEx/Patches/Managers/TowerManager_Patch.cs delete mode 100644 BepInEx/Patches/Managers/TravelBuffMgr_Patch.cs delete mode 100644 BepInEx/Patches/Managers/TravelMgr_Patch.cs delete mode 100644 BepInEx/Patches/Managers/TreasureManager_Patch.cs delete mode 100644 BepInEx/Patches/Managers/UIMgr_Patch.cs delete mode 100644 BepInEx/Patches/OtherManagers/AchievementClip_Patch.cs delete mode 100644 BepInEx/Patches/OtherManagers/GardenUI_Patch.cs delete mode 100644 BepInEx/Patches/OtherManagers/MenuText_Patch.cs delete mode 100644 BepInEx/Patches/OtherManagers/ThanksMenu_Patch.cs delete mode 100644 BepInEx/PvZ Fusion Translator [BepInEx].csproj delete mode 100644 BepInEx/Utils.cs delete mode 100644 MelonLoader/AssetStore/AudioStore.cs delete mode 100644 MelonLoader/AssetStore/CheckSumStore.cs delete mode 100644 MelonLoader/AssetStore/DllStore.cs delete mode 100644 MelonLoader/AssetStore/FontStore.cs delete mode 100644 MelonLoader/AssetStore/StringStore.cs delete mode 100644 MelonLoader/AssetStore/TextureStore.cs delete mode 100644 MelonLoader/AssetStore/WarningStore.cs delete mode 100644 MelonLoader/Core.cs delete mode 100644 MelonLoader/FileLoader.cs delete mode 100644 MelonLoader/FontHandler.cs delete mode 100644 MelonLoader/Log.cs delete mode 100644 MelonLoader/ModFeatures.cs delete mode 100644 MelonLoader/Patches/BaseTextObjects/InGameText_Patch.cs delete mode 100644 MelonLoader/Patches/BaseTextObjects/TMP_Dropdown_Patch.cs delete mode 100644 MelonLoader/Patches/BaseTextObjects/TMP_InputField_Patch.cs delete mode 100644 MelonLoader/Patches/BaseTextObjects/TextMeshProUGUI_Patch.cs delete mode 100644 MelonLoader/Patches/BaseTextObjects/TextMeshPro_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/AlmanacBuffMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/AlmanacCardUI_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/AlmanacPlantMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/AlmanacPlantWindow_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/AlmanacSelectMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/AlmanacZombieMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/AlmanacZombieWindow_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/Almanac_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/BaseMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/Board_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ButtonObjects/Advanture_Btn_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ButtonObjects/BackToIndex_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ButtonObjects/CustomLevelEnter_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ButtonObjects/ExploreMakeSceneButton_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ButtonObjects/ExploreMakeZombieButton_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ButtonObjects/GodShootingLevelButton_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ButtonObjects/InGameBtn_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ButtonObjects/LevelSaveEnter_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ButtonObjects/MainMenu_Btn_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ButtonObjects/NormalBtn_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ButtonObjects/OptionBtn_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ButtonObjects/PVPPotBtn_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ButtonObjects/PauseMenu_Btn_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ButtonObjects/SaveMenuBtn_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ButtonObjects/UIBtn_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ButtonObjects/UIButton_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/Close_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ConfirmMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/CrisisZombieWindow_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/CustomSettings_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/CustomSun_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/EveBuffMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/EveOptionWindow_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ExploreEnterWindow_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ExploreMakeMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ExploreMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/FruitNinjaSelectWindow_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/GardenPlant_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/GardenStoreMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/GodShootingMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/LevelResultMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/LoseMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/MainMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/MinorObjects/Brain_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/MinorObjects/DY_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/MinorObjects/GameLose_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/MinorObjects/HealthSlider_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/MinorObjects/Jigsaw_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/MinorObjects/LanternUmbrella_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/MinorObjects/MagnetBox_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/MinorObjects/MagnetInterface_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/MinorObjects/Money_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/MinorObjects/Plant_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/MinorObjects/PlayerName_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/MinorObjects/PumpinerChestMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/MinorObjects/SelectYourPlants_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/MinorObjects/SpecialCard_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/MinorObjects/TrainingDummy_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/MinorObjects/TreasureMoney_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/MinorObjects/UIProgress2_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/MinorObjects/UltimateChomper_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/MinorObjects/Zombie_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/NoticePauseMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/OtherMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/PVPRandomManager_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/PlantCardPackageBuilder_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/PlantDamageMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/PlantDataMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/PlantInfoWindow_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/PlayerSaveMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/PlayerShootingMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/PlayerShootingWindow_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ReNameMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/RogueCardWindow_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/RogueStartMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/SeedLibrary_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ShootingMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/ShootingSelectWindow_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/SpriteRenderer_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/TowerOption_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/TowerUpgradeMenu_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/UIDifficulty_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/UIZombieNum_Patch.cs delete mode 100644 MelonLoader/Patches/GameObjects/WarningMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Managers/AbyssDevelopMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Managers/AbyssMenu2_Patch.cs delete mode 100644 MelonLoader/Patches/Managers/AbyssMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Managers/AlmanacMgrZombie_Patch.cs delete mode 100644 MelonLoader/Patches/Managers/AlmanacPlantBank_Patch.cs delete mode 100644 MelonLoader/Patches/Managers/CanvasUpUI_Patch.cs delete mode 100644 MelonLoader/Patches/Managers/ChessManager_Patch.cs delete mode 100644 MelonLoader/Patches/Managers/CustomLevelShower_Patch.cs delete mode 100644 MelonLoader/Patches/Managers/DifficultyMgr_Patch.cs delete mode 100644 MelonLoader/Patches/Managers/DrawCardManager_Patch.cs delete mode 100644 MelonLoader/Patches/Managers/EndlessMgr_Patch.cs delete mode 100644 MelonLoader/Patches/Managers/Garden_Patch.cs delete mode 100644 MelonLoader/Patches/Managers/IZBottomMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Managers/InGameUI_Patch.cs delete mode 100644 MelonLoader/Patches/Managers/PVPScareyPot_Patch.cs delete mode 100644 MelonLoader/Patches/Managers/SaveMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Managers/Screen_Patch.cs delete mode 100644 MelonLoader/Patches/Managers/TowerManager_Patch.cs delete mode 100644 MelonLoader/Patches/Managers/UIMgr_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Abyss/AbyssBagMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Abyss/AbyssBuffButton_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Abyss/AbyssBuffData_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Abyss/AbyssBuffMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Abyss/AbyssCheckInBag_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Abyss/AbyssCheckSellMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Abyss/AbyssDevelopMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Abyss/AbyssGoods_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Abyss/AbyssInfo_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Abyss/AbyssLevelEnter_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Abyss/AbyssMenu2_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Abyss/AbyssMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Abyss/AbyssSelectBuffWindow_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Abyss/AbyssSettlementMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Abyss/AbyssStoreMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Harvest/GardenBagMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Harvest/GardenCard_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Harvest/TreasureConfirmMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Harvest/TreasureEquipmentMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Harvest/TreasureEvacuateMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Harvest/TreasureMainMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Harvest/TreasureManager_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Harvest/TreasureStoreMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Harvest/TreasureUpgradeMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Harvest/TreasureWarehouseMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Odyssey/MultipleChoiceMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Odyssey/OppositeBuffManager_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Odyssey/ShootingManager_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Odyssey/SynergyDisplay_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Odyssey/TravelAdvantureMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Odyssey/TravelBuffMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Odyssey/TravelBuffMgr_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Odyssey/TravelBuffOptionButton_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Odyssey/TravelBuff_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Odyssey/TravelInvestMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Odyssey/TravelLookBuff_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Odyssey/TravelLookMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Odyssey/TravelMgr_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Odyssey/TravelRefresh_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Odyssey/TravelStoreWindow_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Odyssey/TravelStore_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Odyssey/TravelSynergyMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Starbound/AdvantureEvolutionMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Starbound/AdvantureHelpMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Starbound/AdvantureMenu2_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Starbound/AdvantureMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Starbound/AdvantureMissionMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Starbound/AdvantureStarMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Super Editor/CustomButton_enterGame_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Super Editor/CustomLevelMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_event_Patch_B.cs delete mode 100644 MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_initZombies_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_page3_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_shooting_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Super Editor/CustomOnlineMenu_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Super Editor/GameLevel/EventNodes/RuntimeEventNodeEditor_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Super Editor/GameLevel/EventNodes/RuntimeNodeUI_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Super Editor/GameLevel/LevelManager_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Super Editor/RhythmGame/RhythmGameChartEditorUI_Patch.cs delete mode 100644 MelonLoader/Patches/Modes/Super Editor/RhythmGame/RhythmGameManager_Patch.cs delete mode 100644 MelonLoader/Patches/OtherManagers/AchievementClip_Patch.cs delete mode 100644 MelonLoader/Patches/OtherManagers/GardenUI_Patch.cs delete mode 100644 MelonLoader/Patches/OtherManagers/MenuText_Patch.cs delete mode 100644 MelonLoader/Patches/OtherManagers/ThanksMenu_Patch.cs delete mode 100644 MelonLoader/PvZ Fusion Translator [MelonLoader].csproj delete mode 100644 MelonLoader/Utils.cs delete mode 100644 PvZ Fusion Translator.sln create mode 100644 PvZ Fusion Translator.sln.DotSettings.user create mode 100644 PvZ Fusion Translator.slnx create mode 100644 Source/AssetStore/AudioStore.cs create mode 100644 Source/AssetStore/DllStore.cs create mode 100644 Source/AssetStore/FontStore.cs create mode 100644 Source/AssetStore/StringStore.cs create mode 100644 Source/AssetStore/TextureStore.cs create mode 100644 Source/AssetStore/WarningStore.cs create mode 100644 Source/Core.cs create mode 100644 Source/FileLoader.cs create mode 100644 Source/FontHandler.cs create mode 100644 Source/Log.cs create mode 100644 Source/ModFeatures.cs create mode 100644 Source/Patches/BaseTextObjects/InGameText_Patch.cs create mode 100644 Source/Patches/BaseTextObjects/TMP_Dropdown_Patch.cs create mode 100644 Source/Patches/BaseTextObjects/TMP_InputField_Patch.cs create mode 100644 Source/Patches/BaseTextObjects/TextMeshProUGUI_Patch.cs create mode 100644 Source/Patches/BaseTextObjects/TextMeshPro_Patch.cs create mode 100644 Source/Patches/GameObjects/AlmanacBuffMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/AlmanacCardUI_Patch.cs create mode 100644 Source/Patches/GameObjects/AlmanacPlantMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/AlmanacPlantWindow_Patch.cs create mode 100644 Source/Patches/GameObjects/AlmanacSelectMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/AlmanacZombieMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/AlmanacZombieWindow_Patch.cs create mode 100644 Source/Patches/GameObjects/Almanac_Patch.cs create mode 100644 Source/Patches/GameObjects/BaseMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/Board_Patch.cs create mode 100644 Source/Patches/GameObjects/ButtonObjects/Advanture_Btn_Patch.cs create mode 100644 Source/Patches/GameObjects/ButtonObjects/BackToIndex_Patch.cs create mode 100644 Source/Patches/GameObjects/ButtonObjects/CustomLevelEnter_Patch.cs create mode 100644 Source/Patches/GameObjects/ButtonObjects/ExploreMakeSceneButton_Patch.cs create mode 100644 Source/Patches/GameObjects/ButtonObjects/ExploreMakeZombieButton_Patch.cs create mode 100644 Source/Patches/GameObjects/ButtonObjects/GodShootingLevelButton_Patch.cs create mode 100644 Source/Patches/GameObjects/ButtonObjects/InGameBtn_Patch.cs create mode 100644 Source/Patches/GameObjects/ButtonObjects/LevelSaveEnter_Patch.cs create mode 100644 Source/Patches/GameObjects/ButtonObjects/MainMenu_Btn_Patch.cs create mode 100644 Source/Patches/GameObjects/ButtonObjects/NormalBtn_Patch.cs create mode 100644 Source/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs create mode 100644 Source/Patches/GameObjects/ButtonObjects/OptionBtn_Patch.cs create mode 100644 Source/Patches/GameObjects/ButtonObjects/PVPPotBtn_Patch.cs create mode 100644 Source/Patches/GameObjects/ButtonObjects/PauseMenu_Btn_Patch.cs create mode 100644 Source/Patches/GameObjects/ButtonObjects/SaveMenuBtn_Patch.cs create mode 100644 Source/Patches/GameObjects/ButtonObjects/UIBtn_Patch.cs create mode 100644 Source/Patches/GameObjects/ButtonObjects/UIButton_Patch.cs create mode 100644 Source/Patches/GameObjects/Close_Patch.cs create mode 100644 Source/Patches/GameObjects/ConfirmMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/CrisisZombieWindow_Patch.cs create mode 100644 Source/Patches/GameObjects/CustomSettings_Patch.cs create mode 100644 Source/Patches/GameObjects/CustomSun_Patch.cs create mode 100644 Source/Patches/GameObjects/EveBuffMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/EveOptionWindow_Patch.cs create mode 100644 Source/Patches/GameObjects/ExploreEnterWindow_Patch.cs create mode 100644 Source/Patches/GameObjects/ExploreMakeMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/ExploreMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/FruitNinjaSelectWindow_Patch.cs create mode 100644 Source/Patches/GameObjects/GardenPlant_Patch.cs create mode 100644 Source/Patches/GameObjects/GardenStoreMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/GodShootingMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/LevelResultMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/LoseMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/MainMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/MinorObjects/Brain_Patch.cs create mode 100644 Source/Patches/GameObjects/MinorObjects/DY_Patch.cs create mode 100644 Source/Patches/GameObjects/MinorObjects/GameLose_Patch.cs create mode 100644 Source/Patches/GameObjects/MinorObjects/HealthSlider_Patch.cs create mode 100644 Source/Patches/GameObjects/MinorObjects/Jigsaw_Patch.cs create mode 100644 Source/Patches/GameObjects/MinorObjects/LanternUmbrella_Patch.cs create mode 100644 Source/Patches/GameObjects/MinorObjects/MagnetBox_Patch.cs create mode 100644 Source/Patches/GameObjects/MinorObjects/MagnetInterface_Patch.cs create mode 100644 Source/Patches/GameObjects/MinorObjects/Money_Patch.cs create mode 100644 Source/Patches/GameObjects/MinorObjects/Plant_Patch.cs create mode 100644 Source/Patches/GameObjects/MinorObjects/PlayerName_Patch.cs create mode 100644 Source/Patches/GameObjects/MinorObjects/PumpinerChestMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/MinorObjects/SelectYourPlants_Patch.cs create mode 100644 Source/Patches/GameObjects/MinorObjects/SpecialCard_Patch.cs create mode 100644 Source/Patches/GameObjects/MinorObjects/TrainingDummy_Patch.cs create mode 100644 Source/Patches/GameObjects/MinorObjects/TreasureMoney_Patch.cs create mode 100644 Source/Patches/GameObjects/MinorObjects/UIProgress2_Patch.cs create mode 100644 Source/Patches/GameObjects/MinorObjects/UltimateChomper_Patch.cs create mode 100644 Source/Patches/GameObjects/MinorObjects/Zombie_Patch.cs create mode 100644 Source/Patches/GameObjects/NoticePauseMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/OtherMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/PVPRandomManager_Patch.cs create mode 100644 Source/Patches/GameObjects/PlantCardPackageBuilder_Patch.cs create mode 100644 Source/Patches/GameObjects/PlantDamageMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/PlantDataMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/PlantInfoWindow_Patch.cs create mode 100644 Source/Patches/GameObjects/PlayerSaveMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/PlayerShootingMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/PlayerShootingWindow_Patch.cs create mode 100644 Source/Patches/GameObjects/ReNameMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/RogueCardWindow_Patch.cs create mode 100644 Source/Patches/GameObjects/RogueStartMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/SeedLibrary_Patch.cs create mode 100644 Source/Patches/GameObjects/ShootingMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/ShootingSelectWindow_Patch.cs create mode 100644 Source/Patches/GameObjects/SpriteRenderer_Patch.cs create mode 100644 Source/Patches/GameObjects/TowerOption_Patch.cs create mode 100644 Source/Patches/GameObjects/TowerUpgradeMenu_Patch.cs create mode 100644 Source/Patches/GameObjects/UIDifficulty_Patch.cs create mode 100644 Source/Patches/GameObjects/UIZombieNum_Patch.cs create mode 100644 Source/Patches/GameObjects/WarningMenu_Patch.cs create mode 100644 Source/Patches/Managers/AbyssDevelopMenu_Patch.cs create mode 100644 Source/Patches/Managers/AbyssMenu2_Patch.cs create mode 100644 Source/Patches/Managers/AbyssMenu_Patch.cs create mode 100644 Source/Patches/Managers/AlmanacMgrZombie_Patch.cs create mode 100644 Source/Patches/Managers/AlmanacPlantBank_Patch.cs create mode 100644 Source/Patches/Managers/CanvasUpUI_Patch.cs create mode 100644 Source/Patches/Managers/ChessManager_Patch.cs create mode 100644 Source/Patches/Managers/CustomLevelShower_Patch.cs create mode 100644 Source/Patches/Managers/DifficultyMgr_Patch.cs create mode 100644 Source/Patches/Managers/DrawCardManager_Patch.cs create mode 100644 Source/Patches/Managers/EndlessMgr_Patch.cs create mode 100644 Source/Patches/Managers/Garden_Patch.cs create mode 100644 Source/Patches/Managers/IZBottomMenu_Patch.cs create mode 100644 Source/Patches/Managers/InGameUI_Patch.cs create mode 100644 Source/Patches/Managers/PVPScareyPot_Patch.cs create mode 100644 Source/Patches/Managers/SaveMenu_Patch.cs create mode 100644 Source/Patches/Managers/Screen_Patch.cs create mode 100644 Source/Patches/Managers/TowerManager_Patch.cs create mode 100644 Source/Patches/Managers/UIMgr_Patch.cs create mode 100644 Source/Patches/Modes/Abyss/AbyssBagMenu_Patch.cs create mode 100644 Source/Patches/Modes/Abyss/AbyssBuffButton_Patch.cs create mode 100644 Source/Patches/Modes/Abyss/AbyssBuffData_Patch.cs create mode 100644 Source/Patches/Modes/Abyss/AbyssBuffMenu_Patch.cs create mode 100644 Source/Patches/Modes/Abyss/AbyssCheckInBag_Patch.cs create mode 100644 Source/Patches/Modes/Abyss/AbyssCheckSellMenu_Patch.cs create mode 100644 Source/Patches/Modes/Abyss/AbyssDevelopMenu_Patch.cs create mode 100644 Source/Patches/Modes/Abyss/AbyssGoods_Patch.cs create mode 100644 Source/Patches/Modes/Abyss/AbyssInfo_Patch.cs create mode 100644 Source/Patches/Modes/Abyss/AbyssLevelEnter_Patch.cs create mode 100644 Source/Patches/Modes/Abyss/AbyssMenu2_Patch.cs create mode 100644 Source/Patches/Modes/Abyss/AbyssMenu_Patch.cs create mode 100644 Source/Patches/Modes/Abyss/AbyssSelectBuffWindow_Patch.cs create mode 100644 Source/Patches/Modes/Abyss/AbyssSettlementMenu_Patch.cs create mode 100644 Source/Patches/Modes/Abyss/AbyssStoreMenu_Patch.cs create mode 100644 Source/Patches/Modes/Harvest/GardenBagMenu_Patch.cs create mode 100644 Source/Patches/Modes/Harvest/GardenCard_Patch.cs create mode 100644 Source/Patches/Modes/Harvest/TreasureConfirmMenu_Patch.cs create mode 100644 Source/Patches/Modes/Harvest/TreasureEquipmentMenu_Patch.cs create mode 100644 Source/Patches/Modes/Harvest/TreasureEvacuateMenu_Patch.cs create mode 100644 Source/Patches/Modes/Harvest/TreasureMainMenu_Patch.cs create mode 100644 Source/Patches/Modes/Harvest/TreasureManager_Patch.cs create mode 100644 Source/Patches/Modes/Harvest/TreasureStoreMenu_Patch.cs create mode 100644 Source/Patches/Modes/Harvest/TreasureUpgradeMenu_Patch.cs create mode 100644 Source/Patches/Modes/Harvest/TreasureWarehouseMenu_Patch.cs create mode 100644 Source/Patches/Modes/Odyssey/MultipleChoiceMenu_Patch.cs create mode 100644 Source/Patches/Modes/Odyssey/OppositeBuffManager_Patch.cs create mode 100644 Source/Patches/Modes/Odyssey/ShootingManager_Patch.cs create mode 100644 Source/Patches/Modes/Odyssey/SynergyDisplay_Patch.cs create mode 100644 Source/Patches/Modes/Odyssey/TravelAdvantureMenu_Patch.cs create mode 100644 Source/Patches/Modes/Odyssey/TravelBuffMenu_Patch.cs create mode 100644 Source/Patches/Modes/Odyssey/TravelBuffMgr_Patch.cs create mode 100644 Source/Patches/Modes/Odyssey/TravelBuffOptionButton_Patch.cs create mode 100644 Source/Patches/Modes/Odyssey/TravelBuff_Patch.cs create mode 100644 Source/Patches/Modes/Odyssey/TravelInvestMenu_Patch.cs create mode 100644 Source/Patches/Modes/Odyssey/TravelLookBuff_Patch.cs create mode 100644 Source/Patches/Modes/Odyssey/TravelLookMenu_Patch.cs create mode 100644 Source/Patches/Modes/Odyssey/TravelMgr_Patch.cs create mode 100644 Source/Patches/Modes/Odyssey/TravelRefresh_Patch.cs create mode 100644 Source/Patches/Modes/Odyssey/TravelStoreWindow_Patch.cs create mode 100644 Source/Patches/Modes/Odyssey/TravelStore_Patch.cs create mode 100644 Source/Patches/Modes/Odyssey/TravelSynergyMenu_Patch.cs create mode 100644 Source/Patches/Modes/Starbound/AdvantureEvolutionMenu_Patch.cs create mode 100644 Source/Patches/Modes/Starbound/AdvantureHelpMenu_Patch.cs create mode 100644 Source/Patches/Modes/Starbound/AdvantureMenu2_Patch.cs create mode 100644 Source/Patches/Modes/Starbound/AdvantureMenu_Patch.cs create mode 100644 Source/Patches/Modes/Starbound/AdvantureMissionMenu_Patch.cs create mode 100644 Source/Patches/Modes/Starbound/AdvantureStarMenu_Patch.cs create mode 100644 Source/Patches/Modes/Super Editor/CustomButton_enterGame_Patch.cs create mode 100644 Source/Patches/Modes/Super Editor/CustomLevelMenu_Patch.cs create mode 100644 Source/Patches/Modes/Super Editor/CustomMenuPage_event_Patch_B.cs create mode 100644 Source/Patches/Modes/Super Editor/CustomMenuPage_initZombies_Patch.cs create mode 100644 Source/Patches/Modes/Super Editor/CustomMenuPage_page3_Patch.cs create mode 100644 Source/Patches/Modes/Super Editor/CustomMenuPage_shooting_Patch.cs create mode 100644 Source/Patches/Modes/Super Editor/CustomOnlineMenu_Patch.cs create mode 100644 Source/Patches/Modes/Super Editor/GameLevel/EventNodes/RuntimeEventNodeEditor_Patch.cs create mode 100644 Source/Patches/Modes/Super Editor/GameLevel/EventNodes/RuntimeNodeUI_Patch.cs create mode 100644 Source/Patches/Modes/Super Editor/GameLevel/LevelManager_Patch.cs create mode 100644 Source/Patches/Modes/Super Editor/RhythmGame/RhythmGameChartEditorUI_Patch.cs create mode 100644 Source/Patches/Modes/Super Editor/RhythmGame/RhythmGameManager_Patch.cs create mode 100644 Source/Patches/OtherManagers/AchievementClip_Patch.cs create mode 100644 Source/Patches/OtherManagers/GardenUI_Patch.cs create mode 100644 Source/Patches/OtherManagers/MenuText_Patch.cs create mode 100644 Source/Patches/OtherManagers/ThanksMenu_Patch.cs create mode 100644 Source/PvZ Fusion Translator.csproj create mode 100644 Source/Utils.cs diff --git a/.gitignore b/.gitignore index 5966056..25ee30e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,137 +1,406 @@ -################################################################################ -# This .gitignore file was automatically created by Microsoft(R) Visual Studio. -################################################################################ +## 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/main/VisualStudio.gitignore -/.vs/BepInEx/copilot-chat/bff105b7/sessions -/.vs -/bin -/obj -/MelonLoader/obj -/BepInEx/obj/Debug/net6.0 -/BepInEx/obj -/BepInEx/bin/ReleaseMulti/net6.0 -/AlmanacPlantBank_Patch.cs -/MelonLoader/bin/x64/Debug -/BepInEx/bin/Debug/net6.0 -.HOWTO-sync-MelonLoader-from-origin-main.txt -/MelonLoader/bin/ReleaseMulti/net6.0 -MelonLoader/bin/Debug/net6.0/WebSocketDotNet.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.XRModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.WindModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.VRModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.VideoModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.VFXModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.VehiclesModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.UnityWebRequestWWWModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.UnityWebRequestTextureModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.UnityWebRequestModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.UnityWebRequestAudioModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.UnityWebRequestAssetBundleModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.UnityTestProtocolModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.UnityCurlModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.UnityConnectModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.UnityAnalyticsModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.UnityAnalyticsCommonModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.UmbraModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.UIModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.UIElementsModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.UI.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.TLSModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.TilemapModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.TextRenderingModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.TextCoreTextEngineModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.TextCoreFontEngineModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.TerrainPhysicsModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.TerrainModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.SubsystemsModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.SubstanceModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.StreamingModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.SpriteShapeModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.SpriteMaskModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.SharedInternalsModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.ScreenCaptureModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.PropertiesModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.ProfilerModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.PhysicsModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.Physics2DModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.PerformanceReportingModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.ParticleSystemModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.LocalizationModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.JSONSerializeModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.InputModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.InputLegacyModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.IMGUIModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.ImageConversionModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.HotReloadModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.GridModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.GIModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.GameCenterModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.DSPGraphModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.DirectorModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.CrashReportingModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.CoreModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.ContentLoadModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.ClothModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.AudioModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.AssetBundleModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.ARModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.AnimationModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.AndroidJNIModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.AIModule.dll -MelonLoader/bin/Debug/net6.0/UnityEngine.AccessibilityModule.dll -MelonLoader/bin/Debug/net6.0/Unity.VisualScripting.Core.dll -MelonLoader/bin/Debug/net6.0/Unity.TextMeshPro.dll -MelonLoader/bin/Debug/net6.0/Unity.RenderPipelines.Universal.Runtime.dll -MelonLoader/bin/Debug/net6.0/Unity.RenderPipelines.Core.Runtime.dll -MelonLoader/bin/Debug/net6.0/Unity.RenderPipeline.Universal.ShaderLibrary.dll -MelonLoader/bin/Debug/net6.0/Unity.Mathematics.dll -MelonLoader/bin/Debug/net6.0/Unity.InternalAPIEngineBridge.001.dll -MelonLoader/bin/Debug/net6.0/Unity.Collections.LowLevel.ILSupport.dll -MelonLoader/bin/Debug/net6.0/Unity.Collections.dll -MelonLoader/bin/Debug/net6.0/Unity.Burst.Unsafe.dll -MelonLoader/bin/Debug/net6.0/Unity.Burst.dll -MelonLoader/bin/Debug/net6.0/Unity.2D.SpriteShape.Runtime.dll -MelonLoader/bin/Debug/net6.0/Unity.2D.Common.Runtime.dll -MelonLoader/bin/Debug/net6.0/Unity.2D.Animation.Runtime.dll -MelonLoader/bin/Debug/net6.0/Tomlet.dll -MelonLoader/bin/Debug/net6.0/PvZ_Fusion_Translator.pdb -MelonLoader/bin/Debug/net6.0/PvZ_Fusion_Translator.dll -MelonLoader/bin/Debug/net6.0/PvZ_Fusion_Translator.deps.json -MelonLoader/bin/Debug/net6.0/MonoMod.Utils.dll -MelonLoader/bin/Debug/net6.0/MonoMod.RuntimeDetour.dll -MelonLoader/bin/Debug/net6.0/MonoMod.ILHelpers.dll -MelonLoader/bin/Debug/net6.0/MonoMod.Backports.dll -MelonLoader/bin/Debug/net6.0/Mono.Cecil.Rocks.dll -MelonLoader/bin/Debug/net6.0/Mono.Cecil.Pdb.dll -MelonLoader/bin/Debug/net6.0/Mono.Cecil.Mdb.dll -MelonLoader/bin/Debug/net6.0/Mono.Cecil.dll -MelonLoader/bin/Debug/net6.0/Microsoft.Extensions.Logging.Abstractions.dll -MelonLoader/bin/Debug/net6.0/Microsoft.Diagnostics.Runtime.dll -MelonLoader/bin/Debug/net6.0/Microsoft.Diagnostics.NETCore.Client.dll -MelonLoader/bin/Debug/net6.0/MelonLoader.xml -MelonLoader/bin/Debug/net6.0/MelonLoader.pdb -MelonLoader/bin/Debug/net6.0/MelonLoader.dll -MelonLoader/bin/Debug/net6.0/Il2CppSystem.Xml.dll -MelonLoader/bin/Debug/net6.0/Il2CppSystem.dll -MelonLoader/bin/Debug/net6.0/Il2CppSystem.Core.dll -MelonLoader/bin/Debug/net6.0/Il2CppSystem.Configuration.dll -MelonLoader/bin/Debug/net6.0/Il2Cppmscorlib.dll -MelonLoader/bin/Debug/net6.0/Il2CppMono.Security.dll -MelonLoader/bin/Debug/net6.0/Il2CppInterop.Runtime.dll -MelonLoader/bin/Debug/net6.0/Il2CppInterop.HarmonySupport.dll -MelonLoader/bin/Debug/net6.0/Il2CppInterop.Generator.dll -MelonLoader/bin/Debug/net6.0/Il2CppInterop.Common.dll -MelonLoader/bin/Debug/net6.0/Il2Cpp__Generated.dll -MelonLoader/bin/Debug/net6.0/bHapticsLib.dll -MelonLoader/bin/Debug/net6.0/AudioImportLib.dll -MelonLoader/bin/Debug/net6.0/AssetsTools.NET.dll -MelonLoader/bin/Debug/net6.0/AssetRipper.Primitives.dll -MelonLoader/bin/Debug/net6.0/Assembly-CSharp.dll -MelonLoader/bin/Debug/net6.0/AsmResolver.PE.File.dll -MelonLoader/bin/Debug/net6.0/AsmResolver.PE.dll -MelonLoader/bin/Debug/net6.0/AsmResolver.DotNet.dll -MelonLoader/bin/Debug/net6.0/AsmResolver.dll -MelonLoader/bin/Debug/net6.0/0Harmony.dll -/MelonLoader/bin +# 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/ +[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 +*.tlog +*.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 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + +# 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/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# 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 + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml +.idea/ + +# Emik.Morsels symlinks +/Directory.Build.local.props +/Directory.Build.props +/Directory.Build.targets +/global.json +/stylecop.json diff --git a/.idea/.idea.PvZ Fusion Translator/.idea/material_theme_project_new.xml b/.idea/.idea.PvZ Fusion Translator/.idea/material_theme_project_new.xml new file mode 100644 index 0000000..301d842 --- /dev/null +++ b/.idea/.idea.PvZ Fusion Translator/.idea/material_theme_project_new.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/BepInEx/AssetStore/AudioStore.cs b/BepInEx/AssetStore/AudioStore.cs deleted file mode 100644 index 6bc8c04..0000000 --- a/BepInEx/AssetStore/AudioStore.cs +++ /dev/null @@ -1,179 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using HarmonyLib; -using UnityEngine; -using AudioImportLib.BepInEx; -using BepInEx.Logging; -using System.Runtime; -using System.Runtime.InteropServices; -using System.Reflection; -using System.IO; -using BepInEx; -using BepInEx.Configuration; - -namespace PvZ_Fusion_Translator__BepInEx_ -{ - internal class AudioStore - { - public static Dictionary AudioClips = []; - public static Dictionary AudioClipNames = []; - public static ManualLogSource Log = Core.Log; - - public static ConfigEntry LogSounds; - public static ConfigEntry category; - - private static bool overrideEnabled; - public static string customAudioPath = Path.Combine(Paths.PluginPath, "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() - { - LoadAudios(); - } - public static void LoadAudios() - { - try - { - // Clear existing dictionaries to prevent duplicate key errors - AudioClips.Clear(); - AudioClipNames.Clear(); - - if (!Directory.Exists(customAudioPath)) - Directory.CreateDirectory(customAudioPath); - - string[] audioFiles = Directory.GetFiles(customAudioPath, "*", SearchOption.AllDirectories); - var ovrClip = audioFiles.SingleOrDefault(f => Path.GetFileNameWithoutExtension(f) == "REPLACE_ALL"); - if (ovrClip == null) - { - foreach (string file in audioFiles) - { - if (!allowedExts.Contains(Path.GetExtension(file))) - continue; - - AudioClip clip = AudioImportLib.BepInEx.API.LoadAudioClip(file); - AudioClips.Add(clip.name, clip); - Log.LogInfo("Added Override: " + clip.name); - } - } - else - { - AudioClip clip = AudioImportLib.BepInEx.API.LoadAudioClip(ovrClip); - AudioClips.Add(clip.name, clip); - overrideEnabled = true; - Log.LogInfo("Added Override: " + clip.name); - } - } - catch (Exception ex) - { - Log.LogError($"Error loading audio clips: {ex.Message}"); - } - } - -#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 - - [HarmonyPatch(typeof(AudioSource), "Play", [])] - public class AudioSource_Patch - { - public static void Prefix(AudioSource __instance) - { - if (Utils.customAudio) - { - if (__instance.clip == null) - return; - - string audioClipName = overrideEnabled ? "REPLACE_ALL" : __instance.clip.name; - - if (AudioClips.TryGetValue(audioClipName, out AudioClip replaceClip)) - { - __instance.pitch = 1; - - __instance.clip = replaceClip; - } - } - } - } - } -} \ No newline at end of file diff --git a/BepInEx/AssetStore/CheckSumStore.cs b/BepInEx/AssetStore/CheckSumStore.cs deleted file mode 100644 index 7ff0704..0000000 --- a/BepInEx/AssetStore/CheckSumStore.cs +++ /dev/null @@ -1,862 +0,0 @@ -#if OBFUSCATE -using System.Security.Cryptography; -using System.Text.Encodings.Web; -using System.Text.Json; -using System.IO; -using static Newtonsoft.Json.JsonConvert; -using static PvZ_Fusion_Translator__BepInEx_.FileLoader; -using System.Collections.Generic; -using System; - -namespace PvZ_Fusion_Translator__BepInEx_.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/BepInEx/AssetStore/FontStore.cs b/BepInEx/AssetStore/FontStore.cs deleted file mode 100644 index 5be4dd3..0000000 --- a/BepInEx/AssetStore/FontStore.cs +++ /dev/null @@ -1,193 +0,0 @@ -using TMPro; -using System.Collections.Generic; -using System.IO; - -namespace PvZ_Fusion_Translator__BepInEx_.AssetStore -{ - public static class FontStore - { - internal static Dictionary fontAssetDict = []; - internal static Dictionary fontAssetDictSecondary = []; - - internal static void Init() - { - // Clear existing dictionaries to prevent duplicate key errors - fontAssetDict.Clear(); - fontAssetDictSecondary.Clear(); - - 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; - if (!fontAssetDict.ContainsKey(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")) - { - if (!fontAssetDictSecondary.ContainsKey(fileNameLanguage + "_Almanac")) - { - fontAssetDictSecondary.Add(fileNameLanguage + "_Almanac", fontAssetDictSecondary[fileNameLanguage]); - } - fontAssetDictSecondary.Remove(fileNameLanguage); - } - else - { - if (!fontAssetDictSecondary.ContainsKey(fileNameLanguage + "_Fallback")) - { - fontAssetDictSecondary.Add(fileNameLanguage + "_Fallback", fontAssetDictSecondary[fileNameLanguage]); - } - fontAssetDictSecondary.Remove(fileNameLanguage); - } - if (!fontAssetDictSecondary.ContainsKey(fileName)) - { - fontAssetDictSecondary.Add(fileName, fallbackFont); - } - } - else - { - if (!fontAssetDictSecondary.ContainsKey(fileNameLanguage)) - { - 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 - - } -} \ No newline at end of file diff --git a/BepInEx/AssetStore/StringStore.cs b/BepInEx/AssetStore/StringStore.cs deleted file mode 100644 index 0fc5372..0000000 --- a/BepInEx/AssetStore/StringStore.cs +++ /dev/null @@ -1,411 +0,0 @@ -using TMPro; -using System.Text.RegularExpressions; -using UnityEngine; -using System.Collections.Generic; -using System.IO; - -namespace PvZ_Fusion_Translator__BepInEx_.AssetStore -{ - public static class StringStore - { - internal static Dictionary stringsDict = []; - - public static Dictionary translationStringRegex = new(); - - public static Dictionary translationString = new(); - - 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:" }, - { "Polish", "Trudność:"}, - { "Hungarian", "Nehézség:"}, - { "Arabic", "صعوبة:"}, - // { "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:" }, - { "Polish" , "Zombi:" }, - { "Hungarian" , "Zombik:" }, - { "Arabic" , "الزومبي:" }, - // { "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 TranslateText(string originalText, string pattern, bool isLog = false) - { - if (TestRegex(originalText, pattern) && translationStringRegex.ContainsKey(pattern)) - { - // Extract dynamic parts from the original text - var regex = new Regex(pattern); - 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(translationStringRegex[pattern], [.. dynamicParts]); - } - else - { - if (isLog) - Log.LogDebug($"Text '{originalText}' not translated"); -#if DEBUG - FileLoader.DumpUntranslatedStrings(originalText); -#endif - return originalText; - } - } - - public static string TranslateColorText(string originalText, bool isLog = false) - { - string pattern = @"(]*>.*?)"; - if (TestRegex(originalText, pattern)) - { - return DoTranslateText(originalText, isLog); - } - return originalText; - } - - public static string DoTranslateText(string originalText, bool isLog = false) - { - if (string.IsNullOrEmpty(originalText)) - { - if (isLog) - Log.LogError("Text Null or Empty"); - - return string.Empty; - } - - if (translationString.ContainsKey(originalText)) - { - if (isLog) - Log.LogDebug($"Text '{originalText} found in translationString"); - return translationString[originalText]; - } - - // Regex-based dynamic translation - foreach (var entry in translationStringRegex) - { - if (TestRegex(originalText, entry.Key)) - { - // Extract dynamic parts from the original text - var regex = new Regex(entry.Key); - 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; - } - - public static bool TestRegex(string originalText, string pattern) - { - return Regex.IsMatch(originalText, pattern); - } - - 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 - }; - } - - public 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/BepInEx/AssetStore/TextureStore.cs b/BepInEx/AssetStore/TextureStore.cs deleted file mode 100644 index 1be856c..0000000 --- a/BepInEx/AssetStore/TextureStore.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System.Collections.Generic; -using System.Collections; -using UnityEngine; -using System.IO; - -namespace PvZ_Fusion_Translator__BepInEx_.AssetStore -{ - public static class TextureStore - { - internal static Dictionary textureDict = []; - - internal static Dictionary spriteDict = []; - - internal static void Init() => FileLoader.LoadTextures(); - - internal static void Reload() - { - textureDict.Clear(); - #if MULTI_LANGUAGE - RestoreTextures(); - #endif - if(!Utils.customTextures) - { - FileLoader.LoadDefaultTextures(); - } - FileLoader.LoadTextures(); - } - - public static IEnumerator ReplaceTexturesCoroutine() - { - if (!Utils.customTextures) - { - FileLoader.LoadDefaultTextures(); - } - 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/BepInEx/AssetStore/WarningStore.cs b/BepInEx/AssetStore/WarningStore.cs deleted file mode 100644 index 16e7a4b..0000000 --- a/BepInEx/AssetStore/WarningStore.cs +++ /dev/null @@ -1,218 +0,0 @@ -using System.Runtime.CompilerServices; - -using TMPro; -using UnityEngine; -using UnityEngine.TextCore.Text; -using System.IO; -using System.Collections.Generic; - -namespace PvZ_Fusion_Translator__BepInEx_.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.") }, - { "Polish" , ("Jedynym wiarygodnym źródłem tego tłumaczenia jest ta społeczność:\n" + - "discord.gg/DPAC5ZVJ8T. Jeśli znalazłeś to gdziekolwiek indziej, np. \n" + - "Plants Hybrid i superhybrid.online, ukradli to.\n" + - "Omijaj inne źródła, ponieważ mogą zawierać wirusy.\n" + - "Odwiedź naszą społeczność, aby uzyskać przyszłe aktualizacje.", - "Okay! Rozumiem.") }, - { "Hungarian" , ("Ennek a fordításnak az egyetlen érvényes forrása ebből a közösségből származik:\n" + - "discord.gg/DPAC5ZVJ8T. Ha ezt valahol máshol szerezted, például \n" + - "Plants Hybrid és superhybrid.online oldalakon, akkor ők lopták.\n" + - "Kerüld a többi forrást, mert vírusokat tartalmazhatnak.\n" + - "Kérjük, látogass el közösségünkbe a jövőbeli frissítésekért.", - "Oké! Értem.") }, - { "Arabic" , ("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.") }, - // { "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(NoticeMenu noticeMenu) - { - //GameAPP.theGameStatus = GameStatus.OpenOptions; - //GameObject gameObject = UnityEngine.Object.Instantiate(Resources.Load("UI/Prefabs/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); - - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - Transform warningTransform = noticeMenu.transform.FindChild("窗口"); - 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 = warningMessage; - array[i].GetComponent().font = fontAsset; - } - } - #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, NoticeMenu noticeMenu) - { - // 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(noticeMenu); - 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/BepInEx/Core.cs b/BepInEx/Core.cs deleted file mode 100644 index 6d58a9d..0000000 --- a/BepInEx/Core.cs +++ /dev/null @@ -1,185 +0,0 @@ -using BepInEx; -using BepInEx.Configuration; -using BepInEx.Logging; -using BepInEx.Unity.IL2CPP; -using BepInEx.Unity.IL2CPP.Utils; -using TMPro; -using HarmonyLib; -using PvZ_Fusion_Translator__BepInEx_; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using PvZ_Fusion_Translator__BepInEx_.Patches.Managers; -using System; -using System.IO; -using System.Reflection; -using UnityEngine; - -[BepInPlugin("PVZFusionTranslator_BepInEx", "PvZ Fusion Translator", "3.1.1")] -[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 new static ManualLogSource Log; - 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; - - private static float lastCheck = 0f; - private static float checkTime = 0f; - private static float checkInterval = 2f; - private static bool stringreloaded = false; - - public override void Load() - { - Log = base.Log; - Instance = this; - LoadConfig(); - MonoInstance = AddComponent(); - Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly()); - dtStart = DateTime.Now; - - FileLoader.LoadLanguage(); - - AudioStore.Init(); - TextureStore.Init(); - StringStore.Init(); - FontStore.Init(); - Utils.RegisterPlantIndices(); - - //Utils.RegisterRecipeLinks(); - //PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects.Zombie_Patch.LoadHPStrings(); - - 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() - { - replaceTextureRoutine = MonoInstance.StartCoroutine(TextureStore.ReplaceTexturesCoroutine()); - } - public static void ShowToast(string message) - { - toast_txt = message; - dtStartToast = DateTime.Now; - } - - public void OnUpdate() - { - ModFeatures.OnLateUpdate(); - - if (Input.GetKeyDown(KeyCode.Insert)) - { - Log.LogInfo("Insert press"); - Utils.OpenSaveDirectory(); - } - - if (Input.GetKeyDown(KeyCode.Delete)) - { - Log.LogInfo("del del"); - Utils.OpenTrello(); - } - if (TowerManager.Instance != null) - { - TowerManager_Patch.UpdateText(); - } - if (Input.GetKeyDown(KeyCode.RightShift)) - { - stringreloaded = !stringreloaded; - } - Core.DebugStringReload(); - } - - public static void DebugStringReload() - { - if (stringreloaded == true) - { - checkTime += Time.deltaTime; - if (checkTime >= checkInterval) - { - StringStore.Reload(); - ShowToast("Strings Reloaded!"); - checkTime = 0f; - } - } - } - - public void OnGUI() - { - #if DEBUG - if (dtStartToast != null) - { - try - { - GUI.Button(new Rect(10f, 10f, 200f, 20f), "\n" + toast_txt + "\n"); - } - catch(Exception e) - { - Log.LogError(e); - } - - 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"; - - if(Config.TryGetEntry(new ConfigDefinition(mainCategory, "DefaultTextures"), out configDefaultTextures) == false) - { - configDefaultTextures = Config.Bind(new ConfigDefinition(mainCategory, "DefaultTextures"), false, new ConfigDescription("Use Default Textures + Translation Textures", new AcceptableValueList(true, false))); - } - bool defaultTextures = Config.TryGetEntry(new ConfigDefinition("PvZ_Fusion_Translator", "DefaultTextures"), out configDefaultTextures); - - if (Config.TryGetEntry(new ConfigDefinition(mainCategory, "DefaultAudio"), out configDefaultAudio) == false) - { - configDefaultAudio = Config.Bind(new ConfigDefinition(mainCategory, "DefaultAudio"), false, new ConfigDescription("Use Default Audio", new AcceptableValueList(true, false))); - } - bool defaultAudio = Config.TryGetEntry(new ConfigDefinition("PvZ_Fusion_Translator", "DefaultAudio"), out configDefaultAudio); - - if (Config.TryGetEntry(new ConfigDefinition(mainCategory, "Language"), out configLanguage) == 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"))); - } - bool language = Config.TryGetEntry(new ConfigDefinition("PvZ_Fusion_Translator", "Language"), out configLanguage); - } -} - -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/BepInEx/Dependencies/AudioImportLib.BepInEx.dll b/BepInEx/Dependencies/AudioImportLib.BepInEx.dll deleted file mode 100644 index 2e87423136310c16b1a33d6c4dc8dd7cfdcd2a05..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 295936 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

y{iiClKkuV?` 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 diff --git a/BepInEx/FileLoader.cs b/BepInEx/FileLoader.cs deleted file mode 100644 index b410aee..0000000 --- a/BepInEx/FileLoader.cs +++ /dev/null @@ -1,382 +0,0 @@ -using BepInEx.Configuration; -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; -using UnityEngine.Rendering; - -namespace PvZ_Fusion_Translator__BepInEx_ -{ - internal static class FileLoader - { - internal enum AssetType - { - Textures, - Strings, - Dumps, - Almanac, - Sprites - } - - 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."); - } - - - internal static void LoadTextures() - { - - // Default or Custom Texturse -> English Textures -> Localized Textures - try - { - if (Utils.customTextures) - { - LoadCustomTextures(); - } - else - { - LoadDefaultTextures(); - } - } - 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) - { - ConfigEntry defaultTextureEntry; - Core.Instance.Config.TryGetEntry(new ConfigDefinition("PvZ_Fusion_Translator", "DefaultTextures"), out defaultTextureEntry); - - 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) && defaultTextureEntry.Value) - { - 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() - { - if (Core.Instance.configDefaultTextures.Value) - { - 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; - string AbyssBuffData = Resources.Load("AbyssBuffData").text; - File.WriteAllText(Path.Combine(dumpDir, "LawnStrings.json"), LawnStrings); - File.WriteAllText(Path.Combine(dumpDir, "ZombieStrings.json"), ZombieStrings); - File.WriteAllText(Path.Combine(dumpDir, "AbyssBuffData.json"), AbyssBuffData); - - Dictionary achievementsList = new Dictionary(); - foreach (var entry in AchievementClip.achievementsText) - { - var key = entry.Key; - var value = entry.Value; - achievementsList.Add(key, new AchievementObject(key, value.Item1, value.Item2)); - } - File.WriteAllText(Path.Combine(dumpDir, "AchievementsText.json"), JsonSerializer.Serialize(achievementsList, new JsonSerializerOptions - { - 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); - var untranslatedStrings = JsonSerializer.Deserialize>(json); - - if (!untranslatedStrings.ContainsKey(text)) - { - untranslatedStrings[text] = text; - var options = new JsonSerializerOptions - { - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, - WriteIndented = true - }; - File.WriteAllText(jsonFile, JsonSerializer.Serialize(untranslatedStrings, options)); - } - } -//#endif - -#if MULTI_LANGUAGE - internal static void LoadLanguage() - { - try - { - // Load the language preference as a string and parse it into the enum - ConfigEntry languageEntry; - Core.Instance.Config.TryGetEntry(new ConfigDefinition("PvZ_Fusion_Translator", "Language"), out languageEntry); - string languageName = languageEntry.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 - ConfigEntry languageEntry; - Core.Instance.Config.TryGetEntry(new ConfigDefinition("PvZ_Fusion_Translator", "Language"), out languageEntry); - languageEntry.Value = Utils.Language.ToString(); - Core.Instance.Config.Save(); - - // 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 - } -} diff --git a/BepInEx/FontHandler.cs b/BepInEx/FontHandler.cs deleted file mode 100644 index 44869f9..0000000 --- a/BepInEx/FontHandler.cs +++ /dev/null @@ -1,45 +0,0 @@ -using BepInEx; -using PvZ_Fusion_Translator__BepInEx_; -using System.IO; -using TMPro; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_ -{ - public static class FontHandler - { - public static Font LoadFont(this string pathFromModsFolder, bool throwException) - { - string fontFilePath = Path.Combine(Paths.PluginPath, pathFromModsFolder); - if (!File.Exists(fontFilePath)) - { - if (throwException) - Log.LogWarning($"Font not found at path: '{fontFilePath}'."); - return null; - } - - 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/BepInEx/Log.cs b/BepInEx/Log.cs deleted file mode 100644 index b9407bf..0000000 --- a/BepInEx/Log.cs +++ /dev/null @@ -1,25 +0,0 @@ -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/BepInEx/ModFeatures.cs b/BepInEx/ModFeatures.cs deleted file mode 100644 index b63a432..0000000 --- a/BepInEx/ModFeatures.cs +++ /dev/null @@ -1,80 +0,0 @@ -//#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)) - { - Log.LogDebug(feature.KeyCode); - feature.ToggleFeature(); - } - } - } - } - } -} -//#endif \ No newline at end of file diff --git a/BepInEx/Patches/BaseTextObjects/InGameText_Patch.cs b/BepInEx/Patches/BaseTextObjects/InGameText_Patch.cs deleted file mode 100644 index 2687306..0000000 --- a/BepInEx/Patches/BaseTextObjects/InGameText_Patch.cs +++ /dev/null @@ -1,62 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using PvZ_Fusion_Translator__BepInEx_.Patches.Managers; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.BaseTextObjects -{ - [HarmonyPatch(typeof(InGameText))] - public static class InGameText_Patch - { - [HarmonyPatch(nameof(InGameText.ShowText), new Type[] { typeof(string), typeof(float), typeof(bool), typeof(bool) })] - [HarmonyPrefix] - private static void ShowText_Pre(InGameText __instance, ref string text) => text = StringStore.TranslateText(text, true); - - [HarmonyPatch(nameof(InGameText.ShowText), new Type[] { typeof(string), typeof(float), typeof(bool), typeof(bool) })] - [HarmonyPostfix] - private static void ShowText_Post(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) - { - string travelMatch = TravelMgr_Patch.MatchTravelBuff(txt.text); - string originalText = txt.text; - - if (txt.gameObject.name.Contains("shadow")) - { - continue; - } - - if (travelMatch != "") - { - txt.text = travelMatch; - if (txt.gameObject.name.Contains("main")) - { - originalText = txt.text; - Transform shadowText = txt.transform.parent.Find("Text_shadow"); - if (shadowText != null) - { - shadowText.GetComponent().text = Utils.RemoveColorTags(originalText); - } - } - } - else if(System.Text.RegularExpressions.Regex.Match(txt.text, @"(]*>.*?)", System.Text.RegularExpressions.RegexOptions.Singleline).Success) - { - txt.text = StringStore.TranslateColorText(txt.text); - } - else - { - txt.text = StringStore.TranslateText(txt.text, true); - } - txt.font = fontAsset; - } - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/BaseTextObjects/TMP_InputField_Patch.cs b/BepInEx/Patches/BaseTextObjects/TMP_InputField_Patch.cs deleted file mode 100644 index c8046b6..0000000 --- a/BepInEx/Patches/BaseTextObjects/TMP_InputField_Patch.cs +++ /dev/null @@ -1,25 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -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/BepInEx/Patches/BaseTextObjects/TextMeshProUGUI_Patch.cs b/BepInEx/Patches/BaseTextObjects/TextMeshProUGUI_Patch.cs deleted file mode 100644 index bf02d9a..0000000 --- a/BepInEx/Patches/BaseTextObjects/TextMeshProUGUI_Patch.cs +++ /dev/null @@ -1,97 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using PvZ_Fusion_Translator__BepInEx_.Patches.Managers; -using UnityEngine.UI; -using UnityEngine; - -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)) - { - if(__instance.transform.parent.parent != null) - { - if (__instance.transform.parent.parent.name.Contains("AbyssBagMenu")) - { - return; - } - } - - __instance = StringStore.TranslateText(__instance); - __instance.autoSizeTextContainer = false; - - if (__instance.name.StartsWith("LevelName")) - { - __instance.text = __instance.text.Replace("\n", " "); - - if (__instance.name == "LevelName2" || __instance.name == "LevelName3") - { - TowerManager_Patch.updatedText.Add(__instance.transform); - } - } - 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)) - { - if (__instance.transform.parent.parent != null) - { - if (__instance.transform.parent.parent.name.Contains("AbyssBagMenu")) - { - return; - } - } - - __instance = StringStore.TranslateText(__instance); - __instance.autoSizeTextContainer = false; - - 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/BepInEx/Patches/BaseTextObjects/TextMeshPro_Patch.cs b/BepInEx/Patches/BaseTextObjects/TextMeshPro_Patch.cs deleted file mode 100644 index 0497378..0000000 --- a/BepInEx/Patches/BaseTextObjects/TextMeshPro_Patch.cs +++ /dev/null @@ -1,30 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; - -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.transform.parent.name.StartsWith("CardBank")) - { - __instance = StringStore.TranslateText(__instance); - __instance.autoSizeTextContainer = false; - return; - } else if (!(__instance.transform.name.Contains("AlmanacZombie") || __instance.transform.name.Contains("AlmanacPlant") || __instance.transform.name.Contains("Name") || __instance.transform.name.Contains("Tips") || __instance.transform.parent.name.Contains("Signboard") || __instance.transform.parent.name.Contains("text"))) - { - __instance = StringStore.TranslateText(__instance); - __instance.autoSizeTextContainer = true; - } - } - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/AbyssBuffMenu_Patch.cs b/BepInEx/Patches/GameObjects/AbyssBuffMenu_Patch.cs deleted file mode 100644 index 7e29e91..0000000 --- a/BepInEx/Patches/GameObjects/AbyssBuffMenu_Patch.cs +++ /dev/null @@ -1,110 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.IO; -using System.Text.Json; -using System.Text.RegularExpressions; -using HarmonyLib; -//using MelonLoader.TinyJSON; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using PvZ_Fusion_Translator__BepInEx_; -using TMPro; -using UnityEngine.TextCore.Text; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(AbyssBuffMenu))] - public static class AbyssBuffMenu_Patch - { - public static Dictionary abyssBuffData = new Dictionary(); - - [HarmonyPatch(nameof(AbyssBuffMenu.Awake))] - [HarmonyPostfix] - public static void Post_Awake(AbyssBuffMenu __instance) - { - LoadAbyssBuffData(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - text.font = fontAsset; - } - - TranslateWindows(__instance, fontAsset); - } - - [HarmonyPatch(nameof(AbyssBuffMenu.SelectWindow))] - [HarmonyPostfix] - public static void Post_SelectWindow(AbyssBuffMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - TranslateWindows(__instance, fontAsset); - } - - [HarmonyPatch(nameof(AbyssBuffMenu.SetFavorite))] - [HarmonyPostfix] - public static void Post_SetFavorite(AbyssBuffMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - text.font = fontAsset; - } - } - - public static void TranslateWindows(AbyssBuffMenu __instance, TMP_FontAsset fontAsset) - { - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - if (abyssBuffData.ContainsKey(text.text)) - { - text.text = abyssBuffData[text.text]; - } - else - { - string translatedRegex = TranslateAbyssBuffRegex(text.text); - if (translatedRegex != null) - { - text.text = translatedRegex; - } - } - - text.font = fontAsset; - } - } - - public static void LoadAbyssBuffData() - { - abyssBuffData.Clear(); - - string abyssBuffText = File.ReadAllText(Path.Combine(FileLoader.GetAssetDir(FileLoader.AssetType.Strings, Utils.Language), "abyss_buffs.json")); - abyssBuffData = JsonSerializer.Deserialize>(abyssBuffText); - } - - public static string TranslateAbyssBuffRegex(string originalText) - { - foreach (var x in abyssBuffData) - { - if (x.Key.Contains("{value}")) - { - string pattern = Regex.Escape(x.Key).Replace("\\{value}", "(\\d+)"); - if (Regex.IsMatch(originalText, pattern)) - { - var regex = new Regex(pattern); - var match = regex.Match(originalText); - - return String.Format(x.Value.Replace("value", "0"), match.Groups[1].Value); - } - } - } - - return null; - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/AbyssCheckInBag_Patch.cs b/BepInEx/Patches/GameObjects/AbyssCheckInBag_Patch.cs deleted file mode 100644 index 28e7733..0000000 --- a/BepInEx/Patches/GameObjects/AbyssCheckInBag_Patch.cs +++ /dev/null @@ -1,28 +0,0 @@ -//using HarmonyLib; -//using System; -//using PvZ_Fusion_Translator__BepInEx_.AssetStore; -//using UnityEngine; -//using UnityEngine.TextCore.Text; -//using UnityEngine.UI; - -//namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -//{ - -// [HarmonyPatch(typeof(AbyssCheckInBag))] -// public static class AbyssCheckInBag_Patch -// { -// [HarmonyPatch(nameof(AbyssCheckInBag.MoveFromBag))] -// [HarmonyPostfix] -// private static void MoveFromBag(AbyssCheckInBag __instance) -// { -// AbyssMenu2.Instance.UpdateIcons(); -// } - -// [HarmonyPatch(nameof(AbyssCheckInBag.SellIcon))] -// [HarmonyPostfix] -// private static void SellIcon(AbyssCheckInBag __instance) -// { -// AbyssMenu2.Instance.UpdateIcons(); -// } -// } -//} diff --git a/BepInEx/Patches/GameObjects/AbyssDevelopMenu_Patch.cs b/BepInEx/Patches/GameObjects/AbyssDevelopMenu_Patch.cs deleted file mode 100644 index 411a415..0000000 --- a/BepInEx/Patches/GameObjects/AbyssDevelopMenu_Patch.cs +++ /dev/null @@ -1,49 +0,0 @@ -//using System.Text.RegularExpressions; -//using HarmonyLib; -//using System; -//using System.Collections.Generic; -//using System.Linq; -//using TMPro; -//using PvZ_Fusion_Translator__BepInEx_.AssetStore; -//using UnityEngine.TextCore.Text; - -//namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -//{ -// [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); - -// TextMeshProUGUI upgradeCostText = __instance.transform.FindChild("UpgradeCost").GetComponent(); -// TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - -// string regexStr = "([^\\s]+)\n当前等级:([^\\s]+)\n\n升级条件:\n([^\\s]+)\n\n升级消耗:([^\\s]+)"; - -// Regex regex = new Regex(regexStr); - -// if (regex.IsMatch(upgradeCostText.text)) -// { -// Match match = regex.Match(upgradeCostText.text); -// int groupCount = match.Groups.Count; - -// List dynamicParts = []; - -// for (int i = 1; i < groupCount; i++) -// { -// string groupValue = match.Groups[i].Value; -// string translatedValue = StringStore.translationString.ContainsKey(groupValue) ? StringStore.translationString[groupValue] : groupValue; -// dynamicParts.Add(translatedValue); -// } - -// upgradeCostText.text = string.Format(StringStore.translationStringRegex[regexStr], [.. dynamicParts]); -// upgradeCostText.font = fontAsset; -// } -// } -// } -//} diff --git a/BepInEx/Patches/GameObjects/AbyssMenu_Patch.cs b/BepInEx/Patches/GameObjects/AbyssMenu_Patch.cs deleted file mode 100644 index 55bfcb7..0000000 --- a/BepInEx/Patches/GameObjects/AbyssMenu_Patch.cs +++ /dev/null @@ -1,49 +0,0 @@ -using HarmonyLib; -using System; -using System.Collections.Generic; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using Unity.VisualScripting; -using UnityEngine; -using System.Text.RegularExpressions; -using UnityEngine.UI; -using PvZ_Fusion_Translator__BepInEx_; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [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; - } - - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - text.font = fontAsset; - } - } - - [HarmonyPatch(nameof(AbyssMenu.UpdateLevelInfo))] - [HarmonyPostfix] - private static void UpdateLevelInfo(AbyssMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.levelInfo) - { - txt.text = StringStore.TranslateText(txt.text, pattern: "第(\\d+)关\n场景:([^\\s]+)\n总波数:(\\d+)波\n特殊环境:([^\\s]+)\n难度:(\\d+)"); - txt.font = fontAsset; - } - } - } -} diff --git a/BepInEx/Patches/GameObjects/AbyssSelectBuffWindow_Patch.cs b/BepInEx/Patches/GameObjects/AbyssSelectBuffWindow_Patch.cs deleted file mode 100644 index 7beb3ea..0000000 --- a/BepInEx/Patches/GameObjects/AbyssSelectBuffWindow_Patch.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System.Text.RegularExpressions; -using HarmonyLib; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using PvZ_Fusion_Translator__BepInEx_; -using TMPro; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(AbyssSelectBuffWindow))] - public static class AbyssSelectBuffWindow_Patch - { - [HarmonyPatch(nameof(AbyssSelectBuffWindow.OnAnimOver))] - [HarmonyPostfix] - private static void OnAnimOver(AbyssSelectBuffWindow __instance) - { - TranslateBuffWindow(__instance); - } - - [HarmonyPatch(nameof(AbyssSelectBuffWindow.SetBuff))] - [HarmonyPostfix] - private static void SetBuff(AbyssSelectBuffWindow __instance) - { - TranslateBuffWindow(__instance); - } - - public static void TranslateBuffWindow(AbyssSelectBuffWindow __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - AbyssBuffMenu_Patch.LoadAbyssBuffData(); - - foreach (TextMeshProUGUI titleText in __instance.titleText) - { - if (AbyssBuffMenu_Patch.abyssBuffData.ContainsKey(titleText.text)) - { - if (titleText.name.Contains("shadow")) - { - titleText.text = Utils.RemoveColorTags(AbyssBuffMenu_Patch.abyssBuffData[titleText.text]); - } - else - { - titleText.text = AbyssBuffMenu_Patch.abyssBuffData[titleText.text]; - } - } - titleText.font = fontAsset; - } - - string translatedIntroduceText = (AbyssBuffMenu_Patch.abyssBuffData.ContainsKey(__instance.introduce.text)) ? AbyssBuffMenu_Patch.abyssBuffData[__instance.introduce.text] : AbyssBuffMenu_Patch.TranslateAbyssBuffRegex(__instance.introduce.text); - - if (translatedIntroduceText != null) - { - __instance.introduce.text = translatedIntroduceText; - __instance.introduce.font = fontAsset; - } - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/AbyssSettlementMenu_Patch.cs b/BepInEx/Patches/GameObjects/AbyssSettlementMenu_Patch.cs deleted file mode 100644 index d8731ce..0000000 --- a/BepInEx/Patches/GameObjects/AbyssSettlementMenu_Patch.cs +++ /dev/null @@ -1,55 +0,0 @@ -//using HarmonyLib; -//using System; -//using System.Collections.Generic; -//using TMPro; -//using PvZ_Fusion_Translator__BepInEx_.AssetStore; -//using Unity.VisualScripting; -//using UnityEngine; -//using System.Text.RegularExpressions; - -//namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -//{ -// [HarmonyPatch(typeof(AbyssSettlementMenu))] -// public static class AbyssSettlementMenu_Patch -// { - -// [HarmonyPatch(nameof(AbyssSettlementMenu.InitSettle))] -// [HarmonyPostfix] -// private static void InitSettle(AbyssSettlementMenu __instance) -// { -// TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - -// string[] regexStrList = [ -// "第(\\d+)关\n通关用时:(\\d+)分(\\d+)秒\n杀敌数量:(\\d+)\n关卡叶绿素产出:(\\d+)\n极限模式产出:(\\d+)\n非首胜无额外产出\n产出叶绿素总计:(\\d+)", -// "第(\\d+)关\n通关用时:(\\d+)分(\\d+)秒\n杀敌数量:(\\d+)\n关卡叶绿素产出:(\\d+)\n极限模式产出:(\\d+)\n首胜产出:(\\d+)\n剩余小推车数量:(\\d+),获得叶绿素:(\\d+)\n产出叶绿素总计:(\\d+)", -// "第(\\d+)关\n通关用时:(\\d+)分(\\d+)秒\n杀敌数量:(\\d+)\n关卡叶绿素产出:(\\d+)\n首胜产出:(\\d+)\n剩余小推车数量:(\\d+),获得叶绿素:(\\d+)\n产出叶绿素总计:(\\d+)", -// "第(\\d+)关\n通关用时:(\\d+)分(\\d+)秒\n杀敌数量:(\\d+)\n关卡叶绿素产出:(\\d+)\n困难模式产出:(\\d+)\n首胜产出:(\\d+)\n剩余小推车数量:(\\d+),获得叶绿素:(\\d+)\n产出叶绿素总计:(\\d+)", -// "第(\\d+)关\n通关用时:(\\d+)分(\\d+)秒\n杀敌数量:(\\d+)\n关卡叶绿素产出:(\\d+)\n非首胜无额外产出\n产出叶绿素总计:(\\d+)", -// "第(\\d+)关\n通关用时:(\\d+)分(\\d+)秒\n杀敌数量:(\\d+)\n关卡叶绿素产出:(\\d+)\n困难模式产出:(\\d+)\n非首胜无额外产出\n产出叶绿素总计:(\\d+)" -// ]; - -// foreach(string regexStr in regexStrList) -// { -// Regex regex = new Regex(regexStr); - -// if (regex.IsMatch(__instance.settleInfo.text)) -// { -// Match match = regex.Match(__instance.settleInfo.text); -// int groupCount = match.Groups.Count; - -// List dynamicParts = []; - -// for (int i = 1; i < groupCount; i++) -// { -// string groupValue = match.Groups[i].Value; -// string translatedValue = StringStore.translationString.ContainsKey(groupValue) ? StringStore.translationString[groupValue] : groupValue; -// dynamicParts.Add(translatedValue); -// } - -// __instance.settleInfo.text = string.Format(StringStore.translationStringRegex[regexStr], [.. dynamicParts]); -// __instance.settleInfo.font = fontAsset; -// } -// } -// } -// } -//} diff --git a/BepInEx/Patches/GameObjects/AbyssStoreMenu_Patch.cs b/BepInEx/Patches/GameObjects/AbyssStoreMenu_Patch.cs deleted file mode 100644 index a1c5f65..0000000 --- a/BepInEx/Patches/GameObjects/AbyssStoreMenu_Patch.cs +++ /dev/null @@ -1,17 +0,0 @@ -using HarmonyLib; -using System; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(AbyssStoreMenu))] - public static class AbyssStoreMenu_Patch - { - [HarmonyPatch(nameof(AbyssStoreMenu.Update))] - [HarmonyPostfix] - private static void UpdateInfo(AbyssStoreMenu __instance) - { - __instance.yourMoney.text = StringStore.TranslateText(__instance.yourMoney.text); - } - } -} diff --git a/BepInEx/Patches/GameObjects/AdvantureEvolutionMenu_Patch.cs b/BepInEx/Patches/GameObjects/AdvantureEvolutionMenu_Patch.cs deleted file mode 100644 index 23fe212..0000000 --- a/BepInEx/Patches/GameObjects/AdvantureEvolutionMenu_Patch.cs +++ /dev/null @@ -1,20 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(AdvantureEvolutionMenu))] - public static class AdvantureEvolutionMenu_Patch - { - [HarmonyPatch(nameof(AdvantureEvolutionMenu.Awake))] - [HarmonyPostfix] - private static void Awake(AdvantureEvolutionMenu __instance) - { - foreach(TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - } -} diff --git a/BepInEx/Patches/GameObjects/AdvantureHelpMenu_Patch.cs b/BepInEx/Patches/GameObjects/AdvantureHelpMenu_Patch.cs deleted file mode 100644 index 7ba5af7..0000000 --- a/BepInEx/Patches/GameObjects/AdvantureHelpMenu_Patch.cs +++ /dev/null @@ -1,20 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(AdvantureHelpMenu))] - public static class AdvantureHelpMenu_Patch - { - [HarmonyPatch(nameof(AdvantureHelpMenu.Awake))] - [HarmonyPostfix] - private static void Awake(AdvantureHelpMenu __instance) - { - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - } -} diff --git a/BepInEx/Patches/GameObjects/AdvantureMenu2_Patch.cs b/BepInEx/Patches/GameObjects/AdvantureMenu2_Patch.cs deleted file mode 100644 index f0926c1..0000000 --- a/BepInEx/Patches/GameObjects/AdvantureMenu2_Patch.cs +++ /dev/null @@ -1,27 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(AdvantureMenu2))] - public static class AdvantureMenu2_Patch - { - [HarmonyPatch(nameof(AdvantureMenu2.Awake))] - [HarmonyPostfix] - private static void Awake(AdvantureMenu2 __instance) - { - foreach(TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - - [HarmonyPatch(nameof(AdvantureMenu2.AdjustDifficulty))] - [HarmonyPostfix] - private static void AdjustDifficulty(AdvantureMenu2 __instance) - { - __instance.difficulty.text = StringStore.TranslateText(__instance.difficulty.text); - } - } -} diff --git a/BepInEx/Patches/GameObjects/AdvantureMenu_Patch.cs b/BepInEx/Patches/GameObjects/AdvantureMenu_Patch.cs deleted file mode 100644 index 7360d02..0000000 --- a/BepInEx/Patches/GameObjects/AdvantureMenu_Patch.cs +++ /dev/null @@ -1,63 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(AdvantureMenu))] - public static class AdvantureMenu_Patch - { - [HarmonyPatch(nameof(AdvantureMenu.Start))] - [HarmonyPostfix] - private static void Start(AdvantureMenu __instance) - { - TranslateAdvantureMenu(__instance); - } - - [HarmonyPatch(nameof(AdvantureMenu.ChangeDifficulty))] - [HarmonyPostfix] - private static void ChangeDifficulty(AdvantureMenu __instance) - { - TranslateAdvantureMenu(__instance); - } - - [HarmonyPatch(nameof(AdvantureMenu.GetChapterDifficulty))] - [HarmonyPostfix] - private static void GetChapterDifficulty(AdvantureMenu __instance) - { - TranslateAdvantureMenu(__instance); - } - - [HarmonyPatch(nameof(AdvantureMenu.UpdateChapterDifficulty))] - [HarmonyPostfix] - private static void UpdateChapterDifficulty(AdvantureMenu __instance) - { - TranslateAdvantureMenu(__instance); - } - - [HarmonyPatch(nameof(AdvantureMenu.UpdateStarCount))] - [HarmonyPostfix] - private static void UpdateStarCount(AdvantureMenu __instance) - { - TranslateAdvantureMenu(__instance); - } - - public static void TranslateAdvantureMenu(AdvantureMenu __instance) - { - bool hasSBString = StringStore.translationString.ContainsKey(__instance.difficulty.text + "_SB"); - __instance.difficulty.text = Utils.RemoveSizeTags(hasSBString ? StringStore.TranslateText(__instance.difficulty.text + "_SB") : StringStore.TranslateText(__instance.difficulty.text)); - __instance.chapterDifficulty.text = StringStore.TranslateText(__instance.chapterDifficulty.text); - __instance.starCount.text = StringStore.TranslateText(__instance.starCount.text); - - foreach (TextMeshProUGUI text in __instance.title) - { - text.text = StringStore.TranslateText(text.text); - } - - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - } -} diff --git a/BepInEx/Patches/GameObjects/AdvantureMissionMenu_Patch.cs b/BepInEx/Patches/GameObjects/AdvantureMissionMenu_Patch.cs deleted file mode 100644 index a26a9e3..0000000 --- a/BepInEx/Patches/GameObjects/AdvantureMissionMenu_Patch.cs +++ /dev/null @@ -1,55 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(AdvantureMissionMenu))] - public static class AdvantureMissionMenu_Patch - { - [HarmonyPatch(nameof(AdvantureMissionMenu.Awake))] - [HarmonyPostfix] - private static void Awake(AdvantureMissionMenu __instance) - { - foreach (TextMeshProUGUI text in __instance.contant.GetComponentsInChildren()) - { - text.text = StringStore.TranslateColorText(text.text); - } - - //foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - //{ - // text.text = StringStore.TranslateText(text.text); - //} - } - - [HarmonyPatch(nameof(AdvantureMissionMenu.InitText))] - [HarmonyPostfix] - private static void InitText(AdvantureMissionMenu __instance) - { - foreach (TextMeshProUGUI text in __instance.contant.GetComponentsInChildren()) - { - text.text = StringStore.TranslateColorText(text.text); - } - - //foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - //{ - // text.text = StringStore.TranslateText(text.text); - //} - } - - [HarmonyPatch(nameof(AdvantureMissionMenu.SwitchAward))] - [HarmonyPostfix] - private static void SwitchAward(AdvantureMissionMenu __instance) - { - foreach(TextMeshProUGUI text in __instance.contant.GetComponentsInChildren()) - { - text.text = StringStore.TranslateColorText(text.text); - } - - //foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - //{ - // text.text = StringStore.TranslateText(text.text); - //} - } - } -} diff --git a/BepInEx/Patches/GameObjects/AdvantureStarMenu_Patch.cs b/BepInEx/Patches/GameObjects/AdvantureStarMenu_Patch.cs deleted file mode 100644 index 1d9541a..0000000 --- a/BepInEx/Patches/GameObjects/AdvantureStarMenu_Patch.cs +++ /dev/null @@ -1,60 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(AdvantureStarMenu))] - public static class AdvantureStarMenu_Patch - { - [HarmonyPatch(nameof(AdvantureStarMenu.Awake))] - [HarmonyPostfix] - private static void Awake(AdvantureStarMenu __instance) - { - foreach(TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - - [HarmonyPatch(nameof(AdvantureStarMenu.GetNodes))] - [HarmonyPostfix] - private static void GetNodes(AdvantureStarMenu __instance) - { - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - - [HarmonyPatch(nameof(AdvantureStarMenu.UpdateStarText))] - [HarmonyPostfix] - private static void UpdateStarText(AdvantureStarMenu __instance) - { - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - - [HarmonyPatch(nameof(AdvantureStarMenu.InitTalents))] - [HarmonyPostfix] - private static void InitTalents(AdvantureStarMenu __instance) - { - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - - [HarmonyPatch(nameof(AdvantureStarMenu.ResetAward))] - [HarmonyPostfix] - private static void ResetAward(AdvantureStarMenu __instance) - { - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - } -} diff --git a/BepInEx/Patches/GameObjects/AlmanacPlantMenu_Patch.cs b/BepInEx/Patches/GameObjects/AlmanacPlantMenu_Patch.cs deleted file mode 100644 index 3dbb2e6..0000000 --- a/BepInEx/Patches/GameObjects/AlmanacPlantMenu_Patch.cs +++ /dev/null @@ -1,88 +0,0 @@ -using HarmonyLib; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; -using UnityEngine.UI; -using static PvZ_Fusion_Translator__BepInEx_.FileLoader; -using static PvZ_Fusion_Translator__BepInEx_.Utils; -using static PvZ_Fusion_Translator__BepInEx_.Log; -using static AlmanacPlantBank; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(AlmanacPlantMenu))] - public static class AlmanacPlantMenu_Patch - { - [HarmonyPatch(nameof(AlmanacPlantMenu.Awake))] - [HarmonyPostfix] - private static void Awake(AlmanacPlantMenu __instance) - { - TMP_FontAsset font = FontStore.LoadTMPFont(Utils.Language.ToString()); - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren(true)) - { - bool isPlantName = text.gameObject.name.Contains("Name") && text.transform.parent.name != "Background"; - if (text.gameObject.name != "Description" && !isPlantName) - { - text.text = StringStore.TranslateText(text.text); - text.font = font; - text.autoSizeTextContainer = true; - } - } - - // skin button resize - - AlmanacPlantWindow window = __instance.window; - GameObject skinButton = window.skinButton; - GameObject skinTextObj = skinButton.transform.GetChild(0).gameObject; - GameObject skinShadowTextObj = skinTextObj.transform.GetChild(0).gameObject; - TextMeshProUGUI skinShadowText = skinShadowTextObj.GetComponent(); - skinShadowText.text = StringStore.TranslateText("换肤_S"); - skinButton.transform.localScale /= 1.75f; - skinButton.transform.localPosition = new Vector3(0.0f, 111.345f, 0.0f); - skinButton.transform.GetChild(1).Translate(new Vector3(-0.35f, 0)); - skinButton.transform.GetChild(2).Translate(new Vector3(0.35f, 0)); - } - - [HarmonyPatch(nameof(AlmanacPlantMenu.SearchChanged))] - [HarmonyPrefix] - public static bool SearchChanged(AlmanacPlantMenu __instance, ref TMP_InputField inputField) - { - string search = inputField.text; - if (search != StringStore.TranslateText("搜索") && search != "") - { - string currentLanguage = Utils.Language.ToString(); - string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); - string path = Path.Combine(almanacDir, "LawnStringsTranslate.json"); - string moddedPath = Path.Combine(almanacDir, "ModdedPlantsTranslate.json"); - - string json; - json = File.ReadAllText(path); - - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); - - PlantData plantData = JsonUtility.FromJson(json); - - Il2CppSystem.Collections.Generic.List searchedPlants = new(); - - foreach (PlantInfo plantInfo in plantData.plants) - { - if (plantInfo.name.ToLower().Contains(search.ToLower())) - { - searchedPlants.Add((PlantType)plantInfo.seedType); - } - } - - __instance.ShowPlants(searchedPlants); - - return false; - } - - return true; - } - } -} - diff --git a/BepInEx/Patches/GameObjects/AlmanacPlantWindow_Patch.cs b/BepInEx/Patches/GameObjects/AlmanacPlantWindow_Patch.cs deleted file mode 100644 index 5dc2db1..0000000 --- a/BepInEx/Patches/GameObjects/AlmanacPlantWindow_Patch.cs +++ /dev/null @@ -1,189 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using System; -using UnityEngine; -using UnityEngine.UI; -using System.IO; -using static PvZ_Fusion_Translator__BepInEx_.FileLoader; -using static PvZ_Fusion_Translator__BepInEx_.Log; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(AlmanacPlantWindow))] - public static class AlmanacPlantWindow_Patch - { - [HarmonyPatch(nameof(AlmanacPlantWindow.UpdateText))] - [HarmonyPostfix] - private static void UpdateText(AlmanacPlantWindow __instance) - { - try - { - if (__instance == null) - { - Log.LogWarning("[AlmanacPlantWindow_Patch] __instance is null"); - return; - } - - if (__instance.showedPlantName == null || __instance.showedPlantIntroduce == null || __instance.plantTextContent == null) - { - Log.LogWarning("[AlmanacPlantWindow_Patch] Required UI components are null"); - return; - } - - string currentLanguage = Utils.Language.ToString(); - string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); - string path = Path.Combine(almanacDir, "LawnStringsTranslate.json"); - string moddedPath = Path.Combine(almanacDir, "ModdedPlantsTranslate.json"); - - if (!File.Exists(path)) - { - Log.LogWarning($"[AlmanacPlantWindow_Patch] LawnStringsTranslate.json not found at: {path}"); - return; - } - - string json; - json = File.ReadAllText(path); - - bool hasAlmanacFont = false; - TMP_FontAsset almanacFontAsset = null; - if (FontStore.fontAssetDictSecondary != null && - (FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage + "_Almanac") || - FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage))) - almanacFontAsset = FontStore.LoadTMPFontAlmanac(currentLanguage); - hasAlmanacFont = almanacFontAsset != null; - - TMP_FontAsset fontAsset = null; - fontAsset = (hasAlmanacFont) ? FontStore.LoadTMPFontAlmanac(Utils.Language.ToString()) : FontStore.LoadTMPFont(Utils.Language.ToString()); - - AlmanacPlantBank.PlantData plantData = null; - - plantData = JsonUtility.FromJson(json); - - - bool foundMatch = false; - foreach (AlmanacPlantBank.PlantInfo plantInfo in plantData.plants) - { - if (plantInfo == null) continue; - if (plantInfo.seedType == (int)__instance.currentPlantType) - { - foundMatch = true; - try - { - if (__instance.showedPlantName != null) - { - foreach (TextMeshProUGUI text in __instance.showedPlantName) - { - if (text == null) continue; - text.autoSizeTextContainer = false; - string plantName = plantInfo.name ?? ""; - text.text = $"{Utils.RemoveSizeTags(plantName)} ({plantInfo.seedType})"; - text.font = fontAsset; - text.fontSizeMax = 21; - } - } - - if (__instance.showedPlantIntroduce != null) - { - string info = plantInfo.info ?? ""; - string introduce = plantInfo.introduce ?? ""; - char[] toTrim = Environment.NewLine.ToCharArray(); - __instance.showedPlantIntroduce.text = Utils.RemoveSizeTags(plantInfo.info) + "\n\n" + Utils.RemoveSizeTags(plantInfo.introduce) + "\n\n" + Utils.RemoveSizeTags(plantInfo.cost).TrimStart(toTrim) + "\n\n"; - __instance.showedPlantIntroduce.font = fontAsset; - __instance.showedPlantIntroduce.margin = new Vector4(6, 2, 12, 0); - __instance.showedPlantIntroduce.enableWordWrapping = true; - __instance.showedPlantIntroduce.overflowMode = TextOverflowModes.ScrollRect; - - Canvas.ForceUpdateCanvases(); - __instance.showedPlantIntroduce.ForceMeshUpdate(); - - if (__instance.plantTextContent != null) - { - float textHeight = __instance.showedPlantIntroduce.preferredHeight; - __instance.plantTextContent.sizeDelta = new Vector2(__instance.plantTextContent.sizeDelta.x, textHeight); - } - } - } - catch (Exception ex) - { - Log.LogError($"[AlmanacPlantWindow_Patch] Error updating plant info: {ex.Message}"); - } - break; - } - } - - if (!foundMatch && File.Exists(moddedPath)) - { - try - { - string moddedJson = File.ReadAllText(moddedPath); - if (!string.IsNullOrEmpty(moddedJson)) - { - AlmanacPlantBank.PlantData moddedPlantData = JsonUtility.FromJson(moddedJson); - if (moddedPlantData != null && moddedPlantData.plants != null) - { - foreach (AlmanacPlantBank.PlantInfo plantInfo in moddedPlantData.plants) - { - if (plantInfo == null) continue; - if (plantInfo.seedType == (int)__instance.currentPlantType) - { - try - { - if (__instance.showedPlantName != null) - { - foreach (TextMeshProUGUI text in __instance.showedPlantName) - { - if (text == null) continue; - text.autoSizeTextContainer = false; - string plantName = plantInfo.name ?? ""; - text.text = $"{Utils.RemoveSizeTags(plantName)} ({plantInfo.seedType})"; - text.font = fontAsset; - text.fontSizeMax = 21; - } - } - - if (__instance.showedPlantIntroduce != null) - { - string info = plantInfo.info ?? ""; - string introduce = plantInfo.introduce ?? ""; - char[] toTrim = Environment.NewLine.ToCharArray(); - __instance.showedPlantIntroduce.text = Utils.RemoveSizeTags(plantInfo.info) + "\n\n" + Utils.RemoveSizeTags(plantInfo.introduce) + "\n\n" + Utils.RemoveSizeTags(plantInfo.cost).TrimStart(toTrim) + "\n\n"; - __instance.showedPlantIntroduce.font = fontAsset; - __instance.showedPlantIntroduce.margin = new Vector4(6, 2, 12, 0); - __instance.showedPlantIntroduce.enableWordWrapping = true; - __instance.showedPlantIntroduce.overflowMode = TextOverflowModes.ScrollRect; - - Canvas.ForceUpdateCanvases(); - __instance.showedPlantIntroduce.ForceMeshUpdate(); - - if (__instance.plantTextContent != null) - { - float textHeight = __instance.showedPlantIntroduce.preferredHeight; - __instance.plantTextContent.sizeDelta = new Vector2(__instance.plantTextContent.sizeDelta.x, textHeight); - } - } - } - catch (Exception ex) - { - Log.LogError($"[AlmanacPlantWindow_Patch] Error updating modded plant info: {ex.Message}"); - } - break; - } - } - } - } - } - catch (Exception ex) - { - Log.LogWarning($"[AlmanacPlantWindow_Patch] Error reading ModdedPlantsTranslate.json: {ex.Message}"); - } - } - } - catch (Exception ex) - { - Log.LogError($"[AlmanacPlantWindow_Patch] Unexpected error in UpdateText: {ex.Message}\n{ex.StackTrace}"); - } - } - } -} - diff --git a/BepInEx/Patches/GameObjects/AlmanacZombieMenu_Patch.cs b/BepInEx/Patches/GameObjects/AlmanacZombieMenu_Patch.cs deleted file mode 100644 index e85aef2..0000000 --- a/BepInEx/Patches/GameObjects/AlmanacZombieMenu_Patch.cs +++ /dev/null @@ -1,31 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; -using static PvZ_Fusion_Translator__BepInEx_.Log; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(AlmanacZombieMenu))] - public static class AlmanacZombieMenu_Patch - { - [HarmonyPatch(nameof(AlmanacZombieMenu.Awake))] - [HarmonyPostfix] - private static void Awake(AlmanacZombieMenu __instance) - { - TMP_FontAsset font = FontStore.LoadTMPFont(Utils.Language.ToString()); - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren(true)) - { - bool isZombieName = text.gameObject.name.Contains("Name") && text.transform.parent.name != "Background"; - if (text.gameObject.name != "Description" && !isZombieName) - { - text.text = StringStore.TranslateText(text.text); - text.font = font; - text.autoSizeTextContainer = true; - } - } - } - } -} - diff --git a/BepInEx/Patches/GameObjects/AlmanacZombieWindow_Patch.cs b/BepInEx/Patches/GameObjects/AlmanacZombieWindow_Patch.cs deleted file mode 100644 index f20926a..0000000 --- a/BepInEx/Patches/GameObjects/AlmanacZombieWindow_Patch.cs +++ /dev/null @@ -1,187 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using System; -using UnityEngine; -using UnityEngine.UI; -using System.IO; -using static PvZ_Fusion_Translator__BepInEx_.FileLoader; -using static PvZ_Fusion_Translator__BepInEx_.Log; -using PvZ_Fusion_Translator__BepInEx_.Patches.Managers; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(AlmanacZombieWindow))] - public static class AlmanacZombieWindow_Patch - { - [HarmonyPatch(nameof(AlmanacZombieWindow.UpdateText))] - [HarmonyPostfix] - private static void UpdateText(AlmanacZombieWindow __instance) - { - try - { - string currentLanguage = Utils.Language.ToString(); - string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); - string path = Path.Combine(almanacDir, "ZombieStringsTranslate.json"); - string moddedPath = Path.Combine(almanacDir, "ModdedZombiesTranslate.json"); - - if (!File.Exists(path)) - { - Log.LogWarning($"[AlmanacZombieWindow_Patch] ZombieStringsTranslate.json not found at: {path}"); - return; - } - - string json; - json = File.ReadAllText(path); - - bool hasAlmanacFont = false; - TMP_FontAsset almanacFontAsset = null; - if (FontStore.fontAssetDictSecondary != null && - (FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage + "_Almanac") || - FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage))) - { - almanacFontAsset = FontStore.LoadTMPFontAlmanac(currentLanguage); - hasAlmanacFont = almanacFontAsset != null; - } - - TMP_FontAsset fontAsset = null; - fontAsset = (hasAlmanacFont) ? FontStore.LoadTMPFontAlmanac(Utils.Language.ToString()) : FontStore.LoadTMPFont(Utils.Language.ToString()); - - ZombieAlmanacData zombieAlmanacData = null; - zombieAlmanacData = JsonUtility.FromJson(json); - var zombieDataDic = ZombieDataManager.zombieDataDic; - - bool foundMatch = false; - foreach (ZombieInfo zombieInfo in zombieAlmanacData.zombies) - { - if (zombieInfo == null) continue; - if (zombieInfo.theZombieType == __instance.currentZombieType) - { - foundMatch = true; - try - { - if (__instance.showedZombieName != null) - { - foreach (TextMeshProUGUI text in __instance.showedZombieName) - { - if (text == null) continue; - text.autoSizeTextContainer = false; - string zombieName = zombieInfo.name ?? ""; - text.text = $"{Utils.RemoveSizeTags(zombieName)} ({(int)zombieInfo.theZombieType})"; - text.font = fontAsset; - text.fontSizeMax = 21; - } - } - - if (__instance.showedZombieIntroduce != null) - { - string info = zombieInfo.info ?? ""; - string introduce = zombieInfo.introduce ?? ""; - - ZombieDataManager.ZombieData zombieData = zombieDataDic[__instance.currentZombieType]; - - string spawnInfo = ""; - string spawnInfoFormat = StringStore.translationStringRegex["出怪等级: (\\d+)\\n出怪权重: (\\d+)"]; - if(spawnInfoFormat != null) - { - spawnInfo = string.Format(spawnInfoFormat, new object[] { zombieData.summonLevel, zombieData.summonWeight }) + "\n\n"; - } - - __instance.showedZombieIntroduce.text = Utils.RemoveSizeTags(info) + "\n\n" + spawnInfo + Utils.RemoveSizeTags(introduce) + "\n\n"; - __instance.showedZombieIntroduce.font = fontAsset; - __instance.showedZombieIntroduce.margin = new Vector4(3, 2, 12, 0); - __instance.showedZombieIntroduce.enableWordWrapping = true; - __instance.showedZombieIntroduce.overflowMode = TextOverflowModes.ScrollRect; - - Canvas.ForceUpdateCanvases(); - __instance.showedZombieIntroduce.ForceMeshUpdate(); - - if (__instance.zombieTextContent != null) - { - float textHeight = __instance.showedZombieIntroduce.preferredHeight; - __instance.zombieTextContent.sizeDelta = new Vector2(__instance.zombieTextContent.sizeDelta.x, textHeight); - } - } - } - catch (Exception ex) - { - Log.LogError($"[AlmanacZombieWindow_Patch] Error updating zombie info: {ex.Message}"); - } - break; - } - } - - if (!foundMatch && File.Exists(moddedPath)) - { - try - { - string moddedJson = File.ReadAllText(moddedPath); - if (!string.IsNullOrEmpty(moddedJson)) - { - ZombieAlmanacData moddedZombieData = JsonUtility.FromJson(moddedJson); - if (moddedZombieData != null && moddedZombieData.zombies != null) - { - foreach (ZombieInfo zombieInfo in moddedZombieData.zombies) - { - if (zombieInfo == null) continue; - if (zombieInfo.theZombieType == __instance.currentZombieType) - { - try - { - if (__instance.showedZombieName != null) - { - foreach (TextMeshProUGUI text in __instance.showedZombieName) - { - if (text == null) continue; - text.autoSizeTextContainer = false; - string zombieName = zombieInfo.name ?? ""; - text.text = $"{Utils.RemoveSizeTags(zombieName)} ({(int)zombieInfo.theZombieType})"; - text.font = fontAsset; - text.fontSizeMax = 21; - } - } - - if (__instance.showedZombieIntroduce != null) - { - string info = zombieInfo.info ?? ""; - string introduce = zombieInfo.introduce ?? ""; - __instance.showedZombieIntroduce.text = Utils.RemoveSizeTags(info) + "\n\n" + Utils.RemoveSizeTags(introduce) + "\n\n"; - __instance.showedZombieIntroduce.font = fontAsset; - __instance.showedZombieIntroduce.margin = new Vector4(3, 2, 12, 0); - __instance.showedZombieIntroduce.enableWordWrapping = true; - __instance.showedZombieIntroduce.overflowMode = TextOverflowModes.ScrollRect; - - Canvas.ForceUpdateCanvases(); - __instance.showedZombieIntroduce.ForceMeshUpdate(); - - if (__instance.zombieTextContent != null) - { - float textHeight = __instance.showedZombieIntroduce.preferredHeight; - __instance.zombieTextContent.sizeDelta = new Vector2(__instance.zombieTextContent.sizeDelta.x, textHeight); - } - } - } - catch (Exception ex) - { - Log.LogError($"[AlmanacZombieWindow_Patch] Error updating modded zombie info: {ex.Message}"); - } - break; - } - } - } - } - } - catch (Exception ex) - { - Log.LogWarning($"[AlmanacZombieWindow_Patch] Error reading ModdedZombiesTranslate.json: {ex.Message}"); - } - } - } - catch (Exception ex) - { - Log.LogError($"[AlmanacZombieWindow_Patch] Unexpected error in UpdateText: {ex.Message}\n{ex.StackTrace}"); - } - } - } -} - diff --git a/BepInEx/Patches/GameObjects/Almanac_Patch.cs b/BepInEx/Patches/GameObjects/Almanac_Patch.cs deleted file mode 100644 index 5ae5678..0000000 --- a/BepInEx/Patches/GameObjects/Almanac_Patch.cs +++ /dev/null @@ -1,49 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(Almanac))] - public static class Almanac_Patch - { - [HarmonyPatch(nameof(Almanac.Awake))] - [HarmonyPostfix] - private static void Awake(Almanac __instance) - { - TranslateAlmanacMenu(__instance); - } - - [HarmonyPatch(nameof(Almanac.OldAlmanac))] - [HarmonyPostfix] - private static void OldAlmanac(Almanac __instance) - { - TranslateAlmanacMenu(__instance); - } - - [HarmonyPatch(nameof(Almanac.AnimSwitch))] - [HarmonyPostfix] - private static void AnimSwitch(Almanac __instance) - { - TranslateAlmanacMenu(__instance); - } - - public static void TranslateAlmanacMenu(Almanac __instance) - { - TMP_FontAsset font = FontStore.LoadTMPFont(Utils.Language.ToString()); - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - if (text.text == "关闭") - { - text.text = StringStore.TranslateText("合上"); - } - else - { - text.text = StringStore.TranslateText(text.text); - } - text.font = font; - } - } - } -} - diff --git a/BepInEx/Patches/GameObjects/BaseMenu_Patch.cs b/BepInEx/Patches/GameObjects/BaseMenu_Patch.cs deleted file mode 100644 index 7d7bd47..0000000 --- a/BepInEx/Patches/GameObjects/BaseMenu_Patch.cs +++ /dev/null @@ -1,41 +0,0 @@ -using HarmonyLib; -using System.Collections.Generic; -using System.Linq; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(BaseMenu))] - public static class BaseMenu_Patch - { - [HarmonyPatch(nameof(BaseMenu.Awake))] - [HarmonyPostfix] - private static void Awake(BaseMenu __instance) - { - TranslateBaseMenu(__instance, "Level"); - TranslateBaseMenu(__instance, "Levels"); - TranslateBaseMenu(__instance, "CustomLevel"); - } - - public static void TranslateBaseMenu(BaseMenu __instance, string levelsName) - { - Transform levels = __instance.transform.Find(levelsName); - if (levels != null) - { - List children = levels.GetComponentsInChildren(true).ToList(); - foreach (Transform child in children) - { - if (child.name == "Nextpage" || child.name == "LastPage" || child.name == "BackToIndex") - { - StringStore.TranslateTextTransform(child); - } - } - - StringStore.TranslateTextTransform(__instance.transform.Find("Goback")); - StringStore.TranslateTextTransform(__instance.transform.Find("Switich")); - } - } - } -} diff --git a/BepInEx/Patches/GameObjects/Board_Patch.cs b/BepInEx/Patches/GameObjects/Board_Patch.cs deleted file mode 100644 index 149d36c..0000000 --- a/BepInEx/Patches/GameObjects/Board_Patch.cs +++ /dev/null @@ -1,27 +0,0 @@ -using HarmonyLib; -using System; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(Board))] - public static class Board_Patch - { - [HarmonyPatch(nameof(Board.Update))] - [HarmonyPostfix] - private static void Update(Board __instance) - { - foreach (SpriteRenderer spriteRenderer in __instance.GetComponentsInChildren()) - { - if (spriteRenderer.sprite != null) - { - if (TextureStore.spriteDict.ContainsKey(spriteRenderer.sprite.name) && spriteRenderer.drawMode != SpriteDrawMode.Sliced) - { - spriteRenderer.drawMode = SpriteDrawMode.Sliced; - } - } - } - } - } -} diff --git a/BepInEx/Patches/GameObjects/ButtonObjects/AbyssBuffButton_Patch.cs b/BepInEx/Patches/GameObjects/ButtonObjects/AbyssBuffButton_Patch.cs deleted file mode 100644 index 83a2ad1..0000000 --- a/BepInEx/Patches/GameObjects/ButtonObjects/AbyssBuffButton_Patch.cs +++ /dev/null @@ -1,53 +0,0 @@ -#if FIX -using System.Text.RegularExpressions; -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.ButtonObjects -{ - [HarmonyPatch(typeof(AbyssBuffButton))] - public static class AbyssBuffButton_Patch - { - [HarmonyPatch(nameof(AbyssBuffButton.SetType))] - [HarmonyPostfix] - private static void SetType(AbyssBuffButton __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - Regex regex = new Regex("([^\\s]+)\n价格:(\\d+)"); - - if (regex.IsMatch(__instance.description.text)) - { - Match match = regex.Match(__instance.description.text); - int groupCount = match.Groups.Count; - - List dynamicParts = []; - - for (int i = 1; i < groupCount; i++) - { - string groupValue = match.Groups[i].Value; - string translatedValue = StringStore.translationString.ContainsKey(groupValue) ? StringStore.translationString[groupValue] : groupValue; - dynamicParts.Add(translatedValue); - MelonLogger.Msg(translatedValue); - } - - __instance.description.text = string.Format(StringStore.translationStringRegex["([^\\s]+)\n价格:(\\d+)"], [.. dynamicParts]); - __instance.description.font = fontAsset; - } - } - - [HarmonyPatch(nameof(AbyssBuffButton.SetSold))] - [HarmonyPostfix] - private static void SetSold(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/BepInEx/Patches/GameObjects/ButtonObjects/AbyssCheckSellMenu_Patch.cs b/BepInEx/Patches/GameObjects/ButtonObjects/AbyssCheckSellMenu_Patch.cs deleted file mode 100644 index 264f419..0000000 --- a/BepInEx/Patches/GameObjects/ButtonObjects/AbyssCheckSellMenu_Patch.cs +++ /dev/null @@ -1,25 +0,0 @@ -//using HarmonyLib; -//using System; -//using PvZ_Fusion_Translator__BepInEx_.AssetStore; -//using UnityEngine; - -//namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.ButtonObjects -//{ -// [HarmonyPatch(typeof(AbyssCheckSellMenu))] -// public static class AbyssCheckSellMenu_Patch -// { -// [HarmonyPatch(nameof(AbyssCheckSellMenu.SellIcon))] -// [HarmonyPostfix] -// private static void SellIcon(AbyssCheckSellMenu __instance) -// { -// AbyssMenu2.Instance.UpdateIcons(); -// } - -// [HarmonyPatch(nameof(AbyssCheckSellMenu.MoveInBag))] -// [HarmonyPostfix] -// private static void MoveInBag(AbyssCheckSellMenu __instance) -// { -// AbyssMenu2.Instance.UpdateIcons(); -// } -// } -//} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/ButtonObjects/AbyssLevelEnter_Patch.cs b/BepInEx/Patches/GameObjects/ButtonObjects/AbyssLevelEnter_Patch.cs deleted file mode 100644 index 5e85488..0000000 --- a/BepInEx/Patches/GameObjects/ButtonObjects/AbyssLevelEnter_Patch.cs +++ /dev/null @@ -1,18 +0,0 @@ -using HarmonyLib; -using System; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.ButtonObjects -{ - [HarmonyPatch(typeof(AbyssLevelEnter))] - public static class AbyssLevelEnter_Patch - { - [HarmonyPatch(nameof(AbyssLevelEnter.SetLevel))] - [HarmonyPostfix] - private static void SetLevel(AbyssLevelEnter __instance) - { - __instance.levelName = StringStore.TranslateText(__instance.levelName); - } - } -} diff --git a/BepInEx/Patches/GameObjects/ButtonObjects/Advanture_Btn_Patch.cs b/BepInEx/Patches/GameObjects/ButtonObjects/Advanture_Btn_Patch.cs deleted file mode 100644 index b469518..0000000 --- a/BepInEx/Patches/GameObjects/ButtonObjects/Advanture_Btn_Patch.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Linq; -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) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - string originalKey = StringStore.translationString.FirstOrDefault(x => x.Value == txt.text).Key; - txt.text = (StringStore.translationString.ContainsKey(originalKey + "_MG")) ? StringStore.TranslateText(originalKey + "_MG") : StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/ButtonObjects/CustomLevelEnter_Patch.cs b/BepInEx/Patches/GameObjects/ButtonObjects/CustomLevelEnter_Patch.cs deleted file mode 100644 index 1342f06..0000000 --- a/BepInEx/Patches/GameObjects/ButtonObjects/CustomLevelEnter_Patch.cs +++ /dev/null @@ -1,27 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; -using System.Linq; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.ButtonObjects -{ - [HarmonyPatch(typeof(CustomLevelEnter))] - public static class CustomLevelEnter_Patch - { - [HarmonyPatch(nameof(CustomLevelEnter.Start))] - [HarmonyPostfix] - private static void Start(CustomLevelEnter __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - string originalKey = StringStore.translationString.FirstOrDefault(x => x.Value == txt.text).Key; - txt.text = (StringStore.translationString.ContainsKey(originalKey + "_IZ")) ? StringStore.TranslateText(originalKey + "_IZ") : StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } -} diff --git a/BepInEx/Patches/GameObjects/ButtonObjects/ExploreMakeSceneButton_Patch.cs b/BepInEx/Patches/GameObjects/ButtonObjects/ExploreMakeSceneButton_Patch.cs deleted file mode 100644 index 7b813d0..0000000 --- a/BepInEx/Patches/GameObjects/ButtonObjects/ExploreMakeSceneButton_Patch.cs +++ /dev/null @@ -1,20 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using PvZ_Fusion_Translator__BepInEx_; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.ButtonObjects -{ - [HarmonyPatch(typeof(ExploreMakeSceneButton))] - public class ExploreMakeSceneButton_Patch - { - [HarmonyPostfix] - [HarmonyPatch(nameof(ExploreMakeSceneButton.Start))] - public static void Start(ExploreMakeSceneButton __instance) - { - __instance.sceneText.text = (StringStore.translationString.ContainsKey(__instance.sceneText.text + "_FS")) ? StringStore.TranslateText(__instance.sceneText.text + "_FS") : StringStore.TranslateText(__instance.sceneText.text); - __instance.sceneText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/ButtonObjects/ExploreMakeZombieButton_Patch.cs b/BepInEx/Patches/GameObjects/ButtonObjects/ExploreMakeZombieButton_Patch.cs deleted file mode 100644 index 1429902..0000000 --- a/BepInEx/Patches/GameObjects/ButtonObjects/ExploreMakeZombieButton_Patch.cs +++ /dev/null @@ -1,20 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using PvZ_Fusion_Translator__BepInEx_; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.ButtonObjects -{ - [HarmonyPatch(typeof(ExploreMakeZombieButton))] - public class ExploreMakeZombieButton_Patch - { - [HarmonyPostfix] - [HarmonyPatch(nameof(ExploreMakeZombieButton.Start))] - public static void Start(ExploreMakeZombieButton __instance) - { - __instance.sceneText.text = Utils.GetZombieNameFromAlmanac(__instance.theZombieType); - __instance.sceneText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/ButtonObjects/InGameBtn_Patch.cs b/BepInEx/Patches/GameObjects/ButtonObjects/InGameBtn_Patch.cs deleted file mode 100644 index 52a196a..0000000 --- a/BepInEx/Patches/GameObjects/ButtonObjects/InGameBtn_Patch.cs +++ /dev/null @@ -1,41 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -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); - } - } - } - - foreach(TextMeshProUGUI text in __instance.transform.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - } -} diff --git a/BepInEx/Patches/GameObjects/ButtonObjects/MainMenu_Btn_Patch.cs b/BepInEx/Patches/GameObjects/ButtonObjects/MainMenu_Btn_Patch.cs deleted file mode 100644 index 15b67f5..0000000 --- a/BepInEx/Patches/GameObjects/ButtonObjects/MainMenu_Btn_Patch.cs +++ /dev/null @@ -1,32 +0,0 @@ -using HarmonyLib; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.ButtonObjects -{ - [HarmonyPatch(typeof(MainMenu_Btn))] - public static class MainMenu_Btn_Patch - { - //[HarmonyPatch(nameof(MainMenu_Btn.OnMouseEnter))] - //[HarmonyPostfix] - //private static void OnMouseEnter(MainMenu_Btn __instance) - //{ - // string textToShow = null; - - // if (__instance.transform.parent.name == "recipe") - // { - // textToShow = "探索模式"; - // } - // else if (__instance.name == "mysterious") - // { - // textToShow = "神秘模式"; - // } - - // if (textToShow != null) - // { - // InGameText.Instance.ShowText(textToShow, 2.0f); - // } - //} - } -} - - diff --git a/BepInEx/Patches/GameObjects/ButtonObjects/NormalBtn_Patch.cs b/BepInEx/Patches/GameObjects/ButtonObjects/NormalBtn_Patch.cs deleted file mode 100644 index 79ad47d..0000000 --- a/BepInEx/Patches/GameObjects/ButtonObjects/NormalBtn_Patch.cs +++ /dev/null @@ -1,26 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.ButtonObjects -{ - [HarmonyPatch(typeof(NormalBtn))] - public class NormalBtn_Patch - { - [HarmonyPostfix] - [HarmonyPatch(nameof(NormalBtn.OnMouseUpAsButton))] - public static void OnMouseUpAsButton(NormalBtn __instance) - { - if (__instance.transform.childCount > 0) - { - Transform banTransform = __instance.transform.GetChild(0); - if (banTransform != null) - { - banTransform.GetComponent().text = StringStore.TranslateText(banTransform.GetComponent().text); - } - } - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs b/BepInEx/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs deleted file mode 100644 index 6c79998..0000000 --- a/BepInEx/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs +++ /dev/null @@ -1,345 +0,0 @@ -#if MULTI_LANGUAGE -using HarmonyLib; -using System.Collections.Generic; -using System; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; -using UnityEngine.UIElements; -using Object = UnityEngine.Object; -using BepInEx.Configuration; -using BepInEx; -using UnityEngine.Experimental.Rendering.RenderGraphModule; -using BepInEx.Unity.IL2CPP.Utils; -using Unity.VisualScripting.FullSerializer; - -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 Utils.ToggleEnum? Toggle { get; set; } // Null if it's the "Next" button - public bool IsNextButton { get; set; } - public bool shifted = false; -} - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.ButtonObjects -{ - internal class OptLanguageBtn_Patch - { - public static Dictionary LanguageBtnDict = new(); - public static Dictionary ToggleBtnDict = new(); - private static bool buttonsCreated = false; - private static bool togglesCreated = false; - private static OptionBtn cachedTemplateButton; - private static OptionBtn cachedTemplateToggleButton; - - private const float startX = 4.3241f + 2.56f; - private const float startY = 2.7769f; - private const float ySpacing = 1.2505f; - - private const float toggleStartX = 4.3241f; - private const float toggleStartY = -2.2251f; - - private static List AvailableLanguages; - private static List AvailableToggles; - private const int LanguagesPerPage = 5; - private static int currentPage = 0; - private static OptionBtn[] buttonSlots = new OptionBtn[6]; // 5 language buttons + 1 next button - private static OptionBtn[] toggleSlots = new OptionBtn[2]; - - 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(); - } - - public static void CreateToggleButtons(OptionBtn templateButton) - { - if (togglesCreated) return; - togglesCreated = true; - cachedTemplateToggleButton = templateButton; - - AvailableToggles = Enum.GetValues(typeof(Utils.ToggleEnum)) - .Cast() - .Where(lang => lang != Utils.ToggleEnum.TOGGLE_END) - .ToList(); - - for (int i = 0; i < 2; i++) - { - var newButton = Object.Instantiate(templateButton, templateButton.transform.parent); - newButton.optionType = 100 + i; - - float yPos = toggleStartY - i * ySpacing; - Vector3 pos = new(toggleStartX, yPos); - newButton.transform.position = pos; - - toggleSlots[i] = newButton; - - ToggleBtnDict[newButton.GetInstanceID()] = new OptionButtonData - { - Button = newButton, - Position = pos - }; - } - - UpdatePage(); - } - - private static void UpdatePage() - { - int startIndex = currentPage * LanguagesPerPage; - int langCount = AvailableLanguages.Count; - int toggleCount = (togglesCreated) ? AvailableToggles.Count : 0; - - 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); - } - } - - if (togglesCreated) - { - for (int i = 0; i < 2; i++) - { - var btn = toggleSlots[i]; - var data = ToggleBtnDict[btn.GetInstanceID()]; - - if (i < toggleCount) - { - var toggle = AvailableToggles[i]; - data.Toggle = toggle; - data.IsNextButton = false; - btn.gameObject.SetActive(true); - UpdateButtonText(btn, toggle.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, float yShift = 0.0f) - { - var child = button.transform.GetChild(0); - if (child != null) - { - var text = child.GetComponent(); - if (text != null) - { - text.text = message; - OptionButtonData data; - bool isToggle = ToggleBtnDict.TryGetValue(button.GetInstanceID(), out data); - - if(isToggle) - { - text.transform.position = new Vector3(text.transform.position.x, text.transform.position.y + (ToggleBtnDict[button.GetInstanceID()].shifted ? 0.0f : yShift), text.transform.position.z); - ToggleBtnDict[button.GetInstanceID()].shifted = true; - } - else - { - text.transform.position = new Vector3(text.transform.position.x, text.transform.position.y + (LanguageBtnDict[button.GetInstanceID()].shifted ? 0.0f : yShift), text.transform.position.z); - LanguageBtnDict[button.GetInstanceID()].shifted = true; - } - } - child.gameObject.SetActive(true); - - System.Threading.Tasks.Task.Delay(1000).ContinueWith(_ => - { - if (button != null && child != null && child.gameObject.activeSelf) - { - child.gameObject.SetActive(false); - } - }); - } - } - - private static void ToggleCustomAssets(string type) - { - if (type != "Textures" && type != "Audio") return; - - if (type == "Textures") - { - ConfigEntry customTexturesEntry; - Core.Instance.Config.TryGetEntry(new ConfigDefinition("PvZ_Fusion_Translator", "DefaultTextures"), out customTexturesEntry); - customTexturesEntry.BoxedValue = !customTexturesEntry.Value; // Toggle the config value - TextureStore.Reload(); - Coroutine replaceTextureRoutine = Core.MonoInstance.StartCoroutine(TextureStore.ReplaceTexturesCoroutine()); - } - - if (type == "Audio") - { - ConfigEntry customAudioEntry; - Core.Instance.Config.TryGetEntry(new ConfigDefinition("PvZ_Fusion_Translator", "DefaultAudio"), out customAudioEntry); - customAudioEntry.BoxedValue = !customAudioEntry.Value; // Toggle the config value - } - Core.Instance.Config.Save(); - } - - [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; - togglesCreated = false; - CreateLanguageButtons(__instance); - CreateToggleButtons(__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!"); - } - } - } - - if (ToggleBtnDict.TryGetValue(__instance.GetInstanceID(), out var toggleData)) - { - string toggleType = toggleData.Toggle.ToString(); - ToggleCustomAssets(toggleType); - if (toggleType == "Textures") - { - FlashMessage(toggleData.Button, "Toggled custom textures!", 0.1f); - } - else if (toggleType == "Audio") - { - FlashMessage(toggleData.Button, "Toggled custom audio!", 0.1f); - } - } - } - - [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; - } - - if (ToggleBtnDict.TryGetValue(__instance.GetInstanceID(), out var toggleData)) - { - toggleData.Button.transform.position = toggleData.Position; - } - } - } - } -} -#endif \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/ButtonObjects/OptionBtn_Patch.cs b/BepInEx/Patches/GameObjects/ButtonObjects/OptionBtn_Patch.cs deleted file mode 100644 index 87f3e66..0000000 --- a/BepInEx/Patches/GameObjects/ButtonObjects/OptionBtn_Patch.cs +++ /dev/null @@ -1,69 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -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/BepInEx/Patches/GameObjects/ButtonObjects/PVPPotBtn_Patch.cs b/BepInEx/Patches/GameObjects/ButtonObjects/PVPPotBtn_Patch.cs deleted file mode 100644 index bb07b21..0000000 --- a/BepInEx/Patches/GameObjects/ButtonObjects/PVPPotBtn_Patch.cs +++ /dev/null @@ -1,42 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -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/BepInEx/Patches/GameObjects/ButtonObjects/PauseMenu_Btn_Patch.cs b/BepInEx/Patches/GameObjects/ButtonObjects/PauseMenu_Btn_Patch.cs deleted file mode 100644 index e110b2f..0000000 --- a/BepInEx/Patches/GameObjects/ButtonObjects/PauseMenu_Btn_Patch.cs +++ /dev/null @@ -1,15 +0,0 @@ -using HarmonyLib; -using System; -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/BepInEx/Patches/GameObjects/ButtonObjects/SaveMenuBtn_Patch.cs b/BepInEx/Patches/GameObjects/ButtonObjects/SaveMenuBtn_Patch.cs deleted file mode 100644 index b6b8df4..0000000 --- a/BepInEx/Patches/GameObjects/ButtonObjects/SaveMenuBtn_Patch.cs +++ /dev/null @@ -1,24 +0,0 @@ -#if FIX -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.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/BepInEx/Patches/GameObjects/ButtonObjects/UIButton_Patch.cs b/BepInEx/Patches/GameObjects/ButtonObjects/UIButton_Patch.cs deleted file mode 100644 index 0de74e2..0000000 --- a/BepInEx/Patches/GameObjects/ButtonObjects/UIButton_Patch.cs +++ /dev/null @@ -1,85 +0,0 @@ -using HarmonyLib; -using TMPro; -using System; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; -using UnityEngine.UI; -using UnityEngine.UIElements; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(UIButton))] - public static class UIButton_Patch - { - [HarmonyPatch(typeof(UIButton), nameof(UIButton.Start))] - [HarmonyPostfix] - public static void Start(UIButton __instance) - { - if (__instance.transform.childCount >= 2) - { - TMP_FontAsset font = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI text in __instance.transform.GetComponentsInChildren()) - { - if (__instance.transform.name == "Goback") - { - text.text = "合上"; - } - text.text = StringStore.TranslateText(text.text); - text.font = font; - } - } - else - { - StringStore.TranslateTextTransform(__instance.transform); - if (__instance.transform.name == "Goback") - { - foreach (TextMeshProUGUI text in __instance.transform.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText("合上"); - } - } - } - } - - [HarmonyPatch(nameof(UIButton.OnMouseUpAsButton))] - [HarmonyPostfix] - public static void Postfix_OnMouseUpAsButton(UIButton __instance) - { - try - { - if (__instance.transform.childCount >= 2) - { - if (__instance.name == "EditMode") - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - TextMeshProUGUI text = __instance.transform.GetChild(0).GetComponent(); - TextMeshProUGUI[] extraTexts = __instance.transform.GetChild(1).GetComponentsInChildren(); - - text.text = StringStore.TranslateText(text.text, false); - text.font = fontAsset; - - foreach (TextMeshProUGUI extraText in extraTexts) - { - extraText.text = StringStore.TranslateText(extraText.text, false); - extraText.font = fontAsset; - } - } - else - { - TextMeshProUGUI text = __instance.transform.GetChild(0).GetComponent(); - TextMeshProUGUI textShadow = __instance.transform.GetChild(1).GetComponent(); - - text.text = StringStore.TranslateText(text.text, false); - textShadow.text = StringStore.TranslateText(textShadow.text, false); - - text.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - textShadow.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } - } - catch (Exception) { } - } - } -} diff --git a/BepInEx/Patches/GameObjects/Close_Patch.cs b/BepInEx/Patches/GameObjects/Close_Patch.cs deleted file mode 100644 index 2df6f37..0000000 --- a/BepInEx/Patches/GameObjects/Close_Patch.cs +++ /dev/null @@ -1,52 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -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/BepInEx/Patches/GameObjects/CrisisZombieWindow_Patch.cs b/BepInEx/Patches/GameObjects/CrisisZombieWindow_Patch.cs deleted file mode 100644 index 88b3411..0000000 --- a/BepInEx/Patches/GameObjects/CrisisZombieWindow_Patch.cs +++ /dev/null @@ -1,37 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; -using System.Text.RegularExpressions; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(CrisisZombieWindow))] - public static class CrisisZombieWindow_Patch - { - [HarmonyPatch(nameof(CrisisZombieWindow.Start))] - [HarmonyPostfix] - private static void Start(CrisisZombieWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - - [HarmonyPatch(nameof(CrisisZombieWindow.SetZombieType))] - [HarmonyPostfix] - private static void SetZombieType(CrisisZombieWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - } -} diff --git a/BepInEx/Patches/GameObjects/CustomSettings_Patch.cs b/BepInEx/Patches/GameObjects/CustomSettings_Patch.cs deleted file mode 100644 index a89481b..0000000 --- a/BepInEx/Patches/GameObjects/CustomSettings_Patch.cs +++ /dev/null @@ -1,24 +0,0 @@ -using HarmonyLib; -using System; -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/BepInEx/Patches/GameObjects/CustomSun_Patch.cs b/BepInEx/Patches/GameObjects/CustomSun_Patch.cs deleted file mode 100644 index 757ba73..0000000 --- a/BepInEx/Patches/GameObjects/CustomSun_Patch.cs +++ /dev/null @@ -1,45 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -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/BepInEx/Patches/GameObjects/EveBuffMenu_Patch.cs b/BepInEx/Patches/GameObjects/EveBuffMenu_Patch.cs deleted file mode 100644 index 68beceb..0000000 --- a/BepInEx/Patches/GameObjects/EveBuffMenu_Patch.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Text.RegularExpressions; -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(EveBuffMenu))] - public static class EveBuffMenu_Patch - { - [HarmonyPatch(nameof(EveBuffMenu.Start))] - [HarmonyPostfix] - private static void Start(EveBuffMenu __instance) - { - foreach (EveOptionWindow window in __instance.windows) - { - EveOptionWindow_Patch.TranslateEveOptionWindow(window); - } - - foreach (TextMeshProUGUI text in __instance.quitButton.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText("合上"); - } - } - - [HarmonyPatch(nameof(EveBuffMenu.InitWindows))] - [HarmonyPostfix] - private static void InitWindows(EveBuffMenu __instance) - { - foreach (EveOptionWindow window in __instance.windows) - { - EveOptionWindow_Patch.TranslateEveOptionWindow(window); - } - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/EveOptionWindow_Patch.cs b/BepInEx/Patches/GameObjects/EveOptionWindow_Patch.cs deleted file mode 100644 index f751dcd..0000000 --- a/BepInEx/Patches/GameObjects/EveOptionWindow_Patch.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.Text.RegularExpressions; -using HarmonyLib; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using TMPro; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(EveOptionWindow))] - public static class EveOptionWindow_Patch - { - [HarmonyPatch(nameof(EveOptionWindow.SetType))] - [HarmonyPostfix] - private static void SetType(EveOptionWindow __instance) - { - TranslateEveOptionWindow(__instance); - } - - [HarmonyPatch(nameof(EveOptionWindow.OnAnimOver))] - [HarmonyPostfix] - private static void OnAnimOver(EveOptionWindow __instance) - { - TranslateEveOptionWindow(__instance); - } - - [HarmonyPatch(nameof(EveOptionWindow.SelectedByRow))] - [HarmonyPostfix] - private static void SelectedByRow(EveOptionWindow __instance) - { - TranslateEveOptionWindow(__instance); - } - - public static void TranslateEveOptionWindow(EveOptionWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - - foreach (TextMeshProUGUI text in __instance.buttonText) - { - text.text = StringStore.TranslateText(text.text); - text.font = fontAsset; - } - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/ExploreEnterWindow_Patch.cs b/BepInEx/Patches/GameObjects/ExploreEnterWindow_Patch.cs deleted file mode 100644 index f0d6b94..0000000 --- a/BepInEx/Patches/GameObjects/ExploreEnterWindow_Patch.cs +++ /dev/null @@ -1,66 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; -using System.Text.RegularExpressions; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(ExploreEnterWindow))] - public static class ExploreEnterWindow_Patch - { - [HarmonyPatch(nameof(ExploreEnterWindow.Awake))] - [HarmonyPostfix] - private static void Awake(ExploreEnterWindow __instance) - { - PlantType thePlantType = (PlantType)__instance.selfType; - - __instance.nameText.text = Utils.GetPlantNameFromAlmanac(thePlantType); - if (__instance.nameText.text == "") - { - __instance.nameText.text = StringStore.TranslateText(__instance.nameText.text); - } - __instance.nameText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - - [HarmonyPatch(nameof(ExploreEnterWindow.SetInfo))] - [HarmonyPostfix] - private static void SetInfo(ExploreEnterWindow __instance) - { - PlantType thePlantType = (PlantType)__instance.selfType; - - __instance.nameText.text = Utils.GetPlantNameFromAlmanac(thePlantType); - if (__instance.nameText.text == "") - { - __instance.nameText.text = StringStore.TranslateText(__instance.nameText.text); - } - __instance.nameText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - - [HarmonyPatch(nameof(ExploreEnterWindow.SetIcon))] - [HarmonyPostfix] - private static void SetIcon(ExploreEnterWindow __instance) - { - PlantType thePlantType = (PlantType)__instance.selfType; - - __instance.nameText.text = Utils.GetPlantNameFromAlmanac(thePlantType); - if (__instance.nameText.text == "") - { - __instance.nameText.text = StringStore.TranslateText(__instance.nameText.text); - } - __instance.nameText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - - [HarmonyPatch(nameof(ExploreEnterWindow.SetDisable))] - [HarmonyPostfix] - private static void SetDisable(ExploreEnterWindow __instance) - { - if (__instance.disabled) - { - __instance.nameText.text = StringStore.TranslateText("敬请期待"); - } - - __instance.nameText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } -} diff --git a/BepInEx/Patches/GameObjects/ExploreMakeMenu_Patch.cs b/BepInEx/Patches/GameObjects/ExploreMakeMenu_Patch.cs deleted file mode 100644 index b2d941e..0000000 --- a/BepInEx/Patches/GameObjects/ExploreMakeMenu_Patch.cs +++ /dev/null @@ -1,79 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using PvZ_Fusion_Translator__BepInEx_; -using System.Text.RegularExpressions; -using UnityEngine; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.IO; -using System.Text.Json; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(ExploreMakeMenu))] - public static class ExploreMakeMenu_Patch - { - [HarmonyPatch(nameof(ExploreMakeMenu.Awake))] - [HarmonyPostfix] - private static void Awake(ExploreMakeMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - - [HarmonyPatch(nameof(ExploreMakeMenu.InitMenu))] - [HarmonyPostfix] - private static void InitMenu(ExploreMakeMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - if(txt.text.Contains("关卡制作中:")) - { - string plantName = Utils.GetPlantNameFromAlmanac(txt.text.Split(":")[1]); - txt.text = String.Format(StringStore.translationStringRegex["关卡制作中:([^\\s]+)"], plantName); - } - else - { - txt.text = StringStore.TranslateText(txt.text); - } - } - } - - [HarmonyPatch(nameof(ExploreMakeMenu.ViewScene))] - [HarmonyPostfix] - private static void ViewScene(ExploreMakeMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - - [HarmonyPatch(nameof(ExploreMakeMenu.InitZombieButtons))] - [HarmonyPostfix] - private static void InitZombieButtons(ExploreMakeMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/ExploreMenu_Patch.cs b/BepInEx/Patches/GameObjects/ExploreMenu_Patch.cs deleted file mode 100644 index 795137f..0000000 --- a/BepInEx/Patches/GameObjects/ExploreMenu_Patch.cs +++ /dev/null @@ -1,48 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(ExploreMenu))] - public static class ExploreMenu_Patch - { - [HarmonyPatch(nameof(ExploreMenu.Awake))] - [HarmonyPostfix] - private static void Awake(ExploreMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - } - - Transform randomLevelTextTransform = __instance.transform.FindChild("RandomLevel"); - //foreach (TextMeshProUGUI txt in randomLevelTextTransform.GetComponentsInChildren()) - //{ - // if (txt.name.Contains("Text (TMP)")) - // { - // txt.autoSizeTextContainer = true; - // if (txt.name == "Text (TMP)") - // { - // txt.transform.localPosition = new Vector3(94.4225f, -45.1565f, 0f); - // } - // } - //} - } - - [HarmonyPatch(nameof(ExploreMenu.UpdateWindows))] - [HarmonyPostfix] - private static void UpdateWindows(ExploreMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - } - } - } -} diff --git a/BepInEx/Patches/GameObjects/FruitNinjaSelectWindow_Patch.cs b/BepInEx/Patches/GameObjects/FruitNinjaSelectWindow_Patch.cs deleted file mode 100644 index 6f36532..0000000 --- a/BepInEx/Patches/GameObjects/FruitNinjaSelectWindow_Patch.cs +++ /dev/null @@ -1,37 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; -using System.Text.RegularExpressions; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(FruitNinjaSelectWindow))] - public static class FruitNinjaSelectWindow_Patch - { - [HarmonyPatch(nameof(FruitNinjaSelectWindow.SetType))] - [HarmonyPostfix] - private static void SetType(FruitNinjaSelectWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - - [HarmonyPatch(nameof(FruitNinjaSelectWindow.OnAnimOver))] - [HarmonyPostfix] - private static void OnAnimOver(FruitNinjaSelectWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - } -} diff --git a/BepInEx/Patches/GameObjects/GardenBagMenu_Patch.cs b/BepInEx/Patches/GameObjects/GardenBagMenu_Patch.cs deleted file mode 100644 index 5c555a1..0000000 --- a/BepInEx/Patches/GameObjects/GardenBagMenu_Patch.cs +++ /dev/null @@ -1,51 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(GardenBagMenu))] - public static class GardenBagMenu_Patch - { - [HarmonyPatch(nameof(GardenBagMenu.SetTreasureCards))] - [HarmonyPostfix] - private static void SetTreasureCards(GardenBagMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - if(txt.transform.parent.name.Contains("Close")) - { - txt.text = StringStore.TranslateText("合上"); - } - else - { - txt.text = StringStore.TranslateText(txt.text); - } - txt.font = fontAsset; - } - } - - [HarmonyPatch(nameof(GardenBagMenu.SetTreasureCard))] - [HarmonyPostfix] - private static void SetTreasureCard(GardenBagMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - if (txt.transform.parent.name.Contains("Close")) - { - txt.text = StringStore.TranslateText("合上"); - } - else - { - txt.text = StringStore.TranslateText(txt.text); - } - txt.font = fontAsset; - } - } - } -} diff --git a/BepInEx/Patches/GameObjects/GardenCard_Patch.cs b/BepInEx/Patches/GameObjects/GardenCard_Patch.cs deleted file mode 100644 index ed7de7d..0000000 --- a/BepInEx/Patches/GameObjects/GardenCard_Patch.cs +++ /dev/null @@ -1,24 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(GardenCard))] - public static class GardenCard_Patch - { - [HarmonyPatch(nameof(GardenCard.Start))] - [HarmonyPostfix] - private static void Start(GardenCard __instance) - { - __instance.text.text = StringStore.TranslateText(__instance.text.text).Replace("26", "16"); - } - - [HarmonyPatch(nameof(GardenCard.ChangeCardSprite))] - [HarmonyPostfix] - private static void ChangeCardSprite(GardenCard __instance) - { - __instance.text.text = StringStore.TranslateText(__instance.text.text).Replace("26", "16"); - } - } -} diff --git a/BepInEx/Patches/GameObjects/GardenPlant_Patch.cs b/BepInEx/Patches/GameObjects/GardenPlant_Patch.cs deleted file mode 100644 index 5d8ea61..0000000 --- a/BepInEx/Patches/GameObjects/GardenPlant_Patch.cs +++ /dev/null @@ -1,28 +0,0 @@ -using HarmonyLib; -using System; -using System.Text.RegularExpressions; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(GardenPlant))] - public static class GardenPlant_Patch - { - [HarmonyPatch(nameof(GardenPlant.Start))] - [HarmonyPostfix] - private static void Start(GardenPlant __instance) - { - __instance.infoText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - __instance.infoText.text = StringStore.TranslateText(__instance.infoText.text); - } - - [HarmonyPatch(nameof(GardenPlant.UpdateInfo))] - [HarmonyPostfix] - private static void UpdateInfo(GardenPlant __instance) - { - - __instance.infoText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - __instance.infoText.text = StringStore.TranslateText(__instance.infoText.text); - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/MainMenu_Patch.cs b/BepInEx/Patches/GameObjects/MainMenu_Patch.cs deleted file mode 100644 index 8d00da2..0000000 --- a/BepInEx/Patches/GameObjects/MainMenu_Patch.cs +++ /dev/null @@ -1,24 +0,0 @@ -using HarmonyLib; -using System; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(MainMenu))] - public class MainMenu_Patch - { - private static bool _warningShown = false; - - [HarmonyPostfix] - [HarmonyPatch(nameof(MainMenu.AnimOver))] - private static void AnimOver(MainMenu __instance) - { - if (_warningShown || NoticeMenu.Instance == null) - return; - - WarningStore.WarningReload(Utils.Language, NoticeMenu.Instance); - _warningShown = true; - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/MinorObjects/AbyssGoods_Patch.cs b/BepInEx/Patches/GameObjects/MinorObjects/AbyssGoods_Patch.cs deleted file mode 100644 index 0c0e3b6..0000000 --- a/BepInEx/Patches/GameObjects/MinorObjects/AbyssGoods_Patch.cs +++ /dev/null @@ -1,21 +0,0 @@ -using HarmonyLib; -using System; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects -{ - [HarmonyPatch(typeof(AbyssGoods))] - public static class AbyssGoods_Patch - { - [HarmonyPostfix] - [HarmonyPatch(nameof(AbyssGoods.Start))] - private static void Start(AbyssGoods __instance) - { - __instance.costText.text = StringStore.TranslateText(__instance.costText.text, false); - __instance.costText_shadow.text = StringStore.TranslateText(__instance.costText_shadow.text, false); - __instance.hasText.text = StringStore.TranslateText(__instance.hasText.text, false); - __instance.hasText_shadow.text = StringStore.TranslateText(__instance.hasText_shadow.text, false); - } - } -} diff --git a/BepInEx/Patches/GameObjects/MinorObjects/Brain_Patch.cs b/BepInEx/Patches/GameObjects/MinorObjects/Brain_Patch.cs deleted file mode 100644 index ed896cf..0000000 --- a/BepInEx/Patches/GameObjects/MinorObjects/Brain_Patch.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System.Text.RegularExpressions; -using HarmonyLib; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using TMPro; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects -{ - [HarmonyPatch(typeof(Brain))] - public static class Brain_Patch - { - [HarmonyPostfix] - [HarmonyPatch(nameof(Brain.Awake))] - private static void Awake(Brain __instance) - { - // reposition original points - Transform pointsTransform = __instance.points.transform; - GameObject pointsObject = __instance.points.gameObject; - pointsTransform.position = new Vector3(-6.5f, pointsTransform.position.y, pointsTransform.position.z); - - // instantiate and move new shadow - GameObject pointsShadowObject = UnityEngine.Object.Instantiate(pointsObject, parent: pointsTransform); - pointsShadowObject.SetActive(true); - Transform pointsShadowTransform = pointsShadowObject.transform; - pointsShadowTransform.position = new Vector3(-6.485f, pointsTransform.position.y - 0.015f, pointsTransform.position.z); - - // set points text - TextMeshPro pointsShadowText = pointsShadowObject.GetComponent(); - pointsShadowText.text = __instance.points.text; - pointsShadowText.sortingOrder -= 2; - pointsShadowText.color = Color.black; - } - - [HarmonyPostfix] - [HarmonyPatch(nameof(Brain.Update))] - private static void Update(Brain __instance) - { - if (__instance.transform.Find("Points").GetChild(0) != null) - { - TextMeshPro shadowText = __instance.transform.Find("Points").GetChild(0).GetComponent(); - shadowText.text = __instance.points.text; - } - } - - [HarmonyPostfix] - [HarmonyPatch(nameof(Brain.WinAction))] - private static void WinAction(Brain __instance) - { - if (__instance.transform.Find("Points").GetChild(0) != null) - { - TextMeshPro shadowText = __instance.transform.Find("Points").GetChild(0).GetComponent(); - shadowText.text = __instance.points.text; - } - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/MinorObjects/DY_Patch.cs b/BepInEx/Patches/GameObjects/MinorObjects/DY_Patch.cs deleted file mode 100644 index 6659ddd..0000000 --- a/BepInEx/Patches/GameObjects/MinorObjects/DY_Patch.cs +++ /dev/null @@ -1,18 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -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); - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/MinorObjects/Jigsaw_Patch.cs b/BepInEx/Patches/GameObjects/MinorObjects/Jigsaw_Patch.cs deleted file mode 100644 index acc26c1..0000000 --- a/BepInEx/Patches/GameObjects/MinorObjects/Jigsaw_Patch.cs +++ /dev/null @@ -1,30 +0,0 @@ -using HarmonyLib; -using System; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(JigsawClip))] - public static class JigsawClip_Patch - { - [HarmonyPostfix] - [HarmonyPatch(nameof(JigsawClip.Awake))] - private static void Postfix_Awake(JigsawClip __instance) - { - if (!__instance || !__instance.description) return; - - StringStore.TranslateTextUI(__instance.description); - } - [HarmonyPostfix] - [HarmonyPatch(nameof(JigsawClip.Update))] - private static void Postfix_Update(JigsawClip __instance) - { - if (!__instance || !__instance.description) return; - - if (__instance.description.text != StringStore.TranslateText(__instance.description.text)) - { - StringStore.TranslateTextUI(__instance.description); - } - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/MinorObjects/LanternUmbrella_Patch.cs b/BepInEx/Patches/GameObjects/MinorObjects/LanternUmbrella_Patch.cs deleted file mode 100644 index e4c913c..0000000 --- a/BepInEx/Patches/GameObjects/MinorObjects/LanternUmbrella_Patch.cs +++ /dev/null @@ -1,18 +0,0 @@ -using HarmonyLib; -using System; -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); - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/MinorObjects/MagnetBox_Patch.cs b/BepInEx/Patches/GameObjects/MinorObjects/MagnetBox_Patch.cs deleted file mode 100644 index 3ff15e8..0000000 --- a/BepInEx/Patches/GameObjects/MinorObjects/MagnetBox_Patch.cs +++ /dev/null @@ -1,17 +0,0 @@ -using HarmonyLib; -using System; -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); - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/MinorObjects/MagnetInterface_Patch.cs b/BepInEx/Patches/GameObjects/MinorObjects/MagnetInterface_Patch.cs deleted file mode 100644 index 4263677..0000000 --- a/BepInEx/Patches/GameObjects/MinorObjects/MagnetInterface_Patch.cs +++ /dev/null @@ -1,17 +0,0 @@ -using HarmonyLib; -using System; -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); - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/MinorObjects/Money_Patch.cs b/BepInEx/Patches/GameObjects/MinorObjects/Money_Patch.cs deleted file mode 100644 index 312d327..0000000 --- a/BepInEx/Patches/GameObjects/MinorObjects/Money_Patch.cs +++ /dev/null @@ -1,18 +0,0 @@ -using HarmonyLib; -using System; -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); - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/MinorObjects/Plant_Patch.cs b/BepInEx/Patches/GameObjects/MinorObjects/Plant_Patch.cs deleted file mode 100644 index cd60f9f..0000000 --- a/BepInEx/Patches/GameObjects/MinorObjects/Plant_Patch.cs +++ /dev/null @@ -1,48 +0,0 @@ -using HarmonyLib; -using System; -using System.Collections.Generic; -using System.Text.RegularExpressions; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects -{ - [HarmonyPatch(typeof(Plant))] - public static class Plant_Patch - { - [HarmonyPostfix] - [HarmonyPatch(nameof(Plant.Awake))] - private static void Awake(Plant __instance) - { - if (!(__instance.thePlantType == PlantType.SuperMachineNut || __instance.thePlantType == PlantType.MachineNut)) - return; - __instance.healthSlider.healthText.text = __instance.healthSlider.healthTextShadow.text = ChangeHPText(__instance.healthSlider.healthTextShadow.text); - } - - [HarmonyPostfix] - [HarmonyPatch(nameof(Plant.UpdateText))] - private static void Update(Plant __instance) - { - if (!(__instance.thePlantType == PlantType.SuperMachineNut || __instance.thePlantType == PlantType.MachineNut)) - return; - if (__instance.thePlantHealth < __instance.thePlantMaxHealth) - return; - __instance.healthSlider.healthText.text = __instance.healthSlider.healthTextShadow.text = ChangeHPText(__instance.healthSlider.healthTextShadow.text); - } - - static string ChangeHPText(string originalText) - { - var regex = new Regex(@"(\d+)\d\d\d/(\d)000"); - if (regex.IsMatch(originalText)) - { - var match = regex.Match(originalText); - int groupCount = match.Groups.Count; - - List dynamicParts = new List(); - - for (int i = 1; i < groupCount; i++) - dynamicParts.Add(match.Groups[i].Value); - return originalText = string.Format("{0}k/{1}k", [.. dynamicParts]); - } - return originalText; - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/MinorObjects/PlayerName_Patch.cs b/BepInEx/Patches/GameObjects/MinorObjects/PlayerName_Patch.cs deleted file mode 100644 index 90b423f..0000000 --- a/BepInEx/Patches/GameObjects/MinorObjects/PlayerName_Patch.cs +++ /dev/null @@ -1,17 +0,0 @@ -using HarmonyLib; -using System; -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); - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/MinorObjects/SelectYourPlants_Patch.cs b/BepInEx/Patches/GameObjects/MinorObjects/SelectYourPlants_Patch.cs deleted file mode 100644 index c9ce753..0000000 --- a/BepInEx/Patches/GameObjects/MinorObjects/SelectYourPlants_Patch.cs +++ /dev/null @@ -1,22 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -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/BepInEx/Patches/GameObjects/MinorObjects/TrainingDummy_Patch.cs b/BepInEx/Patches/GameObjects/MinorObjects/TrainingDummy_Patch.cs deleted file mode 100644 index 3b34a5a..0000000 --- a/BepInEx/Patches/GameObjects/MinorObjects/TrainingDummy_Patch.cs +++ /dev/null @@ -1,16 +0,0 @@ -using HarmonyLib; -using System; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects -{ - [HarmonyPatch(typeof(TrainingDummy), nameof(TrainingDummy.UpdateHealthText))] - public static class TrainingDummy_Patch - { - [HarmonyPostfix] - public static void UpdateHealthText(TrainingDummy __instance) - { - Zombie_Patch.TranslateHpUI_T(__instance.healthText, __instance); - Zombie_Patch.TranslateHpUI_T(__instance.healthTextShadow, __instance); - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/MinorObjects/TreasureMoney_Patch.cs b/BepInEx/Patches/GameObjects/MinorObjects/TreasureMoney_Patch.cs deleted file mode 100644 index 3c4543d..0000000 --- a/BepInEx/Patches/GameObjects/MinorObjects/TreasureMoney_Patch.cs +++ /dev/null @@ -1,16 +0,0 @@ -using HarmonyLib; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects -{ - [HarmonyPatch(typeof(TreasureMoney))] - public static class TreasureMoney_Patch - { - [HarmonyPostfix] - [HarmonyPatch(nameof(TreasureMoney.Update))] - private static void Update(TreasureMoney __instance) - { - __instance.text = StringStore.TranslateText(__instance.text); - } - } -} diff --git a/BepInEx/Patches/GameObjects/MinorObjects/UIProgress2_Patch.cs b/BepInEx/Patches/GameObjects/MinorObjects/UIProgress2_Patch.cs deleted file mode 100644 index 8c8ccf0..0000000 --- a/BepInEx/Patches/GameObjects/MinorObjects/UIProgress2_Patch.cs +++ /dev/null @@ -1,17 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(UIProgress2))] - public static class UIProgress2_Patch - { - [HarmonyPatch(nameof(UIProgress2.Update))] - [HarmonyPostfix] - private static void Update(UIProgress2 __instance) - { - __instance.t.text = StringStore.TranslateText(__instance.t.text); - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/MinorObjects/UltimateChomper_Patch.cs b/BepInEx/Patches/GameObjects/MinorObjects/UltimateChomper_Patch.cs deleted file mode 100644 index 5e8aac3..0000000 --- a/BepInEx/Patches/GameObjects/MinorObjects/UltimateChomper_Patch.cs +++ /dev/null @@ -1,17 +0,0 @@ -using HarmonyLib; -using System; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects -{ - [HarmonyPatch(typeof(UltimateChomper), nameof(UltimateChomper.UpdateText))] - public static class UltimateChomper_Patch - { - [HarmonyPostfix] - public static void UpdateText(UltimateChomper __instance) - { - StringStore.TranslateText(__instance.killingText); - StringStore.TranslateText(__instance.killingTextShadow); - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/MinorObjects/Zombie_Patch.cs b/BepInEx/Patches/GameObjects/MinorObjects/Zombie_Patch.cs deleted file mode 100644 index ff271df..0000000 --- a/BepInEx/Patches/GameObjects/MinorObjects/Zombie_Patch.cs +++ /dev/null @@ -1,176 +0,0 @@ -using HarmonyLib; -using System; -using System.Collections.Generic; -using System.Linq; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using System.Text.RegularExpressions; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects -{ - [HarmonyPatch(typeof(Zombie))] - public static class Zombie_Patch - { - private static Dictionary HPStrings = new Dictionary() - { - { "最后一击:(\\d+)\nDPS:([^\\s]+)\n总伤害:(\\d+)", "Last Damage: {0}\nDPS: {1}\nTotal: {2}" }, - { "^HP:(\\d+)/(\\d+)\n一类:(\\d+)/(\\d+)\n二类:(\\d+)/(\\d+)$", "HP: {0}/{1}\nType 1 armor: {2}/{3}\nType 2 armor: {4}/{5}" }, - { "^HP:(\\d+)/(\\d+)\n一类:(\\d+)/(\\d+)$", "HP: {0}/{1}\nType 1 armor: {2}/{3}" }, - { "^HP:(\\d+)/(\\d+)\n二类:(\\d+)/(\\d+)$", "HP: {0}/{1}\nType 2 armor: {2}/{3}" }, - { "^HP:(\\d+)/(\\d+)$", "HP: {0}/{1}" } - }; - - public static void LoadHPStrings() - { - foreach (var hp in HPStrings) - if (StringStore.translationStringRegex.ContainsKey(hp.Key)) - HPStrings[hp.Key] = StringStore.translationStringRegex[hp.Key]; - } - - [HarmonyPatch(nameof(Zombie.Start))] - [HarmonyPostfix] - public static void Start(Zombie __instance) - { - TranslateHpUI(__instance.healthText, __instance); - TranslateHpUI(__instance.healthTextShadow, __instance); - - if (__instance.healthText.transform.rotation != Quaternion.Euler(0, 0, 0)) - __instance.healthText.transform.rotation = Quaternion.Euler(0f, 0f, 0f); - } - - [HarmonyPatch(nameof(Zombie.Update))] - [HarmonyPrefix] - public static void Update(Zombie __instance) - { - if (__instance.theZombieType == ZombieType.TrainingDummy || !Board.Instance.showZombieHealth) - return; - TranslateHpUI(__instance.healthText, __instance); - TranslateHpUI(__instance.healthTextShadow, __instance); - - if (__instance.healthText.transform.rotation != Quaternion.Euler(0f, 0f, 0f)) - __instance.healthText.transform.rotation = Quaternion.Euler(0f, 0f, 0f); - } - - public static void TranslateHpUI(TextMeshPro textTMP, Zombie __instance) - { - if (textTMP) - { - string origText = textTMP.text; - string translatedText = origText; - string pattern = "(\\d+)阶\\n([\\s\\S]+)"; - if (StringStore.TestRegex(translatedText, pattern)) - { - var match = Regex.Match(translatedText, pattern, RegexOptions.Singleline); - string tier = match.Groups[1].Value; - string healthText = TranslateHPText(match.Groups[2].Value, __instance); - string fStr = StringStore.translationStringRegex[pattern]; - translatedText = string.Format(fStr, new object[] { tier, healthText }); - } - else - { - translatedText = TranslateHPText(origText, __instance); - } - textTMP.text = translatedText == origText ? origText : translatedText; - textTMP.autoSizeTextContainer = false; - if (translatedText != origText) - textTMP.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } - - public static void TranslateHpUI_T(TextMeshPro textTMP, TrainingDummy __instance) - { - if (textTMP) - { - string origText = textTMP.text; - string translatedText = TranslateHPText_T(origText, __instance); - textTMP.text = translatedText == origText ? origText : translatedText; - textTMP.autoSizeTextContainer = false; - if (translatedText != origText) - textTMP.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } - - public static string TranslateHPText(string originalText, Zombie __instance) - { - if(originalText == null) - { - return originalText; - } - string finalText = __instance.healthText.text; - int fIndex = -1; - bool found = false; - - for (int i = 0; i < HPStrings.Count; i++) - { - var hp = HPStrings.ElementAt(i); - if(Regex.Match(originalText, hp.Key, RegexOptions.Singleline).Success) - { - fIndex = i; - found = true; - } - } - - if (fIndex > -1 && found) - { - string fStr = HPStrings.ElementAt(fIndex).Value; - - switch (fIndex) - { - case 1: - finalText = string.Format(fStr, __instance.theHealth, __instance.theMaxHealth, __instance.theFirstArmorHealth, __instance.theFirstArmorMaxHealth, __instance.theSecondArmorHealth, __instance.theSecondArmorMaxHealth); - break; - case 2: - finalText = string.Format(fStr, __instance.theHealth, __instance.theMaxHealth, __instance.theFirstArmorHealth, __instance.theFirstArmorMaxHealth); - break; - case 3: - finalText = string.Format(fStr, __instance.theHealth, __instance.theMaxHealth, __instance.theSecondArmorHealth, __instance.theSecondArmorMaxHealth); - break; - case 4: - finalText = string.Format(fStr, __instance.theHealth, __instance.theMaxHealth); - break; - default: - break; - } - } - - return finalText; - } - - public static string TranslateHPText_T(string originalText, TrainingDummy __instance) - { - string finalText = __instance.healthText.text; - int fIndex = -1; - bool found = false; - - for (int i = 0; i < HPStrings.Count; i++) - { - var hp = HPStrings.ElementAt(i); - Regex regex = new Regex(hp.Key); - if (regex.IsMatch(originalText)) - { - fIndex = i; - found = true; - } - } - - if (fIndex > -1 && found) - { - string fStr = HPStrings.ElementAt(fIndex).Value; - string DPS = originalText.Split("\n")[1].Replace("DPS:", ""); - DPS = StringStore.TranslateText(DPS); - - switch (fIndex) - { - case 0: - finalText = string.Format(fStr, __instance.lastDamage, DPS, __instance.totalDamage); - break; - default: - break; - } - } - - return finalText; - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/NoticePauseMenu_Patch.cs b/BepInEx/Patches/GameObjects/NoticePauseMenu_Patch.cs deleted file mode 100644 index 0579148..0000000 --- a/BepInEx/Patches/GameObjects/NoticePauseMenu_Patch.cs +++ /dev/null @@ -1,62 +0,0 @@ -using HarmonyLib; -using UnityEngine.UI; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; -using System.IO; -using System; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(NoticeMenu))] - public class NoticePauseMenu_Patch - { - [HarmonyPrefix] - [HarmonyPatch(nameof(NoticeMenu.Awake))] - private static void Pre_Awake(NoticeMenu __instance) - { - GameObject contentObject = __instance.transform.FindChild("Scroll View/Viewport/Content").gameObject; - - TextMeshProUGUI contentText = contentObject.GetComponent(); - File.WriteAllText(Path.Combine(FileLoader.GetAssetDir(FileLoader.AssetType.Dumps), "changelog.txt"), contentText.text); - - string stringDir = FileLoader.GetAssetDir(FileLoader.AssetType.Strings, Utils.Language); - string changelogDir = Path.Combine(stringDir, "changelog.txt"); - - if (!File.Exists(changelogDir)) - { - File.WriteAllText(changelogDir, contentText.text); - } - } - - [HarmonyPostfix] - [HarmonyPatch(nameof(NoticeMenu.Awake))] - private static void Post_Awake(NoticeMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - string stringDir = FileLoader.GetAssetDir(FileLoader.AssetType.Strings, Utils.Language); - string changelogDir = Path.Combine(stringDir, "changelog.txt"); - - string changelogText = File.ReadAllText(changelogDir); - - GameObject contentObject = __instance.transform.FindChild("Scroll View/Viewport/Content").gameObject; - - TextMeshProUGUI contentText = contentObject.GetComponent(); - contentText.text = changelogText; - contentText.margin = new Vector4(6, 2, 12, 0); - - contentText.enableWordWrapping = true; - contentText.overflowMode = TextOverflowModes.ScrollRect; - - Canvas.ForceUpdateCanvases(); - contentText.ForceMeshUpdate(); - - //float textHeight = contentText.preferredHeight; - //RectTransform contentRect = contentObject.GetComponent(); - //contentRect.sizeDelta = new Vector2(contentRect.sizeDelta.x, textHeight); - - ContentSizeFitter sizeFitter = contentObject.AddComponent(); - sizeFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/OtherMenu_Patch.cs b/BepInEx/Patches/GameObjects/OtherMenu_Patch.cs deleted file mode 100644 index 4ffed8c..0000000 --- a/BepInEx/Patches/GameObjects/OtherMenu_Patch.cs +++ /dev/null @@ -1,19 +0,0 @@ -using HarmonyLib; -using System; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(OtherMenu))] - public static class OtherMenu_Patch - { - [HarmonyPatch(nameof(OtherMenu.UpdateText))] - [HarmonyPostfix] - private static void UpdateText(OtherMenu __instance) - { - __instance.text1 = StringStore.TranslateText(__instance.text1); - __instance.text2 = StringStore.TranslateText(__instance.text2); - } - } -} diff --git a/BepInEx/Patches/GameObjects/PlantDamageMenu_Patch.cs b/BepInEx/Patches/GameObjects/PlantDamageMenu_Patch.cs deleted file mode 100644 index d30635a..0000000 --- a/BepInEx/Patches/GameObjects/PlantDamageMenu_Patch.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Text.RegularExpressions; -using HarmonyLib; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using TMPro; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(PlantDamageMenu))] - public static class PlantDamageMenu_Patch - { - [HarmonyPatch(nameof(PlantDamageMenu.Awake))] - [HarmonyPostfix] - private static void Awake(PlantDamageMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - text.font = fontAsset; - } - } - - [HarmonyPatch(nameof(PlantDamageMenu.InitCards))] - [HarmonyPostfix] - private static void InitCards(PlantDamageMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - text.font = fontAsset; - } - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/PlantInfoWindow_Patch.cs b/BepInEx/Patches/GameObjects/PlantInfoWindow_Patch.cs deleted file mode 100644 index ed6e8dc..0000000 --- a/BepInEx/Patches/GameObjects/PlantInfoWindow_Patch.cs +++ /dev/null @@ -1,54 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; -using UnityEngine.UIElements; -using static PvZ_Fusion_Translator__BepInEx_.FileLoader; -using System; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(PlantInfoWindow))] - public static class PlantInfoWindow_Patch - { - [HarmonyPatch(nameof(PlantInfoWindow.InitText))] - [HarmonyPostfix] - private static void InitText(PlantInfoWindow __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - BigGardenPlant thePlant = __instance.plant; - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - if (txt.name.Contains("Introduce") && thePlant != null) - { - PlantType thePlantType = thePlant.thePlantType; - txt.text = StringStore.TranslateText(txt.text); - - string text = txt.text; - string[] lines = text.Split("\n"); - - lines[0] = Utils.GetPlantNameFromAlmanac(thePlantType); - string updatedText = String.Join("\n", lines); - - txt.text = updatedText; - } - else - { - txt.text = StringStore.TranslateText(txt.text); - } - - txt.font = fontAsset; - } - - Transform parentWindowTransform = __instance.transform.parent; - Transform returnPlantTransform = parentWindowTransform.FindChild("Close"); - - foreach(TextMeshProUGUI txt in returnPlantTransform.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText("合上"); - } - } - } -} diff --git a/BepInEx/Patches/GameObjects/PlayerShootingMenu_Patch.cs b/BepInEx/Patches/GameObjects/PlayerShootingMenu_Patch.cs deleted file mode 100644 index b893898..0000000 --- a/BepInEx/Patches/GameObjects/PlayerShootingMenu_Patch.cs +++ /dev/null @@ -1,40 +0,0 @@ -using HarmonyLib; -using TMPro; -using BepInEx.Unity.IL2CPP; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(PlayerShootingMenu))] - public static class PlayerShootingMenu_Patch - { - [HarmonyPatch(nameof(PlayerShootingMenu.Update))] - [HarmonyPostfix] - private static void Update(PlayerShootingMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - - [HarmonyPatch(nameof(PlayerShootingMenu.Refresh))] - [HarmonyPostfix] - private static void Refresh(PlayerShootingMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - Transform refreshTransform = __instance.transform.FindChild("Button"); - foreach (TextMeshProUGUI text in refreshTransform.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - text.font = fontAsset; - text.autoSizeTextContainer = false; - } - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/PlayerShootingWindow_Patch.cs b/BepInEx/Patches/GameObjects/PlayerShootingWindow_Patch.cs deleted file mode 100644 index 2c228af..0000000 --- a/BepInEx/Patches/GameObjects/PlayerShootingWindow_Patch.cs +++ /dev/null @@ -1,36 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; -using System.Text.RegularExpressions; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(PlayerShootingWindow))] - public static class PlayerShootingWindow_Patch - { - [HarmonyPatch(nameof(PlayerShootingWindow.SetType))] - [HarmonyPostfix] - private static void SetType(PlayerShootingWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - - [HarmonyPatch(nameof(PlayerShootingWindow.OnAnimOver))] - [HarmonyPostfix] - private static void OnAnimOver(PlayerShootingWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - } -} diff --git a/BepInEx/Patches/GameObjects/RogueCardWindow_Patch.cs b/BepInEx/Patches/GameObjects/RogueCardWindow_Patch.cs deleted file mode 100644 index 47797d5..0000000 --- a/BepInEx/Patches/GameObjects/RogueCardWindow_Patch.cs +++ /dev/null @@ -1,37 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; -using System.Text.RegularExpressions; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(RogueCardWindow))] - public static class RogueCardWindow_Patch - { - [HarmonyPatch(nameof(RogueCardWindow.InitCard))] - [HarmonyPostfix] - private static void InitCard(RogueCardWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - - [HarmonyPatch(nameof(RogueCardWindow.OnAnimOver))] - [HarmonyPostfix] - private static void OnAnimOver(RogueCardWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - } -} diff --git a/BepInEx/Patches/GameObjects/RogueStartMenu_Patch.cs b/BepInEx/Patches/GameObjects/RogueStartMenu_Patch.cs deleted file mode 100644 index ce379ad..0000000 --- a/BepInEx/Patches/GameObjects/RogueStartMenu_Patch.cs +++ /dev/null @@ -1,42 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; -using UnityEngine.TextCore.Text; -using UnityEngine.UI; -using static System.Net.Mime.MediaTypeNames; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - - [HarmonyPatch(typeof(RogueStartMenu))] - public static class RogueStartMenu_Patch - { - [HarmonyPatch(nameof(RogueStartMenu.SetLeader))] - [HarmonyPostfix] - private static void SetLeader(RogueStartMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - - [HarmonyPatch(nameof(RogueStartMenu.EnterGame))] - [HarmonyPostfix] - private static void EnterGame(RogueStartMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } -} diff --git a/BepInEx/Patches/GameObjects/SeedLibrary_Patch.cs b/BepInEx/Patches/GameObjects/SeedLibrary_Patch.cs deleted file mode 100644 index f2ba774..0000000 --- a/BepInEx/Patches/GameObjects/SeedLibrary_Patch.cs +++ /dev/null @@ -1,36 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(SeedLibrary))] - public static class SeedLibrary_Patch - { - [HarmonyPatch(nameof(SeedLibrary.ChangeSafeMode))] - [HarmonyPostfix] - private static void ChangeSafeMode(SeedLibrary __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - - Transform safetyBoxButtonTransform = __instance.transform.Find("SafeBox").Find("StartSafeMode"); - - if (__instance.safeMode == false && safetyBoxButtonTransform != null) - { - foreach (TextMeshProUGUI txt in safetyBoxButtonTransform.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText("合上"); - } - } - } - } -} - - diff --git a/BepInEx/Patches/GameObjects/ShootingMenu_Patch.cs b/BepInEx/Patches/GameObjects/ShootingMenu_Patch.cs deleted file mode 100644 index 4169bda..0000000 --- a/BepInEx/Patches/GameObjects/ShootingMenu_Patch.cs +++ /dev/null @@ -1,25 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(ShootingMenu))] - public static class ShootingMenu_Patch - { - [HarmonyPatch(nameof(ShootingMenu.Update))] - [HarmonyPostfix] - private static void Update(ShootingMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/ShootingSelectWindow_Patch.cs b/BepInEx/Patches/GameObjects/ShootingSelectWindow_Patch.cs deleted file mode 100644 index f42f5a5..0000000 --- a/BepInEx/Patches/GameObjects/ShootingSelectWindow_Patch.cs +++ /dev/null @@ -1,73 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; -using System.Text.RegularExpressions; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(ShootingSelectWindow))] - public static class ShootingSelectWindow_Patch - { - [HarmonyPatch(nameof(ShootingSelectWindow.InitPlantType))] - [HarmonyPostfix] - private static void InitCard(ShootingSelectWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - - [HarmonyPatch(nameof(ShootingSelectWindow.OnAnimOver))] - [HarmonyPostfix] - private static void OnAnimOver(ShootingSelectWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - - [HarmonyPatch(nameof(ShootingSelectWindow.SetUpgradePlantTypes))] - [HarmonyPostfix] - private static void SetUpgradePlantTypes(ShootingSelectWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - - [HarmonyPatch(nameof(ShootingSelectWindow.GetMaxIndexInRoutes))] - [HarmonyPostfix] - private static void GetMaxIndexInRoutes(ShootingSelectWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - - [HarmonyPatch(nameof(ShootingSelectWindow.Start))] - [HarmonyPostfix] - private static void Start(ShootingSelectWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - } -} diff --git a/BepInEx/Patches/GameObjects/SpriteRenderer_patch.cs b/BepInEx/Patches/GameObjects/SpriteRenderer_patch.cs deleted file mode 100644 index 07279bd..0000000 --- a/BepInEx/Patches/GameObjects/SpriteRenderer_patch.cs +++ /dev/null @@ -1,25 +0,0 @@ -using HarmonyLib; -using TMPro; -using BepInEx.Unity.IL2CPP; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(SpriteRenderer))] - public static class SpriteRenderer_Patch - { - [HarmonyPatch(nameof(SpriteRenderer.InvokeSpriteChanged))] - [HarmonyPostfix] - private static void InvokeSpriteChanged(SpriteRenderer __instance) - { - if (__instance.sprite != null) - { - if (TextureStore.spriteDict.ContainsKey(__instance.sprite.name) && __instance.drawMode != SpriteDrawMode.Sliced) - { - __instance.drawMode = SpriteDrawMode.Sliced; - } - } - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/TowerOption_Patch.cs b/BepInEx/Patches/GameObjects/TowerOption_Patch.cs deleted file mode 100644 index a8784d1..0000000 --- a/BepInEx/Patches/GameObjects/TowerOption_Patch.cs +++ /dev/null @@ -1,21 +0,0 @@ -//using HarmonyLib; -//using System; -//using TMPro; -//using PvZ_Fusion_Translator__BepInEx_.AssetStore; -//using UnityEngine; - -//namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -//{ -// [HarmonyPatch(typeof(TowerOption))] -// public static class TowerOption_Patch -// { -// [HarmonyPatch(nameof(TowerOption.Start))] -// [HarmonyPostfix] -// private static void Postfix_Start(TowerOption __instance) -// { -// //TextMeshProUGUI[] allTexts = __instance.GetComponentsInChildren(true); -// __instance.introduce.text = StringStore.TranslateText(__instance.introduce.text); -// __instance.introduce.font = FontStore.LoadTMPFont(Utils.Language.ToString()); -// } -// } -//} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/TowerUpgradeMenu_Patch.cs b/BepInEx/Patches/GameObjects/TowerUpgradeMenu_Patch.cs deleted file mode 100644 index fee9af4..0000000 --- a/BepInEx/Patches/GameObjects/TowerUpgradeMenu_Patch.cs +++ /dev/null @@ -1,39 +0,0 @@ -using HarmonyLib; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using TMPro; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(TowerUpgradeMenu))] - public static class TowerUpgradeMenu_Patch - { - [HarmonyPatch(nameof(TowerUpgradeMenu.Awake))] - [HarmonyPostfix] - private static void Awake(TowerUpgradeMenu __instance) - { - __instance.des.text = StringStore.TranslateText(__instance.des.text); - __instance.des2.text = StringStore.TranslateText(__instance.des2.text); - - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - text.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } - - [HarmonyPatch(nameof(TowerUpgradeMenu.SetText))] - [HarmonyPostfix] - private static void SetText(TowerUpgradeMenu __instance) - { - __instance.des.text = StringStore.TranslateText(__instance.des.text); - __instance.des2.text = StringStore.TranslateText(__instance.des2.text); - - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - text.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/TravelBuffMenu_Patch.cs b/BepInEx/Patches/GameObjects/TravelBuffMenu_Patch.cs deleted file mode 100644 index 2532e0c..0000000 --- a/BepInEx/Patches/GameObjects/TravelBuffMenu_Patch.cs +++ /dev/null @@ -1,26 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using static PvZ_Fusion_Translator__BepInEx_.Patches.Managers.TravelMgr_Patch; -using UnityEngine; -using System.Collections.Generic; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(TravelBuffMenu))] - public static class TravelBuffMenu_Patch - { - [HarmonyPatch(nameof(TravelBuffMenu.RefeshOptions))] - [HarmonyPostfix] - private static void RefeshOptions(TravelBuffMenu __instance) - { - foreach (TravelBuffOptionButton button in __instance.options) - { - button.introduce.text = translatedTravelBuffs[buffLinks[button.buffType]][button.buffIndex]; - List buffSet = translatedTravelBuffs[buffLinks[button.buffType]]; - string buffText = (button.buffIndex < buffSet.Count && button.show != null) ? buffSet[button.buffIndex] : StringStore.TranslateText(button.introduce.text); - button.introduce.text = buffText; - } - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/TravelBuffOptionButton_Patch.cs b/BepInEx/Patches/GameObjects/TravelBuffOptionButton_Patch.cs deleted file mode 100644 index 9c67c46..0000000 --- a/BepInEx/Patches/GameObjects/TravelBuffOptionButton_Patch.cs +++ /dev/null @@ -1,41 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using static PvZ_Fusion_Translator__BepInEx_.Patches.Managers.TravelMgr_Patch; -using UnityEngine; -using System.Collections.Generic; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(TravelBuffOptionButton))] - public static class TravelBuffOptionButton_Patch - { - [HarmonyPatch(nameof(TravelBuffOptionButton.SetBuff))] - [HarmonyPostfix] - private static void SetBuff(TravelBuffOptionButton __instance) - { - List buffSet = translatedTravelBuffs[buffLinks[__instance.buffType]]; - string buffText = (__instance.buffIndex < buffSet.Count && __instance.show != null) ? buffSet[__instance.buffIndex] : StringStore.TranslateText(__instance.introduce.text); - __instance.introduce.text = buffText; - } - - [HarmonyPatch(nameof(TravelBuffOptionButton.Awake))] - [HarmonyPostfix] - private static void Awake(TravelBuffOptionButton __instance) - { - List buffSet = translatedTravelBuffs[buffLinks[__instance.buffType]]; - string buffText = (__instance.buffIndex < buffSet.Count && __instance.show != null) ? buffSet[__instance.buffIndex] : StringStore.TranslateText(__instance.introduce.text); - __instance.introduce.text = buffText; - } - - [HarmonyPatch(nameof(TravelBuffOptionButton.OnAnimOver))] - [HarmonyPostfix] - private static void OnAnimOver(TravelBuffOptionButton __instance) - { - List buffSet = translatedTravelBuffs[buffLinks[__instance.buffType]]; - string buffText = (__instance.buffIndex < buffSet.Count && __instance.show != null) ? buffSet[__instance.buffIndex] : StringStore.TranslateText(__instance.introduce.text); - __instance.introduce.text = buffText; - } - } -} diff --git a/BepInEx/Patches/GameObjects/TravelBuff_Patch.cs b/BepInEx/Patches/GameObjects/TravelBuff_Patch.cs deleted file mode 100644 index 29ed00b..0000000 --- a/BepInEx/Patches/GameObjects/TravelBuff_Patch.cs +++ /dev/null @@ -1,18 +0,0 @@ -using HarmonyLib; -using System; - -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); - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/TravelLookBuff_Patch.cs b/BepInEx/Patches/GameObjects/TravelLookBuff_Patch.cs deleted file mode 100644 index d5e9697..0000000 --- a/BepInEx/Patches/GameObjects/TravelLookBuff_Patch.cs +++ /dev/null @@ -1,63 +0,0 @@ -using HarmonyLib; -using System; -using System.Collections.Generic; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using static PvZ_Fusion_Translator__BepInEx_.Patches.Managers.TravelMgr_Patch; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(TravelLookBuff))] - public static class TravelLookBuff_Patch - { - [HarmonyPatch(nameof(TravelLookBuff.Clear))] - [HarmonyPostfix] - public static void Post_Clear(TravelLookBuff __instance) - { - __instance.introduce.text = StringStore.TranslateText("无"); - __instance.set = false; - - foreach (TextMeshProUGUI text in __instance.transform.FindChild("Images").FindChild("Button").GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - - [HarmonyPatch(nameof(TravelLookBuff.OnMouseUpAsButton))] - [HarmonyPostfix] - public static void Post_OnMouseUpAsButton(TravelLookBuff __instance) - { - foreach (TextMeshProUGUI text in __instance.transform.FindChild("Images").FindChild("Button").GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - - [HarmonyPatch(nameof(TravelLookBuff.SetBuff))] - [HarmonyPostfix] - public static void Post_SetBuff(TravelLookBuff __instance) - { - List buffSet = translatedTravelBuffs[buffLinks[__instance.buffType]]; - string buffText = (__instance.buffIndex < buffSet.Count) ? buffSet[__instance.buffIndex] : StringStore.TranslateText(__instance.introduce.text); - __instance.introduce.text = buffText; -#if DEBUG - if (__instance.introduce.text != null) - { - Log.LogInfo($"BuffType: {__instance.buffType}, BuffIndex: {__instance.buffIndex}, BuffIntroduce: {__instance.introduce.text}"); - if (__instance.introduce.text != buffText) - { - FileLoader.DumpUntranslatedStrings(__instance.introduce.text); - //Log.LogInfo($"Mapped BuffIntroduce: {buffText}"); - } - } - -#endif - - foreach (TextMeshProUGUI text in __instance.transform.FindChild("Images").FindChild("Button").GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/TravelLookMenu_Patch.cs b/BepInEx/Patches/GameObjects/TravelLookMenu_Patch.cs deleted file mode 100644 index 6eeb4a2..0000000 --- a/BepInEx/Patches/GameObjects/TravelLookMenu_Patch.cs +++ /dev/null @@ -1,46 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(TravelLookMenu))] - public static class TravelLookMenu_Patch - { - public static string savedAssetString = ""; - - [HarmonyPatch(nameof(TravelLookMenu.Start))] - [HarmonyPostfix] - private static void Postfix_Start(TravelLookMenu __instance) - { - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - - Transform quitButtonTransform = __instance.transform.Find("Quit"); - foreach (TextMeshProUGUI txt in quitButtonTransform.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText("合上"); - txt.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - - __instance.treasureText.text = StringStore.TranslateText(__instance.treasureText.text); - savedAssetString = __instance.treasureText.text; - } - - [HarmonyPatch(nameof(TravelLookMenu.Update))] - [HarmonyPostfix] - private static void Update(TravelLookMenu __instance) - { - if (savedAssetString != __instance.treasureText.text) - { - __instance.treasureText.text = StringStore.TranslateText(__instance.treasureText.text); - savedAssetString = __instance.treasureText.text; - } - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/TravelRefresh_Patch.cs b/BepInEx/Patches/GameObjects/TravelRefresh_Patch.cs deleted file mode 100644 index 5b0ee24..0000000 --- a/BepInEx/Patches/GameObjects/TravelRefresh_Patch.cs +++ /dev/null @@ -1,28 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(TravelRefresh))] - public static class TravelRefresh_Patch - { - [HarmonyPatch(nameof(TravelRefresh.Start))] - [HarmonyPostfix] - private static void Start(TravelRefresh __instance) - { - __instance.text = StringStore.TranslateText(__instance.text); - __instance.text_shadow = StringStore.TranslateText(__instance.text_shadow); - } - - [HarmonyPatch(nameof(TravelRefresh.OnMouseUpAsButton))] - [HarmonyPostfix] - private static void OnMouseUpAsButton(TravelRefresh __instance) - { - __instance.text = StringStore.TranslateText(__instance.text); - __instance.text_shadow = StringStore.TranslateText(__instance.text_shadow); - } - } -} diff --git a/BepInEx/Patches/GameObjects/TravelStore_Patch.cs b/BepInEx/Patches/GameObjects/TravelStore_Patch.cs deleted file mode 100644 index 5635ef8..0000000 --- a/BepInEx/Patches/GameObjects/TravelStore_Patch.cs +++ /dev/null @@ -1,70 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using static PvZ_Fusion_Translator__BepInEx_.Patches.Managers.TravelMgr_Patch; -using UnityEngine; -using System.Linq; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - public static class TravelStore_Patch - { - [HarmonyPatch(nameof(TravelStore.Update))] - [HarmonyPostfix] - private static void Update(TravelStore __instance) - { - foreach (TextMeshProUGUI text in __instance.introduces) - { - if (__instance.currentSelect != null) - { - var buffList = translatedTravelBuffs[buffLinks[(BuffType)__instance.currentSelect.theBuffType]]; - if (__instance.currentSelect.theBuffNumber < buffList.Count && __instance.currentSelect.theBuffNumber > -1) - { - text.text = buffList[__instance.currentSelect.theBuffNumber]; - } - else - { - text.text = StringStore.TranslateText(text.text); - } - } - } - foreach (var textMesh in __instance.points) - { - textMesh.text = StringStore.TranslateText(textMesh.text); - } - } - - [HarmonyPatch(nameof(TravelStore.RefreshBuff))] - [HarmonyPostfix] - private static void RefreshBuff(TravelStore __instance) - { - foreach (TravelBuff buff in __instance.travelBuffs) - { - TextMeshProUGUI cost = buff.transform.GetChild(1).GetComponent(); - cost.text = StringStore.TranslateText(cost.text); - cost.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - - foreach (TextMeshProUGUI text in __instance.introduces) - { - if (__instance.currentSelect != null) - { - var buffList = translatedTravelBuffs[buffLinks[(BuffType)__instance.currentSelect.theBuffType]]; - if (__instance.currentSelect.theBuffNumber < buffList.Count && __instance.currentSelect.theBuffNumber > -1) - { - text.text = buffList[__instance.currentSelect.theBuffNumber]; - } - else - { - text.text = StringStore.TranslateText(text.text); - } - } - } - foreach (var textMesh in __instance.points) - { - textMesh.text = StringStore.TranslateText(textMesh.text); - } - } - } -} diff --git a/BepInEx/Patches/GameObjects/TreasureConfirmMenu_Patch.cs b/BepInEx/Patches/GameObjects/TreasureConfirmMenu_Patch.cs deleted file mode 100644 index 5c7df14..0000000 --- a/BepInEx/Patches/GameObjects/TreasureConfirmMenu_Patch.cs +++ /dev/null @@ -1,24 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(TreasureConfirmMenu))] - public static class TreasureConfirmMenu_Patch - { - [HarmonyPatch(nameof(TreasureConfirmMenu.SetText))] - [HarmonyPostfix] - private static void SetText(TreasureConfirmMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } -} diff --git a/BepInEx/Patches/GameObjects/TreasureEquipmentMenu_Patch.cs b/BepInEx/Patches/GameObjects/TreasureEquipmentMenu_Patch.cs deleted file mode 100644 index 729ab03..0000000 --- a/BepInEx/Patches/GameObjects/TreasureEquipmentMenu_Patch.cs +++ /dev/null @@ -1,37 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(TreasureEquipmentMenu))] - public static class TreasureEquipmentMenu_Patch - { - [HarmonyPatch(nameof(TreasureEquipmentMenu.Awake))] - [HarmonyPostfix] - private static void Awake(TreasureEquipmentMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - - [HarmonyPatch(nameof(TreasureEquipmentMenu.UpdateCards))] - [HarmonyPostfix] - private static void UpdateCards(TreasureEquipmentMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } -} diff --git a/BepInEx/Patches/GameObjects/TreasureEvacuateMenu_Patch.cs b/BepInEx/Patches/GameObjects/TreasureEvacuateMenu_Patch.cs deleted file mode 100644 index a399829..0000000 --- a/BepInEx/Patches/GameObjects/TreasureEvacuateMenu_Patch.cs +++ /dev/null @@ -1,30 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(TreasureEvacuateMenu))] - public static class TreasureEvacuateMenu_Patch - { - [HarmonyPatch(nameof(TreasureEvacuateMenu.Start))] - [HarmonyPostfix] - private static void Start(TreasureEvacuateMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - if (txt.name.Contains("text (1)")) - { - txt.name = txt.name + "_EVACUATE"; - } - } - } - } -} - - diff --git a/BepInEx/Patches/GameObjects/TreasureMainMenu_Patch.cs b/BepInEx/Patches/GameObjects/TreasureMainMenu_Patch.cs deleted file mode 100644 index 649af54..0000000 --- a/BepInEx/Patches/GameObjects/TreasureMainMenu_Patch.cs +++ /dev/null @@ -1,24 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(TreasureMainMenu))] - public static class TreasureMainMenu_Patch - { - [HarmonyPatch(nameof(TreasureMainMenu.Update))] - [HarmonyPostfix] - private static void Update(TreasureMainMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } -} diff --git a/BepInEx/Patches/GameObjects/TreasureStoreMenu_Patch.cs b/BepInEx/Patches/GameObjects/TreasureStoreMenu_Patch.cs deleted file mode 100644 index 7d11fe7..0000000 --- a/BepInEx/Patches/GameObjects/TreasureStoreMenu_Patch.cs +++ /dev/null @@ -1,24 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(TreasureStoreMenu))] - public static class TreasureStoreMenu_Patch - { - [HarmonyPatch(nameof(TreasureStoreMenu.InitCards))] - [HarmonyPostfix] - private static void InitCards(TreasureStoreMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } -} diff --git a/BepInEx/Patches/GameObjects/TreasureUpgradeMenu_Patch.cs b/BepInEx/Patches/GameObjects/TreasureUpgradeMenu_Patch.cs deleted file mode 100644 index b3990ab..0000000 --- a/BepInEx/Patches/GameObjects/TreasureUpgradeMenu_Patch.cs +++ /dev/null @@ -1,61 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using System.Text.RegularExpressions; -using UnityEngine; -using UnityEngine.UI; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(TreasureUpgradeMenu))] - public static class TreasureUpgradeMenu_Patch - { - [HarmonyPatch(nameof(TreasureUpgradeMenu.Start))] - [HarmonyPostfix] - private static void Start(TreasureUpgradeMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - - [HarmonyPatch(nameof(TreasureUpgradeMenu.UpgradeWareHouse))] - [HarmonyPostfix] - private static void UpgradeWareHouse(TreasureUpgradeMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - - [HarmonyPatch(nameof(TreasureUpgradeMenu.InitWareHouseUpgrade))] - [HarmonyPostfix] - private static void InitWareHouseUpgrade(TreasureUpgradeMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - - foreach (Text txt in __instance.GetComponentsInChildren()) - { - GameObject newTxtObj = Utils.ConvertToTextMeshProUGUI(txt.gameObject, txt.transform.parent, "text"); - TextMeshProUGUI newTxt = newTxtObj.GetComponent(); - newTxt.text = StringStore.TranslateText("植物商店"); - newTxt.autoSizeTextContainer = true; - newTxt.color = new Color(0, 0, 0.3922f, 1); - } - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/TreasureWarehouseMenu_Patch.cs b/BepInEx/Patches/GameObjects/TreasureWarehouseMenu_Patch.cs deleted file mode 100644 index 235daba..0000000 --- a/BepInEx/Patches/GameObjects/TreasureWarehouseMenu_Patch.cs +++ /dev/null @@ -1,63 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(TreasureWarehouseMenu))] - public static class TreasureWarehouseMenu_Patch - { - [HarmonyPatch(nameof(TreasureWarehouseMenu.InitCards))] - [HarmonyPostfix] - private static void InitCards(TreasureWarehouseMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - - [HarmonyPatch(nameof(TreasureWarehouseMenu.QuickSell))] - [HarmonyPostfix] - private static void QuickSell(TreasureWarehouseMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - - [HarmonyPatch(nameof(TreasureWarehouseMenu.FastSell))] - [HarmonyPostfix] - private static void FastSell(TreasureWarehouseMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - - [HarmonyPatch(nameof(TreasureWarehouseMenu.EnterStore))] - [HarmonyPostfix] - private static void EnterStore(TreasureWarehouseMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } -} diff --git a/BepInEx/Patches/GameObjects/UIDifficulty_Patch.cs b/BepInEx/Patches/GameObjects/UIDifficulty_Patch.cs deleted file mode 100644 index 49159a5..0000000 --- a/BepInEx/Patches/GameObjects/UIDifficulty_Patch.cs +++ /dev/null @@ -1,23 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using System.Text.RegularExpressions; - -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) - { - __instance.t.text = StringStore.TranslateText(__instance.t.text); - foreach(TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/GameObjects/UIZombieNum_Patch.cs b/BepInEx/Patches/GameObjects/UIZombieNum_Patch.cs deleted file mode 100644 index d547f91..0000000 --- a/BepInEx/Patches/GameObjects/UIZombieNum_Patch.cs +++ /dev/null @@ -1,29 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; - -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) - { - - #if MULTI_LANGUAGE - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - string zombieText = StringStore.TranslateText(__instance.t.text); - __instance.t.text = zombieText; - #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/BepInEx/Patches/Managers/AbyssBuffData_Patch.cs b/BepInEx/Patches/Managers/AbyssBuffData_Patch.cs deleted file mode 100644 index e839ade..0000000 --- a/BepInEx/Patches/Managers/AbyssBuffData_Patch.cs +++ /dev/null @@ -1,125 +0,0 @@ -//using HarmonyLib; -//using BepInEx; -//using System; -//using System.Collections.Generic; -//using System.Linq; -//using System.IO; -//using System.Text; -//using System.Text.Json; -//using System.Threading.Tasks; -//using Unity.VisualScripting; -//using UnityEngine; - -//namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers -//{ -// [HarmonyPatch(typeof(AbyssBuffData))] -// public static class AbyssBuffData_Patch -// { -// [HarmonyPatch(nameof(AbyssBuffData.LoadData))] -// [HarmonyPostfix] -// public static void Pre_LoadData(AbyssBuffData __instance) -// { -// string originalAbyssBuffStr = Resources.Load("AbyssBuffData").text; -// Dictionary> originalAbyssBuffData = JsonSerializer.Deserialize>>(originalAbyssBuffStr); -// List infos = originalAbyssBuffData["infos"]; -// Il2CppSystem.Collections.Generic.Dictionary> result = new(); - -// string abyssBuffDataDir = Path.Combine(FileLoader.GetAssetDir(FileLoader.AssetType.Strings, Utils.Language), "abyss_buffs.json"); -// if (!File.Exists(abyssBuffDataDir)) -// { -// File.WriteAllText(abyssBuffDataDir, originalAbyssBuffStr); -// } - -// Dictionary abyssBuffData = JsonSerializer.Deserialize>(File.ReadAllText(abyssBuffDataDir)); - -// for (int i = 0; i < infos.Count; i++) -// { -// AbyssBuffInfo originalTuple = infos[i]; -// Il2CppSystem.ValueTuple translatedTuple = new(); - -// translatedTuple.Item1 = abyssBuffData.ContainsKey(originalTuple.name) ? abyssBuffData[originalTuple.name] : originalTuple.name; -// translatedTuple.Item2 = abyssBuffData.ContainsKey(originalTuple.introduce) ? abyssBuffData[originalTuple.introduce] : originalTuple.introduce; -// translatedTuple.Item3 = originalTuple.value; - -// foreach (var x in AbyssBuffData.buffDatas) -// { -// if (x.Value.Item1 == originalTuple.name) -// { -// AbyssBuffData.buffDatas[x.Key] = translatedTuple; -// break; -// } -// } -// } -// } -// } - -// public enum AbyssBuffClone -// { -// 生存_聚塑, -// 生存_启命, -// 生存_坚定, -// 生存_弥合, -// 生存_警戒, -// 生存_霸体, -// 生存_共存, -// 生存_护盾, -// 生存_治疗, -// 生存_主宰, -// 寒冰_聚塑, -// 寒冰_刺骨, -// 寒冰_凛风, -// 寒冰_冻结, -// 寒冰_保护, -// 寒冰_折磨, -// 寒冰_扩散, -// 寒冰_凝神, -// 寒冰_破冰, -// 寒冰_永冻, -// 魅惑_聚塑, -// 魅惑_感应, -// 魅惑_催眠, -// 魅惑_无畏, -// 魅惑_脆弱, -// 魅惑_黑曜, -// 魅惑_转世, -// 魅惑_支援, -// 魅惑_沉重, -// 魅惑_共鸣, -// 烈焰_聚塑, -// 烈焰_爆破, -// 烈焰_怒火, -// 烈焰_红唇, -// 烈焰_融化, -// 烈焰_燃烧, -// 烈焰_浴火, -// 烈焰_鬼火, -// 烈焰_诅咒, -// 烈焰_太阳, -// 通用_断水, -// 通用_千斤, -// 通用_急迫, -// 通用_折扣, -// 通用_密植, -// 通用_超级, -// 通用_究极, -// 通用_极速, -// 通用_强力, -// 通用_专注, -// 通用_迸发, -// 通用_投资, -// 通用_机遇, -// 通用_命运, -// 通用_时停, -// 通用_升级, -// 蒜毒_聚塑, -// 蒜毒_腐蚀, -// 蒜毒_侵蚀, -// 蒜毒_血清, -// 蒜毒_混乱, -// 蒜毒_虚弱, -// 蒜毒_反胃, -// 蒜毒_虫噬, -// 蒜毒_百毒, -// 蒜毒_爆裂 -// } -//} \ No newline at end of file diff --git a/BepInEx/Patches/Managers/AbyssDevelopMenu_Patch.cs b/BepInEx/Patches/Managers/AbyssDevelopMenu_Patch.cs deleted file mode 100644 index 3459635..0000000 --- a/BepInEx/Patches/Managers/AbyssDevelopMenu_Patch.cs +++ /dev/null @@ -1,18 +0,0 @@ -using HarmonyLib; -using System; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; - -namespace PvZ_Fusion_Translator__BepInEx_.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/BepInEx/Patches/Managers/AbyssInfo_Patch.cs b/BepInEx/Patches/Managers/AbyssInfo_Patch.cs deleted file mode 100644 index ce2e837..0000000 --- a/BepInEx/Patches/Managers/AbyssInfo_Patch.cs +++ /dev/null @@ -1,12 +0,0 @@ -//using System; -//using System.Collections.Generic; -//using System.Linq; -//using System.Text; -//using System.Threading.Tasks; - -//namespace PvZ_Fusion_Translator.Patches.Managers -//{ -// public class AbyssInfo_Patch -// { -// } -//} \ No newline at end of file diff --git a/BepInEx/Patches/Managers/AbyssMenu2_Patch.cs b/BepInEx/Patches/Managers/AbyssMenu2_Patch.cs deleted file mode 100644 index 6d02d4b..0000000 --- a/BepInEx/Patches/Managers/AbyssMenu2_Patch.cs +++ /dev/null @@ -1,101 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers -{ - [HarmonyPatch(typeof(AbyssMenu2))] - public static class AbyssMenu2_Patch - { - private static void UpdateAbyss2Text(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); - - // Translate option buttons - Transform optionsTransform = __instance.transform.FindChild("Options").transform; - foreach (TextMeshProUGUI textMesh in optionsTransform.GetComponentsInChildren()) - { - textMesh.text = StringStore.TranslateText(textMesh.text); - } - - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - text.font = fontAsset; - } - } - - [HarmonyPatch(nameof(AbyssMenu2.Start))] - [HarmonyPostfix] - private static void Start(AbyssMenu2 __instance) - { - UpdateAbyss2Text(__instance); - Utils.ConvertButtonText(__instance.transform, "Help"); - - // custom bag text - __instance.transform.FindChild("Bag").FindChild("text").GetComponent().text += "_深渊"; - Utils.ConvertButtonText(__instance.transform, "Bag"); - } - - [HarmonyPatch(nameof(AbyssMenu2.Awake))] - [HarmonyPostfix] - private static void Awake(AbyssMenu2 __instance) - { - UpdateAbyss2Text(__instance); - } - - [HarmonyPatch(nameof(AbyssMenu2.UpdateIcons))] - [HarmonyPostfix] - private static void UpdateIcons(AbyssMenu2 __instance) - { - UpdateAbyss2Text(__instance); - } - - [HarmonyPatch(nameof(AbyssMenu2.UpdateBuff))] - [HarmonyPostfix] - private static void UpdateBuff(AbyssMenu2 __instance) - { - UpdateAbyss2Text(__instance); - } - - [HarmonyPatch(nameof(AbyssMenu2.BuyBuff))] - [HarmonyPostfix] - private static void BuyBuff(AbyssMenu2 __instance) - { - UpdateAbyss2Text(__instance); - } - - [HarmonyPatch(nameof(AbyssMenu2.ShowBag))] - [HarmonyPostfix] - private static void ShowBag(AbyssMenu2 __instance) - { - UpdateAbyss2Text(__instance); - } - } -} diff --git a/BepInEx/Patches/Managers/AbyssMenu_Patch.cs b/BepInEx/Patches/Managers/AbyssMenu_Patch.cs deleted file mode 100644 index 0c60bcb..0000000 --- a/BepInEx/Patches/Managers/AbyssMenu_Patch.cs +++ /dev/null @@ -1,26 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; - -namespace PvZ_Fusion_Translator__BepInEx_.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/BepInEx/Patches/Managers/AlmanacMgrZombie_Patch.cs b/BepInEx/Patches/Managers/AlmanacMgrZombie_Patch.cs deleted file mode 100644 index 002d522..0000000 --- a/BepInEx/Patches/Managers/AlmanacMgrZombie_Patch.cs +++ /dev/null @@ -1,145 +0,0 @@ -using HarmonyLib; -using System; -using System.Collections.Generic; -using System.IO; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; -using static PvZ_Fusion_Translator__BepInEx_.FileLoader; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers -{ - [HarmonyPatch(typeof(AlmanacMgrZombie))] - public static partial class AlmanacMgrZombie_Patch - { - [HarmonyPatch(nameof(AlmanacMgrZombie.InitNameAndInfoFromJson))] - [HarmonyPostfix] - private static void 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"); - string moddedPath = Path.Combine(almanacDir, "ModdedZombiesTranslate.json"); - - if (!File.Exists(path)) - { - Log.LogError($"ZombieStringsTranslate.json file not found at path: {path}"); - return; - } - -#if OBFUSCATE - if (CheckSumStore.IsModified(path)) - { - Log.LogError("File {0} was modified!", path); - return; - } -#endif - - string json; - json = File.ReadAllText(path); - - bool hasAlmanacFont = false; - TMP_FontAsset almanacFontAsset = null; - if (FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage + "_Almanac") || FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage)) - { - almanacFontAsset = FontStore.LoadTMPFontAlmanac(currentLanguage); - hasAlmanacFont = true; - } - -#if MULTI_LANGUAGE - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); -#else - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(); -#endif - - TextMeshPro component = __instance.info.GetComponent(); - TextMeshPro component2 = __instance.zombieName.GetComponent(); - TextMeshPro component3 = __instance.zombieName.transform.GetChild(0).GetComponent(); - - ZombieAlmanacData zombieData = JsonUtility.FromJson(json); - - foreach (ZombieInfo zombieInfo in zombieData.zombies) - { - if (zombieInfo.theZombieType == __instance.theZombieType) - { - component.text = zombieInfo.info + "\n\n" + zombieInfo.introduce; - component.overflowMode = TextOverflowModes.Page; - component2.text = zombieInfo.name; - component2.autoSizeTextContainer = true; - component3.text = Utils.RemoveColorTags(zombieInfo.name); - component3.autoSizeTextContainer = true; - - if (hasAlmanacFont) - component.font = almanacFontAsset; - else - component.font = fontAsset; - component2.font = fontAsset; - component3.font = fontAsset; - } - } - - if (File.Exists(moddedPath)) - { - string moddedJson; - moddedJson = File.ReadAllText(moddedPath); - - ZombieAlmanacData moddedZombieData = JsonUtility.FromJson(moddedJson); - - foreach (ZombieInfo zombieInfo in moddedZombieData.zombies) - { - if (zombieInfo.theZombieType == __instance.theZombieType) - { - component.text = zombieInfo.info + "\n\n" + zombieInfo.introduce; - component.overflowMode = TextOverflowModes.Page; - component2.text = zombieInfo.name; - component2.autoSizeTextContainer = true; - component3.text = Utils.RemoveColorTags(zombieInfo.name); - component3.autoSizeTextContainer = true; - - if (hasAlmanacFont) - component.font = almanacFontAsset; - else - component.font = fontAsset; - component2.font = fontAsset; - component3.font = fontAsset; - } - } - } - - return; - } - - [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; - } - } - - [Serializable] - public class ZombieAlmanacData - { - public List zombies; - } - - [Serializable] - public class ZombieInfo - { - public string name; - public string info; - public string introduce; - public ZombieType theZombieType; - } -} diff --git a/BepInEx/Patches/Managers/AlmanacPlantBank_Patch.cs b/BepInEx/Patches/Managers/AlmanacPlantBank_Patch.cs deleted file mode 100644 index 9e23635..0000000 --- a/BepInEx/Patches/Managers/AlmanacPlantBank_Patch.cs +++ /dev/null @@ -1,200 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using System.IO; -using UnityEngine; -using static PvZ_Fusion_Translator__BepInEx_.FileLoader; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers -{ - [HarmonyPatch(typeof(AlmanacPlantBank))] - public static partial class AlmanacPlantBank_Patch - { - [HarmonyPatch(nameof(AlmanacPlantBank.InitNameAndInfoFromJson))] - [HarmonyPostfix] - private static void InitNameAndInfoFromJson(AlmanacPlantBank __instance) - { -#if MULTI_LANGUAGE - string currentLanguage = Utils.Language.ToString(); - string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); -#else - string almanacDir = GetAssetDir(AssetType.Almanac); - string currentLanguage = "English"; -#endif - string path = Path.Combine(almanacDir, "LawnStringsTranslate.json"); - string moddedPath = Path.Combine(almanacDir, "ModdedPlantsTranslate.json"); - - if (!File.Exists(path)) - { - Log.LogError($"LawnStringsTranslate.json file not found at path: {path}"); - return; - } - -#if OBFUSCATE - if (CheckSumStore.IsModified(path)) - { - Log.LogError("File {0} was modified!", path); - return; - } -#endif - - string json; - json = File.ReadAllText(path); - - bool hasAlmanacFont = false; - TMP_FontAsset almanacFontAsset = null; - if (FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage + "_Almanac") || FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage)) - { - almanacFontAsset = FontStore.LoadTMPFontAlmanac(currentLanguage); - hasAlmanacFont = true; - } - -#if MULTI_LANGUAGE - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); -#else - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(); -#endif - - TextMeshPro component = __instance.introduce.GetComponent(); - TextMeshPro component2 = __instance.plantName.GetComponent(); - TextMeshPro component3 = __instance.plantName.transform.GetChild(0).GetComponent(); - TextMeshPro component4 = __instance.cost.GetComponent(); - - AlmanacPlantBank.PlantData plantData = JsonUtility.FromJson(json); - - foreach (AlmanacPlantBank.PlantInfo plantInfo in plantData.plants) - { - if (plantInfo.seedType == __instance.theSeedType && !string.IsNullOrEmpty(plantInfo.name)) - { - component.autoSizeTextContainer = false; - component.text = plantInfo.info + "\n\n" + plantInfo.introduce; - component.overflowMode = TextOverflowModes.Page; - - // fix dimensions for cost text - component.rectTransform.offsetMax = new Vector2(component.rectTransform.offsetMax.x, 27.3839f); - component.rectTransform.offsetMin = new Vector2(component.rectTransform.offsetMin.x, -29.3079f); - component.rectTransform.sizeDelta = new Vector2(component.rectTransform.sizeDelta.x, 50.917f); - component.transform.localPosition = new Vector3(component.transform.localPosition.x, component.transform.localPosition.y + 0.15f, component.transform.localPosition.z); - - - component2.text = plantInfo.name; - component2.autoSizeTextContainer = true; - - component3.text = Utils.RemoveColorTags(plantInfo.name ?? string.Empty); - component3.autoSizeTextContainer = true; - - component4.text = plantInfo.cost; - - if (hasAlmanacFont) - { - component.font = almanacFontAsset; - component4.font = almanacFontAsset; - } - else - { - component.font = fontAsset; - component4.font = fontAsset; - } - component2.font = fontAsset; - component3.font = fontAsset; - } - } - - if (File.Exists(moddedPath)) - { - string moddedJson; - moddedJson = File.ReadAllText(moddedPath); - - AlmanacPlantBank.PlantData moddedPlantData = JsonUtility.FromJson(moddedJson); - - foreach (AlmanacPlantBank.PlantInfo plantInfo in moddedPlantData.plants) - { - if (plantInfo.seedType == __instance.theSeedType && !string.IsNullOrEmpty(plantInfo.name)) - { - component.autoSizeTextContainer = false; - component.text = plantInfo.info + "\n\n" + plantInfo.introduce; - component.overflowMode = TextOverflowModes.Page; - - // fix dimensions for cost text - component.rectTransform.offsetMax = new Vector2(component.rectTransform.offsetMax.x, 27.3839f); - component.rectTransform.offsetMin = new Vector2(component.rectTransform.offsetMin.x, -29.3079f); - component.rectTransform.sizeDelta = new Vector2(component.rectTransform.sizeDelta.x, 50.917f); - component.transform.localPosition = new Vector3(component.transform.localPosition.x, component.transform.localPosition.y + 0.15f, component.transform.localPosition.z); - - - component2.text = plantInfo.name; - component2.autoSizeTextContainer = true; - - component3.text = Utils.RemoveColorTags(plantInfo.name ?? string.Empty); - 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; - } - - [HarmonyPatch(nameof(AlmanacPlantBank.OnMouseDown))] - [HarmonyPrefix] - private static bool OnMouseDown(AlmanacPlantBank __instance) - { - TextMeshPro component = __instance.introduce.GetComponent(); - if (component != null) - { - component.pageToDisplay = component.pageToDisplay > component.m_pageNumber ? 1 : component.pageToDisplay + 1; - return false; - } - return true; - } - - [HarmonyPatch(nameof(AlmanacPlantBank.PVPInit))] - [HarmonyPostfix] - private static void PVPInit(AlmanacPlantBank __instance) - { - TextMeshPro component = __instance.introduce.GetComponent(); - if (component != null) - { - component.autoSizeTextContainer = false; - } - - Transform banTransform = __instance.transform.FindChild("Ban").GetChild(0); - if (banTransform != null) - { - banTransform.GetComponent().text = StringStore.TranslateText(banTransform.GetComponent().text); - } - } - - [HarmonyPatch(nameof(AlmanacPlantBank.Start))] - [HarmonyPostfix] - public static void Post_Start(AlmanacPlantBank __instance) - { - GameObject skinTextObj = __instance.skinButton.transform.GetChild(0).gameObject; - GameObject skinShadowTextObj = UnityEngine.Object.Instantiate(skinTextObj, parent: __instance.skinButton.transform); - TextMeshPro skinShadowText = skinShadowTextObj.GetComponent(); - skinShadowText.text = StringStore.TranslateText("换肤_S"); - skinShadowText.sortingOrder -= 2; - skinShadowTextObj.transform.Translate(new Vector3(0.015f, -0.015f, 0)); - skinTextObj.transform.Translate(new Vector3(-0.022f, 0)); - skinShadowTextObj.transform.Translate(new Vector3(-0.022f, 0)); - __instance.skinButton.transform.localScale /= 1.75f; - __instance.skinButton.transform.Translate(new Vector3(-0.075f, -0.15f, 0)); - __instance.skinButton.transform.GetChild(1).Translate(new Vector3(0.35f, 0)); - __instance.skinButton.transform.GetChild(2).Translate(new Vector3(-0.35f, 0)); - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/Managers/CanvasUpUI_Patch.cs b/BepInEx/Patches/Managers/CanvasUpUI_Patch.cs deleted file mode 100644 index c73b142..0000000 --- a/BepInEx/Patches/Managers/CanvasUpUI_Patch.cs +++ /dev/null @@ -1,34 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using PvZ_Fusion_Translator__BepInEx_; -using System; -using System.Linq; -using System.Collections.Generic; -using System.Text.RegularExpressions; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers -{ - [HarmonyPatch(typeof(CanvasUpUI))] - public static class CanvasUpUI_Patch - { - [HarmonyPatch(nameof(CanvasUpUI.Start))] - [HarmonyPostfix] - public static void Start(CanvasUpUI __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach(TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - string originalKey = StringStore.translationString.FirstOrDefault(x => (x.Value == text.text || x.Value.Replace("\n", "") == text.text)).Key; - text.text = (StringStore.translationString.ContainsKey(originalKey + "_MG")) ? StringStore.TranslateText(originalKey + "_MG") : StringStore.TranslateText(text.text); - if(text.gameObject.name.Contains("LevelName")) - { - text.text = text.text.Replace("\n", " "); - } - text.font = fontAsset; - } - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/Managers/ChessManager_Patch.cs b/BepInEx/Patches/Managers/ChessManager_Patch.cs deleted file mode 100644 index 1c2f52f..0000000 --- a/BepInEx/Patches/Managers/ChessManager_Patch.cs +++ /dev/null @@ -1,37 +0,0 @@ -using HarmonyLib; -using System; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; -using UnityEngine.TextCore.Text; -using UnityEngine.UI; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(ChessManager))] - public static class ChessManager_Patch - { - [HarmonyPatch(nameof(ChessManager.Start))] - [HarmonyPostfix] - private static void Postfix_Start(ChessManager __instance) - { - __instance.textMesh.text = StringStore.TranslateText(__instance.textMesh.text); - __instance.textMesh.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - - [HarmonyPatch(nameof(ChessManager.Update))] - [HarmonyPostfix] - private static void Postfix_Update(ChessManager __instance) - { - __instance.textMesh.text = StringStore.TranslateText(__instance.textMesh.text); - __instance.textMesh.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - - [HarmonyPatch(nameof(ChessManager.UpdateText))] - [HarmonyPostfix] - private static void Postfix_UpdateText(ChessManager __instance) - { - __instance.textMesh.text = StringStore.TranslateText(__instance.textMesh.text); - __instance.textMesh.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } -} diff --git a/BepInEx/Patches/Managers/CustomLevelShower_Patch.cs b/BepInEx/Patches/Managers/CustomLevelShower_Patch.cs deleted file mode 100644 index 81f4a72..0000000 --- a/BepInEx/Patches/Managers/CustomLevelShower_Patch.cs +++ /dev/null @@ -1,23 +0,0 @@ -#if FIX -using HarmonyLib; -using System; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.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/BepInEx/Patches/Managers/DifficultyMgr_Patch.cs b/BepInEx/Patches/Managers/DifficultyMgr_Patch.cs deleted file mode 100644 index 84585b5..0000000 --- a/BepInEx/Patches/Managers/DifficultyMgr_Patch.cs +++ /dev/null @@ -1,18 +0,0 @@ -using HarmonyLib; -using System; -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/BepInEx/Patches/Managers/DrawCardManager_Patch.cs b/BepInEx/Patches/Managers/DrawCardManager_Patch.cs deleted file mode 100644 index c85ca88..0000000 --- a/BepInEx/Patches/Managers/DrawCardManager_Patch.cs +++ /dev/null @@ -1,61 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using Il2CppSystem.Collections.Generic; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; -using UnityEngine.TextCore.Text; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects -{ - [HarmonyPatch(typeof(DrawCardManager))] - public static class DrawCardManager_Patch - { - [HarmonyPatch(nameof(DrawCardManager.UpdateText))] - [HarmonyPostfix] - private static void Postfix_UpdateText(DrawCardManager __instance) - { - Il2CppSystem.Collections.Generic.List texts = __instance.texts; - __instance.upName = StringStore.TranslateText(__instance.upName); - if (texts != null && texts.Count > 0) - { - foreach (TextMeshProUGUI textComponent in texts) - { - if (textComponent != null) - { - string translatedText = StringStore.TranslateText(textComponent.text); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - textComponent.text = translatedText; - textComponent.font = fontAsset; - } - } - } - } - - - - [HarmonyPatch(nameof(DrawCardManager.Update))] - [HarmonyPostfix] - private static void Postfix_Update(DrawCardManager __instance) - { - Il2CppSystem.Collections.Generic.List texts = __instance.texts; - __instance.upName = StringStore.TranslateText(__instance.upName); - - if (texts != null && texts.Count > 0) - { - foreach (TextMeshProUGUI textComponent in texts) - { - if (textComponent != null) - { - string translatedText = StringStore.TranslateText(textComponent.text); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - textComponent.text = translatedText; - textComponent.font = fontAsset; - } - } - } - - } - } -} - diff --git a/BepInEx/Patches/Managers/EndlessMgr_Patch.cs b/BepInEx/Patches/Managers/EndlessMgr_Patch.cs deleted file mode 100644 index b137eff..0000000 --- a/BepInEx/Patches/Managers/EndlessMgr_Patch.cs +++ /dev/null @@ -1,27 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -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/BepInEx/Patches/Managers/GameAPP_Patch.cs b/BepInEx/Patches/Managers/GameAPP_Patch.cs deleted file mode 100644 index 3fdccef..0000000 --- a/BepInEx/Patches/Managers/GameAPP_Patch.cs +++ /dev/null @@ -1,27 +0,0 @@ -using HarmonyLib; -using TMPro; -using UnityEngine.EventSystems; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers -{ - [HarmonyPatch(typeof(GameAPP))] - public class GameAPP_Patch - { - [HarmonyPatch(nameof(GameAPP.Update))] - [HarmonyPrefix] - private static bool Update(GameAPP __instance) - { - Core.Instance.OnUpdate(); - - if (EventSystem.current?.currentSelectedGameObject != null) - { - if (EventSystem.current.currentSelectedGameObject.TryGetComponent(out TMP_InputField field)) - { - __instance.MusicUpdate(); - return false; - } - } - return true; - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/Managers/Garden_Patch.cs b/BepInEx/Patches/Managers/Garden_Patch.cs deleted file mode 100644 index 6548f63..0000000 --- a/BepInEx/Patches/Managers/Garden_Patch.cs +++ /dev/null @@ -1,21 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers -{ - [HarmonyPatch(typeof(Garden))] - public static class Garden_Patch - { - [HarmonyPatch(nameof(Garden.Awake))] - [HarmonyPostfix] - private static void Awake(Garden __instance) - { - foreach (TextMeshPro text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - text.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } - } -} diff --git a/BepInEx/Patches/Managers/IZBottomMenu_Patch.cs b/BepInEx/Patches/Managers/IZBottomMenu_Patch.cs deleted file mode 100644 index c114a24..0000000 --- a/BepInEx/Patches/Managers/IZBottomMenu_Patch.cs +++ /dev/null @@ -1,54 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using System.Text.RegularExpressions; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers -{ - [HarmonyPatch(typeof(IZBottomMenu))] - public static class IZBottomMenu_Patch - { - [HarmonyPatch(nameof(IZBottomMenu.ChangeString))] - [HarmonyPostfix] - public static void ChangeStringz(IZBottomMenu __instance) - { - foreach (TextMeshProUGUI text in __instance.levelName) - { - string fStr = StringStore.translationStringRegex["([^\\s]+),推荐难度:(\\d+)"]; - string[] parts = text.text.Split(",推荐难度:"); - - if (new Regex("([^\\s]+),推荐难度:(\\d+)").IsMatch(text.text)) - { - string customName = (StringStore.translationString.ContainsKey(parts[0] + "_IZ")) ? parts[0] + "_IZ" : parts[0]; - text.text = string.Format(fStr, StringStore.TranslateText(customName), parts[1]); - } - - text.text = StringStore.TranslateText(text.text); - text.text = text.text.Replace("\n", " "); - } - } - - [HarmonyPatch(nameof(IZBottomMenu.SetLevelName))] - [HarmonyPostfix] - public static void SetLevelName(IZBottomMenu __instance) - { - foreach (TextMeshProUGUI text in __instance.levelName) - { - string fStr = StringStore.translationStringRegex["([^\\s]+),推荐难度:(\\d+)"]; - string[] parts = text.text.Split(",推荐难度:"); - - if (new Regex("([^\\s]+),推荐难度:(\\d+)").IsMatch(text.text)) - { - text.text = string.Format(fStr, StringStore.TranslateText(parts[0]), parts[1]); - } - - text.text = StringStore.TranslateText(text.text); - text.text = text.text.Replace("\n", " "); - } - } - } -} - - diff --git a/BepInEx/Patches/Managers/InGameUIMgr_Patch.cs b/BepInEx/Patches/Managers/InGameUIMgr_Patch.cs deleted file mode 100644 index 8d698ec..0000000 --- a/BepInEx/Patches/Managers/InGameUIMgr_Patch.cs +++ /dev/null @@ -1,34 +0,0 @@ -using HarmonyLib; -using System; - -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; - -namespace PvZ_Fusion_Translator__BepInEx_.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/BepInEx/Patches/Managers/InGameUI_Patch.cs b/BepInEx/Patches/Managers/InGameUI_Patch.cs deleted file mode 100644 index 6b2c63a..0000000 --- a/BepInEx/Patches/Managers/InGameUI_Patch.cs +++ /dev/null @@ -1,78 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using System.Text.RegularExpressions; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers -{ - [HarmonyPatch(typeof(InGameUI))] - public static class InGameUI_Patch - { - [HarmonyPatch(nameof(InGameUI.Start))] - [HarmonyPostfix] - private static void Start(InGameUI __instance) - { - TextMeshProUGUI[] array = new TextMeshProUGUI[] - { - __instance.transform.GetChild(4).GetComponent(), - __instance.transform.GetChild(4).GetChild(0).GetComponent(), - __instance.transform.GetChild(5).GetComponent(), - __instance.transform.GetChild(5).GetChild(0).GetComponent(), - __instance.transform.GetChild(6).GetComponent(), - __instance.transform.GetChild(6).GetChild(0).GetComponent()}; - TextMeshProUGUI[] array2 = array; - for (int i = 0; i < array2.Length; i++) - { - string originalText = array2[i].text; - array2[i].text = array2[i].text.Replace("\n", " "); - Regex checkFusionChallenge = new Regex("^超级([^\\s:]+)(:?挑战1?)"); - - if (array2[i].text.Contains("配方:") && !checkFusionChallenge.IsMatch(array2[i].text)) - { - string[] lines = array2[i].text.Split(":"); - lines[1] = Utils.GetPlantNameFromAlmanac(lines[1]); - if (lines[1] == "") - { - Log.LogError("Couldn't find plant! (Fusion Showcase)"); - lines[1] = StringStore.TranslateText(lines[1]); - } - array2[i].text = StringStore.TranslateText("配方:") + lines[1]; - array2[i].autoSizeTextContainer = true; - } - else - { - array2[i].text = (StringStore.translationString.ContainsKey(array2[i].text + "_MG")) ? StringStore.TranslateText(array2[i].text + "_MG") : StringStore.TranslateText(array2[i].text); - array2[i].text = array2[i].text.Replace("\n", " "); - } - } - } - - [HarmonyPatch(nameof(InGameUI.Update))] - [HarmonyPostfix] - private static void Update(InGameUI __instance) - { - foreach(TextMeshProUGUI txt in __instance.ShovelBank.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } - } - - [HarmonyPatch(typeof(InGameUI_IZ))] - public static class InGameUI_IZ_Patch - { - [HarmonyPatch(nameof(InGameUI_IZ.Update))] - [HarmonyPostfix] - private static void Update(InGameUI_IZ __instance) - { - foreach (TextMeshProUGUI txt in __instance.shovel.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } - } -} diff --git a/BepInEx/Patches/Managers/OppositeBuffManager_Patch.cs b/BepInEx/Patches/Managers/OppositeBuffManager_Patch.cs deleted file mode 100644 index b35fa41..0000000 --- a/BepInEx/Patches/Managers/OppositeBuffManager_Patch.cs +++ /dev/null @@ -1,48 +0,0 @@ -using HarmonyLib; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using System.Collections.Generic; -using System.Text.RegularExpressions; -using TMPro; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers -{ - [HarmonyPatch(typeof(OppositeBuffManager))] - public static class OppositeBuffManager_Patch - { - public static Dictionary buffLinks = TravelMgr_Patch.buffLinks; - public static Dictionary> translatedTravelBuffs = TravelMgr_Patch.translatedTravelBuffs; - public static string badPattern = @"^但(.*)"; - public static string badFormat = StringStore.translationStringRegex.ContainsKey(badPattern) ? StringStore.translationStringRegex[badPattern] : "But, {0}"; - public static TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - [HarmonyPatch(nameof(OppositeBuffManager.Awake))] - [HarmonyPostfix] - private static void Awake(OppositeBuffManager __instance) - { - TranslateOppositeText(__instance.textA_bad, BuffType.Debuff, __instance.buffA.theDebuffID, true); - TranslateOppositeText(__instance.textA_good, __instance.buffA.theOptionType, __instance.buffA.theOptionID); - TranslateOppositeText(__instance.textB_bad, BuffType.Debuff, __instance.buffB.theDebuffID, true); - TranslateOppositeText(__instance.textB_good, __instance.buffB.theOptionType, __instance.buffB.theOptionID); - } - - public static void TranslateOppositeText(Il2CppSystem.Collections.Generic.List textList, BuffType buffType, int buffIndex, bool isBad = false) - { - string buff = translatedTravelBuffs[buffLinks[buffType]][buffIndex]; - - foreach (var text in textList) - { - if (isBad) - { - text.text = string.Format(badFormat, buff); - } - else - { - text.text = buff; - } - - text.font = fontAsset; - } - } - } -} diff --git a/BepInEx/Patches/Managers/SaveMenu_Patch.cs b/BepInEx/Patches/Managers/SaveMenu_Patch.cs deleted file mode 100644 index aa5d1f0..0000000 --- a/BepInEx/Patches/Managers/SaveMenu_Patch.cs +++ /dev/null @@ -1,28 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; - -namespace PvZ_Fusion_Translator__BepInEx_.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; - - foreach(SaveMenuBtn level in __instance.levels) - { - level.theName.text = StringStore.TranslateText(level.theName.text); - } - } - } -} diff --git a/BepInEx/Patches/Managers/TowerManager_Patch.cs b/BepInEx/Patches/Managers/TowerManager_Patch.cs deleted file mode 100644 index 71d3656..0000000 --- a/BepInEx/Patches/Managers/TowerManager_Patch.cs +++ /dev/null @@ -1,33 +0,0 @@ -using HarmonyLib; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using TMPro; -using BepInEx.Unity.IL2CPP; -using System.Collections.Generic; -using UnityEngine; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers -{ - [HarmonyPatch(typeof(TowerManager))] - public static class TowerManager_Patch - { - public static List updatedText = []; - - public static void UpdateText() - { - foreach (Transform transform in updatedText) - { - if (transform != null) - { - transform.GetComponent().text = StringStore.TranslateText(transform.GetComponent().text); - } - } - } - - [HarmonyPatch(nameof(TowerManager.Update))] - [HarmonyPostfix] - public static void Update(TowerManager __instance) - { - - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/Managers/TravelBuffMgr_Patch.cs b/BepInEx/Patches/Managers/TravelBuffMgr_Patch.cs deleted file mode 100644 index c72829f..0000000 --- a/BepInEx/Patches/Managers/TravelBuffMgr_Patch.cs +++ /dev/null @@ -1,27 +0,0 @@ -using HarmonyLib; -using System; -using System.Text.Encodings.Web; -using System.Text.Json; - -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 = 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/BepInEx/Patches/Managers/TravelMgr_Patch.cs b/BepInEx/Patches/Managers/TravelMgr_Patch.cs deleted file mode 100644 index 51d56e8..0000000 --- a/BepInEx/Patches/Managers/TravelMgr_Patch.cs +++ /dev/null @@ -1,103 +0,0 @@ -using TMPro; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.Encodings.Web; -using System.Text.Json; -using System.IO; -using System.Threading.Tasks; -using HarmonyLib; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers -{ - [HarmonyPatch(typeof(TravelMgr))] - public static class TravelMgr_Patch - { - public static Dictionary buffLinks = new Dictionary() - { - { BuffType.AdvancedBuff, "advancedUpgrades" }, - { BuffType.UltimateBuff, "ultimateUpgrades" }, - { BuffType.UnlockPlant, "strongUltimates" }, - { BuffType.Debuff, "debuffs" }, - }; - - public static Dictionary> dumpedTravelBuffs = new Dictionary>() - { - { "advancedUpgrades", [] }, - { "ultimateUpgrades", [] }, - { "strongUltimates", [] }, - { "debuffs", [] } - }; - - public static Dictionary> translatedTravelBuffs = new Dictionary>(); - - public static void DumpTravelBuffs(Il2CppSystem.Collections.Generic.Dictionary source, Dictionary> dest, string index) - { - foreach (var i in source) - { - if (!Utils.CheckForUntranslatedText(i.Value)) - { - break; - } - dest[index].Add(i.Value); - } - } - - public static string MatchTravelBuff(string originalText) - { - string res = ""; - - foreach(var i in dumpedTravelBuffs) - { - if(i.Value.Contains(originalText)) - { - res = translatedTravelBuffs[i.Key][i.Value.IndexOf(originalText)]; - break; - } - } - - return res; - } - - [HarmonyPatch(nameof(TravelMgr.Awake))] - [HarmonyPrefix] - private static void Pre_Awake(TravelMgr __instance) - { - // Dump buffs - - dumpedTravelBuffs = new Dictionary>() // reset dump - { - { "advancedUpgrades", [] }, - { "ultimateUpgrades", [] }, - { "strongUltimates", [] }, - { "debuffs", [] } - }; - - DumpTravelBuffs(TravelMgr.advancedBuffs, dumpedTravelBuffs, "advancedUpgrades"); - DumpTravelBuffs(TravelMgr.ultimateBuffs, dumpedTravelBuffs, "ultimateUpgrades"); - DumpTravelBuffs(TravelMgr.unlocks, dumpedTravelBuffs, "strongUltimates"); - DumpTravelBuffs(TravelMgr.debuffs, dumpedTravelBuffs, "debuffs"); - - string dumpDir = FileLoader.GetAssetDir(FileLoader.AssetType.Dumps); - var options = new JsonSerializerOptions - { - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, - WriteIndented = true - }; - File.WriteAllText(Path.Combine(dumpDir, "travel_buffs.json"), JsonSerializer.Serialize(dumpedTravelBuffs, options)); - - string stringDir = FileLoader.GetAssetDir(FileLoader.AssetType.Strings, Utils.Language); - string travelBuffDir = Path.Combine(stringDir, "travel_buffs.json"); - - if(!File.Exists(travelBuffDir)) - { - File.WriteAllText(travelBuffDir, JsonSerializer.Serialize(dumpedTravelBuffs, options)); - } - - string travelBuffs = File.ReadAllText(Path.Combine(stringDir, "travel_buffs.json")); - - translatedTravelBuffs = JsonSerializer.Deserialize>>(travelBuffs); - } - } -} \ No newline at end of file diff --git a/BepInEx/Patches/Managers/TreasureManager_Patch.cs b/BepInEx/Patches/Managers/TreasureManager_Patch.cs deleted file mode 100644 index 6375434..0000000 --- a/BepInEx/Patches/Managers/TreasureManager_Patch.cs +++ /dev/null @@ -1,31 +0,0 @@ -using HarmonyLib; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; - -namespace PvZ_Fusion_Translator__BepInEx_.Patches.Managers -{ - [HarmonyPatch(typeof(TreasureManager))] - public static class TreasureManager_Patch - { - [HarmonyPatch(nameof(TreasureManager.Update))] - [HarmonyPostfix] - private static void Update(TreasureManager __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.evaText) - { - txt.autoSizeTextContainer = false; - - if (txt.text != "Evacuate") - { - txt.text = StringStore.TranslateText(txt.text); - txt.name = txt.text + "_EVACUATE"; - txt.font = fontAsset; - } - } - } - } -} - - diff --git a/BepInEx/Patches/Managers/UIMgr_Patch.cs b/BepInEx/Patches/Managers/UIMgr_Patch.cs deleted file mode 100644 index 12f5d50..0000000 --- a/BepInEx/Patches/Managers/UIMgr_Patch.cs +++ /dev/null @@ -1,22 +0,0 @@ -using HarmonyLib; -using System; -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"); - // #if MULTI_LANGUAGE - // WarningStore.WarningReload(Utils.Language); - // #else - // WarningStore.WarningReload(); - // #endif - //} - } -} \ No newline at end of file diff --git a/BepInEx/Patches/OtherManagers/AchievementClip_Patch.cs b/BepInEx/Patches/OtherManagers/AchievementClip_Patch.cs deleted file mode 100644 index 2c3de3d..0000000 --- a/BepInEx/Patches/OtherManagers/AchievementClip_Patch.cs +++ /dev/null @@ -1,73 +0,0 @@ -using HarmonyLib; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using TMPro; -using Newtonsoft.Json; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using static PvZ_Fusion_Translator__BepInEx_.FileLoader; -using static PvZ_Fusion_Translator__BepInEx_.Patches.Managers.AlmanacPlantBank_Patch; - -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) - { - #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/BepInEx/Patches/OtherManagers/GardenUI_Patch.cs b/BepInEx/Patches/OtherManagers/GardenUI_Patch.cs deleted file mode 100644 index d313017..0000000 --- a/BepInEx/Patches/OtherManagers/GardenUI_Patch.cs +++ /dev/null @@ -1,22 +0,0 @@ -using HarmonyLib; -using System; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using UnityEngine; - -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); - - // Transform PageText = __instance.transform.Find("PageText"); - // StringStore.TranslateTextTransform(PageText.transform); - } - } -} diff --git a/BepInEx/Patches/OtherManagers/MenuText_Patch.cs b/BepInEx/Patches/OtherManagers/MenuText_Patch.cs deleted file mode 100644 index 8aaf4f2..0000000 --- a/BepInEx/Patches/OtherManagers/MenuText_Patch.cs +++ /dev/null @@ -1,23 +0,0 @@ -#if FIX -using HarmonyLib; -using System; -using TMPro; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; - -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); - } - } -} -#endif \ No newline at end of file diff --git a/BepInEx/Patches/OtherManagers/ThanksMenu_Patch.cs b/BepInEx/Patches/OtherManagers/ThanksMenu_Patch.cs deleted file mode 100644 index cf94e6c..0000000 --- a/BepInEx/Patches/OtherManagers/ThanksMenu_Patch.cs +++ /dev/null @@ -1,23 +0,0 @@ -using HarmonyLib; -using System; -using TMPro; -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; - } - } - } -} \ No newline at end of file diff --git a/BepInEx/PvZ Fusion Translator [BepInEx].csproj b/BepInEx/PvZ Fusion Translator [BepInEx].csproj deleted file mode 100644 index d1a8ddf..0000000 --- a/BepInEx/PvZ Fusion Translator [BepInEx].csproj +++ /dev/null @@ -1,614 +0,0 @@ - - - - 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\Admin\Downloads\PvZ FUSION VH FANMADE - C:\Users\rainb\Desktop\PC_PVZ-Fusion_3.1.1 - Debug;DebugEnglish;ReleaseMulti;ReleaseEnglish;DebugTesting;ReleaseOther;DebugObfuscate;ReleaseObfuscate;DebugMulti - AnyCPU;x64 - - - - - - - - - - - True - false - - - - $(DefineConstants);MULTI_LANGUAGE;CHEAT;DEBUG - - - - $(DefineConstants);MULTI_LANGUAGE;CHEAT;DEBUG;OBFUSCATE - - - - $(DefineConstants);MULTI_LANGUAGE;CHEAT;DEBUG - - - - $(DefineConstants);MULTI_LANGUAGE;CHEAT;DEBUG;OBFUSCATE - - - - $(DefineConstants);MULTI_LANGUAGE;CHEAT;DEBUG - - - - $(DefineConstants);MULTI_LANGUAGE;CHEAT;DEBUG;OBFUSCATE - - - - $(DefineConstants);MULTI_LANGUAGE;CHEAT;TESTING;DEBUG - - - - $(DefineConstants);MULTI_LANGUAGE;CHEAT;TESTING;DEBUG - - - - $(DefineConstants);MULTI_LANGUAGE;CHEAT;TESTING;DEBUG - - - - $(DefineConstants);CHEAT;DEBUG - - - - $(DefineConstants);CHEAT;DEBUG - - - - $(DefineConstants);CHEAT;DEBUG - - - - $(DefineConstants);MULTI_LANGUAGE;OBFUSCATE - - - - $(DefineConstants);MULTI_LANGUAGE;OBFUSCATE - - - - $(DefineConstants);MULTI_LANGUAGE;OBFUSCATE - - - - $(DefineConstants);OTHER;OBFUSCATE - - - - $(DefineConstants);OTHER;OBFUSCATE - - - - $(DefineConstants);OTHER;OBFUSCATE - - - - $(DefineConstants);MULTI_LANGUAGE;OBFUSCATE;RELEASE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $(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 - - - $(GamePath)\BepInEx\interop\Assembly-CSharp.dll - - - $(GamePath)\BepInEx\plugins\AudioImportLib.BepInEx.dll - - - $(GamePath)\BepInEx\core\Newtonsoft.Json.dll - - - - - - - - - diff --git a/BepInEx/Utils.cs b/BepInEx/Utils.cs deleted file mode 100644 index a09ed3a..0000000 --- a/BepInEx/Utils.cs +++ /dev/null @@ -1,430 +0,0 @@ -using BepInEx; -using BepInEx.Configuration; -using PvZ_Fusion_Translator__BepInEx_.AssetStore; -using PvZ_Fusion_Translator__BepInEx_.Patches.Managers; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Text.RegularExpressions; -using TMPro; -using Unity.Burst.Intrinsics; -using Unity.VisualScripting.FullSerializer; -using UnityEngine; -using UnityEngine.Experimental.Rendering; -using UnityEngine.UI; -using static AlmanacPlantBank; -using static PvZ_Fusion_Translator__BepInEx_.FileLoader; - -namespace PvZ_Fusion_Translator__BepInEx_ -{ - public class Utils - { - public static Dictionary> plantIndices = new Dictionary>(); - - public static void RegisterPlantIndices() - { - plantIndices = new Dictionary>(); - string originalJson; - string translatedJson; - - string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); - string dumpDir = GetAssetDir(AssetType.Dumps); - string originalPath = Path.Combine(dumpDir, "LawnStrings.json"); - string path = Path.Combine(almanacDir, "LawnStringsTranslate.json"); - - if ((!File.Exists(path)) || (!File.Exists(originalPath))) - { - Log.LogError($"LawnStringsTranslate.json file not found at path: {path}"); - } - else - { - originalJson = File.ReadAllText(originalPath); - translatedJson = File.ReadAllText(path); - AlmanacPlantBank.PlantData originalPlantData = JsonUtility.FromJson(originalJson); - AlmanacPlantBank.PlantData translatedPlantData = JsonUtility.FromJson(translatedJson); - - for (int i = 0; i < originalPlantData.plants.Count; i++) - { - var originalPlantInfo = originalPlantData.plants[i]; - AlmanacPlantBank.PlantInfo translatedPlantInfo = null; - - foreach (var info in translatedPlantData.plants) - { - if (info.seedType == originalPlantInfo.seedType) - { - translatedPlantInfo = info; - } - } - - if (translatedPlantInfo != null) - { - var temp = new KeyValuePair(translatedPlantInfo.seedType, translatedPlantInfo.name); - plantIndices.Add(originalPlantInfo.seedType, temp); - } - } - } - } - - public static Dictionary> recipeLinks = new Dictionary>(); - - public static void RegisterRecipeLinks() - { - recipeLinks.Clear(); - - Il2CppSystem.Array mixData = MixData.data.Cast(); - int rows = mixData.GetLength(0); - int columns = mixData.GetLength(1); - - foreach (PlantType plantType in Enum.GetValues(typeof(PlantType))) - { - int seedType = (int)plantType; - - recipeLinks.Add(seedType, new()); - - if (seedType > 0) - { - foreach (PlantType checkType in Enum.GetValues(typeof(PlantType))) - { - if (checkType > 0) - { - int[] checks = [mixData.GetValue(seedType, (int)checkType).Unbox(), mixData.GetValue((int)checkType, seedType).Unbox()]; - - if (checks[0] != 0) - { - recipeLinks[seedType].Add(checks[0]); - } - - if (checks[1] != 0) - { - recipeLinks[seedType].Add(checks[1]); - } - } - } - } - if (recipeLinks[seedType].Count > 0) - { - Log.LogDebug($"Found {recipeLinks[seedType].Count} fusions for {seedType}!"); - } - } - } - - internal static bool TryReplaceTexture2D(Texture2D ogTexture) - { - if (ogTexture != null) - { - if (TextureStore.textureDict.TryGetValue(ogTexture.name, out string texturePath)) - { - try - { - ImageConversion.LoadImage(ogTexture, File.ReadAllBytes(texturePath)); - - Core.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) - { - if (string.IsNullOrEmpty(text)) - return text ?? string.Empty; - - // Remove opening color tags like - string withoutOpenTags = Regex.Replace(text, @"]+>", string.Empty, RegexOptions.IgnoreCase); - // Remove closing color tags like - string withoutCloseTags = Regex.Replace(withoutOpenTags, @"", string.Empty, RegexOptions.IgnoreCase); - return withoutCloseTags; - } - - public static string RemoveSizeTags(string text) - { - if (string.IsNullOrEmpty(text)) - return text ?? string.Empty; - - string withoutOpenTags = Regex.Replace(text, @"]+>", string.Empty, RegexOptions.IgnoreCase); - string withoutCloseTags = Regex.Replace(withoutOpenTags, @"", string.Empty, RegexOptions.IgnoreCase); - return withoutCloseTags; - } - - public static GameObject ConvertToTextMeshProUGUI(GameObject originalText, Transform parent, string name) - { - GameObject newObj = new GameObject(name); - newObj.transform.position = originalText.transform.position; - newObj.AddComponent(); - newObj.AddComponent(); - newObj.AddComponent(); - newObj.transform.SetParent(parent); - newObj.transform.localScale = Vector3.one; - - UnityEngine.Object.Destroy(originalText); - return newObj; - } - - public static void ConvertButtonText(Transform original, string name) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - Transform transform = original.FindChild(name); - Transform textTransform = transform.FindChild("text"); - string text = textTransform.GetComponent().text; - Color color = textTransform.GetComponent().color; - - TextMeshProUGUI newGoBackText = Utils.ConvertToTextMeshProUGUI(textTransform.gameObject, transform, "text2").GetComponent(); - newGoBackText.autoSizeTextContainer = true; - newGoBackText.text = StringStore.TranslateText(text, false); - newGoBackText.font = fontAsset; - newGoBackText.color = color; - } - - public static string GetPlantNameFromAlmanac(PlantType thePlantType) - { - string json; - string thePlantName = ""; - - 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}"); - Log.LogError("Plant name could not be found!"); - thePlantName = ""; - } - else - { - json = File.ReadAllText(path); - AlmanacPlantBank.PlantData plantData = JsonUtility.FromJson(json); - - foreach (AlmanacPlantBank.PlantInfo plantInfo in plantData.plants) - { - if (plantInfo.seedType == (int)thePlantType) - { - thePlantName = plantInfo.name; - } - } - } - - return thePlantName; - } - - public static string GetPlantNameFromAlmanac(string theOriginalPlantName) - { - string originalJson; - string translatedJson; - string thePlantName = ""; - - string currentLanguage = Utils.Language.ToString(); - string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); - string dumpDir = GetAssetDir(AssetType.Dumps); - string originalPath = Path.Combine(dumpDir, "LawnStrings.json"); - string path = Path.Combine(almanacDir, "LawnStringsTranslate.json"); - - if ((!File.Exists(path)) || (!File.Exists(originalPath))) - { - Log.LogError($"LawnStringsTranslate.json file not found at path: {path}"); - Log.LogError("Plant name could not be found!"); - thePlantName = ""; - } - else - { - bool foundPlantName = false; - - originalJson = File.ReadAllText(originalPath); - translatedJson = File.ReadAllText(path); - AlmanacPlantBank.PlantData originalPlantData = JsonUtility.FromJson(originalJson); - AlmanacPlantBank.PlantData translatedPlantData = JsonUtility.FromJson(translatedJson); - - for (int i = 0; i < originalPlantData.plants.Count; i++) - { - AlmanacPlantBank.PlantInfo originalPlantInfo = originalPlantData.plants[i]; - KeyValuePair translatedPlantInfo = plantIndices[originalPlantInfo.seedType]; - - if (originalPlantInfo.name == theOriginalPlantName) - { - thePlantName = translatedPlantInfo.Value; - foundPlantName = true; - } - } - - if (!foundPlantName) - { - Log.LogInfo("Couldn't find plant name!"); - thePlantName = ""; - } - } - - return thePlantName; - } - - public static string GetZombieNameFromAlmanac(ZombieType theZombieType) - { - string json; - string theZombieName = ""; - - 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}"); - Log.LogError("Zombie name could not be found!"); - theZombieName = ""; - } - else - { - json = File.ReadAllText(path); - ZombieAlmanacData zombieData = JsonUtility.FromJson(json); - - foreach (ZombieInfo zombieInfo in zombieData.zombies) - { - if ((int)zombieInfo.theZombieType == (int)theZombieType) - { - theZombieName = zombieInfo.name; - } - } - } - - return theZombieName; - } - - - - public static bool CheckForUntranslatedText(string text) - { - Regex regex = new("\\p{IsCJKUnifiedIdeographs}+"); - try - { - Match match = regex.Match(text); - return match.Success; - } - catch(Exception e) - { - Log.LogError(e); - } - return false; - } - - -#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(); - RegisterPlantIndices(); - PvZ_Fusion_Translator__BepInEx_.Patches.GameObjects.MinorObjects.Zombie_Patch.LoadHPStrings(); - } - #endif - - #if MULTI_LANGUAGE - public static Utils.LanguageEnum OldLanguage; - #endif - - public static Utils.LanguageEnum Language; - - public static string mainCategory = "PvZ_Fusion_Translator"; - - public static bool customTextures => Core.Instance != null && !Core.Instance.configDefaultTextures.Value; - public static bool customAudio => Core.Instance != null && !Core.Instance.configDefaultAudio.Value; - - public enum LanguageEnum - { - // first column - English, - French, - Italian, - German, - Spanish, - Portuguese, - - // second column - Javanese, //Filipino, - Vietnamese, - Indonesian, - Russian, //NOTE: legacy language - Japanese, - Korean, - - // third column - Ukrainian, - // Slovak, - //Polish, - Turkish, - //Arabic, - Romanian, - - LANG_END - } - - public enum ToggleEnum - { - Textures, - Audio, - TOGGLE_END - } - } - -} \ No newline at end of file diff --git a/MelonLoader/AssetStore/AudioStore.cs b/MelonLoader/AssetStore/AudioStore.cs deleted file mode 100644 index d37899e..0000000 --- a/MelonLoader/AssetStore/AudioStore.cs +++ /dev/null @@ -1,179 +0,0 @@ -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() - { - 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(Utils.customAudio) - { - if (__instance.clip == null) - return; - - if (Il2CppRhythmGame.RhythmGameManager.Instance != null && __instance.clip.name == "loon") - 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/MelonLoader/AssetStore/CheckSumStore.cs b/MelonLoader/AssetStore/CheckSumStore.cs deleted file mode 100644 index fc9ce51..0000000 --- a/MelonLoader/AssetStore/CheckSumStore.cs +++ /dev/null @@ -1,858 +0,0 @@ -#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/MelonLoader/AssetStore/DllStore.cs b/MelonLoader/AssetStore/DllStore.cs deleted file mode 100644 index 663f7ba..0000000 --- a/MelonLoader/AssetStore/DllStore.cs +++ /dev/null @@ -1,115 +0,0 @@ -/*using MelonLoader; -using MelonLoader.Utils; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace PvZ_Fusion_Translator.AssetStore -{ - public static class DllStore - { - public static Dictionary dllData = new Dictionary() - { - { "Blooms_QOL.dll", null }, - { "PvZ_Fusion_Translator.dll", null } - }; - public static bool updateOnClose = false; - - public static void Init(string gameVersion) => TryGetNewDll(gameVersion); - - public static void TryGetNewDll(string gameVersion) - { - bool ableToUpdate = true; - string unableReason = ""; - string getGameVersionRequest = Utils.GetDataFromWeb("https://raw.githubusercontent.com/SillyStar-Github/PvZF-Translation-DLLs/refs/heads/main/CURRENT_GAME_VER").Result; - if(getGameVersionRequest != null) - { - Log.LogDebug($"Requst game version: {getGameVersionRequest} -> {Utils.CalculateGameVersion(getGameVersionRequest)}"); - Log.LogDebug($"This game version: {gameVersion} -> {Utils.CalculateGameVersion(gameVersion)}"); - if (Utils.CalculateGameVersion(getGameVersionRequest) != Utils.CalculateGameVersion(gameVersion)) - { - ableToUpdate = false; - unableReason = "Incorrect game version..."; - } - } - else - { - ableToUpdate = false; - unableReason = "Couldn't get latest game version info..."; - } - - if (ableToUpdate) - { - foreach(var key in dllData.Keys) - { - byte[] newDllRequest = Utils.GetByteDataFromWeb($"https://raw.githubusercontent.com/SillyStar-Github/PvZF-Translation-DLLs/refs/heads/main/{key}").Result; - if(newDllRequest != null) - { - dllData[key] = newDllRequest; - SaveNewDll(key); - } - else - { - Log.LogError($"Couldn't get latest {key} data!"); - } - } - } - else - { - Log.LogError($"Unable to update! {unableReason}"); - } - } - - public static void SaveNewDll(string name) - { - byte[] newDllData = dllData[name]; - if(newDllData != null) - { - string basePath = MelonEnvironment.ModsDirectory; - string toSavePath = Path.Combine(basePath, name + ".update"); - File.WriteAllBytes(toSavePath, newDllData); - } - } - - public static void UpdateNewDll() - { - foreach(var pair in dllData) - { - if(pair.Value != null) - { - updateOnClose = true; - } - } - - if(updateOnClose) - { - int processId = (Process.GetCurrentProcess().Id); - - var assembly = Core.Instance.MelonAssembly.Assembly; - string programName = "PvZ_Fusion_Translator.Resources.ModUpdateUtil.exe"; - - using var exeResourceStream = assembly.GetManifestResourceStream(programName); - string tempPath = Path.Combine(MelonEnvironment.ModsDirectory, "ModUpdateUtil.exe"); - using (var fileStream = File.Create(tempPath)) - { - exeResourceStream.CopyTo(fileStream); - } - - Process.Start(new ProcessStartInfo - { - FileName = tempPath, - Arguments = $"{processId.ToString()} {string.Join(",", dllData.Keys)} \"{MelonEnvironment.ModsDirectory}\"", - UseShellExecute = true - }); - } - else - { - Log.LogError("Cannot update on close! All .dll data is null!"); - } - } - } -} -*/ \ No newline at end of file diff --git a/MelonLoader/AssetStore/FontStore.cs b/MelonLoader/AssetStore/FontStore.cs deleted file mode 100644 index 48c5af1..0000000 --- a/MelonLoader/AssetStore/FontStore.cs +++ /dev/null @@ -1,150 +0,0 @@ -using Il2CppTMPro; -using MelonLoader; -using System.Reflection; -using UnityEngine; -using UnityEngine.TextCore.Text; - -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]"); - - AssetBundle assetBundle = Utils.GetAssetBundle(Path.Combine(fontsDir, "translation")); - - #if MULTI_LANGUAGE - foreach (string file in assetBundle.GetAllAssetNames()) - { - string fileName = Path.GetFileNameWithoutExtension(file); - - if (!fileName.EndsWith("_almanac") && !fileName.EndsWith("_fallback")) - { - TMP_FontAsset fontAsset = assetBundle.LoadAsset(file); - - fontAssetDict.Add(fileName, fontAsset); - - Log.LogInfo($"Font for language '{fileName}' loaded"); - } - } - - InitFallback(assetBundle); - #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(AssetBundle assetBundle) - { - string fontsDir = Path.Combine(Core.Instance.modsDirectory, "[Custom Fonts]"); - - foreach (string file in assetBundle.GetAllAssetNames()) - { - string fileName = Path.GetFileNameWithoutExtension(file); - - if (fileName.EndsWith("_almanac") || fileName.EndsWith("_fallback")) - { - TMP_FontAsset fallbackFont = assetBundle.LoadAsset(file); - - string fileNameLanguage = fileName.Replace("_fallback", "").Replace("_almanac", ""); - - Utils.TryAdd(fontAssetDictSecondary, fileName, 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.ToLower(), 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.ToLower())) - { - if (fontAssetDictSecondary.TryGetValue(language.ToLower(), out TMP_FontAsset almanacAsset)) - { - return almanacAsset; - } - } - if (fontAssetDictSecondary.ContainsKey(language.ToLower() + "_almanac")) - { - if (fontAssetDictSecondary.TryGetValue(language.ToLower() + "_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/MelonLoader/AssetStore/StringStore.cs b/MelonLoader/AssetStore/StringStore.cs deleted file mode 100644 index f3df218..0000000 --- a/MelonLoader/AssetStore/StringStore.cs +++ /dev/null @@ -1,637 +0,0 @@ -using Il2CppTMPro; -using PvZ_Fusion_Translator.Patches.BaseTextObjects; -using System.Text.RegularExpressions; -using UnityEngine; - -namespace PvZ_Fusion_Translator.AssetStore -{ - public static class StringStore - { - internal static Dictionary stringsDict = []; - - public static Dictionary translationStringRegex = new(); - - public static Dictionary translationString = new(); - - public static Dictionary customLevelStringRegex = new(); - - public static Dictionary customLevelString = new(); - - public static Dictionary izLevelTipDictionary = new(); - - public static Dictionary izTipCollectionString = new(); - - public static Dictionary fsLevelTipDictionary = new(); - - public static Dictionary fsTipCollectionString = new(); - - 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:" }, - { "Polish", "Trudność:"}, - { "Hungarian", "Nehézség:"}, - { "Arabic", "صعوبة:"}, - // { "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:" }, - { "Polish" , "Zombi:" }, - { "Hungarian" , "Zombik:" }, - { "Arabic" , "الزومبي:" }, - // { "Ukrainian" , "Зомбі:" }, - // { "Slovak" , "Zombíci:"} - } - } - - }; - - internal static void Init() - { - FileLoader.LoadStrings(); - } - - internal static void Reload() - { - translationString.Clear(); - translationStringRegex.Clear(); - customLevelString.Clear(); - customLevelStringRegex.Clear(); - izLevelTipDictionary.Clear(); - izTipCollectionString.Clear(); - fsLevelTipDictionary.Clear(); - fsTipCollectionString.Clear(); - InGameText_Patch.currentText = ""; - Utils.RegisterPlantIndices(); - 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) - { - /*var frame = new StackTrace().GetFrame(1); - var method = frame.GetMethod(); - var className = method.DeclaringType.Name; - - Console.WriteLine($"tmp pro ugui: {className}.{method.Name}");*/ - - #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 TranslateText(string originalText, string pattern, bool isLog = false) - { - if (TestRegex(originalText, pattern)) - { - if(translationStringRegex.ContainsKey(pattern)) - { - // Extract dynamic parts from the original text - var regex = new Regex(pattern); - 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 = DoTranslateString(groupValue); - dynamicParts.Add(translatedValue); - } - - // Format the output string with dynamic parts - return string.Format(translationStringRegex[pattern], [.. dynamicParts]); - } - else if(customLevelStringRegex.ContainsKey(pattern)) - { - // Extract dynamic parts from the original text - var regex = new Regex(pattern); - var match = regex.Match(originalText); - int groupCount = match.Groups.Count; - - if (isLog) - Log.LogDebug("Text found in customLevelStringRegex {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 = customLevelString.ContainsKey(groupValue) - ? customLevelString[groupValue] - : groupValue; - dynamicParts.Add(translatedValue); - } - - // Format the output string with dynamic parts - return string.Format(customLevelStringRegex[pattern], [.. dynamicParts]); - } - else - { - return originalText; - } - } - else - { - if (isLog) - Log.LogDebug($"Text '{originalText}' not translated"); - FileLoader.DumpUntranslatedStrings(originalText); - return originalText; - } - } - - public static string DoTranslateString(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]; - } - - if(izTipCollectionString.ContainsKey(originalText)) - { - if(isLog) - { - Log.LogDebug($"Text '{originalText}' found in izTipCollectionString"); - } - return izTipCollectionString[originalText]; - } - - if(fsTipCollectionString.ContainsKey(originalText)) - { - if(isLog) - { - Log.LogDebug($"Text '{originalText}' found in fsTipCollectionString"); - } - return fsTipCollectionString[originalText]; - } - - if(customLevelString.ContainsKey(originalText)) - { - if(isLog) - { - Log.LogDebug($"Text '{originalText}' found in customLevelString"); - } - return customLevelString[originalText]; - } - - if (Utils.plantIndiceString.ContainsKey(originalText)) - { - if(isLog) - { - Log.LogDebug($"Text '{originalText}' found in plantIndiceString"); - } - return Utils.plantIndiceString[originalText]; - } - - return originalText; - } - - public static string DoTranslateText(string originalText, bool isLog = false) - { - if (string.IsNullOrEmpty(originalText)) - { - if (isLog) - Log.LogError("Text Null or Empty"); - - return string.Empty; - } - - if (!Utils.CheckForUntranslatedText(originalText) && !(originalText).Contains("_")) return originalText; - - if (translationString.ContainsKey(originalText)) - { - if (isLog) - Log.LogDebug($"Text '{originalText} found in translationString"); - return translationString[originalText]; - } - - if(izTipCollectionString.ContainsKey(originalText)) - { - if(isLog) - { - Log.LogDebug($"Text '{originalText}' found in izTipCollectionString"); - } - return izTipCollectionString[originalText]; - } - - if(fsTipCollectionString.ContainsKey(originalText)) - { - if(isLog) - { - Log.LogDebug($"Text '{originalText}' found in fsTipCollectionString"); - } - return fsTipCollectionString[originalText]; - } - - if(customLevelString.ContainsKey(originalText)) - { - if(isLog) - { - Log.LogDebug($"Text '{originalText}' found in customLevelString"); - } - return customLevelString[originalText]; - } - - if (Utils.plantIndiceString.ContainsKey(originalText)) - { - if(isLog) - { - Log.LogDebug($"Text '{originalText}' found in plantIndiceString"); - } - return Utils.plantIndiceString[originalText]; - } - - // Regex-based dynamic translation - foreach (var entry in translationStringRegex) - { - if (TestRegex(originalText, entry.Key)) - { - // Extract dynamic parts from the original text - var regex = new Regex(entry.Key); - 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 = DoTranslateString(groupValue); - dynamicParts.Add(translatedValue); - } - - // Format the output string with dynamic parts - return string.Format(entry.Value, [.. dynamicParts]); - } - } - - foreach (var entry in customLevelStringRegex) - { - if (TestRegex(originalText, entry.Key)) - { - // Extract dynamic parts from the original text - var regex = new Regex(entry.Key); - var match = regex.Match(originalText); - int groupCount = match.Groups.Count; - - if (isLog) - Log.LogDebug("Text found in customLevelRegex {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 = customLevelString.ContainsKey(groupValue) - ? customLevelString[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"); - if(Utils.CheckForUntranslatedText(originalText)) - { - FileLoader.DumpUntranslatedStrings(originalText); - } - return originalText; - } - - public static string TranslateColorText(string originalText, bool isLog = false) - { - string text = TranslateColorSegments(originalText); - 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 TranslateColorSegments(string input) - { - string result = ""; - string pattern = @"]+>[\s\S]*?(?:<\/color>|$)|(?:<(?!color=)|[^<])+"; - string smallPattern = @"(]+>)(.*?)()"; - MatchCollection matches = Regex.Matches(input, pattern); - - for (int i = 0; i < matches.Count; i++) - { - Match match = matches[i]; - if (Regex.Match(match.Value, smallPattern, RegexOptions.Singleline).Success) - { - result += TranslateColorSegment(match.Value); - } - else - { - result += DoTranslateText(match.Value); - } - } - - return result; - } - - public static string TranslateColorSegment(string input) - { - string result = input; - string pattern = @"(]+>)(.*?)()"; - Match match = Regex.Match(input, pattern, RegexOptions.Singleline); - string translatedText = DoTranslateText(match.Groups[2].Value); - if(Utils.CheckForUntranslatedText(translatedText)) - { - FileLoader.DumpUntranslatedStrings(translatedText); - } - result = match.Groups[1].Value + translatedText + match.Groups[3].Value; - - return result; - } - public static bool TestRegex(string originalText, string pattern, bool singleLine = false) - { - RegexOptions options = (singleLine) ? RegexOptions.None : RegexOptions.Singleline; - return Regex.IsMatch(originalText, pattern, options); - } - - 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 - }; - } - - public 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/MelonLoader/AssetStore/TextureStore.cs b/MelonLoader/AssetStore/TextureStore.cs deleted file mode 100644 index f5760d5..0000000 --- a/MelonLoader/AssetStore/TextureStore.cs +++ /dev/null @@ -1,67 +0,0 @@ -using MelonLoader; -using System.Collections; -using UnityEngine; - -namespace PvZ_Fusion_Translator.AssetStore -{ - public static class TextureStore - { - internal static Dictionary textureDict = []; - internal static Dictionary spriteDict = []; - - internal static void Init() => FileLoader.LoadTextures(); - - internal static void Reload() - { - textureDict.Clear(); - #if MULTI_LANGUAGE - RestoreTextures(); - #endif - 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/MelonLoader/AssetStore/WarningStore.cs b/MelonLoader/AssetStore/WarningStore.cs deleted file mode 100644 index 7f753f1..0000000 --- a/MelonLoader/AssetStore/WarningStore.cs +++ /dev/null @@ -1,234 +0,0 @@ -//using System.Runtime.CompilerServices; -//using Il2Cpp; -//using Il2CppTMPro; -//using MelonLoader; -//using UnityEngine; -//using UnityEngine.TextCore.Text; -//using static MelonLoader.MelonLogger; - -//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.") }, -// { "Polish" , ("Jedynym wiarygodnym źródłem tego tłumaczenia jest ta społeczność:\n" + -// "discord.gg/DPAC5ZVJ8T. Jeśli znalazłeś to gdziekolwiek indziej, np. \n" + -// "Plants Hybrid i superhybrid.online, ukradli to.\n" + -// "Omijaj inne źródła, ponieważ mogą zawierać wirusy.\n" + -// "Odwiedź naszą społeczność, aby uzyskać przyszłe aktualizacje.", -// "Okay! Rozumiem.") }, -// { "Hungarian" , ("Ennek a fordításnak az egyetlen érvényes forrása ebből a közösségből származik:\n" + -// "discord.gg/DPAC5ZVJ8T. Ha ezt valahol máshol szerezted, például \n" + -// "Plants Hybrid és superhybrid.online oldalakon, akkor ők lopták.\n" + -// "Kerüld a többi forrást, mert vírusokat tartalmazhatnak.\n" + -// "Kérjük, látogass el közösségünkbe a jövőbeli frissítésekért.", -// "Oké! Értem.") }, -// { "Arabic" , ("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.") }, -// // { "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(NoticeMenu noticeMenu) -// { -// if (noticeMenu == null || noticeMenu.transform == null) -// { -// MelonLogger.Warning("[WarningStore] NoticeMenu or transform is null - ABORTING"); -// return; -// } - -//#if MULTI_LANGUAGE -// try -// { -// var (warningMessage, okayButton) = GetWarningMessage(Utils.Language); -// TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - -// Transform warningTransform = noticeMenu.transform.Find("窗口"); -// if (warningTransform == null) -// { -// MelonLogger.Warning("[WarningStore] '窗口' transform not found - ABORTING"); -// return; -// } - -// Transform warningTextTransform = warningTransform.Find("文字"); -// Transform warningTextShadowTransform = warningTransform.Find("文字2"); - -// if (warningTextTransform == null || warningTextShadowTransform == null) -// { -// MelonLogger.Warning("[WarningStore] Could not find text components (文字/文字2)"); -// return; -// } - -// TextMeshProUGUI warningText = warningTextTransform.GetComponent(); -// TextMeshProUGUI shadowText = warningTextShadowTransform.GetComponent(); - -// if (warningText == null || shadowText == null) -// { -// MelonLogger.Warning("[WarningStore] TextMeshProUGUI components missing"); -// return; -// } - -// warningText.text = warningMessage; -// shadowText.text = warningMessage; - -// if (fontAsset != null) -// { -// warningText.font = fontAsset; -// shadowText.font = fontAsset; -// } -// else -// { -// MelonLogger.Warning("[WarningStore] Font asset is null"); -// } - -// MelonLogger.Msg("Warning message loaded successfully!"); -// } -// catch (Exception e) -// { -// MelonLogger.Error($"Critical error in WarningLoad: {e}"); -// } -//#endif -// } -//#if MULTI_LANGUAGE -// public static bool isWarningMessageLoaded = false; - -// public static void WarningReload(Utils.LanguageEnum language, NoticeMenu noticeMenu) -// { -// if (noticeMenu == null) -// { -// MelonLogger.Warning("[WarningStore] NoticeMenu is null in WarningReload"); -// return; -// } - -// if (Utils.OldLanguage.ToString() == language.ToString() && Utils.OldLanguage.ToString() != "English") -// { -// return; -// } - -// if (!isWarningMessageLoaded) -// { -// WarningLoad(noticeMenu); -// isWarningMessageLoaded = true; -// } -// } -//#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/MelonLoader/Core.cs b/MelonLoader/Core.cs deleted file mode 100644 index a93977c..0000000 --- a/MelonLoader/Core.cs +++ /dev/null @@ -1,132 +0,0 @@ -using MelonLoader; -using MelonLoader.Utils; -using PvZ_Fusion_Translator.AssetStore; -using PvZ_Fusion_Translator.Patches.Managers; -using PvZ_Fusion_Translator.Patches.Modes.Super_Editor; -using UnityEngine; -using static PvZ_Fusion_Translator.FileLoader; - -[assembly: MelonInfo(typeof(PvZ_Fusion_Translator.Core), "PvZ Fusion Translator", "231.0.0", "dynaslash / arifrios1st / lancerx0 / JustNull / Dakosha / Mamoru-kun / cassidy / Teyliu", 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 bool isInitialized = false; - 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(); - - isInitialized = true; - } - - public override void OnLateInitializeMelon() - { - dtStart = DateTime.Now; - replaceTextureRoutine = MelonCoroutines.Start(TextureStore.ReplaceTexturesCoroutine()); - LoadTravelBuffs(); - Utils.RegisterPlantIndices(); - } - - public override void OnDeinitializeMelon() - { - MelonCoroutines.Stop(replaceTextureRoutine); - #if MULTI_LANGUAGE - FileLoader.SaveLanguage(); - #endif - //DllStore.UpdateNewDll(); - #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.PageUp)) - { - Utils.OpenOnlineAlmanac(); - } - - TowerManager_Patch.UpdateText(); - - if (CustomLevelMenu_Patch.requestTimer > 0) - { - CustomLevelMenu_Patch.requestTimer -= Time.deltaTime; - if(CustomLevelMenu_Patch.requestTimer < 0) - { - CustomLevelMenu_Patch.requestTimer = 0; - } - } - } - - 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 configUseLocal; - 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); - configUseLocal = category.CreateEntry("UseLocal", false); - configLanguage = category.CreateEntry("Language", "English"); - - MelonPreferences.Save(); - } - } -} \ No newline at end of file diff --git a/MelonLoader/FileLoader.cs b/MelonLoader/FileLoader.cs deleted file mode 100644 index f3d9e36..0000000 --- a/MelonLoader/FileLoader.cs +++ /dev/null @@ -1,1232 +0,0 @@ -using Il2Cpp; -using Il2CppAlmanacData; -using Il2CppInterop.Runtime.InteropTypes.Arrays; -using JetBrains.Annotations; -using MelonLoader; -using MelonLoader.TinyJSON; -using Newtonsoft.Json; -using PvZ_Fusion_Translator.AssetStore; -using PvZ_Fusion_Translator.Patches.GameObjects; -using PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects; -using PvZ_Fusion_Translator.Patches.Modes.Odyssey; -using PvZ_Fusion_Translator.Patches.OtherManagers; -using System.CodeDom.Compiler; -using System.Text; -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, - Sprites - } - - 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()); - - 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); - } - - if(!Utils.useLocal) - { - // load translationStrings - string translationStringsContent = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Strings/translation_strings.json").Result; - - if(translationStringsContent != null) - { - LoadTranslationStrings(translationStringsContent); - } - else - { - string translationStringsPath = Path.Combine(GetAssetDir(AssetType.Strings, Utils.Language), "translation_strings.json"); - if(File.Exists(translationStringsPath)) - { - LoadTranslationStrings(File.ReadAllText(translationStringsPath)); - } - } - - // load translationRegexs - string translationRegexsContent = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Strings/translation_regexs.json").Result; - - if(translationRegexsContent != null) - { - LoadTranslationRegexs(translationRegexsContent); - } - else - { - string translationRegexsPath = Path.Combine(GetAssetDir(AssetType.Strings, Utils.Language), "translation_regexs.json"); - if(File.Exists(translationRegexsPath)) - { - LoadTranslationRegexs(File.ReadAllText(translationRegexsPath)); - } - } - - string customLevelStringsContent = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Strings/customlevel_strings.json").Result; - - if(customLevelStringsContent != null) - { - LoadCustomLevelStrings(customLevelStringsContent); - } - else - { - string customLevelStringsPath = Path.Combine(GetAssetDir(AssetType.Strings, Utils.Language), "customlevel_strings.json"); - if(File.Exists(customLevelStringsPath)) - { - LoadCustomLevelStrings(File.ReadAllText(customLevelStringsPath)); - } - } - - // load translationRegexs - string customLevelRegexsContent = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Strings/customlevel_regexs.json").Result; - - if(customLevelRegexsContent != null) - { - LoadCustomLevelRegexs(customLevelRegexsContent); - } - else - { - string customLevelRegexsPath = Path.Combine(GetAssetDir(AssetType.Strings, Utils.Language), "customlevel_regexs.json"); - if(File.Exists(customLevelRegexsPath)) - { - LoadCustomLevelRegexs(File.ReadAllText(customLevelRegexsPath)); - } - } - - // load changelog - - LoadChangelogText(); - - // load tips - string izTipsContent = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Strings/tips_iz.json").Result; - - if(izTipsContent != null) - { - LoadIZStrings(izTipsContent); - } - else - { - string izTipsPath = Path.Combine(GetAssetDir(AssetType.Strings, Utils.Language), "tips_iz.json"); - if(File.Exists(izTipsPath)) - { - LoadIZStrings(File.ReadAllText(izTipsPath)); - } - } - - string fsTipsContent = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Strings/tips_fs.json").Result; - - if(fsTipsContent != null) - { - LoadFSStrings(fsTipsContent); - } - else - { - string fsTipsPath = Path.Combine(GetAssetDir(AssetType.Strings, Utils.Language), "tips_fs.json"); - if(File.Exists(fsTipsPath)) - { - LoadFSStrings(File.ReadAllText(fsTipsPath)); - } - } - - // load almanacs - - string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); - - if(!Directory.Exists(almanacDir)) - { - Directory.CreateDirectory(almanacDir); - } - - string plantAlmanacContent = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Almanac/LawnStringsTranslate.json").Result; - - if(plantAlmanacContent != null) - { - AlmanacPlantMenu_Patch.LoadPlantAlmanacData(plantAlmanacContent); - } - else - { - string path = Path.Combine(almanacDir, "LawnStringsTranslate.json"); - if(File.Exists(path)) - { - AlmanacPlantMenu_Patch.LoadPlantAlmanacData(File.ReadAllText(path)); - } - } - - string zombieAlmanacContent = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Almanac/ZombieStringsTranslate.json").Result; - - if(zombieAlmanacContent != null) - { - AlmanacZombieMenu_Patch.almanacJson = zombieAlmanacContent; - } - else - { - string path = Path.Combine(almanacDir, "ZombieStringsTranslate.json"); - if(File.Exists(path)) - { - AlmanacZombieMenu_Patch.almanacJson = File.ReadAllText(path); - } - } - - string detailStringsContent = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Almanac/DetailStringsTranslate.json").Result; - if(detailStringsContent != null) - { - LoadDetailStrings(detailStringsContent); - } - else - { - string path = Path.Combine(almanacDir, "DetailStringsTranslate.json"); - if(File.Exists(path)) - { - LoadDetailStrings(File.ReadAllText(path)); - } - } - - // load travel_buffs - - LoadTravelBuffs(); - - // load abyss buffs - - //Patches.Modes.Abyss.AbyssBuffMenu_Patch.LoadAbyssBuffData(); - - SaveStrings(); - DumpJson(); - } - else - { - 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("translation_strings")) - { - LoadTranslationStrings(jsonString); - } - else if (fileName.EndsWith("translation_regexs")) - { - LoadTranslationRegexs(jsonString); - } - else if (fileName.EndsWith("customlevel_strings")) - { - LoadCustomLevelStrings(jsonString); - } - else if (fileName.EndsWith("customlevel_regexs")) - { - LoadCustomLevelRegexs(jsonString); - } - else if(fileName.EndsWith("tips_iz")) - { - LoadIZStrings(jsonString); - } - else if(fileName.EndsWith("tips_fs")) - { - LoadFSStrings(jsonString); - } - //else if(fileName.EndsWith("abyss_buffs")) - //{ - // Patches.Modes.Abyss.AbyssBuffMenu_Patch.LoadAbyssBuffData(); - //} - else if (fileName.EndsWith("travel_buffs")) - { - LoadTravelBuffs(); - } - } - - string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); - - if(!Directory.Exists(almanacDir)) - { - Directory.CreateDirectory(almanacDir); - } - - string plantAlmanacPath = Path.Combine(almanacDir, "LawnStringsTranslate.json"); - - if(File.Exists(plantAlmanacPath)) - { - AlmanacPlantMenu_Patch.LoadPlantAlmanacData(File.ReadAllText(plantAlmanacPath)); - } - - string zombieAlmanacPath = Path.Combine(almanacDir, "ZombieStringsTranslate.json"); - if(File.Exists(zombieAlmanacPath)) - { - AlmanacZombieMenu_Patch.almanacJson = File.ReadAllText(zombieAlmanacPath); - } - - string detailStringsPath = Path.Combine(almanacDir, "DetailStringsTranslate.json"); - if(File.Exists(detailStringsPath)) - { - LoadDetailStrings(File.ReadAllText(detailStringsPath)); - } - - LoadChangelogText(); - - SaveStrings(); - DumpJson(); - } - catch (Exception e) - { - Log.LogError("Error loading string."); - Log.LogError(e.GetType() + " " + e.Message); - } - } - - Log.LogInfo("Strings loaded successfully."); - } - - internal static void LoadTranslationStrings(string content) - { - Dictionary dictionary = System.Text.Json.JsonSerializer.Deserialize>(content); - foreach (var (key, value) in dictionary) - { - StringStore.translationString[key] = value; - } - } - - internal static void LoadTranslationRegexs(string content) - { - Dictionary dictionary = System.Text.Json.JsonSerializer.Deserialize>(content); - foreach (var (key, value) in dictionary) - { - StringStore.translationStringRegex[key] = value; - } - Zombie_Patch.LoadHPStrings(); - } - - internal static void LoadCustomLevelStrings(string content) - { - Dictionary dictionary = System.Text.Json.JsonSerializer.Deserialize>(content); - foreach (var (key, value) in dictionary) - { - StringStore.customLevelString[key] = value; - } - } - - internal static void LoadCustomLevelRegexs(string content) - { - Dictionary dictionary = System.Text.Json.JsonSerializer.Deserialize>(content); - foreach (var (key, value) in dictionary) - { - StringStore.customLevelStringRegex[key] = value; - } - } - - internal static void LoadIZStrings(string content) - { - var izDump = DumpIZStrings(); - var izLevelData = izDump.Item1; - var izLevelDataDump = izDump.Item2; - - var izTranslatedTips = System.Text.Json.JsonSerializer.Deserialize>(content); - - foreach (var level in izLevelData) - { - string data = level.text; - LevelData levelData = JsonUtility.FromJson(data); - if(levelData.tips != null) - { - if(izTranslatedTips.ContainsKey(level.name) && !StringStore.izTipCollectionString.ContainsKey(levelData.tips)) - { - StringStore.izLevelTipDictionary.Add(level.name, izTranslatedTips[level.name]); - StringStore.izTipCollectionString.Add(levelData.tips, izTranslatedTips[level.name]); - } - } - } - } - - internal static void LoadFSStrings(string content) - { - var fusionShowcaseDump = DumpFSStrings(); - var fusionShowcaseData = fusionShowcaseDump.Item1; - var fusionShowcaseDataDump = fusionShowcaseDump.Item2; - - var fsTranslatedTips = System.Text.Json.JsonSerializer.Deserialize>(content); - - foreach (var level in fusionShowcaseData) - { - string data = level.text; - LevelData levelData = JsonUtility.FromJson(data); - if (levelData.tips != null) - { - if (fsTranslatedTips.ContainsKey(level.name) && !StringStore.fsTipCollectionString.ContainsKey(levelData.tips)) - { - StringStore.fsLevelTipDictionary.Add(level.name, fsTranslatedTips[level.name]); - StringStore.fsTipCollectionString.Add(levelData.tips, fsTranslatedTips[level.name]); - } - } - } - } - - internal static void LoadDetailStrings(string content) - { - var detailStringsDump = DumpDetailStrings(); - var detailStringsData = detailStringsDump.Item1; - var detailStrings = detailStringsDump.Item2; - - var translatedDetailStrings = System.Text.Json.JsonSerializer.Deserialize>(content); - AlmanacSelectMenu_Patch.detailStrings = translatedDetailStrings; - - foreach (var detailString in detailStringsData.details) - { - if (translatedDetailStrings.ContainsKey(detailString.title)) - { - if(!AlmanacSelectMenu_Patch.detailTranslateStrings.ContainsKey(detailString.text)) - { - AlmanacSelectMenu_Patch.detailTranslateStrings.Add(detailString.text, translatedDetailStrings[detailString.title]); - } - else - { - AlmanacSelectMenu_Patch.detailTranslateStrings[detailString.text] = translatedDetailStrings[detailString.title]; - } - } - } - } - - internal static void LoadChangelogText() - { - string stringDir = FileLoader.GetAssetDir(FileLoader.AssetType.Strings, Utils.Language); - string changelogDir = Path.Combine(stringDir, "changelog.txt"); - string changelogText = ""; - if (!File.Exists(changelogDir)) - { - File.WriteAllText(changelogDir, ""); - } - - changelogText = File.ReadAllText(changelogDir); - - if(!Utils.useLocal) - { - string changelogContent = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Strings/changelog.txt").Result; - - if(changelogContent != null) - { - changelogText = changelogContent; - } - } - else - { - changelogText = File.ReadAllText(changelogDir); - } - - NoticePauseMenu_Patch.changelogText = changelogText; - } - - internal static void LoadTravelBuffs() - { - if (!Utils.useLocal) - { - string travelBuffsContent = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Strings/travel_buffs.json").Result; - - if (travelBuffsContent != null) - { - TravelMgr_Patch.GenerateTranslatedTravelBuffs(travelBuffsContent); - } - else - { - string travelBuffsPath = Path.Combine(GetAssetDir(AssetType.Strings, Utils.Language), "travel_buffs.json"); - if (File.Exists(travelBuffsPath)) - { - TravelMgr_Patch.GenerateTranslatedTravelBuffs(File.ReadAllText(travelBuffsPath)); - } - } - } - else - { - string stringDir = FileLoader.GetAssetDir(FileLoader.AssetType.Strings, Utils.Language); - - foreach (string filepath in Directory.EnumerateFiles(stringDir, "*.json", SearchOption.AllDirectories)) - { - string fileName = Path.GetFileNameWithoutExtension(filepath); - string jsonString = File.ReadAllText(filepath); - if (fileName.EndsWith("travel_buffs")) - { - TravelMgr_Patch.GenerateTranslatedTravelBuffs(jsonString); - } - } - } - } - - public static bool loadDefaultTextures = MelonPreferences.GetEntryValue("PvZ_Fusion_Translator", "DefaultTextures"); - internal static void LoadTextures() - { - // Default or Custom Texturse -> English Textures -> Localized Textures - try - { - if (Utils.customTextures) - { - LoadCustomTextures(); - } - } - catch (Exception e) - { - Log.LogError("Error loading texture setting."); - Log.LogError($"{e.GetType()} {e.Message}"); - } - - #if MULTI_LANGUAGE - LoadLocalizedTextures(Utils.Language); - LoadLocalizedSprites(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 - { - Dictionary localTOC = new Dictionary(); - string localTOCDir = Path.Combine(textureDir, "Texture_TOC.json"); - if (!File.Exists(localTOCDir)) - { - File.WriteAllText(localTOCDir, "{}"); - } - - string localTOCContent = File.ReadAllText(localTOCDir); - localTOC = System.Text.Json.JsonSerializer.Deserialize>(localTOCContent); - - string basePath = Core.Instance.modsDirectory; - - if (!Utils.useLocal) - { - string textureTOCRequest = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Textures/Texture_TOC.json").Result; - if (textureTOCRequest != null) - { - Dictionary textureTOC = JsonConvert.DeserializeObject>(textureTOCRequest); - - List toDownload = new(); - - foreach(var pair in textureTOC) - { - if(!localTOC.ContainsKey(pair.Key)) - { - toDownload.Add(pair.Key); - continue; - } - - if(pair.Value != localTOC[pair.Key]) - { - toDownload.Add(pair.Key); - } - - if(!File.Exists(Path.Combine(basePath, pair.Key))) - { - toDownload.Add(pair.Key); - continue; - } - } - - string toWriteText = SerializeWithIndentation(textureTOC); - File.WriteAllText(localTOCDir, toWriteText); - - foreach(string path in toDownload) - { - string downloadPath = Path.Combine(basePath, path); - - string baseUrl = $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/"; - string url = baseUrl + path; - - byte[] imageData = Utils.GetByteDataFromWeb(url).Result; - if(imageData != null) - { - string fileName = Path.GetFileName(downloadPath); - Texture2D texture2D = Utils.LoadImage(imageData); - TextureStore.textureDict[fileName] = imageData; - if(!Directory.Exists(Path.GetDirectoryName(downloadPath))) - { - Directory.CreateDirectory(Path.GetDirectoryName(downloadPath)); - } - File.WriteAllBytes(downloadPath, imageData); - } - } - } - } - - foreach (string filepath in Directory.EnumerateFiles(textureDir, "*.png", SearchOption.AllDirectories)) - { - if (filepath.Contains("[Custom Textures]", StringComparison.OrdinalIgnoreCase) && loadDefaultTextures) - { - continue; - } - - if (!localTOC.ContainsKey(filepath.Replace(basePath + "\\", "").Replace("\\", "/")) - && (SerializeWithIndentation(localTOC) != "{}")) continue; - - #if OBFUSCATE - if (CheckSumStore.IsModified(filepath)) - { - Log.LogError("File {0} was modified!" , filepath); - continue; - } - #endif - - #if DEBUG - Log.LogDebug("Loading File : " + filepath); - #endif - - byte[] imageData = File.ReadAllBytes(filepath); - Texture2D texture2D = Utils.LoadImage(imageData); - TextureStore.textureDict[Path.GetFileNameWithoutExtension(filepath)] = imageData; - } - } - - catch (Exception e) - { - Log.LogError("Error loading Texture."); - Log.LogError(e.GetType() + " " + e.Message); - } - } - - internal static void LoadLocalizedSprites(Utils.LanguageEnum? language = null) - { - string textureDir = GetAssetDir(AssetType.Sprites, language); - - if (!Directory.Exists(textureDir)) - { - Directory.CreateDirectory(textureDir); - } - try - { - string trueTextureDir = GetAssetDir(AssetType.Textures, language); - Dictionary localTOC = new Dictionary(); - string localTOCDir = Path.Combine(trueTextureDir, "Texture_TOC.json"); - if (!File.Exists(localTOCDir)) - { - File.WriteAllText(localTOCDir, "{}"); - } - - string localTOCContent = File.ReadAllText(localTOCDir); - localTOC = System.Text.Json.JsonSerializer.Deserialize>(localTOCContent); - - string basePath = Core.Instance.modsDirectory; - - if(!Utils.useLocal) - { - string textureTOCRequest = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Textures/Texture_TOC.json").Result; - if (textureTOCRequest != null) - { - Dictionary textureTOC = JsonConvert.DeserializeObject>(textureTOCRequest); - - List toDownload = new(); - - foreach(var pair in textureTOC) - { - if(!localTOC.ContainsKey(pair.Key)) - { - toDownload.Add(pair.Key); - continue; - } - - if(pair.Value != localTOC[pair.Key]) - { - toDownload.Add(pair.Key); - } - - if(!File.Exists(Path.Combine(basePath, pair.Key))) - { - toDownload.Add(pair.Key); - continue; - } - } - - string toWriteText = SerializeWithIndentation(textureTOC); - File.WriteAllText(localTOCDir, toWriteText); - - foreach(string path in toDownload) - { - string downloadPath = Path.Combine(basePath, path); - - string baseUrl = $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/"; - string url = baseUrl + path; - - byte[] imageData = Utils.GetByteDataFromWeb(url).Result; - if(imageData != null) - { - string fileName = Path.GetFileName(downloadPath); - Texture2D texture2D = Utils.LoadImage(imageData); - TextureStore.spriteDict[fileName] = imageData; - if(!Directory.Exists(Path.GetDirectoryName(downloadPath))) - { - Directory.CreateDirectory(Path.GetDirectoryName(downloadPath)); - } - File.WriteAllBytes(downloadPath, imageData); - } - } - } - } - - foreach (string filepath in Directory.EnumerateFiles(textureDir, "*.png", SearchOption.AllDirectories)) - { - if (filepath.Contains("[Custom Textures]", StringComparison.OrdinalIgnoreCase) && loadDefaultTextures) - { - continue; - } - - if (!localTOC.ContainsKey(filepath.Replace(basePath + "\\", "").Replace("\\", "/")) - && (SerializeWithIndentation(localTOC) != "{}")) continue; - - #if OBFUSCATE - if (CheckSumStore.IsModified(filepath)) - { - Log.LogError("File {0} was modified!" , filepath); - continue; - } - #endif - - #if DEBUG - Log.LogDebug("Loading File (Sprite): " + filepath); - #endif - - byte[] imageData = File.ReadAllBytes(filepath); - Texture2D texture2D = Utils.LoadImage(imageData); - TextureStore.spriteDict[Path.GetFileNameWithoutExtension(filepath)] = imageData; - } - } - - catch (Exception e) - { - Log.LogError("Error loading Texture."); - Log.LogError(e.GetType() + " " + e.Message); - } - } - - internal static void LoadDefaultTextures() - { - if(Utils.customTextures == false) - { - string textureDefaultDir = Path.Combine(Core.Instance.modsDirectory, AssetType.Dumps.ToString(), "Default Textures [Do Not Remove]"); - if (!Directory.Exists(textureDefaultDir)) - { - Directory.CreateDirectory(textureDefaultDir); - } - try - { - string trueTextureDir = Path.Combine(Core.Instance.modsDirectory, "[Custom Textures]"); - Dictionary localTOC = new Dictionary(); - string localTOCDir = Path.Combine(trueTextureDir, "Default_TOC.json"); - if (!File.Exists(localTOCDir)) - { - File.WriteAllText(localTOCDir, "{}"); - } - - string localTOCContent = File.ReadAllText(localTOCDir); - localTOC = System.Text.Json.JsonSerializer.Deserialize>(localTOCContent); - - string basePath = Core.Instance.modsDirectory; - - if (!Utils.useLocal) - { - string textureTOCRequest = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/{Uri.EscapeDataString("[Custom Textures]")}/Default_TOC.json").Result; - if (textureTOCRequest != null) - { - Dictionary textureTOC = JsonConvert.DeserializeObject>(textureTOCRequest); - - List toDownload = new(); - - foreach (var pair in textureTOC) - { - if (!localTOC.ContainsKey(pair.Key)) - { - toDownload.Add(pair.Key); - continue; - } - - if (pair.Value != localTOC[pair.Key]) - { - toDownload.Add(pair.Key); - } - - if(!File.Exists(Path.Combine(basePath, pair.Key))) - { - toDownload.Add(pair.Key); - continue; - } - } - - string toWriteText = SerializeWithIndentation(textureTOC); - File.WriteAllText(localTOCDir, toWriteText); - - foreach (string path in toDownload) - { - string downloadPath = Path.Combine(basePath, path); - - string baseUrl = $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/"; - string url = baseUrl + path; - - byte[] imageData = Utils.GetByteDataFromWeb(url).Result; - if (imageData != null) - { - string fileName = Path.GetFileName(downloadPath); - Texture2D texture2D = Utils.LoadImage(imageData); - TextureStore.textureDict[fileName] = imageData; - if(!Directory.Exists(Path.GetDirectoryName(downloadPath))) - { - Directory.CreateDirectory(Path.GetDirectoryName(downloadPath)); - } - File.WriteAllBytes(downloadPath, imageData); - } - } - } - } - - foreach (string filepath in Directory.EnumerateFiles(textureDefaultDir, "*.png", SearchOption.AllDirectories)) - { - if (!localTOC.ContainsKey(filepath.Replace(basePath + "\\", "").Replace("\\", "/")) - && (SerializeWithIndentation(localTOC) != "{}")) continue; - - #if OBFUSCATE - if (CheckSumStore.IsModified(filepath)) - { - Log.LogError("File {0} was modified!" , filepath); - continue; - } - #endif - - byte[] imageData = File.ReadAllBytes(filepath); - Texture2D texture2D = Utils.LoadImage(imageData); - TextureStore.textureDict[Path.GetFileNameWithoutExtension(filepath)] = imageData; - } - } - - 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 - { - string trueTextureDir = Path.Combine(Core.Instance.modsDirectory, "[Custom Textures]"); - Dictionary localTOC = new Dictionary(); - string localTOCDir = Path.Combine(trueTextureDir, "Custom_TOC.json"); - if (!File.Exists(localTOCDir)) - { - File.WriteAllText(localTOCDir, "{}"); - } - - string localTOCContent = File.ReadAllText(localTOCDir); - localTOC = System.Text.Json.JsonSerializer.Deserialize>(localTOCContent); - - string basePath = Core.Instance.modsDirectory; - - if (!Utils.useLocal) - { - string textureTOCRequest = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/{Uri.EscapeDataString("[Custom Textures]")}/Custom_TOC.json").Result; - if (textureTOCRequest != null) - { - Dictionary textureTOC = JsonConvert.DeserializeObject>(textureTOCRequest); - - List toDownload = new(); - - foreach (var pair in textureTOC) - { - if (!localTOC.ContainsKey(pair.Key)) - { - toDownload.Add(pair.Key); - continue; - } - - if (pair.Value != localTOC[pair.Key]) - { - toDownload.Add(pair.Key); - continue; - } - - if(!File.Exists(Path.Combine(basePath, pair.Key))) - { - toDownload.Add(pair.Key); - continue; - } - } - - string toWriteText = SerializeWithIndentation(textureTOC); - File.WriteAllText(localTOCDir, toWriteText); - - foreach (string path in toDownload) - { - string downloadPath = Path.Combine(basePath, path); - - string baseUrl = $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/"; - string url = baseUrl + path; - - byte[] imageData = Utils.GetByteDataFromWeb(url).Result; - if (imageData != null) - { - string fileName = Path.GetFileName(downloadPath); - Texture2D texture2D = Utils.LoadImage(imageData); - TextureStore.textureDict[fileName] = imageData; - if(!Directory.Exists(Path.GetDirectoryName(downloadPath))) - { - Directory.CreateDirectory(Path.GetDirectoryName(downloadPath)); - } - File.WriteAllBytes(downloadPath, imageData); - } - } - } - } - - 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 - - if (!localTOC.ContainsKey(filepath.Replace(basePath + "\\", "").Replace("\\", "/")) - && (SerializeWithIndentation(localTOC) != "{}")) continue; - - byte[] imageData = File.ReadAllBytes(filepath); - Texture2D texture2D = Utils.LoadImage(imageData); - TextureStore.textureDict[Path.GetFileNameWithoutExtension(filepath)] = imageData; - } - } - - 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); - } - - // save regexs - - string translationStringRegex = SerializeWithIndentation(StringStore.translationStringRegex, 2); - - File.WriteAllText(Path.Combine(stringDir, "translation_regexs.json"), translationStringRegex); - - // save strings - - string translationString = SerializeWithIndentation(StringStore.translationString, 2); - - File.WriteAllText(Path.Combine(stringDir, "translation_strings.json"), translationString); - - // save iz tips - - string izTipCollectionString = SerializeWithIndentation(StringStore.izLevelTipDictionary, 1, ' '); - - File.WriteAllText(Path.Combine(stringDir, "tips_iz.json"), izTipCollectionString); - - // save fs tips - - string fsLevelTipDictionary = SerializeWithIndentation(StringStore.fsLevelTipDictionary); - - File.WriteAllText(Path.Combine(stringDir, "tips_fs.json"), fsLevelTipDictionary); - - // save changelog - - if(NoticePauseMenu_Patch.changelogText != "") - { - File.WriteAllText(Path.Combine(stringDir, "changelog.txt"), NoticePauseMenu_Patch.changelogText); - } - - // save abyss buffs - - //if(Patches.Modes.Abyss.AbyssBuffMenu_Patch.abyssBuffData != new Dictionary()) - //{ - // string abyssBuffData = SerializeWithIndentation(Patches.Modes.Abyss.AbyssBuffMenu_Patch.abyssBuffData, 2); - // File.WriteAllText(Path.Combine(stringDir, "abyss_buffs.json"), abyssBuffData); - //} - - // save almanacs - - string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); - - if(AlmanacPlantMenu_Patch.almanacJson != "") - { - string plantAlmanac = SerializeWithIndentation(AlmanacPlantMenu_Patch.almanacJson); - - File.WriteAllText(Path.Combine(almanacDir, "LawnStringsTranslate.json"), AlmanacPlantMenu_Patch.almanacJson); - } - - if(AlmanacZombieMenu_Patch.almanacJson != "") - { - string zombieAlmanac = SerializeWithIndentation(AlmanacZombieMenu_Patch.almanacJson); - - File.WriteAllText(Path.Combine(almanacDir, "ZombieStringsTranslate.json"), AlmanacZombieMenu_Patch.almanacJson); - } - - if(AlmanacSelectMenu_Patch.detailStrings != new Dictionary()) - { - string detailStrings = SerializeWithIndentation(AlmanacSelectMenu_Patch.detailStrings); - - File.WriteAllText(Path.Combine(almanacDir, "DetailStringsTranslate.json"), detailStrings); - } - } - - public static string SerializeWithIndentation(T value, int size = 4, char indentChar = ' ') - { - var stringBuilder = new StringBuilder(); - var stringWriter = new StringWriter(); - using (JsonTextWriter writer = new JsonTextWriter(stringWriter)) - { - writer.Formatting = Formatting.Indented; - writer.Indentation = size; - writer.IndentChar = indentChar; - - Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer(); - serializer.Serialize(writer, value, typeof(T)); - } - - return stringWriter.ToString(); - } - - 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; - //string AbyssBuffData = Resources.Load("AbyssBuffData").text; - File.WriteAllText(Path.Combine(dumpDir, "LawnStrings.json"), LawnStrings); - File.WriteAllText(Path.Combine(dumpDir, "ZombieStrings.json"), ZombieStrings); - //File.WriteAllText(Path.Combine(dumpDir, "AbyssBuffData.json"), AbyssBuffData); - - // dump iz tips - var izDump = DumpIZStrings(); - var izLevelData = izDump.Item1; - var izLevelDataDump = izDump.Item2; - - File.WriteAllText(Path.Combine(dumpDir, "tips_iz.json"), System.Text.Json.JsonSerializer.Serialize(izLevelDataDump, new JsonSerializerOptions - { - WriteIndented = true, - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping - })); - - // dump fusion showcase tips - var fusionShowcaseDump = DumpFSStrings(); - var fusionShowcaseData = fusionShowcaseDump.Item1; - var fusionShowcaseDataDump = fusionShowcaseDump.Item2; - - File.WriteAllText(Path.Combine(dumpDir, "tips_fs.json"), System.Text.Json.JsonSerializer.Serialize(fusionShowcaseDataDump, new JsonSerializerOptions - { - WriteIndented = true, - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping - })); - - // dump almanac mechanics - var detailStringsDump = DumpDetailStrings(); - var detailStringsData = detailStringsDump.Item1; - var detailStrings = detailStringsDump.Item2; - - File.WriteAllText(Path.Combine(dumpDir, "DetailStrings.json"), System.Text.Json.JsonSerializer.Serialize(detailStrings, new JsonSerializerOptions - { - WriteIndented = true, - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping - })); - - /*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"), System.Text.Json.JsonSerializer.Serialize(achievementsList, new JsonSerializerOptions - { - WriteIndented = true, - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping - }));*/ - } - - public static ValueTuple, Dictionary> DumpIZStrings() - { - var izLevelData = Resources.LoadAll("izleveldata"); - Dictionary izLevelDataDump = new Dictionary(); - foreach (var level in izLevelData) - { - string data = level.text; - LevelData levelData = JsonUtility.FromJson(data); - if(levelData.tips != null) - { - izLevelDataDump.Add(level.name, levelData.tips); - } - } - return new ValueTuple, Dictionary>(izLevelData, izLevelDataDump); - } - - public static ValueTuple, Dictionary> DumpFSStrings() - { - var fusionShowcaseData = Resources.LoadAll("leveldata/explore"); - Dictionary fusionShowcaseDataDump = new Dictionary(); - foreach (var level in fusionShowcaseData) - { - string data = level.text; - LevelData levelData = JsonUtility.FromJson(data); - if (levelData.tips != null) - { - fusionShowcaseDataDump.Add(level.name, levelData.tips); - } - } - return new ValueTuple, Dictionary>(fusionShowcaseData, fusionShowcaseDataDump); - } - - public static ValueTuple> DumpDetailStrings() - { - string detailStringsData = Resources.Load("detailstrings").text; - Il2CppAlmanacData.AlmanacData detailStrings = JsonUtility.FromJson(detailStringsData); - - Dictionary detailStringsDump = new Dictionary(); - foreach (var detailString in detailStrings.details) - { - if(detailStringsDump.ContainsKey(detailString.title)) - { - detailStringsDump[detailString.title] = detailString.text; - } - else - { - detailStringsDump.Add(detailString.title, detailString.text); - } - } - return new ValueTuple>(detailStrings, detailStringsDump); - } - - #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); - var untranslatedStrings = System.Text.Json.JsonSerializer.Deserialize>(json); - - if (!untranslatedStrings.ContainsKey(text)) - { - untranslatedStrings[text] = text; - var options = new JsonSerializerOptions - { - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, - WriteIndented = true - }; - File.WriteAllText(jsonFile, System.Text.Json.JsonSerializer.Serialize(untranslatedStrings, options)); - } - } - #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/MelonLoader/FontHandler.cs b/MelonLoader/FontHandler.cs deleted file mode 100644 index a2cad5a..0000000 --- a/MelonLoader/FontHandler.cs +++ /dev/null @@ -1,43 +0,0 @@ -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/MelonLoader/Log.cs b/MelonLoader/Log.cs deleted file mode 100644 index d7d93b6..0000000 --- a/MelonLoader/Log.cs +++ /dev/null @@ -1,25 +0,0 @@ -using MelonLoader; -using MelonLoader.Logging; -using System.Drawing; - -namespace PvZ_Fusion_Translator -{ - internal static class Log - { - public static void LogDebug(object txt) => Melon.Logger.Msg(ColorARGB.Gray, txt); - public static void LogDebug(string txt) => Melon.Logger.Msg(ColorARGB.Gray, txt); - public static void LogDebug(string txt, params object[] args) => Melon.Logger.Msg(ColorARGB.Gray, txt, args); - - public static void LogInfo(object txt) => Melon.Logger.Msg(ColorARGB.Blue, txt); - public static void LogInfo(string txt) => Melon.Logger.Msg(ColorARGB.Blue, txt); - public static void LogInfo(string txt, params object[] args) => Melon.Logger.Msg(ColorARGB.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/MelonLoader/ModFeatures.cs b/MelonLoader/ModFeatures.cs deleted file mode 100644 index ca2703b..0000000 --- a/MelonLoader/ModFeatures.cs +++ /dev/null @@ -1,95 +0,0 @@ -//#if DEBUG -using Il2Cpp; -using Il2CppGameLevel; -using PvZ_Fusion_Translator.AssetStore; -using PvZ_Fusion_Translator.Patches.Modes.Super_Editor; -using UnityEngine; - -namespace PvZ_Fusion_Translator -{ - public static class ModFeatures - { - public enum ModType - { - ReloadStrings, - ReloadTextures, - ExportLevelStrings - } - - 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; - } - - if (this.ModType == ModType.ExportLevelStrings) - { - CustomMenu customMenu = UnityEngine.Object.FindObjectOfType(); - if (!customMenu) return; - if(customMenu.isActiveAndEnabled) - { - Patches.Modes.Super_Editor.GameLevel.LevelManager_Patch.ExportLevelStrings(customMenu.LevelData); - Core.ShowToast("Dumped level strings!"); - } - 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)}, - {ModType.ExportLevelStrings,new ModFeature("Export Level Strings",ModType.ExportLevelStrings,KeyCode.N, 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/MelonLoader/Patches/BaseTextObjects/InGameText_Patch.cs b/MelonLoader/Patches/BaseTextObjects/InGameText_Patch.cs deleted file mode 100644 index 4fc812f..0000000 --- a/MelonLoader/Patches/BaseTextObjects/InGameText_Patch.cs +++ /dev/null @@ -1,400 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppCore; -using Il2CppAlmanacData; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using PvZ_Fusion_Translator.Patches.Modes.Odyssey; -using System.Text.RegularExpressions; -using System.Xml.Linq; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.BaseTextObjects -{ - [HarmonyPatch(typeof(InGameText))] - public static class InGameText_Patch - { - public static string currentText = ""; - - [HarmonyPatch(nameof(InGameText.ShowText))] - [HarmonyPostfix] - public static void ShowText(InGameText __instance) - { - TranslateInGameText(__instance); - } - - [HarmonyPatch(nameof(InGameText.DebugWarning))] - [HarmonyPostfix] - public static void DebugWarning(InGameText __instance) - { - TranslateInGameText(__instance); - } - - [HarmonyPatch(nameof(InGameText.Update))] - [HarmonyPostfix] - public static void Update(InGameText __instance) - { - TranslateInGameText(__instance); - } - - public static void TranslateInGameText(InGameText __instance) - { - TextMeshProUGUI txt = null; - - if (__instance.textMesh == null || __instance.textHead == null) - { - if (__instance.TryGetComponent(out TextMeshProUGUI selfTxt)) - { - txt = selfTxt; - } - } - else - { - txt = __instance.textMesh; - } - - if(txt != null) - { - if (!txt.gameObject.active) return; - - TranslateInGameTextMesh(txt); - } - } - - public static void TranslateInGameTextMesh(TextMeshProUGUI txt) - { - if (txt == null) return; - if (txt.text == currentText) return; - - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - string originalText = txt.text; - string lockedPlantMatch = CheckLockedMessage(originalText); - string travelMatch = TravelMgr_Patch.MatchTravelBuff(originalText); - int godsGachaCheck = CheckGodsGachaPopup(originalText); - string godsGachaMatch = ""; - string superEditorPlantMatch = CheckSuperEditorPopup(originalText); - string customLevelRegexMatch = CheckCustomLevelRegex(originalText); - string qualityCheckMatch = CheckQualityUpgrade(originalText); - - switch(godsGachaCheck) - { - case 1: - case 2: - case 3: - godsGachaMatch = TranslateGodsGachaPopup(originalText, godsGachaCheck); - break; - default: - break; - } - - if(godsGachaMatch != "") - { - txt.text = godsGachaMatch; - if (txt.gameObject.name.Contains("main")) - { - originalText = txt.text; - Transform shadowText = txt.transform.parent.Find("Text_shadow"); - if (shadowText != null) - { - shadowText.GetComponent().text = Utils.RemoveColorTags(originalText); - } - } - } - else if (travelMatch != "") - { - txt.text = TravelMgr_Patch.AddBuffName(travelMatch); - if (txt.gameObject.name.Contains("main")) - { - originalText = txt.text; - Transform shadowText = txt.transform.parent.Find("Text_shadow"); - if (shadowText != null) - { - shadowText.GetComponent().text = Utils.RemoveColorTags(originalText); - } - } - } - else if(qualityCheckMatch != "") - { - txt.text = qualityCheckMatch; - } - else if(superEditorPlantMatch != "") - { - txt.text = superEditorPlantMatch; - } - else if(lockedPlantMatch != "") - { - txt.text = lockedPlantMatch; - } - else if(customLevelRegexMatch != "") - { - txt.text = customLevelRegexMatch; - } - else if((Regex.Match(txt.text, @"(]*>.*?)", RegexOptions.Singleline).Success) && - !StringStore.translationString.ContainsKey(txt.text) && - !StringStore.fsTipCollectionString.ContainsKey(txt.text) && - !StringStore.izTipCollectionString.ContainsKey(txt.text) && - !StringStore.customLevelString.ContainsKey(txt.text)) - { - txt.text = StringStore.TranslateColorText(txt.text, true); - if (txt.gameObject.name.Contains("main")) - { - originalText = txt.text; - Transform shadowText = txt.transform.parent.Find("Text_shadow"); - if (shadowText != null) - { - shadowText.GetComponent().text = Utils.RemoveColorTags(originalText); - } - } - } - else - { - txt.text = StringStore.TranslateText(txt.text, true); - if (txt.gameObject.name.Contains("main")) - { - originalText = txt.text; - Transform shadowText = txt.transform.parent.Find("Text_shadow"); - if (shadowText != null) - { - shadowText.GetComponent().text = Utils.RemoveColorTags(originalText); - } - } - } - txt.font = fontAsset; - - currentText = txt.text; - } - - public static string namePlantedPattern = "种植了:([^\\s]+)"; - public static string nameUpgradedPattern = "升级成功:([^\\s]+) -> ([^\\s]+)"; - public static string nameAlreadyPlantedPattern = "场上已经有一个([^\\s]+)了"; - public static string upgradePathRemovedPattern = "已移除路线:([^\\s]+)"; - - public static string lockedPlantPattern = "^([\\s\\S]+)\\+([\\S]+)$"; - public static string multiLockedPlantPattern = "^或 ([\\s\\S]+)\\+([\\S]+)$"; - - public static string qualityChangePattern = "诸神注视着你,并选中了一个他们喜欢的词条\n植物【([\\S]+)】的词条【强化:([\\S]+)】获得品质升级\n当前品质:([\\S]+)"; - - public static Dictionary fallbackFStrs = new Dictionary() - { - { namePlantedPattern, "{0} planted!"}, - { nameUpgradedPattern, "{0} successfully upgraded to {1}!"}, - { nameAlreadyPlantedPattern, "{0} already exists on the lawn!"}, - { upgradePathRemovedPattern, "Upgrade Path removed for {0}" }, - { @"([^\s]+)\((\d+)\)", "{0}({1})" }, - { lockedPlantPattern, "{0} + {1}" }, - { multiLockedPlantPattern, "or {0} + {1}" }, - { qualityChangePattern, "The gods are watching you, and they have granted you an upgrade!\nThe {1} upgrade for {0} has been upgraded.\nCurrent Quality: {2}" } - }; - - public static int CheckGodsGachaPopup(string originalText) - { - int res = 0; - - if (Regex.IsMatch(originalText, namePlantedPattern)) - { - res = 1; - } - else if(Regex.IsMatch(originalText, nameUpgradedPattern)) - { - res = 2; - } - else if(Regex.IsMatch(originalText, nameAlreadyPlantedPattern)) - { - res = 3; - } - - return res; - } - - public static string TranslateGodsGachaPopup(string originalText, int type) - { - string res = originalText; - - switch(type) - { - case 1: - res = StringStore.TranslateText(originalText, namePlantedPattern); - break; - case 2: - res = StringStore.TranslateText(originalText, nameUpgradedPattern); - break; - case 3: - res = StringStore.TranslateText(originalText, nameAlreadyPlantedPattern); - break; - default: - break; - } - - return res; - } - - public static string TranslatePlantNameParts(string originalText, string pattern) - { - string res = ""; - string fStr = ""; - Match match = Regex.Match(originalText, pattern); - if(match.Success) - { - GroupCollection groups = match.Groups; - fStr = StringStore.translationStringRegex.ContainsKey(pattern) ? StringStore.translationStringRegex[pattern] : fallbackFStrs[pattern]; - List dynamicParts = []; - for(int i = 1; i < groups.Count; i++) - { - string group = groups[i].Value; - string plantName = Utils.GetPlantNameFromAlmanac(group); - dynamicParts.Add(plantName); - } - res = string.Format(fStr, [.. dynamicParts]); - } - return res; - } - - public static string TranslatePlantNameParts(string originalText, string pattern, string fallback) - { - string res = ""; - string fStr = ""; - Match match = Regex.Match(originalText, pattern); - if(match.Success) - { - GroupCollection groups = match.Groups; - fStr = StringStore.translationStringRegex.ContainsKey(pattern) ? StringStore.translationStringRegex[pattern] : fallback; - List dynamicParts = []; - for(int i = 1; i < groups.Count; i++) - { - string group = groups[i].Value; - string plantName = Utils.GetPlantNameFromAlmanac(group); - if (plantName == "") plantName = StringStore.TranslateText(group); - dynamicParts.Add(plantName); - } - res = string.Format(fStr, [.. dynamicParts]); - } - return res; - } - - public static string CheckSuperEditorPopup(string originalText) - { - string res = ""; - - if(Regex.IsMatch(originalText, upgradePathRemovedPattern)) - { - res = StringStore.TranslateText(originalText, upgradePathRemovedPattern); - } - else if(Regex.IsMatch(originalText, "当前全部基础植物:(.*)")) - { - string pattern = "当前全部基础植物:(.*)"; - Match match = Regex.Match(originalText, pattern); - if(match.Success) - { - GroupCollection groups = match.Groups; - string plantNameGroup = groups[1].Value; - string[] plantNames = plantNameGroup.Split(" "); - string plantRes = ""; - string shortPattern = @"([^\s]+)\((\d+)\)"; - foreach (string plantName in plantNames) - { - Match shortMatch = Regex.Match(plantName, shortPattern); - if(shortMatch.Success) - { - string fStr = StringStore.translationStringRegex.ContainsKey(shortPattern) ? StringStore.translationStringRegex[shortPattern] : fallbackFStrs[shortPattern]; - string shortRes = string.Format(fStr, [Utils.GetPlantNameFromAlmanac(shortMatch.Groups[1].Value), shortMatch.Groups[2].Value]); - plantRes += shortRes + " "; - } - } - res = StringStore.TranslateText("当前全部基础植物:" + plantRes); - } - } - - return res; - } - - public static string CheckLockedMessage(string originalText) - { - string res = ""; - - Regex lockedPlantRegex = new Regex(lockedPlantPattern); - Regex multiLockedPlantRegex = new Regex(multiLockedPlantPattern); - - if(lockedPlantRegex.IsMatch(originalText)) - { - if(originalText.Contains("\n")) - { - string[] lines = originalText.Split("\n"); - if (lockedPlantRegex.IsMatch(lines[0])) - { - string firstLine = lines[0]; - Match match = lockedPlantRegex.Match(firstLine); - GroupCollection groups = match.Groups; - if (Utils.plantIndiceString.ContainsKey(groups[1].Value) && Utils.plantIndiceString.ContainsKey(groups[2].Value)) - { - firstLine = StringStore.TranslateText(firstLine, lockedPlantPattern); - List translatedLines = new List() { firstLine }; - for(int i = 1; i < lines.Length; i++) - { - string nextLine = lines[i]; - string translatedNextLine = StringStore.TranslateText(nextLine, multiLockedPlantPattern); - translatedLines.Add(translatedNextLine); - } - res = string.Join("\n", translatedLines); - } - else - { - return ""; - } - } - } - else - { - if (lockedPlantRegex.IsMatch(originalText)) - { - Match match = lockedPlantRegex.Match(originalText); - GroupCollection groups = match.Groups; - if (Utils.plantIndiceString.ContainsKey(groups[1].Value) && Utils.plantIndiceString.ContainsKey(groups[2].Value)) - { - res = StringStore.TranslateText(originalText, lockedPlantPattern); - } - else - { - return ""; - } - } - } - } - - return res; - } - - public static string CheckCustomLevelRegex(string originalText) - { - string res = ""; - - foreach(var pair in StringStore.customLevelStringRegex) - { - if(StringStore.TestRegex(originalText, pair.Key)) - { - res = StringStore.TranslateText(originalText, pair.Key); - } - } - foreach(var pair in StringStore.translationStringRegex) - { - if(StringStore.TestRegex(originalText, pair.Key)) - { - res = ""; - } - } - return res; - } - - public static string CheckQualityUpgrade(string originalText) - { - string res = ""; - - if(Regex.IsMatch(originalText, qualityChangePattern)) - { - res = StringStore.TranslateText(originalText, qualityChangePattern); - } - - return res; - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/BaseTextObjects/TMP_Dropdown_Patch.cs b/MelonLoader/Patches/BaseTextObjects/TMP_Dropdown_Patch.cs deleted file mode 100644 index 9b7a3a3..0000000 --- a/MelonLoader/Patches/BaseTextObjects/TMP_Dropdown_Patch.cs +++ /dev/null @@ -1,49 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.Patches.Managers; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using UnityEngine.UI; - -namespace PvZ_Fusion_Translator.Patches.BaseTextObjects -{ - [HarmonyPatch(typeof(TMP_Dropdown))] - public static class TMP_Dropdown_Patch - { - [HarmonyPatch(nameof(TMP_Dropdown.Awake))] - [HarmonyPatch(nameof(TMP_Dropdown.Start))] - [HarmonyPatch(nameof(TMP_Dropdown.Show))] - [HarmonyPatch(nameof(TMP_Dropdown.SetValue))] - [HarmonyPostfix] - public static void Awake(TMP_Dropdown __instance) - { - if(__instance.captionText) - { - TMP_Text txt = __instance.captionText; - txt.text = StringStore.translationString.ContainsKey(txt.text + "_code") ? StringStore.TranslateText(txt.text + "_code") : StringStore.TranslateText(txt.text); - } - - if(__instance.itemText) - { - TMP_Text txt = __instance.itemText; - txt.text = StringStore.translationString.ContainsKey(txt.text + "_code") ? StringStore.TranslateText(txt.text + "_code") : StringStore.TranslateText(txt.text); - } - - foreach(TMP_Dropdown.DropdownItem dropdownItem in __instance.m_Items) - { - TMP_Text txt = dropdownItem.text; - txt.text = StringStore.translationString.ContainsKey(txt.text + "_code") ? StringStore.TranslateText(txt.text + "_code") : StringStore.TranslateText(txt.text); - } - } - - [HarmonyPatch(nameof(TMP_Dropdown.CreateDropdownList))] - public static void CreateDropdownList(TMP_Dropdown __instance) - { - foreach(TMP_Text txt in __instance.GetComponentsInChildren(true)) - { - txt.text = StringStore.translationString.ContainsKey(txt.text + "_code") ? StringStore.TranslateText(txt.text + "_code") : StringStore.TranslateText(txt.text); - } - } - } -} diff --git a/MelonLoader/Patches/BaseTextObjects/TMP_InputField_Patch.cs b/MelonLoader/Patches/BaseTextObjects/TMP_InputField_Patch.cs deleted file mode 100644 index 0465668..0000000 --- a/MelonLoader/Patches/BaseTextObjects/TMP_InputField_Patch.cs +++ /dev/null @@ -1,24 +0,0 @@ -using HarmonyLib; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.BaseTextObjects -{ - [HarmonyPatch(typeof(TMP_InputField))] - public static class TMP_InputField_Patch - { - [HarmonyPatch(nameof(TMP_InputField.OnEnable))] - [HarmonyPostfix] - public 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/MelonLoader/Patches/BaseTextObjects/TextMeshProUGUI_Patch.cs b/MelonLoader/Patches/BaseTextObjects/TextMeshProUGUI_Patch.cs deleted file mode 100644 index e7444ca..0000000 --- a/MelonLoader/Patches/BaseTextObjects/TextMeshProUGUI_Patch.cs +++ /dev/null @@ -1,110 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.Patches.Managers; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -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.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - - if (!Utils.CheckForUntranslatedText(__instance.text) && !(__instance.text).Contains("_")) return; - - if(__instance.transform.parent != null) - { - if(__instance.transform.parent.name.Contains("DrawCardsText")) - { - return; - } - - if(__instance.transform.parent.parent != null) - { - if (__instance.transform.parent.parent.name.Contains("AbyssBagMenu")) - { - return; - } - } - } - - __instance = StringStore.TranslateText(__instance); - __instance.autoSizeTextContainer = false; - - if (__instance.name.StartsWith("LevelName")) - { - __instance.text = __instance.text.Replace("\n", " "); - - if ((__instance.name == "LevelName2" || __instance.name == "LevelName3") && !(__instance.gameObject.transform.parent.name.Contains("Difficulty") || __instance.gameObject.name.Contains("Difficulty"))) - { - TowerManager_Patch.updatedText.Add(__instance.transform); - } - } - 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)) - { - if (__instance.transform.parent.parent != null) - { - if (__instance.transform.parent.parent.name.Contains("AbyssBagMenu")) - { - return; - } - } - - __instance = StringStore.TranslateText(__instance); - __instance.autoSizeTextContainer = false; - - 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/MelonLoader/Patches/BaseTextObjects/TextMeshPro_Patch.cs b/MelonLoader/Patches/BaseTextObjects/TextMeshPro_Patch.cs deleted file mode 100644 index 2be83f5..0000000 --- a/MelonLoader/Patches/BaseTextObjects/TextMeshPro_Patch.cs +++ /dev/null @@ -1,33 +0,0 @@ -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.Contains("DrawCardsText")) - { - return; - } - else if (__instance.transform.parent.name.StartsWith("AlmanacHelp") || __instance.transform.parent.name.StartsWith("CardBank")) - { - __instance = StringStore.TranslateText(__instance); - __instance.autoSizeTextContainer = false; - return; - } else if (!(__instance.transform.name.Contains("AlmanacZombie") || __instance.transform.name.Contains("AlmanacPlant") || __instance.transform.name.Contains("Name") || __instance.transform.name.Contains("Tips") || __instance.transform.parent.name.Contains("Signboard") || __instance.transform.parent.name.Contains("text"))) - { - __instance = StringStore.TranslateText(__instance); - __instance.autoSizeTextContainer = true; - } - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/AlmanacBuffMenu_Patch.cs b/MelonLoader/Patches/GameObjects/AlmanacBuffMenu_Patch.cs deleted file mode 100644 index 968af10..0000000 --- a/MelonLoader/Patches/GameObjects/AlmanacBuffMenu_Patch.cs +++ /dev/null @@ -1,100 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppAlmanacData; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using System.Drawing; -using static Il2Cpp.AlmanacBuffMenu; -using static PvZ_Fusion_Translator.FileLoader; -using static PvZ_Fusion_Translator.Patches.Modes.Odyssey.TravelMgr_Patch; -using static PvZ_Fusion_Translator.Utils; -using Unity.VisualScripting; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(AlmanacBuffMenu))] - public static class AlmanacBuffMenu_Patch - { - [HarmonyPatch(nameof(AlmanacBuffMenu.Awake))] - [HarmonyPostfix] - public static void Post_Awake(AlmanacBuffMenu __instance) - { - foreach(AlmanacCardUI cardUI in __instance.cards) - { - AlmanacBuffMenu.CardInfo cardInfo = __instance.cardInfos[cardUI]; - var buffData = FindBuffData(cardInfo.description); - - if (buffData.Item1 == null || buffData.Item3 == null) continue; - - cardUI.cost.text = (buffData.Item4) ? buffData.Item1 : $"{buffData.Item1} #{buffData.Item2}"; - } - - Post_OnCardClick(__instance); - } - - [HarmonyPatch(nameof(AlmanacBuffMenu.SetAllCards))] - [HarmonyPatch(nameof(AlmanacBuffMenu.Start))] - [HarmonyPatch(nameof(AlmanacBuffMenu.InitMenu))] - [HarmonyPostfix] - public static void Post_SetAllCards(AlmanacBuffMenu __instance) - { - foreach(AlmanacCardUI cardUI in __instance.cards) - { - AlmanacBuffMenu.CardInfo cardInfo = __instance.cardInfos[cardUI]; - var buffData = FindBuffData(cardInfo.description); - if (buffData.Item1 == null || buffData.Item3 == null) continue; - - cardUI.cost.text = (buffData.Item4) ? buffData.Item1 : $"{buffData.Item1} #{buffData.Item2}"; - } - - Post_OnToolClick(__instance); - - Post_OnCardClick(__instance); - } - - [HarmonyPatch(nameof(AlmanacBuffMenu.OnToolClick))] - [HarmonyPostfix] - public static void Post_OnToolClick(AlmanacBuffMenu __instance) - { - foreach(TextMeshProUGUI txt in __instance.toolButton.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } - - [HarmonyPatch(nameof(AlmanacBuffMenu.OnCardClick))] - [HarmonyPostfix] - public static void Post_OnCardClick(AlmanacBuffMenu __instance) - { - var buffData = FindBuffData(__instance.buffDescription.text); - - if (buffData.Item1 == null || buffData.Item3 == null) - { - return; - } - - __instance.buffTitle.text = (buffData.Item4) ? buffData.Item1 : $"{buffData.Item1} #{buffData.Item2}"; - __instance.buffTitle.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - string buffFStr = StringStore.translationStringRegex.ContainsKey("BUFF_NAME_FORMAT") ? StringStore.translationStringRegex["BUFF_NAME_FORMAT"] : "{0}: {1}"; - string fBuffDesc = string.Format(buffFStr, buffData.Item1, buffData.Item3); - __instance.buffDescription.text = (buffData.Item4) ? fBuffDesc + "\n\n" : buffData.Item3 + "\n\n"; - __instance.buffDescription.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - string colorHex = StringStore.translationString.ContainsKey("MOD_ALMANAC_COL") ? StringStore.TranslateText("MOD_ALMANAC_COL") : "#000000"; - System.Drawing.Color descriptionColor = ColorTranslator.FromHtml(colorHex); - __instance.buffDescription.color = new UnityEngine.Color(descriptionColor.R / 255.0f, descriptionColor.G / 255.0f, descriptionColor.B / 255.0f); - - __instance.buffDescription.fontSizeMax = 18; - __instance.buffDescription.margin = new Vector4(8, 4, 25, 0); - - __instance.buffDescription.enableWordWrapping = true; - __instance.buffDescription.overflowMode = TextOverflowModes.ScrollRect; - - Canvas.ForceUpdateCanvases(); - __instance.buffDescription.ForceMeshUpdate(); - - Post_OnToolClick(__instance); - } - } -} diff --git a/MelonLoader/Patches/GameObjects/AlmanacCardUI_Patch.cs b/MelonLoader/Patches/GameObjects/AlmanacCardUI_Patch.cs deleted file mode 100644 index 9cdf33e..0000000 --- a/MelonLoader/Patches/GameObjects/AlmanacCardUI_Patch.cs +++ /dev/null @@ -1,28 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using PvZ_Fusion_Translator.AssetStore; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(AlmanacCardUI))] - public static class AlmanacCardUI_Patch - { - [HarmonyPatch(nameof(AlmanacCardUI.Awake))] - [HarmonyPostfix] - public static void Awake(AlmanacCardUI __instance) - { - if (!Utils.CheckForUntranslatedText(__instance.cost.text)) return; - __instance.cost.text = StringStore.TranslateText(__instance.cost.text); - } - - /*[HarmonyPatch(nameof(AlmanacCardUI.OnPointerDown))] - [HarmonyPostfix] - public static void OnPointerDown(AlmanacCardUI __instance) - { - foreach (AlmanacCardUI almanacCardUI in __instance.menu.GetComponentsInChildren()) - { - AlmanacCardUI_Patch.Awake(almanacCardUI); - } - }*/ - } -} diff --git a/MelonLoader/Patches/GameObjects/AlmanacPlantMenu_Patch.cs b/MelonLoader/Patches/GameObjects/AlmanacPlantMenu_Patch.cs deleted file mode 100644 index 39a454d..0000000 --- a/MelonLoader/Patches/GameObjects/AlmanacPlantMenu_Patch.cs +++ /dev/null @@ -1,137 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppAlmanacData; -using Il2CppTMPro; -using MelonLoader.TinyJSON; -using PvZ_Fusion_Translator.AssetStore; -using System.Text.Json; -using System.Text.RegularExpressions; -using Unity.Collections; -using Unity.VisualScripting; -using UnityEngine; -using UnityEngine.UI; -using UnityEngine.UIElements; -using static PvZ_Fusion_Translator.FileLoader; -using static PvZ_Fusion_Translator.Utils; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(AlmanacPlantMenu))] - public static class AlmanacPlantMenu_Patch - { - public static string almanacJson = ""; - public static Dictionary plantInfoDict = new(); - - [HarmonyPatch(nameof(AlmanacPlantMenu.Awake))] - [HarmonyPostfix] - private static void Awake(AlmanacPlantMenu __instance) - { - TMP_FontAsset font = FontStore.LoadTMPFont(Utils.Language.ToString()); - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren(true)) - { - bool isPlantName = text.gameObject.name.Contains("Name") && text.transform.parent.name != "Background"; - if (text.gameObject.name != "Description" && !isPlantName && !text.gameObject.name.Contains("Cost")) - { - text.text = StringStore.TranslateText(text.text); - text.font = font; - text.autoSizeTextContainer = true; - } - } - - foreach (AlmanacCardUI almanacCardUI in __instance.GetComponentsInChildren()) - { - AlmanacCardUI_Patch.Awake(almanacCardUI); - } - - // skin button resize - - AlmanacPlantWindow window = __instance.window; - GameObject skinButton = window.skinButton; - GameObject skinTextObj = skinButton.transform.Find("text_1").gameObject; - skinButton.transform.localScale /= 1.75f; - skinButton.transform.localPosition = new Vector3(0.0f, 111.345f, 0.0f); - skinButton.transform.GetChild(1).Translate(new Vector3(-0.35f, 0)); - skinButton.transform.GetChild(2).Translate(new Vector3(0.35f, 0)); - } - - [HarmonyPatch(nameof(AlmanacPlantMenu.SearchChanged))] - [HarmonyPrefix] - public static bool SearchChanged(AlmanacPlantMenu __instance, ref TMP_InputField inputField) - { - string search = inputField.text; - if (search != StringStore.TranslateText("搜索") && search != "") - { - string currentLanguage = Utils.Language.ToString(); - string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); - string path = Path.Combine(almanacDir, "LawnStringsTranslate.json"); - - string json = AlmanacPlantMenu_Patch.almanacJson; - - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); - - AlmanacData plantData = JsonUtility.FromJson(json); - - Il2CppSystem.Collections.Generic.List searchedPlants = new(); - - foreach (PlantInfo plantInfo in plantData.plants) - { - if (plantInfo.name.ToLower().Contains(search.ToLower())) - { - searchedPlants.Add((PlantType)plantInfo.seedType); - } - else if ($"{plantInfo.seedType}".ToLower().StartsWith(search.ToLower())) - { - searchedPlants.Add((PlantType)plantInfo.seedType); - } - } - - __instance.ShowPlants(searchedPlants); - - return false; - } - - return true; - } - - [HarmonyPatch(nameof(AlmanacPlantMenu.ShowPlants), argumentTypes: [typeof(Il2CppSystem.Func)])] - [HarmonyPostfix] - public static void ShowPlants(AlmanacPlantMenu __instance, ref Func condition) - { - foreach (AlmanacCardUI cardUI in __instance.cards) - { - AlmanacCardUI_Patch.Awake(cardUI); - } - } - - [HarmonyPatch(nameof(AlmanacPlantMenu.ClassicMix))] - [HarmonyPostfix] - public static void ClassicMix(AlmanacPlantMenu __instance) - { - foreach (AlmanacCardUI cardUI in __instance.cards) - { - AlmanacCardUI_Patch.Awake(cardUI); - } - } - - public static void LoadPlantAlmanacData(string json) - { - if (json == null) return; - - almanacJson = json; - - var plantData = JsonUtility.FromJson(almanacJson); - - foreach (Il2CppAlmanacData.PlantInfo plantInfo in plantData.plants) - { - if(plantInfoDict.ContainsKey(plantInfo.seedType)) - { - plantInfoDict[plantInfo.seedType] = plantInfo; - } - else - { - plantInfoDict.Add(plantInfo.seedType, plantInfo); - } - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/AlmanacPlantWindow_Patch.cs b/MelonLoader/Patches/GameObjects/AlmanacPlantWindow_Patch.cs deleted file mode 100644 index b752d26..0000000 --- a/MelonLoader/Patches/GameObjects/AlmanacPlantWindow_Patch.cs +++ /dev/null @@ -1,69 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppAlmanacData; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using System.Text.RegularExpressions; -using Unity.VisualScripting; -using UnityEngine; -using UnityEngine.UI; -using static PvZ_Fusion_Translator.FileLoader; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(AlmanacPlantWindow))] - public static class AlmanacPlantWindow_Patch - { - [HarmonyPatch(nameof(AlmanacPlantWindow.UpdateText))] - [HarmonyPostfix] - private static void UpdateText(AlmanacPlantWindow __instance) - { - string currentLanguage = Utils.Language.ToString(); - string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); - string path = Path.Combine(almanacDir, "LawnStringsTranslate.json"); - string moddedPath = Path.Combine(almanacDir, "ModdedPlantsTranslate.json"); - - string json = AlmanacPlantMenu_Patch.almanacJson; - - bool hasAlmanacFont = false; - TMP_FontAsset almanacFontAsset = null; - if (FontStore.fontAssetDictSecondary.ContainsKey((currentLanguage + "_almanac").ToLower()) || FontStore.fontAssetDictSecondary.ContainsKey((currentLanguage).ToLower())) - { - almanacFontAsset = FontStore.LoadTMPFontAlmanac(currentLanguage); - hasAlmanacFont = true; - } - - TMP_FontAsset fontAsset = (hasAlmanacFont) ? FontStore.LoadTMPFontAlmanac(Utils.Language.ToString()) : FontStore.LoadTMPFont(Utils.Language.ToString()); - - AlmanacData plantData = JsonUtility.FromJson(json); - - if(AlmanacPlantMenu_Patch.plantInfoDict.ContainsKey((int)__instance.currentPlantType)) - { - PlantInfo plantInfo = AlmanacPlantMenu_Patch.plantInfoDict[(int)__instance.currentPlantType]; - - foreach (TextMeshProUGUI text in __instance.showedPlantName) - { - text.autoSizeTextContainer = false; - text.text = $"{Utils.RemoveSizeTags(plantInfo.name)} ({plantInfo.seedType})"; - text.font = fontAsset; - text.fontSizeMax = 21; - } - - char[] toTrim = Environment.NewLine.ToCharArray(); - __instance.showedPlantIntroduce.text = Utils.RemoveSizeTags(plantInfo.info) + "\n\n" + Utils.RemoveSizeTags(plantInfo.introduce) + "\n\n" + Utils.RemoveSizeTags(plantInfo.cost).TrimStart(toTrim) + "\n\n"; - __instance.showedPlantIntroduce.font = fontAsset; - __instance.showedPlantIntroduce.fontSizeMax = 21; - __instance.showedPlantIntroduce.margin = new Vector4(6, 2, 12, 0); - - __instance.showedPlantIntroduce.enableWordWrapping = true; - __instance.showedPlantIntroduce.overflowMode = TextOverflowModes.ScrollRect; - - Canvas.ForceUpdateCanvases(); - __instance.showedPlantIntroduce.ForceMeshUpdate(); - - float textHeight = __instance.showedPlantIntroduce.preferredHeight; - __instance.plantTextContent.sizeDelta = new Vector2(__instance.plantTextContent.sizeDelta.x, textHeight); - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/AlmanacSelectMenu_Patch.cs b/MelonLoader/Patches/GameObjects/AlmanacSelectMenu_Patch.cs deleted file mode 100644 index c335bb3..0000000 --- a/MelonLoader/Patches/GameObjects/AlmanacSelectMenu_Patch.cs +++ /dev/null @@ -1,56 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppAlmanacData; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using System.Text.RegularExpressions; -using Unity.Collections; -using Unity.VisualScripting; -using UnityEngine; -using UnityEngine.UI; -using UnityEngine.UIElements; -using static PvZ_Fusion_Translator.FileLoader; -using static PvZ_Fusion_Translator.Utils; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(AlmanacSelectMenu))] - public static class AlmanacSelectMenu_Patch - { - public static Dictionary detailStrings = new Dictionary(); - public static Dictionary detailTranslateStrings = new Dictionary(); - - [HarmonyPatch(nameof(AlmanacSelectMenu.Awake))] - [HarmonyPostfix] - public static void Awake(AlmanacSelectMenu __instance) - { - TranslateAlmanacSelectMenu(__instance); - - foreach(UIButton uiButton in __instance.GetComponentsInChildren()) - { - if(uiButton.gameObject.name.Contains("Selection(Clone)")) - { - uiButton.clickEvent.AddListener(new Action(() => { TranslateAlmanacSelectMenu(__instance); })); - } - } - } - - [HarmonyPatch(nameof(AlmanacSelectMenu.InitMenu))] - [HarmonyPostfix] - public static void InitMenu(AlmanacSelectMenu __instance) - { - TranslateAlmanacSelectMenu(__instance); - } - - public static void TranslateAlmanacSelectMenu(AlmanacSelectMenu __instance) - { - TMP_FontAsset font = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach(TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = detailTranslateStrings.ContainsKey(txt.text) ? detailTranslateStrings[txt.text] : StringStore.TranslateText(txt.text); - txt.font = font; - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/AlmanacZombieMenu_Patch.cs b/MelonLoader/Patches/GameObjects/AlmanacZombieMenu_Patch.cs deleted file mode 100644 index 17e6a27..0000000 --- a/MelonLoader/Patches/GameObjects/AlmanacZombieMenu_Patch.cs +++ /dev/null @@ -1,38 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using System.Text.RegularExpressions; -using Unity.VisualScripting; -using UnityEngine; -using UnityEngine.UI; -using static PvZ_Fusion_Translator.FileLoader; -using static PvZ_Fusion_Translator.Utils; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(AlmanacZombieMenu))] - public static class AlmanacZombieMenu_Patch - { - public static string almanacJson = ""; - - [HarmonyPatch(nameof(AlmanacZombieMenu.Start))] - [HarmonyPostfix] - private static void Start(AlmanacZombieMenu __instance) - { - TMP_FontAsset font = FontStore.LoadTMPFont(Utils.Language.ToString()); - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren(true)) - { - if (text.gameObject.name.Contains("Cost")) continue; - - bool isZombieName = text.gameObject.name.Contains("Name") && text.transform.parent.name != "Background"; - if (text.gameObject.name != "Description" && !isZombieName) - { - text.text = StringStore.TranslateText(text.text); - text.font = font; - text.autoSizeTextContainer = true; - } - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/AlmanacZombieWindow_Patch.cs b/MelonLoader/Patches/GameObjects/AlmanacZombieWindow_Patch.cs deleted file mode 100644 index 49a4852..0000000 --- a/MelonLoader/Patches/GameObjects/AlmanacZombieWindow_Patch.cs +++ /dev/null @@ -1,77 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using System.Text.RegularExpressions; -using Unity.VisualScripting; -using UnityEngine; -using UnityEngine.UI; -using static PvZ_Fusion_Translator.FileLoader; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(AlmanacZombieWindow))] - public static class AlmanacZombieWindow_Patch - { - [HarmonyPatch(nameof(AlmanacZombieWindow.UpdateText))] - [HarmonyPostfix] - private static void UpdateText(AlmanacZombieWindow __instance) - { - string currentLanguage = Utils.Language.ToString(); - string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); - string path = Path.Combine(almanacDir, "ZombieStringsTranslate.json"); - - string json = AlmanacZombieMenu_Patch.almanacJson; - - bool hasAlmanacFont = false; - TMP_FontAsset almanacFontAsset = null; - if (FontStore.fontAssetDictSecondary.ContainsKey((currentLanguage + "_almanac").ToLower()) || FontStore.fontAssetDictSecondary.ContainsKey((currentLanguage).ToLower())) - { - almanacFontAsset = FontStore.LoadTMPFontAlmanac(currentLanguage); - hasAlmanacFont = true; - } - - TMP_FontAsset fontAsset = (hasAlmanacFont) ? FontStore.LoadTMPFontAlmanac(Utils.Language.ToString()) : FontStore.LoadTMPFont(Utils.Language.ToString()); - - Il2CppAlmanacData.AlmanacData zombieAlmanacData = JsonUtility.FromJson(json); - var zombieDataDic = ZombieDataManager.zombieDataDic; - - foreach (Il2CppAlmanacData.ZombieInfo zombieInfo in zombieAlmanacData.zombies) - { - if (zombieInfo.theZombieType == __instance.currentZombieType) - { - foreach (TextMeshProUGUI text in __instance.showedZombieName) - { - text.autoSizeTextContainer = false; - text.text = $"{Utils.RemoveSizeTags(zombieInfo.name)} ({(int)zombieInfo.theZombieType})"; - text.font = fontAsset; - text.fontSizeMax = 21; - } - - ZombieDataManager.ZombieData zombieData = zombieDataDic[__instance.currentZombieType]; - - string spawnInfo = ""; - string spawnInfoFormat = StringStore.translationStringRegex.ContainsKey("出怪等级: (\\d+)\n出怪权重: (\\d+)") ? StringStore.translationStringRegex["出怪等级: (\\d+)\n出怪权重: (\\d+)"] : null; - if(spawnInfoFormat != null) - { - spawnInfo = string.Format(spawnInfoFormat, [zombieData.summonLevel, zombieData.summonWeight]) + "\n\n"; - } - - __instance.showedZombieIntroduce.text = Utils.RemoveSizeTags(zombieInfo.info) + "\n\n" + spawnInfo + Utils.RemoveSizeTags(zombieInfo.introduce) + "\n\n"; - __instance.showedZombieIntroduce.font = fontAsset; - __instance.showedZombieIntroduce.fontSizeMax = 21; - __instance.showedZombieIntroduce.margin = new Vector4(3, 2, 12, 0); - - __instance.showedZombieIntroduce.enableWordWrapping = true; - __instance.showedZombieIntroduce.overflowMode = TextOverflowModes.ScrollRect; - - Canvas.ForceUpdateCanvases(); - __instance.showedZombieIntroduce.ForceMeshUpdate(); - - float textHeight = __instance.showedZombieIntroduce.preferredHeight; - __instance.zombieTextContent.sizeDelta = new Vector2(__instance.zombieTextContent.sizeDelta.x, textHeight); - } - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/Almanac_Patch.cs b/MelonLoader/Patches/GameObjects/Almanac_Patch.cs deleted file mode 100644 index d1e2885..0000000 --- a/MelonLoader/Patches/GameObjects/Almanac_Patch.cs +++ /dev/null @@ -1,54 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using System.Text.RegularExpressions; -using Unity.VisualScripting; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(Almanac))] - public static class Almanac_Patch - { - [HarmonyPatch(nameof(Almanac.Awake))] - [HarmonyPostfix] - private static void Awake(Almanac __instance) - { - TranslateAlmanacMenu(__instance); - } - - /*[HarmonyPatch(nameof(Almanac.OldAlmanac))] - [HarmonyPostfix] - private static void OldAlmanac(Almanac __instance) - { - TranslateAlmanacMenu(__instance); - }*/ - - [HarmonyPatch(nameof(Almanac.AnimSwitch))] - [HarmonyPostfix] - private static void AnimSwitch(Almanac __instance) - { - TranslateAlmanacMenu(__instance); - } - - public static void TranslateAlmanacMenu(Almanac __instance) - { - TMP_FontAsset font = FontStore.LoadTMPFont(Utils.Language.ToString()); - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - if (text.gameObject.name.Contains("Cost")) continue; - - if(text.text == "关闭") - { - text.text = StringStore.TranslateText("合上"); - } - else - { - text.text = StringStore.TranslateText(text.text); - } - text.font = font; - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/BaseMenu_Patch.cs b/MelonLoader/Patches/GameObjects/BaseMenu_Patch.cs deleted file mode 100644 index 49c2fa3..0000000 --- a/MelonLoader/Patches/GameObjects/BaseMenu_Patch.cs +++ /dev/null @@ -1,67 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppAlmanacData; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using static MelonLoader.MelonLogger; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(BaseMenu))] - public static class BaseMenu_Patch - { - [HarmonyPatch(nameof(BaseMenu.Awake))] - [HarmonyPrefix] - private static void Pre_Awake(BaseMenu __instance) - { - if(__instance.name.Contains("NoticePauseMenu")) - { - NoticePauseMenu_Patch.Pre_Awake(__instance); - } - } - - [HarmonyPatch(nameof(BaseMenu.Awake))] - [HarmonyPostfix] - private static void Post_Awake(BaseMenu __instance) - { - if(__instance.name.Contains("NoticePauseMenu")) - { - NoticePauseMenu_Patch.Post_Awake(__instance); - } - - if(__instance.name.StartsWith("MainMenu(Clone)")) - { - MainMenu_Patch.AnimOver(__instance); - } - - if(__instance.name.StartsWith("PlantDamageMenu")) - { - PlantDamageMenu_Patch.Awake(__instance); - } - - TranslateBaseMenuTransform(__instance, "Level"); - TranslateBaseMenuTransform(__instance, "Levels"); - TranslateBaseMenuTransform(__instance, "CustomLevel"); - - StringStore.TranslateTextTransform(__instance.transform.Find("Goback")); - StringStore.TranslateTextTransform(__instance.transform.Find("Switich")); - } - - public static void TranslateBaseMenuTransform(BaseMenu __instance, string levelsName) - { - Transform levels = __instance.transform.Find(levelsName); - if (levels != null) - { - List children = levels.GetComponentsInChildren(true).ToList(); - foreach (Transform child in children) - { - if (child.name == "Nextpage" || child.name == "LastPage" || child.name == "BackToIndex") - { - StringStore.TranslateTextTransform(child); - } - } - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/Board_Patch.cs b/MelonLoader/Patches/GameObjects/Board_Patch.cs deleted file mode 100644 index 328e768..0000000 --- a/MelonLoader/Patches/GameObjects/Board_Patch.cs +++ /dev/null @@ -1,28 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(Board))] - public static class Board_Patch - { - [HarmonyPatch(nameof(Board.Update))] - [HarmonyPostfix] - private static void Update(Board __instance) - { - foreach (SpriteRenderer spriteRenderer in __instance.GetComponentsInChildren()) - { - if (spriteRenderer.sprite != null) - { - if (TextureStore.spriteDict.ContainsKey(spriteRenderer.sprite.name) && spriteRenderer.drawMode != SpriteDrawMode.Sliced) - { - spriteRenderer.drawMode = SpriteDrawMode.Sliced; - } - } - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/ButtonObjects/Advanture_Btn_Patch.cs b/MelonLoader/Patches/GameObjects/ButtonObjects/Advanture_Btn_Patch.cs deleted file mode 100644 index 1238676..0000000 --- a/MelonLoader/Patches/GameObjects/ButtonObjects/Advanture_Btn_Patch.cs +++ /dev/null @@ -1,26 +0,0 @@ -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) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - string originalKey = StringStore.translationString.FirstOrDefault(x => x.Value == txt.text).Key; - txt.text = (StringStore.translationString.ContainsKey(originalKey + "_MG")) ? StringStore.TranslateText(originalKey + "_MG") : StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/ButtonObjects/BackToIndex_Patch.cs b/MelonLoader/Patches/GameObjects/ButtonObjects/BackToIndex_Patch.cs deleted file mode 100644 index 621e118..0000000 --- a/MelonLoader/Patches/GameObjects/ButtonObjects/BackToIndex_Patch.cs +++ /dev/null @@ -1,19 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects -{ - //[HarmonyPatch(typeof(BackToIndex))] - //public class BackToIndex_Patch - // { - // [HarmonyPostfix] - // [HarmonyPatch(nameof(BackToIndex.Awake))] - // public static void Awake(BackToIndex __instance) - // { - // StringStore.TranslateTextTransform(__instance.transform.GetChild(0)); - // } - //} -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/ButtonObjects/CustomLevelEnter_Patch.cs b/MelonLoader/Patches/GameObjects/ButtonObjects/CustomLevelEnter_Patch.cs deleted file mode 100644 index ed70973..0000000 --- a/MelonLoader/Patches/GameObjects/ButtonObjects/CustomLevelEnter_Patch.cs +++ /dev/null @@ -1,27 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using MelonLoader; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects -{ - [HarmonyPatch(typeof(CustomLevelEnter))] - public static class CustomLevelEnter_Patch - { - [HarmonyPatch(nameof(CustomLevelEnter.Start))] - [HarmonyPostfix] - private static void Start(CustomLevelEnter __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach(TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - string originalKey = StringStore.translationString.FirstOrDefault(x => x.Value == txt.text).Key; - txt.text = (StringStore.translationString.ContainsKey(originalKey + "_IZ")) ? StringStore.TranslateText(originalKey + "_IZ") : StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/ButtonObjects/ExploreMakeSceneButton_Patch.cs b/MelonLoader/Patches/GameObjects/ButtonObjects/ExploreMakeSceneButton_Patch.cs deleted file mode 100644 index 1e7e111..0000000 --- a/MelonLoader/Patches/GameObjects/ButtonObjects/ExploreMakeSceneButton_Patch.cs +++ /dev/null @@ -1,20 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects -{ - [HarmonyPatch(typeof(ExploreMakeSceneButton))] - public class ExploreMakeSceneButton_Patch - { - [HarmonyPostfix] - [HarmonyPatch(nameof(ExploreMakeSceneButton.Start))] - public static void Start(ExploreMakeSceneButton __instance) - { - __instance.sceneText.text = (StringStore.translationString.ContainsKey(__instance.sceneText.text + "_FS")) ? StringStore.TranslateText(__instance.sceneText.text + "_FS") : StringStore.TranslateText(__instance.sceneText.text); - __instance.sceneText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/ButtonObjects/ExploreMakeZombieButton_Patch.cs b/MelonLoader/Patches/GameObjects/ButtonObjects/ExploreMakeZombieButton_Patch.cs deleted file mode 100644 index 49d638f..0000000 --- a/MelonLoader/Patches/GameObjects/ButtonObjects/ExploreMakeZombieButton_Patch.cs +++ /dev/null @@ -1,20 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects -{ - [HarmonyPatch(typeof(ExploreMakeZombieButton))] - public class ExploreMakeZombieButton_Patch - { - [HarmonyPostfix] - [HarmonyPatch(nameof(ExploreMakeZombieButton.Start))] - public static void Start(ExploreMakeZombieButton __instance) - { - __instance.sceneText.text = Utils.GetZombieNameFromAlmanac(__instance.theZombieType); - __instance.sceneText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/ButtonObjects/GodShootingLevelButton_Patch.cs b/MelonLoader/Patches/GameObjects/ButtonObjects/GodShootingLevelButton_Patch.cs deleted file mode 100644 index 6964c15..0000000 --- a/MelonLoader/Patches/GameObjects/ButtonObjects/GodShootingLevelButton_Patch.cs +++ /dev/null @@ -1,27 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using MelonLoader; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects -{ - [HarmonyPatch(typeof(GodShootingLevelButton))] - public static class GodShootingLevelButton_Patch - { - [HarmonyPatch(nameof(GodShootingLevelButton.Awake))] - [HarmonyPostfix] - private static void Awake(GodShootingLevelButton __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach(TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - string originalKey = StringStore.translationString.FirstOrDefault(x => x.Value == txt.text).Key; - txt.text = (StringStore.translationString.ContainsKey(originalKey + "_GS")) ? StringStore.TranslateText(originalKey + "_GS") : StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/ButtonObjects/InGameBtn_Patch.cs b/MelonLoader/Patches/GameObjects/ButtonObjects/InGameBtn_Patch.cs deleted file mode 100644 index 62b7911..0000000 --- a/MelonLoader/Patches/GameObjects/ButtonObjects/InGameBtn_Patch.cs +++ /dev/null @@ -1,41 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects -{ - [HarmonyPatch(typeof(InGameBtn))] - public static class InGameBtn_Patch - { - [HarmonyPatch(nameof(InGameBtn.Start))] - [HarmonyPostfix] - private static void Start(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); - } - } - } - - foreach(TextMeshProUGUI text in __instance.transform.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/ButtonObjects/LevelSaveEnter_Patch.cs b/MelonLoader/Patches/GameObjects/ButtonObjects/LevelSaveEnter_Patch.cs deleted file mode 100644 index 86a42f0..0000000 --- a/MelonLoader/Patches/GameObjects/ButtonObjects/LevelSaveEnter_Patch.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects -{ - public static class LevelSaveEnter_Patch - { - public static void TranslateEnter(LevelSaveEnter __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - __instance.text.text = StringStore.TranslateText(__instance.text.text); - __instance.text.font = fontAsset; - } - } -} diff --git a/MelonLoader/Patches/GameObjects/ButtonObjects/MainMenu_Btn_Patch.cs b/MelonLoader/Patches/GameObjects/ButtonObjects/MainMenu_Btn_Patch.cs deleted file mode 100644 index 097df1f..0000000 --- a/MelonLoader/Patches/GameObjects/ButtonObjects/MainMenu_Btn_Patch.cs +++ /dev/null @@ -1,37 +0,0 @@ -/*using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using UnityEngine; -using PvZ_Fusion_Translator.AssetStore; - -namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects -{ - [HarmonyPatch(typeof(MainMenu_Btn))] - public static class MainMenu_Btn_Patch - { - //public static List speechBubbles = new List(); - - //[HarmonyPatch(nameof(MainMenu_Btn.OnMouseEnter))] - //[HarmonyPostfix] - //private static void OnMouseEnter(MainMenu_Btn __instance) - //{ - // string textToShow = null; - - // if(__instance.transform.parent.name == "recipe") - // { - // textToShow = "探索模式"; - // } - // else if (__instance.name == "mysterious") - // { - // textToShow = "神秘模式"; - // } - - // if(textToShow != null) - // { - // InGameText.Instance.ShowText(textToShow, 2.0f); - // } - // } - } - -} -*/ \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/ButtonObjects/NormalBtn_Patch.cs b/MelonLoader/Patches/GameObjects/ButtonObjects/NormalBtn_Patch.cs deleted file mode 100644 index 8ccfcf0..0000000 --- a/MelonLoader/Patches/GameObjects/ButtonObjects/NormalBtn_Patch.cs +++ /dev/null @@ -1,26 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects -{ - [HarmonyPatch(typeof(NormalBtn))] - public class NormalBtn_Patch - { - [HarmonyPostfix] - [HarmonyPatch(nameof(NormalBtn.OnMouseUpAsButton))] - public static void OnMouseUpAsButton(NormalBtn __instance) - { - if(__instance.transform.childCount > 0) - { - Transform banTransform = __instance.transform.GetChild(0); - if (banTransform != null) - { - banTransform.GetComponent().text = StringStore.TranslateText(banTransform.GetComponent().text); - } - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs b/MelonLoader/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs deleted file mode 100644 index 45d94df..0000000 --- a/MelonLoader/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs +++ /dev/null @@ -1,393 +0,0 @@ -#if MULTI_LANGUAGE -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using MelonLoader; -using PvZ_Fusion_Translator; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using UnityEngine.UIElements; -using static MelonLoader.MelonLogger; -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 Utils.ToggleEnum? Toggle { get; set; } // Null if it's the "Next" button - public bool IsNextButton { get; set; } - public bool shifted = false; -} - -namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects -{ - internal class OptLanguageBtn_Patch - { - public static Dictionary LanguageBtnDict = new(); - public static Dictionary ToggleBtnDict = new(); - private static bool buttonsCreated = false; - private static bool togglesCreated = false; - private static OptionBtn cachedTemplateButton; - private static OptionBtn cachedTemplateToggleButton; - - private const float startX = 4.3241f + 2.56f; - private const float startY = 2.7769f; - private const float ySpacing = 1.2505f; - - private const float toggleStartX = 4.3241f; - private const float toggleStartY = -0.9746f; - - private static List AvailableLanguages; - private static List AvailableToggles; - private const int LanguagesPerPage = 5; - private static int currentPage = 0; - public static OptionBtn[] buttonSlots = new OptionBtn[6]; // 5 language buttons + 1 next button - public static OptionBtn[] toggleSlots = new OptionBtn[3]; - - 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.tag = "LangOpt"; - foreach(Transform child in newButton.GetComponentsInChildren()) - { - child.tag = "LangOpt"; - } - 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(); - } - - public static void CreateToggleButtons(OptionBtn templateButton) - { - if (togglesCreated) return; - togglesCreated = true; - cachedTemplateToggleButton = templateButton; - - AvailableToggles = Enum.GetValues(typeof(Utils.ToggleEnum)) - .Cast() - .Where(lang => lang != Utils.ToggleEnum.TOGGLE_END) - .ToList(); - - for (int i = 0; i < 3; i++) - { - var newButton = Object.Instantiate(templateButton, templateButton.transform.parent); - newButton.tag = "LangOpt"; - foreach(Transform child in newButton.GetComponentsInChildren()) - { - child.tag = "LangOpt"; - } - newButton.optionType = 100 + i; - - float yPos = toggleStartY - i * ySpacing; - Vector3 pos = new(toggleStartX, yPos); - newButton.transform.position = pos; - - toggleSlots[i] = newButton; - - ToggleBtnDict[newButton.GetInstanceID()] = new OptionButtonData - { - Button = newButton, - Position = pos - }; - } - - UpdatePage(); - } - - private static void UpdatePage() - { - int startIndex = currentPage * LanguagesPerPage; - int langCount = AvailableLanguages.Count; - int toggleCount = (togglesCreated) ? AvailableToggles.Count : 0; - - 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); - - string languageName = Utils.LanguageNames.ContainsKey(lang) ? Utils.LanguageNames[lang] : lang.ToString(); - UpdateButtonText(btn, languageName, FontStore.LoadTMPFont(lang.ToString())); - } - else - { - data.Language = null; - data.IsNextButton = false; - btn.gameObject.SetActive(false); - } - } - - if (togglesCreated) - { - for (int i = 0; i < 3; i++) - { - var btn = toggleSlots[i]; - var data = ToggleBtnDict[btn.GetInstanceID()]; - - if (i < toggleCount) - { - var toggle = AvailableToggles[i]; - data.Toggle = toggle; - data.IsNextButton = false; - btn.gameObject.SetActive(true); - string buttonText = Utils.ToggleNames.ContainsKey(toggle) ? Utils.ToggleNames[toggle] : toggle.ToString(); - UpdateButtonText(btn, StringStore.TranslateText(buttonText), FontStore.LoadTMPFont(Utils.Language.ToString())); - string sourceMsg = ""; - switch(i) - { - case 0: - sourceMsg = "" + (!(Utils.customTextures) ? "Texture Source:\nDefault" : "Texture Source:\nCustom"); - FlashMessage(btn, sourceMsg, 0.1f, false); - break; - case 1: - sourceMsg = "" + (!(Utils.customAudio) ? "Audio Source:\nDefault" : "Audio Source:\nCustom"); - FlashMessage(btn, sourceMsg, 0.1f, false); - break; - case 2: - sourceMsg = "" + (!(Utils.useLocal) ? "Translation Source:\nOnline" : "Translation Source:\nLocal"); - FlashMessage(btn, sourceMsg, 0.1f, false); - break; - default: - break; - } - } - 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 fontAsset = null) - { - 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 = (fontAsset != null) ? fontAsset : defaultAsset; - text.autoSizeTextContainer = false; - } - } - } - } - - public static void FlashMessage(OptionBtn button, string message, float yShift = 0.0f, bool useTimer = true) - { - var child = button.transform.GetChild(0); - if (child != null) - { - var text = child.GetComponent(); - string originalMsg = ""; - if (text != null) - { - originalMsg = text.text; - text.text = message; - OptionButtonData data; - bool isToggle = ToggleBtnDict.TryGetValue(button.GetInstanceID(), out data); - - if(isToggle) - { - text.transform.position = new Vector3(text.transform.position.x, text.transform.position.y + (ToggleBtnDict[button.GetInstanceID()].shifted ? 0.0f : yShift), text.transform.position.z); - ToggleBtnDict[button.GetInstanceID()].shifted = true; - } - else - { - text.transform.position = new Vector3(text.transform.position.x, text.transform.position.y + (LanguageBtnDict[button.GetInstanceID()].shifted ? 0.0f : yShift), text.transform.position.z); - LanguageBtnDict[button.GetInstanceID()].shifted = true; - } - } - child.gameObject.SetActive(true); - - if(useTimer) - { - System.Threading.Tasks.Task.Delay(1000).ContinueWith(_ => - { - if (button != null && child != null && child.gameObject.activeSelf) - { - OptionButtonData buttonData = ToggleBtnDict[button.GetInstanceID()]; - if(buttonData.Toggle != null) - { - string sourceMsg = originalMsg; - switch(buttonData.Toggle) - { - case Utils.ToggleEnum.Textures: - sourceMsg = "" + (!(Utils.customTextures) ? "Texture Source:\nDefault" : "Texture Source:\nCustom"); - break; - case Utils.ToggleEnum.Audio: - sourceMsg = "" + (!(Utils.customAudio) ? "Audio Source:\nDefault" : "Audio Source:\nCustom"); - break; - default: - break; - } - text.text = sourceMsg; - } - - } - }); - } - } - } - - private static void ToggleCustomAssets(string type) - { - if (type != "Textures" && type != "Audio" && type != "SwapLocal") return; - - if(type == "Textures") - { - Utils.customTextures = !Utils.customTextures; - MelonPreferences.SetEntryValue("PvZ_Fusion_Translator", "DefaultTextures", !Utils.customTextures); - TextureStore.Reload(); - object replaceTextureRoutine = MelonCoroutines.Start(TextureStore.ReplaceTexturesCoroutine()); - } - - if (type == "Audio") - { - Utils.customAudio = (Utils.customAudio) ? false : true; - MelonPreferences.SetEntryValue("PvZ_Fusion_Translator", "DefaultAudio", !Utils.customAudio); - } - - if (type == "SwapLocal") - { - Utils.WarnLocalData(); - } - - MelonPreferences.Save(); - } - - [HarmonyPatch(typeof(OptionBtn))] - public static class OptLangBtn_Patch - { - public static void Awake(OptionBtn __instance) - { - if (!buttonsCreated || cachedTemplateButton == null) - { - buttonsCreated = false; - togglesCreated = false; - CreateLanguageButtons(__instance); - CreateToggleButtons(__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!"); - } - } - } - - if (ToggleBtnDict.TryGetValue(__instance.GetInstanceID(), out var toggleData)) - { - string toggleType = toggleData.Toggle.ToString(); - ToggleCustomAssets(toggleType); - if (toggleType == "Textures") - { - FlashMessage(toggleData.Button, "Toggled custom textures!\n(Restart Required)", 0.1f); - } - else if (toggleType == "Audio") - { - FlashMessage(toggleData.Button, "Toggled custom audio!", 0.1f); - } - } - } - - [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; - } - - if (ToggleBtnDict.TryGetValue(__instance.GetInstanceID(), out var toggleData)) - { - toggleData.Button.transform.position = toggleData.Position; - } - } - } - } -} -#endif \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/ButtonObjects/OptionBtn_Patch.cs b/MelonLoader/Patches/GameObjects/ButtonObjects/OptionBtn_Patch.cs deleted file mode 100644 index e4d1e07..0000000 --- a/MelonLoader/Patches/GameObjects/ButtonObjects/OptionBtn_Patch.cs +++ /dev/null @@ -1,69 +0,0 @@ -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/MelonLoader/Patches/GameObjects/ButtonObjects/PVPPotBtn_Patch.cs b/MelonLoader/Patches/GameObjects/ButtonObjects/PVPPotBtn_Patch.cs deleted file mode 100644 index 2dfd98e..0000000 --- a/MelonLoader/Patches/GameObjects/ButtonObjects/PVPPotBtn_Patch.cs +++ /dev/null @@ -1,43 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppPVPScaryPot; -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/MelonLoader/Patches/GameObjects/ButtonObjects/PauseMenu_Btn_Patch.cs b/MelonLoader/Patches/GameObjects/ButtonObjects/PauseMenu_Btn_Patch.cs deleted file mode 100644 index 501706f..0000000 --- a/MelonLoader/Patches/GameObjects/ButtonObjects/PauseMenu_Btn_Patch.cs +++ /dev/null @@ -1,15 +0,0 @@ -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/MelonLoader/Patches/GameObjects/ButtonObjects/SaveMenuBtn_Patch.cs b/MelonLoader/Patches/GameObjects/ButtonObjects/SaveMenuBtn_Patch.cs deleted file mode 100644 index f9b16ac..0000000 --- a/MelonLoader/Patches/GameObjects/ButtonObjects/SaveMenuBtn_Patch.cs +++ /dev/null @@ -1,24 +0,0 @@ -#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/MelonLoader/Patches/GameObjects/ButtonObjects/UIBtn_Patch.cs b/MelonLoader/Patches/GameObjects/ButtonObjects/UIBtn_Patch.cs deleted file mode 100644 index 4afc43c..0000000 --- a/MelonLoader/Patches/GameObjects/ButtonObjects/UIBtn_Patch.cs +++ /dev/null @@ -1,23 +0,0 @@ -//using HarmonyLib; -//using Il2Cpp; -//using Il2CppTMPro; -//using PvZ_Fusion_Translator.AssetStore; -//using UnityEngine; -//using UnityEngine.UI; - -//namespace PvZ_Fusion_Translator.Patches.GameObjects -//{ -// [HarmonyPatch(typeof(UIBtn))] -// public static class UIBtn_Patch -// { -// [HarmonyPatch(nameof(UIBtn.Awake))] -// [HarmonyPostfix] -// private static void Postfix_Awake(UIBtn __instance) -// { -// if(__instance.TryGetComponent(out BackToIndex component)) -// { -// Utils.ConvertButtonText(__instance.transform.parent, component.name); -// } -// } -// } -//} diff --git a/MelonLoader/Patches/GameObjects/ButtonObjects/UIButton_Patch.cs b/MelonLoader/Patches/GameObjects/ButtonObjects/UIButton_Patch.cs deleted file mode 100644 index 515f9d8..0000000 --- a/MelonLoader/Patches/GameObjects/ButtonObjects/UIButton_Patch.cs +++ /dev/null @@ -1,56 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using UnityEngine.UI; -using UnityEngine.UIElements; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(UIButton))] - public static class UIButton_Patch - { - [HarmonyPatch(typeof(UIButton), nameof(UIButton.Start))] - [HarmonyPostfix] - public static void Start(UIButton __instance) - { - if(__instance.transform.childCount >= 2) - { - TMP_FontAsset font = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI text in __instance.transform.GetComponentsInChildren()) - { - if (__instance.transform.name == "Goback") - { - text.text = "合上"; - } - text.text = StringStore.TranslateText(text.text); - text.font = font; - } - } - else - { - StringStore.TranslateTextTransform(__instance.transform); - if(__instance.transform.name == "Goback") - { - foreach(TextMeshProUGUI text in __instance.transform.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText("合上"); - } - } - } - } - - [HarmonyPatch(nameof(UIButton.OnMouseUpAsButton))] - [HarmonyPostfix] - public static void Postfix_OnMouseUpAsButton(UIButton __instance) - { - foreach(TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/Close_Patch.cs b/MelonLoader/Patches/GameObjects/Close_Patch.cs deleted file mode 100644 index fb6ff9a..0000000 --- a/MelonLoader/Patches/GameObjects/Close_Patch.cs +++ /dev/null @@ -1,53 +0,0 @@ -/*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")); - - } - } -} -*/ \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/ConfirmMenu_Patch.cs b/MelonLoader/Patches/GameObjects/ConfirmMenu_Patch.cs deleted file mode 100644 index 6dc92b7..0000000 --- a/MelonLoader/Patches/GameObjects/ConfirmMenu_Patch.cs +++ /dev/null @@ -1,24 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using System.Text.RegularExpressions; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(ConfirmMenu))] - public static class ConfirmMenu_Patch - { - [HarmonyPatch(nameof(ConfirmMenu.SetTitle))] - [HarmonyPostfix] - private static void SetTitle(ConfirmMenu __instance) - { - foreach(TextMeshProUGUI title in __instance.title) - { - title.text = StringStore.TranslateText(title.text); - title.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/CrisisZombieWindow_Patch.cs b/MelonLoader/Patches/GameObjects/CrisisZombieWindow_Patch.cs deleted file mode 100644 index 9bef668..0000000 --- a/MelonLoader/Patches/GameObjects/CrisisZombieWindow_Patch.cs +++ /dev/null @@ -1,37 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using System.Text.RegularExpressions; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(CrisisZombieWindow))] - public static class CrisisZombieWindow_Patch - { - [HarmonyPatch(nameof(CrisisZombieWindow.Start))] - [HarmonyPostfix] - private static void Start(CrisisZombieWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - - [HarmonyPatch(nameof(CrisisZombieWindow.SetZombieType))] - [HarmonyPostfix] - private static void SetZombieType(CrisisZombieWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - } -} diff --git a/MelonLoader/Patches/GameObjects/CustomSettings_Patch.cs b/MelonLoader/Patches/GameObjects/CustomSettings_Patch.cs deleted file mode 100644 index 18ee55a..0000000 --- a/MelonLoader/Patches/GameObjects/CustomSettings_Patch.cs +++ /dev/null @@ -1,24 +0,0 @@ -//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/MelonLoader/Patches/GameObjects/CustomSun_Patch.cs b/MelonLoader/Patches/GameObjects/CustomSun_Patch.cs deleted file mode 100644 index 5d71423..0000000 --- a/MelonLoader/Patches/GameObjects/CustomSun_Patch.cs +++ /dev/null @@ -1,46 +0,0 @@ -/*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); - } - } - } - } -} -*/ \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/EveBuffMenu_Patch.cs b/MelonLoader/Patches/GameObjects/EveBuffMenu_Patch.cs deleted file mode 100644 index 51725ab..0000000 --- a/MelonLoader/Patches/GameObjects/EveBuffMenu_Patch.cs +++ /dev/null @@ -1,38 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using System.Text.RegularExpressions; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(EveBuffMenu))] - public static class EveBuffMenu_Patch - { - [HarmonyPatch(nameof(EveBuffMenu.Start))] - [HarmonyPostfix] - private static void Start(EveBuffMenu __instance) - { - foreach (EveOptionWindow window in __instance.windows) - { - EveOptionWindow_Patch.TranslateEveOptionWindow(window); - } - - foreach (TextMeshProUGUI text in __instance.quitButton.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText("合上"); - } - } - - [HarmonyPatch(nameof(EveBuffMenu.InitWindows))] - [HarmonyPostfix] - private static void InitWindows(EveBuffMenu __instance) - { - foreach(EveOptionWindow window in __instance.windows) - { - EveOptionWindow_Patch.TranslateEveOptionWindow(window); - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/EveOptionWindow_Patch.cs b/MelonLoader/Patches/GameObjects/EveOptionWindow_Patch.cs deleted file mode 100644 index 3d0a4c0..0000000 --- a/MelonLoader/Patches/GameObjects/EveOptionWindow_Patch.cs +++ /dev/null @@ -1,50 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using System.Text.RegularExpressions; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(EveOptionWindow))] - public static class EveOptionWindow_Patch - { - [HarmonyPatch(nameof(EveOptionWindow.SetType))] - [HarmonyPostfix] - private static void SetType(EveOptionWindow __instance) - { - TranslateEveOptionWindow(__instance); - } - - [HarmonyPatch(nameof(EveOptionWindow.OnAnimOver))] - [HarmonyPostfix] - private static void OnAnimOver(EveOptionWindow __instance) - { - TranslateEveOptionWindow(__instance); - } - - [HarmonyPatch(nameof(EveOptionWindow.SelectedByRow))] - [HarmonyPostfix] - private static void SelectedByRow(EveOptionWindow __instance) - { - TranslateEveOptionWindow(__instance); - } - - public static void TranslateEveOptionWindow(EveOptionWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - - foreach (TextMeshProUGUI text in __instance.buttonText) - { - text.text = StringStore.TranslateText(text.text); - text.font = fontAsset; - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/ExploreEnterWindow_Patch.cs b/MelonLoader/Patches/GameObjects/ExploreEnterWindow_Patch.cs deleted file mode 100644 index 648d2e2..0000000 --- a/MelonLoader/Patches/GameObjects/ExploreEnterWindow_Patch.cs +++ /dev/null @@ -1,73 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using System.Text.RegularExpressions; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(ExploreEnterWindow))] - public static class ExploreEnterWindow_Patch - { - [HarmonyPatch(nameof(ExploreEnterWindow.Awake))] - [HarmonyPostfix] - private static void Awake(ExploreEnterWindow __instance) - { - PlantType thePlantType = (PlantType)__instance.selfType; - - __instance.nameText.text = Utils.GetPlantNameFromAlmanac(thePlantType); - - if(__instance.nameText.text == "") - { - StringStore.TranslateText(__instance.nameText.text); - } - - __instance.nameText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - - [HarmonyPatch(nameof(ExploreEnterWindow.SetInfo))] - [HarmonyPostfix] - private static void SetInfo(ExploreEnterWindow __instance) - { - PlantType thePlantType = (PlantType)__instance.selfType; - - __instance.nameText.text = Utils.GetPlantNameFromAlmanac(thePlantType); - - if (__instance.nameText.text == "") - { - StringStore.TranslateText(__instance.nameText.text); - } - - __instance.nameText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - - [HarmonyPatch(nameof(ExploreEnterWindow.SetIcon))] - [HarmonyPostfix] - private static void SetIcon(ExploreEnterWindow __instance) - { - PlantType thePlantType = (PlantType)__instance.selfType; - - __instance.nameText.text = Utils.GetPlantNameFromAlmanac(thePlantType); - - if (__instance.nameText.text == "") - { - StringStore.TranslateText(__instance.nameText.text); - } - - __instance.nameText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - - [HarmonyPatch(nameof(ExploreEnterWindow.SetDisable))] - [HarmonyPostfix] - private static void SetDisable(ExploreEnterWindow __instance) - { - if (__instance.disabled) - { - __instance.nameText.text = StringStore.TranslateText("敬请期待"); - } - - __instance.nameText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } -} diff --git a/MelonLoader/Patches/GameObjects/ExploreMakeMenu_Patch.cs b/MelonLoader/Patches/GameObjects/ExploreMakeMenu_Patch.cs deleted file mode 100644 index 4116c29..0000000 --- a/MelonLoader/Patches/GameObjects/ExploreMakeMenu_Patch.cs +++ /dev/null @@ -1,72 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using System.Text.RegularExpressions; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(ExploreMakeMenu))] - public static class ExploreMakeMenu_Patch - { - [HarmonyPatch(nameof(ExploreMakeMenu.Awake))] - [HarmonyPostfix] - private static void Awake(ExploreMakeMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - - [HarmonyPatch(nameof(ExploreMakeMenu.InitMenu))] - [HarmonyPostfix] - private static void InitMenu(ExploreMakeMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - if(txt.text.Contains("关卡制作中:")) - { - string plantName = Utils.GetPlantNameFromAlmanac(txt.text.Split(":")[1]); - txt.text = String.Format(StringStore.translationStringRegex["关卡制作中:([^\\s]+)"], plantName); - } - else - { - txt.text = StringStore.TranslateText(txt.text); - } - } - } - - [HarmonyPatch(nameof(ExploreMakeMenu.ViewScene))] - [HarmonyPostfix] - private static void ViewScene(ExploreMakeMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - - [HarmonyPatch(nameof(ExploreMakeMenu.InitZombieButtons))] - [HarmonyPostfix] - private static void InitZombieButtons(ExploreMakeMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/ExploreMenu_Patch.cs b/MelonLoader/Patches/GameObjects/ExploreMenu_Patch.cs deleted file mode 100644 index 63a4f66..0000000 --- a/MelonLoader/Patches/GameObjects/ExploreMenu_Patch.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Numerics; -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(ExploreMenu))] - public static class ExploreMenu_Patch - { - [HarmonyPatch(nameof(ExploreMenu.Awake))] - [HarmonyPostfix] - private static void Awake(ExploreMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - } - - Transform randomLevelTextTransform = __instance.transform.FindChild("RandomLevel"); - } - - [HarmonyPatch(nameof(ExploreMenu.UpdateWindows))] - [HarmonyPostfix] - private static void UpdateWindows(ExploreMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/FruitNinjaSelectWindow_Patch.cs b/MelonLoader/Patches/GameObjects/FruitNinjaSelectWindow_Patch.cs deleted file mode 100644 index b04fd27..0000000 --- a/MelonLoader/Patches/GameObjects/FruitNinjaSelectWindow_Patch.cs +++ /dev/null @@ -1,37 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using System.Text.RegularExpressions; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(FruitNinjaSelectWindow))] - public static class FruitNinjaSelectWindow_Patch - { - [HarmonyPatch(nameof(FruitNinjaSelectWindow.SetType))] - [HarmonyPostfix] - private static void SetType(FruitNinjaSelectWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - - [HarmonyPatch(nameof(FruitNinjaSelectWindow.OnAnimOver))] - [HarmonyPostfix] - private static void OnAnimOver(FruitNinjaSelectWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - } -} diff --git a/MelonLoader/Patches/GameObjects/GardenPlant_Patch.cs b/MelonLoader/Patches/GameObjects/GardenPlant_Patch.cs deleted file mode 100644 index 92ad5ec..0000000 --- a/MelonLoader/Patches/GameObjects/GardenPlant_Patch.cs +++ /dev/null @@ -1,29 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using PvZ_Fusion_Translator.AssetStore; -using System.Text.RegularExpressions; -using Il2CppZenGarden; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(GardenPlant))] - public static class GardenPlant_Patch - { - [HarmonyPatch(nameof(GardenPlant.Start))] - [HarmonyPostfix] - private static void Start(GardenPlant __instance) - { - __instance.infoText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - __instance.infoText.text = StringStore.TranslateText(__instance.infoText.text); - } - - [HarmonyPatch(nameof(GardenPlant.UpdateInfo))] - [HarmonyPostfix] - private static void UpdateInfo(GardenPlant __instance) - { - - __instance.infoText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - __instance.infoText.text = StringStore.TranslateText(__instance.infoText.text); - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/GardenStoreMenu_Patch.cs b/MelonLoader/Patches/GameObjects/GardenStoreMenu_Patch.cs deleted file mode 100644 index fcb586d..0000000 --- a/MelonLoader/Patches/GameObjects/GardenStoreMenu_Patch.cs +++ /dev/null @@ -1,40 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppAlmanacData; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using System.Drawing; -using Il2CppZenGarden; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(GardenStoreMenu))] - public static class GardenStoreMenu_Patch - { - [HarmonyPatch(nameof(GardenStoreMenu.InitGoodsList))] - [HarmonyPatch(nameof(GardenStoreMenu.GetDatas))] - [HarmonyPatch(nameof(GardenStoreMenu.PurchaseGoods))] - [HarmonyPatch(nameof(GardenStoreMenu.Update))] - [HarmonyPatch(nameof(GardenStoreMenu.Start))] - [HarmonyPostfix] - public static void TranslateGardenStoreMenu(GardenStoreMenu __instance) - { - foreach(GardenShopSlot slot in __instance.GetComponentsInChildren()) - { - TranslateGardenShopSlot(slot); - } - } - - [HarmonyPatch(nameof(GardenShopSlot.Start))] - [HarmonyPostfix] - public static void TranslateGardenShopSlot(GardenShopSlot __instance) - { - foreach(TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/GodShootingMenu_Patch.cs b/MelonLoader/Patches/GameObjects/GodShootingMenu_Patch.cs deleted file mode 100644 index 4932b4b..0000000 --- a/MelonLoader/Patches/GameObjects/GodShootingMenu_Patch.cs +++ /dev/null @@ -1,44 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using static MelonLoader.MelonLogger; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(GodShootingMenu))] - public static class GodShootingMenu_Patch - { - [HarmonyPatch(nameof(GodShootingMenu.Start))] - [HarmonyPostfix] - private static void Start(GodShootingMenu __instance) - { - foreach(TextMeshProUGUI text in __instance.transform.Find("Background").GetComponentsInChildren()) - { - text.autoSizeTextContainer = true; - text.text = StringStore.TranslateText(text.text); - } - - foreach(TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - - [HarmonyPatch(nameof(GodShootingMenu.ShowRoutes))] - [HarmonyPostfix] - private static void ShowRoutes(GodShootingMenu __instance) - { - foreach(var route in __instance.routes) - { - if (route.Value == null) continue; - - foreach(TextMeshProUGUI text in route.Value.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/LevelResultMenu_Patch.cs b/MelonLoader/Patches/GameObjects/LevelResultMenu_Patch.cs deleted file mode 100644 index 3f52c2c..0000000 --- a/MelonLoader/Patches/GameObjects/LevelResultMenu_Patch.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Il2Cpp; -using UnityEngine; -using HarmonyLib; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(LevelResultMenu))] - public static class LevelResultMenu_Patch - { - [HarmonyPatch(nameof(LevelResultMenu.Start))] - [HarmonyPatch(nameof(LevelResultMenu.ShowResult))] - [HarmonyPostfix] - public static void Awake(LevelResultMenu __instance) - { - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/LoseMenu_Patch.cs b/MelonLoader/Patches/GameObjects/LoseMenu_Patch.cs deleted file mode 100644 index 2ba8b25..0000000 --- a/MelonLoader/Patches/GameObjects/LoseMenu_Patch.cs +++ /dev/null @@ -1,26 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using MelonLoader; -using PvZ_Fusion_Translator.AssetStore; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(LoseMenu))] - public static class LoseMenu_Patch - { - public static void TranslateLoseMenu(BaseMenu __instance) - { - if(__instance.TryGetComponent(out LoseMenu loseMenu)) - { - loseMenu.title.text = StringStore.TranslateText(loseMenu.title.text); - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/MainMenu_Patch.cs b/MelonLoader/Patches/GameObjects/MainMenu_Patch.cs deleted file mode 100644 index 770d936..0000000 --- a/MelonLoader/Patches/GameObjects/MainMenu_Patch.cs +++ /dev/null @@ -1,109 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects; -using Unity.VisualScripting; -using UnityEngine; -using UnityEngine.Events; -using UnityEngine.Rendering; -using UnityEngine.UIElements; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(MainMenu))] - public class MainMenu_Patch - { - public static void AnimOver(BaseMenu __instance) - { - Transform changelogObj = __instance.transform.Find("Grave/UpdateInfoButton"); - Transform langObj = UnityEngine.Object.Instantiate(changelogObj, changelogObj.position + new Vector3(0.0f, 0.855f), changelogObj.rotation, __instance.transform.Find("Grave")); - langObj.name = "LanguagesButton"; - __instance.collider2Ds.Add(langObj.GetComponent()); - UIButton langBtn = langObj.GetComponent(); - - foreach(TextMeshProUGUI text in langObj.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText("Languages"); - } - - langBtn.clickEvent = new UnityEvent(); - langBtn.clickEvent.AddListener(new Action(() => OpenLanguageMenu(langBtn.gameObject))); - } - - public static void OpenLanguageMenu(GameObject langBtn) - { - UIMgr.EnterOptionMenu(); - GameObject newOptionsMenu = GameAPP.canvasUp.Find("OptionMenu(Clone)").gameObject; - newOptionsMenu.name = "LanguageMenu"; - - List toKeep = new List() { "Background", "F", "Goback"}; - foreach(Transform child in newOptionsMenu.GetComponentsInChildren()) - { - if(!toKeep.Contains(child.name) && !toKeep.Contains(child.parent.name) && child.name != "LanguageMenu") - { - child.gameObject.SetActive(false); - } - } - - OptionBtn templateButton = newOptionsMenu.transform.Find("Buttons/F").GetComponent(); - OptLanguageBtn_Patch.OptLangBtn_Patch.Awake(templateButton); - - UIButton goBackButton = newOptionsMenu.transform.Find("Goback").GetComponent(); - - newOptionsMenu.transform.Find("Buttons/F").gameObject.SetActive(false); - newOptionsMenu.transform.Find("Buttons").gameObject.SetActive(true); - - foreach (TextMeshProUGUI text in newOptionsMenu.transform.Find("Background").GetComponentsInChildren()) - { - text.text = StringStore.TranslateText("Language Settings"); - } - - /*GameObject optionMenuAnchor = UnityEngine.Object.Instantiate(assetBundle.LoadAsset("OptionMenu").TryCast(), GameAPP.canvasUp); - optionMenuAnchor.transform.SetParent(newOptionsMenu.transform, false); - Transform messageAnchor = optionMenuAnchor.transform.Find("MessageAnchor"); - Transform plantAnchor = optionMenuAnchor.transform.Find("PlantAnchor"); - - System.Random random = new System.Random(); - var plantTypes = Enum.GetValues(typeof(PlantType)); - PlantType randomPlantChoice = (PlantType)plantTypes.GetValue(random.Next(plantTypes.Length)); - - if(!GameAPP.resourcesManager.plantPrefabs.ContainsKey(randomPlantChoice) || GameAPP.resourcesManager.plantPrefabs[randomPlantChoice] == null) - { - randomPlantChoice = (PlantType)plantTypes.GetValue(random.Next(plantTypes.Length)); - } - - if (GameAPP.resourcesManager.plantPrefabs[randomPlantChoice] != null) - { - GameObject plant = CreatePlant.SetPlantInAlmamac(plantAnchor.position, (int)randomPlantChoice); - plant.transform.SetParent(newOptionsMenu.transform); - SortingGroup sortingGroup = plant.AddComponent(); - sortingGroup.sortingLayerName = "UI"; - sortingGroup.sortingOrder = 20001; - //plant.transform.position = new Vector3(-7.21f, -3.66f); - UnityEngine.Object.Destroy(plant.GetComponent()); - }*/ - - /*GameObject messageObj = new GameObject(); - messageObj.name = "MultilangMessage"; - messageObj.transform.SetParent(newOptionsMenu.transform); - TextMeshProUGUI messageText = messageObj.AddComponent(); - messageObj.transform.localScale = Vector3.one; - messageText.autoSizeTextContainer = false; - messageText.font = FontStore.LoadTMPFont(Utils.LanguageEnum.English.ToString()); - messageText.text = "Hello this is multilanguage choose language over there ------>";*/ - } - - [HarmonyPatch(nameof(MainMenu.EnterUpdateUrl))] - [HarmonyPrefix] - public static bool Pre_EnterUpdateUrl(MainMenu __instance) - { - System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo - { - FileName = @"https://github.com/Teyliu/PVZF-Translation", - UseShellExecute = true - }); - return false; - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/MinorObjects/Brain_Patch.cs b/MelonLoader/Patches/GameObjects/MinorObjects/Brain_Patch.cs deleted file mode 100644 index 58a09e7..0000000 --- a/MelonLoader/Patches/GameObjects/MinorObjects/Brain_Patch.cs +++ /dev/null @@ -1,57 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using System.Text.RegularExpressions; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects -{ - [HarmonyPatch(typeof(Brain))] - public static class Brain_Patch - { - [HarmonyPostfix] - [HarmonyPatch(nameof(Brain.Awake))] - private static void Awake(Brain __instance) - { - // reposition original points - Transform pointsTransform = __instance.points.transform; - GameObject pointsObject = __instance.points.gameObject; - pointsTransform.position = new Vector3(-6.5f, pointsTransform.position.y, pointsTransform.position.z); - - // instantiate and move new shadow - GameObject pointsShadowObject = UnityEngine.Object.Instantiate(pointsObject, parent: pointsTransform); - pointsShadowObject.SetActive(true); - Transform pointsShadowTransform = pointsShadowObject.transform; - pointsShadowTransform.position = new Vector3(-6.485f, pointsTransform.position.y - 0.015f, pointsTransform.position.z); - - // set points text - TextMeshPro pointsShadowText = pointsShadowObject.GetComponent(); - pointsShadowText.text = __instance.points.text; - pointsShadowText.sortingOrder -= 2; - pointsShadowText.color = Color.black; - } - - [HarmonyPostfix] - [HarmonyPatch(nameof(Brain.Update))] - private static void Update(Brain __instance) - { - if(__instance.transform.Find("Points").GetChild(0) != null) - { - TextMeshPro shadowText = __instance.transform.Find("Points").GetChild(0).GetComponent(); - shadowText.text = __instance.points.text; - } - } - - [HarmonyPostfix] - [HarmonyPatch(nameof(Brain.WinAction))] - private static void WinAction(Brain __instance) - { - if (__instance.transform.Find("Points").GetChild(0) != null) - { - TextMeshPro shadowText = __instance.transform.Find("Points").GetChild(0).GetComponent(); - shadowText.text = __instance.points.text; - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/MinorObjects/DY_Patch.cs b/MelonLoader/Patches/GameObjects/MinorObjects/DY_Patch.cs deleted file mode 100644 index 10b48b2..0000000 --- a/MelonLoader/Patches/GameObjects/MinorObjects/DY_Patch.cs +++ /dev/null @@ -1,17 +0,0 @@ -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/MelonLoader/Patches/GameObjects/MinorObjects/GameLose_Patch.cs b/MelonLoader/Patches/GameObjects/MinorObjects/GameLose_Patch.cs deleted file mode 100644 index e55957f..0000000 --- a/MelonLoader/Patches/GameObjects/MinorObjects/GameLose_Patch.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using HarmonyLib; -using UnityEngine; -using Il2Cpp; -using Il2CppCore; -using PvZ_Fusion_Translator.Patches.BaseTextObjects; - -namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects -{ - [HarmonyPatch(typeof(GameLose))] - public static class GameLose_Patch - { - [HarmonyPatch(nameof(GameLose.UpdateSecondChanceTimer))] - public static void UpdateSecondChanceTimer(GameLose __instance) - { - if (InGameText.Instance == null) return; - - if (InGameText.Instance.timer < 0) return; - - InGameText_Patch.TranslateInGameText(InGameText.Instance); - } - } -} diff --git a/MelonLoader/Patches/GameObjects/MinorObjects/HealthSlider_Patch.cs b/MelonLoader/Patches/GameObjects/MinorObjects/HealthSlider_Patch.cs deleted file mode 100644 index 370d592..0000000 --- a/MelonLoader/Patches/GameObjects/MinorObjects/HealthSlider_Patch.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Il2Cpp; -using HarmonyLib; -using UnityEngine; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using Unity.VisualScripting; - -namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects -{ - [HarmonyPatch(typeof(HealthSlider))] - public static class HealthSlider_Patch - { - public static TMP_FontAsset fontAsset = null; - - [HarmonyPatch(nameof(HealthSlider.Start))] - [HarmonyPostfix] - public static void Post_Start(HealthSlider __instance) - { - if(!fontAsset) - { - fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } - - [HarmonyPatch(nameof(HealthSlider.UpdateText))] - [HarmonyPostfix] - public static void Post_UpdateText(HealthSlider __instance) - { - if(!fontAsset) fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - if (__instance.healthText.font != fontAsset) __instance.healthText.font = fontAsset; - - foreach(TextMeshProUGUI txt in __instance.healthTextContainer.GetComponentsInChildren(true)) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/MinorObjects/Jigsaw_Patch.cs b/MelonLoader/Patches/GameObjects/MinorObjects/Jigsaw_Patch.cs deleted file mode 100644 index ff0bb5d..0000000 --- a/MelonLoader/Patches/GameObjects/MinorObjects/Jigsaw_Patch.cs +++ /dev/null @@ -1,31 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(JigsawClip))] - public static class JigsawClip_Patch - { - [HarmonyPostfix] - [HarmonyPatch(nameof(JigsawClip.Awake))] - private static void Postfix_Awake(JigsawClip __instance) - { - if (!__instance || !__instance.description) return; - - StringStore.TranslateTextUI(__instance.description); - } - [HarmonyPostfix] - [HarmonyPatch(nameof(JigsawClip.Update))] - private static void Postfix_Update(JigsawClip __instance) - { - if (!__instance || !__instance.description) return; - - if (__instance.description.text != StringStore.TranslateText(__instance.description.text)) - { - StringStore.TranslateTextUI(__instance.description); - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/MinorObjects/LanternUmbrella_Patch.cs b/MelonLoader/Patches/GameObjects/MinorObjects/LanternUmbrella_Patch.cs deleted file mode 100644 index d4a1c82..0000000 --- a/MelonLoader/Patches/GameObjects/MinorObjects/LanternUmbrella_Patch.cs +++ /dev/null @@ -1,18 +0,0 @@ -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/MelonLoader/Patches/GameObjects/MinorObjects/MagnetBox_Patch.cs b/MelonLoader/Patches/GameObjects/MinorObjects/MagnetBox_Patch.cs deleted file mode 100644 index ea419b4..0000000 --- a/MelonLoader/Patches/GameObjects/MinorObjects/MagnetBox_Patch.cs +++ /dev/null @@ -1,17 +0,0 @@ -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/MelonLoader/Patches/GameObjects/MinorObjects/MagnetInterface_Patch.cs b/MelonLoader/Patches/GameObjects/MinorObjects/MagnetInterface_Patch.cs deleted file mode 100644 index a46f208..0000000 --- a/MelonLoader/Patches/GameObjects/MinorObjects/MagnetInterface_Patch.cs +++ /dev/null @@ -1,17 +0,0 @@ -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/MelonLoader/Patches/GameObjects/MinorObjects/Money_Patch.cs b/MelonLoader/Patches/GameObjects/MinorObjects/Money_Patch.cs deleted file mode 100644 index 3caa1d1..0000000 --- a/MelonLoader/Patches/GameObjects/MinorObjects/Money_Patch.cs +++ /dev/null @@ -1,19 +0,0 @@ -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) - { - if (!Utils.CheckForUntranslatedText(__instance.beanCount.text)) return; - __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/MelonLoader/Patches/GameObjects/MinorObjects/Plant_Patch.cs b/MelonLoader/Patches/GameObjects/MinorObjects/Plant_Patch.cs deleted file mode 100644 index b46f0db..0000000 --- a/MelonLoader/Patches/GameObjects/MinorObjects/Plant_Patch.cs +++ /dev/null @@ -1,47 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using System.Text.RegularExpressions; - -namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects -{ - /*[HarmonyPatch(typeof(Plant))] - public static class Plant_Patch - { - [HarmonyPostfix] - [HarmonyPatch(nameof(Plant.Awake))] - private static void Awake(Plant __instance) - { - if (!(__instance.thePlantType == PlantType.SuperMachineNut || __instance.thePlantType == PlantType.MachineNut)) - return; - __instance.healthSlider.healthText.text = __instance.healthSlider.healthTextShadow.text = ChangeHPText(__instance.healthSlider.healthTextShadow.text); - } - - [HarmonyPostfix] - [HarmonyPatch(nameof(Plant.UpdateText))] - private static void Update(Plant __instance) - { - if (!(__instance.thePlantType == PlantType.SuperMachineNut || __instance.thePlantType == PlantType.MachineNut)) - return; - if (__instance.thePlantHealth < __instance.thePlantMaxHealth) - return; - __instance.healthSlider.healthText.text = __instance.healthSlider.healthTextShadow.text = ChangeHPText(__instance.healthSlider.healthTextShadow.text); - } - - static string ChangeHPText(string originalText) - { - var regex = new Regex(@"(\d+)\d\d\d/(\d)000"); - if (regex.IsMatch(originalText)) - { - var match = regex.Match(originalText); - int groupCount = match.Groups.Count; - - List dynamicParts = new List(); - - for (int i = 1; i < groupCount; i++) - dynamicParts.Add(match.Groups[i].Value); - return originalText = string.Format("{0}k/{1}k", [.. dynamicParts]); - } - return originalText; - } - }*/ -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/MinorObjects/PlayerName_Patch.cs b/MelonLoader/Patches/GameObjects/MinorObjects/PlayerName_Patch.cs deleted file mode 100644 index 6b55d0a..0000000 --- a/MelonLoader/Patches/GameObjects/MinorObjects/PlayerName_Patch.cs +++ /dev/null @@ -1,17 +0,0 @@ -/*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/MelonLoader/Patches/GameObjects/MinorObjects/PumpinerChestMenu_Patch.cs b/MelonLoader/Patches/GameObjects/MinorObjects/PumpinerChestMenu_Patch.cs deleted file mode 100644 index 4a54d10..0000000 --- a/MelonLoader/Patches/GameObjects/MinorObjects/PumpinerChestMenu_Patch.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Il2Cpp; -using UnityEngine; -using HarmonyLib; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; - -namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects -{ - [HarmonyPatch(typeof(PumpinerChestMenu))] - public static class PumpinerChestMenu_Patch - { - [HarmonyPatch(nameof(PumpinerChestMenu.InitPlants))] - [HarmonyPostfix] - public static void Post_InitPlants(PumpinerChestMenu __instance) - { - Transform closeBtnTransform = __instance.transform.Find("SampleButton"); - TextMeshProUGUI txt = closeBtnTransform.GetComponentInChildren(); - txt.text = StringStore.TranslateText("合上"); - } - } -} diff --git a/MelonLoader/Patches/GameObjects/MinorObjects/SelectYourPlants_Patch.cs b/MelonLoader/Patches/GameObjects/MinorObjects/SelectYourPlants_Patch.cs deleted file mode 100644 index a5c1d73..0000000 --- a/MelonLoader/Patches/GameObjects/MinorObjects/SelectYourPlants_Patch.cs +++ /dev/null @@ -1,22 +0,0 @@ -/*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; - } - } -} -*/ \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/MinorObjects/SpecialCard_Patch.cs b/MelonLoader/Patches/GameObjects/MinorObjects/SpecialCard_Patch.cs deleted file mode 100644 index 875809e..0000000 --- a/MelonLoader/Patches/GameObjects/MinorObjects/SpecialCard_Patch.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects -{ - [HarmonyPatch(typeof(SpecialCard))] - public static class SpecialCard_Patch - { - [HarmonyPatch(nameof(SpecialCard.Awake))] - [HarmonyPatch(nameof(SpecialCard.Start))] - [HarmonyPatch(nameof(SpecialCard.ClickedEvent))] - [HarmonyPostfix] - public static void Post_Awake(SpecialCard __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach(TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/MinorObjects/TrainingDummy_Patch.cs b/MelonLoader/Patches/GameObjects/MinorObjects/TrainingDummy_Patch.cs deleted file mode 100644 index 8128ccc..0000000 --- a/MelonLoader/Patches/GameObjects/MinorObjects/TrainingDummy_Patch.cs +++ /dev/null @@ -1,16 +0,0 @@ -using HarmonyLib; -using Il2Cpp; - -namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects -{ - [HarmonyPatch(typeof(TrainingDummy), nameof(TrainingDummy.UpdateHealthText))] - public static class TrainingDummy_Patch - { - [HarmonyPostfix] - public static void UpdateHealthText(TrainingDummy __instance) - { - Zombie_Patch.TranslateHpUI_T(__instance.healthText, __instance); - //Zombie_Patch.TranslateHpUI_T(__instance.healthTextShadow, __instance); - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/MinorObjects/TreasureMoney_Patch.cs b/MelonLoader/Patches/GameObjects/MinorObjects/TreasureMoney_Patch.cs deleted file mode 100644 index 60dc971..0000000 --- a/MelonLoader/Patches/GameObjects/MinorObjects/TreasureMoney_Patch.cs +++ /dev/null @@ -1,17 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using PvZ_Fusion_Translator.AssetStore; - -namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects -{ - [HarmonyPatch(typeof(TreasureMoney))] - public static class TreasureMoney_Patch - { - [HarmonyPostfix] - [HarmonyPatch(nameof(TreasureMoney.Update))] - private static void Update(TreasureMoney __instance) - { - __instance.text = StringStore.TranslateText(__instance.text); - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/MinorObjects/UIProgress2_Patch.cs b/MelonLoader/Patches/GameObjects/MinorObjects/UIProgress2_Patch.cs deleted file mode 100644 index 2ab8b59..0000000 --- a/MelonLoader/Patches/GameObjects/MinorObjects/UIProgress2_Patch.cs +++ /dev/null @@ -1,17 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using PvZ_Fusion_Translator.AssetStore; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(UIProgress2))] - public static class UIProgress2_Patch - { - [HarmonyPatch(nameof(UIProgress2.Update))] - [HarmonyPostfix] - private static void Update(UIProgress2 __instance) - { - __instance.t.text = StringStore.TranslateText(__instance.t.text); - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/MinorObjects/UltimateChomper_Patch.cs b/MelonLoader/Patches/GameObjects/MinorObjects/UltimateChomper_Patch.cs deleted file mode 100644 index 9443605..0000000 --- a/MelonLoader/Patches/GameObjects/MinorObjects/UltimateChomper_Patch.cs +++ /dev/null @@ -1,17 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using PvZ_Fusion_Translator.AssetStore; - -namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects -{ - /*[HarmonyPatch(typeof(UltimateChomper), nameof(UltimateChomper.UpdateText))] - public static class UltimateChomper_Patch - { - [HarmonyPostfix] - public static void UpdateText(UltimateChomper __instance) - { - StringStore.TranslateText(__instance.killingText); - StringStore.TranslateText(__instance.killingTextShadow); - } - }*/ -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/MinorObjects/Zombie_Patch.cs b/MelonLoader/Patches/GameObjects/MinorObjects/Zombie_Patch.cs deleted file mode 100644 index 6dd850a..0000000 --- a/MelonLoader/Patches/GameObjects/MinorObjects/Zombie_Patch.cs +++ /dev/null @@ -1,178 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using PvZ_Fusion_Translator.AssetStore; -using System.Text.RegularExpressions; -using UnityEngine; -using Il2CppTMPro; -using System.Reflection.Metadata.Ecma335; - -namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects -{ - [HarmonyPatch(typeof(Zombie))] - public static class Zombie_Patch - { - private static Dictionary HPStrings = new Dictionary() - { - { "最后一击:(\\d+)\nDPS:([^\\s]+)\n总伤害:(\\d+)", "Last Damage: {0}\nDPS: {1}\nTotal: {2}" }, - { "^HP:(\\d+)/(\\d+)\n一类:(\\d+)/(\\d+)\n二类:(\\d+)/(\\d+)$", "HP: {0}/{1}\nT1 armor: {2}/{3}\nT2 armor: {4}/{5}" }, - { "^HP:(\\d+)/(\\d+)\n一类:(\\d+)/(\\d+)$", "HP: {0}/{1}\nT1 armor: {2}/{3}" }, - { "^HP:(\\d+)/(\\d+)\n二类:(\\d+)/(\\d+)$", "HP: {0}/{1}\nT2 armor: {2}/{3}" }, - { "^HP:(\\d+)/(\\d+)$", "HP: {0}/{1}" } - }; - - public static void LoadHPStrings() - { - foreach (var hp in HPStrings) - if (StringStore.translationStringRegex.ContainsKey(hp.Key)) - HPStrings[hp.Key] = StringStore.translationStringRegex[hp.Key]; - } - - [HarmonyPatch(nameof(Zombie.Start))] - [HarmonyPostfix] - public static void Start(Zombie __instance) - { - TranslateHpUI(__instance.healthText, __instance); - //TranslateHpUI(__instance.healthTextShadow, __instance); - - if (__instance.healthText.transform.rotation != Quaternion.Euler(0, 0, 0)) - __instance.healthText.transform.rotation = Quaternion.Euler(0f, 0f, 0f); - } - - [HarmonyPatch(nameof(Zombie.UpdateHealthText))] - [HarmonyPostfix] - public static void Update(Zombie __instance) - { - if (__instance.theZombieType == ZombieType.TrainingDummy || !Board.Instance.showZombieHealth) - return; - - if (__instance.healthText == null) return; - - TranslateHpUI(__instance.healthText, __instance); - //TranslateHpUI(__instance.healthTextShadow, __instance); - - if (__instance.healthText.transform.rotation != Quaternion.Euler(0f, 0f, 0f)) - __instance.healthText.transform.rotation = Quaternion.Euler(0f, 0f, 0f); - } - - public static void TranslateHpUI(TextMeshPro textTMP, Zombie __instance) - { - if (textTMP) - { - string origText = textTMP.text; - string translatedText = origText; - if (translatedText == null) return; - string pattern = "(\\d+)阶\n([\\s\\S]+)"; - if (StringStore.TestRegex(translatedText, pattern)) - { - var match = Regex.Match(translatedText, pattern, RegexOptions.Singleline); - string tier = match.Groups[1].Value; - string healthText = TranslateHPText(match.Groups[2].Value, __instance); - string fStr = StringStore.translationStringRegex[pattern]; - translatedText = string.Format(fStr, [tier, healthText]); - } - else - { - translatedText = TranslateHPText(origText, __instance); - } - textTMP.text = translatedText == origText ? origText : translatedText; - textTMP.autoSizeTextContainer = false; - if (translatedText != origText) - textTMP.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } - - public static void TranslateHpUI_T(TextMeshPro textTMP, TrainingDummy __instance) - { - if (textTMP) - { - string origText = textTMP.text; - string translatedText = TranslateHPText_T(origText, __instance); - textTMP.text = translatedText == origText ? origText : translatedText; - textTMP.autoSizeTextContainer = false; - if (translatedText != origText) - textTMP.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } - - public static string TranslateHPText(string originalText, Zombie __instance) - { - if(originalText == null) - { - return originalText; - } - - string finalText = __instance.healthText.text; - int fIndex = -1; - bool found = false; - - for(int i = 0; i < HPStrings.Count; i++) - { - var hp = HPStrings.ElementAt(i); - if(Regex.Match(originalText, hp.Key, RegexOptions.Singleline).Success) - { - fIndex = i; - found = true; - } - } - - if(fIndex > -1 && found) - { - string fStr = HPStrings.ElementAt(fIndex).Value; - - switch (fIndex) - { - case 1: - finalText = string.Format(fStr, __instance.theHealth, __instance.theMaxHealth, __instance.theFirstArmorHealth, __instance.theFirstArmorMaxHealth, __instance.theSecondArmorHealth, __instance.theSecondArmorMaxHealth); - break; - case 2: - finalText = string.Format(fStr, __instance.theHealth, __instance.theMaxHealth, __instance.theFirstArmorHealth, __instance.theFirstArmorMaxHealth); - break; - case 3: - finalText = string.Format(fStr, __instance.theHealth, __instance.theMaxHealth, __instance.theSecondArmorHealth, __instance.theSecondArmorMaxHealth); - break; - case 4: - finalText = string.Format(fStr, __instance.theHealth, __instance.theMaxHealth); - break; - default: - break; - } - } - - return finalText; - } - - public static string TranslateHPText_T(string originalText, TrainingDummy __instance) - { - string finalText = __instance.healthText.text; - int fIndex = -1; - bool found = false; - - for (int i = 0; i < HPStrings.Count; i++) - { - var hp = HPStrings.ElementAt(i); - Regex regex = new Regex(hp.Key); - if (regex.IsMatch(originalText)) - { - fIndex = i; - found = true; - } - } - - if (fIndex > -1 && found) - { - string fStr = HPStrings.ElementAt(fIndex).Value; - - switch (fIndex) - { - case 0: - finalText = string.Format(fStr, __instance.lastDamage, __instance.CurrentDPS, __instance.totalDamage); - break; - default: - break; - } - } - - return finalText; - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/NoticePauseMenu_Patch.cs b/MelonLoader/Patches/GameObjects/NoticePauseMenu_Patch.cs deleted file mode 100644 index e050e37..0000000 --- a/MelonLoader/Patches/GameObjects/NoticePauseMenu_Patch.cs +++ /dev/null @@ -1,56 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using UnityEngine.UI; -using static PvZ_Fusion_Translator.FileLoader; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - public class NoticePauseMenu_Patch - { - public static string changelogText = ""; - - public static void Pre_Awake(BaseMenu __instance) - { - GameObject contentObject = __instance.transform.FindChild("Scroll View/Viewport/Content").gameObject; - - TextMeshProUGUI contentText = contentObject.GetComponent(); - File.WriteAllText(Path.Combine(FileLoader.GetAssetDir(FileLoader.AssetType.Dumps), "changelog.txt"), contentText.text); - - string stringDir = FileLoader.GetAssetDir(FileLoader.AssetType.Strings, Utils.Language); - string changelogDir = Path.Combine(stringDir, "changelog.txt"); - - if (!File.Exists(changelogDir)) - { - File.WriteAllText(changelogDir, contentText.text); - } - } - - public static void Post_Awake(BaseMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - FileLoader.LoadChangelogText(); - - GameObject contentObject = __instance.transform.FindChild("Scroll View/Viewport/Content").gameObject; - - TextMeshProUGUI contentText = contentObject.GetComponent(); - contentText.text = changelogText; - contentText.margin = new Vector4(6, 2, 12, 0); - - contentText.enableWordWrapping = true; - contentText.overflowMode = TextOverflowModes.ScrollRect; - - Canvas.ForceUpdateCanvases(); - contentText.ForceMeshUpdate(); - - //float textHeight = contentText.preferredHeight; - //RectTransform contentRect = contentObject.GetComponent(); - //contentRect.sizeDelta = new Vector2(contentRect.sizeDelta.x, textHeight); - - ContentSizeFitter sizeFitter = contentObject.AddComponent(); - sizeFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/OtherMenu_Patch.cs b/MelonLoader/Patches/GameObjects/OtherMenu_Patch.cs deleted file mode 100644 index 8fed8a9..0000000 --- a/MelonLoader/Patches/GameObjects/OtherMenu_Patch.cs +++ /dev/null @@ -1,20 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(OtherMenu))] - public static class OtherMenu_Patch - { - [HarmonyPatch(nameof(OtherMenu.UpdateText))] - [HarmonyPostfix] - private static void UpdateText(OtherMenu __instance) - { - __instance.text1 = StringStore.TranslateText(__instance.text1); - __instance.text2 = StringStore.TranslateText(__instance.text2); - } - } -} diff --git a/MelonLoader/Patches/GameObjects/PVPRandomManager_Patch.cs b/MelonLoader/Patches/GameObjects/PVPRandomManager_Patch.cs deleted file mode 100644 index a3d21b0..0000000 --- a/MelonLoader/Patches/GameObjects/PVPRandomManager_Patch.cs +++ /dev/null @@ -1,33 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using static MelonLoader.MelonLogger; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(PVPRandomManager))] - public static class PVPRandomManager_Patch - { - [HarmonyPatch(nameof(PVPRandomManager.Start))] - [HarmonyPostfix] - private static void Start(PVPRandomManager __instance) - { - foreach(TextMeshPro text in __instance.texts) - { - text.text = StringStore.TranslateText(text.text); - } - } - - [HarmonyPatch(nameof(PVPRandomManager.Update))] - [HarmonyPostfix] - private static void ZombieEnterHouse(PVPRandomManager __instance) - { - foreach(TextMeshPro text in __instance.texts) - { - text.text = StringStore.TranslateText(text.text); - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/PlantCardPackageBuilder_Patch.cs b/MelonLoader/Patches/GameObjects/PlantCardPackageBuilder_Patch.cs deleted file mode 100644 index 50c7f38..0000000 --- a/MelonLoader/Patches/GameObjects/PlantCardPackageBuilder_Patch.cs +++ /dev/null @@ -1,22 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(PlantCardPackageBuilder))] - public static class PlantCardPackageBuilder_Patch - { - [HarmonyPatch(nameof(PlantCardPackageBuilder.UpdateText))] - [HarmonyPostfix] - private static void UpdateText(PlantCardPackageBuilder __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - __instance.text.text = StringStore.TranslateText(__instance.text.text); - __instance.text.font = fontAsset; - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/PlantDamageMenu_Patch.cs b/MelonLoader/Patches/GameObjects/PlantDamageMenu_Patch.cs deleted file mode 100644 index f29c099..0000000 --- a/MelonLoader/Patches/GameObjects/PlantDamageMenu_Patch.cs +++ /dev/null @@ -1,38 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using System.Text.RegularExpressions; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(PlantDamageMenu))] - public static class PlantDamageMenu_Patch - { - public static void Awake(BaseMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - foreach(TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - string originalKey = StringStore.translationString.FirstOrDefault(x => x.Value == text.text).Key; - text.text = StringStore.translationString.ContainsKey(originalKey + "_RM") ? StringStore.TranslateText(originalKey + "_RM") : StringStore.TranslateText(text.text); - text.font = fontAsset; - } - } - - [HarmonyPatch(nameof(PlantDamageMenu.Awake))] - [HarmonyPatch(nameof(PlantDamageMenu.InitCards))] - [HarmonyPostfix] - public static void InitCards(PlantDamageMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - string originalKey = StringStore.translationString.FirstOrDefault(x => x.Value == text.text).Key; - text.text = StringStore.translationString.ContainsKey(originalKey + "_RM") ? StringStore.TranslateText(originalKey + "_RM") : StringStore.TranslateText(text.text); - text.font = fontAsset; - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/PlantDataMenu_Patch.cs b/MelonLoader/Patches/GameObjects/PlantDataMenu_Patch.cs deleted file mode 100644 index 1643d0d..0000000 --- a/MelonLoader/Patches/GameObjects/PlantDataMenu_Patch.cs +++ /dev/null @@ -1,94 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading.Tasks; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(PlantDataMenu))] - public static class PlantDataMenu_Patch - { - [HarmonyPatch(nameof(PlantDataMenu.Start))] - [HarmonyPostfix] - public static void Post_Start(PlantDataMenu __instance) - { - TranslatePlantDataMenu(__instance); - } - - /*[HarmonyPatch(nameof(PlantDataMenu.Update))] - [HarmonyPostfix] - public static void Post_Update(PlantDataMenu __instance) - { - TranslatePlantDataMenu(__instance); - }*/ - - [HarmonyPatch(nameof(PlantDataMenu.InitDataFromPlant))] - [HarmonyPostfix] - public static void Post_InitDataFromPlant(PlantDataMenu __instance) - { - TranslatePlantDataMenu(__instance); - } - - public static void TranslatePlantDataMenu(PlantDataMenu __instance) - { - if (!__instance) return; - - PlantType thePlantType = __instance.plant.thePlantType; - string plantName = Utils.GetPlantNameFromAlmanac(thePlantType); - - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach(TextMeshProUGUI text in __instance.nameText) - { - text.text = plantName; - text.font = fontAsset; - } - - foreach(TextMeshProUGUI text in __instance.infoText) - { - string toTranslate = text.text; - string startColorTag = ""; - - string colorPattern = @"(]+>)(.*?)()"; - Match match = Regex.Match(toTranslate, colorPattern); - if(match.Success) - { - startColorTag = match.Groups[1].Value; - toTranslate = match.Groups[2].Value; - } - - string[] parts = toTranslate.Split("\n"); - List translatedParts = new List(); - - foreach(string part in parts) - { - translatedParts.Add(StringStore.TranslateText(part)); - } - - string joinedTranslation = String.Join("\n", translatedParts); - - if(startColorTag != "") - { - text.text = startColorTag + joinedTranslation + ""; - } - else - { - text.text = joinedTranslation; - } - - text.font = fontAsset; - } - - foreach(TextMeshProUGUI text in __instance.toggles.transform.Find("Viewport/Content/Toggles").GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/PlantInfoWindow_Patch.cs b/MelonLoader/Patches/GameObjects/PlantInfoWindow_Patch.cs deleted file mode 100644 index f749978..0000000 --- a/MelonLoader/Patches/GameObjects/PlantInfoWindow_Patch.cs +++ /dev/null @@ -1,56 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using MelonLoader.TinyJSON; -using PvZ_Fusion_Translator.AssetStore; -using Unity.Collections; -using UnityEngine; -using UnityEngine.UIElements; -using static PvZ_Fusion_Translator.FileLoader; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(PlantInfoWindow))] - public static class PlantInfoWindow_Patch - { - [HarmonyPatch(nameof(PlantInfoWindow.InitText))] - [HarmonyPostfix] - private static void InitText(PlantInfoWindow __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - BigGardenPlant thePlant = __instance.plant; - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - if (txt.name.Contains("Introduce") && thePlant != null) - { - PlantType thePlantType = thePlant.thePlantType; - txt.text = StringStore.TranslateText(txt.text); - - string text = txt.text; - string[] lines = text.Split("\n"); - - lines[0] = Utils.GetPlantNameFromAlmanac(thePlantType); - string updatedText = String.Join("\n", lines); - - txt.text = updatedText; - } - else - { - txt.text = StringStore.TranslateText(txt.text); - } - - txt.font = fontAsset; - } - - Transform parentWindowTransform = __instance.transform.parent; - Transform returnPlantTransform = parentWindowTransform.FindChild("Close"); - - foreach(TextMeshProUGUI txt in returnPlantTransform.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText("合上"); - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/PlayerSaveMenu_Patch.cs b/MelonLoader/Patches/GameObjects/PlayerSaveMenu_Patch.cs deleted file mode 100644 index d550ff9..0000000 --- a/MelonLoader/Patches/GameObjects/PlayerSaveMenu_Patch.cs +++ /dev/null @@ -1,36 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using System.Text.RegularExpressions; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(PlayerSaveMenu))] - public static class PlayerSaveMenu_Patch - { - [HarmonyPatch(nameof(PlayerSaveMenu.CreatePlayerData))] - [HarmonyPostfix] - public static void CreatePlayerData(PlayerSaveMenu __instance) - { - TranslateCreatePlayerSaveMenu(); - } - - [HarmonyPatch(nameof(PlayerSaveMenu.ResetName))] - [HarmonyPostfix] - public static void ResetName(PlayerSaveMenu __instance) - { - TranslateCreatePlayerSaveMenu(); - } - - public static void TranslateCreatePlayerSaveMenu() - { - Transform reNameMenuTransform = GameAPP.canvasUp.Find("ReNameMenu(Clone)"); - if(reNameMenuTransform.TryGetComponent(out ReNameMenu reNameMenu)) - { - reNameMenu.title.text = StringStore.TranslateText(reNameMenu.title.text); - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/PlayerShootingMenu_Patch.cs b/MelonLoader/Patches/GameObjects/PlayerShootingMenu_Patch.cs deleted file mode 100644 index 3e47e10..0000000 --- a/MelonLoader/Patches/GameObjects/PlayerShootingMenu_Patch.cs +++ /dev/null @@ -1,40 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(PlayerShootingMenu))] - public static class PlayerShootingMenu_Patch - { - [HarmonyPatch(nameof(PlayerShootingMenu.Update))] - [HarmonyPostfix] - private static void Update(PlayerShootingMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - - [HarmonyPatch(nameof(PlayerShootingMenu.Refresh))] - [HarmonyPostfix] - private static void Refresh(PlayerShootingMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - Transform refreshTransform = __instance.transform.FindChild("Button"); - foreach (TextMeshProUGUI text in refreshTransform.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - text.font = fontAsset; - text.autoSizeTextContainer = false; - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/PlayerShootingWindow_Patch.cs b/MelonLoader/Patches/GameObjects/PlayerShootingWindow_Patch.cs deleted file mode 100644 index de7a336..0000000 --- a/MelonLoader/Patches/GameObjects/PlayerShootingWindow_Patch.cs +++ /dev/null @@ -1,37 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using System.Text.RegularExpressions; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(PlayerShootingWindow))] - public static class PlayerShootingWindow_Patch - { - [HarmonyPatch(nameof(PlayerShootingWindow.SetType))] - [HarmonyPostfix] - private static void SetType(PlayerShootingWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - - [HarmonyPatch(nameof(PlayerShootingWindow.OnAnimOver))] - [HarmonyPostfix] - private static void OnAnimOver(PlayerShootingWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - } -} diff --git a/MelonLoader/Patches/GameObjects/ReNameMenu_Patch.cs b/MelonLoader/Patches/GameObjects/ReNameMenu_Patch.cs deleted file mode 100644 index 5a1ce8e..0000000 --- a/MelonLoader/Patches/GameObjects/ReNameMenu_Patch.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using HarmonyLib; -using UnityEngine; -using Il2Cpp; -using PvZ_Fusion_Translator.AssetStore; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(ReNameMenu))] - public static class ReNameMenu_Patch - { - [HarmonyPatch(nameof(ReNameMenu.SetTitle))] - [HarmonyPostfix] - public static void SetTitle(ReNameMenu __instance) - { - __instance.title.text = StringStore.TranslateText(__instance.title.text); - } - - [HarmonyPatch(nameof(ReNameMenu.SetInputText))] - [HarmonyPostfix] - public static void SetInputText(ReNameMenu __instance) - { - __instance.input.text = StringStore.TranslateText(__instance.input.text); - } - } -} diff --git a/MelonLoader/Patches/GameObjects/RogueCardWindow_Patch.cs b/MelonLoader/Patches/GameObjects/RogueCardWindow_Patch.cs deleted file mode 100644 index 57db19c..0000000 --- a/MelonLoader/Patches/GameObjects/RogueCardWindow_Patch.cs +++ /dev/null @@ -1,37 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using System.Text.RegularExpressions; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(RogueCardWindow))] - public static class RogueCardWindow_Patch - { - [HarmonyPatch(nameof(RogueCardWindow.InitCard))] - [HarmonyPostfix] - private static void InitCard(RogueCardWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - - [HarmonyPatch(nameof(RogueCardWindow.OnAnimOver))] - [HarmonyPostfix] - private static void OnAnimOver(RogueCardWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - } -} diff --git a/MelonLoader/Patches/GameObjects/RogueStartMenu_Patch.cs b/MelonLoader/Patches/GameObjects/RogueStartMenu_Patch.cs deleted file mode 100644 index c231ce3..0000000 --- a/MelonLoader/Patches/GameObjects/RogueStartMenu_Patch.cs +++ /dev/null @@ -1,44 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using MelonLoader; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using UnityEngine.TextCore.Text; -using UnityEngine.UI; -using static MelonLoader.MelonLogger; -using static System.Net.Mime.MediaTypeNames; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - - [HarmonyPatch(typeof(RogueStartMenu))] - public static class RogueStartMenu_Patch - { - [HarmonyPatch(nameof(RogueStartMenu.SetLeader))] - [HarmonyPostfix] - private static void SetLeader(RogueStartMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - - [HarmonyPatch(nameof(RogueStartMenu.EnterGame))] - [HarmonyPostfix] - private static void EnterGame(RogueStartMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } -} diff --git a/MelonLoader/Patches/GameObjects/SeedLibrary_Patch.cs b/MelonLoader/Patches/GameObjects/SeedLibrary_Patch.cs deleted file mode 100644 index f307a4f..0000000 --- a/MelonLoader/Patches/GameObjects/SeedLibrary_Patch.cs +++ /dev/null @@ -1,58 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(SeedLibrary))] - public static class SeedLibrary_Patch - { - [HarmonyPatch(nameof(SeedLibrary.ChangeSafeMode))] - [HarmonyPostfix] - private static void ChangeSafeMode(SeedLibrary __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - //foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - //{ - // txt.text = StringStore.TranslateText(txt.text); - // txt.font = fontAsset; - //} - - Transform safetyBoxButtonTransform = __instance.transform.FindChild("SafeBox").FindChild("StartSafeMode"); - - if (__instance.safeMode == false && safetyBoxButtonTransform != null) - { - foreach (TextMeshProUGUI txt in safetyBoxButtonTransform.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText("合上"); - } - } - } - - [HarmonyPatch(nameof(SeedLibrary.Start))] - [HarmonyPatch(nameof(SeedLibrary.SetAllCards))] - [HarmonyPostfix] - private static void SetAllCards(SeedLibrary __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - //foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - //{ - // txt.text = StringStore.TranslateText(txt.text); - // txt.font = fontAsset; - //} - - foreach(TextMeshProUGUI txt in __instance.page.GetComponentsInChildren(true)) - { - txt.font = fontAsset; - if (!Utils.CheckForUntranslatedText(txt.text)) - { - txt.text = StringStore.TranslateText(txt.text); - } - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/ShootingMenu_Patch.cs b/MelonLoader/Patches/GameObjects/ShootingMenu_Patch.cs deleted file mode 100644 index 7735106..0000000 --- a/MelonLoader/Patches/GameObjects/ShootingMenu_Patch.cs +++ /dev/null @@ -1,25 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - /*[HarmonyPatch(typeof(ShootingMenu))] - public static class ShootingMenu_Patch - { - [HarmonyPatch(nameof(ShootingMenu.Update))] - [HarmonyPostfix] - private static void Update(ShootingMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - }*/ -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/ShootingSelectWindow_Patch.cs b/MelonLoader/Patches/GameObjects/ShootingSelectWindow_Patch.cs deleted file mode 100644 index 79580b5..0000000 --- a/MelonLoader/Patches/GameObjects/ShootingSelectWindow_Patch.cs +++ /dev/null @@ -1,73 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using System.Text.RegularExpressions; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - /*[HarmonyPatch(typeof(ShootingSelectWindow))] - public static class ShootingSelectWindow_Patch - { - [HarmonyPatch(nameof(ShootingSelectWindow.InitPlantType))] - [HarmonyPostfix] - private static void InitCard(ShootingSelectWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - - [HarmonyPatch(nameof(ShootingSelectWindow.OnAnimOver))] - [HarmonyPostfix] - private static void OnAnimOver(ShootingSelectWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - - [HarmonyPatch(nameof(ShootingSelectWindow.SetUpgradePlantTypes))] - [HarmonyPostfix] - private static void SetUpgradePlantTypes(ShootingSelectWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - - [HarmonyPatch(nameof(ShootingSelectWindow.GetMaxIndexInRoutes))] - [HarmonyPostfix] - private static void GetMaxIndexInRoutes(ShootingSelectWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - - [HarmonyPatch(nameof(ShootingSelectWindow.Start))] - [HarmonyPostfix] - private static void Start(ShootingSelectWindow __instance) - { - Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); - TextMeshProUGUI introduceText = introduceTransform.GetComponent(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - introduceText.text = StringStore.TranslateText(introduceText.text); - introduceText.font = fontAsset; - } - }*/ -} diff --git a/MelonLoader/Patches/GameObjects/SpriteRenderer_Patch.cs b/MelonLoader/Patches/GameObjects/SpriteRenderer_Patch.cs deleted file mode 100644 index 744fa5b..0000000 --- a/MelonLoader/Patches/GameObjects/SpriteRenderer_Patch.cs +++ /dev/null @@ -1,25 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(SpriteRenderer))] - public static class SpriteRenderer_Patch - { - [HarmonyPatch(nameof(SpriteRenderer.InvokeSpriteChanged))] - [HarmonyPostfix] - private static void InvokeSpriteChanged(SpriteRenderer __instance) - { - if (__instance.sprite != null) - { - if (TextureStore.spriteDict.ContainsKey(__instance.sprite.name) && __instance.drawMode != SpriteDrawMode.Sliced) - { - __instance.drawMode = SpriteDrawMode.Sliced; - } - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/TowerOption_Patch.cs b/MelonLoader/Patches/GameObjects/TowerOption_Patch.cs deleted file mode 100644 index 1dcceda..0000000 --- a/MelonLoader/Patches/GameObjects/TowerOption_Patch.cs +++ /dev/null @@ -1,21 +0,0 @@ -//using HarmonyLib; -//using Il2Cpp; -//using Il2CppTMPro; -//using PvZ_Fusion_Translator.AssetStore; -//using UnityEngine; - -//namespace PvZ_Fusion_Translator.Patches.GameObjects -//{ -// [HarmonyPatch(typeof(TowerOption))] -// public static class TowerOption_Patch -// { -// [HarmonyPatch(nameof(TowerOption.Start))] -// [HarmonyPostfix] -// private static void Postfix_Start(TowerOption __instance) -// { -// //TextMeshProUGUI[] allTexts = __instance.GetComponentsInChildren(true); -// __instance.introduce.text = StringStore.TranslateText(__instance.introduce.text); -// __instance.introduce.font = FontStore.LoadTMPFont(Utils.Language.ToString()); -// } -// } -//}} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/TowerUpgradeMenu_Patch.cs b/MelonLoader/Patches/GameObjects/TowerUpgradeMenu_Patch.cs deleted file mode 100644 index 4b863b3..0000000 --- a/MelonLoader/Patches/GameObjects/TowerUpgradeMenu_Patch.cs +++ /dev/null @@ -1,40 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(TowerUpgradeMenu))] - public static class TowerUpgradeMenu_Patch - { - [HarmonyPatch(nameof(TowerUpgradeMenu.Awake))] - [HarmonyPostfix] - private static void Awake(TowerUpgradeMenu __instance) - { - __instance.des.text = StringStore.TranslateText(__instance.des.text); - __instance.des2.text = StringStore.TranslateText(__instance.des2.text); - - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - text.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } - - [HarmonyPatch(nameof(TowerUpgradeMenu.SetText))] - [HarmonyPostfix] - private static void SetText(TowerUpgradeMenu __instance) - { - __instance.des.text = StringStore.TranslateText(__instance.des.text); - __instance.des2.text = StringStore.TranslateText(__instance.des2.text); - - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - text.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/UIDifficulty_Patch.cs b/MelonLoader/Patches/GameObjects/UIDifficulty_Patch.cs deleted file mode 100644 index c7b6c5b..0000000 --- a/MelonLoader/Patches/GameObjects/UIDifficulty_Patch.cs +++ /dev/null @@ -1,21 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using MelonLoader; -using PvZ_Fusion_Translator.AssetStore; -using System.Text.RegularExpressions; - -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 (!Utils.CheckForUntranslatedText(__instance.t.text)) return; - __instance.t.text = StringStore.TranslateText(__instance.t.text); - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/GameObjects/UIZombieNum_Patch.cs b/MelonLoader/Patches/GameObjects/UIZombieNum_Patch.cs deleted file mode 100644 index 9401da2..0000000 --- a/MelonLoader/Patches/GameObjects/UIZombieNum_Patch.cs +++ /dev/null @@ -1,29 +0,0 @@ -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.TranslateText(__instance.t.text); - __instance.t.text = zombieText; - #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/MelonLoader/Patches/GameObjects/WarningMenu_Patch.cs b/MelonLoader/Patches/GameObjects/WarningMenu_Patch.cs deleted file mode 100644 index f3103ff..0000000 --- a/MelonLoader/Patches/GameObjects/WarningMenu_Patch.cs +++ /dev/null @@ -1,96 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using System.Text.RegularExpressions; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(WarningMenu))] - public static class WarningMenu_Patch - { - [HarmonyPatch(nameof(WarningMenu.Start))] - [HarmonyPostfix] - private static void Start(WarningMenu __instance) - { - TranslateInvestmentWarning(__instance); - } - - [HarmonyPatch(nameof(WarningMenu.EnableChallengeMode))] - [HarmonyPostfix] - private static void EnableChallengeMode(WarningMenu __instance) - { - TranslateInvestmentWarning(__instance); - } - - [HarmonyPatch(nameof(WarningMenu.Cancel))] - [HarmonyPostfix] - private static void Cancel(WarningMenu __instance) - { - TranslateInvestmentWarning(__instance); - } - - public static void TranslateInvestmentWarning(WarningMenu __instance) - { - Transform normalModeTransform = __instance.transform.Find("Normal"); - Transform challengeModeTransform = __instance.transform.Find("Challenge"); - - if (normalModeTransform != null) - { - TextMeshProUGUI text = normalModeTransform.Find("text").GetComponent(); - TextMeshProUGUI textShadow = normalModeTransform.Find("text (1)").GetComponent(); - - text.text = StringStore.translationString.ContainsKey("普通模式_IV") ? StringStore.TranslateText("普通模式_IV") : Utils.RemoveColorTags(StringStore.TranslateText(text.text)); - text.alignment = TextAlignmentOptions.Center; - text.autoSizeTextContainer = true; - textShadow.text = Utils.RemoveColorTags(text.text); - textShadow.alignment = TextAlignmentOptions.Center; - textShadow.autoSizeTextContainer = true; - } - - if (challengeModeTransform != null) - { - TextMeshProUGUI text = challengeModeTransform.Find("text").GetComponent(); - TextMeshProUGUI textShadow = challengeModeTransform.Find("text (1)").GetComponent(); - - text.text = StringStore.translationString.ContainsKey("诅咒模式_IV") ? StringStore.TranslateText("诅咒模式_IV") : Utils.RemoveColorTags(StringStore.TranslateText(text.text)); - text.alignment = TextAlignmentOptions.Center; - text.autoSizeTextContainer = true; - textShadow.text = Utils.RemoveColorTags(text.text); - textShadow.alignment = TextAlignmentOptions.Center; - textShadow.autoSizeTextContainer = true; - } - - if (__instance.tutor != null) - { - foreach (TextMeshProUGUI text in __instance.tutor.GetComponentsInChildren()) - { - if (text.gameObject.name == "text1") - { - text.text = StringStore.TranslateText(text.text); - if (text.transform.parent.Find("text").TryGetComponent(out TextMeshProUGUI textShadow)) - { - textShadow.text = Utils.RemoveColorTags(text.text); - } - } - } - } - - if (__instance.challenge != null) - { - foreach (TextMeshProUGUI text in __instance.challenge.GetComponentsInChildren()) - { - if (text.gameObject.name == "text1") - { - text.text = StringStore.TranslateText(text.text); - if (text.transform.parent.Find("text").TryGetComponent(out TextMeshProUGUI textShadow)) - { - textShadow.text = Utils.RemoveColorTags(text.text); - } - } - } - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/Managers/AbyssDevelopMenu_Patch.cs b/MelonLoader/Patches/Managers/AbyssDevelopMenu_Patch.cs deleted file mode 100644 index a0f32d7..0000000 --- a/MelonLoader/Patches/Managers/AbyssDevelopMenu_Patch.cs +++ /dev/null @@ -1,19 +0,0 @@ -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/MelonLoader/Patches/Managers/AbyssMenu2_Patch.cs b/MelonLoader/Patches/Managers/AbyssMenu2_Patch.cs deleted file mode 100644 index bbd5a58..0000000 --- a/MelonLoader/Patches/Managers/AbyssMenu2_Patch.cs +++ /dev/null @@ -1,74 +0,0 @@ -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/MelonLoader/Patches/Managers/AbyssMenu_Patch.cs b/MelonLoader/Patches/Managers/AbyssMenu_Patch.cs deleted file mode 100644 index aa48391..0000000 --- a/MelonLoader/Patches/Managers/AbyssMenu_Patch.cs +++ /dev/null @@ -1,26 +0,0 @@ -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/MelonLoader/Patches/Managers/AlmanacMgrZombie_Patch.cs b/MelonLoader/Patches/Managers/AlmanacMgrZombie_Patch.cs deleted file mode 100644 index a47e22c..0000000 --- a/MelonLoader/Patches/Managers/AlmanacMgrZombie_Patch.cs +++ /dev/null @@ -1,128 +0,0 @@ -/*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(AlmanacMgrZombie))] - public static partial class AlmanacMgrZombie_Patch - { - [HarmonyPatch(nameof(AlmanacMgrZombie.InitNameAndInfoFromJson))] - [HarmonyPostfix] - private static void 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"); - string moddedPath = Path.Combine(almanacDir, "ModdedZombiesTranslate.json"); - - if (!File.Exists(path)) - { - Log.LogError($"ZombieStringsTranslate.json file not found at path: {path}"); - return; - } - -#if OBFUSCATE - if (CheckSumStore.IsModified(path)) - { - Log.LogError("File {0} was modified!", path); - return; - } -#endif - - string json; - json = File.ReadAllText(path); - - bool hasAlmanacFont = false; - TMP_FontAsset almanacFontAsset = null; - if (FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage + "_Almanac") || FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage)) - { - almanacFontAsset = FontStore.LoadTMPFontAlmanac(currentLanguage); - hasAlmanacFont = true; - } - -#if MULTI_LANGUAGE - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); -#else - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(); -#endif - - TextMeshPro component = __instance.info.GetComponent(); - TextMeshPro component2 = __instance.zombieName.GetComponent(); - TextMeshPro component3 = __instance.zombieName.transform.GetChild(0).GetComponent(); - - ZombieAlmanacData zombieData = JsonUtility.FromJson(json); - - foreach (ZombieInfo zombieInfo in zombieData.zombies) - { - if (zombieInfo.theZombieType == __instance.theZombieType) - { - component.text = zombieInfo.info + "\n\n" + zombieInfo.introduce; - component.overflowMode = TextOverflowModes.Page; - component2.text = zombieInfo.name; - component2.autoSizeTextContainer = true; - component3.text = Utils.RemoveColorTags(zombieInfo.name); - component3.autoSizeTextContainer = true; - - if (hasAlmanacFont) - component.font = almanacFontAsset; - else - component.font = fontAsset; - component2.font = fontAsset; - component3.font = fontAsset; - } - } - - if (File.Exists(moddedPath)) - { - string moddedJson; - moddedJson = File.ReadAllText(moddedPath); - - ZombieAlmanacData moddedZombieData = JsonUtility.FromJson(moddedJson); - - foreach (ZombieInfo zombieInfo in moddedZombieData.zombies) - { - if (zombieInfo.theZombieType == __instance.theZombieType) - { - component.text = zombieInfo.info + "\n\n" + zombieInfo.introduce; - component.overflowMode = TextOverflowModes.Page; - component2.text = zombieInfo.name; - component2.autoSizeTextContainer = true; - component3.text = Utils.RemoveColorTags(zombieInfo.name); - component3.autoSizeTextContainer = true; - - if (hasAlmanacFont) - component.font = almanacFontAsset; - else - component.font = fontAsset; - component2.font = fontAsset; - component3.font = fontAsset; - } - } - } - - return; - } - - [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; - } - } -}*/ \ No newline at end of file diff --git a/MelonLoader/Patches/Managers/AlmanacPlantBank_Patch.cs b/MelonLoader/Patches/Managers/AlmanacPlantBank_Patch.cs deleted file mode 100644 index 236fc5c..0000000 --- a/MelonLoader/Patches/Managers/AlmanacPlantBank_Patch.cs +++ /dev/null @@ -1,200 +0,0 @@ -/*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))] - [HarmonyPostfix] - private static void 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"); - string moddedPath = Path.Combine(almanacDir, "ModdedPlantsTranslate.json"); - - if (!File.Exists(path)) - { - Log.LogError($"LawnStringsTranslate.json file not found at path: {path}"); - return; - } - -#if OBFUSCATE - if (CheckSumStore.IsModified(path)) - { - Log.LogError("File {0} was modified!", path); - return; - } -#endif - - string json; - json = File.ReadAllText(path); - - bool hasAlmanacFont = false; - TMP_FontAsset almanacFontAsset = null; - if (FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage + "_Almanac") || FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage)) - { - almanacFontAsset = FontStore.LoadTMPFontAlmanac(currentLanguage); - hasAlmanacFont = true; - } - -#if MULTI_LANGUAGE - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(currentLanguage); -#else - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(); -#endif - - TextMeshPro component = __instance.introduce.GetComponent(); - TextMeshPro component2 = __instance.plantName.GetComponent(); - TextMeshPro component3 = __instance.plantName.transform.GetChild(0).GetComponent(); - TextMeshPro component4 = __instance.cost.GetComponent(); - - AlmanacPlantBank.PlantData plantData = JsonUtility.FromJson(json); - - foreach (AlmanacPlantBank.PlantInfo plantInfo in plantData.plants) - { - if (plantInfo.seedType == __instance.theSeedType && !string.IsNullOrEmpty(plantInfo.name)) - { - component.autoSizeTextContainer = false; - component.text = plantInfo.info + "\n\n" + plantInfo.introduce; - component.overflowMode = TextOverflowModes.Page; - - // fix dimensions for cost text - component.rectTransform.offsetMax = new Vector2(component.rectTransform.offsetMax.x, 27.3839f); - component.rectTransform.offsetMin = new Vector2(component.rectTransform.offsetMin.x, -29.3079f); - component.rectTransform.sizeDelta = new Vector2(component.rectTransform.sizeDelta.x, 50.917f); - component.transform.localPosition = new Vector3(component.transform.localPosition.x, component.transform.localPosition.y + 0.15f, component.transform.localPosition.z); - - - component2.text = plantInfo.name; - component2.autoSizeTextContainer = true; - - component3.text = Utils.RemoveColorTags(plantInfo.name ?? string.Empty); - component3.autoSizeTextContainer = true; - - component4.text = plantInfo.cost; - - if (hasAlmanacFont) - { - component.font = almanacFontAsset; - component4.font = almanacFontAsset; - } - else - { - component.font = fontAsset; - component4.font = fontAsset; - } - component2.font = fontAsset; - component3.font = fontAsset; - } - } - - if (File.Exists(moddedPath)) - { - string moddedJson; - moddedJson = File.ReadAllText(moddedPath); - - AlmanacPlantBank.PlantData moddedPlantData = JsonUtility.FromJson(moddedJson); - - foreach (AlmanacPlantBank.PlantInfo plantInfo in moddedPlantData.plants) - { - if (plantInfo.seedType == __instance.theSeedType && !string.IsNullOrEmpty(plantInfo.name)) - { - component.autoSizeTextContainer = false; - component.text = plantInfo.info + "\n\n" + plantInfo.introduce; - component.overflowMode = TextOverflowModes.Page; - - // fix dimensions for cost text - component.rectTransform.offsetMax = new Vector2(component.rectTransform.offsetMax.x, 27.3839f); - component.rectTransform.offsetMin = new Vector2(component.rectTransform.offsetMin.x, -29.3079f); - component.rectTransform.sizeDelta = new Vector2(component.rectTransform.sizeDelta.x, 50.917f); - component.transform.localPosition = new Vector3(component.transform.localPosition.x, component.transform.localPosition.y + 0.15f, component.transform.localPosition.z); - - - component2.text = plantInfo.name; - component2.autoSizeTextContainer = true; - - component3.text = Utils.RemoveColorTags(plantInfo.name ?? string.Empty); - 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; - } - - [HarmonyPatch(nameof(AlmanacPlantBank.OnMouseDown))] - [HarmonyPrefix] - private static bool OnMouseDown(AlmanacPlantBank __instance) - { - TextMeshPro component = __instance.introduce.GetComponent(); - if (component != null) - { - component.pageToDisplay = component.pageToDisplay > component.m_pageNumber ? 1 : component.pageToDisplay + 1; - return false; - } - return true; - } - - [HarmonyPatch(nameof(AlmanacPlantBank.PVPInit))] - [HarmonyPostfix] - private static void PVPInit(Il2Cpp.AlmanacPlantBank __instance) - { - TextMeshPro component = __instance.introduce.GetComponent(); - if (component != null) - { - component.autoSizeTextContainer = false; - } - - Transform banTransform = __instance.transform.FindChild("Ban").GetChild(0); - if (banTransform != null) - { - banTransform.GetComponent().text = StringStore.TranslateText(banTransform.GetComponent().text); - } - } - - [HarmonyPatch(nameof(AlmanacPlantBank.Start))] - [HarmonyPostfix] - public static void Post_Start(AlmanacPlantBank __instance) - { - GameObject skinTextObj = __instance.skinButton.transform.GetChild(0).gameObject; - GameObject skinShadowTextObj = UnityEngine.Object.Instantiate(skinTextObj, parent: __instance.skinButton.transform); - TextMeshPro skinShadowText = skinShadowTextObj.GetComponent(); - skinShadowText.text = StringStore.TranslateText("换肤_S"); - skinShadowText.sortingOrder -= 2; - skinShadowTextObj.transform.Translate(new Vector3(0.015f, -0.015f, 0)); - skinTextObj.transform.Translate(new Vector3(-0.022f, 0)); - skinShadowTextObj.transform.Translate(new Vector3(-0.022f, 0)); - __instance.skinButton.transform.localScale /= 1.75f; - __instance.skinButton.transform.Translate(new Vector3(-0.075f, -0.15f, 0)); - __instance.skinButton.transform.GetChild(1).Translate(new Vector3(0.35f, 0)); - __instance.skinButton.transform.GetChild(2).Translate(new Vector3(-0.35f, 0)); - } - } -}*/ \ No newline at end of file diff --git a/MelonLoader/Patches/Managers/CanvasUpUI_Patch.cs b/MelonLoader/Patches/Managers/CanvasUpUI_Patch.cs deleted file mode 100644 index 6efb242..0000000 --- a/MelonLoader/Patches/Managers/CanvasUpUI_Patch.cs +++ /dev/null @@ -1,31 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using System.Text.RegularExpressions; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Managers -{ - [HarmonyPatch(typeof(CanvasUpUI))] - public static class CanvasUpUI_Patch - { - [HarmonyPatch(nameof(CanvasUpUI.Start))] - [HarmonyPostfix] - public static void Start(CanvasUpUI __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach(TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - string originalKey = StringStore.translationString.FirstOrDefault(x => (x.Value == text.text || x.Value.Replace("\n", "") == text.text)).Key; - text.text = (StringStore.translationString.ContainsKey(originalKey + "_MG")) ? StringStore.TranslateText(originalKey + "_MG") : StringStore.TranslateText(text.text); - if(text.gameObject.name.Contains("LevelName")) - { - text.text = text.text.Replace("\n", " "); - } - text.font = fontAsset; - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/Managers/ChessManager_Patch.cs b/MelonLoader/Patches/Managers/ChessManager_Patch.cs deleted file mode 100644 index 8ff4841..0000000 --- a/MelonLoader/Patches/Managers/ChessManager_Patch.cs +++ /dev/null @@ -1,38 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using UnityEngine.TextCore.Text; -using UnityEngine.UI; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(ChessManager))] - public static class ChessManager_Patch - { - [HarmonyPatch(nameof(ChessManager.Start))] - [HarmonyPostfix] - private static void Postfix_Start(ChessManager __instance) - { - __instance.textMesh.text = StringStore.TranslateText(__instance.textMesh.text); - __instance.textMesh.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - - [HarmonyPatch(nameof(ChessManager.Update))] - [HarmonyPostfix] - private static void Postfix_Update(ChessManager __instance) - { - __instance.textMesh.text = StringStore.TranslateText(__instance.textMesh.text); - __instance.textMesh.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - - [HarmonyPatch(nameof(ChessManager.UpdateText))] - [HarmonyPostfix] - private static void Postfix_UpdateText(ChessManager __instance) - { - __instance.textMesh.text = StringStore.TranslateText(__instance.textMesh.text); - __instance.textMesh.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } -} diff --git a/MelonLoader/Patches/Managers/CustomLevelShower_Patch.cs b/MelonLoader/Patches/Managers/CustomLevelShower_Patch.cs deleted file mode 100644 index 8ed0487..0000000 --- a/MelonLoader/Patches/Managers/CustomLevelShower_Patch.cs +++ /dev/null @@ -1,23 +0,0 @@ -#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/MelonLoader/Patches/Managers/DifficultyMgr_Patch.cs b/MelonLoader/Patches/Managers/DifficultyMgr_Patch.cs deleted file mode 100644 index 3d05ff1..0000000 --- a/MelonLoader/Patches/Managers/DifficultyMgr_Patch.cs +++ /dev/null @@ -1,19 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -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/MelonLoader/Patches/Managers/DrawCardManager_Patch.cs b/MelonLoader/Patches/Managers/DrawCardManager_Patch.cs deleted file mode 100644 index 0db3ecf..0000000 --- a/MelonLoader/Patches/Managers/DrawCardManager_Patch.cs +++ /dev/null @@ -1,78 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using PvZ_Fusion_Translator.Patches.BaseTextObjects; -using System.Text.RegularExpressions; -using UnityEngine; -using UnityEngine.TextCore.Text; -using static MelonLoader.MelonLogger; - -namespace PvZ_Fusion_Translator.Patches.GameObjects -{ - [HarmonyPatch(typeof(DrawCardManager))] - public static class DrawCardManager_Patch - { - public static TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - [HarmonyPatch(nameof(DrawCardManager.Awake))] - [HarmonyPostfix] - private static void Awake(DrawCardManager __instance) - { - fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - - [HarmonyPatch(nameof(DrawCardManager.UpdateText))] - [HarmonyPostfix] - private static void Postfix_UpdateText(DrawCardManager __instance) - { - KeyValuePair regexPair = new KeyValuePair("抽取次数:\n(\\d+)/(\\d+)\n当前up植物:\n([^\\s]+)\nup刷新倒计时:\n(\\d+)", "Draw Count:\n{0}/{1}\nCurrent Up:\n{2}\nNext Up in: \n{3}s"); - - foreach(TextMeshProUGUI txt in __instance.texts) - { - if(Regex.IsMatch(txt.text, regexPair.Key)) - { - txt.text = TranslateGashaponText(txt.text, regexPair.Key, regexPair.Value, __instance.up); - txt.font = fontAsset; - } - } - } - - public static string TranslateGashaponText(string originalText, string pattern, string fallback, PlantType up) - { - string res = ""; - string fStr = ""; - Match match = Regex.Match(originalText, pattern); - if(match.Success) - { - GroupCollection groups = match.Groups; - fStr = StringStore.translationStringRegex.ContainsKey(pattern) ? StringStore.translationStringRegex[pattern] : fallback; - List dynamicParts = []; - for(int i = 1; i < groups.Count; i++) - { - string group = groups[i].Value; - string translatedGroup = ""; - if(i == 3 && up != PlantType.Peashooter) - { - translatedGroup = Utils.GetPlantNameFromAlmanac(up); - } - else - { - translatedGroup = StringStore.TranslateText(group); - } - dynamicParts.Add(translatedGroup); - } - res = string.Format(fStr, [.. dynamicParts]); - } - return res; - } - - /*[HarmonyPatch(nameof(DrawCardManager.Update))] - [HarmonyPostfix] - private static void Postfix_Update(DrawCardManager __instance) - { - Postfix_UpdateText(__instance); - }*/ - } -} - diff --git a/MelonLoader/Patches/Managers/EndlessMgr_Patch.cs b/MelonLoader/Patches/Managers/EndlessMgr_Patch.cs deleted file mode 100644 index de57cbf..0000000 --- a/MelonLoader/Patches/Managers/EndlessMgr_Patch.cs +++ /dev/null @@ -1,27 +0,0 @@ -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/MelonLoader/Patches/Managers/Garden_Patch.cs b/MelonLoader/Patches/Managers/Garden_Patch.cs deleted file mode 100644 index 698e2a5..0000000 --- a/MelonLoader/Patches/Managers/Garden_Patch.cs +++ /dev/null @@ -1,22 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; - -namespace PvZ_Fusion_Translator.Patches.Managers -{ - [HarmonyPatch(typeof(Garden))] - public static class Garden_Patch - { - [HarmonyPatch(nameof(Garden.Awake))] - [HarmonyPostfix] - private static void Awake(Garden __instance) - { - foreach (TextMeshPro text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - text.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } - } -} diff --git a/MelonLoader/Patches/Managers/IZBottomMenu_Patch.cs b/MelonLoader/Patches/Managers/IZBottomMenu_Patch.cs deleted file mode 100644 index 8630912..0000000 --- a/MelonLoader/Patches/Managers/IZBottomMenu_Patch.cs +++ /dev/null @@ -1,52 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using System.Text.RegularExpressions; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Managers -{ - [HarmonyPatch(typeof(IZBottomMenu))] - public static class IZBottomMenu_Patch - { - [HarmonyPatch(nameof(IZBottomMenu.ChangeString))] - [HarmonyPostfix] - public static void ChangeStringz(IZBottomMenu __instance) - { - foreach(TextMeshProUGUI text in __instance.levelName) - { - string fStr = StringStore.translationStringRegex["([^\\s]+),推荐难度:(\\d+)"]; - string[] parts = text.text.Split(",推荐难度:"); - - if(new Regex("([^\\s]+),推荐难度:(\\d+)").IsMatch(text.text)) - { - string customName = (StringStore.translationString.ContainsKey(parts[0] + "_IZ")) ? parts[0] + "_IZ" : parts[0]; - text.text = string.Format(fStr, StringStore.TranslateText(customName), parts[1]); - } - - text.text = StringStore.TranslateText(text.text); - text.text = text.text.Replace("\n", " "); - } - } - - [HarmonyPatch(nameof(IZBottomMenu.SetLevelName))] - [HarmonyPostfix] - public static void SetLevelName(IZBottomMenu __instance) - { - foreach(TextMeshProUGUI text in __instance.levelName) - { - string fStr = StringStore.translationStringRegex["([^\\s]+),推荐难度:(\\d+)"]; - string[] parts = text.text.Split(",推荐难度:"); - - if (new Regex("([^\\s]+),推荐难度:(\\d+)").IsMatch(text.text)) - { - text.text = string.Format(fStr, StringStore.TranslateText(parts[0]), parts[1]); - } - - text.text = StringStore.TranslateText(text.text); - text.text = text.text.Replace("\n", " "); - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/Managers/InGameUI_Patch.cs b/MelonLoader/Patches/Managers/InGameUI_Patch.cs deleted file mode 100644 index b9878bc..0000000 --- a/MelonLoader/Patches/Managers/InGameUI_Patch.cs +++ /dev/null @@ -1,87 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator; -using PvZ_Fusion_Translator.AssetStore; -using PvZ_Fusion_Translator.Patches.BaseTextObjects; -using System.Text.RegularExpressions; -using Unity.Collections; - -namespace PvZ_Fusion_Translator.Patches.Managers -{ - [HarmonyPatch(typeof(InGameUI))] - public static class InGameUI_Patch - { - public static string travelAdventurePattern = "^旅行冒险 ([^\\s:]+)"; - public static string travelAdventureFallback = "Odyssey Adventure: {0}"; - - [HarmonyPatch(nameof(InGameUI.Start))] - [HarmonyPostfix] - private static void Start(InGameUI __instance) - { - SetLevelName(__instance); - } - - [HarmonyPatch(nameof(InGameUI.SetUniqueText))] - [HarmonyPostfix] - private static void SetUniqueText(InGameUI __instance) - { - SetLevelName(__instance); - } - - [HarmonyPatch(nameof(InGameUI.SetLevelName))] - [HarmonyPostfix] - private static void SetLevelName(InGameUI __instance) - { - foreach (TextMeshProUGUI text in __instance.levelNameText) - { - if (text.text == null) continue; - - string originalText = text.text; - text.text = text.text.Replace("\n", " "); - - Regex checkFusionChallenge = new Regex("^超级([^\\s:]+)(:?挑战1?)"); - Regex checkTravelAdv = new Regex(travelAdventurePattern); - - if(checkTravelAdv.IsMatch(originalText)) - { - text.text = InGameText_Patch.TranslatePlantNameParts(originalText, travelAdventurePattern, travelAdventureFallback); - } - else if (text.text.Contains("配方:") && !checkFusionChallenge.IsMatch(text.text)) - { - string[] lines = text.text.Split(":"); - lines[1] = Utils.GetPlantNameFromAlmanac(lines[1]); - if (lines[1] == "") - { - Log.LogError("Couldn't find plant! (Fusion Showcase)"); - lines[1] = StringStore.TranslateText(lines[1]); - } - text.text = StringStore.TranslateText("配方:") + lines[1]; - text.autoSizeTextContainer = true; - } - else - { - text.text = (StringStore.translationString.ContainsKey(text.text + "_MG")) ? StringStore.TranslateText(text.text + "_MG") : StringStore.TranslateText(text.text); - text.text = text.text.Replace("\n", " "); - } - } - } - - /*[HarmonyPatch(nameof(InGameUI.Update))] - [HarmonyPostfix] - private static void Update(InGameUI __instance) - { - if (!__instance.board.boardTag.isDrawCards) return; - - KeyValuePair regexPair = new KeyValuePair("抽取次数:\n(\\d+)/(\\d+)\n当前up植物:\n([^\\s]+)\nup刷新倒计时:\n(\\d+)", "Draw Count:\n{0}/{1}\nCurrent Up:\n{2}\nNext Up in: \n{3}s"); - - foreach(TextMeshProUGUI txt in __instance.DrawCardsHead.GetComponentsInChildren()) - { - if(Regex.IsMatch(txt.text, regexPair.Key)) - { - txt.text = InGameText_Patch.TranslatePlantNameParts(txt.text, regexPair.Key, regexPair.Value); - } - } - }*/ - } -} diff --git a/MelonLoader/Patches/Managers/PVPScareyPot_Patch.cs b/MelonLoader/Patches/Managers/PVPScareyPot_Patch.cs deleted file mode 100644 index 3302de1..0000000 --- a/MelonLoader/Patches/Managers/PVPScareyPot_Patch.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Il2Cpp; -using UnityEngine; -using HarmonyLib; -using Il2CppPVPScaryPot; -using PvZ_Fusion_Translator.AssetStore; - -namespace PvZ_Fusion_Translator.Patches.Managers -{ - [HarmonyPatch(typeof(PVPScareyPot))] - public static class PVPScareyPot_Patch - { - [HarmonyPatch(nameof(PVPScareyPot.Awake))] - [HarmonyPatch(nameof(PVPScareyPot.Start))] - [HarmonyPatch(nameof(PVPScareyPot.AutoRuleUpdate))] - [HarmonyPatch(nameof(PVPScareyPot.RandomCardUpdate))] - [HarmonyPatch(nameof(PVPScareyPot.Update))] - [HarmonyPostfix] - public static void TranslatePlayerDatas(PVPScareyPot __instance) - { - TranslatePlayerData(__instance.player1); - TranslatePlayerData(__instance.player2); - TranslatePlayerData(__instance.currentPlayer); - } - - public static void TranslatePlayerData(PVPScareyPot.PlayerData playerData) - { - if(playerData != null) - { - playerData.textMesh.text = StringStore.TranslateText(playerData.textMesh.text); - playerData.textMesh.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - } - } -} diff --git a/MelonLoader/Patches/Managers/SaveMenu_Patch.cs b/MelonLoader/Patches/Managers/SaveMenu_Patch.cs deleted file mode 100644 index 0f5ae09..0000000 --- a/MelonLoader/Patches/Managers/SaveMenu_Patch.cs +++ /dev/null @@ -1,37 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Managers -{ - [HarmonyPatch(typeof(SaveMenu))] - public static class SaveMenu_Patch - { - [HarmonyPatch(nameof(SaveMenu.Start))] - [HarmonyPatch(nameof(SaveMenu.CreateLevelEnter))] - [HarmonyPatch(nameof(SaveMenu.InitLevelSaveEnters))] - [HarmonyPostfix] - private static void Start(SaveMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - __instance.menuTitle.text = StringStore.TranslateText(__instance.menuTitle.text); - __instance.menuTitle.font = fontAsset; - - foreach(LevelSaveEnter enter in __instance.GetComponentsInChildren()) - { - LevelSaveEnter_Patch.TranslateEnter(enter); - } - } - - [HarmonyPatch(nameof(SaveMenu.OnEditSelectedButtonClicked))] - [HarmonyPostfix] - private static void OnEditSelectedButtonClicked(SaveMenu __instance) - { - - } - } -} diff --git a/MelonLoader/Patches/Managers/Screen_Patch.cs b/MelonLoader/Patches/Managers/Screen_Patch.cs deleted file mode 100644 index da7c0ed..0000000 --- a/MelonLoader/Patches/Managers/Screen_Patch.cs +++ /dev/null @@ -1,28 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using UnityEngine.EventSystems; -using UnityEngine.UI; - -namespace PvZ_Fusion_Translator.Patches.Managers -{ - [HarmonyPatch(typeof(Screen))] - public static class Screen_Patch - { - [HarmonyPatch(nameof(Screen.SetResolution), argumentTypes: [typeof(int), typeof(int), typeof(bool)])] - [HarmonyPrefix] - private static bool SetResolution(Screen __instance) - { - if(EventSystem.current.currentSelectedGameObject != null) - { - if (EventSystem.current.currentSelectedGameObject.TryGetComponent(out TMP_InputField field)) - { - return false; - } - } - return true; - } - } -} diff --git a/MelonLoader/Patches/Managers/TowerManager_Patch.cs b/MelonLoader/Patches/Managers/TowerManager_Patch.cs deleted file mode 100644 index 3088e45..0000000 --- a/MelonLoader/Patches/Managers/TowerManager_Patch.cs +++ /dev/null @@ -1,28 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Managers -{ - [HarmonyPatch(typeof(TowerManager))] - public static class TowerManager_Patch - { - public static List updatedText = []; - - public static void UpdateText() - { - foreach (Transform transform in updatedText) - { - if (transform != null) - { - if(transform.gameObject.active) - { - transform.GetComponent().text = StringStore.TranslateText(transform.GetComponent().text); - } - } - } - } - } -} diff --git a/MelonLoader/Patches/Managers/UIMgr_Patch.cs b/MelonLoader/Patches/Managers/UIMgr_Patch.cs deleted file mode 100644 index e3e1bad..0000000 --- a/MelonLoader/Patches/Managers/UIMgr_Patch.cs +++ /dev/null @@ -1,19 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Managers -{ - [HarmonyPatch(typeof(UIMgr))] - public class UIMgr_Patch - { - [HarmonyPatch(nameof(UIMgr.EnterLoseMenu))] - [HarmonyPostfix] - private static void EnterLoseMenu(UIMgr __instance) - { - LoseMenu loseMenu = GameObject.FindObjectOfType(); - loseMenu.title.text = StringStore.TranslateText(loseMenu.title.text); - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/Modes/Abyss/AbyssBagMenu_Patch.cs b/MelonLoader/Patches/Modes/Abyss/AbyssBagMenu_Patch.cs deleted file mode 100644 index a226fe5..0000000 --- a/MelonLoader/Patches/Modes/Abyss/AbyssBagMenu_Patch.cs +++ /dev/null @@ -1,30 +0,0 @@ -//using HarmonyLib; -//using Il2Cpp; -//using Il2CppTMPro; -//using MelonLoader; -//using PvZ_Fusion_Translator.AssetStore; -//using UnityEngine; -//using UnityEngine.TextCore.Text; -//using UnityEngine.UI; -//using static MelonLoader.MelonLogger; - -//namespace PvZ_Fusion_Translator.Patches.GameObjects -//{ - -// [HarmonyPatch(typeof(AbyssBagMenu))] -// public static class AbyssBagMenu_Patch -// { -// [HarmonyPatch(nameof(AbyssBagMenu.Awake))] -// [HarmonyPostfix] -// private static void Awake_Post(AbyssCheckInBag __instance) -// { -// foreach(TextMeshProUGUI text in __instance.transform.FindChild("Background").GetComponentsInChildren()) -// { -// text.text = text.text + "_深渊"; -// text.text = StringStore.TranslateText("背包_深渊"); -// text.font = FontStore.LoadTMPFont(Utils.Language.ToString()); -// } -// AbyssMenu2.Instance.UpdateIcons(); -// } -// } -//} diff --git a/MelonLoader/Patches/Modes/Abyss/AbyssBuffButton_Patch.cs b/MelonLoader/Patches/Modes/Abyss/AbyssBuffButton_Patch.cs deleted file mode 100644 index f83d585..0000000 --- a/MelonLoader/Patches/Modes/Abyss/AbyssBuffButton_Patch.cs +++ /dev/null @@ -1,54 +0,0 @@ -#if FIX -using System.Text.RegularExpressions; -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using MelonLoader; - -namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects -{ - [HarmonyPatch(typeof(AbyssBuffButton))] - public static class AbyssBuffButton_Patch - { - [HarmonyPatch(nameof(AbyssBuffButton.SetType))] - [HarmonyPostfix] - private static void SetType(AbyssBuffButton __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - Regex regex = new Regex("([^\\s]+)\n价格:(\\d+)"); - - if (regex.IsMatch(__instance.description.text)) - { - Match match = regex.Match(__instance.description.text); - int groupCount = match.Groups.Count; - - List dynamicParts = []; - - for (int i = 1; i < groupCount; i++) - { - string groupValue = match.Groups[i].Value; - string translatedValue = StringStore.translationString.ContainsKey(groupValue) ? StringStore.translationString[groupValue] : groupValue; - dynamicParts.Add(translatedValue); - MelonLogger.Msg(translatedValue); - } - - __instance.description.text = string.Format(StringStore.translationStringRegex["([^\\s]+)\n价格:(\\d+)"], [.. dynamicParts]); - __instance.description.font = fontAsset; - } - } - - [HarmonyPatch(nameof(AbyssBuffButton.SetSold))] - [HarmonyPostfix] - private static void SetSold(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/MelonLoader/Patches/Modes/Abyss/AbyssBuffData_Patch.cs b/MelonLoader/Patches/Modes/Abyss/AbyssBuffData_Patch.cs deleted file mode 100644 index 0858150..0000000 --- a/MelonLoader/Patches/Modes/Abyss/AbyssBuffData_Patch.cs +++ /dev/null @@ -1,125 +0,0 @@ -//using HarmonyLib; -//using Il2Cpp; -//using MelonLoader; -//using System; -//using System.Collections.Generic; -//using System.Linq; -//using System.Text; -//using System.Text.Json; -//using System.Threading.Tasks; -//using Unity.VisualScripting; -//using UnityEngine; - -//namespace PvZ_Fusion_Translator.Patches.Managers -//{ -// [HarmonyPatch(typeof(AbyssBuffData))] -// public static class AbyssBuffData_Patch -// { -// [HarmonyPatch(nameof(AbyssBuffData.LoadData))] -// [HarmonyPostfix] -// public static void Pre_LoadData(AbyssBuffData __instance) -// { -// string originalAbyssBuffStr = Resources.Load("AbyssBuffData").text; -// Dictionary> originalAbyssBuffData = JsonSerializer.Deserialize>>(originalAbyssBuffStr); -// List infos = originalAbyssBuffData["infos"]; -// Il2CppSystem.Collections.Generic.Dictionary> result = new(); - -// string abyssBuffDataDir = Path.Combine(FileLoader.GetAssetDir(FileLoader.AssetType.Strings, Utils.Language), "abyss_buffs.json"); -// if (!File.Exists(abyssBuffDataDir)) -// { -// File.WriteAllText(abyssBuffDataDir, originalAbyssBuffStr); -// } - -// Dictionary abyssBuffData = JsonSerializer.Deserialize>(File.ReadAllText(abyssBuffDataDir)); - -// for (int i = 0; i < infos.Count; i++) -// { -// AbyssBuffInfo originalTuple = infos[i]; -// Il2CppSystem.ValueTuple translatedTuple = new(); - -// translatedTuple.Item1 = abyssBuffData.ContainsKey(originalTuple.name) ? abyssBuffData[originalTuple.name] : originalTuple.name; -// translatedTuple.Item2 = abyssBuffData.ContainsKey(originalTuple.introduce) ? abyssBuffData[originalTuple.introduce] : originalTuple.introduce; -// translatedTuple.Item3 = originalTuple.value; - -// foreach (var x in AbyssBuffData.buffDatas) -// { -// if (x.Value.Item1 == originalTuple.name) -// { -// AbyssBuffData.buffDatas[x.Key] = translatedTuple; -// break; -// } -// } -// } -// } -// } - -// public enum AbyssBuffClone -// { -// 生存_聚塑, -// 生存_启命, -// 生存_坚定, -// 生存_弥合, -// 生存_警戒, -// 生存_霸体, -// 生存_共存, -// 生存_护盾, -// 生存_治疗, -// 生存_主宰, -// 寒冰_聚塑, -// 寒冰_刺骨, -// 寒冰_凛风, -// 寒冰_冻结, -// 寒冰_保护, -// 寒冰_折磨, -// 寒冰_扩散, -// 寒冰_凝神, -// 寒冰_破冰, -// 寒冰_永冻, -// 魅惑_聚塑, -// 魅惑_感应, -// 魅惑_催眠, -// 魅惑_无畏, -// 魅惑_脆弱, -// 魅惑_黑曜, -// 魅惑_转世, -// 魅惑_支援, -// 魅惑_沉重, -// 魅惑_共鸣, -// 烈焰_聚塑, -// 烈焰_爆破, -// 烈焰_怒火, -// 烈焰_红唇, -// 烈焰_融化, -// 烈焰_燃烧, -// 烈焰_浴火, -// 烈焰_鬼火, -// 烈焰_诅咒, -// 烈焰_太阳, -// 通用_断水, -// 通用_千斤, -// 通用_急迫, -// 通用_折扣, -// 通用_密植, -// 通用_超级, -// 通用_究极, -// 通用_极速, -// 通用_强力, -// 通用_专注, -// 通用_迸发, -// 通用_投资, -// 通用_机遇, -// 通用_命运, -// 通用_时停, -// 通用_升级, -// 蒜毒_聚塑, -// 蒜毒_腐蚀, -// 蒜毒_侵蚀, -// 蒜毒_血清, -// 蒜毒_混乱, -// 蒜毒_虚弱, -// 蒜毒_反胃, -// 蒜毒_虫噬, -// 蒜毒_百毒, -// 蒜毒_爆裂 -// } -//} \ No newline at end of file diff --git a/MelonLoader/Patches/Modes/Abyss/AbyssBuffMenu_Patch.cs b/MelonLoader/Patches/Modes/Abyss/AbyssBuffMenu_Patch.cs deleted file mode 100644 index 9353590..0000000 --- a/MelonLoader/Patches/Modes/Abyss/AbyssBuffMenu_Patch.cs +++ /dev/null @@ -1,133 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using MelonLoader.TinyJSON; -using PvZ_Fusion_Translator.AssetStore; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Text.Json; -using System.Text.RegularExpressions; -using UnityEngine.TextCore.Text; -using static PvZ_Fusion_Translator.FileLoader; - -namespace PvZ_Fusion_Translator.Patches.Modes.Abyss -{ - /*[HarmonyPatch(typeof(AbyssBuffMenu))] - public static class AbyssBuffMenu_Patch - { - public static Dictionary abyssBuffData = new Dictionary(); - - [HarmonyPatch(nameof(AbyssBuffMenu.Awake))] - [HarmonyPostfix] - public static void Post_Awake(AbyssBuffMenu __instance) - { - LoadAbyssBuffData(); - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - text.font = fontAsset; - } - - TranslateWindows(__instance, fontAsset); - } - - [HarmonyPatch(nameof(AbyssBuffMenu.SelectWindow))] - [HarmonyPostfix] - public static void Post_SelectWindow(AbyssBuffMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - TranslateWindows(__instance, fontAsset); - } - - [HarmonyPatch(nameof(AbyssBuffMenu.SetFavorite))] - [HarmonyPostfix] - public static void Post_SetFavorite(AbyssBuffMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - text.font = fontAsset; - } - } - - public static void TranslateWindows(AbyssBuffMenu __instance, TMP_FontAsset fontAsset) - { - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - if (abyssBuffData.ContainsKey(text.text)) - { - text.text = abyssBuffData[text.text]; - } - else - { - string translatedRegex = TranslateAbyssBuffRegex(text.text); - if (translatedRegex != null) - { - text.text = translatedRegex; - } - } - - text.font = fontAsset; - } - } - - public static void LoadAbyssBuffData() - { - abyssBuffData.Clear(); - - string abyssBuffText = "{}"; - - if(!Utils.useLocal) - { - string abyssBuffsContent = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Strings/abyss_buffs.json").Result; - - if(abyssBuffsContent != null) - { - abyssBuffText = abyssBuffsContent; - } - else - { - string abyssBuffsPath = Path.Combine(GetAssetDir(AssetType.Strings, Utils.Language), "abyss_buffs.json"); - if(File.Exists(abyssBuffsPath)) - { - abyssBuffText = File.ReadAllText(abyssBuffsPath); - } - } - } - else - { - abyssBuffText = File.ReadAllText(Path.Combine(FileLoader.GetAssetDir(FileLoader.AssetType.Strings, Utils.Language), "abyss_buffs.json")); - } - - abyssBuffData = JsonSerializer.Deserialize>(abyssBuffText); - } - - public static string TranslateAbyssBuffRegex(string originalText) - { - foreach (var x in abyssBuffData) - { - if (x.Key.Contains("{value}")) - { - string pattern = Regex.Escape(x.Key).Replace("\\{value}", "(\\d+)"); - if (Regex.IsMatch(originalText, pattern)) - { - var regex = new Regex(pattern); - var match = regex.Match(originalText); - - return string.Format(x.Value.Replace("value", "0"), match.Groups[1].Value); - } - } - } - - return null; - } - }*/ -} diff --git a/MelonLoader/Patches/Modes/Abyss/AbyssCheckInBag_Patch.cs b/MelonLoader/Patches/Modes/Abyss/AbyssCheckInBag_Patch.cs deleted file mode 100644 index 413a7a6..0000000 --- a/MelonLoader/Patches/Modes/Abyss/AbyssCheckInBag_Patch.cs +++ /dev/null @@ -1,31 +0,0 @@ -//using HarmonyLib; -//using Il2Cpp; -//using Il2CppTMPro; -//using MelonLoader; -//using PvZ_Fusion_Translator.AssetStore; -//using UnityEngine; -//using UnityEngine.TextCore.Text; -//using UnityEngine.UI; -//using static MelonLoader.MelonLogger; - -//namespace PvZ_Fusion_Translator.Patches.GameObjects -//{ - -// [HarmonyPatch(typeof(AbyssCheckInBag))] -// public static class AbyssCheckInBag_Patch -// { -// [HarmonyPatch(nameof(AbyssCheckInBag.MoveFromBag))] -// [HarmonyPostfix] -// private static void MoveFromBag(AbyssCheckInBag __instance) -// { -// AbyssMenu2.Instance.UpdateIcons(); -// } - -// [HarmonyPatch(nameof(AbyssCheckInBag.SellIcon))] -// [HarmonyPostfix] -// private static void SellIcon(AbyssCheckInBag __instance) -// { -// AbyssMenu2.Instance.UpdateIcons(); -// } -// } -//} diff --git a/MelonLoader/Patches/Modes/Abyss/AbyssCheckSellMenu_Patch.cs b/MelonLoader/Patches/Modes/Abyss/AbyssCheckSellMenu_Patch.cs deleted file mode 100644 index fede3de..0000000 --- a/MelonLoader/Patches/Modes/Abyss/AbyssCheckSellMenu_Patch.cs +++ /dev/null @@ -1,26 +0,0 @@ -//using HarmonyLib; -//using Il2Cpp; -//using Il2CppTMPro; -//using PvZ_Fusion_Translator.AssetStore; -//using UnityEngine; - -//namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects -//{ -// [HarmonyPatch(typeof(AbyssCheckSellMenu))] -// public static class AbyssCheckSellMenu_Patch -// { -// [HarmonyPatch(nameof(AbyssCheckSellMenu.SellIcon))] -// [HarmonyPostfix] -// private static void SellIcon(AbyssCheckSellMenu __instance) -// { -// AbyssMenu2.Instance.UpdateIcons(); -// } - -// [HarmonyPatch(nameof(AbyssCheckSellMenu.MoveInBag))] -// [HarmonyPostfix] -// private static void MoveInBag(AbyssCheckSellMenu __instance) -// { -// AbyssMenu2.Instance.UpdateIcons(); -// } -// } -//} \ No newline at end of file diff --git a/MelonLoader/Patches/Modes/Abyss/AbyssDevelopMenu_Patch.cs b/MelonLoader/Patches/Modes/Abyss/AbyssDevelopMenu_Patch.cs deleted file mode 100644 index 549f1e7..0000000 --- a/MelonLoader/Patches/Modes/Abyss/AbyssDevelopMenu_Patch.cs +++ /dev/null @@ -1,48 +0,0 @@ -//using System.Text.RegularExpressions; -//using HarmonyLib; -//using Il2Cpp; -//using Il2CppTMPro; -//using MelonLoader; -//using PvZ_Fusion_Translator.AssetStore; -//using UnityEngine.TextCore.Text; - -//namespace PvZ_Fusion_Translator.Patches.GameObjects -//{ -// [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); - -// TextMeshProUGUI upgradeCostText = __instance.transform.FindChild("UpgradeCost").GetComponent(); -// TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - -// string regexStr = "([^\\s]+)\n当前等级:([^\\s]+)\n\n升级条件:\n([^\\s]+)\n\n升级消耗:([^\\s]+)"; - -// Regex regex = new Regex(regexStr); - -// if (regex.IsMatch(upgradeCostText.text)) -// { -// Match match = regex.Match(upgradeCostText.text); -// int groupCount = match.Groups.Count; - -// List dynamicParts = []; - -// for (int i = 1; i < groupCount; i++) -// { -// string groupValue = match.Groups[i].Value; -// string translatedValue = StringStore.translationString.ContainsKey(groupValue) ? StringStore.translationString[groupValue] : groupValue; -// dynamicParts.Add(translatedValue); -// } - -// upgradeCostText.text = string.Format(StringStore.translationStringRegex[regexStr], [.. dynamicParts]); -// upgradeCostText.font = fontAsset; -// } -// } -// } -//} diff --git a/MelonLoader/Patches/Modes/Abyss/AbyssGoods_Patch.cs b/MelonLoader/Patches/Modes/Abyss/AbyssGoods_Patch.cs deleted file mode 100644 index 70a5b12..0000000 --- a/MelonLoader/Patches/Modes/Abyss/AbyssGoods_Patch.cs +++ /dev/null @@ -1,22 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Modes.Abyss -{ - /*[HarmonyPatch(typeof(AbyssGoods))] - public static class AbyssGoods_Patch - { - [HarmonyPostfix] - [HarmonyPatch(nameof(AbyssGoods.Start))] - private static void Start(AbyssGoods __instance) - { - __instance.costText.text = StringStore.TranslateText(__instance.costText.text, false); - __instance.costText_shadow.text = StringStore.TranslateText(__instance.costText_shadow.text, false); - __instance.hasText.text = StringStore.TranslateText(__instance.hasText.text, false); - __instance.hasText_shadow.text = StringStore.TranslateText(__instance.hasText_shadow.text, false); - } - }*/ -} diff --git a/MelonLoader/Patches/Modes/Abyss/AbyssInfo_Patch.cs b/MelonLoader/Patches/Modes/Abyss/AbyssInfo_Patch.cs deleted file mode 100644 index 1ac118d..0000000 --- a/MelonLoader/Patches/Modes/Abyss/AbyssInfo_Patch.cs +++ /dev/null @@ -1,12 +0,0 @@ -//using System; -//using System.Collections.Generic; -//using System.Linq; -//using System.Text; -//using System.Threading.Tasks; - -//namespace PvZ_Fusion_Translator.Patches.Managers -//{ -// public class AbyssInfo_Patch -// { -// } -//} diff --git a/MelonLoader/Patches/Modes/Abyss/AbyssLevelEnter_Patch.cs b/MelonLoader/Patches/Modes/Abyss/AbyssLevelEnter_Patch.cs deleted file mode 100644 index ab7e8d1..0000000 --- a/MelonLoader/Patches/Modes/Abyss/AbyssLevelEnter_Patch.cs +++ /dev/null @@ -1,19 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Modes.Abyss -{ - /*[HarmonyPatch(typeof(AbyssLevelEnter))] - public static class AbyssLevelEnter_Patch - { - [HarmonyPatch(nameof(AbyssLevelEnter.SetLevel))] - [HarmonyPostfix] - private static void SetLevel(AbyssLevelEnter __instance) - { - __instance.levelName = StringStore.TranslateText(__instance.levelName); - } - }*/ -} diff --git a/MelonLoader/Patches/Modes/Abyss/AbyssMenu2_Patch.cs b/MelonLoader/Patches/Modes/Abyss/AbyssMenu2_Patch.cs deleted file mode 100644 index 2749e73..0000000 --- a/MelonLoader/Patches/Modes/Abyss/AbyssMenu2_Patch.cs +++ /dev/null @@ -1,104 +0,0 @@ -//using HarmonyLib; -//using Il2Cpp; -//using Il2CppTMPro; -//using MelonLoader; -//using PvZ_Fusion_Translator.AssetStore; -//using UnityEngine; -//using UnityEngine.TextCore.Text; -//using UnityEngine.UI; -//using static MelonLoader.MelonLogger; - -//namespace PvZ_Fusion_Translator.Patches.GameObjects -//{ - -// [HarmonyPatch(typeof(AbyssMenu2))] -// public static class AbyssMenu2_Patch -// { -// private static void UpdateAbyss2Text(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); - -// Transform optionsTransform = __instance.transform.FindChild("Options").transform; -// foreach (AbyssBuffButton abyssBuffButton in optionsTransform.GetComponentsInChildren()) -// { -// foreach (TextMeshProUGUI textMesh in abyssBuffButton.GetComponentsInChildren()) -// { -// textMesh.text = StringStore.TranslateText(textMesh.text); -// } -// } - -// foreach(TextMeshProUGUI text in __instance.GetComponentsInChildren()) -// { -// text.text = StringStore.TranslateText(text.text); -// text.font = fontAsset; -// } -// } - -// [HarmonyPatch(nameof(AbyssMenu2.Start))] -// [HarmonyPostfix] -// private static void Start(AbyssMenu2 __instance) -// { -// UpdateAbyss2Text(__instance); - -// Utils.ConvertButtonText(__instance.transform, "Help"); - -// // custom bag text :D - -// __instance.transform.FindChild("Bag").FindChild("text").GetComponent().text += "_深渊"; - -// Utils.ConvertButtonText(__instance.transform, "Bag"); -// } - -// [HarmonyPatch(nameof(AbyssMenu2.UpdateIcons))] -// [HarmonyPostfix] -// private static void UpdateIcons(AbyssMenu2 __instance) -// { -// UpdateAbyss2Text(__instance); -// } - -// [HarmonyPatch(nameof(AbyssMenu2.UpdateBuff))] -// [HarmonyPostfix] -// private static void UpdateBuff(AbyssMenu2 __instance) -// { -// UpdateAbyss2Text(__instance); -// } - -// [HarmonyPatch(nameof(AbyssMenu2.BuyBuff))] -// [HarmonyPostfix] -// private static void BuyBuff(AbyssMenu2 __instance) -// { -// UpdateAbyss2Text(__instance); -// } - -// [HarmonyPatch(nameof(AbyssMenu2.ShowBag))] -// [HarmonyPostfix] -// private static void ShowBag(AbyssMenu2 __instance) -// { -// UpdateAbyss2Text(__instance); -// } -// } -//} diff --git a/MelonLoader/Patches/Modes/Abyss/AbyssMenu_Patch.cs b/MelonLoader/Patches/Modes/Abyss/AbyssMenu_Patch.cs deleted file mode 100644 index 93c1b32..0000000 --- a/MelonLoader/Patches/Modes/Abyss/AbyssMenu_Patch.cs +++ /dev/null @@ -1,49 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using MelonLoader; -using PvZ_Fusion_Translator.AssetStore; -using Unity.VisualScripting; -using UnityEngine; -using System.Text.RegularExpressions; -using UnityEngine.UI; -using MelonLoader.Utils; - -namespace PvZ_Fusion_Translator.Patches.Modes.Abyss -{ - /*[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, pattern: "第(\\d+)关\n场景:([^\\s]+)\n总波数:(\\d+)波\n特殊环境:([^\\s]+)\n难度:(\\d+)"); - txt.font = fontAsset; - } - - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - text.font = fontAsset; - } - } - - [HarmonyPatch(nameof(AbyssMenu.UpdateLevelInfo))] - [HarmonyPostfix] - private static void UpdateLevelInfo(AbyssMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.levelInfo) - { - txt.text = StringStore.TranslateText(txt.text, pattern: "第(\\d+)关\n场景:([^\\s]+)\n总波数:(\\d+)波\n特殊环境:([^\\s]+)\n难度:(\\d+)"); - txt.font = fontAsset; - } - } - }*/ -} diff --git a/MelonLoader/Patches/Modes/Abyss/AbyssSelectBuffWindow_Patch.cs b/MelonLoader/Patches/Modes/Abyss/AbyssSelectBuffWindow_Patch.cs deleted file mode 100644 index ee1c2d3..0000000 --- a/MelonLoader/Patches/Modes/Abyss/AbyssSelectBuffWindow_Patch.cs +++ /dev/null @@ -1,57 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using System.Text.RegularExpressions; - -namespace PvZ_Fusion_Translator.Patches.Modes.Abyss -{ - /*[HarmonyPatch(typeof(AbyssSelectBuffWindow))] - public static class AbyssSelectBuffWindow_Patch - { - [HarmonyPatch(nameof(AbyssSelectBuffWindow.OnAnimOver))] - [HarmonyPostfix] - private static void OnAnimOver(AbyssSelectBuffWindow __instance) - { - TranslateBuffWindow(__instance); - } - - [HarmonyPatch(nameof(AbyssSelectBuffWindow.SetBuff))] - [HarmonyPostfix] - private static void SetBuff(AbyssSelectBuffWindow __instance) - { - TranslateBuffWindow(__instance); - } - - public static void TranslateBuffWindow(AbyssSelectBuffWindow __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - AbyssBuffMenu_Patch.LoadAbyssBuffData(); - - foreach (TextMeshProUGUI titleText in __instance.titleText) - { - if (AbyssBuffMenu_Patch.abyssBuffData.ContainsKey(titleText.text)) - { - if(titleText.name.Contains("shadow")) - { - titleText.text = Utils.RemoveColorTags(AbyssBuffMenu_Patch.abyssBuffData[titleText.text]); - } - else - { - titleText.text = AbyssBuffMenu_Patch.abyssBuffData[titleText.text]; - } - } - titleText.font = fontAsset; - } - - string translatedIntroduceText = AbyssBuffMenu_Patch.abyssBuffData.ContainsKey(__instance.introduce.text) ? AbyssBuffMenu_Patch.abyssBuffData[__instance.introduce.text] : AbyssBuffMenu_Patch.TranslateAbyssBuffRegex(__instance.introduce.text); - - if (translatedIntroduceText != null) - { - __instance.introduce.text = translatedIntroduceText; - __instance.introduce.font = fontAsset; - } - } - }*/ -} diff --git a/MelonLoader/Patches/Modes/Abyss/AbyssSettlementMenu_Patch.cs b/MelonLoader/Patches/Modes/Abyss/AbyssSettlementMenu_Patch.cs deleted file mode 100644 index 3ed38cd..0000000 --- a/MelonLoader/Patches/Modes/Abyss/AbyssSettlementMenu_Patch.cs +++ /dev/null @@ -1,55 +0,0 @@ -//using HarmonyLib; -//using Il2Cpp; -//using Il2CppTMPro; -//using MelonLoader; -//using PvZ_Fusion_Translator.AssetStore; -//using Unity.VisualScripting; -//using UnityEngine; -//using System.Text.RegularExpressions; - -//namespace PvZ_Fusion_Translator.Patches.GameObjects -//{ -// [HarmonyPatch(typeof(AbyssSettlementMenu))] -// public static class AbyssSettlementMenu_Patch -// { - -// [HarmonyPatch(nameof(AbyssSettlementMenu.InitSettle))] -// [HarmonyPostfix] -// private static void InitSettle(AbyssSettlementMenu __instance) -// { -// TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - -// string[] regexStrList = [ -// "第(\\d+)关\n通关用时:(\\d+)分(\\d+)秒\n杀敌数量:(\\d+)\n关卡叶绿素产出:(\\d+)\n极限模式产出:(\\d+)\n非首胜无额外产出\n产出叶绿素总计:(\\d+)", -// "第(\\d+)关\n通关用时:(\\d+)分(\\d+)秒\n杀敌数量:(\\d+)\n关卡叶绿素产出:(\\d+)\n极限模式产出:(\\d+)\n首胜产出:(\\d+)\n剩余小推车数量:(\\d+),获得叶绿素:(\\d+)\n产出叶绿素总计:(\\d+)", -// "第(\\d+)关\n通关用时:(\\d+)分(\\d+)秒\n杀敌数量:(\\d+)\n关卡叶绿素产出:(\\d+)\n首胜产出:(\\d+)\n剩余小推车数量:(\\d+),获得叶绿素:(\\d+)\n产出叶绿素总计:(\\d+)", -// "第(\\d+)关\n通关用时:(\\d+)分(\\d+)秒\n杀敌数量:(\\d+)\n关卡叶绿素产出:(\\d+)\n困难模式产出:(\\d+)\n首胜产出:(\\d+)\n剩余小推车数量:(\\d+),获得叶绿素:(\\d+)\n产出叶绿素总计:(\\d+)", -// "第(\\d+)关\n通关用时:(\\d+)分(\\d+)秒\n杀敌数量:(\\d+)\n关卡叶绿素产出:(\\d+)\n非首胜无额外产出\n产出叶绿素总计:(\\d+)", -// "第(\\d+)关\n通关用时:(\\d+)分(\\d+)秒\n杀敌数量:(\\d+)\n关卡叶绿素产出:(\\d+)\n困难模式产出:(\\d+)\n非首胜无额外产出\n产出叶绿素总计:(\\d+)" -// ]; - -// foreach(string regexStr in regexStrList) -// { -// Regex regex = new Regex(regexStr); - -// if (regex.IsMatch(__instance.settleInfo.text)) -// { -// Match match = regex.Match(__instance.settleInfo.text); -// int groupCount = match.Groups.Count; - -// List dynamicParts = []; - -// for (int i = 1; i < groupCount; i++) -// { -// string groupValue = match.Groups[i].Value; -// string translatedValue = StringStore.translationString.ContainsKey(groupValue) ? StringStore.translationString[groupValue] : groupValue; -// dynamicParts.Add(translatedValue); -// } - -// __instance.settleInfo.text = string.Format(StringStore.translationStringRegex[regexStr], [.. dynamicParts]); -// __instance.settleInfo.font = fontAsset; -// } -// } -// } -// } -//} diff --git a/MelonLoader/Patches/Modes/Abyss/AbyssStoreMenu_Patch.cs b/MelonLoader/Patches/Modes/Abyss/AbyssStoreMenu_Patch.cs deleted file mode 100644 index 18946f0..0000000 --- a/MelonLoader/Patches/Modes/Abyss/AbyssStoreMenu_Patch.cs +++ /dev/null @@ -1,24 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; - -namespace PvZ_Fusion_Translator.Patches.Modes.Abyss -{ - /*[HarmonyPatch(typeof(AbyssStoreMenu))] - public static class AbyssStoreMenu_Patch - { - [HarmonyPatch(nameof(AbyssStoreMenu.Update))] - [HarmonyPostfix] - private static void Update(AbyssStoreMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach(TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - text.font = fontAsset; - } - } - }*/ -} diff --git a/MelonLoader/Patches/Modes/Harvest/GardenBagMenu_Patch.cs b/MelonLoader/Patches/Modes/Harvest/GardenBagMenu_Patch.cs deleted file mode 100644 index 958b0dc..0000000 --- a/MelonLoader/Patches/Modes/Harvest/GardenBagMenu_Patch.cs +++ /dev/null @@ -1,25 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Modes.Harvest -{ - [HarmonyPatch(typeof(GardenBagMenu))] - public static class GardenBagMenu_Patch - { - [HarmonyPatch(nameof(GardenBagMenu.Awake))] - [HarmonyPostfix] - private static void Awake(GardenBagMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - Transform closeButtonTransform = __instance.transform.Find("Close"); - foreach(TextMeshProUGUI text in closeButtonTransform.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText("合上"); - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/Modes/Harvest/GardenCard_Patch.cs b/MelonLoader/Patches/Modes/Harvest/GardenCard_Patch.cs deleted file mode 100644 index d1baac8..0000000 --- a/MelonLoader/Patches/Modes/Harvest/GardenCard_Patch.cs +++ /dev/null @@ -1,24 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using PvZ_Fusion_Translator.AssetStore; - -namespace PvZ_Fusion_Translator.Patches.Modes.Harvest -{ - [HarmonyPatch(typeof(GardenCard))] - public static class GardenCard_Patch - { - [HarmonyPatch(nameof(GardenCard.Start))] - [HarmonyPostfix] - private static void Start(GardenCard __instance) - { - __instance.text.text = StringStore.TranslateText(__instance.text.text).Replace("26", "16"); - } - - [HarmonyPatch(nameof(GardenCard.ChangeCardSprite))] - [HarmonyPostfix] - private static void ChangeCardSprite(GardenCard __instance) - { - __instance.text.text = StringStore.TranslateText(__instance.text.text).Replace("26", "16"); - } - } -} diff --git a/MelonLoader/Patches/Modes/Harvest/TreasureConfirmMenu_Patch.cs b/MelonLoader/Patches/Modes/Harvest/TreasureConfirmMenu_Patch.cs deleted file mode 100644 index 2f5c947..0000000 --- a/MelonLoader/Patches/Modes/Harvest/TreasureConfirmMenu_Patch.cs +++ /dev/null @@ -1,25 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Modes.Harvest -{ - [HarmonyPatch(typeof(TreasureConfirmMenu))] - public static class TreasureConfirmMenu_Patch - { - [HarmonyPatch(nameof(TreasureConfirmMenu.SetText))] - [HarmonyPostfix] - private static void SetText(TreasureConfirmMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/Modes/Harvest/TreasureEquipmentMenu_Patch.cs b/MelonLoader/Patches/Modes/Harvest/TreasureEquipmentMenu_Patch.cs deleted file mode 100644 index 1033f57..0000000 --- a/MelonLoader/Patches/Modes/Harvest/TreasureEquipmentMenu_Patch.cs +++ /dev/null @@ -1,38 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Modes.Harvest -{ - [HarmonyPatch(typeof(TreasureEquipmentMenu))] - public static class TreasureEquipmentMenu_Patch - { - [HarmonyPatch(nameof(TreasureEquipmentMenu.Awake))] - [HarmonyPostfix] - private static void Awake(TreasureEquipmentMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - - [HarmonyPatch(nameof(TreasureEquipmentMenu.UpdateCards))] - [HarmonyPostfix] - private static void UpdateCards(TreasureEquipmentMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/Modes/Harvest/TreasureEvacuateMenu_Patch.cs b/MelonLoader/Patches/Modes/Harvest/TreasureEvacuateMenu_Patch.cs deleted file mode 100644 index e133b8f..0000000 --- a/MelonLoader/Patches/Modes/Harvest/TreasureEvacuateMenu_Patch.cs +++ /dev/null @@ -1,30 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using UnityEngine.UI; - -namespace PvZ_Fusion_Translator.Patches.Modes.Harvest -{ - [HarmonyPatch(typeof(TreasureEvacuateMenu))] - public static class TreasureEvacuateMenu_Patch - { - [HarmonyPatch(nameof(TreasureEvacuateMenu.Start))] - [HarmonyPostfix] - private static void Start(TreasureEvacuateMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - if(txt.name.Contains("text (1)")) - { - txt.name = txt.name + "_EVACUATE"; - } - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/Modes/Harvest/TreasureMainMenu_Patch.cs b/MelonLoader/Patches/Modes/Harvest/TreasureMainMenu_Patch.cs deleted file mode 100644 index df5b950..0000000 --- a/MelonLoader/Patches/Modes/Harvest/TreasureMainMenu_Patch.cs +++ /dev/null @@ -1,25 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Modes.Harvest -{ - [HarmonyPatch(typeof(TreasureMainMenu))] - public static class TreasureMainMenu_Patch - { - [HarmonyPatch(nameof(TreasureMainMenu.Update))] - [HarmonyPostfix] - private static void Update(TreasureMainMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/Modes/Harvest/TreasureManager_Patch.cs b/MelonLoader/Patches/Modes/Harvest/TreasureManager_Patch.cs deleted file mode 100644 index 9e9f92f..0000000 --- a/MelonLoader/Patches/Modes/Harvest/TreasureManager_Patch.cs +++ /dev/null @@ -1,31 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Modes.Harvest -{ - [HarmonyPatch(typeof(TreasureManager))] - public static class TreasureManager_Patch - { - [HarmonyPatch(nameof(TreasureManager.Update))] - [HarmonyPostfix] - private static void Update(TreasureManager __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach(TextMeshProUGUI txt in __instance.evaText) - { - txt.autoSizeTextContainer = false; - - if (txt.text != "Evacuate") - { - txt.text = StringStore.TranslateText(txt.text); - txt.name = txt.text + "_EVACUATE"; - txt.font = fontAsset; - } - } - } - } -} diff --git a/MelonLoader/Patches/Modes/Harvest/TreasureStoreMenu_Patch.cs b/MelonLoader/Patches/Modes/Harvest/TreasureStoreMenu_Patch.cs deleted file mode 100644 index 05c3d8c..0000000 --- a/MelonLoader/Patches/Modes/Harvest/TreasureStoreMenu_Patch.cs +++ /dev/null @@ -1,25 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Modes.Harvest -{ - [HarmonyPatch(typeof(TreasureStoreMenu))] - public static class TreasureStoreMenu_Patch - { - [HarmonyPatch(nameof(TreasureStoreMenu.InitCards))] - [HarmonyPostfix] - private static void InitCards(TreasureStoreMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/Modes/Harvest/TreasureUpgradeMenu_Patch.cs b/MelonLoader/Patches/Modes/Harvest/TreasureUpgradeMenu_Patch.cs deleted file mode 100644 index fc8c177..0000000 --- a/MelonLoader/Patches/Modes/Harvest/TreasureUpgradeMenu_Patch.cs +++ /dev/null @@ -1,63 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppSystem; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using System.Text.RegularExpressions; -using UnityEngine; -using UnityEngine.UI; - -namespace PvZ_Fusion_Translator.Patches.Modes.Harvest -{ - [HarmonyPatch(typeof(TreasureUpgradeMenu))] - public static class TreasureUpgradeMenu_Patch - { - [HarmonyPatch(nameof(TreasureUpgradeMenu.Start))] - [HarmonyPostfix] - private static void Start(TreasureUpgradeMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - - [HarmonyPatch(nameof(TreasureUpgradeMenu.UpgradeWareHouse))] - [HarmonyPostfix] - private static void UpgradeWareHouse(TreasureUpgradeMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - - [HarmonyPatch(nameof(TreasureUpgradeMenu.InitWareHouseUpgrade))] - [HarmonyPostfix] - private static void InitWareHouseUpgrade(TreasureUpgradeMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - - foreach (Text txt in __instance.GetComponentsInChildren()) - { - GameObject newTxtObj = Utils.ConvertToTextMeshProUGUI(txt.gameObject, txt.transform.parent, "text"); - TextMeshProUGUI newTxt = newTxtObj.GetComponent(); - newTxt.text = StringStore.TranslateText("植物商店"); - newTxt.autoSizeTextContainer = true; - newTxt.color = new Color(0, 0, 0.3922f, 1); - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/Modes/Harvest/TreasureWarehouseMenu_Patch.cs b/MelonLoader/Patches/Modes/Harvest/TreasureWarehouseMenu_Patch.cs deleted file mode 100644 index edddd80..0000000 --- a/MelonLoader/Patches/Modes/Harvest/TreasureWarehouseMenu_Patch.cs +++ /dev/null @@ -1,64 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Modes.Harvest -{ - [HarmonyPatch(typeof(TreasureWarehouseMenu))] - public static class TreasureWarehouseMenu_Patch - { - [HarmonyPatch(nameof(TreasureWarehouseMenu.InitCards))] - [HarmonyPostfix] - private static void InitCards(TreasureWarehouseMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - - [HarmonyPatch(nameof(TreasureWarehouseMenu.QuickSell))] - [HarmonyPostfix] - private static void QuickSell(TreasureWarehouseMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - - [HarmonyPatch(nameof(TreasureWarehouseMenu.FastSell))] - [HarmonyPostfix] - private static void FastSell(TreasureWarehouseMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - - [HarmonyPatch(nameof(TreasureWarehouseMenu.EnterStore))] - [HarmonyPostfix] - private static void EnterStore(TreasureWarehouseMenu __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/Modes/Odyssey/MultipleChoiceMenu_Patch.cs b/MelonLoader/Patches/Modes/Odyssey/MultipleChoiceMenu_Patch.cs deleted file mode 100644 index a8371aa..0000000 --- a/MelonLoader/Patches/Modes/Odyssey/MultipleChoiceMenu_Patch.cs +++ /dev/null @@ -1,61 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; -using UnityEngine.TextCore.Text; - -namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey -{ - [HarmonyPatch(typeof(MultipleChoiceMenu))] - public static class MultipleChoiceMenu_Patch - { - public static TMP_FontAsset fontAsset => FontStore.LoadTMPFont(Utils.Language.ToString()); - - [HarmonyPatch(nameof(MultipleChoiceMenu.Awake))] - [HarmonyPatch(nameof(MultipleChoiceMenu.Cancel))] - [HarmonyPatch(nameof(MultipleChoiceMenu.Refresh))] - [HarmonyPatch(nameof(MultipleChoiceMenu.TurnPage))] - [HarmonyPatch(nameof(MultipleChoiceMenu.UpdateWindow))] - [HarmonyPostfix] - public static void Awake(MultipleChoiceMenu __instance) - { - foreach(BaseWindow window in __instance.windows) - { - TranslateWindowText(window.title); - TranslateWindowText(window.introduce); - } - - foreach(TheButton button in __instance.GetComponentsInChildren()) - { - foreach(TextMeshProUGUI txt in button.GetComponentsInChildren()) - { - txt.text = StringStore.translationString.ContainsKey(txt.text + "_MC") ? StringStore.TranslateText(txt.text + "_MC") : StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } - - public static void TranslateWindowText(TextMeshProUGUI txt) - { - txt.font = fontAsset; - if(StringStore.customLevelString.ContainsKey(txt.text)) - { - txt.text = StringStore.customLevelString[txt.text]; - } - else if(Utils.GetPlantNameFromAlmanac(txt.text) != "") - { - txt.text = Utils.GetPlantNameFromAlmanac(txt.text); - } - else - { - txt.text = StringStore.translationString.ContainsKey(txt.text + "_MC") ? StringStore.TranslateText(txt.text + "_MC") : StringStore.TranslateText(txt.text); - } - } - } -} diff --git a/MelonLoader/Patches/Modes/Odyssey/OppositeBuffManager_Patch.cs b/MelonLoader/Patches/Modes/Odyssey/OppositeBuffManager_Patch.cs deleted file mode 100644 index a29838f..0000000 --- a/MelonLoader/Patches/Modes/Odyssey/OppositeBuffManager_Patch.cs +++ /dev/null @@ -1,52 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using System.Text.RegularExpressions; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey -{ - /*[HarmonyPatch(typeof(OppositeBuffManager))] - public static class OppositeBuffManager_Patch - { - public static Dictionary buffLinks = TravelMgr_Patch.buffLinks; - public static Dictionary> translatedTravelBuffs = TravelMgr_Patch.translatedTravelBuffs; - public static string badPattern = @"^但(.*)"; - public static string badFormat = StringStore.translationStringRegex.ContainsKey(badPattern) ? StringStore.translationStringRegex[badPattern] : "But, {0}"; - public static TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - [HarmonyPatch(nameof(OppositeBuffManager.SetText))] - [HarmonyPostfix] - private static void SetText(OppositeBuffManager __instance) - { - *//*if (TravelMgr_Patch.travelBuffString.ContainsKey(__result)) - { - __result = TravelMgr_Patch.travelBuffString[__result]; - } - else if(TravelMgr_Patch.travelBuffString.ContainsKey(TravelMgr_Patch.RemoveBuffName(__result))) - { - __result = TravelMgr_Patch.travelBuffString[TravelMgr_Patch.RemoveBuffName(__result)]; - }*//* - } - - public static void TranslateOppositeText(Il2CppSystem.Collections.Generic.List textList, Il2CppSystem.Object buff, bool isBad = false) - { - string buffText = TravelMgr.Instance.GetText(buff); - - foreach (var text in textList) - { - if (isBad) - { - text.text = string.Format(badFormat, buffText); - } - else - { - text.text = buffText; - } - - text.font = fontAsset; - } - } - }*/ -} diff --git a/MelonLoader/Patches/Modes/Odyssey/ShootingManager_Patch.cs b/MelonLoader/Patches/Modes/Odyssey/ShootingManager_Patch.cs deleted file mode 100644 index 514e1a9..0000000 --- a/MelonLoader/Patches/Modes/Odyssey/ShootingManager_Patch.cs +++ /dev/null @@ -1,583 +0,0 @@ -using HarmonyLib; -using Il2CppGameLevel.RogueShooting; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey -{ - [HarmonyPatch(typeof(ShootingManager))] - public static class ShootingManager_Patch - { - [HarmonyPatch(nameof(ShootingManager.RegisterCoreBuff))] - [HarmonyPatch(nameof(ShootingManager.RegisterExpertBuff))] - [HarmonyPatch(nameof(ShootingManager.RegisterGetPlantBuff))] - [HarmonyPatch(nameof(ShootingManager.RegisterOtherBuff))] - [HarmonyPostfix] - public static void UpgradeBuff(ShootingManager __instance, ref Il2Cpp.MultipleChoiceMenu menu) - { - MultipleChoiceMenu_Patch.Awake(menu); - } - - public static void GetBuffs() - { - /*#region code - - AbyssSwordStar t0 = new(); - Bamboo t1 = new(); - BigChomper t4 = new(); - BigGatling t5 = new(); - CabbageCannon t6 = new(); - Cabbagepult t7 = new(); - Cactus t8 = new(); - Caltrop t9 = new(); - CaltropNut t10 = new(); - CattailLour t11 = new(); - CherryChomper t12 = new(); - CherryGatling t13 = new(); - CherrySquash t14 = new(); - Chomper t15 = new(); - Cornpult t17 = new(); - DoomCactus t20 = new(); - DoomChomper t21 = new(); - DoomSniper t22 = new(); - EmeraleBlover t23 = new(); - FireMelon t24 = new(); - FumeShroom t25 = new(); - GarlicFume t26 = new(); - GloomShroom t28 = new(); - GoldCabbage t29 = new(); - HelmetGatling t30 = new(); - HypnoEmperor t31 = new(); - HypnoNut t32 = new(); - HypnoShroom t33 = new(); - IceFumeShroom t34 = new(); - IcePuff t35 = new(); - IFVIronPuff t36 = new(); - IronPuff t37 = new(); - LanternSplit t38 = new(); - LanternUmbrella t39 = new(); - LaserUmbrella t40 = new(); - LotusBamboo t41 = new(); - Melonpult t42 = new(); - NuclearSquash t43 = new(); - ObsidianSpike t44 = new(); - ObsidianWallNut t45 = new(); - PeaMine t46 = new(); - Peashooter t47 = new(); - PortalCorn t48 = new(); - PotatoMine t49 = new(); - ScaredyDoom t54 = new(); - ScaredyShroom t55 = new(); - SmallPuff t57 = new(); - SniperPea t58 = new(); - SnowGatlingPuff t59 = new(); - SpikeRock t61 = new(); - Squalour t62 = new(); - Squash t63 = new(); - StarFruit t64 = new(); - SuperChomper t66 = new(); - SuperHypno t67 = new(); - SuperMelon t68 = new(); - SuperStar t69 = new(); - SuperThreePeater t70 = new(); - SwordStar t71 = new(); - TallNut t72 = new(); - ThreeMine t73 = new(); - ThreePeater t74 = new(); - ThreeSquash t75 = new(); - UltimateBamboo t76 = new(); - UltimateBigChomper t77 = new(); - UltimateBigGatling t78 = new(); - UltimateBlover t79 = new(); - UltimateCabbage t80 = new(); - UltimateCabbageCannon t81 = new(); - UltimateCactus t82 = new(); - UltimateChomper t83 = new(); - UltimateCorn t84 = new(); - UltimateDoomScared t85 = new(); - UltimateFume t86 = new(); - UltimateGatling t87 = new(); - UltimateGloom t88 = new(); - UltimateHelmetGatling t89 = new(); - UltimateHypno t90 = new(); - UltimateLanternSplit t91 = new(); - UltimateMelon t92 = new(); - UltimateMinigun t93 = new(); - UltimatePoisonFume t94 = new(); - UltimateSniperGatling t95 = new(); - UltimateSpring t96 = new(); - UltimateStar t97 = new(); - UltimateStarTorch t98 = new(); - UltimateTallNut t99 = new(); - UltimateWinterMelon t100 = new(); - Umbrellaleaf t101 = new(); - WallNut t103 = new(); - WinterMelon t104 = new(); - - Dictionary t = new(); - - #region 3 - - if(t0.Buffs != null) - { - Utils.TryAdd(t, t0.Role, t0.Role); - } - - if(t1.Buffs != null) - { - Utils.TryAdd(t, t1.Role, t1.Role); - } - - if(t4.Buffs != null) - { - Utils.TryAdd(t, t4.Role, t4.Role); - } - - if(t5.Buffs != null) - { - Utils.TryAdd(t, t5.Role, t5.Role); - } - - if(t6.Buffs != null) - { - Utils.TryAdd(t, t6.Role, t6.Role); - } - - if(t7.Buffs != null) - { - Utils.TryAdd(t, t7.Role, t7.Role); - } - - if(t8.Buffs != null) - { - Utils.TryAdd(t, t8.Role, t8.Role); - } - - if(t9.Buffs != null) - { - Utils.TryAdd(t, t9.Role, t9.Role); - } - - if(t10.Buffs != null) - { - Utils.TryAdd(t, t10.Role, t10.Role); - } - - if(t11.Buffs != null) - { - Utils.TryAdd(t, t11.Role, t11.Role); - } - - if(t12.Buffs != null) - { - Utils.TryAdd(t, t12.Role, t12.Role); - } - - if(t13.Buffs != null) - { - Utils.TryAdd(t, t13.Role, t13.Role); - } - - if(t14.Buffs != null) - { - Utils.TryAdd(t, t14.Role, t14.Role); - } - - if(t15.Buffs != null) - { - Utils.TryAdd(t, t15.Role, t15.Role); - } - - if(t17.Buffs != null) - { - Utils.TryAdd(t, t17.Role, t17.Role); - } - - if(t20.Buffs != null) - { - Utils.TryAdd(t, t20.Role, t20.Role); - } - - if(t21.Buffs != null) - { - Utils.TryAdd(t, t21.Role, t21.Role); - } - - if(t22.Buffs != null) - { - Utils.TryAdd(t, t22.Role, t22.Role); - } - - if(t23.Buffs != null) - { - Utils.TryAdd(t, t23.Role, t23.Role); - } - - if(t24.Buffs != null) - { - Utils.TryAdd(t, t24.Role, t24.Role); - } - - if(t25.Buffs != null) - { - Utils.TryAdd(t, t25.Role, t25.Role); - } - - if(t26.Buffs != null) - { - Utils.TryAdd(t, t26.Role, t26.Role); - } - - if(t28.Buffs != null) - { - Utils.TryAdd(t, t28.Role, t28.Role); - } - - if(t29.Buffs != null) - { - Utils.TryAdd(t, t29.Role, t29.Role); - } - - if(t30.Buffs != null) - { - Utils.TryAdd(t, t30.Role, t30.Role); - } - - if(t31.Buffs != null) - { - Utils.TryAdd(t, t31.Role, t31.Role); - } - - if(t32.Buffs != null) - { - Utils.TryAdd(t, t32.Role, t32.Role); - } - - if(t33.Buffs != null) - { - Utils.TryAdd(t, t33.Role, t33.Role); - } - - if(t34.Buffs != null) - { - Utils.TryAdd(t, t34.Role, t34.Role); - } - - if(t35.Buffs != null) - { - Utils.TryAdd(t, t35.Role, t35.Role); - } - - if(t36.Buffs != null) - { - Utils.TryAdd(t, t36.Role, t36.Role); - } - - if(t37.Buffs != null) - { - Utils.TryAdd(t, t37.Role, t37.Role); - } - - if(t38.Buffs != null) - { - Utils.TryAdd(t, t38.Role, t38.Role); - } - - if(t39.Buffs != null) - { - Utils.TryAdd(t, t39.Role, t39.Role); - } - - if(t40.Buffs != null) - { - Utils.TryAdd(t, t40.Role, t40.Role); - } - - if(t41.Buffs != null) - { - Utils.TryAdd(t, t41.Role, t41.Role); - } - - if(t42.Buffs != null) - { - Utils.TryAdd(t, t42.Role, t42.Role); - } - - if(t43.Buffs != null) - { - Utils.TryAdd(t, t43.Role, t43.Role); - } - - if(t44.Buffs != null) - { - Utils.TryAdd(t, t44.Role, t44.Role); - } - - if(t45.Buffs != null) - { - Utils.TryAdd(t, t45.Role, t45.Role); - } - - if(t46.Buffs != null) - { - Utils.TryAdd(t, t46.Role, t46.Role); - } - - if(t47.Buffs != null) - { - Utils.TryAdd(t, t47.Role, t47.Role); - } - - if(t48.Buffs != null) - { - Utils.TryAdd(t, t48.Role, t48.Role); - } - - if(t49.Buffs != null) - { - Utils.TryAdd(t, t49.Role, t49.Role); - } - - if(t54.Buffs != null) - { - Utils.TryAdd(t, t54.Role, t54.Role); - } - - if(t55.Buffs != null) - { - Utils.TryAdd(t, t55.Role, t55.Role); - } - - if(t57.Buffs != null) - { - Utils.TryAdd(t, t57.Role, t57.Role); - } - - if(t58.Buffs != null) - { - Utils.TryAdd(t, t58.Role, t58.Role); - } - - if(t59.Buffs != null) - { - Utils.TryAdd(t, t59.Role, t59.Role); - } - - if(t61.Buffs != null) - { - Utils.TryAdd(t, t61.Role, t61.Role); - } - - if(t62.Buffs != null) - { - Utils.TryAdd(t, t62.Role, t62.Role); - } - - if(t63.Buffs != null) - { - Utils.TryAdd(t, t63.Role, t63.Role); - } - - if(t64.Buffs != null) - { - Utils.TryAdd(t, t64.Role, t64.Role); - } - - if(t66.Buffs != null) - { - Utils.TryAdd(t, t66.Role, t66.Role); - } - - if(t67.Buffs != null) - { - Utils.TryAdd(t, t67.Role, t67.Role); - } - - if(t68.Buffs != null) - { - Utils.TryAdd(t, t68.Role, t68.Role); - } - - if(t69.Buffs != null) - { - Utils.TryAdd(t, t69.Role, t69.Role); - } - - if(t70.Buffs != null) - { - Utils.TryAdd(t, t70.Role, t70.Role); - } - - if(t71.Buffs != null) - { - Utils.TryAdd(t, t71.Role, t71.Role); - } - - if(t72.Buffs != null) - { - Utils.TryAdd(t, t72.Role, t72.Role); - } - - if(t73.Buffs != null) - { - Utils.TryAdd(t, t73.Role, t73.Role); - } - - if(t74.Buffs != null) - { - Utils.TryAdd(t, t74.Role, t74.Role); - } - - if(t75.Buffs != null) - { - Utils.TryAdd(t, t75.Role, t75.Role); - } - - if(t76.Buffs != null) - { - Utils.TryAdd(t, t76.Role, t76.Role); - } - - if(t77.Buffs != null) - { - Utils.TryAdd(t, t77.Role, t77.Role); - } - - if(t78.Buffs != null) - { - Utils.TryAdd(t, t78.Role, t78.Role); - } - - if(t79.Buffs != null) - { - Utils.TryAdd(t, t79.Role, t79.Role); - } - - if(t80.Buffs != null) - { - Utils.TryAdd(t, t80.Role, t80.Role); - } - - if(t81.Buffs != null) - { - Utils.TryAdd(t, t81.Role, t81.Role); - } - - if(t82.Buffs != null) - { - Utils.TryAdd(t, t82.Role, t82.Role); - } - - if(t83.Buffs != null) - { - Utils.TryAdd(t, t83.Role, t83.Role); - } - - if(t84.Buffs != null) - { - Utils.TryAdd(t, t84.Role, t84.Role); - } - - if(t85.Buffs != null) - { - Utils.TryAdd(t, t85.Role, t85.Role); - } - - if(t86.Buffs != null) - { - Utils.TryAdd(t, t86.Role, t86.Role); - } - - if(t87.Buffs != null) - { - Utils.TryAdd(t, t87.Role, t87.Role); - } - - if(t88.Buffs != null) - { - Utils.TryAdd(t, t88.Role, t88.Role); - } - - if(t89.Buffs != null) - { - Utils.TryAdd(t, t89.Role, t89.Role); - } - - if(t90.Buffs != null) - { - Utils.TryAdd(t, t90.Role, t90.Role); - } - - if(t91.Buffs != null) - { - Utils.TryAdd(t, t91.Role, t91.Role); - } - - if(t92.Buffs != null) - { - Utils.TryAdd(t, t92.Role, t92.Role); - } - - if(t93.Buffs != null) - { - Utils.TryAdd(t, t93.Role, t93.Role); - } - - if(t94.Buffs != null) - { - Utils.TryAdd(t, t94.Role, t94.Role); - } - - if(t95.Buffs != null) - { - Utils.TryAdd(t, t95.Role, t95.Role); - } - - if(t96.Buffs != null) - { - Utils.TryAdd(t, t96.Role, t96.Role); - } - - if(t97.Buffs != null) - { - Utils.TryAdd(t, t97.Role, t97.Role); - } - - if(t98.Buffs != null) - { - Utils.TryAdd(t, t98.Role, t98.Role); - } - - if(t99.Buffs != null) - { - Utils.TryAdd(t, t99.Role, t99.Role); - } - - if(t100.Buffs != null) - { - Utils.TryAdd(t, t100.Role, t100.Role); - } - - if(t101.Buffs != null) - { - Utils.TryAdd(t, t101.Role, t101.Role); - } - - if(t103.Buffs != null) - { - Utils.TryAdd(t, t103.Role, t103.Role); - } - - if(t104.Buffs != null) - { - Utils.TryAdd(t, t104.Role, t104.Role); - } - - #endregion - - File.WriteAllText("tge_roles.json", FileLoader.SerializeWithIndentation(t)); - - #endregion*/ - } - } -} diff --git a/MelonLoader/Patches/Modes/Odyssey/SynergyDisplay_Patch.cs b/MelonLoader/Patches/Modes/Odyssey/SynergyDisplay_Patch.cs deleted file mode 100644 index 2ec60a3..0000000 --- a/MelonLoader/Patches/Modes/Odyssey/SynergyDisplay_Patch.cs +++ /dev/null @@ -1,32 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using static PvZ_Fusion_Translator.Patches.Modes.Odyssey.TravelMgr_Patch; -using UnityEngine; -using MelonLoader; - -namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey -{ - [HarmonyPatch(typeof(SynergyDisplay))] - public static class SynergyDisplay_Patch - { - [HarmonyPatch(nameof(SynergyDisplay.Start))] - [HarmonyPostfix] - public static void Start(SynergyDisplay __instance) - { - __instance.text.text = TranslateInvestDisplay(__instance.text.text); - } - - public static string TranslateInvestDisplay(string originalText) - { - string[] parts = originalText.Split("\n\n"); - List translatedParts = new List(); - foreach(string part in parts) - { - translatedParts.Add(StringStore.TranslateColorText(part)); - } - return String.Join("\n\n", translatedParts); - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/Modes/Odyssey/TravelAdvantureMenu_Patch.cs b/MelonLoader/Patches/Modes/Odyssey/TravelAdvantureMenu_Patch.cs deleted file mode 100644 index 4411728..0000000 --- a/MelonLoader/Patches/Modes/Odyssey/TravelAdvantureMenu_Patch.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using HarmonyLib; -using Il2Cpp; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey -{ - [HarmonyPatch(typeof(TravelAdvantureMenu))] - public static class TravelAdvantureMenu_Patch - { - [HarmonyPatch(nameof(TravelAdvantureMenu.Awake))] - [HarmonyPostfix] - public static void Awake(TravelAdvantureMenu __instance) - { - foreach(CustomButton_enterGame button in __instance.GetComponentsInChildren()) - { - string plantName = Utils.GetPlantNameFromAlmanac(button.levelName.text); - if(Utils.Language == Utils.LanguageEnum.Arabic) - { - button.levelName.text = StringStore.TranslateText(button.levelName.text); - } - else - { - button.levelName.text = (plantName != "") ? plantName : StringStore.TranslateText(button.levelName.text); - } - } - } - - [HarmonyPatch(nameof(TravelAdvantureMenu.LookWeak))] - [HarmonyPostfix] - public static void LookWeak(TravelAdvantureMenu __instance) - { - Awake(__instance); - } - - [HarmonyPatch(nameof(TravelAdvantureMenu.LookUlti))] - [HarmonyPostfix] - public static void LookUlti(TravelAdvantureMenu __instance) - { - Awake(__instance); - } - } -} diff --git a/MelonLoader/Patches/Modes/Odyssey/TravelBuffMenu_Patch.cs b/MelonLoader/Patches/Modes/Odyssey/TravelBuffMenu_Patch.cs deleted file mode 100644 index 84c83bc..0000000 --- a/MelonLoader/Patches/Modes/Odyssey/TravelBuffMenu_Patch.cs +++ /dev/null @@ -1,35 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using static PvZ_Fusion_Translator.Patches.Modes.Odyssey.TravelMgr_Patch; -using UnityEngine; -using MelonLoader; - -namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey -{ - [HarmonyPatch(typeof(TravelBuffMenu))] - public static class TravelBuffMenu_Patch - { - [HarmonyPatch(nameof(TravelBuffMenu.RefeshOptions))] - [HarmonyPostfix] - public static void RefeshOptions(TravelBuffMenu __instance) - { - foreach (TravelBuffOptionButton button in __instance.options) - { - TravelBuffOptionButton_Patch.TranslateOptionButton(button); - } - } - - [HarmonyPatch(nameof(TravelBuffMenu.Awake))] - [HarmonyPostfix] - public static void Awake(TravelBuffMenu __instance) - { - Transform refreshTransform = __instance.transform.Find("Refresh"); - foreach (TextMeshProUGUI text in refreshTransform.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/Modes/Odyssey/TravelBuffMgr_Patch.cs b/MelonLoader/Patches/Modes/Odyssey/TravelBuffMgr_Patch.cs deleted file mode 100644 index 7d583df..0000000 --- a/MelonLoader/Patches/Modes/Odyssey/TravelBuffMgr_Patch.cs +++ /dev/null @@ -1,27 +0,0 @@ -//using HarmonyLib; -//using Il2Cpp; -//using System.Text.Encodings.Web; -//using System.Text.Json; - -//namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey -//{ -// [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/MelonLoader/Patches/Modes/Odyssey/TravelBuffOptionButton_Patch.cs b/MelonLoader/Patches/Modes/Odyssey/TravelBuffOptionButton_Patch.cs deleted file mode 100644 index a20704f..0000000 --- a/MelonLoader/Patches/Modes/Odyssey/TravelBuffOptionButton_Patch.cs +++ /dev/null @@ -1,51 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using MelonLoader; -using PvZ_Fusion_Translator.AssetStore; -using static MelonLoader.MelonLogger; -using static PvZ_Fusion_Translator.Patches.Modes.Odyssey.TravelMgr_Patch; - -namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey -{ - [HarmonyPatch(typeof(TravelBuffOptionButton))] - public static class TravelBuffOptionButton_Patch - { - [HarmonyPatch(nameof(TravelBuffOptionButton.Awake))] - [HarmonyPostfix] - public static void Awake(TravelBuffOptionButton __instance) - { - TranslateOptionButton(__instance); - } - - [HarmonyPatch(nameof(TravelBuffOptionButton.OnAnimOver))] - [HarmonyPostfix] - public static void OnAnimOver(TravelBuffOptionButton __instance) - { - TranslateOptionButton(__instance); - } - - public static void TranslateOptionButton(TravelBuffOptionButton button) - { - if(TravelMgr_Patch.travelBuffString.ContainsKey(button.introduce.text)) - { - string translatedBuff = travelBuffString[button.introduce.text]; - button.introduce.text = AddBuffName(translatedBuff); - } - - if(!Utils.CheckForUntranslatedText(button.introduce.text)) - { - button.introduce.text = AddBuffName(button.introduce.text); - } - - if(!TravelMgr_Patch.travelBuffString.ContainsKey(button.introduce.text) && Utils.CheckForUntranslatedText(button.introduce.text)) - { - button.introduce.text = StringStore.TranslateText(button.introduce.text); - } - } - } - - //List buffSet = translatedTravelBuffs[buffLinks[__instance.buffType]]; - //string buff = (__instance.show != null) ? buffSet[__instance.buffIndex] : StringStore.TranslateText("无"); - //__instance.introduce.text = buff; -} diff --git a/MelonLoader/Patches/Modes/Odyssey/TravelBuff_Patch.cs b/MelonLoader/Patches/Modes/Odyssey/TravelBuff_Patch.cs deleted file mode 100644 index fbed59a..0000000 --- a/MelonLoader/Patches/Modes/Odyssey/TravelBuff_Patch.cs +++ /dev/null @@ -1,18 +0,0 @@ -//using HarmonyLib; -//using Il2Cpp; - -//namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey -//{ -// [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/MelonLoader/Patches/Modes/Odyssey/TravelInvestMenu_Patch.cs b/MelonLoader/Patches/Modes/Odyssey/TravelInvestMenu_Patch.cs deleted file mode 100644 index bef66f2..0000000 --- a/MelonLoader/Patches/Modes/Odyssey/TravelInvestMenu_Patch.cs +++ /dev/null @@ -1,32 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey -{ - [HarmonyPatch(typeof(TravelInvestMenu))] - public static class TravelInvestMenu_Patch - { - [HarmonyPatch(nameof(TravelInvestMenu.Start))] - [HarmonyPostfix] - private static void Start(TravelInvestMenu __instance) - { - Transform titleText = __instance.transform.Find("Title"); - TextMeshProUGUI shadowText = titleText.GetComponent(); - - TextMeshProUGUI regularText = titleText.transform.Find("Title2").GetComponent(); - regularText.text = StringStore.TranslateText(regularText.text); - - shadowText.text = Utils.RemoveColorTags(regularText.text); - } - - [HarmonyPatch(nameof(TravelInvestMenu.RefreshBuff))] - [HarmonyPostfix] - private static void RefreshBuff(TravelInvestMenu __instance, ref TravelBuffOptionButton option) - { - TravelBuffOptionButton_Patch.TranslateOptionButton(option); - } - } -} diff --git a/MelonLoader/Patches/Modes/Odyssey/TravelLookBuff_Patch.cs b/MelonLoader/Patches/Modes/Odyssey/TravelLookBuff_Patch.cs deleted file mode 100644 index 53c1360..0000000 --- a/MelonLoader/Patches/Modes/Odyssey/TravelLookBuff_Patch.cs +++ /dev/null @@ -1,70 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using static PvZ_Fusion_Translator.Patches.Modes.Odyssey.TravelMgr_Patch; -using UnityEngine; -using MelonLoader; - -namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey -{ - [HarmonyPatch(typeof(TravelLookBuff))] - public static class TravelLookBuff_Patch - { - [HarmonyPatch(nameof(TravelLookBuff.Clear))] - [HarmonyPostfix] - public static void Post_Clear(TravelLookBuff __instance) - { - __instance.introduce.text = StringStore.TranslateText("无"); - __instance.set = false; - - foreach (TextMeshProUGUI text in __instance.transform.FindChild("Images").FindChild("Button").GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - - [HarmonyPatch(nameof(TravelLookBuff.OnMouseUpAsButton))] - [HarmonyPostfix] - public static void Post_OnMouseUpAsButton(TravelLookBuff __instance) - { - foreach (TextMeshProUGUI text in __instance.transform.FindChild("Images").FindChild("Button").GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - - [HarmonyPatch(nameof(TravelLookBuff.SetBuff))] - [HarmonyPostfix] - public static void Post_SetBuff(TravelLookBuff __instance) - { - /*SortedDictionary buffSet = translatedTravelBuffs[buffLinks[__instance.buffType]]; - string buffText = buffSet.ContainsKey(__instance.buffIndex) ? buffSet[__instance.buffIndex] : StringStore.TranslateText(__instance.introduce.text); - __instance.introduce.text = buffText;*/ - - foreach (TextMeshProUGUI text in __instance.transform.FindChild("Images").FindChild("Introduce").GetComponentsInChildren()) - { - if(TravelMgr_Patch.travelBuffString.ContainsKey(text.text)) - { - string translatedBuff = travelBuffString[text.text]; - text.text = AddBuffName(translatedBuff); - } - - if(!Utils.CheckForUntranslatedText(text.text)) - { - text.text = AddBuffName(text.text); - } - - if(!TravelMgr_Patch.travelBuffString.ContainsKey(text.text) && Utils.CheckForUntranslatedText(text.text)) - { - text.text = StringStore.TranslateText(text.text); - } - } - - foreach (TextMeshProUGUI text in __instance.transform.FindChild("Images").FindChild("Button").GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/Modes/Odyssey/TravelLookMenu_Patch.cs b/MelonLoader/Patches/Modes/Odyssey/TravelLookMenu_Patch.cs deleted file mode 100644 index cda2c7a..0000000 --- a/MelonLoader/Patches/Modes/Odyssey/TravelLookMenu_Patch.cs +++ /dev/null @@ -1,46 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey -{ - [HarmonyPatch(typeof(TravelLookMenu))] - public static class TravelLookMenu_Patch - { - public static string savedAssetString = ""; - - [HarmonyPatch(nameof(TravelLookMenu.Start))] - [HarmonyPostfix] - private static void Postfix_Start(TravelLookMenu __instance) - { - foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText(txt.text); - txt.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - - Transform quitButtonTransform = __instance.transform.Find("Quit"); - foreach (TextMeshProUGUI txt in quitButtonTransform.GetComponentsInChildren()) - { - txt.text = StringStore.TranslateText("合上"); - txt.font = FontStore.LoadTMPFont(Utils.Language.ToString()); - } - - __instance.treasureText.text = StringStore.TranslateText(__instance.treasureText.text); - savedAssetString = __instance.treasureText.text; - } - - [HarmonyPatch(nameof(TravelLookMenu.Update))] - [HarmonyPostfix] - private static void Update(TravelLookMenu __instance) - { - if (savedAssetString != __instance.treasureText.text) - { - __instance.treasureText.text = StringStore.TranslateText(__instance.treasureText.text); - savedAssetString = __instance.treasureText.text; - } - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/Modes/Odyssey/TravelMgr_Patch.cs b/MelonLoader/Patches/Modes/Odyssey/TravelMgr_Patch.cs deleted file mode 100644 index e96322e..0000000 --- a/MelonLoader/Patches/Modes/Odyssey/TravelMgr_Patch.cs +++ /dev/null @@ -1,367 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using PvZ_Fusion_Translator.AssetStore; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.Encodings.Web; -using System.Text.Json; -using System.Threading.Tasks; -using Unity.Collections; -using UnityEngine.Rendering; -using static PvZ_Fusion_Translator.FileLoader; - -namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey -{ - public class TravelBuffInfo - { - public string name = ""; - public string desc = ""; - - public TravelBuffInfo(string name_a = "", string desc_a = "") - { - name = name_a; - desc = desc_a; - } - } - - public class TravelBuffSet - { - public SortedDictionary advancedBuffs = new(); - public SortedDictionary ultimateBuffs = new(); - public SortedDictionary debuffs = new(); - public SortedDictionary unlocks = new(); - public SortedDictionary investmentBuffs = new(); - private Dictionary> _travelBuffSets = []; - - public TravelBuffSet() - { - advancedBuffs = new(); - ultimateBuffs = new(); - debuffs = new(); - unlocks = new(); - investmentBuffs = new(); - - _travelBuffSets = new() - { - { "advancedBuffs", advancedBuffs }, - { "ultimateBuffs", ultimateBuffs }, - { "debuffs", debuffs }, - { "unlocks", unlocks }, - { "investmentBuffs", investmentBuffs } - }; - } - - public SortedDictionary TryGet(string name) - { - switch(name) - { - case "advancedBuffs": - return advancedBuffs; - case "ultimateBuffs": - return ultimateBuffs; - case "debuffs": - return debuffs; - case "unlocks": - return unlocks; - case "investmentBuffs": - return investmentBuffs; - default: - return null; - } - } - - public IEnumerator>> GetEnumerator() - { - foreach(var item in _travelBuffSets) - { - yield return new(item.Key, item.Value); - } - } - } - - [HarmonyPatch(typeof(TravelMgr))] - public static class TravelMgr_Patch - { - public static readonly TravelBuffSet templateTravelBuffs = new(); - - public static TravelBuffSet dumpedTravelBuffs = new(); - - public static TravelBuffSet translatedTravelBuffs = new(); - - public static Dictionary travelBuffString = new() - { - - }; - - public static Dictionary buffLinks = new() - { - { BuffType.AdvancedBuff, "advancedBuffs" }, - { BuffType.UltimateBuff, "ultimateBuffs" }, - { BuffType.Debuff, "debuffs" }, - { BuffType.UnlockPlant, "unlocks" }, - { BuffType.InvestmentBuff, "investmentBuffs" } - }; - - [HarmonyPatch(nameof(TravelMgr.GetText))] - [HarmonyPostfix] - public static void GetText(TravelMgr __instance, ref string __result) - { - if (travelBuffString.ContainsKey(__result)) - { - __result = travelBuffString[__result]; - } - else if(travelBuffString.ContainsKey(RemoveBuffName(__result))) - { - __result = travelBuffString[RemoveBuffName(__result)]; - } - else - { - __result = StringStore.TranslateText(__result); - } - } - - public static void DumpTravelBuffs() - { - TravelMgr.Instance.GetPlantBuffUnlockCount(PlantType.DoomGatling); - - dumpedTravelBuffs = new(); - travelBuffString.Clear(); - - foreach (var pair in TravelDictionary.advancedBuffsText) - { - Utils.TryAdd(dumpedTravelBuffs.advancedBuffs, (int)pair.Key, new TravelBuffInfo("", pair.Value)); - Utils.TryAdd(travelBuffString, pair.Value, pair.Value); - } - - foreach (var pair in TravelDictionary.ultimateBuffsText) - { - Utils.TryAdd(dumpedTravelBuffs.ultimateBuffs, (int)pair.Key, new TravelBuffInfo("", pair.Value)); - Utils.TryAdd(travelBuffString, pair.Value, pair.Value); - } - - foreach (var pair in TravelDictionary.debuffData) - { - Utils.TryAdd(dumpedTravelBuffs.debuffs, (int)pair.Key, new TravelBuffInfo("", pair.Value.Item1)); - Utils.TryAdd(travelBuffString, pair.Value.Item1, pair.Value.Item1); - } - - foreach (var pair in TravelDictionary.unlocksText) - { - Utils.TryAdd(dumpedTravelBuffs.unlocks, (int)pair.Key, new TravelBuffInfo("", pair.Value)); - Utils.TryAdd(travelBuffString, pair.Value, pair.Value); - } - - foreach (var pair in TravelMgr.InvestBuffsData) - { - Utils.TryAdd(dumpedTravelBuffs.investmentBuffs, (int)pair.Key, new TravelBuffInfo("", pair.Value.GetDescription())); - Utils.TryAdd(travelBuffString, pair.Value.GetDescription(), pair.Value.GetDescription()); - } - - File.WriteAllText(Path.Combine(GetAssetDir(AssetType.Dumps), "travel_buffs.json"), SerializeWithIndentation(dumpedTravelBuffs)); - - string translatedTravelBuffsPath = Path.Combine(GetAssetDir(AssetType.Strings, Utils.Language), "travel_buffs.json"); - - if (!File.Exists(translatedTravelBuffsPath)) - { - File.WriteAllText(translatedTravelBuffsPath, SerializeWithIndentation(dumpedTravelBuffs)); - translatedTravelBuffs = dumpedTravelBuffs; - } - } - - //System.Text.Json.JsonSerializer.Deserialize>>(travelBuffsContent); - public static void GenerateTranslatedTravelBuffs(string travelBuffsContent) - { - if (!Core.isInitialized) return; - - DumpTravelBuffs(); - - TravelBuffSet travelBuffs = Newtonsoft.Json.JsonConvert.DeserializeObject(travelBuffsContent); - translatedTravelBuffs = travelBuffs; - travelBuffString.Clear(); - - foreach(var i in travelBuffs) - { - var originalBuffSet = dumpedTravelBuffs.TryGet(i.Item1); - foreach(var j in originalBuffSet) - { - TravelBuffInfo originalBuff = j.Value; - var translatedBuffSet = travelBuffs.TryGet(i.Item1); - - if (j.Value.desc == originalBuff.desc) - { - if (translatedBuffSet.ContainsKey(j.Key)) - { - Utils.TryAdd(travelBuffString, originalBuff.desc, translatedBuffSet[j.Key].desc); - } - } - else if(j.Value.desc == RemoveBuffName(originalBuff.desc)) - { - if (translatedBuffSet.ContainsKey(j.Key)) - { - Utils.TryAdd(travelBuffString, originalBuff.desc, translatedBuffSet[j.Key].desc); - } - } - - /*var translatedBuffSet = travelBuffs[i.Key]; - if(translatedBuffSet.ContainsKey(j.Key)) - { - string translatedBuff = travelBuffs[i.Key][j.Key]; - travelBuffString[originalBuff] = translatedBuff; - }*/ - } - } - - string travelBuffsToSave = SerializeWithIndentation(TravelMgr_Patch.translatedTravelBuffs); - string stringDir = GetAssetDir(AssetType.Strings, Utils.Language); - File.WriteAllText(Path.Combine(stringDir, "travel_buffs.json"), travelBuffsToSave); - } - - public static string MatchTravelBuff(string originalText) - { - string res = ""; - - foreach (var i in dumpedTravelBuffs) - { - foreach (var j in dumpedTravelBuffs.TryGet(i.Item1)) - { - if (j.Value.desc == originalText || j.Value.desc == RemoveBuffName(originalText)) - { - var translatedBuffSet = translatedTravelBuffs.TryGet(i.Item1); - if (translatedBuffSet.ContainsKey(j.Key)) - { - res = translatedBuffSet[j.Key].desc; - } - break; - } - } - - if (res != "") break; - } - - return res; - } - - public static string RemoveBuffName(string buffText) - { - string res = buffText; - int firstColon = res.IndexOf(":"); - if(firstColon > 0) - { - res = res.Substring(firstColon + 1); - } - return res; - } - - public static Dictionary modifierNameDict = new Dictionary() - { - { "advancedBuffs", "COMMON_MODIFIER_TAG" }, - { "ultimateBuffs", "EPIC_MODIFIER_TAG" }, - { "debuffs", "ZOMBIE_MODIFIER_TAG" }, - { "unlocks", "UNLOCK_MODIFIER_TAG" }, - { "investmentBuffs", "INVEST_MODIFIER_TAG" } - }; - - public static Dictionary fallbackNameDict = new Dictionary() - { - { "COMMON_MODIFIER_TAG", "Common Modifier" }, - { "EPIC_MODIFIER_TAG", "Epic Modifier" }, - { "ZOMBIE_MODIFIER_TAG", "Zombie Modifier" }, - { "UNLOCK_MODIFIER_TAG", "Unlock Modifier" }, - { "INVEST_MODIFIER_TAG", "Investment Modifier" } - }; - - public static string TranslateNameTag(string originalText) - { - string res = originalText; - - string nameTag = modifierNameDict[originalText]; - res = StringStore.translationString.ContainsKey(nameTag) ? StringStore.TranslateText(nameTag) : fallbackNameDict[nameTag]; - - return res; - } - - public static ValueTuple FindBuffData(string buffText) - { - ValueTuple res = new(); - foreach(var pair1 in translatedTravelBuffs) - { - foreach(var pair2 in pair1.Item2) - { - if(buffText == pair2.Value.desc) - { - if(pair2.Value.name != "") - { - res.Item1 = pair2.Value.name; - res.Item4 = true; - } - else - { - res.Item1 = TranslateNameTag(pair1.Item1); - res.Item4 = false; - } - res.Item2 = pair2.Key; - } - } - } - - foreach(var pair1 in dumpedTravelBuffs) - { - foreach(var pair2 in pair1.Item2) - { - if(buffText == pair2.Value.desc) - { - if(pair2.Value.name != "") - { - res.Item1 = pair2.Value.name; - res.Item4 = true; - } - else - { - res.Item1 = TranslateNameTag(pair1.Item1); - res.Item4 = false; - } - res.Item2 = pair2.Key; - } - } - } - - string finalBuffText = buffText; - if(travelBuffString.ContainsKey(buffText)) - { - finalBuffText = travelBuffString[buffText]; - } - else - { - finalBuffText = StringStore.TranslateText(buffText); - } - res.Item3 = finalBuffText; - - return res; - } - - public static string fallbackFBuffStr = "{0}: {1}"; - - public static string AddBuffName(string buffText) - { - string translatedBuff = buffText; - if(Utils.CheckForUntranslatedText(buffText)) - { - if(travelBuffString.ContainsKey(buffText)) - { - translatedBuff = travelBuffString[buffText]; - } - } - var buffData = FindBuffData(translatedBuff); - if(buffData.Item1 != null && buffData.Item3 != null) - { - string buffFStr = StringStore.translationStringRegex.ContainsKey("BUFF_NAME_FORMAT") ? StringStore.translationStringRegex["BUFF_NAME_FORMAT"] : "{0}: {1}"; - string fBuffDesc = string.Format(buffFStr, buffData.Item1, buffData.Item3); - translatedBuff = fBuffDesc; - } - - return translatedBuff; - } - } -} diff --git a/MelonLoader/Patches/Modes/Odyssey/TravelRefresh_Patch.cs b/MelonLoader/Patches/Modes/Odyssey/TravelRefresh_Patch.cs deleted file mode 100644 index 5d58593..0000000 --- a/MelonLoader/Patches/Modes/Odyssey/TravelRefresh_Patch.cs +++ /dev/null @@ -1,28 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey -{ - [HarmonyPatch(typeof(TravelRefresh))] - public static class TravelRefresh_Patch - { - [HarmonyPatch(nameof(TravelRefresh.Awake))] - [HarmonyPostfix] - private static void Awake(TravelRefresh __instance) - { - __instance.text = StringStore.TranslateText(__instance.text); - __instance.text_shadow = StringStore.TranslateText(__instance.text_shadow); - } - - [HarmonyPatch(nameof(TravelRefresh.OnMouseUpAsButton))] - [HarmonyPostfix] - private static void OnMouseUpAsButton(TravelRefresh __instance) - { - __instance.text = StringStore.TranslateText(__instance.text); - __instance.text_shadow = StringStore.TranslateText(__instance.text_shadow); - } - } -} diff --git a/MelonLoader/Patches/Modes/Odyssey/TravelStoreWindow_Patch.cs b/MelonLoader/Patches/Modes/Odyssey/TravelStoreWindow_Patch.cs deleted file mode 100644 index b8fc49f..0000000 --- a/MelonLoader/Patches/Modes/Odyssey/TravelStoreWindow_Patch.cs +++ /dev/null @@ -1,93 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using System.Text.RegularExpressions; -using UnityEngine; -using static Il2CppSystem.Globalization.TimeSpanFormat; -using static PvZ_Fusion_Translator.Patches.Modes.Odyssey.TravelMgr_Patch; - -namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey -{ - [HarmonyPatch(typeof(TravelStoreWindow))] - public static class TravelStoreWindow_Patch - { - [HarmonyPatch(nameof(TravelStoreWindow.SetType))] - [HarmonyPostfix] - private static void SetType(TravelStoreWindow __instance) - { - /*var buffSet = translatedTravelBuffs[buffLinks[__instance.buffType]]; - - string buff = __instance.show != null && __instance.introduce.text != "词条已选完" ? buffSet[__instance.buffIndex] : StringStore.TranslateText("词条已选完");*/ - string originalText = __instance.introduce.text; - string affinityPattern = "([\\s\\S]+)(\\\n)([\\s\\S]+)(<\\/color>)"; - if(Regex.IsMatch(__instance.introduce.text, affinityPattern, options: RegexOptions.Singleline)) - { - Match match = Regex.Match(__instance.introduce.text, affinityPattern, options: RegexOptions.Singleline); - string startText = match.Groups[1].Value; - string affinityText = match.Groups[3].Value; - string affinities = TranslateAffinities(affinityText); - __instance.introduce.text = AddBuffName(startText) + affinities; - } - else - { - __instance.introduce.text = AddBuffName(originalText); - } - - foreach (var text in __instance.buttonText) - { - text.text = StringStore.TranslateText(text.text); - } - } - - [HarmonyPatch(nameof(TravelStoreWindow.UpdateButtonText))] - [HarmonyPostfix] - private static void UpdateButtonText(TravelStoreWindow __instance) - { - foreach (var text in __instance.buttonText) - { - text.text = StringStore.TranslateText(text.text); - } - } - - public static string TranslateAffinities(string originalText) - { - string result = ""; - List translatedAffinities = []; - - string[] lines = originalText.Split('\n'); - - foreach(string line in lines) - { - if (string.IsNullOrEmpty(line)) continue; - - string fStr = StringStore.translationStringRegex.ContainsKey("【([^\\s]+)】_IV") ? StringStore.translationStringRegex["【([^\\s]+)】_IV"] : "[{0}]"; - - // Extract dynamic parts from the original text - var regex = new Regex("【([^\\s]+)】"); - var match = regex.Match(line); - int groupCount = match.Groups.Count; - - // 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 = StringStore.translationString.ContainsKey(groupValue) - ? StringStore.translationString[groupValue] - : groupValue; - dynamicParts.Add(translatedValue); - } - - // Format the output string with dynamic parts - string translatedAffinity = string.Format(fStr, [.. dynamicParts]); - translatedAffinities.Add(translatedAffinity); - } - - result = "\n" + "" + String.Join("\n", translatedAffinities) + ""; - return result; - } - } -} diff --git a/MelonLoader/Patches/Modes/Odyssey/TravelStore_Patch.cs b/MelonLoader/Patches/Modes/Odyssey/TravelStore_Patch.cs deleted file mode 100644 index dc07b75..0000000 --- a/MelonLoader/Patches/Modes/Odyssey/TravelStore_Patch.cs +++ /dev/null @@ -1,96 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using static PvZ_Fusion_Translator.Patches.Modes.Odyssey.TravelMgr_Patch; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey -{ - [HarmonyPatch(typeof(TravelStore))] - public static class TravelStore_Patch - { - [HarmonyPatch(nameof(TravelStore.Start))] - [HarmonyPostfix] - private static void Start(TravelStore __instance) - { - TranslateStoreText(__instance); - } - - [HarmonyPatch(nameof(TravelStore.Update))] - [HarmonyPostfix] - private static void Update(TravelStore __instance) - { - TranslateStoreText(__instance); - } - - [HarmonyPatch(nameof(TravelStore.RefreshBuff))] - [HarmonyPostfix] - private static void RefreshBuff(TravelStore __instance) - { - TranslateStoreText(__instance); - } - - [HarmonyPatch(nameof(TravelStore.SelectBuff))] - [HarmonyPostfix] - private static void SelectBuff(TravelStore __instance, ref TravelStoreWindow window) - { - TranslateStoreText(__instance); - - foreach (var text in window.buttonText) - { - text.text = StringStore.TranslateText(text.text); - } - - __instance.investText.text = TranslateInvestText(__instance.investText.text); - __instance.investTextshadow.text = TranslateInvestText(__instance.investTextshadow.text); - } - - public static void TranslateStoreText(TravelStore __instance) - { - __instance.investText.text = TranslateInvestText(__instance.investText.text); - __instance.investTextshadow.text = TranslateInvestText(__instance.investTextshadow.text); - - foreach (var text in __instance.pointText) - { - text.text = StringStore.TranslateText(text.text); - } - foreach (var text in __instance.refreshText) - { - text.text = StringStore.TranslateText(text.text); - } - foreach(var text in __instance.transform.Find("Quit").GetComponentsInChildren()) - { - text.text = StringStore.TranslateText("合上"); - } - } - - public static string TranslateInvestText(string investText) - { - string res = investText; - - if(!Utils.CheckForUntranslatedText(res)) - { - return res; - } - - string[] investStats = investText.Split("\n\n"); - List translatedInvestStats = new List(); - foreach(string investStat in investStats) - { - string[] lines = investStat.Split("\n"); - List translatedLines = new List(); - foreach(string line in lines) - { - translatedLines.Add(StringStore.TranslateColorText(line)); - } - string translatedInvestStat = String.Join("\n", translatedLines); - translatedInvestStats.Add(translatedInvestStat); - } - - res = String.Join("\n\n", translatedInvestStats); - - return res; - } - } -} diff --git a/MelonLoader/Patches/Modes/Odyssey/TravelSynergyMenu_Patch.cs b/MelonLoader/Patches/Modes/Odyssey/TravelSynergyMenu_Patch.cs deleted file mode 100644 index 4c1f8a0..0000000 --- a/MelonLoader/Patches/Modes/Odyssey/TravelSynergyMenu_Patch.cs +++ /dev/null @@ -1,107 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using static PvZ_Fusion_Translator.Patches.Modes.Odyssey.TravelMgr_Patch; -using UnityEngine; -using System.Text.RegularExpressions; - -namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey -{ - [HarmonyPatch(typeof(TravelSynergyMenu))] - public static class TravelSynergyMenu_Patch - { - [HarmonyPatch(nameof(TravelSynergyMenu.Awake))] - [HarmonyPostfix] - public static void Awake(TravelSynergyMenu __instance) - { - Transform background = __instance.transform.Find("Background"); - Transform tip = __instance.transform.Find("Text (TMP)"); - - foreach(TextMeshProUGUI text in background.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - - foreach (TextMeshProUGUI text in tip.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - } - - [HarmonyPatch(typeof(SynergyNode))] - public static class SynergyNode_Patch - { - [HarmonyPatch(nameof(SynergyNode.InitNode))] - [HarmonyPostfix] - public static void InitNode(SynergyNode __instance) - { - int firstNewlineIndex = __instance.synergyTitle.text.IndexOf("\n"); - string title = __instance.synergyTitle.text.Substring(0, firstNewlineIndex); - string description = __instance.synergyTitle.text.Substring(firstNewlineIndex + 1); - description = (description.Substring(0, 8) == "") ? description.Substring(8) : description; - - string pattern = @"]+>[\s\S]*?(?:<\/color>|$)|(?:<(?!color=)|[^<])+"; - string smallPattern = @"(]+>)(.*?)()"; - MatchCollection matches = Regex.Matches(description, pattern); - string translatedDescription = ""; - foreach(Match match in matches) - { - Match colorMatch = Regex.Match(match.Value, smallPattern, RegexOptions.Singleline); - if (colorMatch.Success) - { - translatedDescription += colorMatch.Groups[1].Value + TranslateSegment(colorMatch.Groups[2].Value) + colorMatch.Groups[3].Value; - } - else - { - translatedDescription += TranslateSegment(match.Value) + "\n"; - } - } - - __instance.synergyTitle.text = "" + StringStore.TranslateColorText(title) + "\n" + translatedDescription; - } - - public static string TranslateSegment(string text) - { - string res = ""; - - List parts = SplitSecondNewLines(text); - - foreach(string part in parts) - { - string temp = ""; - string[] lines = part.Split('\n'); - if(lines.Length > 1) - { - temp = StringStore.TranslateText(lines[0]) + "\n" + StringStore.TranslateText(lines[1]); - } - res += temp + "\n"; - } - return res.Substring(0, res.Length - 1); - } - - public static List SplitSecondNewLines(string originalText) - { - List results = new List(); - - string[] lines = originalText.Split('\n'); - for (int i = 0; i < lines.Length; i += 2) - { - string res = ""; - if(i + 1 < lines.Length) - { - res = lines[i] + "\n" + lines[i + 1]; - results.Add(res); - } - else - { - res = lines[i]; - results.Add(res); - } - } - - return results; - } - } -} diff --git a/MelonLoader/Patches/Modes/Starbound/AdvantureEvolutionMenu_Patch.cs b/MelonLoader/Patches/Modes/Starbound/AdvantureEvolutionMenu_Patch.cs deleted file mode 100644 index 0564ff5..0000000 --- a/MelonLoader/Patches/Modes/Starbound/AdvantureEvolutionMenu_Patch.cs +++ /dev/null @@ -1,77 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Modes.Starbound -{ - [HarmonyPatch(typeof(AdvantureEvolutionMenu))] - public static class AdvantureEvolutionMenu_Patch - { - [HarmonyPatch(nameof(AdvantureMenu.Awake))] - [HarmonyPostfix] - public static void Awake(AdvantureEvolutionMenu __instance) - { - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateColorText(text.text); - } - - Transform baseWindow = __instance.transform.Find("BaseWindow"); - Transform advancedWindow = __instance.transform.Find("AdvancedWindow"); - - if(baseWindow != null) - { - foreach(TextMeshProUGUI text in baseWindow.GetComponentsInChildren()) - { - if(text.gameObject.name.Contains("Name")) - { - text.text = Utils.GetPlantNameFromAlmanac(__instance.thePlantType); - } - } - } - - if (advancedWindow != null) - { - foreach (TextMeshProUGUI text in advancedWindow.GetComponentsInChildren()) - { - if (text.gameObject.name.Contains("Name")) - { - text.text = Utils.GetPlantNameFromAlmanac(__instance.thePlantType); - } - } - } - } - - [HarmonyPatch(nameof(AdvantureEvolutionMenu.UpdateText))] - [HarmonyPostfix] - public static void UpdateText(AdvantureEvolutionMenu __instance) - { - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateColorText(text.text); - } - } - - [HarmonyPatch(nameof(AdvantureEvolutionMenu.RollEvolution))] - [HarmonyPostfix] - public static void RollEvolution(AdvantureEvolutionMenu __instance) - { - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateColorText(text.text); - } - } - - [HarmonyPatch(nameof(AdvantureEvolutionMenu.RollEvolutionGood))] - [HarmonyPostfix] - public static void RollEvolutionGood(AdvantureEvolutionMenu __instance) - { - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateColorText(text.text); - } - } - } -} diff --git a/MelonLoader/Patches/Modes/Starbound/AdvantureHelpMenu_Patch.cs b/MelonLoader/Patches/Modes/Starbound/AdvantureHelpMenu_Patch.cs deleted file mode 100644 index 4f9751f..0000000 --- a/MelonLoader/Patches/Modes/Starbound/AdvantureHelpMenu_Patch.cs +++ /dev/null @@ -1,21 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; - -namespace PvZ_Fusion_Translator.Patches.Modes.Starbound -{ - [HarmonyPatch(typeof(AdvantureHelpMenu))] - public static class AdvantureHelpMenu_Patch - { - [HarmonyPatch(nameof(AdvantureHelpMenu.InitText))] - [HarmonyPostfix] - private static void InitText(AdvantureHelpMenu __instance) - { - foreach(TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - } -} diff --git a/MelonLoader/Patches/Modes/Starbound/AdvantureMenu2_Patch.cs b/MelonLoader/Patches/Modes/Starbound/AdvantureMenu2_Patch.cs deleted file mode 100644 index 46814ba..0000000 --- a/MelonLoader/Patches/Modes/Starbound/AdvantureMenu2_Patch.cs +++ /dev/null @@ -1,28 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; - -namespace PvZ_Fusion_Translator.Patches.Modes.Starbound -{ - [HarmonyPatch(typeof(AdvantureMenu2))] - public static class AdvantureMenu2_Patch - { - [HarmonyPatch(nameof(AdvantureMenu2.Awake))] - [HarmonyPostfix] - private static void Awake(AdvantureMenu2 __instance) - { - foreach(TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - - [HarmonyPatch(nameof(AdvantureMenu2.AdjustDifficulty))] - [HarmonyPostfix] - private static void AdjustDifficulty(AdvantureMenu2 __instance) - { - __instance.difficulty.text = StringStore.TranslateText(__instance.difficulty.text); - } - } -} diff --git a/MelonLoader/Patches/Modes/Starbound/AdvantureMenu_Patch.cs b/MelonLoader/Patches/Modes/Starbound/AdvantureMenu_Patch.cs deleted file mode 100644 index 91c593b..0000000 --- a/MelonLoader/Patches/Modes/Starbound/AdvantureMenu_Patch.cs +++ /dev/null @@ -1,64 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; - -namespace PvZ_Fusion_Translator.Patches.Modes.Starbound -{ - [HarmonyPatch(typeof(AdvantureMenu))] - public static class AdvantureMenu_Patch - { - [HarmonyPatch(nameof(AdvantureMenu.Start))] - [HarmonyPostfix] - private static void Start(AdvantureMenu __instance) - { - TranslateAdvantureMenu(__instance); - } - - [HarmonyPatch(nameof(AdvantureMenu.ChangeDifficulty))] - [HarmonyPostfix] - private static void ChangeDifficulty(AdvantureMenu __instance) - { - TranslateAdvantureMenu(__instance); - } - - [HarmonyPatch(nameof(AdvantureMenu.GetChapterDifficulty))] - [HarmonyPostfix] - private static void GetChapterDifficulty(AdvantureMenu __instance) - { - TranslateAdvantureMenu(__instance); - } - - [HarmonyPatch(nameof(AdvantureMenu.UpdateChapterDifficulty))] - [HarmonyPostfix] - private static void UpdateChapterDifficulty(AdvantureMenu __instance) - { - TranslateAdvantureMenu(__instance); - } - - [HarmonyPatch(nameof(AdvantureMenu.UpdateStarCount))] - [HarmonyPostfix] - private static void UpdateStarCount(AdvantureMenu __instance) - { - TranslateAdvantureMenu(__instance); - } - - public static void TranslateAdvantureMenu(AdvantureMenu __instance) - { - bool hasSBString = StringStore.translationString.ContainsKey(__instance.difficulty.text + "_SB"); - __instance.difficulty.text = Utils.RemoveSizeTags(hasSBString ? StringStore.TranslateText(__instance.difficulty.text + "_SB") : StringStore.TranslateText(__instance.difficulty.text)); - __instance.chapterDifficulty.text = StringStore.TranslateText(__instance.chapterDifficulty.text); - __instance.starCount.text = StringStore.TranslateText(__instance.starCount.text); - - foreach (TextMeshProUGUI text in __instance.title) - { - text.text = StringStore.TranslateText(text.text); - } - - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - } -} diff --git a/MelonLoader/Patches/Modes/Starbound/AdvantureMissionMenu_Patch.cs b/MelonLoader/Patches/Modes/Starbound/AdvantureMissionMenu_Patch.cs deleted file mode 100644 index 2aac117..0000000 --- a/MelonLoader/Patches/Modes/Starbound/AdvantureMissionMenu_Patch.cs +++ /dev/null @@ -1,56 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; - -namespace PvZ_Fusion_Translator.Patches.Modes.Starbound -{ - [HarmonyPatch(typeof(AdvantureMissionMenu))] - public static class AdvantureMissionMenu_Patch - { - [HarmonyPatch(nameof(AdvantureMissionMenu.Awake))] - [HarmonyPostfix] - private static void Awake(AdvantureMissionMenu __instance) - { - foreach (TextMeshProUGUI text in __instance.contant.GetComponentsInChildren()) - { - text.text = StringStore.TranslateColorText(text.text); - } - - //foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - //{ - // text.text = StringStore.TranslateText(text.text); - //} - } - - [HarmonyPatch(nameof(AdvantureMissionMenu.InitText))] - [HarmonyPostfix] - private static void InitText(AdvantureMissionMenu __instance) - { - foreach (TextMeshProUGUI text in __instance.contant.GetComponentsInChildren()) - { - text.text = StringStore.TranslateColorText(text.text); - } - - //foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - //{ - // text.text = StringStore.TranslateText(text.text); - //} - } - - [HarmonyPatch(nameof(AdvantureMissionMenu.SwitchAward))] - [HarmonyPostfix] - private static void SwitchAward(AdvantureMissionMenu __instance) - { - foreach(TextMeshProUGUI text in __instance.contant.GetComponentsInChildren()) - { - text.text = StringStore.TranslateColorText(text.text); - } - - //foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - //{ - // text.text = StringStore.TranslateText(text.text); - //} - } - } -} diff --git a/MelonLoader/Patches/Modes/Starbound/AdvantureStarMenu_Patch.cs b/MelonLoader/Patches/Modes/Starbound/AdvantureStarMenu_Patch.cs deleted file mode 100644 index 2b8c4b1..0000000 --- a/MelonLoader/Patches/Modes/Starbound/AdvantureStarMenu_Patch.cs +++ /dev/null @@ -1,61 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; - -namespace PvZ_Fusion_Translator.Patches.Modes.Starbound -{ - [HarmonyPatch(typeof(AdvantureStarMenu))] - public static class AdvantureStarMenu_Patch - { - [HarmonyPatch(nameof(AdvantureStarMenu.Awake))] - [HarmonyPostfix] - private static void Awake(AdvantureStarMenu __instance) - { - foreach(TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - - [HarmonyPatch(nameof(AdvantureStarMenu.GetNodes))] - [HarmonyPostfix] - private static void GetNodes(AdvantureStarMenu __instance) - { - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - - [HarmonyPatch(nameof(AdvantureStarMenu.UpdateStarText))] - [HarmonyPostfix] - private static void UpdateStarText(AdvantureStarMenu __instance) - { - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - - [HarmonyPatch(nameof(AdvantureStarMenu.InitTalents))] - [HarmonyPostfix] - private static void InitTalents(AdvantureStarMenu __instance) - { - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - - [HarmonyPatch(nameof(AdvantureStarMenu.ResetAward))] - [HarmonyPostfix] - private static void ResetAward(AdvantureStarMenu __instance) - { - foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) - { - text.text = StringStore.TranslateText(text.text); - } - } - } -} diff --git a/MelonLoader/Patches/Modes/Super Editor/CustomButton_enterGame_Patch.cs b/MelonLoader/Patches/Modes/Super Editor/CustomButton_enterGame_Patch.cs deleted file mode 100644 index a99986d..0000000 --- a/MelonLoader/Patches/Modes/Super Editor/CustomButton_enterGame_Patch.cs +++ /dev/null @@ -1,104 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppGameLevel; -using Il2CppGameLevel.EventNodes; -using PvZ_Fusion_Translator.AssetStore; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.Encodings.Web; -using System.Text.Json; -using System.Threading.Tasks; -using Unity.VisualScripting.FullSerializer; -using UnityEngine; -using UnityEngine.UIElements; - -namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor -{ - [HarmonyPatch(typeof(CustomButton_enterGame))] - public static class CustomButton_enterGame_Patch - { - [HarmonyPatch(nameof(CustomButton_enterGame.LoadOnlineLevelAsync))] - [HarmonyPostfix] - public static void LoadOnlineLevelAsync(CustomButton_enterGame __instance) - { - string dumpPath = Path.Combine(FileLoader.GetAssetDir(FileLoader.AssetType.Dumps), "custom_level_data.json"); - Dictionary dumpData = new Dictionary(); - - if (!File.Exists(dumpPath)) - { - File.WriteAllText(dumpPath, System.Text.Json.JsonSerializer.Serialize(dumpData, new JsonSerializerOptions - { - WriteIndented = true, - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping - })); - } - - dumpData = JsonSerializer.Deserialize>(File.ReadAllText(dumpPath)); - - string dumpStringsPath = Path.Combine(FileLoader.GetAssetDir(FileLoader.AssetType.Dumps), "custom_level_strings.json"); - Dictionary dumpStringsData = new Dictionary(); - - if (!File.Exists(dumpStringsPath)) - { - File.WriteAllText(dumpStringsPath, System.Text.Json.JsonSerializer.Serialize(dumpStringsData, new JsonSerializerOptions - { - WriteIndented = true, - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping - })); - } - - dumpStringsData = JsonSerializer.Deserialize>(File.ReadAllText(dumpStringsPath)); - - var level = __instance; - - if(level.onlineLevelInfo != null) - { - string levelId = level.onlineLevelInfo.levelId; - if(levelId != null) - { - SerializedLevelData serializedLevel = level.serializedLevel; - if(CustomLevelMenu_Patch.translatedLevelData.ContainsKey(levelId)) - { - TranslatedLevelData levelData = CustomLevelMenu_Patch.translatedLevelData[levelId]; - level.levelName.text = levelData.name; - serializedLevel.name = levelData.name; - serializedLevel.boardConfig.startTip = levelData.startTip; - } - else - { - TranslatedLevelData dumpedLevelData = new TranslatedLevelData(level.onlineLevelInfo.levelName, serializedLevel.boardConfig.startTip); - - if (dumpData.ContainsKey(levelId)) - { - dumpData[levelId] = dumpedLevelData; - } - else - { - dumpData.Add(levelId, dumpedLevelData); - } - } - - /*level.levelData.SerializedLevelData - foreach()*/ - } - } - else - { - level.levelName.text = StringStore.TranslateText(level.levelName.text); - } - - File.WriteAllText(dumpPath, System.Text.Json.JsonSerializer.Serialize(dumpData, new JsonSerializerOptions - { - WriteIndented = true, - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping - })); - File.WriteAllText(dumpStringsPath, System.Text.Json.JsonSerializer.Serialize(dumpStringsData, new JsonSerializerOptions - { - WriteIndented = true, - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping - })); - } - } -} \ No newline at end of file diff --git a/MelonLoader/Patches/Modes/Super Editor/CustomLevelMenu_Patch.cs b/MelonLoader/Patches/Modes/Super Editor/CustomLevelMenu_Patch.cs deleted file mode 100644 index 31eead2..0000000 --- a/MelonLoader/Patches/Modes/Super Editor/CustomLevelMenu_Patch.cs +++ /dev/null @@ -1,175 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppTMPro; -using MelonLoader; -using Newtonsoft.Json; -using PvZ_Fusion_Translator.AssetStore; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.Encodings.Web; -using System.Text.Json; -using System.Threading.Tasks; -using System.Threading.Tasks; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor -{ - [HarmonyPatch(typeof(CustomLevelMenu))] - public static class CustomLevelMenu_Patch - { - public static Dictionary translatedLevelData = new Dictionary(); - public static float requestTimer = 0f; - - [HarmonyPatch(nameof(CustomLevelMenu.LoadOnlineFiles))] - [HarmonyPostfix] - public static void LoadOnlineFiles(CustomLevelMenu __instance) - { - if (!Utils.useLocal) - { - LoadOnlineData(); - } - else - { - LoadLocalData(); - } - } - - [HarmonyPatch(nameof(CustomLevelMenu.InitLocalWindows))] - [HarmonyPostfix] - public static void InitWindows(CustomLevelMenu __instance) - { - TranslateLevelButtons(__instance); - } - - [HarmonyPatch(nameof(CustomLevelMenu.InitOnlineWindow))] - [HarmonyPostfix] - public static void InitOnlineWindow(CustomLevelMenu __instance) - { - TranslateLevelButtons(__instance); - } - - [HarmonyPatch(nameof(CustomLevelMenu.ReloadFiles))] - [HarmonyPostfix] - public static void ReloadFiles(CustomLevelMenu __instance) - { - TranslateLevelButtons(__instance); - } - - public static void TranslateLevelButtons(CustomLevelMenu __instance) - { - string dumpPath = Path.Combine(FileLoader.GetAssetDir(FileLoader.AssetType.Dumps), "custom_level_data.json"); - Dictionary dumpData = new Dictionary(); - - if (!File.Exists(dumpPath)) - { - File.WriteAllText(dumpPath, System.Text.Json.JsonSerializer.Serialize(dumpData, new JsonSerializerOptions - { - WriteIndented = true, - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping - })); - } - - foreach(CustomButton_enterGame level in __instance.levels) - { - if(level.onlineLevelInfo != null) - { - string levelId = level.onlineLevelInfo.levelId; - if(levelId != null) - { - if(translatedLevelData.ContainsKey(levelId)) - { - TranslatedLevelData levelData = translatedLevelData[levelId]; - level.levelName.text = levelData.name; - level.serializedLevel.name = levelData.name; - level.serializedLevel.boardConfig.startTip = levelData.startTip; - } - else - { - TranslatedLevelData dumpedLevelData = new TranslatedLevelData(level.onlineLevelInfo.levelName, level.serializedLevel.boardConfig.startTip); - dumpData.Add(levelId, dumpedLevelData); - } - } - } - else - { - level.levelName.text = StringStore.TranslateText(level.levelName.text); - } - } - - File.WriteAllText(dumpPath, System.Text.Json.JsonSerializer.Serialize(dumpData, new JsonSerializerOptions - { - WriteIndented = true, - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping - })); - } - - public static async System.Threading.Tasks.Task> GetTranslatedLevelData() - { - string levelDataString = Utils.GetDataFromWeb($"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language.ToString()}/Strings/custom_level_data.json").Result; - if(levelDataString != null) - { - Dictionary levelDataJson = JsonConvert.DeserializeObject>(levelDataString); - return levelDataJson; - } - else - { - new CancellationTokenSource().Cancel(); - return null; - } - } - - public static void LoadOnlineData() - { - if (requestTimer <= 0) - { - requestTimer = 5f; // 5 seconds in between request attempts to prevent any issues with github - - translatedLevelData = new Dictionary(); - - var translatedLevelDataRequest = System.Threading.Tasks.Task.Run(() => GetTranslatedLevelData()); - - if (translatedLevelDataRequest.Result != null) - { - translatedLevelData = translatedLevelDataRequest.Result; - Log.LogInfo($"Successfully loaded level data for {Utils.Language.ToString()}!"); - } - else - { - Log.LogError($"Couldn't find level data for {Utils.Language.ToString()}!"); - } - } - else - { - Log.LogInfo($"Please wait before requesting levels again! Current cooldown: {Math.Round(requestTimer, 3)}s"); - } - } - - public static void LoadLocalData() - { - translatedLevelData = new Dictionary(); - string assetDir = Path.Combine(FileLoader.GetAssetDir(FileLoader.AssetType.Strings, Utils.Language), "custom_level_data.json"); - if (!File.Exists(assetDir)) - { - File.CreateText(assetDir); - File.WriteAllText(assetDir, "{}"); - } - string levelDataString = File.ReadAllText(assetDir); - Dictionary levelDataJson = JsonConvert.DeserializeObject>(levelDataString); - translatedLevelData = levelDataJson; - } - } - - public class TranslatedLevelData - { - public string name { get; set; } - public string startTip { get; set; } - - public TranslatedLevelData(string name, string startTip) - { - this.name = name; - this.startTip = startTip; - } - } -} diff --git a/MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_event_Patch_B.cs b/MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_event_Patch_B.cs deleted file mode 100644 index b0cd093..0000000 --- a/MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_event_Patch_B.cs +++ /dev/null @@ -1,29 +0,0 @@ -/*using MelonLoader; -using HarmonyLib; -using UnityEngine; -using Il2Cpp; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using Il2CppGameLevel; -using PvZ_Fusion_Translator.Patches.Modes.Super_Editor.GameLevel.EventNodes; - -namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor -{ - [HarmonyPatch(typeof(CustomMenuPage_event))] - public static class CustomMenuPage_event_Patch - { - [HarmonyPatch(nameof(CustomMenuPage_event.InitializeNodeEditor))] - [HarmonyPostfix] - public static void InitializeNodeEditor(CustomMenuPage_event __instance) - { - RuntimeEventNodeEditor_Patch.Update(__instance.nodeEditor); - NodeInfoPanel_Patch.UpdatePanelContent(__instance.nodeInfoPanel); - } - } -} -*/ \ No newline at end of file diff --git a/MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_initZombies_Patch.cs b/MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_initZombies_Patch.cs deleted file mode 100644 index cc0df54..0000000 --- a/MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_initZombies_Patch.cs +++ /dev/null @@ -1,32 +0,0 @@ -using MelonLoader; -using HarmonyLib; -using UnityEngine; -using Il2Cpp; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; - -namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor -{ - [HarmonyPatch(typeof(CustomMenuPage_initZombies))] - public static class CustomMenuPage_initZombies_Patch - { - [HarmonyPatch(nameof(CustomMenuPage_initZombies.SubWave))] - [HarmonyPostfix] - public static void SubWave(CustomMenuPage_initZombies __instance) - { - __instance.currentWaveText.text = StringStore.TranslateText(__instance.currentWaveText.text); - } - - [HarmonyPatch(nameof(CustomMenuPage_initZombies.AddWave))] - [HarmonyPostfix] - public static void AddWave(CustomMenuPage_initZombies __instance) - { - __instance.currentWaveText.text = StringStore.TranslateText(__instance.currentWaveText.text); - } - } -} diff --git a/MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_page3_Patch.cs b/MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_page3_Patch.cs deleted file mode 100644 index 7b0d4dd..0000000 --- a/MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_page3_Patch.cs +++ /dev/null @@ -1,34 +0,0 @@ -using MelonLoader; -using HarmonyLib; -using UnityEngine; -using Il2Cpp; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; - -namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor -{ - [HarmonyPatch(typeof(CustomMenu_page3))] - public static class CustomMenuPage_page3_Patch - { - [HarmonyPatch(nameof(CustomMenu_page3.UpdateCardsText))] - [HarmonyPostfix] - public static void UpdateCardsText(CustomMenu_page3 __instance) - { - string plantName = Utils.GetPlantNameFromAlmanac(__instance.nameText.text); - __instance.nameText.text = (plantName != "") ? (plantName) : StringStore.TranslateText(__instance.nameText.text); - } - - [HarmonyPatch(nameof(CustomMenu_page3.UpdateAdvancedInfo))] - [HarmonyPostfix] - public static void UpdateAdvancedInfo(CustomMenu_page3 __instance) - { - string plantName = Utils.GetPlantNameFromAlmanac(__instance.nameText.text); - __instance.nameText.text = (plantName != "") ? (plantName) : StringStore.TranslateText(__instance.nameText.text); - } - } -} diff --git a/MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_shooting_Patch.cs b/MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_shooting_Patch.cs deleted file mode 100644 index a019938..0000000 --- a/MelonLoader/Patches/Modes/Super Editor/CustomMenuPage_shooting_Patch.cs +++ /dev/null @@ -1,65 +0,0 @@ -using MelonLoader; -using HarmonyLib; -using UnityEngine; -using Il2Cpp; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; - -namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor -{ - [HarmonyPatch(typeof(CustomMenuPage_shooting))] - public static class CustomMenuPage_shooting_Patch - { - [HarmonyPatch(nameof(CustomMenuPage_shooting.CreateRoute))] - [HarmonyPostfix] - public static void CreateRoute(CustomMenuPage_shooting __instance) - { - TranslateRoutes(__instance); - } - - [HarmonyPatch(nameof(CustomMenuPage_shooting.CreateStage))] - [HarmonyPostfix] - public static void CreateStage(CustomMenuPage_shooting __instance) - { - TranslateRoutes(__instance); - } - - [HarmonyPatch(nameof(CustomMenuPage_shooting.Awake))] - [HarmonyPostfix] - public static void Awake(CustomMenuPage_shooting __instance) - { - TranslateRoutes(__instance); - } - - [HarmonyPatch(nameof(CustomMenuPage_shooting.SearchRoute))] - [HarmonyPostfix] - public static void SearchRoute(CustomMenuPage_shooting __instance) - { - TranslateRoutes(__instance); - } - - [HarmonyPatch(nameof(CustomMenuPage_shooting.SearchAllRoute))] - [HarmonyPostfix] - public static void SearchAllRoute(CustomMenuPage_shooting __instance) - { - TranslateRoutes(__instance); - } - - public static void TranslateRoutes(CustomMenuPage_shooting __instance) - { - foreach(TextMeshProUGUI text in __instance.scollContent.GetComponentsInChildren()) - { - if (text.name == "PlantText") - { - string plantName = Utils.GetPlantNameFromAlmanac(text.text); - text.text = (plantName != "") ? plantName : StringStore.TranslateText(text.text); - } - } - } - } -} diff --git a/MelonLoader/Patches/Modes/Super Editor/CustomOnlineMenu_Patch.cs b/MelonLoader/Patches/Modes/Super Editor/CustomOnlineMenu_Patch.cs deleted file mode 100644 index 103d448..0000000 --- a/MelonLoader/Patches/Modes/Super Editor/CustomOnlineMenu_Patch.cs +++ /dev/null @@ -1,80 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppGameLevel; -using Il2CppTMPro; -using MelonLoader; -using PvZ_Fusion_Translator.AssetStore; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.Encodings.Web; -using System.Text.Json; -using System.Threading.Tasks; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor -{ - [HarmonyPatch(typeof(CustomOnlineMenu))] - public static class CustomOnlineMenu_Patch - { - [HarmonyPatch(nameof(CustomOnlineMenu.EditLevel))] - [HarmonyPostfix] - public static void EditLevel(CustomOnlineMenu __instance) - { - TranslateLevelName(__instance); - } - - [HarmonyPatch(nameof(CustomOnlineMenu.Start))] - [HarmonyPostfix] - public static void Start(CustomOnlineMenu __instance) - { - TranslateLevelName(__instance); - } - - public static void TranslateLevelName(CustomOnlineMenu __instance) - { - string translatedText = StringStore.TranslateText(__instance.title.text); - __instance.title.text = translatedText; - __instance.title2.text = translatedText; - - TranslateLevelData(__instance.levelData); - } - - public static void TranslateLevelData(CustomLevelData levelData) - { - Dictionary dumpData = new Dictionary(); - - if(levelData != null) - { - string levelId = levelData.levelId; - if(levelId != null) - { - if(CustomLevelMenu_Patch.translatedLevelData.ContainsKey(levelId)) - { - TranslatedLevelData translatedLevelData = CustomLevelMenu_Patch.translatedLevelData[levelId]; - levelData.Name = translatedLevelData.name; - levelData.SerializedLevelData.name = translatedLevelData.name; - levelData.SerializedLevelData.boardConfig.startTip = translatedLevelData.startTip; - } - else - { - TranslatedLevelData dumpedLevelData = new TranslatedLevelData(levelData.Name, levelData.SerializedLevelData.boardConfig.startTip); - dumpData.Add(levelId, dumpedLevelData); - } - } - } - else - { - levelData.Name = StringStore.TranslateText(levelData.Name); - } - - string dumpPath = Path.Combine(FileLoader.GetAssetDir(FileLoader.AssetType.Dumps), "custom_level_data.json"); - File.WriteAllText(dumpPath, System.Text.Json.JsonSerializer.Serialize(dumpData, new JsonSerializerOptions - { - WriteIndented = true, - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping - })); - } - } -} diff --git a/MelonLoader/Patches/Modes/Super Editor/GameLevel/EventNodes/RuntimeEventNodeEditor_Patch.cs b/MelonLoader/Patches/Modes/Super Editor/GameLevel/EventNodes/RuntimeEventNodeEditor_Patch.cs deleted file mode 100644 index 91d43fc..0000000 --- a/MelonLoader/Patches/Modes/Super Editor/GameLevel/EventNodes/RuntimeEventNodeEditor_Patch.cs +++ /dev/null @@ -1,49 +0,0 @@ -using HarmonyLib; -using Il2CppGameLevel.EventNodes; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using PvZ_Fusion_Translator.Patches.BaseTextObjects; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor.GameLevel.EventNodes -{ - [HarmonyPatch(typeof(RuntimeEventNodeEditor))] - public static class RuntimeEventNodeEditor_Patch - { - public static TMP_FontAsset fontAsset => FontStore.LoadTMPFont(Utils.Language.ToString()); - - [HarmonyPatch(nameof(RuntimeEventNodeEditor.Update))] - [HarmonyPostfix] - public static void Update(RuntimeEventNodeEditor __instance) - { - // translate the new screens (3.7) - TranslateFullTransform(__instance.nodeInfoPanel.transform); - TranslateFullTransform(__instance.attributePanel.transform); - TranslateFullTransform(__instance.canvas.transform); - if(__instance.TryGetComponent(out EventNodeContextMenu eventNodeContextMenu)) - { - TranslateFullTransform(eventNodeContextMenu.transform); - } - } - - public static void TranslateFullTransform(Transform transform) - { - if (transform == null) return; - - foreach(TextMeshProUGUI txt in transform.GetComponentsInChildren()) - { - txt.text = RuntimeNodeUI_Patch.TranslateCodeText(txt.text); - txt.font = fontAsset; - } - - foreach(TMP_InputField inputField in transform.GetComponentsInChildren()) - { - TMP_InputField_Patch.OnEnable(inputField); - foreach(TextMeshProUGUI txt in inputField.GetComponentsInChildren(true)) - { - txt.text = RuntimeNodeUI_Patch.TranslateCodeText(txt.text); - } - } - } - } -} diff --git a/MelonLoader/Patches/Modes/Super Editor/GameLevel/EventNodes/RuntimeNodeUI_Patch.cs b/MelonLoader/Patches/Modes/Super Editor/GameLevel/EventNodes/RuntimeNodeUI_Patch.cs deleted file mode 100644 index 540f243..0000000 --- a/MelonLoader/Patches/Modes/Super Editor/GameLevel/EventNodes/RuntimeNodeUI_Patch.cs +++ /dev/null @@ -1,143 +0,0 @@ -using HarmonyLib; -using Il2CppGameLevel.EventNodes; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using PvZ_Fusion_Translator.Patches.BaseTextObjects; - -namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor.GameLevel.EventNodes -{ - [HarmonyPatch(typeof(RuntimeNodeUI))] - public static class RuntimeNodeUI_Patch - { - [HarmonyPatch(nameof(RuntimeNodeUI.Awake))] - [HarmonyPatch(nameof(RuntimeNodeUI.CreatePorts))] - [HarmonyPatch(nameof(RuntimeNodeUI.CreateValueEditUI))] - [HarmonyPatch(nameof(RuntimeNodeUI.GetPortUI))] - [HarmonyPatch(nameof(RuntimeNodeUI.UpdateDisplay))] - [HarmonyPatch(nameof(RuntimeNodeUI.UpdateSelectionVisual))] - [HarmonyPatch(nameof(RuntimeNodeUI.UpdateVisable))] - [HarmonyPostfix] - public static void Post_UpdateDisplay(RuntimeNodeUI __instance) - { - if (!__instance.isActiveAndEnabled) return; - - if (__instance.Node == null) return; - - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - __instance.titleText.text = TranslateCodeText(__instance.titleText.text); - __instance.titleText.font = fontAsset; - - foreach(TextMeshProUGUI txt in __instance.inputPortsContainer.GetComponentsInChildren()) - { - txt.text = TranslateCodeText(txt.text); - txt.font = fontAsset; - } - - foreach(TextMeshProUGUI txt in __instance.outputPortsContainer.GetComponentsInChildren()) - { - txt.text = TranslateCodeText(txt.text); - txt.font = fontAsset; - } - - if ( - __instance.GetComponentsInChildren().Count == 0 - && __instance.GetComponentsInChildren().Count == 0 - && __instance.Node.nodeType != "PlantTypeValueNode" - && __instance.Node.nodeType != "SinglePlantTypeListNode" - && __instance.Node.nodeType != "ZombieTypeValueNode" - ) return; - - if (__instance.Node != null) - { - if(__instance.Node.nodeType == "PlantTypeValueNode") - { - foreach(TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - if(txt.gameObject.name.Contains("Label")) - { - if (Utils.CheckForUntranslatedText(txt.text)) - { - PlantTypeValueNode castedNode = __instance.Node.TryCast(); - if (castedNode != null) - { - string portName = castedNode.value_PortName; - string plantName = Utils.GetPlantNameFromAlmanac(castedNode.value, removeTags: true); - txt.text = (plantName != "") ? plantName : StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } - } - } - - if(__instance.Node.nodeType == "SinglePlantTypeListNode") - { - foreach(TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - if (txt.gameObject.name.Contains("Label")) - { - if (Utils.CheckForUntranslatedText(txt.text)) - { - SinglePlantTypeListNode castedNode = __instance.Node.TryCast(); - if (castedNode != null) - { - string portName = castedNode.plantTypeList_PortName; - string plantName = Utils.GetPlantNameFromAlmanac(castedNode.plantType, removeTags: true); - txt.text = (plantName != "") ? plantName : StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } - } - } - - if(__instance.Node.nodeType == "ZombieTypeValueNode") - { - foreach(TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - if(txt.gameObject.name.Contains("Label")) - { - if(Utils.CheckForUntranslatedText(txt.text)) - { - ZombieTypeValueNode castedNode = __instance.Node.TryCast(); - if(castedNode != null) - { - string portName = castedNode.value_PortName; - string zombieName = Utils.GetZombieNameFromAlmanac(castedNode.value, removeTags: true); - txt.text = (zombieName != "") ? zombieName : StringStore.TranslateText(txt.text); - txt.font = fontAsset; - } - } - } - } - } - } - - if(__instance.GetComponentsInChildren().Count > 0) - { - foreach(TMP_Dropdown dropdown in __instance.GetComponentsInChildren()) - { - TMP_Dropdown_Patch.CreateDropdownList(dropdown); - } - } - - if(__instance.GetComponentsInChildren().Count > 0) - { - foreach(TMP_InputField inputField in __instance.GetComponentsInChildren()) - { - TMP_InputField_Patch.OnEnable(inputField); - foreach(TextMeshProUGUI txt in inputField.GetComponentsInChildren(true)) - { - txt.text = TranslateCodeText(txt.text); - } - } - } - } - - public static string TranslateCodeText(string originalText) - { - return StringStore.translationString.ContainsKey(originalText + "_code") ? StringStore.TranslateText(originalText + "_code") : StringStore.TranslateText(originalText); - } - } -} diff --git a/MelonLoader/Patches/Modes/Super Editor/GameLevel/LevelManager_Patch.cs b/MelonLoader/Patches/Modes/Super Editor/GameLevel/LevelManager_Patch.cs deleted file mode 100644 index 57b919a..0000000 --- a/MelonLoader/Patches/Modes/Super Editor/GameLevel/LevelManager_Patch.cs +++ /dev/null @@ -1,280 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using Il2CppGameLevel; -using Il2CppGameLevel.EventNodes; -using MelonLoader; -using PvZ_Fusion_Translator.AssetStore; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.Encodings.Web; -using System.Text.Json; -using System.Threading.Tasks; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor.GameLevel -{ - [HarmonyPatch(typeof(LevelManager))] - public static class LevelManager_Patch - { - [HarmonyPatch(nameof(LevelManager.SaveLevelData))] - [HarmonyPrefix] - public static void Pre_SaveLevelData(LevelManager __instance, ref SerializedLevelData serializedLevelData) - { - if (serializedLevelData.name == "未命名关卡") - { - serializedLevelData.name = StringStore.translationString.ContainsKey("LEVEL_UNNAMED") ? StringStore.TranslateText("LEVEL_UNNAMED") : "Unnamed"; - } - } - - public static void ExportLevelStrings(SerializedLevelData serializedLevelData) - { - string levelDataString = JsonUtility.ToJson(serializedLevelData); - ReferenceLevelData referenceLevelData = Newtonsoft.Json.JsonConvert.DeserializeObject(levelDataString); - EventNodeGraph eventNodeGraph = serializedLevelData.eventNodeGraph; - eventNodeGraph.BuildCache(); - - List stringValueNodeIds = new List(); - List stringConcatNodeIds = new List(); - List showTextNodeIds = new List(); - List addOptionNodeIds = new List(); - - foreach (var reference in referenceLevelData.references.RefIds) - { - string nodeType = reference.data.nodeType; - string nodeId = reference.data.nodeId; - - if (nodeType == "ShowTextNode") - { - if(!showTextNodeIds.Contains(nodeId)) - { - showTextNodeIds.Add(nodeId); - } - } - else if (nodeType == "AddMultipleChoiceOptionNode") - { - if(!addOptionNodeIds.Contains(nodeId)) - { - addOptionNodeIds.Add(nodeId); - } - } - } - - foreach (var reference in referenceLevelData.references.RefIds) - { - string nodeType = reference.data.nodeType; - string nodeId = reference.data.nodeId; - - switch(nodeType) - { - case "StringValueNode": - case "FloatToStringNode": - case "StringConcatNode": - stringValueNodeIds.Add(nodeId); - if(nodeType == "StringConcatNode") - { - stringConcatNodeIds.Add(nodeId); - } - break; - default: - break; - } - } - - Dictionary> stringConcatNodePairs = new(); - - foreach(var connection in eventNodeGraph.connections) - { - string sourceNodeId = connection.sourceNodeId; - string sourcePortName = connection.sourcePortName; - string targetNodeId = connection.targetNodeId; - string targetPortName = connection.targetPortName; - - if(stringValueNodeIds.Contains(sourceNodeId)) - { - if(stringConcatNodeIds.Contains(targetNodeId)) - { - if(stringConcatNodePairs.ContainsKey(targetNodeId)) - { - ValueTuple temp = stringConcatNodePairs[targetNodeId]; - switch(targetPortName) - { - case "A": - temp.Item1 = sourceNodeId; - stringConcatNodePairs[targetNodeId] = temp; - break; - case "B": - temp.Item2 = sourceNodeId; - stringConcatNodePairs[targetNodeId] = temp; - break; - default: - break; - } - } - else - { - stringConcatNodePairs.Add(targetNodeId, new ValueTuple()); - ValueTuple temp = stringConcatNodePairs[targetNodeId]; - switch(targetPortName) - { - case "A": - temp.Item1 = sourceNodeId; - stringConcatNodePairs[targetNodeId] = temp; - break; - case "B": - temp.Item2 = sourceNodeId; - stringConcatNodePairs[targetNodeId] = temp; - break; - default: - break; - } - } - } - } - } - - string GetStringNodeValue(EventNodeBase eventNodeBase) - { - string stringValue = ""; - - switch(eventNodeBase.nodeType) - { - case "StringValueNode": - StringValueNode stringNode = eventNodeBase.TryCast(); - stringValue = stringNode.value; - break; - case "FloatToStringNode": - stringValue = "([^\\s]+)"; - break; - case "StringConcatNode": - StringConcatNode stringConcatNode = eventNodeBase.TryCast(); - stringConcatNode.InitializeConnections(eventNodeGraph); - stringValue = GetStringNodeValue(stringConcatNode.aSourceNode) + GetStringNodeValue(stringConcatNode.bSourceNode); - break; - default: - break; - } - - return stringValue; - } - - string baseDumpDir = FileLoader.GetAssetDir(FileLoader.AssetType.Dumps); - string levelDumpDir = Path.Combine(baseDumpDir, "CustomLevels.json"); - if (!File.Exists(levelDumpDir)) File.WriteAllText(levelDumpDir, "{}"); - Dictionary dump = JsonSerializer.Deserialize>(File.ReadAllText(levelDumpDir)); - - foreach(string showTextNodeId in showTextNodeIds) - { - ShowTextNode showTextNode = eventNodeGraph.GetNodeById(showTextNodeId).TryCast(); - showTextNode.InitializeConnections(eventNodeGraph); - string value = GetStringNodeValue(showTextNode.textSourceNode); - if (!dump.ContainsKey(value)) - { - dump.Add(value, value); - } - } - - foreach(string addOptionId in addOptionNodeIds) - { - AddMultipleChoiceOptionNode addOptionNode = eventNodeGraph.GetNodeById(addOptionId).TryCast(); - addOptionNode.InitializeConnections(eventNodeGraph); - string titleValue = GetStringNodeValue(addOptionNode.titleSourceNode); - if (!dump.ContainsKey(titleValue)) - { - dump.Add(titleValue, titleValue); - } - string descriptionValue = GetStringNodeValue(addOptionNode.descriptionSourceNode); - if (!dump.ContainsKey(descriptionValue)) - { - dump.Add(descriptionValue, descriptionValue); - } - } - - File.WriteAllText(levelDumpDir, JsonSerializer.Serialize(dump, new JsonSerializerOptions - { - WriteIndented = true, - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping - })); - } - - // reference level data classes - - public class ReferenceLevelData - { - public References references { get; set; } - } - - public class Data - { - public string nodeId { get; set; } - public string nodeType { get; set; } - public Position position { get; set; } - public string nodeName { get; set; } - public string plant_PortName { get; set; } - public string column_PortName { get; set; } - public string row_PortName { get; set; } - public string plantType_PortName { get; set; } - public object value { get; set; } - public string value_PortName { get; set; } - public string plantTypeA_PortName { get; set; } - public string plantTypeB_PortName { get; set; } - public string equal_PortName { get; set; } - public string trigger_PortName { get; set; } - public string count_PortName { get; set; } - public string output_PortName { get; set; } - public string index_PortName { get; set; } - public string plants_PortName { get; set; } - public string plantList_PortName { get; set; } - public string loopBody_PortName { get; set; } - public string currentPlant_PortName { get; set; } - public string currentIndex_PortName { get; set; } - public string onCompleted_PortName { get; set; } - public string condition_PortName { get; set; } - public string then_PortName { get; set; } - public string else_PortName { get; set; } - public string a_PortName { get; set; } - public string b_PortName { get; set; } - public string result_PortName { get; set; } - public string shouldReset_PortName { get; set; } - public string onCount_PortName { get; set; } - public int? startValue { get; set; } - public string valueA_PortName { get; set; } - public string valueB_PortName { get; set; } - public string greater_PortName { get; set; } - public string less_PortName { get; set; } - public string displayText { get; set; } - public double? duration { get; set; } - public string text_PortName { get; set; } - public string duration_PortName { get; set; } - public string int_PortName { get; set; } - public string float_PortName { get; set; } - } - - public class Position - { - public double x { get; set; } - public double y { get; set; } - } - - public class References - { - public int version { get; set; } - public List RefIds { get; set; } - } - - public class RefId - { - public int rid { get; set; } - public Type type { get; set; } - public Data data { get; set; } - } - - public class Type - { - public string @class { get; set; } - public string ns { get; set; } - public string asm { get; set; } - } - } -} diff --git a/MelonLoader/Patches/Modes/Super Editor/RhythmGame/RhythmGameChartEditorUI_Patch.cs b/MelonLoader/Patches/Modes/Super Editor/RhythmGame/RhythmGameChartEditorUI_Patch.cs deleted file mode 100644 index 1cd3db6..0000000 --- a/MelonLoader/Patches/Modes/Super Editor/RhythmGame/RhythmGameChartEditorUI_Patch.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Il2Cpp; -using Il2CppRhythmGameEditor; -using Il2CppRhythmGame; -using HarmonyLib; -using UnityEngine; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; - -namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor.RhythmGameEditor -{ - [HarmonyPatch(typeof(RhythmGameChartEditorUI))] - public static class RhythmGameChartEditorUI_Patch - { - [HarmonyPatch(nameof(RhythmGameChartEditorUI.Awake))] - [HarmonyPostfix] - public static void Awake(RhythmGameChartEditorUI __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - foreach(TextMeshProUGUI txt in __instance.GetComponentsInChildren()) - { - txt.font = fontAsset; - if (!Utils.CheckForUntranslatedText(txt.text)) continue; - txt.text = StringStore.TranslateText(txt.text); - } - - foreach(TextMeshProUGUI txt in __instance.dropdown.GetComponentsInChildren(true)) - { - txt.text = StringStore.TranslateText(txt.text); - } - } - - [HarmonyPatch(nameof(RhythmGameChartEditorUI.Start))] - [HarmonyPostfix] - public static void Start(RhythmGameChartEditorUI __instance) - { - Awake(__instance); - } - - [HarmonyPatch(nameof(RhythmGameChartEditorUI.InitializeSubSystems))] - [HarmonyPostfix] - public static void InitializeSubSystems(RhythmGameChartEditorUI __instance) - { - Awake(__instance); - } - - [HarmonyPatch(nameof(RhythmGameChartEditorUI.Update))] - [HarmonyPostfix] - public static void Update(RhythmGameChartEditorUI __instance) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - foreach(TextMeshProUGUI txt in __instance.transform.Find("TopPanel").GetComponentsInChildren()) - { - txt.font = fontAsset; - txt.text = StringStore.TranslateText(txt.text); - } - - foreach(TheButton btn in __instance.transform.GetComponentsInChildren()) - { - foreach(TextMeshProUGUI txt in btn.GetComponentsInChildren()) - { - if (!Utils.CheckForUntranslatedText(txt.text)) continue; - txt.text = StringStore.TranslateText(txt.text); - } - } - - foreach(TextMeshProUGUI txt in __instance.dropdown.GetComponentsInChildren(true)) - { - if (!Utils.CheckForUntranslatedText(txt.text)) continue; - txt.text = Utils.RemoveSizeTags(StringStore.TranslateText(txt.text)); - } - } - - [HarmonyPatch(nameof(RhythmGameChartEditorUI.UpdateUI))] - [HarmonyPostfix] - public static void UpdateUI(RhythmGameChartEditorUI __instance) - { - foreach(TextMeshProUGUI txt in __instance.dropdown.GetComponentsInChildren(true)) - { - txt.text = StringStore.TranslateText(txt.text); - } - } - - [HarmonyPatch(nameof(RhythmGameChartEditorUI.UpdateSelectedNoteInfo))] - [HarmonyPostfix] - public static void UpdateSelectedNoteInfo(RhythmGameChartEditorUI __instance) - { - __instance.selectedNoteInfoText.text = StringStore.TranslateText(__instance.selectedNoteInfoText.text); - } - } -} diff --git a/MelonLoader/Patches/Modes/Super Editor/RhythmGame/RhythmGameManager_Patch.cs b/MelonLoader/Patches/Modes/Super Editor/RhythmGame/RhythmGameManager_Patch.cs deleted file mode 100644 index e9e3eff..0000000 --- a/MelonLoader/Patches/Modes/Super Editor/RhythmGame/RhythmGameManager_Patch.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using HarmonyLib; -using Il2Cpp; -using Il2CppRhythmGame; -using Il2CppTMPro; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; - -namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor.RhythmGameEditor -{ - [HarmonyPatch(typeof(RhythmGameManager))] - public static class RhythmGameManager_Patch - { - [HarmonyPatch(nameof(RhythmGameManager.Awake))] - [HarmonyPatch(nameof(RhythmGameManager.ComboUpdate))] - [HarmonyPostfix] - public static void Awake(RhythmGameManager __instance) - { - if(__instance.comboText) - { - __instance.comboText.autoSizeTextContainer = false; - __instance.comboText.ForceMeshUpdate(); - } - } - - [HarmonyPatch(nameof(RhythmGameManager.OnNoteClicked))] - [HarmonyPostfix] - public static void OnNoteClicked(RhythmGameManager __instance) - { - if (!__instance.particle) return; - - TextParticle txtParticle = __instance.particle.GetComponent(); - if(txtParticle) - { - TextMeshPro txt = txtParticle.text.GetComponent(); - - if(txt) - { - string originalKey = StringStore.translationString.FirstOrDefault(x => x.Value == txt.text).Key; - txt.text = StringStore.translationString.ContainsKey(originalKey + "_RG") ? StringStore.TranslateText(originalKey + "_RG") : StringStore.TranslateText(txt.text); - txt.autoSizeTextContainer = false; - txt.ForceMeshUpdate(); - } - } - } - } -} diff --git a/MelonLoader/Patches/OtherManagers/AchievementClip_Patch.cs b/MelonLoader/Patches/OtherManagers/AchievementClip_Patch.cs deleted file mode 100644 index 3b295f4..0000000 --- a/MelonLoader/Patches/OtherManagers/AchievementClip_Patch.cs +++ /dev/null @@ -1,71 +0,0 @@ -/*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; - } - } -} -*/ \ No newline at end of file diff --git a/MelonLoader/Patches/OtherManagers/GardenUI_Patch.cs b/MelonLoader/Patches/OtherManagers/GardenUI_Patch.cs deleted file mode 100644 index 6219f62..0000000 --- a/MelonLoader/Patches/OtherManagers/GardenUI_Patch.cs +++ /dev/null @@ -1,22 +0,0 @@ -using HarmonyLib; -using Il2Cpp; -using PvZ_Fusion_Translator.AssetStore; -using UnityEngine; -using Il2CppZenGarden; - -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); - - // Transform PageText = __instance.transform.Find("PageText"); - // StringStore.TranslateTextTransform(PageText.transform); - } - } -} diff --git a/MelonLoader/Patches/OtherManagers/MenuText_Patch.cs b/MelonLoader/Patches/OtherManagers/MenuText_Patch.cs deleted file mode 100644 index be63d9f..0000000 --- a/MelonLoader/Patches/OtherManagers/MenuText_Patch.cs +++ /dev/null @@ -1,23 +0,0 @@ -#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/MelonLoader/Patches/OtherManagers/ThanksMenu_Patch.cs b/MelonLoader/Patches/OtherManagers/ThanksMenu_Patch.cs deleted file mode 100644 index 267a80b..0000000 --- a/MelonLoader/Patches/OtherManagers/ThanksMenu_Patch.cs +++ /dev/null @@ -1,23 +0,0 @@ -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/MelonLoader/PvZ Fusion Translator [MelonLoader].csproj b/MelonLoader/PvZ Fusion Translator [MelonLoader].csproj deleted file mode 100644 index 816e321..0000000 --- a/MelonLoader/PvZ Fusion Translator [MelonLoader].csproj +++ /dev/null @@ -1,596 +0,0 @@ - - - net6.0 - enable - disable - PvZ_Fusion_Translator - default - false - 1.0.0.0 - 1.0.0.0 - en-US - PvZ_Fusion_Translator - latest - enable - Debug;DebugEnglish;ReleaseMulti;ReleaseEnglish;DebugTesting;ReleaseOther;DebugObfuscate;ReleaseObfuscate - D:\PvZ Fusion\Game Files - AnyCPU;ARM64;x64 - - - - - - - - - - - - - - - - - - - - - - - $(GamePath)\Mods\AudioImportLib.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\Assembly-CSharp.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\Il2CppMono.Security.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\Il2Cppmscorlib.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\Il2CppSystem.Configuration.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\Il2CppSystem.Core.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\Il2CppSystem.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\Il2CppSystem.Xml.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\Il2Cpp__Generated.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\Unity.2D.Animation.Runtime.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\Unity.Burst.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\Unity.Burst.Unsafe.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\Unity.Collections.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\Unity.Collections.LowLevel.ILSupport.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\Unity.InternalAPIEngineBridge.001.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\Unity.Mathematics.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\Unity.RenderPipeline.Universal.ShaderLibrary.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\Unity.RenderPipelines.Core.Runtime.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\Unity.RenderPipelines.Universal.Runtime.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\Unity.TextMeshPro.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\Unity.VisualScripting.Core.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.AccessibilityModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.AIModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.AndroidJNIModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.AnimationModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.ARModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.AssetBundleModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.AudioModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.ClothModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.ContentLoadModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.CoreModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.CrashReportingModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.DirectorModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.DSPGraphModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.GameCenterModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.GIModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.GridModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.HotReloadModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.ImageConversionModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.IMGUIModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.InputLegacyModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.InputModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.JSONSerializeModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.LocalizationModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.ParticleSystemModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.PerformanceReportingModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.Physics2DModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.PhysicsModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.ProfilerModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.PropertiesModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.ScreenCaptureModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.SharedInternalsModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.SpriteMaskModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.SpriteShapeModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.StreamingModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.SubstanceModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.SubsystemsModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.TerrainModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.TerrainPhysicsModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.TextCoreFontEngineModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.TextCoreTextEngineModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.TextRenderingModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.TilemapModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.TLSModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.UI.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.UIElementsModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.UIModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.UmbraModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.UnityAnalyticsCommonModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.UnityAnalyticsModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.UnityConnectModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.UnityCurlModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.UnityTestProtocolModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.UnityWebRequestAssetBundleModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.UnityWebRequestAudioModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.UnityWebRequestModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.UnityWebRequestTextureModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.UnityWebRequestWWWModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.VehiclesModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.VFXModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.VideoModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.VRModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.WindModule.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\UnityEngine.XRModule.dll - - - $(GamePath)\MelonLoader\net6\MelonLoader.dll - - - $(GamePath)\MelonLoader\net6\0Harmony.dll - - - $(GamePath)\MelonLoader\net6\Il2CppInterop.Runtime.dll - - - $(GamePath)\MelonLoader\net6\Il2CppInterop.Common.dll - - - $(GamePath)\MelonLoader\Il2CppAssemblies\Il2CppCore.dll - - - - - - True - false - - - - $(DefineConstants);MULTI_LANGUAGE;CHEAT;DEBUG - - - - $(DefineConstants);MULTI_LANGUAGE;CHEAT;DEBUG;OBFUSCATE - - - - $(DefineConstants);MULTI_LANGUAGE;CHEAT;DEBUG - - - - $(DefineConstants);MULTI_LANGUAGE;CHEAT;DEBUG;OBFUSCATE - - - - $(DefineConstants);MULTI_LANGUAGE;CHEAT;DEBUG - - - - $(DefineConstants);MULTI_LANGUAGE;CHEAT;DEBUG;OBFUSCATE - - - - $(DefineConstants);MULTI_LANGUAGE;CHEAT;TESTING;DEBUG - - - - $(DefineConstants);MULTI_LANGUAGE;CHEAT;TESTING;DEBUG - - - - $(DefineConstants);MULTI_LANGUAGE;CHEAT;TESTING;DEBUG - - - - $(DefineConstants);CHEAT;DEBUG - - - - $(DefineConstants);CHEAT;DEBUG - - - - $(DefineConstants);CHEAT;DEBUG - - - - $(DefineConstants);MULTI_LANGUAGE;OBFUSCATE - - - - $(DefineConstants);MULTI_LANGUAGE;OBFUSCATE - - - - $(DefineConstants);MULTI_LANGUAGE;OBFUSCATE - - - - $(DefineConstants);OTHER;OBFUSCATE - - - - $(DefineConstants);OTHER;OBFUSCATE - - - - $(DefineConstants);OTHER;OBFUSCATE - - - - $(DefineConstants);MULTI_LANGUAGE;OBFUSCATE;RELEASE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MelonLoader/Utils.cs b/MelonLoader/Utils.cs deleted file mode 100644 index 375a205..0000000 --- a/MelonLoader/Utils.cs +++ /dev/null @@ -1,704 +0,0 @@ -using Harmony; -using Il2Cpp; -using Il2CppTMPro; -using MelonLoader; -using MelonLoader.TinyJSON; -using Newtonsoft.Json; -using PvZ_Fusion_Translator.AssetStore; -using PvZ_Fusion_Translator.Patches.GameObjects; -using PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects; -using PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects; -using PvZ_Fusion_Translator.Patches.Modes.Super_Editor; -using System.Diagnostics; -using System.Reflection; -using System.Text.RegularExpressions; -using Unity.Burst.Intrinsics; -using UnityEngine; -using UnityEngine.Events; -using UnityEngine.Experimental.Rendering; -using UnityEngine.UI; -using static MelonLoader.MelonLogger; -using static PvZ_Fusion_Translator.FileLoader; - -namespace PvZ_Fusion_Translator -{ - public class Utils - { - internal static bool TryReplaceTexture2D(Texture2D ogTexture) - { - if (ogTexture != null) - { - if (TextureStore.textureDict.TryGetValue(ogTexture.name, out byte[] textureData)) - { - try - { - ImageConversion.LoadImage(ogTexture, textureData); - - 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); - 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; - } - - internal static Texture2D LoadImage(byte[] bytes) - { - if (bytes == null) - { - throw new FileNotFoundException($"Byte array was null."); - } - - byte[] array = bytes; - 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 OpenOnlineAlmanac() - { - string website = "https://carroti4ch.itch.io/almanac"; - Process.Start(new ProcessStartInfo(website) { UseShellExecute = true }); - } - - public static string RemoveColorTags(string text) - { - if (string.IsNullOrEmpty(text)) - return text ?? string.Empty; - - // Remove opening color tags like - string withoutOpenTags = Regex.Replace(text, @"]+>", string.Empty, RegexOptions.IgnoreCase); - // Remove closing color tags like - string withoutCloseTags = Regex.Replace(withoutOpenTags, @"", string.Empty, RegexOptions.IgnoreCase); - return withoutCloseTags; - } - - public static string RemoveSizeTags(string text) - { - if (string.IsNullOrEmpty(text)) - return text ?? string.Empty; - - // Remove opening size tags like - string withoutOpenTags = Regex.Replace(text, @"]+>", string.Empty, RegexOptions.IgnoreCase); - // Remove closing size tags like - string withoutCloseTags = Regex.Replace(withoutOpenTags, @"", string.Empty, RegexOptions.IgnoreCase); - return withoutCloseTags; - } - - public static string RemoveFormatTags(string text) - { - if (string.IsNullOrEmpty(text)) - return text ?? string.Empty; - - string withoutUnderlineTags = Regex.Replace(text, @"", string.Empty, RegexOptions.IgnoreCase); - string withoutUnderlineCloseTags = Regex.Replace(withoutUnderlineTags, @"", string.Empty, RegexOptions.IgnoreCase); - string withoutItalicTags = Regex.Replace(withoutUnderlineCloseTags, @"", string.Empty, RegexOptions.IgnoreCase); - string withoutItalicCloseTags = Regex.Replace(withoutItalicTags, @"", string.Empty, RegexOptions.IgnoreCase); - - return withoutItalicCloseTags; - } - - public static string RemoveAllTags(string text) - { - if (string.IsNullOrEmpty(text)) - return text ?? string.Empty; - - return RemoveColorTags(RemoveSizeTags(RemoveFormatTags(text))); - } - - public static GameObject ConvertToTextMeshProUGUI(GameObject originalText, Transform parent, string name) - { - GameObject newObj = new GameObject(name); - newObj.transform.position = originalText.transform.position; - newObj.AddComponent(); - newObj.AddComponent(); - newObj.AddComponent(); - newObj.transform.SetParent(parent); - newObj.transform.localScale = Vector3.one; - - UnityEngine.Object.Destroy(originalText); - return newObj; - } - - public static void ConvertButtonText(Transform original, string name) - { - TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); - - Transform transform = original.FindChild(name); - Transform textTransform = transform.FindChild("text"); - string text = textTransform.GetComponent().text; - Color color = textTransform.GetComponent().color; - - TextMeshProUGUI newGoBackText = Utils.ConvertToTextMeshProUGUI(textTransform.gameObject, transform, "text2").GetComponent(); - newGoBackText.autoSizeTextContainer = true; - newGoBackText.text = StringStore.TranslateText(text, false); - newGoBackText.font = fontAsset; - newGoBackText.color = color; - } - - public static string GetPlantNameFromAlmanac(PlantType thePlantType, bool removeTags = false, bool log = false) - { - bool foundPlantName = false; - string thePlantName = ""; - - if(plantIndices.ContainsKey((int)thePlantType)) - { - foundPlantName = true; - thePlantName = plantIndices[(int)thePlantType].Value; - } - - if (!foundPlantName) - { - if(log) - { - Log.LogInfo("Couldn't find plant name!"); - } - thePlantName = ""; - } - - thePlantName = (removeTags) ? RemoveAllTags(thePlantName) : thePlantName; - - return thePlantName; - } - - public static string GetPlantNameFromAlmanac(string theOriginalPlantName, bool removeTags = false, bool log = false) - { - bool foundPlantName = false; - string thePlantName = ""; - - if(plantIndiceString.ContainsKey(theOriginalPlantName)) - { - foundPlantName = true; - thePlantName = plantIndiceString[theOriginalPlantName]; - } - - if (!foundPlantName) - { - if(log) - { - Log.LogInfo("Couldn't find plant name!"); - } - thePlantName = ""; - } - - thePlantName = (removeTags) ? RemoveAllTags(thePlantName) : thePlantName; - - return thePlantName; - } - - public static string GetZombieNameFromAlmanac(ZombieType theZombieType, bool removeTags = false) - { - string json; - string theZombieName = ""; - - string currentLanguage = Utils.Language.ToString(); - - json = AlmanacZombieMenu_Patch.almanacJson; - Il2CppAlmanacData.AlmanacData zombieData = JsonUtility.FromJson(json); - - foreach (Il2CppAlmanacData.ZombieInfo zombieInfo in zombieData.zombies) - { - if ((int)zombieInfo.theZombieType == (int)theZombieType) - { - theZombieName = zombieInfo.name; - } - } - - theZombieName = (removeTags) ? RemoveAllTags(theZombieName) : theZombieName; - - return theZombieName; - } - - public static Dictionary> plantIndices = new Dictionary>(); - public static Dictionary plantIndiceString = new Dictionary(); - - public static void RegisterPlantIndices() - { - plantIndices = new Dictionary>(); - plantIndiceString = new Dictionary(); - string originalJson; - string translatedJson; - - string currentLanguage = Utils.Language.ToString(); - string almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); - string dumpDir = GetAssetDir(AssetType.Dumps); - string originalPath = Path.Combine(dumpDir, "LawnStrings.json"); - string path = Path.Combine(almanacDir, "LawnStringsTranslate.json"); - - if ((!File.Exists(originalPath))) - { - Log.LogError($"LawnStrings.json file not found at path: {originalPath}"); - } - else - { - try - { - originalJson = File.ReadAllText(originalPath); - translatedJson = AlmanacPlantMenu_Patch.almanacJson; - Il2CppAlmanacData.AlmanacData originalPlantData = JsonUtility.FromJson(originalJson); - Il2CppAlmanacData.AlmanacData translatedPlantData = JsonUtility.FromJson(translatedJson); - - foreach (Il2CppAlmanacData.PlantInfo originalPlantInfo in originalPlantData.plants) - { - if(!plantIndiceString.ContainsKey(originalPlantInfo.name)) - { - plantIndiceString.Add(originalPlantInfo.name, originalPlantInfo.name); - } - Il2CppAlmanacData.PlantInfo translatedPlantInfo = null; - - foreach (Il2CppAlmanacData.PlantInfo info in translatedPlantData.plants) - { - if (info.seedType == originalPlantInfo.seedType) - { - translatedPlantInfo = info; - } - } - - if (translatedPlantInfo != null) - { - if(translatedPlantInfo.name != null) - { - KeyValuePair temp = new KeyValuePair(translatedPlantInfo.seedType, translatedPlantInfo.name); - plantIndices.Add(originalPlantInfo.seedType, temp); - plantIndiceString[originalPlantInfo.name] = translatedPlantInfo.name; - } - } - } - } - catch (Exception e) - { - Log.LogError(e); - } - } - } - - public static void TryAdd(Dictionary dict, A key, B val) - { - if (dict.ContainsKey(key)) - { - dict[key] = val; - } - else - { - dict.Add(key, val); - } - } - - public static void TryAdd(SortedDictionary dict, A key, B val) - { - if (dict.ContainsKey(key)) - { - dict[key] = val; - } - else - { - dict.Add(key, val); - } - } - - public static AssetBundle GetAssetBundle(Assembly assembly, string assetBundlePath, bool log = false) - { - try - { - if (assembly != null) - { - Stream manifestResourceStream = assembly.GetManifestResourceStream($"PvZ_Fusion_Translator.Resources.{assetBundlePath}"); - using (manifestResourceStream) - { - if (manifestResourceStream == null) - { - throw new Exception("Stream was null."); - } - - byte[] array = new byte[manifestResourceStream.Length]; - manifestResourceStream.Read(array, 0, array.Length); - AssetBundle assetBundle = AssetBundle.LoadFromMemory(array); - ArgumentNullException.ThrowIfNull(assetBundle, "assetBundle"); - if(log) - { - Log.LogDebug($"AssetBundle {assetBundlePath} has successfully been loaded."); - } - return assetBundle; - } - } - - throw new Exception($"AssetBundle {assetBundlePath} was null."); - } - catch (Exception value) - { - throw new ArgumentException($"Failed to load {assetBundlePath}. \n{value}"); - } - } - - public static AssetBundle GetAssetBundle(string path) - { - AssetBundle assetBundle = AssetBundle.LoadFromFile(path); - return assetBundle; - } - - /*public static Dictionary> recipeLinks = new Dictionary>(); - - public static void RegisterRecipeLinks() - { - recipeLinks.Clear(); - - Il2CppSystem.Array mixData = MixData.data.Cast(); - int rows = mixData.GetLength(0); - int columns = mixData.GetLength(1); - - foreach (PlantType plantType in Enum.GetValues(typeof(PlantType))) - { - int seedType = (int)plantType; - - recipeLinks.Add(seedType, new()); - - if (seedType > 0) - { - foreach (PlantType checkType in Enum.GetValues(typeof(PlantType))) - { - if (checkType > 0) - { - int[] checks = [mixData.GetValue(seedType, (int)checkType).Unbox(), mixData.GetValue((int)checkType, seedType).Unbox()]; - - if (checks[0] != 0) - { - recipeLinks[seedType].Add(checks[0]); - } - - if (checks[1] != 0) - { - recipeLinks[seedType].Add(checks[1]); - } - } - } - } - if (recipeLinks[seedType].Count > 0) - { - Log.LogDebug($"Found {recipeLinks[seedType].Count} fusions for {seedType}!"); - } - } - }*/ - - public static Regex untranslatedRegex = new("\\p{IsCJKUnifiedIdeographs}+"); - - public static bool CheckForUntranslatedText(string text) - { - try - { - Match match = untranslatedRegex.Match(text); - return match.Success; - } - catch(Exception e) - { - Log.LogError(e); - } - return false; - } - - public static bool useLocal = MelonPreferences.GetEntryValue("PvZ_Fusion_Translator", "UseLocal"); - - public static void WarnLocalData() - { - BaseMenu newMenu = GameAPP.UIManager.Push(UIType.ConfirmMenu, GameAPP.canvasUp); - ConfirmMenu confirmMenu = newMenu.gameObject.GetComponent(); - - string modeTo = (Utils.useLocal) ? "online mode" : "local mode"; - confirmMenu.SetTitle($"WARNING: This button is meant for translator testing and can overwrite/interfere with the translation files saved in your installation. Proceed with caution. You are switching to {modeTo}.\nOnline Mode: Default, strings will auto-sync with the latest version when opening the game\nLocal Mode: Strings are only loaded from your installaion and do not update (meant for translators)"); - confirmMenu.transform.Find("window/text").GetComponent().text = Utils.RemoveColorTags(confirmMenu.transform.Find("window/text").GetComponent().text); - UIButton confirmButton = confirmMenu.transform.Find("Image").GetComponent(); - UIButton cancelButton = confirmMenu.transform.Find("Image2").GetComponent(); - - confirmButton.clickEvent = new UnityEvent(); - confirmButton.clickEvent.AddListener(new Action(() => SwapLocalData())); - confirmButton.clickEvent.AddListener(new Action(() => CursorChange.SetDefaultCursor())); - confirmButton.clickEvent.AddListener(new Action(() => GameAPP.UIManager.Pop())); - } - - public static void SwapLocalData() - { - Utils.useLocal = (Utils.useLocal) ? false : true; - MelonPreferences.SetEntryValue("PvZ_Fusion_Translator", "UseLocal", Utils.useLocal); - ChangeLanguage(Utils.Language.ToString()); - string sourceMsg = "" + (!(Utils.useLocal) ? "Translation Source:\nOnline" : "Translation Source:\nLocal"); - OptLanguageBtn_Patch.FlashMessage(OptLanguageBtn_Patch.toggleSlots[2], sourceMsg, 0.1f, false); - CursorChange.SetDefaultCursor(); - } - - public static async Task GetDataFromWeb(string url, bool isLog = true) - { - if (isLog) - { - Log.LogInfo($"Attempting to read {url}"); - } - HttpClient client = new HttpClient(); - try - { - var dataRequest = await client.GetAsync(url); - if(dataRequest.StatusCode == System.Net.HttpStatusCode.OK) - { - if (isLog) - { - Log.LogInfo($"Successfully loaded data from {url}!"); - } - - string content = await dataRequest.Content.ReadAsStringAsync(); - return content; - } - else - { - if (isLog) - { - Log.LogError($"Failed to load data from {url}! Falling back..."); - Log.LogError($"Status code: {dataRequest.StatusCode}"); - } - new CancellationTokenSource().Cancel(); - return null; - } - } - catch(Exception ex) - { - Log.LogError($"Failed to load data from {url}! Falling back..."); - Log.LogError(ex); - new CancellationTokenSource().Cancel(); - return null; - } - } - - public static async Task GetByteDataFromWeb(string url, bool isLog = true) - { - if (isLog) - { - Log.LogInfo($"Attempting to read {url}"); - } - HttpClient client = new HttpClient(); - try - { - var dataRequest = await client.GetAsync(url); - if (dataRequest.StatusCode == System.Net.HttpStatusCode.OK) - { - if (isLog) - { - Log.LogInfo($"Successfully loaded data from {url}!"); - } - - byte[] content = await dataRequest.Content.ReadAsByteArrayAsync(); - return content; - } - else - { - if (isLog) - { - Log.LogError($"Failed to load data from {url}! Falling back..."); - Log.LogError($"Status code: {dataRequest.StatusCode}"); - } - new CancellationTokenSource().Cancel(); - return null; - } - } - catch(Exception ex) - { - Log.LogError($"Failed to load data from {url}! Falling back..."); - Log.LogError(ex); - new CancellationTokenSource().Cancel(); - return null; - } - } - - public static async Task GetDataFromWebWithInput(string url, bool isLog = true) - { - if (isLog) - { - Log.LogInfo($"Attempting to read {url}"); - } - HttpClient client = new HttpClient(); - - using var request = new HttpRequestMessage() - { - Method = HttpMethod.Get, - RequestUri = new Uri(url) - }; - request.Headers.Add("Accept", "*/*"); - request.Headers.Add("Accept-Encoding", "gzip, deflate, br"); - request.Headers.Add("User-Agent", "TranslatorMod"); - - - var dataRequest = await client.SendAsync(request); - if(dataRequest.StatusCode == System.Net.HttpStatusCode.OK) - { - if (isLog) - { - Log.LogInfo($"Successfully loaded data from {url}!"); - } - - string content = await dataRequest.Content.ReadAsStringAsync(); - return content; - } - else - { - if (isLog) - { - Log.LogError($"Failed to load data from {url}! Falling back..."); - Log.LogError($"Status code: {dataRequest.StatusCode}"); - } - new CancellationTokenSource().Cancel(); - return null; - } - } - - public static int CalculateGameVersion(string gameVersion) - { - int res = 0; - string[] gameVersionParts = gameVersion.Split('.'); - - int startingPower = (int)Math.Max(gameVersionParts.Length, 3); - for (int i = 0; i < startingPower; i++) - { - int factor = 0; - if (i < gameVersionParts.Length) - { - factor = int.Parse(gameVersionParts[i]); - } - int power = startingPower - i; - res += factor * (int)Math.Pow(10, power - 1); - } - - return res; - } - - #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(); - RegisterPlantIndices(); - Zombie_Patch.LoadHPStrings(); - } - #endif - - #if MULTI_LANGUAGE - public static Utils.LanguageEnum OldLanguage; - #endif - - public static Utils.LanguageEnum Language; - - public static bool customTextures = !MelonPreferences.GetEntryValue("PvZ_Fusion_Translator", "DefaultTextures"); - public static bool customAudio = !MelonPreferences.GetEntryValue("PvZ_Fusion_Translator", "DefaultAudio"); - - public enum LanguageEnum - { - // first column - English, - Chinese_cn, - French, - //Italian, - German, - Spanish, - - - // second column - //Portuguese, - //Javanese, - //Filipino, - Vietnamese, - Indonesian, - //Russian, //NOTE: legacy language - Japanese, - - - // third column - Korean, - Ukrainian, - // Slovak, - //Polish, - //Turkish, - Arabic, - Romanian, - - LANG_END - } - - public static Dictionary LanguageNames = new Dictionary() - { - { LanguageEnum.English, "English"}, - { LanguageEnum.Chinese_cn, "简体中文"}, - { LanguageEnum.French, "Français"}, - { LanguageEnum.German, "Deutsch"}, - { LanguageEnum.Spanish, "Español"}, - { LanguageEnum.Vietnamese, "Tiếng Việt"}, - { LanguageEnum.Indonesian, "Bahasa Indonesia"}, - { LanguageEnum.Japanese, "日本語"}, - { LanguageEnum.Korean, "한국어"}, - { LanguageEnum.Ukrainian, "українська"}, - { LanguageEnum.Arabic, "ﺔﻴﺑﺮﻌﻟا"}, - { LanguageEnum.Romanian, "Română"} - }; - - public static Dictionary ToggleNames = new Dictionary() - { - { ToggleEnum.Textures, "Change Texture\nSource"}, - { ToggleEnum.Audio, "Change Audio\nSource"}, - { ToggleEnum.SwapLocal, "Change Translation\nSource"} - }; - - public enum ToggleEnum - { - Textures, - Audio, - SwapLocal, - TOGGLE_END - } - } -} \ No newline at end of file diff --git a/PvZ Fusion Translator.sln b/PvZ Fusion Translator.sln deleted file mode 100644 index 7b38d36..0000000 --- a/PvZ Fusion Translator.sln +++ /dev/null @@ -1,146 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 18 -VisualStudioVersion = 18.7.11911.148 stable -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}" - ProjectSection(SolutionItems) = preProject - README.md = README.md - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PvZ Fusion Translator [BepInEx]", "BepInEx\PvZ Fusion Translator [BepInEx].csproj", "{395E60A0-A884-61F2-EF18-BC94BB7D9C69}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PvZ Fusion Translator [MelonLoader]", "MelonLoader\PvZ Fusion Translator [MelonLoader].csproj", "{A058E167-7411-D3CA-0C9F-40F030C12860}" -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 - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.Debug|Any CPU.Build.0 = Debug|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.Debug|ARM64.Build.0 = Debug|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.Debug|x64.ActiveCfg = Debug|x64 - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.Debug|x64.Build.0 = Debug|x64 - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugEnglish|Any CPU.ActiveCfg = DebugEnglish|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugEnglish|Any CPU.Build.0 = DebugEnglish|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugEnglish|ARM64.ActiveCfg = DebugEnglish|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugEnglish|ARM64.Build.0 = DebugEnglish|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugEnglish|x64.ActiveCfg = DebugEnglish|x64 - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugEnglish|x64.Build.0 = DebugEnglish|x64 - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugObfuscate|Any CPU.ActiveCfg = DebugObfuscate|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugObfuscate|Any CPU.Build.0 = DebugObfuscate|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugObfuscate|ARM64.ActiveCfg = DebugObfuscate|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugObfuscate|ARM64.Build.0 = DebugObfuscate|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugObfuscate|x64.ActiveCfg = DebugObfuscate|x64 - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugObfuscate|x64.Build.0 = DebugObfuscate|x64 - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugTesting|Any CPU.ActiveCfg = DebugTesting|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugTesting|Any CPU.Build.0 = DebugTesting|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugTesting|ARM64.ActiveCfg = DebugTesting|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugTesting|ARM64.Build.0 = DebugTesting|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugTesting|x64.ActiveCfg = DebugTesting|x64 - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.DebugTesting|x64.Build.0 = DebugTesting|x64 - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseEnglish|Any CPU.ActiveCfg = ReleaseEnglish|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseEnglish|Any CPU.Build.0 = ReleaseEnglish|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseEnglish|ARM64.ActiveCfg = ReleaseEnglish|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseEnglish|ARM64.Build.0 = ReleaseEnglish|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseEnglish|x64.ActiveCfg = ReleaseEnglish|x64 - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseEnglish|x64.Build.0 = ReleaseEnglish|x64 - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseMulti|Any CPU.ActiveCfg = ReleaseMulti|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseMulti|Any CPU.Build.0 = ReleaseMulti|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseMulti|ARM64.ActiveCfg = ReleaseMulti|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseMulti|ARM64.Build.0 = ReleaseMulti|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseMulti|x64.ActiveCfg = ReleaseMulti|x64 - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseMulti|x64.Build.0 = ReleaseMulti|x64 - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseObfuscate|Any CPU.ActiveCfg = ReleaseObfuscate|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseObfuscate|Any CPU.Build.0 = ReleaseObfuscate|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseObfuscate|ARM64.ActiveCfg = ReleaseObfuscate|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseObfuscate|ARM64.Build.0 = ReleaseObfuscate|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseObfuscate|x64.ActiveCfg = ReleaseObfuscate|x64 - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseObfuscate|x64.Build.0 = ReleaseObfuscate|x64 - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseOther|Any CPU.ActiveCfg = ReleaseOther|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseOther|Any CPU.Build.0 = ReleaseOther|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseOther|ARM64.ActiveCfg = ReleaseOther|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseOther|ARM64.Build.0 = ReleaseOther|Any CPU - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseOther|x64.ActiveCfg = ReleaseOther|x64 - {395E60A0-A884-61F2-EF18-BC94BB7D9C69}.ReleaseOther|x64.Build.0 = ReleaseOther|x64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A058E167-7411-D3CA-0C9F-40F030C12860}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A058E167-7411-D3CA-0C9F-40F030C12860}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.Debug|ARM64.Build.0 = Debug|ARM64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.Debug|x64.ActiveCfg = Debug|x64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.Debug|x64.Build.0 = Debug|x64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.DebugEnglish|Any CPU.ActiveCfg = DebugEnglish|Any CPU - {A058E167-7411-D3CA-0C9F-40F030C12860}.DebugEnglish|Any CPU.Build.0 = DebugEnglish|Any CPU - {A058E167-7411-D3CA-0C9F-40F030C12860}.DebugEnglish|ARM64.ActiveCfg = DebugEnglish|ARM64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.DebugEnglish|ARM64.Build.0 = DebugEnglish|ARM64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.DebugEnglish|x64.ActiveCfg = DebugEnglish|x64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.DebugEnglish|x64.Build.0 = DebugEnglish|x64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.DebugObfuscate|Any CPU.ActiveCfg = DebugObfuscate|Any CPU - {A058E167-7411-D3CA-0C9F-40F030C12860}.DebugObfuscate|Any CPU.Build.0 = DebugObfuscate|Any CPU - {A058E167-7411-D3CA-0C9F-40F030C12860}.DebugObfuscate|ARM64.ActiveCfg = DebugObfuscate|ARM64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.DebugObfuscate|ARM64.Build.0 = DebugObfuscate|ARM64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.DebugObfuscate|x64.ActiveCfg = DebugObfuscate|x64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.DebugObfuscate|x64.Build.0 = DebugObfuscate|x64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.DebugTesting|Any CPU.ActiveCfg = DebugTesting|Any CPU - {A058E167-7411-D3CA-0C9F-40F030C12860}.DebugTesting|Any CPU.Build.0 = DebugTesting|Any CPU - {A058E167-7411-D3CA-0C9F-40F030C12860}.DebugTesting|ARM64.ActiveCfg = DebugTesting|ARM64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.DebugTesting|ARM64.Build.0 = DebugTesting|ARM64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.DebugTesting|x64.ActiveCfg = DebugTesting|x64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.DebugTesting|x64.Build.0 = DebugTesting|x64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseEnglish|Any CPU.ActiveCfg = ReleaseEnglish|Any CPU - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseEnglish|Any CPU.Build.0 = ReleaseEnglish|Any CPU - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseEnglish|ARM64.ActiveCfg = ReleaseEnglish|ARM64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseEnglish|ARM64.Build.0 = ReleaseEnglish|ARM64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseEnglish|x64.ActiveCfg = ReleaseEnglish|x64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseEnglish|x64.Build.0 = ReleaseEnglish|x64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseMulti|Any CPU.ActiveCfg = ReleaseMulti|Any CPU - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseMulti|Any CPU.Build.0 = ReleaseMulti|Any CPU - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseMulti|ARM64.ActiveCfg = ReleaseMulti|ARM64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseMulti|ARM64.Build.0 = ReleaseMulti|ARM64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseMulti|x64.ActiveCfg = ReleaseMulti|x64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseMulti|x64.Build.0 = ReleaseMulti|x64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseObfuscate|Any CPU.ActiveCfg = ReleaseObfuscate|Any CPU - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseObfuscate|Any CPU.Build.0 = ReleaseObfuscate|Any CPU - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseObfuscate|ARM64.ActiveCfg = ReleaseObfuscate|ARM64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseObfuscate|ARM64.Build.0 = ReleaseObfuscate|ARM64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseObfuscate|x64.ActiveCfg = ReleaseObfuscate|x64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseObfuscate|x64.Build.0 = ReleaseObfuscate|x64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseOther|Any CPU.ActiveCfg = ReleaseOther|Any CPU - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseOther|Any CPU.Build.0 = ReleaseOther|Any CPU - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseOther|ARM64.ActiveCfg = ReleaseOther|ARM64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseOther|ARM64.Build.0 = ReleaseOther|ARM64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseOther|x64.ActiveCfg = ReleaseOther|x64 - {A058E167-7411-D3CA-0C9F-40F030C12860}.ReleaseOther|x64.Build.0 = ReleaseOther|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {ECF1E7B1-C1AD-41F5-BC76-4862410A89AA} - EndGlobalSection -EndGlobal diff --git a/PvZ Fusion Translator.sln.DotSettings.user b/PvZ Fusion Translator.sln.DotSettings.user new file mode 100644 index 0000000..ad79a6e --- /dev/null +++ b/PvZ Fusion Translator.sln.DotSettings.user @@ -0,0 +1,6 @@ + + ForceIncluded + ForceIncluded + ForceIncluded + ForceIncluded + ForceIncluded \ No newline at end of file diff --git a/PvZ Fusion Translator.slnx b/PvZ Fusion Translator.slnx new file mode 100644 index 0000000..ae87c1e --- /dev/null +++ b/PvZ Fusion Translator.slnx @@ -0,0 +1,7 @@ + + + + + + + diff --git a/README.md b/README.md index b0992a5..ec3ebf4 100644 --- a/README.md +++ b/README.md @@ -28,4 +28,3 @@ PvZ Fusion Translator is a **Melon Mod** that allows for an easier method of tra # Contribution If you'd like to contribute in any way, please join us on our [Discord](https://discord.gg/DPAC5ZVJ8T). - diff --git a/Source/AssetStore/AudioStore.cs b/Source/AssetStore/AudioStore.cs new file mode 100644 index 0000000..77fb4d4 --- /dev/null +++ b/Source/AssetStore/AudioStore.cs @@ -0,0 +1,166 @@ +// ReSharper disable once RedundantUsingDirective +using System.Reflection; +// ReSharper disable once RedundantUsingDirective +using HarmonyLib; + +namespace PvZ_Fusion_Translator.AssetStore; + +internal static class AudioStore +{ + public static readonly Dictionary AudioClips = []; + + public static Dictionary AudioClipNames = []; + + private static bool s_overrideEnabled; + + private static readonly string s_customAudioPath = Path.Combine(Core.ModDirectory, "[Custom Audios]"); + + private static readonly string[] s_allowedExts = [".wav", ".mp3", ".ogg"]; + + public static Canvas Canvas { get; set; } + + public static RectTransform SongRectTransform { get; private set; } + + public static void Init() => LoadAudios(); + + public static void LoadAudios() + { + if (!Directory.Exists(s_customAudioPath)) + Directory.CreateDirectory(s_customAudioPath); + + var audioFiles = Directory.GetFiles(s_customAudioPath, "*", SearchOption.AllDirectories); + var ovrClip = audioFiles.SingleOrDefault(f => Path.GetFileNameWithoutExtension(f) == "REPLACE_ALL"); + + if (ovrClip == null) + foreach (var clip in audioFiles + .Where(file => s_allowedExts.Contains(Path.GetExtension(file))) + .Select(file => AudioImportLibAPI.LoadAudioClip(file))) + { + AudioClips.Add(clip.name, clip); + Log.LogInfo("Added Override: " + clip.name); + } + else + { + var clip = AudioImportLibAPI.LoadAudioClip(ovrClip); + AudioClips.Add(clip.name, clip); + s_overrideEnabled = true; + Log.LogInfo("Added Override: " + clip.name); + } +#if MELONLOADER + var audioSourceType = typeof(AudioSource); + const string SourceMethodName = "Play"; + var prefixMethod = typeof(AudioStore).GetMethod(nameof(AudioPlayPatch), BindingFlags.Static | BindingFlags.Public); + + if (prefixMethod == null) + { + Log.LogError($"Couldn't find method named \"AudioPlayPatch\" in type <{typeof(AudioStore)}>."); + return; + } + + _ = Core.Instance.HarmonyInstance.Patch( + AccessTools.Method(audioSourceType, SourceMethodName), + new(prefixMethod) + ); + + Core.Instance.HarmonyInstance.Patch( + AccessTools.Method(audioSourceType, SourceMethodName, [typeof(ulong)]), + new(prefixMethod) + ); +#endif + } + + public static void InitializeCanvas() + { + Debug.Assert(ModFeatures.IsAudioTesting, nameof(ModFeatures.IsAudioTesting)); + + if (Canvas != null) + return; // Prevent duplicate canvas creation + + Canvas = new GameObject("AudioSourceCanvas").AddComponent(); + Canvas.renderMode = RenderMode.ScreenSpaceOverlay; + + var scaler = Canvas.gameObject.AddComponent(); + scaler.uiScaleMode = UnityEngine.UI.CanvasScaler.ScaleMode.ScaleWithScreenSize; + scaler.referenceResolution = new(1920, 1080); + + Canvas.gameObject.AddComponent(); + + // Add a RectTransform for positioning text + var songTextObject = new GameObject("SongText"); + songTextObject.transform.SetParent(Canvas.transform); + + SongRectTransform = songTextObject.AddComponent(); + SongRectTransform.anchorMin = new(1, 1); // Top-right corner + SongRectTransform.anchorMax = new(1, 1); + SongRectTransform.pivot = new(1, 1); + SongRectTransform.anchoredPosition = new(-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(s_customAudioPath)) + Directory.CreateDirectory(s_customAudioPath); + + var path = Path.Combine(s_customAudioPath, "audio_source.json"); + + if (!File.Exists(path)) + { + Log.LogError($"LawnStringsTranslate.json file not found at path: {path}"); + return; + } + + var json = File.ReadAllText(path); + AudioClipNames = System.Text.Json.JsonSerializer.Deserialize>(json); + } + + public static (string, string) GetAudioSource(string clipName) => + AudioClipNames.TryGetValue(clipName, out var audioSource) ? audioSource : ("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}"; + } + + public static void AudioPlayPatch(AudioSource __instance) + { + if (Core.Instance.ConfigDefaultAudio.Value) + return; + + if (__instance.clip == null) + return; + + if (RhythmGameManager.Instance != null && __instance.clip.name == "loon") + return; + + if (ModFeatures.IsAudioTesting) + Log.LogInfo($"Playing \"{__instance.clip.name}\" from object \"{__instance.gameObject.name}\""); + + var audioClipName = s_overrideEnabled ? "REPLACE_ALL" : __instance.clip.name; + + if (AudioClips.TryGetValue(audioClipName, out var replaceClip)) + { + __instance.pitch = 1; + __instance.clip = replaceClip; + } + + if (!ModFeatures.IsAudioTesting) + return; + + // Update the displayed audio source + var (name, source) = GetAudioSource(__instance.clip.name); + UpdateAudioSourceText(name, source); + } +} diff --git a/Source/AssetStore/DllStore.cs b/Source/AssetStore/DllStore.cs new file mode 100644 index 0000000..ed7eeeb --- /dev/null +++ b/Source/AssetStore/DllStore.cs @@ -0,0 +1,111 @@ +#if false +using System.Diagnostics; + +namespace PvZ_Fusion_Translator.AssetStore; + +public static class DllStore +{ + public static readonly Dictionary DLLData = new() + { + { "Blooms_QOL.dll", null }, + { "PvZ_Fusion_Translator.dll", null }, + }; + + public static bool UpdateOnClose { get; set; } + + public static void Init(string gameVersion) => TryGetNewDll(gameVersion); + + public static void TryGetNewDll(string gameVersion) + { + var ableToUpdate = true; + var unableReason = ""; + + var getGameVersionRequest = Utils.GetDataFromWeb( + "https://raw.githubusercontent.com/SillyStar-Github/PvZF-Translation-DLLs/refs/heads/main/CURRENT_GAME_VER" + ) + .Result; + + if (getGameVersionRequest != null) + { + Log.LogDebug( + $"Requst game version: {getGameVersionRequest} -> {Utils.CalculateGameVersion(getGameVersionRequest)}" + ); + + Log.LogDebug($"This game version: {gameVersion} -> {Utils.CalculateGameVersion(gameVersion)}"); + + if (Utils.CalculateGameVersion(getGameVersionRequest) != Utils.CalculateGameVersion(gameVersion)) + { + ableToUpdate = false; + unableReason = "Incorrect game version..."; + } + } + else + { + ableToUpdate = false; + unableReason = "Couldn't get latest game version info..."; + } + + if (ableToUpdate) + foreach (var key in DLLData.Keys) + { + var newDllRequest = Utils.GetByteDataFromWeb( + $"https://raw.githubusercontent.com/SillyStar-Github/PvZF-Translation-DLLs/refs/heads/main/{key}" + ) + .Result; + + if (newDllRequest != null) + { + DLLData[key] = newDllRequest; + SaveNewDll(key); + } + else + Log.LogError($"Couldn't get latest {key} data!"); + } + else + Log.LogError($"Unable to update! {unableReason}"); + } + + public static void SaveNewDll(string name) + { + var newDllData = DLLData[name]; + + if (newDllData == null) + return; + + var basePath = MelonEnvironment.ModsDirectory; + var toSavePath = Path.Combine(basePath, name + ".update"); + File.WriteAllBytes(toSavePath, newDllData); + } + + public static void UpdateNewDll() + { + UpdateOnClose = DLLData.Any(pair => pair.Value is not null); + + if (!UpdateOnClose) + { + Log.LogError("Cannot update on close! All .dll data is null!"); + return; + } + + var assembly = Core.Instance.MelonAssembly.Assembly; + const string ProgramName = "PvZ_Fusion_Translator.Resources.ModUpdateUtil.exe"; + + using var exeResourceStream = assembly.GetManifestResourceStream(ProgramName); + var tempPath = Path.Combine(MelonEnvironment.ModsDirectory, "ModUpdateUtil.exe"); + + // ReSharper disable once PossibleNullReferenceException + using (var fileStream = File.Create(tempPath)) + exeResourceStream.CopyTo(fileStream); + + Process.Start( + new ProcessStartInfo + { + FileName = tempPath, + Arguments = + $"{Environment.ProcessId} {string.Join(",", DLLData.Keys)} \"{MelonEnvironment.ModsDirectory}\"", + UseShellExecute = true, + } + ); + } +} +#endif diff --git a/Source/AssetStore/FontStore.cs b/Source/AssetStore/FontStore.cs new file mode 100644 index 0000000..68f7bb4 --- /dev/null +++ b/Source/AssetStore/FontStore.cs @@ -0,0 +1,117 @@ +namespace PvZ_Fusion_Translator.AssetStore; + +public static class FontStore +{ + internal static readonly Dictionary FontAssetDict = [], FontAssetDictSecondary = []; + + internal static void Init() + { + var fontsDir = Path.Combine(Core.ModDirectory, "[Custom Fonts]"); + var assetBundle = Utils.GetAssetBundle(Path.Combine(fontsDir, "translation")); + + if (ModFeatures.IsMultiLanguage) + { + foreach (var file in assetBundle.GetAllAssetNames()) + { + var fileName = Path.GetFileNameWithoutExtension(file); + + if (fileName.EndsWith("_almanac") || fileName.EndsWith("_fallback")) + continue; + + var fontAsset = assetBundle.LoadAsset(file); + FontAssetDict.Add(fileName, fontAsset); + Log.LogInfo($"Font for language '{fileName}' loaded"); + } + + InitFallback(assetBundle); + } + else + { + var defaultFontDir = Path.Combine("[Custom Fonts]", "English.ttf"); + var defaultFont = FontHandler.LoadTMPFont(defaultFontDir, true); + FontAssetDict.Add("English", defaultFont); + } + } + + internal static void InitFallback(AssetBundle assetBundle) + { + foreach (var file in assetBundle.GetAllAssetNames()) + { + var fileName = Path.GetFileNameWithoutExtension(file); + + if (!fileName.EndsWith("_almanac") && !fileName.EndsWith("_fallback")) + continue; + + var fallbackFont = assetBundle.LoadAsset(file); + var fileNameLanguage = fileName.Replace("_fallback", "").Replace("_almanac", ""); + Utils.TryAdd(FontAssetDictSecondary, fileName, fallbackFont); + + if (ModFeatures.IsDebug) + Log.LogInfo($"Fallback font for language '{fileNameLanguage}' loaded"); + } + + AddFallback(); + } + + public static void AddFallback() + { + foreach (var lang in FontAssetDict.Keys) + { + FontAssetDict[lang].fallbackFontAssetTable ??= new(); + + if (FontAssetDictSecondary.TryGetValue(lang, out var value)) + { + FontAssetDict[lang].fallbackFontAssetTable.Add(value); + Log.LogInfo("Fallback font for language '" + lang + "' added"); + continue; + } + + if (FontAssetDictSecondary.TryGetValue(lang + "_almanac", out var valueAlmanac)) + { + FontAssetDict[lang].fallbackFontAssetTable.Add(valueAlmanac); + Log.LogInfo("Fallback font for language '" + lang + "' added"); + continue; + } + + if (!FontAssetDictSecondary.TryGetValue(lang + "_fallback", out var valueFallback)) + continue; + + FontAssetDict[lang].fallbackFontAssetTable.Add(valueFallback); + Log.LogInfo("Fallback font for language '" + lang + "' added"); + } + } + + public static TMP_FontAsset LoadTMPFont(string language) + { + Debug.Assert(ModFeatures.IsMultiLanguage, nameof(ModFeatures.IsMultiLanguage)); + + if (!FontAssetDict.TryGetValue(language.ToLower(), out var font)) + return FontAssetDict.GetValueOrDefault("english"); + + if (ModFeatures.IsDebug && font.fallbackFontAssetTable != null) + Log.LogInfo( + $"Fallback font for language '{language}' loaded. The name of the FB Font is{font.fallbackFontAssetTable[0].name}" + ); + + return font; + } + + public static TMP_FontAsset LoadTMPFont() + { + Debug.Assert(ModFeatures.IsMultiLanguage, nameof(ModFeatures.IsMultiLanguage)); + var defaultFont = FontAssetDict["English"]; + return defaultFont; + } + + public static TMP_FontAsset LoadTMPFontAlmanac(string language) => + FontAssetDictSecondary.TryGetValue(language.ToLower(), out var first) ? first : + FontAssetDictSecondary.TryGetValue(language.ToLower() + "_almanac", out var second) ? second : + FontAssetDict.GetValueOrDefault("english"); + + public static void Reload() + { + Debug.Assert(ModFeatures.IsMultiLanguage, nameof(ModFeatures.IsMultiLanguage)); + // Get the current language and load its corresponding font. + _ = LoadTMPFont(Utils.Language.ToString()); + } +} diff --git a/Source/AssetStore/StringStore.cs b/Source/AssetStore/StringStore.cs new file mode 100644 index 0000000..97668a6 --- /dev/null +++ b/Source/AssetStore/StringStore.cs @@ -0,0 +1,613 @@ +using PvZ_Fusion_Translator.Patches.BaseTextObjects; +using System.Text.RegularExpressions; + +namespace PvZ_Fusion_Translator.AssetStore; + +public static class StringStore +{ + // ReSharper disable once CollectionNeverQueried.Global + internal static readonly Dictionary StringsDict = []; + + public static readonly Dictionary TranslationStringRegex = new(); + + public static readonly Dictionary TranslationString = new(); + + public static readonly Dictionary CustomLevelStringRegex = new(); + + public static readonly Dictionary CustomLevelString = new(); + + public static readonly Dictionary IZLevelTipDictionary = new(); + + public static readonly Dictionary IZTipCollectionString = new(); + + public static readonly Dictionary FSLevelTipDictionary = new(); + + public static readonly Dictionary FSTipCollectionString = new(); + + public static readonly Dictionary> PatchesStore = new() + { + { + "Difficulty", new() + { + { "English", "Difficulty:" }, + { "French", "Difficulté:" }, + { "Italian", "Difficoltà:" }, + { "German", "Schwierigkeit:" }, + { "Spanish", "Dificultad:" }, + { "Portuguese", "Dificuldade:" }, + { "Filipino", "Ang Hirap:" }, + { "Vietnamese", "Độ Khó:" }, + { "Indonesian", "Kesulitan:" }, + { "Russian", "Сложность:" }, + { "Japanese", "困難:" }, + { "Korean", "난이도:" }, + { "Javanese", "Kesulitan:" }, + { "Polish", "Trudność:" }, + { "Hungarian", "Nehézség:" }, + { "Arabic", "صعوبة:" }, + // { "Ukrainian" , "Складність:" }, + // { "Slovak" , "Náročnosť:" }, + } + }, + { + "Zombies", new() + { + { "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:" }, + { "Polish", "Zombi:" }, + { "Hungarian", "Zombik:" }, + { "Arabic", "الزومبي:" }, + // { "Ukrainian" , "Зомбі:" }, + // { "Slovak" , "Zombíci:"} + } + }, + }; + + internal static void Init() => FileLoader.LoadStrings(); + + internal static void Reload() + { + TranslationString.Clear(); + TranslationStringRegex.Clear(); + CustomLevelString.Clear(); + CustomLevelStringRegex.Clear(); + IZLevelTipDictionary.Clear(); + IZTipCollectionString.Clear(); + FSLevelTipDictionary.Clear(); + FSTipCollectionString.Clear(); + InGameText_Patch.CurrentText = ""; + Utils.RegisterPlantIndices(); + FileLoader.LoadStrings(); + } + + public static TextMeshPro TranslateText(TextMeshPro originalTMP, bool isLog = false) + { + var fontAsset = FontStore.LoadTMPFont(ModFeatures.IsMultiLanguage ? Utils.Language.ToString() : null); + var translatedText = TranslateText(originalTMP.text); + originalTMP.font = fontAsset; + originalTMP.text = translatedText; + return originalTMP; + } + + public static TextMeshProUGUI TranslateText(TextMeshProUGUI originalTMP, bool isLog = false) + { + var fontAsset = ModFeatures.IsMultiLanguage + ? FontStore.LoadTMPFont(Utils.Language.ToString()) + : FontStore.LoadTMPFont(); + + var translatedText = TranslateText(originalTMP.text); + originalTMP.font = fontAsset; + originalTMP.text = translatedText; + return originalTMP; + } + + public static string TranslateText(string originalText, bool isLog = false) + { + var text = DoTranslateText(originalText); + + if (!ModFeatures.IsDebug) + return text; + + Regex regex = new("\\p{IsCJKUnifiedIdeographs}+"); + var match = regex.Match(text); + + if (match.Success) + FileLoader.DumpUntranslatedStrings(text); + + return text; + } + + public static string TranslateText(string originalText, string pattern, bool isLog = false) + { + if (TestRegex(originalText, pattern)) + { + if (TranslationStringRegex.TryGetValue(pattern, out var value)) + { + // Extract dynamic parts from the original text + var regex = new Regex(pattern); + var match = regex.Match(originalText); + var 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 (var i = 1; i < groupCount; i++) + { + var groupValue = match.Groups[i].Value; + var translatedValue = DoTranslateString(groupValue); + dynamicParts.Add(translatedValue); + } + + // Format the output string with dynamic parts + return string.Format(value, [..dynamicParts]); + } + + if (!CustomLevelStringRegex.TryGetValue(pattern, out var value1)) + return originalText; + + { + // Extract dynamic parts from the original text + var regex = new Regex(pattern); + var match = regex.Match(originalText); + var groupCount = match.Groups.Count; + + if (isLog) + Log.LogDebug("Text found in customLevelStringRegex {0}: {1}", match, groupCount); + + // List to hold formatted dynamic parts + List dynamicParts = []; + + // Loop through each group and determine its translation + for (var i = 1; i < groupCount; i++) + { + var groupValue = match.Groups[i].Value; + var translatedValue = CustomLevelString.GetValueOrDefault(groupValue, groupValue); + dynamicParts.Add(translatedValue); + } + + // Format the output string with dynamic parts + return string.Format(value1, [..dynamicParts]); + } + } + + if (isLog) + Log.LogDebug($"Text '{originalText}' not translated"); + + FileLoader.DumpUntranslatedStrings(originalText); + return originalText; + } + + public static string DoTranslateString(string originalText, bool isLog = false) + { + if (string.IsNullOrEmpty(originalText)) + { + if (isLog) + Log.LogError("Text Null or Empty"); + + return string.Empty; + } + + if (TranslationString.TryGetValue(originalText, out var s)) + { + if (isLog) + Log.LogDebug($"Text '{originalText} found in translationString"); + + return s; + } + + if (IZTipCollectionString.TryGetValue(originalText, out var translateString)) + { + if (isLog) + Log.LogDebug($"Text '{originalText}' found in izTipCollectionString"); + + return translateString; + } + + if (FSTipCollectionString.TryGetValue(originalText, out var doTranslateString)) + { + if (isLog) + Log.LogDebug($"Text '{originalText}' found in fsTipCollectionString"); + + return doTranslateString; + } + + if (CustomLevelString.TryGetValue(originalText, out var s1)) + { + if (isLog) + Log.LogDebug($"Text '{originalText}' found in customLevelString"); + + return s1; + } + + if (!Utils.PlantIndiceString.TryGetValue(originalText, out var translateString1)) + return originalText; + + if (isLog) + Log.LogDebug($"Text '{originalText}' found in plantIndiceString"); + + return translateString1; + } + + public static string DoTranslateText(string originalText, bool isLog = false) + { + if (string.IsNullOrEmpty(originalText)) + { + if (isLog) + Log.LogError("Text Null or Empty"); + + return string.Empty; + } + + if (!Utils.CheckForUntranslatedText(originalText) && !originalText.Contains('_')) + return originalText; + + if (TranslationString.TryGetValue(originalText, out var text)) + { + if (isLog) + Log.LogDebug($"Text '{originalText} found in translationString"); + + return text; + } + + if (IZTipCollectionString.TryGetValue(originalText, out var translateText)) + { + if (isLog) + Log.LogDebug($"Text '{originalText}' found in izTipCollectionString"); + + return translateText; + } + + if (FSTipCollectionString.TryGetValue(originalText, out var doTranslateText)) + { + if (isLog) + Log.LogDebug($"Text '{originalText}' found in fsTipCollectionString"); + + return doTranslateText; + } + + if (CustomLevelString.TryGetValue(originalText, out var text1)) + { + if (isLog) + Log.LogDebug($"Text '{originalText}' found in customLevelString"); + + return text1; + } + + if (Utils.PlantIndiceString.TryGetValue(originalText, out var translateText1)) + { + if (isLog) + Log.LogDebug($"Text '{originalText}' found in plantIndiceString"); + + return translateText1; + } + + // Regex-based dynamic translation + foreach (var entry in TranslationStringRegex) + if (TestRegex(originalText, entry.Key)) + { + // Extract dynamic parts from the original text + var regex = new Regex(entry.Key); + var match = regex.Match(originalText); + var 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 (var i = 1; i < groupCount; i++) + { + var groupValue = match.Groups[i].Value; + var translatedValue = DoTranslateString(groupValue); + dynamicParts.Add(translatedValue); + } + + // Format the output string with dynamic parts + return string.Format(entry.Value, [..dynamicParts]); + } + + foreach (var entry in CustomLevelStringRegex) + if (TestRegex(originalText, entry.Key)) + { + // Extract dynamic parts from the original text + var regex = new Regex(entry.Key); + var match = regex.Match(originalText); + var groupCount = match.Groups.Count; + + if (isLog) + Log.LogDebug("Text found in customLevelRegex {0}: {1}", match, groupCount); + + // List to hold formatted dynamic parts + List dynamicParts = []; + + // Loop through each group and determine its translation + for (var i = 1; i < groupCount; i++) + { + var groupValue = match.Groups[i].Value; + var translatedValue = CustomLevelString.GetValueOrDefault(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"); + + if (Utils.CheckForUntranslatedText(originalText)) + FileLoader.DumpUntranslatedStrings(originalText); + + return originalText; + } + + public static string TranslateColorText(string originalText, bool isLog = false) + { + var text = TranslateColorSegments(originalText); + + if (!ModFeatures.IsDebug) + return text; + + Regex regex = new("\\p{IsCJKUnifiedIdeographs}+"); + var match = regex.Match(text); + + if (match.Success) + // Log.LogDebug("Untranslated String: " + match.Value); + FileLoader.DumpUntranslatedStrings(text); + + return text; + } + + public static string TranslateColorSegments(string input) + { + var result = ""; + const string Pattern = @"]+>[\s\S]*?(?:<\/color>|$)|(?:<(?!color=)|[^<])+"; + const string SmallPattern = "(]+>)(.*?)()"; + var matches = Regex.Matches(input, Pattern); + + for (var i = 0; i < matches.Count; i++) + { + var match = matches[i]; + + if (Regex.Match(match.Value, SmallPattern, RegexOptions.Singleline).Success) + result += TranslateColorSegment(match.Value); + else + result += DoTranslateText(match.Value); + } + + return result; + } + + public static string TranslateColorSegment(string input) + { + const string Pattern = "(]+>)(.*?)()"; + var match = Regex.Match(input, Pattern, RegexOptions.Singleline); + var translatedText = DoTranslateText(match.Groups[2].Value); + + if (Utils.CheckForUntranslatedText(translatedText)) + FileLoader.DumpUntranslatedStrings(translatedText); + + return match.Groups[1].Value + translatedText + match.Groups[3].Value; + } + + public static bool TestRegex(string originalText, string pattern, bool singleLine = false) + { + var options = singleLine ? RegexOptions.None : RegexOptions.Singleline; + return Regex.IsMatch(originalText, pattern, options); + } + + private static TextAlignmentOptions TextAnchorToTMPAlignment(TextAnchor anchor) => + 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, + }; + + public 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}"); + + var textObject = oldText.gameObject; + + // Preserve text content and settings + var originalText = oldText.text; + originalText = TranslateText(originalText, isLog); + var alignment = oldText.alignment; + var color = oldText.color; + + // Remove old Text component + UnityEngine.Object.DestroyImmediate(oldText); + + // Add TextMeshProUGUI component + var 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; + + var currentLanguage = ModFeatures.IsMultiLanguage ? Utils.Language.ToString() : null; + var fontAsset = FontStore.LoadTMPFont(currentLanguage); + + if (fontAsset == null) + { + Log.LogError( + ModFeatures.IsMultiLanguage + ? $"Font for language '{currentLanguage}' not found. Translation aborted." + : "Font not found. Translation aborted." + ); + + return; + } + + // Local function for processing transforms + void ProcessTextTransform(Transform textTransform) + { + if (!textTransform) + return; + + // Handle TextMeshPro components + var textTMP = textTransform.GetComponent(); + + if (textTMP) + { + textTMP.text = TranslateText(textTMP.text, isLog); + textTMP.autoSizeTextContainer = isAutoTextContainer; + textTMP.font = fontAsset; + } + + var textTmpugui = textTransform.GetComponent(); + + if (textTmpugui) + { + textTmpugui.text = TranslateText(textTmpugui.text, isLog); + textTmpugui.enableAutoSizing = isAutoTextContainer; + textTmpugui.font = fontAsset; + } + + // Handle UnityEngine.UI.Text components + var 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")); + + var shadowTransform = baseTransform.Find("text/shadow"); + + if (shadowTransform) + ProcessTextTransform(shadowTransform); + + shadowTransform = baseTransform.Find("text1/shadow"); + + if (shadowTransform) + ProcessTextTransform(shadowTransform); + + if (!ModFeatures.IsTesting) + return; + + var childTransform = baseTransform.GetChild(0); + + if (childTransform) + ProcessTextTransform(childTransform); + } + + public static void TranslateTextUI(TextMeshPro textTMP, bool? isAutoTextContainer = null, bool isLog = false) + { + var currentLanguage = Utils.Language.ToString(); + + if (!textTMP) + return; + + 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) + { + var currentLanguage = Utils.Language.ToString(); + + if (!textTMP) + return; + + var 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) + { + var currentLanguage = Utils.Language.ToString(); + + if (!textInput) + return; + + var 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/Source/AssetStore/TextureStore.cs b/Source/AssetStore/TextureStore.cs new file mode 100644 index 0000000..f030b7a --- /dev/null +++ b/Source/AssetStore/TextureStore.cs @@ -0,0 +1,55 @@ +using System.Collections; + +namespace PvZ_Fusion_Translator.AssetStore; + +public static class TextureStore +{ + internal static readonly Dictionary TextureDict = [], SpriteDict = []; + + internal static void Init() => FileLoader.LoadTextures(); + + internal static void Reload() + { + TextureDict.Clear(); + + if (ModFeatures.IsMultiLanguage) + RestoreTextures(); + + FileLoader.LoadTextures(); + } + + public static IEnumerator ReplaceTexturesCoroutine() + { + while (true) + { + ReplaceTextures(); + yield return new WaitForSeconds(0.5f); // Adjust this interval as needed + } // ReSharper disable once IteratorNeverReturns + } + + public static void ReplaceTextures() + { + foreach (var texture in Resources + .FindObjectsOfTypeAll() + .Where(texture => !texture.name.StartsWith("replaced_"))) + Utils.TryReplaceTexture2D(texture); + } + + public static void RestoreTextures() + { + Debug.Assert(ModFeatures.IsMultiLanguage, nameof(ModFeatures.IsMultiLanguage)); + + Texture2D[] textures = Resources.FindObjectsOfTypeAll(); + + foreach (var texture in textures.Where(texture => texture != null)) + texture.name = texture.name.Replace("replaced_", ""); + } + + public static void LogAll() + { + Log.LogInfo("Logging all TextureStore entries."); + + foreach (var entry in TextureDict) + Log.LogInfo("TextureDict Entry: " + entry.Key + " | " + entry.Value); + } +} diff --git a/Source/AssetStore/WarningStore.cs b/Source/AssetStore/WarningStore.cs new file mode 100644 index 0000000..1544dfd --- /dev/null +++ b/Source/AssetStore/WarningStore.cs @@ -0,0 +1,285 @@ +#if false +namespace PvZ_Fusion_Translator.AssetStore; + +public static class WarningStore +{ + private static readonly Dictionary s_warningMessages = new() + { + { + "English", + (""" + The only valid source of this translation is from this community: + discord.gg/DPAC5ZVJ8T. If you got this anywhere else like + Plants Hybrid and superhybrid.online, they stole it. + Stray away from other sources as they may contain viruses. + Please visit our community for future updates. + """, "Okay! Got it.") + }, + { + "French", + (""" + La seule source valide pour cette traduction provient de cette + communauté :discord.gg/DPAC5ZVJ8T. Si vous l'avez obtenue + ailleurs, comme Plants Hybrid ou superhybrid.online, ils l'ont volée. + Évitez les autres sources, car elles peuvent contenir des virus. + Veuillez visiter notre communauté pour les mises à jour futures. + """, "D'accord !") + }, + { + "Italian", + (""" + L'unica fonte valida di questa traduzione è questa community: + discord.gg/DPAC5ZVJ8T. Se l'hai ottenuta altrove, come + Plants Hybrid e superhybrid.online, l'hanno rubata. + Evita altre fonti, potrebbero contenere virus. + Visita la nostra community per aggiornamenti futuri. + """, "Va bene! Ho capito.") + }, + { + "German", + (""" + Die einzige gültige Quelle für diese Übersetzung stammt aus + dieser Community: discord.gg/DPAC5ZVJ8T. Wenn Sie diese + irgendwo anders gefunden haben, z. B. bei Plants Hybrid oder + superhybrid.online, dann haben sie sie gestohlen. + Meiden Sie andere Quellen, da diese Viren enthalten könnten. + 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 + comunidad: discord.gg/DPAC5ZVJ8T. Si la obtuvo en cualquier + otro lugar como Plants Hybrid o superhybrid.online, la robaron. + Manténgase alejado de otras fuentes, ya que podrían contener virus. + Por favor, visite nuestra comunidad para futuras actualizaciones. + """, "¡Entendido!") + }, + { + "Portuguese", + (""" + O lugar original e seguro dessa tradução vem daqui: + discord.gg/DPAC5ZVJ8T. Se você baixou ela de qualquer + lugar como Plants Hybrid ou superhybrid.online, eles + roubaram. Evite baixar deles, pode conter vírus. + Por favor, visite nossa comunidade para atualizações futuras. + """, "Okay, entendido.") + }, + { + "Filipino", + (""" + Ang tanging opisyal na source ng pagsasaling ito ay mula + lamang dito: discord.gg/DPAC5ZVJ8T. Kung nakuha nmo ito kahit + saan pa tulad ng Plants Hybrid at superhybrid.online, ito ay ninakaw. + Lumayo sa ibang source dahil posibleng may kasamang virus. + 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 + đồng này: discord.gg/DPAC5ZVJ8T. Nếu bạn nhận + được nó ở bất cứ nơi nào khác như Plants Hybrid + hoặc superhybrid.online, họ đã ăn cắp nó. + Tránh xa các nguồn khác vì chúng có thể chứa + virus. Hãy ghé thăm cộng đồng của chúng tôi để + cập nhật trong tương lai. + """, "Đồng ý!") + }, + { + "Indonesian", + (""" + Satu-satunya sumber resmi dari terjemahan ini adalah + komunitas kami: discord.gg/DPAC5ZVJ8T. Jika Anda + mendapatkannya dari sumber lain seperti Plants Hybrid + dan superhybrid.online, mereka mencurinya. + Jauhi sumber lain karena mungkin ada virus. + Silakan kunjungi komunitas kami untuk pembaruan berikutnya. + """, "Oke! Mengerti.") + }, + { + "Russian", (""" + Единственный проверенный источник этого перевода — + сообщество discord.gg/DPAC5ZVJ8T. + Или же его замена https://t.me/nekoshkindom + Если вы скачали этот мод где-либо ещё, возможно он содержит вирусы. + Программист перевода: LancerX0. + Переводчик: Nekosha. + """, "Хорошо!") + }, + { + "Japanese", (""" + この翻訳の唯一の有効なソースは、このコミュニティからです: + discord.gg/DPAC5ZVJ8T.Plants Hybridやsuperhybrid.online、 + YoutubeのBlue Flyが作っているもの、他のどこかでこれを入手した場合、 + 彼らはそれを盗んだことになります。ウイルスが含まれている可能性があるので、 + 他のソースからは離れてください。今後のアップデートについては、 + 私たちのコミュニティをご覧ください。 + """, + "了解しました!") + }, + { + "Korean", (""" + 이 번역은 Bloom(discord.gg/DPAC5ZVJ8T)에서만 + 제공됩니다. Bloom 디스코드 이외의 다른서드 파티 사이트, + 예를 들어 Plants Hybrid 및 superhybrid.online, 또는 + 유튜브 Blue Fly등에서 제공하는 파일은 무단으로 재배포된 것이며, + 이런 사이트들에는 바이러스가 포함되어 있을 가능성이 높습니다. + 향후 업데이트를 위해 저희 디스코드를 방문해 주세요. + """, + "확인") + }, + { + "Javanese", (""" + Sumber mung sing sah kanggo terjemahan iki saka komunitas iki: + discord.gg/DPAC5ZVJ8T. Yen sampeyan nemokake iki ing papan + liya kaya Plants Hybrid lan superhybrid.online, iku dicolong. + Aja nyedhaki sumber liya amarga bisa ngandhut virus. Mangga + ngunjungi komunitas kita kanggo nganyari ing mangsa ngarep. + """, + "Oke! Ngertos.") + }, + { + "Polish", (""" + Jedynym wiarygodnym źródłem tego tłumaczenia jest ta społeczność: + discord.gg/DPAC5ZVJ8T. Jeśli znalazłeś to gdziekolwiek indziej, np. + Plants Hybrid i superhybrid.online, ukradli to. + Omijaj inne źródła, ponieważ mogą zawierać wirusy. + Odwiedź naszą społeczność, aby uzyskać przyszłe aktualizacje. + """, + "Okay! Rozumiem.") + }, + { + "Hungarian", ( + """ + Ennek a fordításnak az egyetlen érvényes forrása ebből a közösségből származik: + discord.gg/DPAC5ZVJ8T. Ha ezt valahol máshol szerezted, például + Plants Hybrid és superhybrid.online oldalakon, akkor ők lopták. + Kerüld a többi forrást, mert vírusokat tartalmazhatnak. + Kérjük, látogass el közösségünkbe a jövőbeli frissítésekért. + """, + "Oké! Értem.") + }, + { + "Arabic", (""" + The only valid source of this translation is from this community: + discord.gg/DPAC5ZVJ8T. If you got this anywhere else like + Plants Hybrid and superhybrid.online, they stole it. + Stray away from other sources as they may contain viruses. + Please visit our community for future updates. + """, + "Okay! Got it.") + }, + // { "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!") }, + }; + + public static bool IsWarningMessageLoaded { get; set; } + + public static string WarningMessage { get; set; } = + "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 { get; set; } = "¡Entendido!"; + + // ReSharper disable once UnusedTupleComponentInReturnValue + public static (string, string) GetWarningMessage(Utils.LanguageEnum language) + { + Debug.Assert(ModFeatures.IsMultiLanguage, nameof(ModFeatures.IsMultiLanguage)); + + return s_warningMessages.TryGetValue(language.ToString(), out var message) + ? message + : s_warningMessages["English"]; // Default to English if language code is not found + } + + public static void WarningLoad(NoticeMenu noticeMenu) + { + if (noticeMenu == null || noticeMenu.transform == null) + { + Log.LogWarning("[WarningStore] NoticeMenu or transform is null - ABORTING"); + return; + } + + if (!ModFeatures.IsMultiLanguage) + return; + + try + { + var (localizedWarningMessage, _) = GetWarningMessage(Utils.Language); + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + Transform warningTransform = noticeMenu.transform.Find("窗口"); + + if (warningTransform == null) + { + Log.LogWarning("[WarningStore] '窗口' transform not found - ABORTING"); + return; + } + + var warningTextTransform = warningTransform.Find("文字"); + var warningTextShadowTransform = warningTransform.Find("文字2"); + + if (warningTextTransform == null || warningTextShadowTransform == null) + { + Log.LogWarning("[WarningStore] Could not find text components (文字/文字2)"); + return; + } + + var warningText = warningTextTransform.GetComponent(); + var shadowText = warningTextShadowTransform.GetComponent(); + + if (warningText == null || shadowText == null) + { + Log.LogWarning("[WarningStore] TextMeshProUGUI components missing"); + return; + } + + warningText.text = localizedWarningMessage; + shadowText.text = localizedWarningMessage; + + if (fontAsset != null) + { + warningText.font = fontAsset; + shadowText.font = fontAsset; + } + else + Log.LogWarning("[WarningStore] Font asset is null"); + + Log.LogInfo("Warning message loaded successfully!"); + } + catch (Exception e) + { + Log.LogError($"Critical error in WarningLoad: {e}"); + } + } + + public static void WarningReload(Utils.LanguageEnum language, NoticeMenu noticeMenu) + { + if (!ModFeatures.IsMultiLanguage) + { + if (IsWarningMessageLoaded) + return; + + WarningStore.WarningLoad(); + IsWarningMessageLoaded = true; + return; + } + + if (noticeMenu == null) + { + Log.LogWarning("[WarningStore] NoticeMenu is null in WarningReload"); + return; + } + + if (Utils.OldLanguage.ToString() == language.ToString() && Utils.OldLanguage.ToString() != "English") + return; + + if (IsWarningMessageLoaded) + return; + + WarningLoad(noticeMenu); + IsWarningMessageLoaded = true; + } +} +#endif diff --git a/Source/Core.cs b/Source/Core.cs new file mode 100644 index 0000000..921e028 --- /dev/null +++ b/Source/Core.cs @@ -0,0 +1,276 @@ +global using UnityEngine; +#if MELONLOADER +global using MelonLoader; +global using MelonLoader.Logging; +global using MelonLoader.Utils; +global using Il2Cpp; +global using Il2CppAlmanacData; +global using Il2CppCore; +global using Il2CppGameLevel; // ReSharper disable once RedundantUsingDirective.Global +global using Il2CppGameLevel.Abyss; +global using Il2CppGameLevel.EventNodes; +global using Il2CppGameLevel.RogueShooting; +global using Il2CppPVPScaryPot; +global using Il2CppRhythmGame; +global using Il2CppRhythmGameEditor; +global using Il2CppTMPro; +global using Il2CppZenGarden; +global using AudioImportLibAPI = AudioImportLib.API; +global using Il2CppAlmanacDataClass = Il2CppAlmanacData.AlmanacData; +global using Il2CppLevelData = Il2Cpp.LevelData; +global using Il2CppPlantInfo = Il2CppAlmanacData.PlantInfo; +#elif BEPINEX +global using AlmanacData; +global using BepInEx; +global using BepInEx.Configuration; +global using BepInEx.Logging; +global using BepInEx.Unity.IL2CPP; +global using BepInEx.Unity.IL2CPP.Utils; +global using Core; +global using GameLevel; +global using GameLevel.Abyss; +global using GameLevel.EventNodes; +global using GameLevel.RogueShooting; +global using PVPScaryPot; +global using RhythmGame; +global using RhythmGameEditor; +global using TMPro; +global using ZenGarden; +global using AudioImportLibAPI = AudioImportLib.BepInEx.API; +global using Il2CppAlmanacDataClass = AlmanacData.AlmanacData; +global using Il2CppLevelData = LevelData; +global using Il2CppPlantInfo = AlmanacData.PlantInfo; +#endif +using PvZ_Fusion_Translator.AssetStore; +using PvZ_Fusion_Translator.Patches.Managers; +using PvZ_Fusion_Translator.Patches.Modes.Super_Editor; + +#if MELONLOADER +[assembly: + MelonGame("LanPiaoPiao", "PlantsVsZombiesRH"), + MelonInfo( + typeof(PvZ_Fusion_Translator.Core), + "PvZ Fusion Translator", + "231.0.0", + "dynaslash / arifrios1st / lancerx0 / JustNull / Dakosha / Mamoru-kun / cassidy / Teyliu / Emik" + )] +#endif + +namespace PvZ_Fusion_Translator; +#pragma warning disable CA1822 // ReSharper disable once ClassNeverInstantiated.Global +#if MELONLOADER +public class Core : MelonMod +#elif BEPINEX +[BepInPlugin("PVZFusionTranslator_BepInEx", "PvZ Fusion Translator", "3.1.1"), BepInProcess("PlantsVsZombiesRH.exe")] +public class Core : BasePlugin +#endif +{ +#if BEPINEX + public sealed class UnityCoroutineHelper : MonoBehaviour + { + // ReSharper disable once MemberHidesStaticFromOuterClass + public static UnityCoroutineHelper Instance { get; private set; } + + public void Awake() => Instance = this; + } +#endif + public static string ModDirectory => +#if MELONLOADER + Path.Combine(MelonEnvironment.ModsDirectory, "PvZ_Fusion_Translator"); +#elif BEPINEX + Path.Combine(Paths.PluginPath, "PvZ_Fusion_Translator"); +#endif + public static bool IsInitialized { get; set; } + + public static Core Instance { get; private set; } +#if MELONLOADER + public MelonPreferences_Entry ConfigDefaultAudio, ConfigDefaultTextures, ConfigUseLocal; + + public MelonPreferences_Entry ConfigLanguage; + + private object _replaceTextureRoutine; +#elif BEPINEX + public static MonoBehaviour MonoInstance { get; private set; } + + public ConfigEntry ConfigDefaultAudio, ConfigDefaultTextures, ConfigUseLocal; + + public ConfigEntry ConfigLanguage; + + public new static ManualLogSource Log { get; private set; } + + private Coroutine _replaceTextureRoutine; +#endif + private static DateTime? s_dtStartToast; + + private static string s_toastText; +#if MELONLOADER + public static object Coroutine(System.Collections.IEnumerator enumerator) => + MelonCoroutines.Start(enumerator); +#elif BEPINEX + public static Coroutine Coroutine(System.Collections.IEnumerator enumerator) => + MonoInstance.StartCoroutine(enumerator); +#endif +#if MELONLOADER + public override void OnInitializeMelon() +#elif BEPINEX + public override void Load() +#endif + { + Instance = this; + LoadConfig(); + + if (ModFeatures.IsMultiLanguage) + FileLoader.LoadLanguage(); + + _replaceTextureRoutine = Coroutine(TextureStore.ReplaceTexturesCoroutine()); + TextureStore.Init(); + StringStore.Init(); + AudioStore.Init(); + FontStore.Init(); +#if MELONLOADER + base.OnInitializeMelon(); +#elif BEPINEX + Log = base.Log; + Utils.RegisterPlantIndices(); + MonoInstance = AddComponent(); + HarmonyLib.Harmony.CreateAndPatchAll(System.Reflection.Assembly.GetExecutingAssembly()); +#endif + IsInitialized = true; + } +#if MELONLOADER + public override void OnLateInitializeMelon() + { + FileLoader.LoadTravelBuffs(); + Utils.RegisterPlantIndices(); + } + + public override void OnDeinitializeMelon() + { + MelonCoroutines.Stop(_replaceTextureRoutine); + + if (ModFeatures.IsMultiLanguage) + FileLoader.SaveLanguage(); + } +#elif BEPINEX + public override bool Unload() + { + if (_replaceTextureRoutine != null) + { + MonoInstance.StopCoroutine(_replaceTextureRoutine); + Log.LogDebug("Coroutine Stopped"); + } + + FileLoader.SaveLanguage(); + return true; + } +#endif + public static void ShowToast(string message) + { + s_toastText = message; + s_dtStartToast = new(DateTime.Now.Ticks); + } +#if MELONLOADER + public override void OnLateUpdate() +#elif BEPINEX + public void OnUpdate() +#endif + { + if (ModFeatures.IsDebug) + ModFeatures.OnLateUpdate(); + + if (Input.GetKeyDown(KeyCode.Insert)) + Utils.OpenSaveDirectory(); + + if (Input.GetKeyDown(KeyCode.PageUp)) + Utils.OpenOnlineAlmanac(); + + TowerManager_Patch.UpdateText(); + + if (CustomLevelMenu_Patch.RequestTimer <= 0) + return; + + CustomLevelMenu_Patch.RequestTimer -= Time.deltaTime; + + if (CustomLevelMenu_Patch.RequestTimer < 0) + CustomLevelMenu_Patch.RequestTimer = 0; + } +#if MELONLOADER + public override void OnGUI() +#elif BEPINEX + public void OnGUI() +#endif + { + if (!ModFeatures.IsDebug) + return; + + if (s_dtStartToast is null) + return; + + GUI.Button(new(10, 10, 200, 20), $"\n{s_toastText}\n"); + var timeSpan = DateTime.Now - s_dtStartToast; + TimeSpan t = new(0, 0, 0, 2); + + if (timeSpan > t) + s_dtStartToast = null; + } +#if MELONLOADER + private void LoadConfig() + { + var category = MelonPreferences.CreateCategory("PvZ_Fusion_Translator", "Fusion Translator Settings"); + + ConfigDefaultTextures = category.CreateEntry("DefaultTextures", false); + ConfigDefaultAudio = category.CreateEntry("DefaultAudio", false); + ConfigUseLocal = category.CreateEntry("UseLocal", false); + ConfigLanguage = category.CreateEntry("Language", "English"); + + MelonPreferences.Save(); + } +#elif BEPINEX + private void LoadConfig() + { + const string MainCategory = "PvZ_Fusion_Translator"; + + if (!Config.TryGetEntry(new(MainCategory, "DefaultTextures"), out ConfigDefaultTextures)) + ConfigDefaultTextures = Config.Bind( + new(MainCategory, "DefaultTextures"), + false, + new("Use Default Textures + Translation Textures", new AcceptableValueList(true, false)) + ); + + Debug.Assert(Config.TryGetEntry(new(MainCategory, "DefaultTextures"), out ConfigDefaultTextures)); + + if (!Config.TryGetEntry(new(MainCategory, "DefaultAudio"), out ConfigDefaultAudio)) + ConfigDefaultAudio = Config.Bind( + new(MainCategory, "DefaultAudio"), + false, + new("Use Default Audio", new AcceptableValueList(true, false)) + ); + + Debug.Assert(Config.TryGetEntry(new(MainCategory, "DefaultAudio"), out ConfigDefaultAudio)); + + if (!Config.TryGetEntry(new(MainCategory, "UseLocal"), out ConfigDefaultAudio)) + ConfigUseLocal = Config.Bind( + new(MainCategory, "UseLocal"), + false, + new("Use Local", new AcceptableValueList(true, false)) + ); + + Debug.Assert(Config.TryGetEntry(new(MainCategory, "DefaultAudio"), out ConfigDefaultAudio)); + + string[] supportedLanguages = + [ + "English", "French", "Italian", "German", "Spanish", "Portuguese", "Indonesian", + "Vietnamese", "Javanese", "Russian", "Japanese", "Korean", + ]; + + if (!Config.TryGetEntry(new(MainCategory, "Language"), out ConfigLanguage)) + ConfigLanguage = Config.Bind( + new(MainCategory, "Language"), + "English", + new("Load the Game in this Language", new AcceptableValueList(supportedLanguages)) + ); + + Debug.Assert(Config.TryGetEntry(new(MainCategory, "Language"), out ConfigLanguage)); + } +#endif +} diff --git a/Source/FileLoader.cs b/Source/FileLoader.cs new file mode 100644 index 0000000..e451ba7 --- /dev/null +++ b/Source/FileLoader.cs @@ -0,0 +1,1142 @@ +using Il2CppInterop.Runtime.InteropTypes.Arrays; +using Newtonsoft.Json; +using PvZ_Fusion_Translator.AssetStore; +using PvZ_Fusion_Translator.Patches.GameObjects; +using PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects; +using PvZ_Fusion_Translator.Patches.Modes.Odyssey; +using System.Text.Encodings.Web; +using System.Text.Json; + +namespace PvZ_Fusion_Translator; + +// ReSharper disable AssignNullToNotNullAttribute Unity.UnknownResource +internal static class FileLoader +{ + internal enum AssetType + { + Textures, Strings, Dumps, Almanac, Sprites, + } + + public static string GetAssetDir(AssetType assetType, Utils.LanguageEnum? language = null) + { + var languagePath = language.HasValue + ? "Localization" + Path.DirectorySeparatorChar + language + : string.Empty; + + return Path.Combine(Core.ModDirectory, languagePath, assetType.ToString()); + } + + // private static string GetAssetDir(AssetType assetType) => + // Path.Combine(Core.Instance.modsDirectory, assetType.ToString()); + + internal static void LoadStrings() => LoadStrings(Utils.Language); + + internal static void LoadStrings(Utils.LanguageEnum language) + { + var stringDir = GetAssetDir(AssetType.Strings, Utils.Language); + + if (!Directory.Exists(stringDir)) + Directory.CreateDirectory(stringDir); + + if (!Core.Instance.ConfigUseLocal.Value) + { + // load translationStrings + var translationStringsContent = Utils.GetDataFromWeb( + $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language}/Strings/translation_strings.json" + ) + .Result; + + if (translationStringsContent != null) + LoadTranslationStrings(translationStringsContent); + else + { + var translationStringsPath = Path.Combine( + GetAssetDir(AssetType.Strings, Utils.Language), + "translation_strings.json" + ); + + if (File.Exists(translationStringsPath)) + LoadTranslationStrings(File.ReadAllText(translationStringsPath)); + } + + // load translationRegexs + var translationRegexsContent = Utils.GetDataFromWeb( + $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language}/Strings/translation_regexs.json" + ) + .Result; + + if (translationRegexsContent != null) + LoadTranslationRegexs(translationRegexsContent); + else + { + var translationRegexsPath = Path.Combine( + GetAssetDir(AssetType.Strings, Utils.Language), + "translation_regexs.json" + ); + + if (File.Exists(translationRegexsPath)) + LoadTranslationRegexs(File.ReadAllText(translationRegexsPath)); + } + + var customLevelStringsContent = Utils.GetDataFromWeb( + $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language}/Strings/customlevel_strings.json" + ) + .Result; + + if (customLevelStringsContent != null) + LoadCustomLevelStrings(customLevelStringsContent); + else + { + var customLevelStringsPath = Path.Combine( + GetAssetDir(AssetType.Strings, Utils.Language), + "customlevel_strings.json" + ); + + if (File.Exists(customLevelStringsPath)) + LoadCustomLevelStrings(File.ReadAllText(customLevelStringsPath)); + } + + // load translationRegexs + var customLevelRegexsContent = Utils.GetDataFromWeb( + $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language}/Strings/customlevel_regexs.json" + ) + .Result; + + if (customLevelRegexsContent != null) + LoadCustomLevelRegexs(customLevelRegexsContent); + else + { + var customLevelRegexsPath = Path.Combine( + GetAssetDir(AssetType.Strings, Utils.Language), + "customlevel_regexs.json" + ); + + if (File.Exists(customLevelRegexsPath)) + LoadCustomLevelRegexs(File.ReadAllText(customLevelRegexsPath)); + } + + // load changelog + + LoadChangelogText(); + + // load tips + var izTipsContent = Utils.GetDataFromWeb( + $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language}/Strings/tips_iz.json" + ) + .Result; + + if (izTipsContent != null) + LoadIZStrings(izTipsContent); + else + { + var izTipsPath = Path.Combine(GetAssetDir(AssetType.Strings, Utils.Language), "tips_iz.json"); + + if (File.Exists(izTipsPath)) + LoadIZStrings(File.ReadAllText(izTipsPath)); + } + + var fsTipsContent = Utils.GetDataFromWeb( + $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language}/Strings/tips_fs.json" + ) + .Result; + + if (fsTipsContent != null) + LoadFsStrings(fsTipsContent); + else + { + var fsTipsPath = Path.Combine(GetAssetDir(AssetType.Strings, Utils.Language), "tips_fs.json"); + + if (File.Exists(fsTipsPath)) + LoadFsStrings(File.ReadAllText(fsTipsPath)); + } + + // load almanacs + + var almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); + + if (!Directory.Exists(almanacDir)) + Directory.CreateDirectory(almanacDir); + + var plantAlmanacContent = Utils.GetDataFromWeb( + $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language}/Almanac/LawnStringsTranslate.json" + ) + .Result; + + if (plantAlmanacContent != null) + AlmanacPlantMenu_Patch.LoadPlantAlmanacData(plantAlmanacContent); + else + { + var path = Path.Combine(almanacDir, "LawnStringsTranslate.json"); + + if (File.Exists(path)) + AlmanacPlantMenu_Patch.LoadPlantAlmanacData(File.ReadAllText(path)); + } + + var zombieAlmanacContent = Utils.GetDataFromWeb( + $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language}/Almanac/ZombieStringsTranslate.json" + ) + .Result; + + if (zombieAlmanacContent != null) + AlmanacZombieMenu_Patch.AlmanacJson = zombieAlmanacContent; + else + { + var path = Path.Combine(almanacDir, "ZombieStringsTranslate.json"); + + if (File.Exists(path)) + AlmanacZombieMenu_Patch.AlmanacJson = File.ReadAllText(path); + } + + var detailStringsContent = Utils.GetDataFromWeb( + $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language}/Almanac/DetailStringsTranslate.json" + ) + .Result; + + if (detailStringsContent != null) + LoadDetailStrings(detailStringsContent); + else + { + var path = Path.Combine(almanacDir, "DetailStringsTranslate.json"); + + if (File.Exists(path)) + LoadDetailStrings(File.ReadAllText(path)); + } + + // load travel_buffs + + LoadTravelBuffs(); + + // load abyss buffs + + //Patches.Modes.Abyss.AbyssBuffMenu_Patch.LoadAbyssBuffData(); + + SaveStrings(); + DumpJson(); + } + else + { + if (!Directory.Exists(stringDir)) + Directory.CreateDirectory(stringDir); + + try + { + foreach (var filepath in Directory.EnumerateFiles(stringDir, "*.json", SearchOption.AllDirectories)) + { + var fileName = Path.GetFileNameWithoutExtension(filepath); + StringStore.StringsDict[fileName] = filepath; + + if (ModFeatures.IsDebug) + Log.LogInfo("Loading File : " + filepath); + + var jsonString = File.ReadAllText(filepath); + + if (fileName.EndsWith("translation_strings")) + LoadTranslationStrings(jsonString); + else if (fileName.EndsWith("translation_regexs")) + LoadTranslationRegexs(jsonString); + else if (fileName.EndsWith("customlevel_strings")) + LoadCustomLevelStrings(jsonString); + else if (fileName.EndsWith("customlevel_regexs")) + LoadCustomLevelRegexs(jsonString); + else if (fileName.EndsWith("tips_iz")) + LoadIZStrings(jsonString); + else if (fileName.EndsWith("tips_fs")) + LoadFsStrings(jsonString); + //else if(fileName.EndsWith("abyss_buffs")) + //{ + // Patches.Modes.Abyss.AbyssBuffMenu_Patch.LoadAbyssBuffData(); + //} + else if (fileName.EndsWith("travel_buffs")) + LoadTravelBuffs(); + } + + var almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); + + if (!Directory.Exists(almanacDir)) + Directory.CreateDirectory(almanacDir); + + var plantAlmanacPath = Path.Combine(almanacDir, "LawnStringsTranslate.json"); + + if (File.Exists(plantAlmanacPath)) + AlmanacPlantMenu_Patch.LoadPlantAlmanacData(File.ReadAllText(plantAlmanacPath)); + + var zombieAlmanacPath = Path.Combine(almanacDir, "ZombieStringsTranslate.json"); + + if (File.Exists(zombieAlmanacPath)) + AlmanacZombieMenu_Patch.AlmanacJson = File.ReadAllText(zombieAlmanacPath); + + var detailStringsPath = Path.Combine(almanacDir, "DetailStringsTranslate.json"); + + if (File.Exists(detailStringsPath)) + LoadDetailStrings(File.ReadAllText(detailStringsPath)); + + LoadChangelogText(); + + SaveStrings(); + DumpJson(); + } + catch (Exception e) + { + Log.LogError("Error loading string."); + Log.LogError(e.GetType() + " " + e.Message); + } + } + + Log.LogInfo("Strings loaded successfully."); + } + + internal static void LoadTranslationStrings(string content) + { + var dictionary = + System.Text.Json.JsonSerializer.Deserialize>(content); + + foreach (var (key, value) in dictionary) + StringStore.TranslationString[key] = value; + } + + internal static void LoadTranslationRegexs(string content) + { + var dictionary = + System.Text.Json.JsonSerializer.Deserialize>(content); + + foreach (var (key, value) in dictionary) + StringStore.TranslationStringRegex[key] = value; + + Zombie_Patch.LoadHpStrings(); + } + + internal static void LoadCustomLevelStrings(string content) + { + var dictionary = + System.Text.Json.JsonSerializer.Deserialize>(content); + + foreach (var (key, value) in dictionary) + StringStore.CustomLevelString[key] = value; + } + + internal static void LoadCustomLevelRegexs(string content) + { + var dictionary = + System.Text.Json.JsonSerializer.Deserialize>(content); + + foreach (var (key, value) in dictionary) + StringStore.CustomLevelStringRegex[key] = value; + } + + internal static void LoadIZStrings(string content) + { + var (izLevelData, _) = DumpIZStrings(); + + var izTranslatedTips = System.Text.Json.JsonSerializer.Deserialize>(content); + + foreach (var level in izLevelData) + { + var data = level.text; + var levelData = JsonUtility.FromJson(data); + + if (levelData.tips == null) + continue; + + if (!izTranslatedTips.ContainsKey(level.name) || + StringStore.IZTipCollectionString.ContainsKey(levelData.tips)) + continue; + + StringStore.IZLevelTipDictionary.Add(level.name, izTranslatedTips[level.name]); + StringStore.IZTipCollectionString.Add(levelData.tips, izTranslatedTips[level.name]); + } + } + + internal static void LoadFsStrings(string content) + { + var (fusionShowcaseData, _) = DumpFSStrings(); + + var fsTranslatedTips = System.Text.Json.JsonSerializer.Deserialize>(content); + + foreach (var level in fusionShowcaseData) + { + var data = level.text; + var levelData = JsonUtility.FromJson(data); + + if (levelData.tips == null) + continue; + + if (!fsTranslatedTips.ContainsKey(level.name) || + StringStore.FSTipCollectionString.ContainsKey(levelData.tips)) + continue; + + StringStore.FSLevelTipDictionary.Add(level.name, fsTranslatedTips[level.name]); + StringStore.FSTipCollectionString.Add(levelData.tips, fsTranslatedTips[level.name]); + } + } + + internal static void LoadDetailStrings(string content) + { + var (detailStringsData, _) = DumpDetailStrings(); + + var translatedDetailStrings = System.Text.Json.JsonSerializer.Deserialize>(content); + AlmanacSelectMenu_Patch.DetailStrings = translatedDetailStrings; + + foreach (var detailString in detailStringsData.details) + if (translatedDetailStrings.TryGetValue(detailString.title, out var s)) + AlmanacSelectMenu_Patch.DetailTranslateStrings[detailString.text] = s; + } + + internal static void LoadChangelogText() + { + var stringDir = GetAssetDir(AssetType.Strings, Utils.Language); + var changelogDir = Path.Combine(stringDir, "changelog.txt"); + + if (!File.Exists(changelogDir)) + File.WriteAllText(changelogDir, ""); + + var changelogText = File.ReadAllText(changelogDir); + + if (!Core.Instance.ConfigUseLocal.Value) + { + var changelogContent = Utils.GetDataFromWeb( + $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language}/Strings/changelog.txt" + ) + .Result; + + if (changelogContent != null) + changelogText = changelogContent; + } + else + changelogText = File.ReadAllText(changelogDir); + + NoticePauseMenu_Patch.ChangelogText = changelogText; + } + + internal static void LoadTravelBuffs() + { + if (!Core.Instance.ConfigUseLocal.Value) + { + var travelBuffsContent = Utils.GetDataFromWeb( + $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language}/Strings/travel_buffs.json" + ) + .Result; + + if (travelBuffsContent != null) + TravelMgr_Patch.GenerateTranslatedTravelBuffs(travelBuffsContent); + else + { + var travelBuffsPath = Path.Combine( + GetAssetDir(AssetType.Strings, Utils.Language), + "travel_buffs.json" + ); + + if (File.Exists(travelBuffsPath)) + TravelMgr_Patch.GenerateTranslatedTravelBuffs(File.ReadAllText(travelBuffsPath)); + } + } + else + { + var stringDir = GetAssetDir(AssetType.Strings, Utils.Language); + + foreach (var jsonString in from filepath in + Directory.EnumerateFiles(stringDir, "*.json", SearchOption.AllDirectories) + let fileName = Path.GetFileNameWithoutExtension(filepath) + let jsonString = File.ReadAllText(filepath) + where fileName.EndsWith("travel_buffs") + select jsonString) + TravelMgr_Patch.GenerateTranslatedTravelBuffs(jsonString); + } + } + + internal static void LoadTextures() + { + // Default or Custom Texturse -> English Textures -> Localized Textures + try + { + if (!Core.Instance.ConfigDefaultTextures.Value) + LoadCustomTextures(); + } + catch (Exception e) + { + Log.LogError("Error loading texture setting."); + Log.LogError($"{e.GetType()} {e.Message}"); + } + + if (ModFeatures.IsMultiLanguage) + { + LoadLocalizedTextures(Utils.Language); + LoadLocalizedSprites(Utils.Language); + } + else + LoadLocalizedTextures(); + + Log.LogInfo("Textures loaded successfully."); + } + + // ReSharper disable once FunctionComplexityOverflow + internal static void LoadLocalizedTextures(Utils.LanguageEnum? language = null) + { + var textureDir = GetAssetDir(AssetType.Textures, language); + + if (!Directory.Exists(textureDir)) + Directory.CreateDirectory(textureDir); + + try + { + var localTocDir = Path.Combine(textureDir, "Texture_TOC.json"); + + if (!File.Exists(localTocDir)) + File.WriteAllText(localTocDir, "{}"); + + var localTocContent = File.ReadAllText(localTocDir); + var localToc = System.Text.Json.JsonSerializer.Deserialize>(localTocContent); + + var basePath = Core.ModDirectory; + + if (!Core.Instance.ConfigUseLocal.Value) + { + var textureTocRequest = Utils.GetDataFromWeb( + $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language}/Textures/Texture_TOC.json" + ) + .Result; + + if (textureTocRequest != null) + { + var textureToc = + JsonConvert.DeserializeObject>(textureTocRequest); + + List toDownload = new(); + + foreach (var pair in textureToc) + { + if (!localToc.TryGetValue(pair.Key, out var value)) + { + toDownload.Add(pair.Key); + continue; + } + + if (pair.Value != value) + toDownload.Add(pair.Key); + + if (!File.Exists(Path.Combine(basePath, pair.Key))) + toDownload.Add(pair.Key); + } + + var toWriteText = SerializeWithIndentation(textureToc); + File.WriteAllText(localTocDir, toWriteText); + + foreach (var path in toDownload) + { + var downloadPath = Path.Combine(basePath, path); + + const string BaseUrl = + "https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/"; + + var imageData = Utils.GetByteDataFromWeb($"{BaseUrl}{path}").Result; + + if (imageData == null) + continue; + + var fileName = Path.GetFileName(downloadPath); + _ = Utils.LoadImage(imageData); + TextureStore.TextureDict[fileName] = imageData; + + if (!Directory.Exists(Path.GetDirectoryName(downloadPath))) + Directory.CreateDirectory(Path.GetDirectoryName(downloadPath)); + + File.WriteAllBytes(downloadPath, imageData); + } + } + } + + foreach (var path in Directory.EnumerateFiles(textureDir, "*.png", SearchOption.AllDirectories) + .Where( + p => (!p.Contains("[Custom Textures]", StringComparison.OrdinalIgnoreCase) || + !Core.Instance.ConfigDefaultTextures.Value) && + (localToc.ContainsKey(p.Replace(basePath + "\\", "").Replace("\\", "/")) || + SerializeWithIndentation(localToc) == "{}") + )) + { + if (ModFeatures.IsDebug) + Log.LogDebug("Loading File : " + path); + + var imageData = File.ReadAllBytes(path); + _ = Utils.LoadImage(imageData); + TextureStore.TextureDict[Path.GetFileNameWithoutExtension(path)] = imageData; + } + } + + catch (Exception e) + { + Log.LogError("Error loading Texture."); + Log.LogError(e.GetType() + " " + e.Message); + } + } + + // ReSharper disable once FunctionComplexityOverflow + internal static void LoadLocalizedSprites(Utils.LanguageEnum? language = null) + { + var textureDir = GetAssetDir(AssetType.Sprites, language); + + if (!Directory.Exists(textureDir)) + Directory.CreateDirectory(textureDir); + + try + { + var trueTextureDir = GetAssetDir(AssetType.Textures, language); + var localTocDir = Path.Combine(trueTextureDir, "Texture_TOC.json"); + + if (!File.Exists(localTocDir)) + File.WriteAllText(localTocDir, "{}"); + + var localTocContent = File.ReadAllText(localTocDir); + var localToc = System.Text.Json.JsonSerializer.Deserialize>(localTocContent); + + var basePath = Core.ModDirectory; + + if (!Core.Instance.ConfigUseLocal.Value) + { + var textureTocRequest = Utils.GetDataFromWeb( + $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language}/Textures/Texture_TOC.json" + ) + .Result; + + if (textureTocRequest != null) + { + var textureToc = + JsonConvert.DeserializeObject>(textureTocRequest); + + List toDownload = new(); + + foreach (var pair in textureToc) + { + if (!localToc.TryGetValue(pair.Key, out var value)) + { + toDownload.Add(pair.Key); + continue; + } + + if (pair.Value != value) + toDownload.Add(pair.Key); + + if (!File.Exists(Path.Combine(basePath, pair.Key))) + toDownload.Add(pair.Key); + } + + var toWriteText = SerializeWithIndentation(textureToc); + File.WriteAllText(localTocDir, toWriteText); + + foreach (var path in toDownload) + { + var downloadPath = Path.Combine(basePath, path); + + const string BaseUrl = + "https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/"; + + var url = $"{BaseUrl}{path}"; + + var imageData = Utils.GetByteDataFromWeb(url).Result; + + if (imageData == null) + continue; + + var fileName = Path.GetFileName(downloadPath); + _ = Utils.LoadImage(imageData); + TextureStore.SpriteDict[fileName] = imageData; + + if (!Directory.Exists(Path.GetDirectoryName(downloadPath))) + Directory.CreateDirectory(Path.GetDirectoryName(downloadPath)); + + File.WriteAllBytes(downloadPath, imageData); + } + } + } + + foreach (var path in Directory.EnumerateFiles(textureDir, "*.png", SearchOption.AllDirectories) + .Where( + p => (!p.Contains("[Custom Textures]", StringComparison.OrdinalIgnoreCase) || + !Core.Instance.ConfigDefaultTextures.Value) && + (localToc.ContainsKey(p.Replace(basePath + "\\", "").Replace("\\", "/")) || + SerializeWithIndentation(localToc) == "{}") + )) + { + if (ModFeatures.IsDebug) + Log.LogDebug("Loading File (Sprite): " + path); + + var imageData = File.ReadAllBytes(path); + _ = Utils.LoadImage(imageData); + TextureStore.SpriteDict[Path.GetFileNameWithoutExtension(path)] = imageData; + } + } + + catch (Exception e) + { + Log.LogError("Error loading Texture."); + Log.LogError(e.GetType() + " " + e.Message); + } + } + + internal static void LoadDefaultTextures() + { + if (!Core.Instance.ConfigDefaultTextures.Value) + return; + + var textureDefaultDir = Path.Combine( + Core.ModDirectory, + nameof(AssetType.Dumps), + "Default Textures [Do Not Remove]" + ); + + if (!Directory.Exists(textureDefaultDir)) + Directory.CreateDirectory(textureDefaultDir); + + try + { + var trueTextureDir = Path.Combine(Core.ModDirectory, "[Custom Textures]"); + var localTocDir = Path.Combine(trueTextureDir, "Default_TOC.json"); + + if (!File.Exists(localTocDir)) + File.WriteAllText(localTocDir, "{}"); + + var localTocContent = File.ReadAllText(localTocDir); + var localToc = System.Text.Json.JsonSerializer.Deserialize>(localTocContent); + + var basePath = Core.ModDirectory; + + if (!Core.Instance.ConfigUseLocal.Value) + { + var textureTocRequest = Utils.GetDataFromWeb( + $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/{Uri.EscapeDataString("[Custom Textures]")}/Default_TOC.json" + ) + .Result; + + if (textureTocRequest != null) + { + var textureToc = + JsonConvert.DeserializeObject>(textureTocRequest); + + List toDownload = new(); + + foreach (var pair in textureToc) + { + if (!localToc.TryGetValue(pair.Key, out var value)) + { + toDownload.Add(pair.Key); + continue; + } + + if (pair.Value != value) + toDownload.Add(pair.Key); + + if (!File.Exists(Path.Combine(basePath, pair.Key))) + toDownload.Add(pair.Key); + } + + var toWriteText = SerializeWithIndentation(textureToc); + File.WriteAllText(localTocDir, toWriteText); + + foreach (var path in toDownload) + { + var downloadPath = Path.Combine(basePath, path); + + const string BaseUrl = + "https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/"; + + var url = $"{BaseUrl}{path}"; + + var imageData = Utils.GetByteDataFromWeb(url).Result; + + if (imageData == null) + continue; + + var fileName = Path.GetFileName(downloadPath); + _ = Utils.LoadImage(imageData); + TextureStore.TextureDict[fileName] = imageData; + + if (!Directory.Exists(Path.GetDirectoryName(downloadPath))) + Directory.CreateDirectory(Path.GetDirectoryName(downloadPath)); + + File.WriteAllBytes(downloadPath, imageData); + } + } + } + + foreach (var filepath in Directory.EnumerateFiles( + textureDefaultDir, + "*.png", + SearchOption.AllDirectories + )) + { + if (!localToc.ContainsKey(filepath.Replace(basePath + "\\", "").Replace("\\", "/")) && + SerializeWithIndentation(localToc) != "{}") + continue; + + var imageData = File.ReadAllBytes(filepath); + _ = Utils.LoadImage(imageData); + TextureStore.TextureDict[Path.GetFileNameWithoutExtension(filepath)] = imageData; + } + } + + catch (Exception e) + { + Log.LogError("Error loading Texture."); + Log.LogError(e.GetType() + " " + e.Message); + } + } + + internal static void LoadCustomTextures() + { + var texturePackDir = Path.Combine(Core.ModDirectory, "[Custom Textures]"); + + if (!Directory.Exists(texturePackDir)) + Directory.CreateDirectory(texturePackDir); + + try + { + var trueTextureDir = Path.Combine(Core.ModDirectory, "[Custom Textures]"); + var localTocDir = Path.Combine(trueTextureDir, "Custom_TOC.json"); + + if (!File.Exists(localTocDir)) + File.WriteAllText(localTocDir, "{}"); + + var localTocContent = File.ReadAllText(localTocDir); + var localToc = System.Text.Json.JsonSerializer.Deserialize>(localTocContent); + + var basePath = Core.ModDirectory; + + if (!Core.Instance.ConfigUseLocal.Value) + { + var textureTocRequest = Utils.GetDataFromWeb( + $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/{Uri.EscapeDataString("[Custom Textures]")}/Custom_TOC.json" + ) + .Result; + + if (textureTocRequest != null) + { + var textureToc = + JsonConvert.DeserializeObject>(textureTocRequest); + + List toDownload = new(); + + foreach (var pair in textureToc) + { + if (!localToc.TryGetValue(pair.Key, out var value) || pair.Value != value) + { + toDownload.Add(pair.Key); + continue; + } + + if (!File.Exists(Path.Combine(basePath, pair.Key))) + toDownload.Add(pair.Key); + } + + var toWriteText = SerializeWithIndentation(textureToc); + File.WriteAllText(localTocDir, toWriteText); + + foreach (var path in toDownload) + { + var downloadPath = Path.Combine(basePath, path); + + const string BaseUrl = + "https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/"; + + var url = $"{BaseUrl}{path}"; + + var imageData = Utils.GetByteDataFromWeb(url).Result; + + if (imageData == null) + continue; + + var fileName = Path.GetFileName(downloadPath); + _ = Utils.LoadImage(imageData); + TextureStore.TextureDict[fileName] = imageData; + + if (!Directory.Exists(Path.GetDirectoryName(downloadPath))) + Directory.CreateDirectory(Path.GetDirectoryName(downloadPath)); + + File.WriteAllBytes(downloadPath, imageData); + } + } + } + + foreach (var filepath in Directory.EnumerateFiles(texturePackDir, "*.png", SearchOption.AllDirectories)) + { + if (!localToc.ContainsKey(filepath.Replace(basePath + "\\", "").Replace("\\", "/")) && + SerializeWithIndentation(localToc) != "{}") + continue; + + var imageData = File.ReadAllBytes(filepath); + _ = Utils.LoadImage(imageData); + TextureStore.TextureDict[Path.GetFileNameWithoutExtension(filepath)] = imageData; + } + } + + catch (Exception e) + { + Log.LogError("Error loading Texture."); + Log.LogError(e.GetType() + " " + e.Message); + } + } + + internal static void SaveStrings() + { + var stringDir = GetAssetDir(AssetType.Strings, ModFeatures.IsMultiLanguage ? Utils.Language : null); + + if (!Directory.Exists(stringDir)) + Directory.CreateDirectory(stringDir); + + // save regexs + + var translationStringRegex = SerializeWithIndentation(StringStore.TranslationStringRegex, 2); + + File.WriteAllText(Path.Combine(stringDir, "translation_regexs.json"), translationStringRegex); + + // save strings + + var translationString = SerializeWithIndentation(StringStore.TranslationString, 2); + + File.WriteAllText(Path.Combine(stringDir, "translation_strings.json"), translationString); + + // save iz tips + + var izTipCollectionString = SerializeWithIndentation(StringStore.IZLevelTipDictionary, 1, ' '); + + File.WriteAllText(Path.Combine(stringDir, "tips_iz.json"), izTipCollectionString); + + // save fs tips + + var fsLevelTipDictionary = SerializeWithIndentation(StringStore.FSLevelTipDictionary); + + File.WriteAllText(Path.Combine(stringDir, "tips_fs.json"), fsLevelTipDictionary); + + // save changelog + + if (NoticePauseMenu_Patch.ChangelogText != "") + File.WriteAllText(Path.Combine(stringDir, "changelog.txt"), NoticePauseMenu_Patch.ChangelogText); + + // save abyss buffs + + //if(Patches.Modes.Abyss.AbyssBuffMenu_Patch.abyssBuffData != new Dictionary()) + //{ + // string abyssBuffData = SerializeWithIndentation(Patches.Modes.Abyss.AbyssBuffMenu_Patch.abyssBuffData, 2); + // File.WriteAllText(Path.Combine(stringDir, "abyss_buffs.json"), abyssBuffData); + //} + + // save almanacs + + var almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); + + if (AlmanacPlantMenu_Patch.AlmanacJson != "") + File.WriteAllText( + Path.Combine(almanacDir, "LawnStringsTranslate.json"), + AlmanacPlantMenu_Patch.AlmanacJson + ); + + if (AlmanacZombieMenu_Patch.AlmanacJson != "") + File.WriteAllText( + Path.Combine(almanacDir, "ZombieStringsTranslate.json"), + AlmanacZombieMenu_Patch.AlmanacJson + ); + + if (AlmanacSelectMenu_Patch.DetailStrings == new Dictionary()) + return; + + var detailStrings = SerializeWithIndentation(AlmanacSelectMenu_Patch.DetailStrings); + + File.WriteAllText(Path.Combine(almanacDir, "DetailStringsTranslate.json"), detailStrings); + } + + public static string SerializeWithIndentation(T value, int size = 4, char indentChar = ' ') + { + var stringWriter = new StringWriter(); + + using (JsonTextWriter writer = new(stringWriter)) + { + writer.Formatting = Formatting.Indented; + writer.Indentation = size; + writer.IndentChar = indentChar; + + Newtonsoft.Json.JsonSerializer serializer = new(); + serializer.Serialize(writer, value, typeof(T)); + } + + return stringWriter.ToString(); + } + + public static void DumpJson() + { + var dumpDir = GetAssetDir(AssetType.Dumps); + + if (!Directory.Exists(dumpDir)) + Directory.CreateDirectory(dumpDir); + + var lawnStrings = Resources.Load("LawnStrings").text; + var zombieStrings = Resources.Load("ZombieStrings").text; + //string AbyssBuffData = Resources.Load("AbyssBuffData").text; + File.WriteAllText(Path.Combine(dumpDir, "LawnStrings.json"), lawnStrings); + File.WriteAllText(Path.Combine(dumpDir, "ZombieStrings.json"), zombieStrings); + //File.WriteAllText(Path.Combine(dumpDir, "AbyssBuffData.json"), AbyssBuffData); + + // Dump IZ tips. + var (_, izLevelDataDump) = DumpIZStrings(); + + File.WriteAllText( + Path.Combine(dumpDir, "tips_iz.json"), + System.Text.Json.JsonSerializer.Serialize( + izLevelDataDump, + new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + } + ) + ); + + // Dump fusion showcase tips. + var (_, fusionShowcaseDataDump) = DumpFSStrings(); + + File.WriteAllText( + Path.Combine(dumpDir, "tips_fs.json"), + System.Text.Json.JsonSerializer.Serialize( + fusionShowcaseDataDump, + new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + } + ) + ); + + // Dump almanac mechanics. + var (_, detailStrings) = DumpDetailStrings(); + + File.WriteAllText( + Path.Combine(dumpDir, "DetailStrings.json"), + System.Text.Json.JsonSerializer.Serialize( + detailStrings, + new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + } + ) + ); + } + + public static (Il2CppArrayBase, Dictionary) DumpIZStrings() + { + var izLevelData = Resources.LoadAll("izleveldata"); + var izLevelDataDump = new Dictionary(); + + foreach (var level in izLevelData) + { + var data = level.text; + var levelData = JsonUtility.FromJson(data); + + if (levelData.tips != null) + izLevelDataDump.Add(level.name, levelData.tips); + } + + return (izLevelData, izLevelDataDump); + } + + public static (Il2CppArrayBase, Dictionary) DumpFSStrings() + { + var fusionShowcaseData = Resources.LoadAll("leveldata/explore"); + var fusionShowcaseDataDump = new Dictionary(); + + foreach (var level in fusionShowcaseData) + { + var data = level.text; + var levelData = JsonUtility.FromJson(data); + + if (levelData.tips != null) + fusionShowcaseDataDump.Add(level.name, levelData.tips); + } + + return (fusionShowcaseData, fusionShowcaseDataDump); + } + + public static (Il2CppAlmanacDataClass, Dictionary) DumpDetailStrings() + { + var detailStringsData = Resources.Load("detailstrings").text; + var detailStrings = JsonUtility.FromJson(detailStringsData); + Dictionary detailStringsDump = new(); + + foreach (var detailString in detailStrings.details) + detailStringsDump[detailString.title] = detailString.text; + + return (detailStrings, detailStringsDump); + } + + public static void DumpUntranslatedStrings(string text) + { + Debug.Assert(ModFeatures.IsDebug, nameof(ModFeatures.IsDebug)); + Log.LogDebug($"Untranslated String: {text}"); + var dumpDir = GetAssetDir(AssetType.Dumps); + var jsonFile = Path.Combine(dumpDir, "UntranslatedStrings.json"); + + if (!Directory.Exists(dumpDir)) + Directory.CreateDirectory(dumpDir); + + if (!File.Exists(jsonFile)) + File.WriteAllText(jsonFile, "{}"); // Initialize empty JSON object + + var json = File.ReadAllText(jsonFile); + var untranslatedStrings = System.Text.Json.JsonSerializer.Deserialize>(json); + + if (!untranslatedStrings.TryAdd(text, text)) + return; + + JsonSerializerOptions options = new() + { + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + WriteIndented = true, + }; + + File.WriteAllText(jsonFile, System.Text.Json.JsonSerializer.Serialize(untranslatedStrings, options)); + } + + internal static void LoadLanguage() + { + Debug.Assert(ModFeatures.IsMultiLanguage, nameof(ModFeatures.IsMultiLanguage)); + + try + { + // Load the language preference as a string and parse it into the enum + var 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() + { + Debug.Assert(ModFeatures.IsMultiLanguage, nameof(ModFeatures.IsMultiLanguage)); + + try + { + // Save the current language as a string + Core.Instance.ConfigLanguage.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/Source/FontHandler.cs b/Source/FontHandler.cs new file mode 100644 index 0000000..dd730fc --- /dev/null +++ b/Source/FontHandler.cs @@ -0,0 +1,43 @@ +namespace PvZ_Fusion_Translator; + +public static class FontHandler +{ + public static Font LoadFont(string pathFromModFolder, bool throwException) + { + var fontFilePath = Path.Combine(Core.ModDirectory, pathFromModFolder); + + 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) + { + var fontAsset = TMP_FontAsset.CreateFontAsset(font); + + if (fontAsset != null) + return fontAsset; + + Log.LogWarning($"Failed to create TMP_FontAsset from font '{font.name}'."); + return null; + } + + public static TMP_FontAsset LoadTMPFont(string pathFromModFolder, bool throwException) + { + var font = LoadFont(pathFromModFolder, throwException); + + if (!font) + return null; + + var fontAsset = font.ConvertToTMP(); + return fontAsset; + } +} diff --git a/Source/Log.cs b/Source/Log.cs new file mode 100644 index 0000000..04bd92f --- /dev/null +++ b/Source/Log.cs @@ -0,0 +1,60 @@ +// ReSharper disable once RedundantUsingDirective +using System.Drawing; + +namespace PvZ_Fusion_Translator; + +internal static class Log +{ +#if MELONLOADER + public static void LogDebug(object txt) => Melon.Logger.Msg(ColorARGB.Gray, txt); + + public static void LogDebug(string txt) => Melon.Logger.Msg(ColorARGB.Gray, txt); + + public static void LogDebug(string txt, params object[] args) => + Melon.Logger.Msg(ColorARGB.Gray, txt, args); + + public static void LogInfo(object txt) => Melon.Logger.Msg(ColorARGB.Blue, txt); + + public static void LogInfo(string txt) => Melon.Logger.Msg(ColorARGB.Blue, txt); + + public static void LogInfo(string txt, params object[] args) => + Melon.Logger.Msg(ColorARGB.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); +#elif BEPINEX + + public static void LogDebug(object txt) => Core.Log.LogDebug(txt); + + public static void LogDebug(string txt) => Core.Log.LogDebug(txt); + + public static void LogDebug(string txt, params object[] args) => Core.Log.LogDebug(string.Format(txt, args)); + + public static void LogInfo(object txt) => Core.Log.LogInfo(txt); + + public static void LogInfo(string txt) => Core.Log.LogInfo(txt); + + public static void LogInfo(string txt, params object[] args) => Core.Log.LogInfo(string.Format(txt, args)); + + public static void LogWarning(object txt) => Core.Log.LogWarning(txt); + + public static void LogWarning(string txt) => Core.Log.LogWarning(txt); + + public static void LogWarning(string txt, params object[] args) => Core.Log.LogWarning(string.Format(txt, args)); + + public static void LogError(object txt) => Core.Log.LogError(txt); + + public static void LogError(string txt) => Core.Log.LogError(txt); + + public static void LogError(string txt, params object[] args) => Core.Log.LogError(string.Format(txt, args)); +#endif +} diff --git a/Source/ModFeatures.cs b/Source/ModFeatures.cs new file mode 100644 index 0000000..2b7335e --- /dev/null +++ b/Source/ModFeatures.cs @@ -0,0 +1,97 @@ +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator; + +public static class ModFeatures +{ + public enum ModType + { + ReloadStrings, ReloadTextures, ExportLevelStrings, + } + + private sealed class ModFeature(string name, ModType modType, KeyCode keyCode, bool defaultValue = false) + { + // ReSharper disable once UnusedMember.Local + public string Name { get; private set; } = name; + + // ReSharper disable once MemberCanBePrivate.Local + public ModType ModType { get; } = modType; + + public KeyCode KeyCode { get; } = keyCode; + + // ReSharper disable once UnusedMember.Local + public bool IsActive { get; set; } = defaultValue; + + public void ToggleFeature() + { + switch (ModType) + { + case ModType.ReloadStrings: + StringStore.Reload(); + Core.ShowToast("Strings Reloaded!"); + return; + case ModType.ReloadTextures: + TextureStore.Reload(); + Core.ShowToast("Textures Reloaded!"); + return; + case ModType.ExportLevelStrings: + var customMenu = UnityEngine.Object.FindObjectOfType(); + + if (!customMenu) + return; + + if (!customMenu.isActiveAndEnabled) + return; + + Patches.Modes.Super_Editor.GameLevel.LevelManager_Patch + .ExportLevelStrings(customMenu.LevelData); + + Core.ShowToast("Dumped level strings!"); + return; + default: return; + } + } + } + + public static bool IsDebug { get; } = IsDefined("PVZ_FUSION_TRANSLATOR_DEBUG"); + + public static bool IsTesting { get; } = IsDefined("PVZ_FUSION_TRANSLATOR_TESTING"); + + public static bool IsAudioTesting { get; } = IsDefined("PVZ_FUSION_TRANSLATOR_AUDIO_TESTING"); + + public static bool IsMultiLanguage { get; } = IsDefined("PVZ_FUSION_TRANSLATOR_MULTI_LANGUAGE", true); + + private static readonly Dictionary s_featureLists = new() + { + { ModType.ReloadStrings, new("Reload Strings", ModType.ReloadStrings, KeyCode.Home, true) }, + { ModType.ReloadTextures, new("Reload Textures", ModType.ReloadTextures, KeyCode.End, true) }, + { + ModType.ExportLevelStrings, + new("Export Level Strings", ModType.ExportLevelStrings, KeyCode.N, true) + }, + }; + + public static void ToggleFeature(ModType modType) + { + if (s_featureLists.TryGetValue(modType, out var list)) + list.ToggleFeature(); + } + + public static void OnLateUpdate() + { + foreach (var (_, feature) in s_featureLists) + if (feature.KeyCode != KeyCode.None && Enum.IsDefined(feature.KeyCode)) + if (Input.GetKeyDown(feature.KeyCode)) + feature.ToggleFeature(); + } + + private static bool IsDefined(string env, bool fallback = false) + { + var ret = + Environment.GetEnvironmentVariable(env)?.ToUpperInvariant() is not "FALSE" and not "0" and var value && + (!string.IsNullOrWhiteSpace(value) || fallback); + + Log.LogInfo($"The feature '{env}' is {(ret ? "enabled" : "disabled")}."); + return ret; + } +} diff --git a/Source/Patches/BaseTextObjects/InGameText_Patch.cs b/Source/Patches/BaseTextObjects/InGameText_Patch.cs new file mode 100644 index 0000000..695c26a --- /dev/null +++ b/Source/Patches/BaseTextObjects/InGameText_Patch.cs @@ -0,0 +1,369 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; +using PvZ_Fusion_Translator.Patches.Modes.Odyssey; +using System.Text.RegularExpressions; + +namespace PvZ_Fusion_Translator.Patches.BaseTextObjects; + +[HarmonyPatch(typeof(InGameText))] +public static class InGameText_Patch +{ +#pragma warning disable CA2211 + public static string CurrentText = ""; +#pragma warning restore CA2211 + [HarmonyPatch(nameof(InGameText.ShowText)), HarmonyPostfix] + public static void ShowText(InGameText __instance) => TranslateInGameText(__instance); + + [HarmonyPatch(nameof(InGameText.DebugWarning)), HarmonyPostfix] + public static void DebugWarning(InGameText __instance) => TranslateInGameText(__instance); + + [HarmonyPatch(nameof(InGameText.Update)), HarmonyPostfix] + public static void Update(InGameText __instance) => TranslateInGameText(__instance); + + public static void TranslateInGameText(InGameText __instance) + { + TextMeshProUGUI txt = null; + + if (__instance.textMesh == null || __instance.textHead == null) + { + if (__instance.TryGetComponent(out TextMeshProUGUI selfTxt)) + txt = selfTxt; + } + else + txt = __instance.textMesh; + + if (txt == null) + return; + + if (!txt.gameObject.active) + return; + + TranslateInGameTextMesh(txt); + } + + public static void TranslateInGameTextMesh(TextMeshProUGUI txt) + { + if (txt == null) + return; + + if (txt.text == CurrentText) + return; + + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + var originalText = txt.text; + var lockedPlantMatch = CheckLockedMessage(originalText); + var travelMatch = TravelMgr_Patch.MatchTravelBuff(originalText); + var godsGachaCheck = CheckGodsGachaPopup(originalText); + var godsGachaMatch = ""; + var superEditorPlantMatch = CheckSuperEditorPopup(originalText); + var customLevelRegexMatch = CheckCustomLevelRegex(originalText); + var qualityCheckMatch = CheckQualityUpgrade(originalText); + + godsGachaMatch = godsGachaCheck switch + { + 1 or 2 or 3 => TranslateGodsGachaPopup(originalText, godsGachaCheck), + _ => godsGachaMatch, + }; + + if (godsGachaMatch != "") + { + txt.text = godsGachaMatch; + + if (txt.gameObject.name.Contains("main")) + { + originalText = txt.text; + var shadowText = txt.transform.parent.Find("Text_shadow"); + + if (shadowText != null) + shadowText.GetComponent().text = Utils.RemoveColorTags(originalText); + } + } + else if (travelMatch != "") + { + txt.text = TravelMgr_Patch.AddBuffName(travelMatch); + + if (txt.gameObject.name.Contains("main")) + { + originalText = txt.text; + var shadowText = txt.transform.parent.Find("Text_shadow"); + + if (shadowText != null) + shadowText.GetComponent().text = Utils.RemoveColorTags(originalText); + } + } + else if (qualityCheckMatch != "") + txt.text = qualityCheckMatch; + else if (superEditorPlantMatch != "") + txt.text = superEditorPlantMatch; + else if (lockedPlantMatch != "") + txt.text = lockedPlantMatch; + else if (customLevelRegexMatch != "") + txt.text = customLevelRegexMatch; + else if (Regex.Match(txt.text, "(]*>.*?)", RegexOptions.Singleline).Success && + !StringStore.TranslationString.ContainsKey(txt.text) && + !StringStore.FSTipCollectionString.ContainsKey(txt.text) && + !StringStore.IZTipCollectionString.ContainsKey(txt.text) && + !StringStore.CustomLevelString.ContainsKey(txt.text)) + { + txt.text = StringStore.TranslateColorText(txt.text, true); + + if (txt.gameObject.name.Contains("main")) + { + originalText = txt.text; + var shadowText = txt.transform.parent.Find("Text_shadow"); + + if (shadowText != null) + shadowText.GetComponent().text = Utils.RemoveColorTags(originalText); + } + } + else + { + txt.text = StringStore.TranslateText(txt.text, true); + + if (txt.gameObject.name.Contains("main")) + { + originalText = txt.text; + var shadowText = txt.transform.parent.Find("Text_shadow"); + + if (shadowText != null) + shadowText.GetComponent().text = Utils.RemoveColorTags(originalText); + } + } + + txt.font = fontAsset; + + CurrentText = txt.text; + } + + public const string NamePlantedPattern = "种植了:([^\\s]+)"; + public const string NameUpgradedPattern = @"升级成功:([^\s]+) -> ([^\s]+)"; + public const string NameAlreadyPlantedPattern = "场上已经有一个([^\\s]+)了"; + public const string UpgradePathRemovedPattern = "已移除路线:([^\\s]+)"; + + public const string LockedPlantPattern = @"^([\s\S]+)\+([\S]+)$"; + public const string MultiLockedPlantPattern = @"^或 ([\s\S]+)\+([\S]+)$"; + + public const string QualityChangePattern = + """ + 诸神注视着你,并选中了一个他们喜欢的词条 + 植物【([\S]+)】的词条【强化:([\S]+)】获得品质升级 + 当前品质:([\S]+) + """; + + public static readonly Dictionary FallbackFStrs = new() + { + { NamePlantedPattern, "{0} planted!" }, + { NameUpgradedPattern, "{0} successfully upgraded to {1}!" }, + { NameAlreadyPlantedPattern, "{0} already exists on the lawn!" }, + { UpgradePathRemovedPattern, "Upgrade Path removed for {0}" }, + { @"([^\s]+)\((\d+)\)", "{0}({1})" }, + { LockedPlantPattern, "{0} + {1}" }, + { MultiLockedPlantPattern, "or {0} + {1}" }, + { + QualityChangePattern, + """ + The gods are watching you, and they have granted you an upgrade! + The {1} upgrade for {0} has been upgraded. + Current Quality: {2} + """ + }, + }; + + public static int CheckGodsGachaPopup(string originalText) + { + var res = 0; + + if (Regex.IsMatch(originalText, NamePlantedPattern)) + res = 1; + else if (Regex.IsMatch(originalText, NameUpgradedPattern)) + res = 2; + else if (Regex.IsMatch(originalText, NameAlreadyPlantedPattern)) + res = 3; + + return res; + } + + public static string TranslateGodsGachaPopup(string originalText, int type) => + type switch + { + 1 => StringStore.TranslateText(originalText, NamePlantedPattern), + 2 => StringStore.TranslateText(originalText, NameUpgradedPattern), + 3 => StringStore.TranslateText(originalText, NameAlreadyPlantedPattern), + _ => originalText, + }; + + public static string TranslatePlantNameParts(string originalText, string pattern) + { + var res = ""; + var match = Regex.Match(originalText, pattern); + + if (!match.Success) + return res; + + var groups = match.Groups; + + var fStr = StringStore.TranslationStringRegex.TryGetValue(pattern, out var value) + ? value + : FallbackFStrs[pattern]; + + List dynamicParts = []; + + for (var i = 1; i < groups.Count; i++) + { + var group = groups[i].Value; + var plantName = Utils.GetPlantNameFromAlmanac(group); + dynamicParts.Add(plantName); + } + + res = string.Format(fStr, [..dynamicParts]); + + return res; + } + + public static string TranslatePlantNameParts(string originalText, string pattern, string fallback) + { + var res = ""; + var match = Regex.Match(originalText, pattern); + + if (!match.Success) + return res; + + var groups = match.Groups; + + var fStr = StringStore.TranslationStringRegex.GetValueOrDefault(pattern, fallback); + + List dynamicParts = []; + + for (var i = 1; i < groups.Count; i++) + { + var group = groups[i].Value; + var plantName = Utils.GetPlantNameFromAlmanac(group); + + if (plantName == "") + plantName = StringStore.TranslateText(group); + + dynamicParts.Add(plantName); + } + + res = string.Format(fStr, [..dynamicParts]); + + return res; + } + + public static string CheckSuperEditorPopup(string originalText) + { + var res = ""; + + if (Regex.IsMatch(originalText, UpgradePathRemovedPattern)) + res = StringStore.TranslateText(originalText, UpgradePathRemovedPattern); + else if (Regex.IsMatch(originalText, "当前全部基础植物:(.*)")) + { + const string Pattern = "当前全部基础植物:(.*)"; + var match = Regex.Match(originalText, Pattern); + + if (!match.Success) + return res; + + var groups = match.Groups; + var plantNameGroup = groups[1].Value; + var plantNames = plantNameGroup.Split(" "); + var plantRes = ""; + const string ShortPattern = @"([^\s]+)\((\d+)\)"; + + foreach (var shortMatch in plantNames + .Select(plantName => Regex.Match(plantName, ShortPattern)) + .Where(shortMatch => shortMatch.Success)) + { + var fStr = StringStore.TranslationStringRegex.TryGetValue(ShortPattern, out var value) + ? value + : FallbackFStrs[ShortPattern]; + + var shortRes = string.Format( + fStr, + [Utils.GetPlantNameFromAlmanac(shortMatch.Groups[1].Value), shortMatch.Groups[2].Value] + ); + + plantRes += shortRes + " "; + } + + res = StringStore.TranslateText("当前全部基础植物:" + plantRes); + } + + return res; + } + + public static string CheckLockedMessage(string originalText) + { + var res = ""; + + var lockedPlantRegex = new Regex(LockedPlantPattern); + // var multiLockedPlantRegex = new Regex(MultiLockedPlantPattern); + + if (!lockedPlantRegex.IsMatch(originalText)) + return res; + + if (originalText.Contains('\n')) + { + var lines = originalText.Split("\n"); + + if (!lockedPlantRegex.IsMatch(lines[0])) + return res; + + var firstLine = lines[0]; + var match = lockedPlantRegex.Match(firstLine); + var groups = match.Groups; + + if (Utils.PlantIndiceString.ContainsKey(groups[1].Value) && + Utils.PlantIndiceString.ContainsKey(groups[2].Value)) + { + firstLine = StringStore.TranslateText(firstLine, LockedPlantPattern); + var translatedLines = new List { firstLine }; + + for (var i = 1; i < lines.Length; i++) + { + var nextLine = lines[i]; + var translatedNextLine = StringStore.TranslateText(nextLine, MultiLockedPlantPattern); + translatedLines.Add(translatedNextLine); + } + + res = string.Join("\n", translatedLines); + } + else + return ""; + } + else + { + if (!lockedPlantRegex.IsMatch(originalText)) + return res; + + var match = lockedPlantRegex.Match(originalText); + var groups = match.Groups; + + if (Utils.PlantIndiceString.ContainsKey(groups[1].Value) && + Utils.PlantIndiceString.ContainsKey(groups[2].Value)) + res = StringStore.TranslateText(originalText, LockedPlantPattern); + else + return ""; + } + + return res; + } + + public static string CheckCustomLevelRegex(string originalText) => + StringStore.TranslationStringRegex.All(p => !StringStore.TestRegex(originalText, p.Key)) && + StringStore.CustomLevelStringRegex.FirstOrDefault(p => StringStore.TestRegex(originalText, p.Key)) is + { Key: var key } + ? StringStore.TranslateText(originalText, key) + : null; + + public static string CheckQualityUpgrade(string originalText) + { + var res = ""; + + if (Regex.IsMatch(originalText, QualityChangePattern)) + res = StringStore.TranslateText(originalText, QualityChangePattern); + + return res; + } +} diff --git a/Source/Patches/BaseTextObjects/TMP_Dropdown_Patch.cs b/Source/Patches/BaseTextObjects/TMP_Dropdown_Patch.cs new file mode 100644 index 0000000..0d8ca89 --- /dev/null +++ b/Source/Patches/BaseTextObjects/TMP_Dropdown_Patch.cs @@ -0,0 +1,49 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.BaseTextObjects; + +[HarmonyPatch(typeof(TMP_Dropdown))] +public static class TMP_Dropdown_Patch +{ + [HarmonyPatch(nameof(TMP_Dropdown.Awake)), HarmonyPatch(nameof(TMP_Dropdown.Start)), + HarmonyPatch(nameof(TMP_Dropdown.Show)), HarmonyPatch(nameof(TMP_Dropdown.SetValue)), HarmonyPostfix] + public static void Awake(TMP_Dropdown __instance) + { + if (__instance.captionText) + { + var txt = __instance.captionText; + + txt.text = StringStore.TranslationString.ContainsKey(txt.text + "_code") + ? StringStore.TranslateText(txt.text + "_code") + : StringStore.TranslateText(txt.text); + } + + if (__instance.itemText) + { + var txt = __instance.itemText; + + txt.text = StringStore.TranslationString.ContainsKey(txt.text + "_code") + ? StringStore.TranslateText(txt.text + "_code") + : StringStore.TranslateText(txt.text); + } + + foreach (var dropdownItem in __instance.m_Items) + { + var txt = dropdownItem.text; + + txt.text = StringStore.TranslationString.ContainsKey(txt.text + "_code") + ? StringStore.TranslateText(txt.text + "_code") + : StringStore.TranslateText(txt.text); + } + } + + [HarmonyPatch(nameof(TMP_Dropdown.CreateDropdownList))] + public static void CreateDropdownList(TMP_Dropdown __instance) + { + foreach (var txt in __instance.GetComponentsInChildren(true)) + txt.text = StringStore.TranslationString.ContainsKey(txt.text + "_code") + ? StringStore.TranslateText(txt.text + "_code") + : StringStore.TranslateText(txt.text); + } +} diff --git a/Source/Patches/BaseTextObjects/TMP_InputField_Patch.cs b/Source/Patches/BaseTextObjects/TMP_InputField_Patch.cs new file mode 100644 index 0000000..dead5d1 --- /dev/null +++ b/Source/Patches/BaseTextObjects/TMP_InputField_Patch.cs @@ -0,0 +1,20 @@ +using HarmonyLib; +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] + public static void OnEnable(TMP_InputField __instance) + { + if (string.IsNullOrEmpty(__instance.text)) + return; + + var 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/Source/Patches/BaseTextObjects/TextMeshProUGUI_Patch.cs b/Source/Patches/BaseTextObjects/TextMeshProUGUI_Patch.cs new file mode 100644 index 0000000..2351352 --- /dev/null +++ b/Source/Patches/BaseTextObjects/TextMeshProUGUI_Patch.cs @@ -0,0 +1,95 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.Patches.Managers; +using PvZ_Fusion_Translator.AssetStore; + +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)) + return; + + __instance.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + + if (!Utils.CheckForUntranslatedText(__instance.text) && !__instance.text.Contains('_')) + return; + + if (__instance.transform.parent != null) + { + if (__instance.transform.parent.name.Contains("DrawCardsText")) + return; + + if (__instance.transform.parent.parent != null) + if (__instance.transform.parent.parent.name.Contains("AbyssBagMenu")) + return; + } + + __instance = StringStore.TranslateText(__instance); + __instance.autoSizeTextContainer = false; + + if (__instance.name.StartsWith("LevelName")) + { + __instance.text = __instance.text.Replace("\n", " "); + + if (__instance.name is "LevelName2" or "LevelName3" && + !(__instance.gameObject.transform.parent.name.Contains("Difficulty") || + __instance.gameObject.name.Contains("Difficulty"))) + TowerManager_Patch.UpdatedText.Add(__instance.transform); + } + + if (__instance.transform.parent == null || !__instance.transform.parent.name.StartsWith("Window")) + return; + + __instance.fontSizeMin = 10; + __instance.fontSize = 12; + // __instance.ForceMeshUpdate(); + } +#if false + [HarmonyPatch(nameof(TextMeshProUGUI.Awake)), HarmonyPostfix] + private static void Awake(TextMeshProUGUI __instance) + { + if (string.IsNullOrEmpty(__instance.text)) + return; + + if (__instance.transform.parent.parent != null) + if (__instance.transform.parent.parent.name.Contains("AbyssBagMenu")) + return; + + __instance = StringStore.TranslateText(__instance); + __instance.autoSizeTextContainer = false; + + 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(); + } +#endif +} +#if false +[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)) + return; + + var text = StringStore.TranslateText(__instance.textComponent.text); + __instance.m_TextComponent.text = StringStore.TranslateText(text); + __instance.textComponent.text = StringStore.TranslateText(text); + } +} +#endif diff --git a/Source/Patches/BaseTextObjects/TextMeshPro_Patch.cs b/Source/Patches/BaseTextObjects/TextMeshPro_Patch.cs new file mode 100644 index 0000000..90e1d25 --- /dev/null +++ b/Source/Patches/BaseTextObjects/TextMeshPro_Patch.cs @@ -0,0 +1,37 @@ +using HarmonyLib; +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)) + return; + + if (__instance.transform.parent.name.Contains("DrawCardsText")) + return; + + if (__instance.transform.parent.name.StartsWith("AlmanacHelp") || + __instance.transform.parent.name.StartsWith("CardBank")) + { + __instance = StringStore.TranslateText(__instance); + __instance.autoSizeTextContainer = false; + return; + } + + if (__instance.transform.name.Contains("AlmanacZombie") || + __instance.transform.name.Contains("AlmanacPlant") || + __instance.transform.name.Contains("Name") || + __instance.transform.name.Contains("Tips") || + __instance.transform.parent.name.Contains("Signboard") || + __instance.transform.parent.name.Contains("text")) + return; + + __instance = StringStore.TranslateText(__instance); + __instance.autoSizeTextContainer = true; + } +} diff --git a/Source/Patches/GameObjects/AlmanacBuffMenu_Patch.cs b/Source/Patches/GameObjects/AlmanacBuffMenu_Patch.cs new file mode 100644 index 0000000..82a0eb3 --- /dev/null +++ b/Source/Patches/GameObjects/AlmanacBuffMenu_Patch.cs @@ -0,0 +1,98 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; +using System.Drawing; +using static PvZ_Fusion_Translator.Patches.Modes.Odyssey.TravelMgr_Patch; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(AlmanacBuffMenu))] +public static class AlmanacBuffMenu_Patch +{ + [HarmonyPatch(nameof(AlmanacBuffMenu.Awake)), HarmonyPostfix] + public static void Post_Awake(AlmanacBuffMenu __instance) + { + foreach (var cardUI in __instance.cards) + { + var cardInfo = __instance.cardInfos[cardUI]; + var buffData = FindBuffData(cardInfo.description); + + if (buffData.Item1 == null || buffData.Item3 == null) + continue; + + cardUI.cost.text = buffData.Item4 ? buffData.Item1 : $"{buffData.Item1} #{buffData.Item2}"; + } + + Post_OnCardClick(__instance); + } + + [HarmonyPatch(nameof(AlmanacBuffMenu.SetAllCards)), HarmonyPatch(nameof(AlmanacBuffMenu.Start)), + HarmonyPatch(nameof(AlmanacBuffMenu.InitMenu)), HarmonyPostfix] + public static void Post_SetAllCards(AlmanacBuffMenu __instance) + { + foreach (var cardUI in __instance.cards) + { + var cardInfo = __instance.cardInfos[cardUI]; + var buffData = FindBuffData(cardInfo.description); + + if (buffData.Item1 == null || buffData.Item3 == null) + continue; + + cardUI.cost.text = buffData.Item4 ? buffData.Item1 : $"{buffData.Item1} #{buffData.Item2}"; + } + + Post_OnToolClick(__instance); + + Post_OnCardClick(__instance); + } + + [HarmonyPatch(nameof(AlmanacBuffMenu.OnToolClick)), HarmonyPostfix] + public static void Post_OnToolClick(AlmanacBuffMenu __instance) + { + foreach (var txt in __instance.toolButton.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + } + + [HarmonyPatch(nameof(AlmanacBuffMenu.OnCardClick)), HarmonyPostfix] + public static void Post_OnCardClick(AlmanacBuffMenu __instance) + { + var buffData = FindBuffData(__instance.buffDescription.text); + + if (buffData.Item1 == null || buffData.Item3 == null) + return; + + __instance.buffTitle.text = buffData.Item4 ? buffData.Item1 : $"{buffData.Item1} #{buffData.Item2}"; + __instance.buffTitle.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + + var buffFStr = StringStore.TranslationStringRegex.GetValueOrDefault("BUFF_NAME_FORMAT", "{0}: {1}"); + + var fBuffDesc = string.Format(buffFStr, buffData.Item1, buffData.Item3); + __instance.buffDescription.text = buffData.Item4 ? fBuffDesc + "\n\n" : buffData.Item3 + "\n\n"; + __instance.buffDescription.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + + var colorHex = StringStore.TranslationString.ContainsKey("MOD_ALMANAC_COL") + ? StringStore.TranslateText("MOD_ALMANAC_COL") + : "#000000"; + + var descriptionColor = ColorTranslator.FromHtml(colorHex); + + __instance.buffDescription.color = new( + descriptionColor.R / 255.0f, + descriptionColor.G / 255.0f, + descriptionColor.B / 255.0f + ); + + __instance.buffDescription.fontSizeMax = 18; + __instance.buffDescription.margin = new(8, 4, 25, 0); + + __instance.buffDescription.enableWordWrapping = true; + __instance.buffDescription.overflowMode = TextOverflowModes.ScrollRect; + + Canvas.ForceUpdateCanvases(); + __instance.buffDescription.ForceMeshUpdate(); + + Post_OnToolClick(__instance); + } +} diff --git a/Source/Patches/GameObjects/AlmanacCardUI_Patch.cs b/Source/Patches/GameObjects/AlmanacCardUI_Patch.cs new file mode 100644 index 0000000..c870a04 --- /dev/null +++ b/Source/Patches/GameObjects/AlmanacCardUI_Patch.cs @@ -0,0 +1,25 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(AlmanacCardUI))] +public static class AlmanacCardUI_Patch +{ + [HarmonyPatch(nameof(AlmanacCardUI.Awake)), HarmonyPostfix] + public static void Awake(AlmanacCardUI __instance) + { + if (!Utils.CheckForUntranslatedText(__instance.cost.text)) + return; + + __instance.cost.text = StringStore.TranslateText(__instance.cost.text); + } +#if false + [HarmonyPatch(nameof(AlmanacCardUI.OnPointerDown)), HarmonyPostfix] + public static void OnPointerDown(AlmanacCardUI __instance) + { + foreach (var almanacCardUI in __instance.menu.GetComponentsInChildren()) + Awake(almanacCardUI); + } +#endif +} diff --git a/Source/Patches/GameObjects/AlmanacPlantMenu_Patch.cs b/Source/Patches/GameObjects/AlmanacPlantMenu_Patch.cs new file mode 100644 index 0000000..b6d26c3 --- /dev/null +++ b/Source/Patches/GameObjects/AlmanacPlantMenu_Patch.cs @@ -0,0 +1,94 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(AlmanacPlantMenu))] +public static class AlmanacPlantMenu_Patch +{ +#pragma warning disable CA2211 + public static string AlmanacJson = ""; +#pragma warning restore CA2211 + public static readonly Dictionary PlantInfoDict = new(); + + [HarmonyPatch(nameof(AlmanacPlantMenu.Awake)), HarmonyPostfix] + private static void Awake(AlmanacPlantMenu __instance) + { + var font = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var text in from text in __instance.GetComponentsInChildren(true) + let isPlantName = text.gameObject.name.Contains("Name") && text.transform.parent.name != "Background" + where text.gameObject.name != "Description" && !isPlantName && !text.gameObject.name.Contains("Cost") + select text) + { + text.text = StringStore.TranslateText(text.text); + text.font = font; + text.autoSizeTextContainer = true; + } + + foreach (var almanacCardUI in __instance.GetComponentsInChildren()) + AlmanacCardUI_Patch.Awake(almanacCardUI); + + // skin button resize + + var window = __instance.window; + var skinButton = window.skinButton; + // var skinTextObj = skinButton.transform.Find("text_1").gameObject; + skinButton.transform.localScale /= 1.75f; + skinButton.transform.localPosition = new(0.0f, 111.345f, 0.0f); + skinButton.transform.GetChild(1).Translate(new(-0.35f, 0)); + skinButton.transform.GetChild(2).Translate(new(0.35f, 0)); + } + + [HarmonyPatch(nameof(AlmanacPlantMenu.SearchChanged)), HarmonyPrefix] + public static bool SearchChanged(AlmanacPlantMenu __instance, ref TMP_InputField inputField) + { + var search = inputField.text; + + if (search == StringStore.TranslateText("搜索") || search == "") + return true; + + var currentLanguage = Utils.Language.ToString(); + // var almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); + // var path = Path.Combine(almanacDir, "LawnStringsTranslate.json"); + _ = FontStore.LoadTMPFont(currentLanguage); + + var plantData = JsonUtility.FromJson(AlmanacJson); + Il2CppSystem.Collections.Generic.List searchedPlants = new(); + + foreach (var plantInfo in plantData.plants) + if (plantInfo.name.ToLower().Contains(search.ToLower()) || + $"{plantInfo.seedType}".ToLower().StartsWith(search.ToLower())) + searchedPlants.Add((PlantType)plantInfo.seedType); + + __instance.ShowPlants(searchedPlants); + return false; + } + + [HarmonyPatch(nameof(AlmanacPlantMenu.ShowPlants), typeof(Il2CppSystem.Func)), + HarmonyPostfix] + public static void ShowPlants(AlmanacPlantMenu __instance, ref Func condition) + { + foreach (var cardUI in __instance.cards) + AlmanacCardUI_Patch.Awake(cardUI); + } + + [HarmonyPatch(nameof(AlmanacPlantMenu.ClassicMix)), HarmonyPostfix] + public static void ClassicMix(AlmanacPlantMenu __instance) + { + foreach (var cardUI in __instance.cards) + AlmanacCardUI_Patch.Awake(cardUI); + } + + public static void LoadPlantAlmanacData(string json) + { + if (json == null) + return; + + AlmanacJson = json; + var plantData = JsonUtility.FromJson(AlmanacJson); + + foreach (var plantInfo in plantData.plants) + PlantInfoDict[plantInfo.seedType] = plantInfo; + } +} diff --git a/Source/Patches/GameObjects/AlmanacPlantWindow_Patch.cs b/Source/Patches/GameObjects/AlmanacPlantWindow_Patch.cs new file mode 100644 index 0000000..c401707 --- /dev/null +++ b/Source/Patches/GameObjects/AlmanacPlantWindow_Patch.cs @@ -0,0 +1,71 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(AlmanacPlantWindow))] +public static class AlmanacPlantWindow_Patch +{ + [HarmonyPatch(nameof(AlmanacPlantWindow.UpdateText)), HarmonyPostfix] + private static void UpdateText(AlmanacPlantWindow __instance) + { + var currentLanguage = Utils.Language.ToString(); + // var almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); + // var path = Path.Combine(almanacDir, "LawnStringsTranslate.json"); + // var moddedPath = Path.Combine(almanacDir, "ModdedPlantsTranslate.json"); + + var hasAlmanacFont = false; + + if (FontStore.FontAssetDictSecondary.ContainsKey((currentLanguage + "_almanac").ToLower()) || + FontStore.FontAssetDictSecondary.ContainsKey(currentLanguage.ToLower())) + { + _ = FontStore.LoadTMPFontAlmanac(currentLanguage); + hasAlmanacFont = true; + } + + var fontAsset = hasAlmanacFont + ? FontStore.LoadTMPFontAlmanac(Utils.Language.ToString()) + : FontStore.LoadTMPFont(Utils.Language.ToString()); + + // var plantData = JsonUtility.FromJson(AlmanacPlantMenu_Patch.AlmanacJson); + + if (!AlmanacPlantMenu_Patch.PlantInfoDict.ContainsKey((int)__instance.currentPlantType)) + return; + + var plantInfo = AlmanacPlantMenu_Patch.PlantInfoDict[(int)__instance.currentPlantType]; + + foreach (var text in __instance.showedPlantName) + { + text.autoSizeTextContainer = false; + text.text = $"{Utils.RemoveSizeTags(plantInfo.name)} ({plantInfo.seedType})"; + text.font = fontAsset; + text.fontSizeMax = 21; + } + + var toTrim = Environment.NewLine.ToCharArray(); + + __instance.showedPlantIntroduce.text = + $""" + {Utils.RemoveSizeTags(plantInfo.info)} + + {Utils.RemoveSizeTags(plantInfo.introduce)} + + {Utils.RemoveSizeTags(plantInfo.cost).TrimStart(toTrim)} + + + """; + + __instance.showedPlantIntroduce.font = fontAsset; + __instance.showedPlantIntroduce.fontSizeMax = 21; + __instance.showedPlantIntroduce.margin = new(6, 2, 12, 0); + + __instance.showedPlantIntroduce.enableWordWrapping = true; + __instance.showedPlantIntroduce.overflowMode = TextOverflowModes.ScrollRect; + + Canvas.ForceUpdateCanvases(); + __instance.showedPlantIntroduce.ForceMeshUpdate(); + + var textHeight = __instance.showedPlantIntroduce.preferredHeight; + __instance.plantTextContent.sizeDelta = new(__instance.plantTextContent.sizeDelta.x, textHeight); + } +} diff --git a/Source/Patches/GameObjects/AlmanacSelectMenu_Patch.cs b/Source/Patches/GameObjects/AlmanacSelectMenu_Patch.cs new file mode 100644 index 0000000..60c384f --- /dev/null +++ b/Source/Patches/GameObjects/AlmanacSelectMenu_Patch.cs @@ -0,0 +1,40 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(AlmanacSelectMenu))] +public static class AlmanacSelectMenu_Patch +{ +#pragma warning disable CA2211 + public static Dictionary DetailStrings = new(); +#pragma warning restore CA2211 + public static readonly Dictionary DetailTranslateStrings = new(); + + [HarmonyPatch(nameof(AlmanacSelectMenu.Awake)), HarmonyPostfix] + public static void Awake(AlmanacSelectMenu __instance) + { + TranslateAlmanacSelectMenu(__instance); + + foreach (var uiButton in __instance.GetComponentsInChildren() + .Where(uiButton => uiButton.gameObject.name.Contains("Selection(Clone)"))) + uiButton.clickEvent.AddListener(new Action(() => { TranslateAlmanacSelectMenu(__instance); })); + } + + [HarmonyPatch(nameof(AlmanacSelectMenu.InitMenu)), HarmonyPostfix] + public static void InitMenu(AlmanacSelectMenu __instance) => TranslateAlmanacSelectMenu(__instance); + + public static void TranslateAlmanacSelectMenu(AlmanacSelectMenu __instance) + { + var font = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = DetailTranslateStrings.TryGetValue(txt.text, out var s) + ? s + : StringStore.TranslateText(txt.text); + + txt.font = font; + } + } +} diff --git a/Source/Patches/GameObjects/AlmanacZombieMenu_Patch.cs b/Source/Patches/GameObjects/AlmanacZombieMenu_Patch.cs new file mode 100644 index 0000000..24b7ca0 --- /dev/null +++ b/Source/Patches/GameObjects/AlmanacZombieMenu_Patch.cs @@ -0,0 +1,28 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(AlmanacZombieMenu))] +public static class AlmanacZombieMenu_Patch +{ +#pragma warning disable CA2211 + public static string AlmanacJson = ""; +#pragma warning restore CA2211 + [HarmonyPatch(nameof(AlmanacZombieMenu.Start)), HarmonyPostfix] + private static void Start(AlmanacZombieMenu __instance) + { + var font = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var text in from text in __instance.GetComponentsInChildren(true) + where !text.gameObject.name.Contains("Cost") + let isZombieName = text.gameObject.name.Contains("Name") && text.transform.parent.name != "Background" + where text.gameObject.name != "Description" && !isZombieName + select text) + { + text.text = StringStore.TranslateText(text.text); + text.font = font; + text.autoSizeTextContainer = true; + } + } +} diff --git a/Source/Patches/GameObjects/AlmanacZombieWindow_Patch.cs b/Source/Patches/GameObjects/AlmanacZombieWindow_Patch.cs new file mode 100644 index 0000000..5a4efa6 --- /dev/null +++ b/Source/Patches/GameObjects/AlmanacZombieWindow_Patch.cs @@ -0,0 +1,80 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(AlmanacZombieWindow))] +public static class AlmanacZombieWindow_Patch +{ + [HarmonyPatch(nameof(AlmanacZombieWindow.UpdateText)), HarmonyPostfix] + private static void UpdateText(AlmanacZombieWindow __instance) + { + var currentLanguage = Utils.Language.ToString(); + // var almanacDir = GetAssetDir(AssetType.Almanac, Utils.Language); + // var path = Path.Combine(almanacDir, "ZombieStringsTranslate.json"); + var hasAlmanacFont = false; + + if (FontStore.FontAssetDictSecondary.ContainsKey((currentLanguage + "_almanac").ToLower()) || + FontStore.FontAssetDictSecondary.ContainsKey(currentLanguage.ToLower())) + { + _ = FontStore.LoadTMPFontAlmanac(currentLanguage); + hasAlmanacFont = true; + } + + var fontAsset = hasAlmanacFont + ? FontStore.LoadTMPFontAlmanac(Utils.Language.ToString()) + : FontStore.LoadTMPFont(Utils.Language.ToString()); + + var zombieAlmanacData = JsonUtility.FromJson(AlmanacZombieMenu_Patch.AlmanacJson); + var zombieDataDic = ZombieDataManager.zombieDataDic; + + foreach (var zombieInfo in zombieAlmanacData.zombies) + if (zombieInfo.theZombieType == __instance.currentZombieType) + { + foreach (var text in __instance.showedZombieName) + { + text.autoSizeTextContainer = false; + text.text = $"{Utils.RemoveSizeTags(zombieInfo.name)} ({(int)zombieInfo.theZombieType})"; + text.font = fontAsset; + text.fontSizeMax = 21; + } + + var zombieData = zombieDataDic[__instance.currentZombieType]; + + var spawnInfo = ""; + + var spawnInfoFormat = + StringStore.TranslationStringRegex.GetValueOrDefault("出怪等级: (\\d+)\n出怪权重: (\\d+)"); + + if (spawnInfoFormat != null) + spawnInfo = string.Format(spawnInfoFormat, [zombieData.summonLevel, zombieData.summonWeight]) + + "\n\n"; + + __instance.showedZombieIntroduce.text = + $""" + {Utils.RemoveSizeTags(zombieInfo.info)} + + {spawnInfo}{Utils.RemoveSizeTags(zombieInfo.introduce)} + + + """; + + __instance.showedZombieIntroduce.font = fontAsset; + __instance.showedZombieIntroduce.fontSizeMax = 21; + __instance.showedZombieIntroduce.margin = new(3, 2, 12, 0); + + __instance.showedZombieIntroduce.enableWordWrapping = true; + __instance.showedZombieIntroduce.overflowMode = TextOverflowModes.ScrollRect; + + Canvas.ForceUpdateCanvases(); + __instance.showedZombieIntroduce.ForceMeshUpdate(); + + var textHeight = __instance.showedZombieIntroduce.preferredHeight; + + __instance.zombieTextContent.sizeDelta = new( + __instance.zombieTextContent.sizeDelta.x, + textHeight + ); + } + } +} diff --git a/Source/Patches/GameObjects/Almanac_Patch.cs b/Source/Patches/GameObjects/Almanac_Patch.cs new file mode 100644 index 0000000..d98ca71 --- /dev/null +++ b/Source/Patches/GameObjects/Almanac_Patch.cs @@ -0,0 +1,30 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(Almanac))] +public static class Almanac_Patch +{ + [HarmonyPatch(nameof(Almanac.Awake)), HarmonyPostfix] + private static void Awake(Almanac __instance) => TranslateAlmanacMenu(__instance); +#if false + [HarmonyPatch(nameof(Almanac.OldAlmanac)), HarmonyPostfix] + private static void OldAlmanac(Almanac __instance) => TranslateAlmanacMenu(__instance); +#endif + [HarmonyPatch(nameof(Almanac.AnimSwitch)), HarmonyPostfix] + private static void AnimSwitch(Almanac __instance) => TranslateAlmanacMenu(__instance); + + public static void TranslateAlmanacMenu(Almanac __instance) + { + var font = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var text in __instance + .GetComponentsInChildren() + .Where(text => !text.gameObject.name.Contains("Cost"))) + { + text.text = StringStore.TranslateText(text.text == "关闭" ? "合上" : text.text); + text.font = font; + } + } +} diff --git a/Source/Patches/GameObjects/BaseMenu_Patch.cs b/Source/Patches/GameObjects/BaseMenu_Patch.cs new file mode 100644 index 0000000..741a4f8 --- /dev/null +++ b/Source/Patches/GameObjects/BaseMenu_Patch.cs @@ -0,0 +1,48 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(BaseMenu))] +public static class BaseMenu_Patch +{ + [HarmonyPatch(nameof(BaseMenu.Awake)), HarmonyPrefix] + private static void Pre_Awake(BaseMenu __instance) + { + if (__instance.name.Contains("NoticePauseMenu")) + NoticePauseMenu_Patch.Pre_Awake(__instance); + } + + [HarmonyPatch(nameof(BaseMenu.Awake)), HarmonyPostfix] + private static void Post_Awake(BaseMenu __instance) + { + if (__instance.name.Contains("NoticePauseMenu")) + NoticePauseMenu_Patch.Post_Awake(__instance); + + if (__instance.name.StartsWith("MainMenu(Clone)")) + MainMenu_Patch.AnimOver(__instance); + + if (__instance.name.StartsWith("PlantDamageMenu")) + PlantDamageMenu_Patch.Awake(__instance); + + TranslateBaseMenuTransform(__instance, "Level"); + TranslateBaseMenuTransform(__instance, "Levels"); + TranslateBaseMenuTransform(__instance, "CustomLevel"); + + StringStore.TranslateTextTransform(__instance.transform.Find("Goback")); + StringStore.TranslateTextTransform(__instance.transform.Find("Switich")); + } + + public static void TranslateBaseMenuTransform(BaseMenu __instance, string levelsName) + { + var levels = __instance.transform.Find(levelsName); + + if (levels == null) + return; + + var children = levels.GetComponentsInChildren(true).ToList(); + + foreach (var child in children.Where(child => child.name is "Nextpage" or "LastPage" or "BackToIndex")) + StringStore.TranslateTextTransform(child); + } +} diff --git a/Source/Patches/GameObjects/Board_Patch.cs b/Source/Patches/GameObjects/Board_Patch.cs new file mode 100644 index 0000000..3caf107 --- /dev/null +++ b/Source/Patches/GameObjects/Board_Patch.cs @@ -0,0 +1,17 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(Board))] +public static class Board_Patch +{ + [HarmonyPatch(nameof(Board.Update)), HarmonyPostfix] + private static void Update(Board __instance) + { + foreach (var spriteRenderer in __instance.GetComponentsInChildren() + .Where(sr => sr.sprite != null) + .Where(sr => TextureStore.SpriteDict.ContainsKey(sr.sprite.name) && sr.drawMode != SpriteDrawMode.Sliced)) + spriteRenderer.drawMode = SpriteDrawMode.Sliced; + } +} diff --git a/Source/Patches/GameObjects/ButtonObjects/Advanture_Btn_Patch.cs b/Source/Patches/GameObjects/ButtonObjects/Advanture_Btn_Patch.cs new file mode 100644 index 0000000..e3e5063 --- /dev/null +++ b/Source/Patches/GameObjects/ButtonObjects/Advanture_Btn_Patch.cs @@ -0,0 +1,25 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +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) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + var originalKey = StringStore.TranslationString.FirstOrDefault(x => x.Value == txt.text).Key; + + txt.text = StringStore.TranslationString.ContainsKey(originalKey + "_MG") + ? StringStore.TranslateText(originalKey + "_MG") + : StringStore.TranslateText(txt.text); + + txt.font = fontAsset; + } + } +} diff --git a/Source/Patches/GameObjects/ButtonObjects/BackToIndex_Patch.cs b/Source/Patches/GameObjects/ButtonObjects/BackToIndex_Patch.cs new file mode 100644 index 0000000..8be4542 --- /dev/null +++ b/Source/Patches/GameObjects/ButtonObjects/BackToIndex_Patch.cs @@ -0,0 +1,14 @@ +#if false +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects; + +[HarmonyPatch(typeof(BackToIndex))] +public class BackToIndex_Patch +{ + [HarmonyPostfix, HarmonyPatch(nameof(BackToIndex.Awake))] + public static void Awake(BackToIndex __instance) => + StringStore.TranslateTextTransform(__instance.transform.GetChild(0)); +} +#endif diff --git a/Source/Patches/GameObjects/ButtonObjects/CustomLevelEnter_Patch.cs b/Source/Patches/GameObjects/ButtonObjects/CustomLevelEnter_Patch.cs new file mode 100644 index 0000000..4172eea --- /dev/null +++ b/Source/Patches/GameObjects/ButtonObjects/CustomLevelEnter_Patch.cs @@ -0,0 +1,25 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects; + +[HarmonyPatch(typeof(CustomLevelEnter))] +public static class CustomLevelEnter_Patch +{ + [HarmonyPatch(nameof(CustomLevelEnter.Start)), HarmonyPostfix] + private static void Start(CustomLevelEnter __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + var originalKey = StringStore.TranslationString.FirstOrDefault(x => x.Value == txt.text).Key; + + txt.text = StringStore.TranslationString.ContainsKey(originalKey + "_IZ") + ? StringStore.TranslateText(originalKey + "_IZ") + : StringStore.TranslateText(txt.text); + + txt.font = fontAsset; + } + } +} diff --git a/Source/Patches/GameObjects/ButtonObjects/ExploreMakeSceneButton_Patch.cs b/Source/Patches/GameObjects/ButtonObjects/ExploreMakeSceneButton_Patch.cs new file mode 100644 index 0000000..f3126de --- /dev/null +++ b/Source/Patches/GameObjects/ButtonObjects/ExploreMakeSceneButton_Patch.cs @@ -0,0 +1,18 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects; + +[HarmonyPatch(typeof(ExploreMakeSceneButton))] +public class ExploreMakeSceneButton_Patch +{ + [HarmonyPostfix, HarmonyPatch(nameof(ExploreMakeSceneButton.Start))] + public static void Start(ExploreMakeSceneButton __instance) + { + __instance.sceneText.text = StringStore.TranslationString.ContainsKey(__instance.sceneText.text + "_FS") + ? StringStore.TranslateText(__instance.sceneText.text + "_FS") + : StringStore.TranslateText(__instance.sceneText.text); + + __instance.sceneText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } +} diff --git a/Source/Patches/GameObjects/ButtonObjects/ExploreMakeZombieButton_Patch.cs b/Source/Patches/GameObjects/ButtonObjects/ExploreMakeZombieButton_Patch.cs new file mode 100644 index 0000000..490ef0b --- /dev/null +++ b/Source/Patches/GameObjects/ButtonObjects/ExploreMakeZombieButton_Patch.cs @@ -0,0 +1,15 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects; + +[HarmonyPatch(typeof(ExploreMakeZombieButton))] +public class ExploreMakeZombieButton_Patch +{ + [HarmonyPostfix, HarmonyPatch(nameof(ExploreMakeZombieButton.Start))] + public static void Start(ExploreMakeZombieButton __instance) + { + __instance.sceneText.text = Utils.GetZombieNameFromAlmanac(__instance.theZombieType); + __instance.sceneText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } +} diff --git a/Source/Patches/GameObjects/ButtonObjects/GodShootingLevelButton_Patch.cs b/Source/Patches/GameObjects/ButtonObjects/GodShootingLevelButton_Patch.cs new file mode 100644 index 0000000..dd685c7 --- /dev/null +++ b/Source/Patches/GameObjects/ButtonObjects/GodShootingLevelButton_Patch.cs @@ -0,0 +1,25 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects; + +[HarmonyPatch(typeof(GodShootingLevelButton))] +public static class GodShootingLevelButton_Patch +{ + [HarmonyPatch(nameof(GodShootingLevelButton.Awake)), HarmonyPostfix] + private static void Awake(GodShootingLevelButton __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + var originalKey = StringStore.TranslationString.FirstOrDefault(x => x.Value == txt.text).Key; + + txt.text = StringStore.TranslationString.ContainsKey(originalKey + "_GS") + ? StringStore.TranslateText(originalKey + "_GS") + : StringStore.TranslateText(txt.text); + + txt.font = fontAsset; + } + } +} diff --git a/Source/Patches/GameObjects/ButtonObjects/InGameBtn_Patch.cs b/Source/Patches/GameObjects/ButtonObjects/InGameBtn_Patch.cs new file mode 100644 index 0000000..9d5ff7a --- /dev/null +++ b/Source/Patches/GameObjects/ButtonObjects/InGameBtn_Patch.cs @@ -0,0 +1,35 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects; + +[HarmonyPatch(typeof(InGameBtn))] +public static class InGameBtn_Patch +{ + [HarmonyPatch(nameof(InGameBtn.Start)), HarmonyPostfix] + private static void Start(InGameBtn __instance) + { + var sceneText = __instance.transform.FindChild("SceneText"); + + if (sceneText != null) + { + var sceneTextTMP = sceneText.transform.GetComponent(); + + if (sceneTextTMP != null) + StringStore.TranslateText(sceneTextTMP); + + var sceneTextShadow = sceneText.transform.FindChild("SceneText"); + + if (sceneTextShadow != null) + { + var sceneTextShadowTMP = sceneTextShadow.transform.GetComponent(); + + if (sceneTextShadowTMP != null) + StringStore.TranslateText(sceneTextShadowTMP); + } + } + + foreach (var text in __instance.transform.GetComponentsInChildren()) + text.text = StringStore.TranslateText(text.text); + } +} diff --git a/Source/Patches/GameObjects/ButtonObjects/LevelSaveEnter_Patch.cs b/Source/Patches/GameObjects/ButtonObjects/LevelSaveEnter_Patch.cs new file mode 100644 index 0000000..6ed8041 --- /dev/null +++ b/Source/Patches/GameObjects/ButtonObjects/LevelSaveEnter_Patch.cs @@ -0,0 +1,14 @@ +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects; + +public static class LevelSaveEnter_Patch +{ + public static void TranslateEnter(LevelSaveEnter __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + __instance.text.text = StringStore.TranslateText(__instance.text.text); + __instance.text.font = fontAsset; + } +} diff --git a/Source/Patches/GameObjects/ButtonObjects/MainMenu_Btn_Patch.cs b/Source/Patches/GameObjects/ButtonObjects/MainMenu_Btn_Patch.cs new file mode 100644 index 0000000..e898902 --- /dev/null +++ b/Source/Patches/GameObjects/ButtonObjects/MainMenu_Btn_Patch.cs @@ -0,0 +1,25 @@ +#if false +using HarmonyLib; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects; + +[HarmonyPatch(typeof(MainMenu_Btn))] +public static class MainMenu_Btn_Patch +{ + public static List speechBubbles = new List(); + + [HarmonyPatch(nameof(MainMenu_Btn.OnMouseEnter)), HarmonyPostfix] + private static void OnMouseEnter(MainMenu_Btn __instance) + { + string textToShow = null; + + if (__instance.transform.parent.name == "recipe") + textToShow = "探索模式"; + else if (__instance.name == "mysterious") + textToShow = "神秘模式"; + + if (textToShow != null) + InGameText.Instance.ShowText(textToShow, 2.0f); + } +} +#endif diff --git a/Source/Patches/GameObjects/ButtonObjects/NormalBtn_Patch.cs b/Source/Patches/GameObjects/ButtonObjects/NormalBtn_Patch.cs new file mode 100644 index 0000000..257f2d9 --- /dev/null +++ b/Source/Patches/GameObjects/ButtonObjects/NormalBtn_Patch.cs @@ -0,0 +1,21 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects; + +[HarmonyPatch(typeof(NormalBtn))] +public class NormalBtn_Patch +{ + [HarmonyPostfix, HarmonyPatch(nameof(NormalBtn.OnMouseUpAsButton))] + public static void OnMouseUpAsButton(NormalBtn __instance) + { + if (__instance.transform.childCount <= 0) + return; + + var banTransform = __instance.transform.GetChild(0); + + if (banTransform != null) + banTransform.GetComponent().text = + StringStore.TranslateText(banTransform.GetComponent().text); + } +} diff --git a/Source/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs b/Source/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs new file mode 100644 index 0000000..986f1f8 --- /dev/null +++ b/Source/Patches/GameObjects/ButtonObjects/OptLanguageBtn_Patch.cs @@ -0,0 +1,415 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; +using Object = UnityEngine.Object; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects; + +public sealed class OptionButtonData +{ + public OptionBtn Button { get; init; } + + public Vector3 Position { get; init; } + + /// if it is the "Next" button. + public Utils.LanguageEnum? Language { get; set; } + + /// if it is the "Next" button. + public Utils.ToggleEnum? Toggle { get; set; } + + public bool IsNextButton { get; set; } + + public bool Shifted; +} + +internal static class OptLanguageBtn_Patch +{ + public static readonly Dictionary LanguageBtnDict = new(), ToggleBtnDict = new(); + + private static bool s_buttonsCreated, s_togglesCreated; + + // ReSharper disable once NotAccessedField.Local + private static OptionBtn s_cachedTemplateButton, s_cachedTemplateToggleButton; + + private const float + StartX = 4.3241f + 2.56f, + StartY = 2.7769f, + YSpacing = 1.2505f, + ToggleStartX = 4.3241f, + ToggleStartY = -0.9746f; + + private static List s_availableLanguages; + + private static List s_availableToggles; + + private const int LanguagesPerPage = 5; + + private static int s_currentPage; + + // 5 language buttons + 1 next button + public static readonly OptionBtn[] ButtonSlots = new OptionBtn[6], ToggleSlots = new OptionBtn[3]; + + public static void CreateLanguageButtons(OptionBtn templateButton) + { + if (s_buttonsCreated) + return; + + s_buttonsCreated = true; + s_cachedTemplateButton = templateButton; + + s_availableLanguages = Enum.GetValues(typeof(Utils.LanguageEnum)) + .Cast() + .Where(lang => lang != Utils.LanguageEnum.LangEnd) + .ToList(); + + for (var i = 0; i < 6; i++) + { + var newButton = Object.Instantiate(templateButton, templateButton.transform.parent); + newButton.tag = "LangOpt"; + + foreach (var child in newButton.GetComponentsInChildren()) + child.tag = "LangOpt"; + + newButton.optionType = 80 + i; + + var yPos = StartY - i * YSpacing; + Vector3 pos = new(StartX, yPos); + newButton.transform.position = pos; + + ButtonSlots[i] = newButton; + + LanguageBtnDict[newButton.GetInstanceID()] = new() + { + Button = newButton, + Position = pos, + }; + } + + UpdatePage(); + } + + public static void CreateToggleButtons(OptionBtn templateButton) + { + if (s_togglesCreated) + return; + + s_togglesCreated = true; + s_cachedTemplateToggleButton = templateButton; + + s_availableToggles = Enum.GetValues() + .Where(lang => lang != Utils.ToggleEnum.ToggleEnd) + .ToList(); + + for (var i = 0; i < 3; i++) + { + var newButton = Object.Instantiate(templateButton, templateButton.transform.parent); + newButton.tag = "LangOpt"; + + foreach (var child in newButton.GetComponentsInChildren()) + child.tag = "LangOpt"; + + newButton.optionType = 100 + i; + + var yPos = ToggleStartY - i * YSpacing; + Vector3 pos = new(ToggleStartX, yPos); + newButton.transform.position = pos; + + ToggleSlots[i] = newButton; + + ToggleBtnDict[newButton.GetInstanceID()] = new() + { + Button = newButton, + Position = pos, + }; + } + + UpdatePage(); + } + + private static void UpdatePage() + { + var startIndex = s_currentPage * LanguagesPerPage; + var langCount = s_availableLanguages.Count; + var toggleCount = s_togglesCreated ? s_availableToggles.Count : 0; + + for (var i = 0; i < 5; i++) + { + var btn = ButtonSlots[i]; + var data = LanguageBtnDict[btn.GetInstanceID()]; + + if (startIndex + i < langCount) + { + var lang = s_availableLanguages[startIndex + i]; + data.Language = lang; + data.IsNextButton = false; + btn.gameObject.SetActive(true); + + var languageName = Utils.LanguageNames.TryGetValue(lang, out var name) ? name : lang.ToString(); + UpdateButtonText(btn, languageName, FontStore.LoadTMPFont(lang.ToString())); + } + else + { + data.Language = null; + data.IsNextButton = false; + btn.gameObject.SetActive(false); + } + } + + if (s_togglesCreated) + for (var i = 0; i < 3; i++) + { + var btn = ToggleSlots[i]; + var data = ToggleBtnDict[btn.GetInstanceID()]; + + if (i < toggleCount) + { + var toggle = s_availableToggles[i]; + data.Toggle = toggle; + data.IsNextButton = false; + btn.gameObject.SetActive(true); + + var buttonText = Utils.ToggleNames.TryGetValue(toggle, out var name) + ? name + : toggle.ToString(); + + UpdateButtonText( + btn, + StringStore.TranslateText(buttonText), + FontStore.LoadTMPFont(Utils.Language.ToString()) + ); + + string sourceMsg; + + switch (i) + { + case 0: + sourceMsg = + $"Texture Source:\n{(Core.Instance.ConfigDefaultTextures.Value ? "Default" : "Custom")}"; + + FlashMessage(btn, sourceMsg, 0.1f, false); + break; + case 1: + sourceMsg = + $"Audio Source:\n{(Core.Instance.ConfigDefaultAudio.Value ? "Default" : "Custom")}"; + + FlashMessage(btn, sourceMsg, 0.1f, false); + break; + case 2: + sourceMsg = + $"Translation Source:\n{(Core.Instance.ConfigUseLocal.Value ? "Local" : "Online")}"; + + FlashMessage(btn, sourceMsg, 0.1f, false); + break; + } + } + 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 fontAsset = null) + { + var defaultAsset = FontStore.LoadTMPFont("English"); + + for (var i = 0; i < 3; i++) + { + var textTransform = button.transform.GetChild(i); + + if (textTransform == null) + continue; + + if (i == 0) + textTransform.gameObject.SetActive(false); + + var text = textTransform.GetComponent(); + + if (text == null) + continue; + + if (i == 0) + { + text.text = ""; + text.color = Color.red; + } + else + text.text = languageName; + + text.fontSize = 16; + text.font = fontAsset != null ? fontAsset : defaultAsset; + text.autoSizeTextContainer = false; + } + } + + public static void FlashMessage(OptionBtn button, string message, float yShift = 0.0f, bool useTimer = true) + { + var child = button.transform.GetChild(0); + + if (child == null) + return; + + var text = child.GetComponent(); + var originalMsg = ""; + + if (text != null) + { + originalMsg = text.text; + text.text = message; + var isToggle = ToggleBtnDict.TryGetValue(button.GetInstanceID(), out _); + + if (isToggle) + { + text.transform.position = new( + text.transform.position.x, + text.transform.position.y + (ToggleBtnDict[button.GetInstanceID()].Shifted ? 0.0f : yShift), + text.transform.position.z + ); + + ToggleBtnDict[button.GetInstanceID()].Shifted = true; + } + else + { + text.transform.position = new( + text.transform.position.x, + text.transform.position.y + (LanguageBtnDict[button.GetInstanceID()].Shifted ? 0.0f : yShift), + text.transform.position.z + ); + + LanguageBtnDict[button.GetInstanceID()].Shifted = true; + } + } + + child.gameObject.SetActive(true); + + if (useTimer) + Task.Delay(1000) + .ContinueWith( + _ => + { + if (button == null || child == null || !child.gameObject.activeSelf) + return; + + var buttonData = ToggleBtnDict[button.GetInstanceID()]; + + if (buttonData.Toggle == null) + return; + + var sourceMsg = buttonData.Toggle switch + { + Utils.ToggleEnum.Textures => + $"Texture Source:\n{(Core.Instance.ConfigDefaultAudio.Value ? "Default" : "Custom")}", + Utils.ToggleEnum.Audio => + $"Audio Source:\n{(Core.Instance.ConfigDefaultAudio.Value ? "Default" : "Custom")}", + _ => originalMsg, + }; + + text.text = sourceMsg; + } + ); + } + + private static void ToggleCustomAssets(string type) + { + switch (type) + { + case "Textures": + Core.Instance.ConfigDefaultTextures.Value = !Core.Instance.ConfigDefaultTextures.Value; + TextureStore.Reload(); + Core.Coroutine(TextureStore.ReplaceTexturesCoroutine()); + break; + case "Audio": + Core.Instance.ConfigDefaultAudio.Value = !Core.Instance.ConfigDefaultAudio.Value; + break; + case "SwapLocal": + Utils.WarnLocalData(); + break; + } + } + + [HarmonyPatch(typeof(OptionBtn))] + public static class OptLangBtn_Patch + { + public static void Awake(OptionBtn __instance) + { + if (s_buttonsCreated && s_cachedTemplateButton != null) + return; + + s_buttonsCreated = false; + s_togglesCreated = false; + CreateLanguageButtons(__instance); + CreateToggleButtons(__instance); + } + + [HarmonyPatch("OnMouseUpAsButton"), HarmonyPrefix] + private static void OnMouseUpAsButton(OptionBtn __instance) + { + if (!ModFeatures.IsMultiLanguage) + return; + + if (LanguageBtnDict.TryGetValue(__instance.GetInstanceID(), out var btnData)) + { + if (btnData.IsNextButton) + { + s_currentPage = (s_currentPage + 1) % + (int)Math.Ceiling((float)s_availableLanguages.Count / LanguagesPerPage); + + UpdatePage(); + return; + } + + if (btnData.Language is { } selectedLang) + { + var 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!"); + } + } + } + + if (!ToggleBtnDict.TryGetValue(__instance.GetInstanceID(), out var toggleData)) + return; + + var toggleType = toggleData.Toggle.ToString(); + ToggleCustomAssets(toggleType); + + switch (toggleType) + { + case "Textures": + FlashMessage(toggleData.Button, "Toggled custom textures!\n(Restart Required)", 0.1f); + break; + case "Audio": + FlashMessage(toggleData.Button, "Toggled custom audio!", 0.1f); + break; + } + } + + [HarmonyPatch(nameof(OptionBtn.Update)), HarmonyPostfix] + private static void Update(OptionBtn __instance) + { + if (!ModFeatures.IsMultiLanguage) + return; + + if (LanguageBtnDict.TryGetValue(__instance.GetInstanceID(), out var btnData)) + btnData.Button.transform.position = btnData.Position; + + if (ToggleBtnDict.TryGetValue(__instance.GetInstanceID(), out var toggleData)) + toggleData.Button.transform.position = toggleData.Position; + } + } +} diff --git a/Source/Patches/GameObjects/ButtonObjects/OptionBtn_Patch.cs b/Source/Patches/GameObjects/ButtonObjects/OptionBtn_Patch.cs new file mode 100644 index 0000000..87c7a16 --- /dev/null +++ b/Source/Patches/GameObjects/ButtonObjects/OptionBtn_Patch.cs @@ -0,0 +1,69 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +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) + { + var text1Transform = __instance.transform.GetChild(0)?.transform; + + if (text1Transform != null) + { + var text1 = text1Transform.GetComponent(); + text1 = StringStore.TranslateText(text1); + text1.autoSizeTextContainer = false; + } + + var textTransform = __instance.transform.GetChild(1)?.transform; + + if (textTransform != null) + { + var text = textTransform.GetComponent(); + text = StringStore.TranslateText(text); + text.autoSizeTextContainer = false; + } + + var text2Transform = __instance.transform.GetChild(2)?.transform; + + if (text2Transform == null) + return; + + var text2 = text2Transform.GetComponent(); + text2 = StringStore.TranslateText(text2); + text2.autoSizeTextContainer = false; + } + + [HarmonyPatch("OnMouseUpAsButton"), HarmonyPostfix] + private static void OnMouseUpAsButtonPostfix(OptionBtn __instance) + { + var text1Transform = __instance.transform.GetChild(0)?.transform; + + if (text1Transform != null) + { + var text1 = text1Transform.GetComponent(); + text1 = StringStore.TranslateText(text1); + text1.autoSizeTextContainer = false; + } + + var textTransform = __instance.transform.GetChild(1)?.transform; + + if (textTransform != null) + { + var text = textTransform.GetComponent(); + text = StringStore.TranslateText(text); + text.autoSizeTextContainer = false; + } + + var text2Transform = __instance.transform.GetChild(2)?.transform; + + if (text2Transform == null) + return; + + var text2 = text2Transform.GetComponent(); + StringStore.TranslateText(text2); + } +} diff --git a/Source/Patches/GameObjects/ButtonObjects/PVPPotBtn_Patch.cs b/Source/Patches/GameObjects/ButtonObjects/PVPPotBtn_Patch.cs new file mode 100644 index 0000000..2f8980f --- /dev/null +++ b/Source/Patches/GameObjects/ButtonObjects/PVPPotBtn_Patch.cs @@ -0,0 +1,41 @@ +#if false +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects; + +[HarmonyPatch(typeof(PVPPotBtn))] // ReSharper disable once InconsistentNaming +public class PVPPotBtn_Patch +{ + [HarmonyPostfix] + [HarmonyPatch(nameof(PVPPotBtn.OnMouseUpAsButton))] + public static void OnMouseUpAsButton(PVPPotBtn __instance) + { + Transform sceneText = __instance.transform.FindChild("text"); + + if (sceneText != null) + { + var sceneTextTMP = sceneText.transform.GetComponent(); + + if (sceneTextTMP != null) + sceneTextTMP.text = StringStore.TranslateText(sceneTextTMP.text); + } + + var sceneTextShadow = sceneText.transform.FindChild("text_1"); + + if (sceneTextShadow != null) + { + var sceneTextShadowTMP = sceneTextShadow.transform.GetComponent(); + + if (sceneTextShadowTMP != null) + sceneTextShadowTMP.text = StringStore.TranslateText(sceneTextShadowTMP.text); + } + + if (!__instance.name.Equals("ChangeBg_3") && !__instance.name.Equals("ChangeBg_4")) + return; + + __instance.gameObject.SetActive(false); + __instance.gameObject.SetActive(true); + } +} +#endif diff --git a/Source/Patches/GameObjects/ButtonObjects/PauseMenu_Btn_Patch.cs b/Source/Patches/GameObjects/ButtonObjects/PauseMenu_Btn_Patch.cs new file mode 100644 index 0000000..ff5a572 --- /dev/null +++ b/Source/Patches/GameObjects/ButtonObjects/PauseMenu_Btn_Patch.cs @@ -0,0 +1,11 @@ +using HarmonyLib; +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/Source/Patches/GameObjects/ButtonObjects/SaveMenuBtn_Patch.cs b/Source/Patches/GameObjects/ButtonObjects/SaveMenuBtn_Patch.cs new file mode 100644 index 0000000..fe68003 --- /dev/null +++ b/Source/Patches/GameObjects/ButtonObjects/SaveMenuBtn_Patch.cs @@ -0,0 +1,18 @@ +#if false +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +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) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + __instance.theName.text = StringStore.TranslateText(__instance.theName.text); + __instance.theName.font = fontAsset; + } +} +#endif diff --git a/Source/Patches/GameObjects/ButtonObjects/UIBtn_Patch.cs b/Source/Patches/GameObjects/ButtonObjects/UIBtn_Patch.cs new file mode 100644 index 0000000..401b8f7 --- /dev/null +++ b/Source/Patches/GameObjects/ButtonObjects/UIBtn_Patch.cs @@ -0,0 +1,16 @@ +#if false +using HarmonyLib; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects; + +[HarmonyPatch(typeof(UIBtn))] +public static class UIBtn_Patch +{ + [HarmonyPatch(nameof(UIBtn.Awake)), HarmonyPostfix] + private static void Postfix_Awake(UIBtn __instance) + { + if (__instance.TryGetComponent(out BackToIndex component)) + Utils.ConvertButtonText(__instance.transform.parent, component.name); + } +} +#endif diff --git a/Source/Patches/GameObjects/ButtonObjects/UIButton_Patch.cs b/Source/Patches/GameObjects/ButtonObjects/UIButton_Patch.cs new file mode 100644 index 0000000..0d2d7fc --- /dev/null +++ b/Source/Patches/GameObjects/ButtonObjects/UIButton_Patch.cs @@ -0,0 +1,46 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects; + +[HarmonyPatch(typeof(UIButton))] +public static class UIButton_Patch +{ + [HarmonyPatch(typeof(UIButton), nameof(UIButton.Start)), HarmonyPostfix] + public static void Start(UIButton __instance) + { + if (__instance.transform.childCount >= 2) + { + var font = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var text in __instance.transform.GetComponentsInChildren()) + { + if (__instance.transform.name == "Goback") + text.text = "合上"; + + text.text = StringStore.TranslateText(text.text); + text.font = font; + } + } + else + { + StringStore.TranslateTextTransform(__instance.transform); + + if (__instance.transform.name != "Goback") + return; + + foreach (var text in __instance.transform.GetComponentsInChildren()) + text.text = StringStore.TranslateText("合上"); + } + } + + [HarmonyPatch(nameof(UIButton.OnMouseUpAsButton)), HarmonyPostfix] + public static void Postfix_OnMouseUpAsButton(UIButton __instance) + { + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + } +} diff --git a/Source/Patches/GameObjects/Close_Patch.cs b/Source/Patches/GameObjects/Close_Patch.cs new file mode 100644 index 0000000..e52fe75 --- /dev/null +++ b/Source/Patches/GameObjects/Close_Patch.cs @@ -0,0 +1,50 @@ +#if false +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +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; + + var almanacTransform = __instance.transform.parent.transform; + var nameTransform = almanacTransform.Find("Name"); + + if (nameTransform != null) + { + var nameTMP = nameTransform.transform.GetComponent(); + + if (nameTMP) + { + nameTMP = StringStore.TranslateText(nameTMP); + nameTMP.autoSizeTextContainer = true; + } + + var nameShadowTransform = nameTransform.Find("NameShadow"); + + if (nameShadowTransform) + { + var 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")); + } +} +#endif diff --git a/Source/Patches/GameObjects/ConfirmMenu_Patch.cs b/Source/Patches/GameObjects/ConfirmMenu_Patch.cs new file mode 100644 index 0000000..cf1d270 --- /dev/null +++ b/Source/Patches/GameObjects/ConfirmMenu_Patch.cs @@ -0,0 +1,18 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(ConfirmMenu))] +public static class ConfirmMenu_Patch +{ + [HarmonyPatch(nameof(ConfirmMenu.SetTitle)), HarmonyPostfix] + private static void SetTitle(ConfirmMenu __instance) + { + foreach (var title in __instance.title) + { + title.text = StringStore.TranslateText(title.text); + title.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + } +} diff --git a/Source/Patches/GameObjects/CrisisZombieWindow_Patch.cs b/Source/Patches/GameObjects/CrisisZombieWindow_Patch.cs new file mode 100644 index 0000000..6949958 --- /dev/null +++ b/Source/Patches/GameObjects/CrisisZombieWindow_Patch.cs @@ -0,0 +1,30 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(CrisisZombieWindow))] +public static class CrisisZombieWindow_Patch +{ + [HarmonyPatch(nameof(CrisisZombieWindow.Start)), HarmonyPostfix] + private static void Start(CrisisZombieWindow __instance) + { + var introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + var introduceText = introduceTransform.GetComponent(); + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } + + [HarmonyPatch(nameof(CrisisZombieWindow.SetZombieType)), HarmonyPostfix] + private static void SetZombieType(CrisisZombieWindow __instance) + { + var introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + var introduceText = introduceTransform.GetComponent(); + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } +} diff --git a/Source/Patches/GameObjects/CustomSettings_Patch.cs b/Source/Patches/GameObjects/CustomSettings_Patch.cs new file mode 100644 index 0000000..31a35b0 --- /dev/null +++ b/Source/Patches/GameObjects/CustomSettings_Patch.cs @@ -0,0 +1,18 @@ +#if false +using HarmonyLib; +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); +} +#endif diff --git a/Source/Patches/GameObjects/CustomSun_Patch.cs b/Source/Patches/GameObjects/CustomSun_Patch.cs new file mode 100644 index 0000000..8392ad7 --- /dev/null +++ b/Source/Patches/GameObjects/CustomSun_Patch.cs @@ -0,0 +1,42 @@ +#if false +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +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) + return; + + var lookZombieTMP = lookZombieTransform.GetComponent(); + + if (lookZombieTMP != null) + StringStore.TranslateText(lookZombieTMP); + } +} +#endif diff --git a/Source/Patches/GameObjects/EveBuffMenu_Patch.cs b/Source/Patches/GameObjects/EveBuffMenu_Patch.cs new file mode 100644 index 0000000..44e582c --- /dev/null +++ b/Source/Patches/GameObjects/EveBuffMenu_Patch.cs @@ -0,0 +1,25 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(EveBuffMenu))] +public static class EveBuffMenu_Patch +{ + [HarmonyPatch(nameof(EveBuffMenu.Start)), HarmonyPostfix] + private static void Start(EveBuffMenu __instance) + { + foreach (var window in __instance.windows) + EveOptionWindow_Patch.TranslateEveOptionWindow(window); + + foreach (var text in __instance.quitButton.GetComponentsInChildren()) + text.text = StringStore.TranslateText("合上"); + } + + [HarmonyPatch(nameof(EveBuffMenu.InitWindows)), HarmonyPostfix] + private static void InitWindows(EveBuffMenu __instance) + { + foreach (var window in __instance.windows) + EveOptionWindow_Patch.TranslateEveOptionWindow(window); + } +} diff --git a/Source/Patches/GameObjects/EveOptionWindow_Patch.cs b/Source/Patches/GameObjects/EveOptionWindow_Patch.cs new file mode 100644 index 0000000..da59511 --- /dev/null +++ b/Source/Patches/GameObjects/EveOptionWindow_Patch.cs @@ -0,0 +1,33 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(EveOptionWindow))] +public static class EveOptionWindow_Patch +{ + [HarmonyPatch(nameof(EveOptionWindow.SetType)), HarmonyPostfix] + private static void SetType(EveOptionWindow __instance) => TranslateEveOptionWindow(__instance); + + [HarmonyPatch(nameof(EveOptionWindow.OnAnimOver)), HarmonyPostfix] + private static void OnAnimOver(EveOptionWindow __instance) => TranslateEveOptionWindow(__instance); + + [HarmonyPatch(nameof(EveOptionWindow.SelectedByRow)), HarmonyPostfix] + private static void SelectedByRow(EveOptionWindow __instance) => TranslateEveOptionWindow(__instance); + + public static void TranslateEveOptionWindow(EveOptionWindow __instance) + { + var introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + var introduceText = introduceTransform.GetComponent(); + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + + foreach (var text in __instance.buttonText) + { + text.text = StringStore.TranslateText(text.text); + text.font = fontAsset; + } + } +} diff --git a/Source/Patches/GameObjects/ExploreEnterWindow_Patch.cs b/Source/Patches/GameObjects/ExploreEnterWindow_Patch.cs new file mode 100644 index 0000000..a5fd0b8 --- /dev/null +++ b/Source/Patches/GameObjects/ExploreEnterWindow_Patch.cs @@ -0,0 +1,56 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(ExploreEnterWindow))] +public static class ExploreEnterWindow_Patch +{ + [HarmonyPatch(nameof(ExploreEnterWindow.Awake)), HarmonyPostfix] + private static void Awake(ExploreEnterWindow __instance) + { + var thePlantType = (PlantType)__instance.selfType; + + __instance.nameText.text = Utils.GetPlantNameFromAlmanac(thePlantType); + + if (__instance.nameText.text == "") + StringStore.TranslateText(__instance.nameText.text); + + __instance.nameText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + + [HarmonyPatch(nameof(ExploreEnterWindow.SetInfo)), HarmonyPostfix] + private static void SetInfo(ExploreEnterWindow __instance) + { + var thePlantType = (PlantType)__instance.selfType; + + __instance.nameText.text = Utils.GetPlantNameFromAlmanac(thePlantType); + + if (__instance.nameText.text == "") + StringStore.TranslateText(__instance.nameText.text); + + __instance.nameText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + + [HarmonyPatch(nameof(ExploreEnterWindow.SetIcon)), HarmonyPostfix] + private static void SetIcon(ExploreEnterWindow __instance) + { + var thePlantType = (PlantType)__instance.selfType; + + __instance.nameText.text = Utils.GetPlantNameFromAlmanac(thePlantType); + + if (__instance.nameText.text == "") + StringStore.TranslateText(__instance.nameText.text); + + __instance.nameText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + + [HarmonyPatch(nameof(ExploreEnterWindow.SetDisable)), HarmonyPostfix] + private static void SetDisable(ExploreEnterWindow __instance) + { + if (__instance.disabled) + __instance.nameText.text = StringStore.TranslateText("敬请期待"); + + __instance.nameText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } +} diff --git a/Source/Patches/GameObjects/ExploreMakeMenu_Patch.cs b/Source/Patches/GameObjects/ExploreMakeMenu_Patch.cs new file mode 100644 index 0000000..5dd1873 --- /dev/null +++ b/Source/Patches/GameObjects/ExploreMakeMenu_Patch.cs @@ -0,0 +1,59 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(ExploreMakeMenu))] +public static class ExploreMakeMenu_Patch +{ + [HarmonyPatch(nameof(ExploreMakeMenu.Awake)), HarmonyPostfix] + private static void Awake(ExploreMakeMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + } + + [HarmonyPatch(nameof(ExploreMakeMenu.InitMenu)), HarmonyPostfix] + private static void InitMenu(ExploreMakeMenu __instance) + { + _ = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + if (txt.text.Contains("关卡制作中:")) + { + var plantName = Utils.GetPlantNameFromAlmanac(txt.text.Split(":")[1]); + txt.text = string.Format(StringStore.TranslationStringRegex["关卡制作中:([^\\s]+)"], plantName); + } + else + txt.text = StringStore.TranslateText(txt.text); + } + + [HarmonyPatch(nameof(ExploreMakeMenu.ViewScene)), HarmonyPostfix] + private static void ViewScene(ExploreMakeMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + } + + [HarmonyPatch(nameof(ExploreMakeMenu.InitZombieButtons)), HarmonyPostfix] + private static void InitZombieButtons(ExploreMakeMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + } +} diff --git a/Source/Patches/GameObjects/ExploreMenu_Patch.cs b/Source/Patches/GameObjects/ExploreMenu_Patch.cs new file mode 100644 index 0000000..3bbd9e3 --- /dev/null +++ b/Source/Patches/GameObjects/ExploreMenu_Patch.cs @@ -0,0 +1,28 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(ExploreMenu))] +public static class ExploreMenu_Patch +{ + [HarmonyPatch(nameof(ExploreMenu.Awake)),HarmonyPostfix] + private static void Awake(ExploreMenu __instance) + { + _ = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + txt.text = StringStore.TranslateText(txt.text); + + // var randomLevelTextTransform = __instance.transform.FindChild("RandomLevel"); + } + + [HarmonyPatch(nameof(ExploreMenu.UpdateWindows)),HarmonyPostfix] + private static void UpdateWindows(ExploreMenu __instance) + { + _ = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + txt.text = StringStore.TranslateText(txt.text); + } +} diff --git a/Source/Patches/GameObjects/FruitNinjaSelectWindow_Patch.cs b/Source/Patches/GameObjects/FruitNinjaSelectWindow_Patch.cs new file mode 100644 index 0000000..c0b7a8e --- /dev/null +++ b/Source/Patches/GameObjects/FruitNinjaSelectWindow_Patch.cs @@ -0,0 +1,30 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(FruitNinjaSelectWindow))] +public static class FruitNinjaSelectWindow_Patch +{ + [HarmonyPatch(nameof(FruitNinjaSelectWindow.SetType)), HarmonyPostfix] + private static void SetType(FruitNinjaSelectWindow __instance) + { + var introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + var introduceText = introduceTransform.GetComponent(); + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } + + [HarmonyPatch(nameof(FruitNinjaSelectWindow.OnAnimOver)), HarmonyPostfix] + private static void OnAnimOver(FruitNinjaSelectWindow __instance) + { + var introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + var introduceText = introduceTransform.GetComponent(); + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } +} diff --git a/Source/Patches/GameObjects/GardenPlant_Patch.cs b/Source/Patches/GameObjects/GardenPlant_Patch.cs new file mode 100644 index 0000000..0ac3265 --- /dev/null +++ b/Source/Patches/GameObjects/GardenPlant_Patch.cs @@ -0,0 +1,22 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(GardenPlant))] +public static class GardenPlant_Patch +{ + [HarmonyPatch(nameof(GardenPlant.Start)), HarmonyPostfix] + private static void Start(GardenPlant __instance) + { + __instance.infoText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + __instance.infoText.text = StringStore.TranslateText(__instance.infoText.text); + } + + [HarmonyPatch(nameof(GardenPlant.UpdateInfo)), HarmonyPostfix] + private static void UpdateInfo(GardenPlant __instance) + { + __instance.infoText.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + __instance.infoText.text = StringStore.TranslateText(__instance.infoText.text); + } +} diff --git a/Source/Patches/GameObjects/GardenStoreMenu_Patch.cs b/Source/Patches/GameObjects/GardenStoreMenu_Patch.cs new file mode 100644 index 0000000..1a5dd2f --- /dev/null +++ b/Source/Patches/GameObjects/GardenStoreMenu_Patch.cs @@ -0,0 +1,27 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(GardenStoreMenu))] +public static class GardenStoreMenu_Patch +{ + [HarmonyPatch(nameof(GardenStoreMenu.InitGoodsList)), HarmonyPatch(nameof(GardenStoreMenu.GetDatas)), + HarmonyPatch(nameof(GardenStoreMenu.PurchaseGoods)), HarmonyPatch(nameof(GardenStoreMenu.Update)), + HarmonyPatch(nameof(GardenStoreMenu.Start)), HarmonyPostfix] + public static void TranslateGardenStoreMenu(GardenStoreMenu __instance) + { + foreach (var slot in __instance.GetComponentsInChildren()) + TranslateGardenShopSlot(slot); + } + + [HarmonyPatch(nameof(GardenShopSlot.Start)), HarmonyPostfix] + public static void TranslateGardenShopSlot(GardenShopSlot __instance) + { + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + } +} diff --git a/Source/Patches/GameObjects/GodShootingMenu_Patch.cs b/Source/Patches/GameObjects/GodShootingMenu_Patch.cs new file mode 100644 index 0000000..b2e0a72 --- /dev/null +++ b/Source/Patches/GameObjects/GodShootingMenu_Patch.cs @@ -0,0 +1,34 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(GodShootingMenu))] +public static class GodShootingMenu_Patch +{ + [HarmonyPatch(nameof(GodShootingMenu.Start)), HarmonyPostfix] + private static void Start(GodShootingMenu __instance) + { + foreach (var text in __instance.transform.Find("Background").GetComponentsInChildren()) + { + text.autoSizeTextContainer = true; + text.text = StringStore.TranslateText(text.text); + } + + foreach (var text in __instance.GetComponentsInChildren()) + text.text = StringStore.TranslateText(text.text); + } + + [HarmonyPatch(nameof(GodShootingMenu.ShowRoutes)), HarmonyPostfix] + private static void ShowRoutes(GodShootingMenu __instance) + { + foreach (var route in __instance.routes) + { + if (route.Value == null) + continue; + + foreach (var text in route.Value.GetComponentsInChildren()) + text.text = StringStore.TranslateText(text.text); + } + } +} diff --git a/Source/Patches/GameObjects/LevelResultMenu_Patch.cs b/Source/Patches/GameObjects/LevelResultMenu_Patch.cs new file mode 100644 index 0000000..bd047ff --- /dev/null +++ b/Source/Patches/GameObjects/LevelResultMenu_Patch.cs @@ -0,0 +1,15 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(LevelResultMenu))] +public static class LevelResultMenu_Patch +{ + [HarmonyPatch(nameof(LevelResultMenu.Start)), HarmonyPatch(nameof(LevelResultMenu.ShowResult)), HarmonyPostfix] + public static void Awake(LevelResultMenu __instance) + { + foreach (var txt in __instance.GetComponentsInChildren()) + txt.text = StringStore.TranslateText(txt.text); + } +} diff --git a/Source/Patches/GameObjects/LoseMenu_Patch.cs b/Source/Patches/GameObjects/LoseMenu_Patch.cs new file mode 100644 index 0000000..96862b6 --- /dev/null +++ b/Source/Patches/GameObjects/LoseMenu_Patch.cs @@ -0,0 +1,14 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(LoseMenu))] +public static class LoseMenu_Patch +{ + public static void TranslateLoseMenu(BaseMenu __instance) + { + if (__instance.TryGetComponent(out var loseMenu)) + loseMenu.title.text = StringStore.TranslateText(loseMenu.title.text); + } +} diff --git a/Source/Patches/GameObjects/MainMenu_Patch.cs b/Source/Patches/GameObjects/MainMenu_Patch.cs new file mode 100644 index 0000000..654e61f --- /dev/null +++ b/Source/Patches/GameObjects/MainMenu_Patch.cs @@ -0,0 +1,103 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; +using PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(MainMenu))] +public class MainMenu_Patch +{ + public static void AnimOver(BaseMenu __instance) + { + var changelogObj = __instance.transform.Find("Grave/UpdateInfoButton"); + + var langObj = UnityEngine.Object.Instantiate( + changelogObj, + changelogObj.position + new Vector3(0.0f, 0.855f), + changelogObj.rotation, + __instance.transform.Find("Grave") + ); + + langObj.name = "LanguagesButton"; + __instance.collider2Ds.Add(langObj.GetComponent()); + var langBtn = langObj.GetComponent(); + + foreach (var text in langObj.GetComponentsInChildren()) + text.text = StringStore.TranslateText("Languages"); + + langBtn.clickEvent = new(); + langBtn.clickEvent.AddListener(new Action(() => OpenLanguageMenu(langBtn.gameObject))); + } + + public static void OpenLanguageMenu(GameObject langBtn) + { + UIMgr.EnterOptionMenu(); + var newOptionsMenu = GameAPP.canvasUp.Find("OptionMenu(Clone)").gameObject; + newOptionsMenu.name = "LanguageMenu"; + + var toKeep = new List { "Background", "F", "Goback" }; + + foreach (var child in newOptionsMenu.GetComponentsInChildren() + .Where(c => !toKeep.Contains(c.name) && !toKeep.Contains(c.parent.name) && c.name != "LanguageMenu")) + child.gameObject.SetActive(false); + + var templateButton = newOptionsMenu.transform.Find("Buttons/F").GetComponent(); + OptLanguageBtn_Patch.OptLangBtn_Patch.Awake(templateButton); + + // var goBackButton = newOptionsMenu.transform.Find("Goback").GetComponent(); + + newOptionsMenu.transform.Find("Buttons/F").gameObject.SetActive(false); + newOptionsMenu.transform.Find("Buttons").gameObject.SetActive(true); + + foreach (var text in newOptionsMenu.transform.Find("Background").GetComponentsInChildren()) + text.text = StringStore.TranslateText("Language Settings"); + + /*GameObject optionMenuAnchor = UnityEngine.Object.Instantiate(assetBundle.LoadAsset("OptionMenu").TryCast(), GameAPP.canvasUp); + optionMenuAnchor.transform.SetParent(newOptionsMenu.transform, false); + Transform messageAnchor = optionMenuAnchor.transform.Find("MessageAnchor"); + Transform plantAnchor = optionMenuAnchor.transform.Find("PlantAnchor"); + + System.Random random = new System.Random(); + var plantTypes = Enum.GetValues(typeof(PlantType)); + PlantType randomPlantChoice = (PlantType)plantTypes.GetValue(random.Next(plantTypes.Length)); + + if(!GameAPP.resourcesManager.plantPrefabs.ContainsKey(randomPlantChoice) || GameAPP.resourcesManager.plantPrefabs[randomPlantChoice] == null) + { + randomPlantChoice = (PlantType)plantTypes.GetValue(random.Next(plantTypes.Length)); + } + + if (GameAPP.resourcesManager.plantPrefabs[randomPlantChoice] != null) + { + GameObject plant = CreatePlant.SetPlantInAlmamac(plantAnchor.position, (int)randomPlantChoice); + plant.transform.SetParent(newOptionsMenu.transform); + SortingGroup sortingGroup = plant.AddComponent(); + sortingGroup.sortingLayerName = "UI"; + sortingGroup.sortingOrder = 20001; + //plant.transform.position = new Vector3(-7.21f, -3.66f); + UnityEngine.Object.Destroy(plant.GetComponent()); + }*/ + + /*GameObject messageObj = new GameObject(); + messageObj.name = "MultilangMessage"; + messageObj.transform.SetParent(newOptionsMenu.transform); + TextMeshProUGUI messageText = messageObj.AddComponent(); + messageObj.transform.localScale = Vector3.one; + messageText.autoSizeTextContainer = false; + messageText.font = FontStore.LoadTMPFont(Utils.LanguageEnum.English.ToString()); + messageText.text = "Hello this is multilanguage choose language over there ------>";*/ + } + + [HarmonyPatch(nameof(MainMenu.EnterUpdateUrl)), HarmonyPrefix] + public static bool Pre_EnterUpdateUrl(MainMenu __instance) + { + System.Diagnostics.Process.Start( + new System.Diagnostics.ProcessStartInfo + { + FileName = "https://github.com/Teyliu/PVZF-Translation", + UseShellExecute = true, + } + ); + + return false; + } +} diff --git a/Source/Patches/GameObjects/MinorObjects/Brain_Patch.cs b/Source/Patches/GameObjects/MinorObjects/Brain_Patch.cs new file mode 100644 index 0000000..844d9ec --- /dev/null +++ b/Source/Patches/GameObjects/MinorObjects/Brain_Patch.cs @@ -0,0 +1,48 @@ +using HarmonyLib; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects; + +[HarmonyPatch(typeof(Brain))] +public static class Brain_Patch +{ + [HarmonyPostfix, HarmonyPatch(nameof(Brain.Awake))] + private static void Awake(Brain __instance) + { + // reposition original points + var pointsTransform = __instance.points.transform; + var pointsObject = __instance.points.gameObject; + pointsTransform.position = new(-6.5f, pointsTransform.position.y, pointsTransform.position.z); + + // instantiate and move new shadow + var pointsShadowObject = UnityEngine.Object.Instantiate(pointsObject, pointsTransform); + pointsShadowObject.SetActive(true); + var pointsShadowTransform = pointsShadowObject.transform; + pointsShadowTransform.position = new(-6.485f, pointsTransform.position.y - 0.015f, pointsTransform.position.z); + + // set points text + var pointsShadowText = pointsShadowObject.GetComponent(); + pointsShadowText.text = __instance.points.text; + pointsShadowText.sortingOrder -= 2; + pointsShadowText.color = Color.black; + } + + [HarmonyPostfix, HarmonyPatch(nameof(Brain.Update))] + private static void Update(Brain __instance) + { + if (__instance.transform.Find("Points").GetChild(0) == null) + return; + + var shadowText = __instance.transform.Find("Points").GetChild(0).GetComponent(); + shadowText.text = __instance.points.text; + } + + [HarmonyPostfix, HarmonyPatch(nameof(Brain.WinAction))] + private static void WinAction(Brain __instance) + { + if (__instance.transform.Find("Points").GetChild(0) == null) + return; + + var shadowText = __instance.transform.Find("Points").GetChild(0).GetComponent(); + shadowText.text = __instance.points.text; + } +} diff --git a/Source/Patches/GameObjects/MinorObjects/DY_Patch.cs b/Source/Patches/GameObjects/MinorObjects/DY_Patch.cs new file mode 100644 index 0000000..922b813 --- /dev/null +++ b/Source/Patches/GameObjects/MinorObjects/DY_Patch.cs @@ -0,0 +1,12 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects; + +[HarmonyPatch(typeof(DY))] +public static class DyPatch +{ + [HarmonyPostfix, HarmonyPatch(nameof(DY.Update))] + private static void Update(DY __instance) => + __instance.TextMeshPro.text = StringStore.TranslateText(__instance.TextMeshPro.text); +} diff --git a/Source/Patches/GameObjects/MinorObjects/GameLose_Patch.cs b/Source/Patches/GameObjects/MinorObjects/GameLose_Patch.cs new file mode 100644 index 0000000..4160996 --- /dev/null +++ b/Source/Patches/GameObjects/MinorObjects/GameLose_Patch.cs @@ -0,0 +1,20 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.Patches.BaseTextObjects; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects; + +[HarmonyPatch(typeof(GameLose))] +public static class GameLose_Patch +{ + [HarmonyPatch(nameof(GameLose.UpdateSecondChanceTimer))] + public static void UpdateSecondChanceTimer(GameLose __instance) + { + if (InGameText.Instance == null) + return; + + if (InGameText.Instance.timer < 0) + return; + + InGameText_Patch.TranslateInGameText(InGameText.Instance); + } +} diff --git a/Source/Patches/GameObjects/MinorObjects/HealthSlider_Patch.cs b/Source/Patches/GameObjects/MinorObjects/HealthSlider_Patch.cs new file mode 100644 index 0000000..9af97c4 --- /dev/null +++ b/Source/Patches/GameObjects/MinorObjects/HealthSlider_Patch.cs @@ -0,0 +1,34 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects; + +[HarmonyPatch(typeof(HealthSlider))] +public static class HealthSlider_Patch +{ +#pragma warning disable CA2211 + public static TMP_FontAsset FontAsset; +#pragma warning restore CA2211 + [HarmonyPatch(nameof(HealthSlider.Start)), HarmonyPostfix] + public static void Post_Start(HealthSlider __instance) + { + if (!FontAsset) + FontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + + [HarmonyPatch(nameof(HealthSlider.UpdateText)), HarmonyPostfix] + public static void Post_UpdateText(HealthSlider __instance) + { + if (!FontAsset) + FontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + if (__instance.healthText.font != FontAsset) + __instance.healthText.font = FontAsset; + + foreach (var txt in __instance.healthTextContainer.GetComponentsInChildren(true)) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = FontAsset; + } + } +} diff --git a/Source/Patches/GameObjects/MinorObjects/Jigsaw_Patch.cs b/Source/Patches/GameObjects/MinorObjects/Jigsaw_Patch.cs new file mode 100644 index 0000000..321901a --- /dev/null +++ b/Source/Patches/GameObjects/MinorObjects/Jigsaw_Patch.cs @@ -0,0 +1,27 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects; + +[HarmonyPatch(typeof(JigsawClip))] +public static class JigsawClip_Patch +{ + [HarmonyPostfix, HarmonyPatch(nameof(JigsawClip.Awake))] + private static void Postfix_Awake(JigsawClip __instance) + { + if (!__instance || !__instance.description) + return; + + StringStore.TranslateTextUI(__instance.description); + } + + [HarmonyPostfix, HarmonyPatch(nameof(JigsawClip.Update))] + private static void Postfix_Update(JigsawClip __instance) + { + if (!__instance || !__instance.description) + return; + + if (__instance.description.text != StringStore.TranslateText(__instance.description.text)) + StringStore.TranslateTextUI(__instance.description); + } +} diff --git a/Source/Patches/GameObjects/MinorObjects/LanternUmbrella_Patch.cs b/Source/Patches/GameObjects/MinorObjects/LanternUmbrella_Patch.cs new file mode 100644 index 0000000..ca783a0 --- /dev/null +++ b/Source/Patches/GameObjects/MinorObjects/LanternUmbrella_Patch.cs @@ -0,0 +1,17 @@ +#if false +using HarmonyLib; +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); + } +} +#endif diff --git a/Source/Patches/GameObjects/MinorObjects/MagnetBox_Patch.cs b/Source/Patches/GameObjects/MinorObjects/MagnetBox_Patch.cs new file mode 100644 index 0000000..d0a85a9 --- /dev/null +++ b/Source/Patches/GameObjects/MinorObjects/MagnetBox_Patch.cs @@ -0,0 +1,11 @@ +using HarmonyLib; +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); +} diff --git a/Source/Patches/GameObjects/MinorObjects/MagnetInterface_Patch.cs b/Source/Patches/GameObjects/MinorObjects/MagnetInterface_Patch.cs new file mode 100644 index 0000000..d09156c --- /dev/null +++ b/Source/Patches/GameObjects/MinorObjects/MagnetInterface_Patch.cs @@ -0,0 +1,11 @@ +using HarmonyLib; +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); +} diff --git a/Source/Patches/GameObjects/MinorObjects/Money_Patch.cs b/Source/Patches/GameObjects/MinorObjects/Money_Patch.cs new file mode 100644 index 0000000..bf7e205 --- /dev/null +++ b/Source/Patches/GameObjects/MinorObjects/Money_Patch.cs @@ -0,0 +1,18 @@ +using HarmonyLib; +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) + { + if (!Utils.CheckForUntranslatedText(__instance.beanCount.text)) + return; + + __instance.beanCount.text = StringStore.TranslateText(__instance.beanCount.text); + __instance.beanCount2.text = StringStore.TranslateText(__instance.beanCount2.text); + } +} diff --git a/Source/Patches/GameObjects/MinorObjects/Plant_Patch.cs b/Source/Patches/GameObjects/MinorObjects/Plant_Patch.cs new file mode 100644 index 0000000..a2a2734 --- /dev/null +++ b/Source/Patches/GameObjects/MinorObjects/Plant_Patch.cs @@ -0,0 +1,51 @@ +#if false +using System.Text.RegularExpressions; +using HarmonyLib; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects; + +[HarmonyPatch(typeof(Plant))] +public static class Plant_Patch +{ + [HarmonyPostfix, HarmonyPatch(nameof(Plant.Awake))] + private static void Awake(Plant __instance) + { + if (__instance.thePlantType is not (PlantType.SuperMachineNut or PlantType.MachineNut)) + return; + + __instance.healthSlider.healthText.text = __instance.healthSlider.healthTextShadow.text = + ChangeHPText(__instance.healthSlider.healthTextShadow.text); + } + + [HarmonyPostfix, HarmonyPatch(nameof(Plant.UpdateText))] + private static void Update(Plant __instance) + { + if (__instance.thePlantType is not (PlantType.SuperMachineNut or PlantType.MachineNut)) + return; + + if (__instance.thePlantHealth < __instance.thePlantMaxHealth) + return; + + __instance.healthSlider.healthText.text = __instance.healthSlider.healthTextShadow.text = + ChangeHPText(__instance.healthSlider.healthTextShadow.text); + } + + private static string ChangeHPText(string originalText) + { + var regex = new Regex(@"(\d+)\d\d\d/(\d)000"); + + if (!regex.IsMatch(originalText)) + return originalText; + + var match = regex.Match(originalText); + var groupCount = match.Groups.Count; + + var dynamicParts = new List(); + + for (var i = 1; i < groupCount; i++) + dynamicParts.Add(match.Groups[i].Value); + + return string.Format("{0}k/{1}k", [..dynamicParts]); + } +} +#endif diff --git a/Source/Patches/GameObjects/MinorObjects/PlayerName_Patch.cs b/Source/Patches/GameObjects/MinorObjects/PlayerName_Patch.cs new file mode 100644 index 0000000..40aa856 --- /dev/null +++ b/Source/Patches/GameObjects/MinorObjects/PlayerName_Patch.cs @@ -0,0 +1,15 @@ +#if false +using HarmonyLib; +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); +} +#endif diff --git a/Source/Patches/GameObjects/MinorObjects/PumpinerChestMenu_Patch.cs b/Source/Patches/GameObjects/MinorObjects/PumpinerChestMenu_Patch.cs new file mode 100644 index 0000000..e93cfa5 --- /dev/null +++ b/Source/Patches/GameObjects/MinorObjects/PumpinerChestMenu_Patch.cs @@ -0,0 +1,16 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects; + +[HarmonyPatch(typeof(PumpinerChestMenu))] +public static class PumpinerChestMenu_Patch +{ + [HarmonyPatch(nameof(PumpinerChestMenu.InitPlants)), HarmonyPostfix] + public static void Post_InitPlants(PumpinerChestMenu __instance) + { + var closeBtnTransform = __instance.transform.Find("SampleButton"); + var txt = closeBtnTransform.GetComponentInChildren(); + txt.text = StringStore.TranslateText("合上"); + } +} diff --git a/Source/Patches/GameObjects/MinorObjects/SelectYourPlants_Patch.cs b/Source/Patches/GameObjects/MinorObjects/SelectYourPlants_Patch.cs new file mode 100644 index 0000000..c00a74b --- /dev/null +++ b/Source/Patches/GameObjects/MinorObjects/SelectYourPlants_Patch.cs @@ -0,0 +1,20 @@ +#if false +using HarmonyLib; +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; + } +} +#endif diff --git a/Source/Patches/GameObjects/MinorObjects/SpecialCard_Patch.cs b/Source/Patches/GameObjects/MinorObjects/SpecialCard_Patch.cs new file mode 100644 index 0000000..59f9cd0 --- /dev/null +++ b/Source/Patches/GameObjects/MinorObjects/SpecialCard_Patch.cs @@ -0,0 +1,21 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects; + +[HarmonyPatch(typeof(SpecialCard))] +public static class SpecialCard_Patch +{ + [HarmonyPatch(nameof(SpecialCard.Awake)), HarmonyPatch(nameof(SpecialCard.Start)), + HarmonyPatch(nameof(SpecialCard.ClickedEvent)), HarmonyPostfix] + public static void Post_Awake(SpecialCard __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + } +} diff --git a/Source/Patches/GameObjects/MinorObjects/TrainingDummy_Patch.cs b/Source/Patches/GameObjects/MinorObjects/TrainingDummy_Patch.cs new file mode 100644 index 0000000..11a4e9d --- /dev/null +++ b/Source/Patches/GameObjects/MinorObjects/TrainingDummy_Patch.cs @@ -0,0 +1,12 @@ +using HarmonyLib; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects; + +[HarmonyPatch(typeof(TrainingDummy), nameof(TrainingDummy.UpdateHealthText))] +public static class TrainingDummy_Patch +{ + [HarmonyPostfix] + public static void UpdateHealthText(TrainingDummy __instance) => + // Zombie_Patch.TranslateHpUI_T(__instance.healthTextShadow, __instance); + Zombie_Patch.TranslateHpUI_T(__instance.healthText, __instance); +} diff --git a/Source/Patches/GameObjects/MinorObjects/TreasureMoney_Patch.cs b/Source/Patches/GameObjects/MinorObjects/TreasureMoney_Patch.cs new file mode 100644 index 0000000..df80c69 --- /dev/null +++ b/Source/Patches/GameObjects/MinorObjects/TreasureMoney_Patch.cs @@ -0,0 +1,12 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects; + +[HarmonyPatch(typeof(TreasureMoney))] +public static class TreasureMoney_Patch +{ + [HarmonyPostfix, HarmonyPatch(nameof(TreasureMoney.Update))] + private static void Update(TreasureMoney __instance) => + __instance.text = StringStore.TranslateText(__instance.text); +} diff --git a/Source/Patches/GameObjects/MinorObjects/UIProgress2_Patch.cs b/Source/Patches/GameObjects/MinorObjects/UIProgress2_Patch.cs new file mode 100644 index 0000000..68b52c0 --- /dev/null +++ b/Source/Patches/GameObjects/MinorObjects/UIProgress2_Patch.cs @@ -0,0 +1,12 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects; + +[HarmonyPatch(typeof(UIProgress2))] +public static class UIProgress2_Patch +{ + [HarmonyPatch(nameof(UIProgress2.Update)), HarmonyPostfix] + private static void Update(UIProgress2 __instance) => + __instance.t.text = StringStore.TranslateText(__instance.t.text); +} diff --git a/Source/Patches/GameObjects/MinorObjects/UltimateChomper_Patch.cs b/Source/Patches/GameObjects/MinorObjects/UltimateChomper_Patch.cs new file mode 100644 index 0000000..1b0ebe6 --- /dev/null +++ b/Source/Patches/GameObjects/MinorObjects/UltimateChomper_Patch.cs @@ -0,0 +1,17 @@ +#if false +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects; + +[HarmonyPatch(typeof(UltimateChomper), nameof(UltimateChomper.UpdateText))] +public static class UltimateChomper_Patch +{ + [HarmonyPostfix] + public static void UpdateText(UltimateChomper __instance) + { + StringStore.TranslateText(__instance.killingText); + StringStore.TranslateText(__instance.killingTextShadow); + } +} +#endif diff --git a/Source/Patches/GameObjects/MinorObjects/Zombie_Patch.cs b/Source/Patches/GameObjects/MinorObjects/Zombie_Patch.cs new file mode 100644 index 0000000..49555a5 --- /dev/null +++ b/Source/Patches/GameObjects/MinorObjects/Zombie_Patch.cs @@ -0,0 +1,184 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; +using System.Text.RegularExpressions; + +namespace PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects; + +[HarmonyPatch(typeof(Zombie))] +public static class Zombie_Patch +{ + private static readonly Dictionary s_hpStrings = new() + { + { "最后一击:(\\d+)\nDPS:([^\\s]+)\n总伤害:(\\d+)", "Last Damage: {0}\nDPS: {1}\nTotal: {2}" }, + { + "^HP:(\\d+)/(\\d+)\n一类:(\\d+)/(\\d+)\n二类:(\\d+)/(\\d+)$", + "HP: {0}/{1}\nT1 armor: {2}/{3}\nT2 armor: {4}/{5}" + }, + { "^HP:(\\d+)/(\\d+)\n一类:(\\d+)/(\\d+)$", "HP: {0}/{1}\nT1 armor: {2}/{3}" }, + { "^HP:(\\d+)/(\\d+)\n二类:(\\d+)/(\\d+)$", "HP: {0}/{1}\nT2 armor: {2}/{3}" }, + { @"^HP:(\d+)/(\d+)$", "HP: {0}/{1}" }, + }; + + public static void LoadHpStrings() + { + foreach (var hp in s_hpStrings) + if (StringStore.TranslationStringRegex.TryGetValue(hp.Key, out var value)) + s_hpStrings[hp.Key] = value; + } + + [HarmonyPatch(nameof(Zombie.Start)), HarmonyPostfix] + public static void Start(Zombie __instance) + { + TranslateHpUI(__instance.healthText, __instance); + //TranslateHpUI(__instance.healthTextShadow, __instance); + + if (__instance.healthText.transform.rotation != Quaternion.Euler(0, 0, 0)) + __instance.healthText.transform.rotation = Quaternion.Euler(0f, 0f, 0f); + } + + [HarmonyPatch(nameof(Zombie.UpdateHealthText)), HarmonyPostfix] + public static void Update(Zombie __instance) + { + if (__instance.theZombieType == ZombieType.TrainingDummy || !Board.Instance.showZombieHealth) + return; + + if (__instance.healthText == null) + return; + + TranslateHpUI(__instance.healthText, __instance); + //TranslateHpUI(__instance.healthTextShadow, __instance); + + if (__instance.healthText.transform.rotation != Quaternion.Euler(0f, 0f, 0f)) + __instance.healthText.transform.rotation = Quaternion.Euler(0f, 0f, 0f); + } + + public static void TranslateHpUI(TextMeshPro textTMP, Zombie __instance) + { + if (!textTMP) + return; + + var origText = textTMP.text; + var translatedText = origText; + + if (translatedText == null) + return; + + const string Pattern = "(\\d+)阶\n([\\s\\S]+)"; + + if (StringStore.TestRegex(translatedText, Pattern)) + { + var match = Regex.Match(translatedText, Pattern, RegexOptions.Singleline); + var tier = match.Groups[1].Value; + var healthText = TranslateHpText(match.Groups[2].Value, __instance); + var fStr = StringStore.TranslationStringRegex[Pattern]; + translatedText = string.Format(fStr, [tier, healthText]); + } + else + translatedText = TranslateHpText(origText, __instance); + + textTMP.text = translatedText == origText ? origText : translatedText; + textTMP.autoSizeTextContainer = false; + + if (translatedText != origText) + textTMP.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + + public static void TranslateHpUI_T(TextMeshPro textTMP, TrainingDummy __instance) + { + if (!textTMP) + return; + + var origText = textTMP.text; + var translatedText = TranslateHPText_T(origText, __instance); + textTMP.text = translatedText == origText ? origText : translatedText; + textTMP.autoSizeTextContainer = false; + + if (translatedText != origText) + textTMP.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + + public static string TranslateHpText(string originalText, Zombie __instance) + { + if (originalText == null) + return null; + + var finalText = __instance.healthText.text; + var fIndex = -1; + var found = false; + + for (var i = 0; i < s_hpStrings.Count; i++) + { + var hp = s_hpStrings.ElementAt(i); + + if (!Regex.Match(originalText, hp.Key, RegexOptions.Singleline).Success) + continue; + + fIndex = i; + found = true; + } + + if (fIndex <= -1 || !found) + return finalText; + + var fStr = s_hpStrings.ElementAt(fIndex).Value; + + return fIndex switch + { + 1 => string.Format( + fStr, + __instance.theHealth, + __instance.theMaxHealth, + __instance.theFirstArmorHealth, + __instance.theFirstArmorMaxHealth, + __instance.theSecondArmorHealth, + __instance.theSecondArmorMaxHealth + ), + 2 => string.Format( + fStr, + __instance.theHealth, + __instance.theMaxHealth, + __instance.theFirstArmorHealth, + __instance.theFirstArmorMaxHealth + ), + 3 => string.Format( + fStr, + __instance.theHealth, + __instance.theMaxHealth, + __instance.theSecondArmorHealth, + __instance.theSecondArmorMaxHealth + ), + 4 => string.Format(fStr, __instance.theHealth, __instance.theMaxHealth), + _ => finalText, + }; + } + + public static string TranslateHPText_T(string originalText, TrainingDummy __instance) + { + var finalText = __instance.healthText.text; + var fIndex = -1; + var found = false; + + for (var i = 0; i < s_hpStrings.Count; i++) + { + var hp = s_hpStrings.ElementAt(i); + var regex = new Regex(hp.Key); + + if (!regex.IsMatch(originalText)) + continue; + + fIndex = i; + found = true; + } + + if (fIndex <= -1 || !found) + return finalText; + + var fStr = s_hpStrings.ElementAt(fIndex).Value; + + return fIndex switch + { + 0 => string.Format(fStr, __instance.lastDamage, __instance.CurrentDPS, __instance.totalDamage), + _ => finalText, + }; + } +} diff --git a/Source/Patches/GameObjects/NoticePauseMenu_Patch.cs b/Source/Patches/GameObjects/NoticePauseMenu_Patch.cs new file mode 100644 index 0000000..bb09216 --- /dev/null +++ b/Source/Patches/GameObjects/NoticePauseMenu_Patch.cs @@ -0,0 +1,53 @@ +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine.UI; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +public static class NoticePauseMenu_Patch +{ +#pragma warning disable CA2211 + public static string ChangelogText = ""; +#pragma warning restore CA2211 + public static void Pre_Awake(BaseMenu __instance) + { + var contentObject = __instance.transform.FindChild("Scroll View/Viewport/Content").gameObject; + + var contentText = contentObject.GetComponent(); + + File.WriteAllText( + Path.Combine(FileLoader.GetAssetDir(FileLoader.AssetType.Dumps), "changelog.txt"), + contentText.text + ); + + var stringDir = FileLoader.GetAssetDir(FileLoader.AssetType.Strings, Utils.Language); + var changelogDir = Path.Combine(stringDir, "changelog.txt"); + + if (!File.Exists(changelogDir)) + File.WriteAllText(changelogDir, contentText.text); + } + + public static void Post_Awake(BaseMenu __instance) + { + _ = FontStore.LoadTMPFont(Utils.Language.ToString()); + FileLoader.LoadChangelogText(); + + var contentObject = __instance.transform.FindChild("Scroll View/Viewport/Content").gameObject; + + var contentText = contentObject.GetComponent(); + contentText.text = ChangelogText; + contentText.margin = new(6, 2, 12, 0); + + contentText.enableWordWrapping = true; + contentText.overflowMode = TextOverflowModes.ScrollRect; + + Canvas.ForceUpdateCanvases(); + contentText.ForceMeshUpdate(); + + //float textHeight = contentText.preferredHeight; + //RectTransform contentRect = contentObject.GetComponent(); + //contentRect.sizeDelta = new Vector2(contentRect.sizeDelta.x, textHeight); + + var sizeFitter = contentObject.AddComponent(); + sizeFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; + } +} diff --git a/Source/Patches/GameObjects/OtherMenu_Patch.cs b/Source/Patches/GameObjects/OtherMenu_Patch.cs new file mode 100644 index 0000000..7cc2c99 --- /dev/null +++ b/Source/Patches/GameObjects/OtherMenu_Patch.cs @@ -0,0 +1,15 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(OtherMenu))] +public static class OtherMenu_Patch +{ + [HarmonyPatch(nameof(OtherMenu.UpdateText)), HarmonyPostfix] + private static void UpdateText(OtherMenu __instance) + { + __instance.text1 = StringStore.TranslateText(__instance.text1); + __instance.text2 = StringStore.TranslateText(__instance.text2); + } +} diff --git a/Source/Patches/GameObjects/PVPRandomManager_Patch.cs b/Source/Patches/GameObjects/PVPRandomManager_Patch.cs new file mode 100644 index 0000000..db06f86 --- /dev/null +++ b/Source/Patches/GameObjects/PVPRandomManager_Patch.cs @@ -0,0 +1,22 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(PVPRandomManager))] // ReSharper disable once InconsistentNaming +public static class PVPRandomManager_Patch +{ + [HarmonyPatch(nameof(PVPRandomManager.Start)), HarmonyPostfix] + private static void Start(PVPRandomManager __instance) + { + foreach (var text in __instance.texts) + text.text = StringStore.TranslateText(text.text); + } + + [HarmonyPatch(nameof(PVPRandomManager.Update)), HarmonyPostfix] + private static void ZombieEnterHouse(PVPRandomManager __instance) + { + foreach (var text in __instance.texts) + text.text = StringStore.TranslateText(text.text); + } +} diff --git a/Source/Patches/GameObjects/PlantCardPackageBuilder_Patch.cs b/Source/Patches/GameObjects/PlantCardPackageBuilder_Patch.cs new file mode 100644 index 0000000..7b7d914 --- /dev/null +++ b/Source/Patches/GameObjects/PlantCardPackageBuilder_Patch.cs @@ -0,0 +1,17 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(PlantCardPackageBuilder))] +public static class PlantCardPackageBuilder_Patch +{ + [HarmonyPatch(nameof(PlantCardPackageBuilder.UpdateText)), HarmonyPostfix] + private static void UpdateText(PlantCardPackageBuilder __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + __instance.text.text = StringStore.TranslateText(__instance.text.text); + __instance.text.font = fontAsset; + } +} diff --git a/Source/Patches/GameObjects/PlantDamageMenu_Patch.cs b/Source/Patches/GameObjects/PlantDamageMenu_Patch.cs new file mode 100644 index 0000000..e0ecb4c --- /dev/null +++ b/Source/Patches/GameObjects/PlantDamageMenu_Patch.cs @@ -0,0 +1,41 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(PlantDamageMenu))] +public static class PlantDamageMenu_Patch +{ + public static void Awake(BaseMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var text in __instance.GetComponentsInChildren()) + { + var originalKey = StringStore.TranslationString.FirstOrDefault(x => x.Value == text.text).Key; + + text.text = StringStore.TranslationString.ContainsKey(originalKey + "_RM") + ? StringStore.TranslateText(originalKey + "_RM") + : StringStore.TranslateText(text.text); + + text.font = fontAsset; + } + } + + [HarmonyPatch(nameof(PlantDamageMenu.Awake)), HarmonyPatch(nameof(PlantDamageMenu.InitCards)), HarmonyPostfix] + public static void InitCards(PlantDamageMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var text in __instance.GetComponentsInChildren()) + { + var originalKey = StringStore.TranslationString.FirstOrDefault(x => x.Value == text.text).Key; + + text.text = StringStore.TranslationString.ContainsKey(originalKey + "_RM") + ? StringStore.TranslateText(originalKey + "_RM") + : StringStore.TranslateText(text.text); + + text.font = fontAsset; + } + } +} diff --git a/Source/Patches/GameObjects/PlantDataMenu_Patch.cs b/Source/Patches/GameObjects/PlantDataMenu_Patch.cs new file mode 100644 index 0000000..29b5eec --- /dev/null +++ b/Source/Patches/GameObjects/PlantDataMenu_Patch.cs @@ -0,0 +1,66 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; +using System.Text.RegularExpressions; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(PlantDataMenu))] +public static class PlantDataMenu_Patch +{ + [HarmonyPatch(nameof(PlantDataMenu.Start)), HarmonyPostfix] + public static void Post_Start(PlantDataMenu __instance) => TranslatePlantDataMenu(__instance); +#if false + [HarmonyPatch(nameof(PlantDataMenu.Update)), HarmonyPostfix] + public static void Post_Update(PlantDataMenu __instance) => TranslatePlantDataMenu(__instance); +#endif + [HarmonyPatch(nameof(PlantDataMenu.InitDataFromPlant)), HarmonyPostfix] + public static void Post_InitDataFromPlant(PlantDataMenu __instance) => TranslatePlantDataMenu(__instance); + + public static void TranslatePlantDataMenu(PlantDataMenu __instance) + { + if (!__instance) + return; + + var thePlantType = __instance.plant.thePlantType; + var plantName = Utils.GetPlantNameFromAlmanac(thePlantType); + + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var text in __instance.nameText) + { + text.text = plantName; + text.font = fontAsset; + } + + foreach (var text in __instance.infoText) + { + var toTranslate = text.text; + var startColorTag = ""; + + const string ColorPattern = "(]+>)(.*?)()"; + var match = Regex.Match(toTranslate, ColorPattern); + + if (match.Success) + { + startColorTag = match.Groups[1].Value; + toTranslate = match.Groups[2].Value; + } + + var parts = toTranslate.Split("\n"); + var translatedParts = parts.Select(part => StringStore.TranslateText(part)).ToList(); + + var joinedTranslation = string.Join("\n", translatedParts); + + if (startColorTag != "") + text.text = startColorTag + joinedTranslation + ""; + else + text.text = joinedTranslation; + + text.font = fontAsset; + } + + foreach (var text in __instance.toggles.transform.Find("Viewport/Content/Toggles") + .GetComponentsInChildren()) + text.text = StringStore.TranslateText(text.text); + } +} diff --git a/Source/Patches/GameObjects/PlantInfoWindow_Patch.cs b/Source/Patches/GameObjects/PlantInfoWindow_Patch.cs new file mode 100644 index 0000000..ce93672 --- /dev/null +++ b/Source/Patches/GameObjects/PlantInfoWindow_Patch.cs @@ -0,0 +1,43 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(PlantInfoWindow))] +public static class PlantInfoWindow_Patch +{ + [HarmonyPatch(nameof(PlantInfoWindow.InitText)), HarmonyPostfix] + private static void InitText(PlantInfoWindow __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + var thePlant = __instance.plant; + + foreach (var txt in __instance.GetComponentsInChildren()) + { + if (txt.name.Contains("Introduce") && thePlant != null) + { + var thePlantType = thePlant.thePlantType; + txt.text = StringStore.TranslateText(txt.text); + + var text = txt.text; + var lines = text.Split("\n"); + + lines[0] = Utils.GetPlantNameFromAlmanac(thePlantType); + var updatedText = string.Join("\n", lines); + + txt.text = updatedText; + } + else + txt.text = StringStore.TranslateText(txt.text); + + txt.font = fontAsset; + } + + var parentWindowTransform = __instance.transform.parent; + var returnPlantTransform = parentWindowTransform.FindChild("Close"); + + foreach (var txt in returnPlantTransform.GetComponentsInChildren()) + txt.text = StringStore.TranslateText("合上"); + } +} diff --git a/Source/Patches/GameObjects/PlayerSaveMenu_Patch.cs b/Source/Patches/GameObjects/PlayerSaveMenu_Patch.cs new file mode 100644 index 0000000..a16af80 --- /dev/null +++ b/Source/Patches/GameObjects/PlayerSaveMenu_Patch.cs @@ -0,0 +1,22 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(PlayerSaveMenu))] +public static class PlayerSaveMenu_Patch +{ + [HarmonyPatch(nameof(PlayerSaveMenu.CreatePlayerData)), HarmonyPostfix] + public static void CreatePlayerData(PlayerSaveMenu __instance) => TranslateCreatePlayerSaveMenu(); + + [HarmonyPatch(nameof(PlayerSaveMenu.ResetName)), HarmonyPostfix] + public static void ResetName(PlayerSaveMenu __instance) => TranslateCreatePlayerSaveMenu(); + + public static void TranslateCreatePlayerSaveMenu() + { + var reNameMenuTransform = GameAPP.canvasUp.Find("ReNameMenu(Clone)"); + + if (reNameMenuTransform.TryGetComponent(out var reNameMenu)) + reNameMenu.title.text = StringStore.TranslateText(reNameMenu.title.text); + } +} diff --git a/Source/Patches/GameObjects/PlayerShootingMenu_Patch.cs b/Source/Patches/GameObjects/PlayerShootingMenu_Patch.cs new file mode 100644 index 0000000..bf0bb3e --- /dev/null +++ b/Source/Patches/GameObjects/PlayerShootingMenu_Patch.cs @@ -0,0 +1,35 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(PlayerShootingMenu))] +public static class PlayerShootingMenu_Patch +{ + [HarmonyPatch(nameof(PlayerShootingMenu.Update)), HarmonyPostfix] + private static void Update(PlayerShootingMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + } + + [HarmonyPatch(nameof(PlayerShootingMenu.Refresh)), HarmonyPostfix] + private static void Refresh(PlayerShootingMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + var refreshTransform = __instance.transform.FindChild("Button"); + + foreach (var text in refreshTransform.GetComponentsInChildren()) + { + text.text = StringStore.TranslateText(text.text); + text.font = fontAsset; + text.autoSizeTextContainer = false; + } + } +} diff --git a/Source/Patches/GameObjects/PlayerShootingWindow_Patch.cs b/Source/Patches/GameObjects/PlayerShootingWindow_Patch.cs new file mode 100644 index 0000000..3b7be3f --- /dev/null +++ b/Source/Patches/GameObjects/PlayerShootingWindow_Patch.cs @@ -0,0 +1,30 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(PlayerShootingWindow))] +public static class PlayerShootingWindow_Patch +{ + [HarmonyPatch(nameof(PlayerShootingWindow.SetType)), HarmonyPostfix] + private static void SetType(PlayerShootingWindow __instance) + { + var introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + var introduceText = introduceTransform.GetComponent(); + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } + + [HarmonyPatch(nameof(PlayerShootingWindow.OnAnimOver)), HarmonyPostfix] + private static void OnAnimOver(PlayerShootingWindow __instance) + { + var introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + var introduceText = introduceTransform.GetComponent(); + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } +} diff --git a/Source/Patches/GameObjects/ReNameMenu_Patch.cs b/Source/Patches/GameObjects/ReNameMenu_Patch.cs new file mode 100644 index 0000000..e7c0f86 --- /dev/null +++ b/Source/Patches/GameObjects/ReNameMenu_Patch.cs @@ -0,0 +1,16 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(ReNameMenu))] +public static class ReNameMenu_Patch +{ + [HarmonyPatch(nameof(ReNameMenu.SetTitle)), HarmonyPostfix] + public static void SetTitle(ReNameMenu __instance) => + __instance.title.text = StringStore.TranslateText(__instance.title.text); + + [HarmonyPatch(nameof(ReNameMenu.SetInputText)), HarmonyPostfix] + public static void SetInputText(ReNameMenu __instance) => + __instance.input.text = StringStore.TranslateText(__instance.input.text); +} diff --git a/Source/Patches/GameObjects/RogueCardWindow_Patch.cs b/Source/Patches/GameObjects/RogueCardWindow_Patch.cs new file mode 100644 index 0000000..fe3ed8b --- /dev/null +++ b/Source/Patches/GameObjects/RogueCardWindow_Patch.cs @@ -0,0 +1,30 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(RogueCardWindow))] +public static class RogueCardWindow_Patch +{ + [HarmonyPatch(nameof(RogueCardWindow.InitCard)), HarmonyPostfix] + private static void InitCard(RogueCardWindow __instance) + { + var introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + var introduceText = introduceTransform.GetComponent(); + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } + + [HarmonyPatch(nameof(RogueCardWindow.OnAnimOver)), HarmonyPostfix] + private static void OnAnimOver(RogueCardWindow __instance) + { + var introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + var introduceText = introduceTransform.GetComponent(); + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } +} diff --git a/Source/Patches/GameObjects/RogueStartMenu_Patch.cs b/Source/Patches/GameObjects/RogueStartMenu_Patch.cs new file mode 100644 index 0000000..564c177 --- /dev/null +++ b/Source/Patches/GameObjects/RogueStartMenu_Patch.cs @@ -0,0 +1,32 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(RogueStartMenu))] +public static class RogueStartMenu_Patch +{ + [HarmonyPatch(nameof(RogueStartMenu.SetLeader)), HarmonyPostfix] + private static void SetLeader(RogueStartMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + } + + [HarmonyPatch(nameof(RogueStartMenu.EnterGame)), HarmonyPostfix] + private static void EnterGame(RogueStartMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + } +} diff --git a/Source/Patches/GameObjects/SeedLibrary_Patch.cs b/Source/Patches/GameObjects/SeedLibrary_Patch.cs new file mode 100644 index 0000000..8a8ff13 --- /dev/null +++ b/Source/Patches/GameObjects/SeedLibrary_Patch.cs @@ -0,0 +1,48 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(SeedLibrary))] +public static class SeedLibrary_Patch +{ + [HarmonyPatch(nameof(SeedLibrary.ChangeSafeMode)), HarmonyPostfix] + private static void ChangeSafeMode(SeedLibrary __instance) + { + _ = FontStore.LoadTMPFont(Utils.Language.ToString()); + + //foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) + //{ + // txt.text = StringStore.TranslateText(txt.text); + // txt.font = fontAsset; + //} + + var safetyBoxButtonTransform = __instance.transform.FindChild("SafeBox").FindChild("StartSafeMode"); + + if (__instance.safeMode || safetyBoxButtonTransform == null) + return; + + foreach (var txt in safetyBoxButtonTransform.GetComponentsInChildren()) + txt.text = StringStore.TranslateText("合上"); + } + + [HarmonyPatch(nameof(SeedLibrary.Start)), HarmonyPatch(nameof(SeedLibrary.SetAllCards)), HarmonyPostfix] + private static void SetAllCards(SeedLibrary __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + //foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) + //{ + // txt.text = StringStore.TranslateText(txt.text); + // txt.font = fontAsset; + //} + + foreach (var txt in __instance.page.GetComponentsInChildren(true)) + { + txt.font = fontAsset; + + if (!Utils.CheckForUntranslatedText(txt.text)) + txt.text = StringStore.TranslateText(txt.text); + } + } +} diff --git a/Source/Patches/GameObjects/ShootingMenu_Patch.cs b/Source/Patches/GameObjects/ShootingMenu_Patch.cs new file mode 100644 index 0000000..1f85c77 --- /dev/null +++ b/Source/Patches/GameObjects/ShootingMenu_Patch.cs @@ -0,0 +1,22 @@ +#if false +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(ShootingMenu))] +public static class ShootingMenu_Patch +{ + [HarmonyPatch(nameof(ShootingMenu.Update)), HarmonyPostfix] + private static void Update(ShootingMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (TextMeshProUGUI txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + } +} +#endif diff --git a/Source/Patches/GameObjects/ShootingSelectWindow_Patch.cs b/Source/Patches/GameObjects/ShootingSelectWindow_Patch.cs new file mode 100644 index 0000000..04c919a --- /dev/null +++ b/Source/Patches/GameObjects/ShootingSelectWindow_Patch.cs @@ -0,0 +1,65 @@ +#if false +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(ShootingSelectWindow))] +public static class ShootingSelectWindow_Patch +{ + [HarmonyPatch(nameof(ShootingSelectWindow.InitPlantType)), HarmonyPostfix] + private static void InitCard(ShootingSelectWindow __instance) + { + Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + var introduceText = introduceTransform.GetComponent(); + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } + + [HarmonyPatch(nameof(ShootingSelectWindow.OnAnimOver)), HarmonyPostfix] + private static void OnAnimOver(ShootingSelectWindow __instance) + { + Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + var introduceText = introduceTransform.GetComponent(); + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } + + [HarmonyPatch(nameof(ShootingSelectWindow.SetUpgradePlantTypes)), HarmonyPostfix] + private static void SetUpgradePlantTypes(ShootingSelectWindow __instance) + { + Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + var introduceText = introduceTransform.GetComponent(); + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } + + [HarmonyPatch(nameof(ShootingSelectWindow.GetMaxIndexInRoutes)), HarmonyPostfix] + private static void GetMaxIndexInRoutes(ShootingSelectWindow __instance) + { + Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + var introduceText = introduceTransform.GetComponent(); + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } + + [HarmonyPatch(nameof(ShootingSelectWindow.Start)), HarmonyPostfix] + private static void Start(ShootingSelectWindow __instance) + { + Transform introduceTransform = __instance.transform.FindChild("Images").FindChild("Introduce"); + var introduceText = introduceTransform.GetComponent(); + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + introduceText.text = StringStore.TranslateText(introduceText.text); + introduceText.font = fontAsset; + } +} +#endif diff --git a/Source/Patches/GameObjects/SpriteRenderer_Patch.cs b/Source/Patches/GameObjects/SpriteRenderer_Patch.cs new file mode 100644 index 0000000..d2e35d9 --- /dev/null +++ b/Source/Patches/GameObjects/SpriteRenderer_Patch.cs @@ -0,0 +1,18 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(SpriteRenderer))] +public static class SpriteRenderer_Patch +{ + [HarmonyPatch(nameof(SpriteRenderer.InvokeSpriteChanged)), HarmonyPostfix] + private static void InvokeSpriteChanged(SpriteRenderer __instance) + { + if (__instance.sprite == null) + return; + + if (TextureStore.SpriteDict.ContainsKey(__instance.sprite.name) && __instance.drawMode != SpriteDrawMode.Sliced) + __instance.drawMode = SpriteDrawMode.Sliced; + } +} diff --git a/Source/Patches/GameObjects/TowerOption_Patch.cs b/Source/Patches/GameObjects/TowerOption_Patch.cs new file mode 100644 index 0000000..6277c0b --- /dev/null +++ b/Source/Patches/GameObjects/TowerOption_Patch.cs @@ -0,0 +1,18 @@ +#if false +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(TowerOption))] +public static class TowerOption_Patch +{ + [HarmonyPatch(nameof(TowerOption.Start)), HarmonyPostfix] + private static void Postfix_Start(TowerOption __instance) + { + //TextMeshProUGUI[] allTexts = __instance.GetComponentsInChildren(true); + __instance.introduce.text = StringStore.TranslateText(__instance.introduce.text); + __instance.introduce.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } +} +#endif diff --git a/Source/Patches/GameObjects/TowerUpgradeMenu_Patch.cs b/Source/Patches/GameObjects/TowerUpgradeMenu_Patch.cs new file mode 100644 index 0000000..ee77a93 --- /dev/null +++ b/Source/Patches/GameObjects/TowerUpgradeMenu_Patch.cs @@ -0,0 +1,34 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(TowerUpgradeMenu))] +public static class TowerUpgradeMenu_Patch +{ + [HarmonyPatch(nameof(TowerUpgradeMenu.Awake)), HarmonyPostfix] + private static void Awake(TowerUpgradeMenu __instance) + { + __instance.des.text = StringStore.TranslateText(__instance.des.text); + __instance.des2.text = StringStore.TranslateText(__instance.des2.text); + + foreach (var text in __instance.GetComponentsInChildren()) + { + text.text = StringStore.TranslateText(text.text); + text.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + } + + [HarmonyPatch(nameof(TowerUpgradeMenu.SetText)), HarmonyPostfix] + private static void SetText(TowerUpgradeMenu __instance) + { + __instance.des.text = StringStore.TranslateText(__instance.des.text); + __instance.des2.text = StringStore.TranslateText(__instance.des2.text); + + foreach (var text in __instance.GetComponentsInChildren()) + { + text.text = StringStore.TranslateText(text.text); + text.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + } +} diff --git a/Source/Patches/GameObjects/UIDifficulty_Patch.cs b/Source/Patches/GameObjects/UIDifficulty_Patch.cs new file mode 100644 index 0000000..fafb786 --- /dev/null +++ b/Source/Patches/GameObjects/UIDifficulty_Patch.cs @@ -0,0 +1,17 @@ +using HarmonyLib; +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 (!Utils.CheckForUntranslatedText(__instance.t.text)) + return; + + __instance.t.text = StringStore.TranslateText(__instance.t.text); + } +} diff --git a/Source/Patches/GameObjects/UIZombieNum_Patch.cs b/Source/Patches/GameObjects/UIZombieNum_Patch.cs new file mode 100644 index 0000000..cebf27a --- /dev/null +++ b/Source/Patches/GameObjects/UIZombieNum_Patch.cs @@ -0,0 +1,31 @@ +using HarmonyLib; +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) + { + TMP_FontAsset fontAsset; + + if (ModFeatures.IsMultiLanguage) + { + fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + __instance.t.text = StringStore.TranslateText(__instance.t.text); + } + else + { + fontAsset = FontStore.LoadTMPFont(); + + __instance.t.text = string.Format( + StringStore.PatchesStore["Zombies"]["Spanish"] + " {0}", + Board.Instance.enermyCount + ); + } + + __instance.t.font = fontAsset; + } +} diff --git a/Source/Patches/GameObjects/WarningMenu_Patch.cs b/Source/Patches/GameObjects/WarningMenu_Patch.cs new file mode 100644 index 0000000..531158b --- /dev/null +++ b/Source/Patches/GameObjects/WarningMenu_Patch.cs @@ -0,0 +1,77 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.GameObjects; + +[HarmonyPatch(typeof(WarningMenu))] +public static class WarningMenu_Patch +{ + [HarmonyPatch(nameof(WarningMenu.Start)), HarmonyPostfix] + private static void Start(WarningMenu __instance) => TranslateInvestmentWarning(__instance); + + [HarmonyPatch(nameof(WarningMenu.EnableChallengeMode)), HarmonyPostfix] + private static void EnableChallengeMode(WarningMenu __instance) => TranslateInvestmentWarning(__instance); + + [HarmonyPatch(nameof(WarningMenu.Cancel)), HarmonyPostfix] + private static void Cancel(WarningMenu __instance) => TranslateInvestmentWarning(__instance); + + public static void TranslateInvestmentWarning(WarningMenu __instance) + { + var normalModeTransform = __instance.transform.Find("Normal"); + var challengeModeTransform = __instance.transform.Find("Challenge"); + + if (normalModeTransform != null) + { + var text = normalModeTransform.Find("text").GetComponent(); + var textShadow = normalModeTransform.Find("text (1)").GetComponent(); + + text.text = StringStore.TranslationString.ContainsKey("普通模式_IV") + ? StringStore.TranslateText("普通模式_IV") + : Utils.RemoveColorTags(StringStore.TranslateText(text.text)); + + text.alignment = TextAlignmentOptions.Center; + text.autoSizeTextContainer = true; + textShadow.text = Utils.RemoveColorTags(text.text); + textShadow.alignment = TextAlignmentOptions.Center; + textShadow.autoSizeTextContainer = true; + } + + if (challengeModeTransform != null) + { + var text = challengeModeTransform.Find("text").GetComponent(); + var textShadow = challengeModeTransform.Find("text (1)").GetComponent(); + + text.text = StringStore.TranslationString.ContainsKey("诅咒模式_IV") + ? StringStore.TranslateText("诅咒模式_IV") + : Utils.RemoveColorTags(StringStore.TranslateText(text.text)); + + text.alignment = TextAlignmentOptions.Center; + text.autoSizeTextContainer = true; + textShadow.text = Utils.RemoveColorTags(text.text); + textShadow.alignment = TextAlignmentOptions.Center; + textShadow.autoSizeTextContainer = true; + } + + if (__instance.tutor != null) + foreach (var text in __instance.tutor.GetComponentsInChildren() + .Where(text => text.gameObject.name == "text1")) + { + text.text = StringStore.TranslateText(text.text); + + if (text.transform.parent.Find("text").TryGetComponent(out var textShadow)) + textShadow.text = Utils.RemoveColorTags(text.text); + } + + if (__instance.challenge == null) + return; + + foreach (var text in __instance.challenge.GetComponentsInChildren() + .Where(text => text.gameObject.name == "text1")) + { + text.text = StringStore.TranslateText(text.text); + + if (text.transform.parent.Find("text").TryGetComponent(out var textShadow)) + textShadow.text = Utils.RemoveColorTags(text.text); + } + } +} diff --git a/Source/Patches/Managers/AbyssDevelopMenu_Patch.cs b/Source/Patches/Managers/AbyssDevelopMenu_Patch.cs new file mode 100644 index 0000000..59f55d7 --- /dev/null +++ b/Source/Patches/Managers/AbyssDevelopMenu_Patch.cs @@ -0,0 +1,17 @@ +#if false +using HarmonyLib; +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); + } +} +#endif diff --git a/Source/Patches/Managers/AbyssMenu2_Patch.cs b/Source/Patches/Managers/AbyssMenu2_Patch.cs new file mode 100644 index 0000000..7c9f617 --- /dev/null +++ b/Source/Patches/Managers/AbyssMenu2_Patch.cs @@ -0,0 +1,86 @@ +#if false +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +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) + { + var 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) + { + var 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); + } +} +#endif diff --git a/Source/Patches/Managers/AbyssMenu_Patch.cs b/Source/Patches/Managers/AbyssMenu_Patch.cs new file mode 100644 index 0000000..9ee9d8c --- /dev/null +++ b/Source/Patches/Managers/AbyssMenu_Patch.cs @@ -0,0 +1,22 @@ +#if false +using HarmonyLib; +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) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.rukous) + { + txt.text = StringStore.TranslateText(txt.text, false); + txt.font = fontAsset; + } + } +} +#endif diff --git a/Source/Patches/Managers/AlmanacMgrZombie_Patch.cs b/Source/Patches/Managers/AlmanacMgrZombie_Patch.cs new file mode 100644 index 0000000..02f472a --- /dev/null +++ b/Source/Patches/Managers/AlmanacMgrZombie_Patch.cs @@ -0,0 +1,95 @@ +#if false +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; +using static PvZ_Fusion_Translator.FileLoader; + +namespace PvZ_Fusion_Translator.Patches.Managers; + +[HarmonyPatch(typeof(AlmanacMgrZombie))] +public static partial class AlmanacMgrZombie_Patch +{ + [HarmonyPatch(nameof(AlmanacMgrZombie.InitNameAndInfoFromJson)), HarmonyPostfix] + private static void InitNameAndInfoFromJson(AlmanacMgrZombie __instance) + { + var (almanacDir, currentLanguage) = ModFeatures.IsMultiLanguage + ? (GetAssetDir(AssetType.Almanac, Utils.Language), Utils.Language.ToString()) + : (GetAssetDir(AssetType.Almanac), "English"); + + var path = Path.Combine(almanacDir, "ZombieStringsTranslate.json"); + var moddedPath = Path.Combine(almanacDir, "ModdedZombiesTranslate.json"); + + if (!File.Exists(path)) + { + Log.LogError($"ZombieStringsTranslate.json file not found at path: {path}"); + return; + } + + var json = File.ReadAllText(path); + var hasAlmanacFont = false; + TMP_FontAsset almanacFontAsset = null; + + if (FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage + "_Almanac") || + FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage)) + { + almanacFontAsset = FontStore.LoadTMPFontAlmanac(currentLanguage); + hasAlmanacFont = true; + } + + FontStore.LoadTMPFont(ModFeatures.IsMultiLanguage ? Utils.Language.ToString() : null); + TextMeshPro component = __instance.info.GetComponent(); + TextMeshPro component2 = __instance.zombieName.GetComponent(); + TextMeshPro component3 = __instance.zombieName.transform.GetChild(0).GetComponent(); + + var zombieData = JsonUtility.FromJson(json); + + foreach (ZombieInfo zombieInfo in zombieData.zombies) + if (zombieInfo.theZombieType == __instance.theZombieType) + { + component.text = zombieInfo.info + "\n\n" + zombieInfo.introduce; + component.overflowMode = TextOverflowModes.Page; + component2.text = zombieInfo.name; + component2.autoSizeTextContainer = true; + component3.text = Utils.RemoveColorTags(zombieInfo.name); + component3.autoSizeTextContainer = true; + component.font = hasAlmanacFont ? almanacFontAsset : fontAsset; + component2.font = fontAsset; + component3.font = fontAsset; + } + + if (!File.Exists(moddedPath)) + return; + + var moddedJson = File.ReadAllText(moddedPath); + + var moddedZombieData = JsonUtility.FromJson(moddedJson); + + foreach (ZombieInfo zombieInfo in moddedZombieData.zombies) + if (zombieInfo.theZombieType == __instance.theZombieType) + { + component.text = zombieInfo.info + "\n\n" + zombieInfo.introduce; + component.overflowMode = TextOverflowModes.Page; + component2.text = zombieInfo.name; + component2.autoSizeTextContainer = true; + component3.text = Utils.RemoveColorTags(zombieInfo.name); + component3.autoSizeTextContainer = true; + component.font = hasAlmanacFont ? almanacFontAsset : fontAsset; + component2.font = fontAsset; + component3.font = fontAsset; + } + } + + [HarmonyPatch(nameof(AlmanacMgrZombie.OnMouseDown)), HarmonyPrefix] + private static bool OnMouseDown(AlmanacMgrZombie __instance) + { + TextMeshPro component = __instance.info.GetComponent(); + + if (component == null) + return true; + + component.pageToDisplay = + component.pageToDisplay > component.m_pageNumber ? 1 : component.pageToDisplay + 1; + + return false; + } +} +#endif diff --git a/Source/Patches/Managers/AlmanacPlantBank_Patch.cs b/Source/Patches/Managers/AlmanacPlantBank_Patch.cs new file mode 100644 index 0000000..023dc57 --- /dev/null +++ b/Source/Patches/Managers/AlmanacPlantBank_Patch.cs @@ -0,0 +1,191 @@ +#if false +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; +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)), HarmonyPostfix] + private static void InitNameAndInfoFromJson(Il2Cpp.AlmanacPlantBank __instance) + { + var (almanacDir, currentLanguage) = ModFeatures.IsMultiLanguage + ? (GetAssetDir(AssetType.Almanac, Utils.Language), Utils.Language.ToString()) + : (GetAssetDir(AssetType.Almanac), "English"); + + var path = Path.Combine(almanacDir, "LawnStringsTranslate.json"); + var moddedPath = Path.Combine(almanacDir, "ModdedPlantsTranslate.json"); + + if (!File.Exists(path)) + { + Log.LogError($"LawnStringsTranslate.json file not found at path: {path}"); + return; + } + + var json = File.ReadAllText(path); + var hasAlmanacFont = false; + TMP_FontAsset almanacFontAsset = null; + + if (FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage + "_Almanac") || + FontStore.fontAssetDictSecondary.ContainsKey(currentLanguage)) + { + almanacFontAsset = FontStore.LoadTMPFontAlmanac(currentLanguage); + hasAlmanacFont = true; + } + + var fontAsset = ModFeatures.IsMultiLanguage + ? FontStore.LoadTMPFont(Utils.Language.ToString()) + : FontStore.LoadTMPFont(); + + TextMeshPro component = __instance.introduce.GetComponent(); + TextMeshPro component2 = __instance.plantName.GetComponent(); + TextMeshPro component3 = __instance.plantName.transform.GetChild(0).GetComponent(); + TextMeshPro component4 = __instance.cost.GetComponent(); + + AlmanacPlantBank.PlantData plantData = JsonUtility.FromJson(json); + + foreach (var plantInfo in plantData.plants) + { + if (plantInfo.seedType != __instance.theSeedType || string.IsNullOrEmpty(plantInfo.name)) + continue; + + component.autoSizeTextContainer = false; + component.text = plantInfo.info + "\n\n" + plantInfo.introduce; + component.overflowMode = TextOverflowModes.Page; + + // fix dimensions for cost text + component.rectTransform.offsetMax = new(component.rectTransform.offsetMax.x, 27.3839f); + component.rectTransform.offsetMin = new(component.rectTransform.offsetMin.x, -29.3079f); + component.rectTransform.sizeDelta = new(component.rectTransform.sizeDelta.x, 50.917f); + + component.transform.localPosition = new( + component.transform.localPosition.x, + component.transform.localPosition.y + 0.15f, + component.transform.localPosition.z + ); + + component2.text = plantInfo.name; + component2.autoSizeTextContainer = true; + + component3.text = Utils.RemoveColorTags(plantInfo.name ?? string.Empty); + component3.autoSizeTextContainer = true; + + component4.text = plantInfo.cost; + + if (hasAlmanacFont) + { + component.font = almanacFontAsset; + component4.font = almanacFontAsset; + } + else + { + component.font = fontAsset; + component4.font = fontAsset; + } + + component2.font = fontAsset; + component3.font = fontAsset; + } + + if (!File.Exists(moddedPath)) + return; + + var moddedJson = File.ReadAllText(moddedPath); + AlmanacPlantBank.PlantData moddedPlantData = JsonUtility.FromJson(moddedJson); + + foreach (AlmanacPlantBank.PlantInfo plantInfo in moddedPlantData.plants) + { + if (plantInfo.seedType != __instance.theSeedType || string.IsNullOrEmpty(plantInfo.name)) + continue; + + component.autoSizeTextContainer = false; + component.text = plantInfo.info + "\n\n" + plantInfo.introduce; + component.overflowMode = TextOverflowModes.Page; + + // fix dimensions for cost text + component.rectTransform.offsetMax = new(component.rectTransform.offsetMax.x, 27.3839f); + component.rectTransform.offsetMin = new(component.rectTransform.offsetMin.x, -29.3079f); + component.rectTransform.sizeDelta = new(component.rectTransform.sizeDelta.x, 50.917f); + + component.transform.localPosition = new( + component.transform.localPosition.x, + component.transform.localPosition.y + 0.15f, + component.transform.localPosition.z + ); + + component2.text = plantInfo.name; + component2.autoSizeTextContainer = true; + + component3.text = Utils.RemoveColorTags(plantInfo.name ?? string.Empty); + 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; + } + } + + [HarmonyPatch(nameof(AlmanacPlantBank.OnMouseDown)), HarmonyPrefix] + private static bool OnMouseDown(AlmanacPlantBank __instance) + { + TextMeshPro component = __instance.introduce.GetComponent(); + + if (component == null) + return true; + + component.pageToDisplay = + component.pageToDisplay > component.m_pageNumber ? 1 : component.pageToDisplay + 1; + + return false; + } + + [HarmonyPatch(nameof(AlmanacPlantBank.PVPInit)), HarmonyPostfix] // ReSharper disable once InconsistentNaming + private static void PVPInit(Il2Cpp.AlmanacPlantBank __instance) + { + TextMeshPro component = __instance.introduce.GetComponent(); + + if (component != null) + component.autoSizeTextContainer = false; + + Transform banTransform = __instance.transform.FindChild("Ban").GetChild(0); + + if (banTransform != null) + banTransform.GetComponent().text = + StringStore.TranslateText(banTransform.GetComponent().text); + } + + [HarmonyPatch(nameof(AlmanacPlantBank.Start)), HarmonyPostfix] + public static void Post_Start(AlmanacPlantBank __instance) + { + GameObject skinTextObj = __instance.skinButton.transform.GetChild(0).gameObject; + + var skinShadowTextObj = + UnityEngine.Object.Instantiate(skinTextObj, parent: __instance.skinButton.transform); + + var skinShadowText = skinShadowTextObj.GetComponent(); + skinShadowText.text = StringStore.TranslateText("换肤_S"); + skinShadowText.sortingOrder -= 2; + skinShadowTextObj.transform.Translate(new(0.015f, -0.015f, 0)); + skinTextObj.transform.Translate(new(-0.022f, 0)); + skinShadowTextObj.transform.Translate(new(-0.022f, 0)); + __instance.skinButton.transform.localScale /= 1.75f; + __instance.skinButton.transform.Translate(new Vector3(-0.075f, -0.15f, 0)); + __instance.skinButton.transform.GetChild(1).Translate(new Vector3(0.35f, 0)); + __instance.skinButton.transform.GetChild(2).Translate(new Vector3(-0.35f, 0)); + } +} +#endif diff --git a/Source/Patches/Managers/CanvasUpUI_Patch.cs b/Source/Patches/Managers/CanvasUpUI_Patch.cs new file mode 100644 index 0000000..bcb963c --- /dev/null +++ b/Source/Patches/Managers/CanvasUpUI_Patch.cs @@ -0,0 +1,30 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Managers; + +[HarmonyPatch(typeof(CanvasUpUI))] +public static class CanvasUpUI_Patch +{ + [HarmonyPatch(nameof(CanvasUpUI.Start)), HarmonyPostfix] + public static void Start(CanvasUpUI __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var text in __instance.GetComponentsInChildren()) + { + var originalKey = StringStore.TranslationString + .FirstOrDefault(x => x.Value == text.text || x.Value.Replace("\n", "") == text.text) + .Key; + + text.text = StringStore.TranslationString.ContainsKey(originalKey + "_MG") + ? StringStore.TranslateText(originalKey + "_MG") + : StringStore.TranslateText(text.text); + + if (text.gameObject.name.Contains("LevelName")) + text.text = text.text.Replace("\n", " "); + + text.font = fontAsset; + } + } +} diff --git a/Source/Patches/Managers/ChessManager_Patch.cs b/Source/Patches/Managers/ChessManager_Patch.cs new file mode 100644 index 0000000..2afda22 --- /dev/null +++ b/Source/Patches/Managers/ChessManager_Patch.cs @@ -0,0 +1,29 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Managers; + +[HarmonyPatch(typeof(ChessManager))] +public static class ChessManager_Patch +{ + [HarmonyPatch(nameof(ChessManager.Start)), HarmonyPostfix] + private static void Postfix_Start(ChessManager __instance) + { + __instance.textMesh.text = StringStore.TranslateText(__instance.textMesh.text); + __instance.textMesh.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + + [HarmonyPatch(nameof(ChessManager.Update)), HarmonyPostfix] + private static void Postfix_Update(ChessManager __instance) + { + __instance.textMesh.text = StringStore.TranslateText(__instance.textMesh.text); + __instance.textMesh.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + + [HarmonyPatch(nameof(ChessManager.UpdateText)), HarmonyPostfix] + private static void Postfix_UpdateText(ChessManager __instance) + { + __instance.textMesh.text = StringStore.TranslateText(__instance.textMesh.text); + __instance.textMesh.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } +} diff --git a/Source/Patches/Managers/CustomLevelShower_Patch.cs b/Source/Patches/Managers/CustomLevelShower_Patch.cs new file mode 100644 index 0000000..f611346 --- /dev/null +++ b/Source/Patches/Managers/CustomLevelShower_Patch.cs @@ -0,0 +1,17 @@ +#if false +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +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 (var transform in __instance.pages) + StringStore.TranslateTextTransform(transform); + } +} +#endif diff --git a/Source/Patches/Managers/DifficultyMgr_Patch.cs b/Source/Patches/Managers/DifficultyMgr_Patch.cs new file mode 100644 index 0000000..e2f2a15 --- /dev/null +++ b/Source/Patches/Managers/DifficultyMgr_Patch.cs @@ -0,0 +1,15 @@ +using HarmonyLib; +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/Source/Patches/Managers/DrawCardManager_Patch.cs b/Source/Patches/Managers/DrawCardManager_Patch.cs new file mode 100644 index 0000000..bb2f5a5 --- /dev/null +++ b/Source/Patches/Managers/DrawCardManager_Patch.cs @@ -0,0 +1,64 @@ +using System.Text.RegularExpressions; +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Managers; + +[HarmonyPatch(typeof(DrawCardManager))] +public static class DrawCardManager_Patch +{ +#pragma warning disable CA2211 + public static TMP_FontAsset FontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); +#pragma warning restore CA2211 + [HarmonyPatch(nameof(DrawCardManager.Awake)), HarmonyPostfix] + private static void Awake(DrawCardManager __instance) => + FontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + [HarmonyPatch(nameof(DrawCardManager.UpdateText)), HarmonyPostfix] + private static void Postfix_UpdateText(DrawCardManager __instance) + { + var regexPair = new KeyValuePair( + "抽取次数:\n(\\d+)/(\\d+)\n当前up植物:\n([^\\s]+)\nup刷新倒计时:\n(\\d+)", + "Draw Count:\n{0}/{1}\nCurrent Up:\n{2}\nNext Up in: \n{3}s" + ); + + foreach (var txt in __instance.texts) + if (Regex.IsMatch(txt.text, regexPair.Key)) + { + txt.text = TranslateGashaponText(txt.text, regexPair.Key, regexPair.Value, __instance.up); + txt.font = FontAsset; + } + } + + public static string TranslateGashaponText(string originalText, string pattern, string fallback, PlantType up) + { + var res = ""; + var match = Regex.Match(originalText, pattern); + + if (!match.Success) + return res; + + var groups = match.Groups; + var fStr = StringStore.TranslationStringRegex.GetValueOrDefault(pattern, fallback); + List dynamicParts = []; + + for (var i = 1; i < groups.Count; i++) + { + var group = groups[i].Value; + + var translatedGroup = i == 3 && up != PlantType.Peashooter + ? Utils.GetPlantNameFromAlmanac(up) + : StringStore.TranslateText(group); + + dynamicParts.Add(translatedGroup); + } + + res = string.Format(fStr, [..dynamicParts]); + + return res; + } +#if false + [HarmonyPatch(nameof(DrawCardManager.Update)), HarmonyPostfix] + private static void Postfix_Update(DrawCardManager __instance) => Postfix_UpdateText(__instance); +#endif +} diff --git a/Source/Patches/Managers/EndlessMgr_Patch.cs b/Source/Patches/Managers/EndlessMgr_Patch.cs new file mode 100644 index 0000000..f58d512 --- /dev/null +++ b/Source/Patches/Managers/EndlessMgr_Patch.cs @@ -0,0 +1,22 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +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) + { + var textTransform = __instance.transform.GetChild(2); + + if (textTransform == null || !textTransform.gameObject.activeSelf) + return; + + var textTMP = textTransform.GetComponent(); + + if (textTMP != null) + StringStore.TranslateText(textTMP); + } +} diff --git a/Source/Patches/Managers/Garden_Patch.cs b/Source/Patches/Managers/Garden_Patch.cs new file mode 100644 index 0000000..25caefd --- /dev/null +++ b/Source/Patches/Managers/Garden_Patch.cs @@ -0,0 +1,18 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Managers; + +[HarmonyPatch(typeof(Garden))] +public static class Garden_Patch +{ + [HarmonyPatch(nameof(Garden.Awake)), HarmonyPostfix] + private static void Awake(Garden __instance) + { + foreach (var text in __instance.GetComponentsInChildren()) + { + text.text = StringStore.TranslateText(text.text); + text.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + } +} diff --git a/Source/Patches/Managers/IZBottomMenu_Patch.cs b/Source/Patches/Managers/IZBottomMenu_Patch.cs new file mode 100644 index 0000000..9a3ba34 --- /dev/null +++ b/Source/Patches/Managers/IZBottomMenu_Patch.cs @@ -0,0 +1,47 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; +using System.Text.RegularExpressions; + +namespace PvZ_Fusion_Translator.Patches.Managers; + +[HarmonyPatch(typeof(IZBottomMenu))] +public static class IZBottomMenu_Patch +{ + [HarmonyPatch(nameof(IZBottomMenu.ChangeString)), HarmonyPostfix] + public static void ChangeStringz(IZBottomMenu __instance) + { + foreach (var text in __instance.levelName) + { + var fStr = StringStore.TranslationStringRegex[@"([^\s]+),推荐难度:(\d+)"]; + var parts = text.text.Split(",推荐难度:"); + + if (new Regex(@"([^\s]+),推荐难度:(\d+)").IsMatch(text.text)) + { + var customName = StringStore.TranslationString.ContainsKey(parts[0] + "_IZ") + ? parts[0] + "_IZ" + : parts[0]; + + text.text = string.Format(fStr, StringStore.TranslateText(customName), parts[1]); + } + + text.text = StringStore.TranslateText(text.text); + text.text = text.text.Replace("\n", " "); + } + } + + [HarmonyPatch(nameof(IZBottomMenu.SetLevelName)), HarmonyPostfix] + public static void SetLevelName(IZBottomMenu __instance) + { + foreach (var text in __instance.levelName) + { + var fStr = StringStore.TranslationStringRegex[@"([^\s]+),推荐难度:(\d+)"]; + var parts = text.text.Split(",推荐难度:"); + + if (new Regex(@"([^\s]+),推荐难度:(\d+)").IsMatch(text.text)) + text.text = string.Format(fStr, StringStore.TranslateText(parts[0]), parts[1]); + + text.text = StringStore.TranslateText(text.text); + text.text = text.text.Replace("\n", " "); + } + } +} diff --git a/Source/Patches/Managers/InGameUI_Patch.cs b/Source/Patches/Managers/InGameUI_Patch.cs new file mode 100644 index 0000000..f5c588a --- /dev/null +++ b/Source/Patches/Managers/InGameUI_Patch.cs @@ -0,0 +1,81 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; +using PvZ_Fusion_Translator.Patches.BaseTextObjects; +using System.Text.RegularExpressions; + +namespace PvZ_Fusion_Translator.Patches.Managers; + +[HarmonyPatch(typeof(InGameUI))] +public static class InGameUI_Patch +{ + public const string TravelAdventurePattern = "^旅行冒险 ([^\\s:]+)"; + public const string TravelAdventureFallback = "Odyssey Adventure: {0}"; + + [HarmonyPatch(nameof(InGameUI.Start)), HarmonyPostfix] + private static void Start(InGameUI __instance) => SetLevelName(__instance); + + [HarmonyPatch(nameof(InGameUI.SetUniqueText)), HarmonyPostfix] + private static void SetUniqueText(InGameUI __instance) => SetLevelName(__instance); + + [HarmonyPatch(nameof(InGameUI.SetLevelName)), HarmonyPostfix] + private static void SetLevelName(InGameUI __instance) + { + foreach (var text in __instance.levelNameText) + { + if (text.text == null) + continue; + + var originalText = text.text; + text.text = text.text.Replace("\n", " "); + + var checkFusionChallenge = new Regex("^超级([^\\s:]+)(:?挑战1?)"); + var checkTravelAdv = new Regex(TravelAdventurePattern); + + if (checkTravelAdv.IsMatch(originalText)) + text.text = InGameText_Patch.TranslatePlantNameParts( + originalText, + TravelAdventurePattern, + TravelAdventureFallback + ); + else if (text.text.Contains("配方:") && !checkFusionChallenge.IsMatch(text.text)) + { + var lines = text.text.Split(":"); + lines[1] = Utils.GetPlantNameFromAlmanac(lines[1]); + + if (lines[1] == "") + { + Log.LogError("Couldn't find plant! (Fusion Showcase)"); + lines[1] = StringStore.TranslateText(lines[1]); + } + + text.text = StringStore.TranslateText("配方:") + lines[1]; + text.autoSizeTextContainer = true; + } + else + { + text.text = StringStore.TranslationString.ContainsKey(text.text + "_MG") + ? StringStore.TranslateText(text.text + "_MG") + : StringStore.TranslateText(text.text); + + text.text = text.text.Replace("\n", " "); + } + } + } +#if false + [HarmonyPatch(nameof(InGameUI.Update)), HarmonyPostfix] + private static void Update(InGameUI __instance) + { + if (!__instance.board.boardTag.isDrawCards) + return; + + KeyValuePair regexPair = new( + "抽取次数:\n(\\d+)/(\\d+)\n当前up植物:\n([^\\s]+)\nup刷新倒计时:\n(\\d+)", + "Draw Count:\n{0}/{1}\nCurrent Up:\n{2}\nNext Up in: \n{3}s" + ); + + foreach (var txt in __instance.DrawCardsHead.GetComponentsInChildren() + .Where(txt => Regex.IsMatch(txt.text, regexPair.Key))) + txt.text = InGameText_Patch.TranslatePlantNameParts(txt.text, regexPair.Key, regexPair.Value); + } +#endif +} diff --git a/Source/Patches/Managers/PVPScareyPot_Patch.cs b/Source/Patches/Managers/PVPScareyPot_Patch.cs new file mode 100644 index 0000000..ea68740 --- /dev/null +++ b/Source/Patches/Managers/PVPScareyPot_Patch.cs @@ -0,0 +1,27 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Managers; + +[HarmonyPatch(typeof(PVPScareyPot))] +public static class PvpScareyPotPatch +{ + [HarmonyPatch(nameof(PVPScareyPot.Awake)), HarmonyPatch(nameof(PVPScareyPot.Start)), + HarmonyPatch(nameof(PVPScareyPot.AutoRuleUpdate)), HarmonyPatch(nameof(PVPScareyPot.RandomCardUpdate)), + HarmonyPatch(nameof(PVPScareyPot.Update)), HarmonyPostfix] + public static void TranslatePlayerDatas(PVPScareyPot __instance) + { + TranslatePlayerData(__instance.player1); + TranslatePlayerData(__instance.player2); + TranslatePlayerData(__instance.currentPlayer); + } + + public static void TranslatePlayerData(PVPScareyPot.PlayerData playerData) + { + if (playerData == null) + return; + + playerData.textMesh.text = StringStore.TranslateText(playerData.textMesh.text); + playerData.textMesh.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } +} diff --git a/Source/Patches/Managers/SaveMenu_Patch.cs b/Source/Patches/Managers/SaveMenu_Patch.cs new file mode 100644 index 0000000..48edc73 --- /dev/null +++ b/Source/Patches/Managers/SaveMenu_Patch.cs @@ -0,0 +1,25 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; +using PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects; + +namespace PvZ_Fusion_Translator.Patches.Managers; + +[HarmonyPatch(typeof(SaveMenu))] +public static class SaveMenu_Patch +{ + [HarmonyPatch(nameof(SaveMenu.Start)), HarmonyPatch(nameof(SaveMenu.CreateLevelEnter)), + HarmonyPatch(nameof(SaveMenu.InitLevelSaveEnters)), HarmonyPostfix] + private static void Start(SaveMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + __instance.menuTitle.text = StringStore.TranslateText(__instance.menuTitle.text); + __instance.menuTitle.font = fontAsset; + + foreach (var enter in __instance.GetComponentsInChildren()) + LevelSaveEnter_Patch.TranslateEnter(enter); + } + + [HarmonyPatch(nameof(SaveMenu.OnEditSelectedButtonClicked)), HarmonyPostfix] + private static void OnEditSelectedButtonClicked(SaveMenu __instance) { } +} diff --git a/Source/Patches/Managers/Screen_Patch.cs b/Source/Patches/Managers/Screen_Patch.cs new file mode 100644 index 0000000..a96d277 --- /dev/null +++ b/Source/Patches/Managers/Screen_Patch.cs @@ -0,0 +1,13 @@ +using HarmonyLib; +using UnityEngine.EventSystems; + +namespace PvZ_Fusion_Translator.Patches.Managers; + +[HarmonyPatch(typeof(Screen))] +public static class Screen_Patch +{ + [HarmonyPatch(nameof(Screen.SetResolution), typeof(int), typeof(int), typeof(bool)), HarmonyPrefix] + private static bool SetResolution(Screen __instance) => + EventSystem.current.currentSelectedGameObject == null || + !EventSystem.current.currentSelectedGameObject.TryGetComponent(out _); +} diff --git a/Source/Patches/Managers/TowerManager_Patch.cs b/Source/Patches/Managers/TowerManager_Patch.cs new file mode 100644 index 0000000..40f5fe1 --- /dev/null +++ b/Source/Patches/Managers/TowerManager_Patch.cs @@ -0,0 +1,18 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Managers; + +[HarmonyPatch(typeof(TowerManager))] +public static class TowerManager_Patch +{ + public static readonly List UpdatedText = []; + + public static void UpdateText() + { + foreach (var transform in UpdatedText.Where(transform => transform != null) + .Where(transform => transform.gameObject.active)) + transform.GetComponent().text = + StringStore.TranslateText(transform.GetComponent().text); + } +} diff --git a/Source/Patches/Managers/UIMgr_Patch.cs b/Source/Patches/Managers/UIMgr_Patch.cs new file mode 100644 index 0000000..c8308f2 --- /dev/null +++ b/Source/Patches/Managers/UIMgr_Patch.cs @@ -0,0 +1,16 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; +using Object = UnityEngine.Object; + +namespace PvZ_Fusion_Translator.Patches.Managers; + +[HarmonyPatch(typeof(UIMgr))] +public class UIMgr_Patch +{ + [HarmonyPatch(nameof(UIMgr.EnterLoseMenu)), HarmonyPostfix] + private static void EnterLoseMenu(UIMgr __instance) + { + var loseMenu = Object.FindObjectOfType(); + loseMenu.title.text = StringStore.TranslateText(loseMenu.title.text); + } +} diff --git a/Source/Patches/Modes/Abyss/AbyssBagMenu_Patch.cs b/Source/Patches/Modes/Abyss/AbyssBagMenu_Patch.cs new file mode 100644 index 0000000..007d42c --- /dev/null +++ b/Source/Patches/Modes/Abyss/AbyssBagMenu_Patch.cs @@ -0,0 +1,24 @@ +#if false +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Abyss; + +[HarmonyPatch(typeof(AbyssBagMenu))] +public static class AbyssBagMenu_Patch +{ + [HarmonyPatch(nameof(AbyssBagMenu.Awake)), HarmonyPostfix] + private static void Awake_Post(AbyssCheckInBag __instance) + { + foreach (TextMeshProUGUI text in __instance.transform.FindChild("Background") + .GetComponentsInChildren()) + { + text.text += "_深渊"; + text.text = StringStore.TranslateText("背包_深渊"); + text.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + + AbyssMenu2.Instance.UpdateIcons(); + } +} +#endif diff --git a/Source/Patches/Modes/Abyss/AbyssBuffButton_Patch.cs b/Source/Patches/Modes/Abyss/AbyssBuffButton_Patch.cs new file mode 100644 index 0000000..f6681a5 --- /dev/null +++ b/Source/Patches/Modes/Abyss/AbyssBuffButton_Patch.cs @@ -0,0 +1,55 @@ +#if false +using System.Text.RegularExpressions; +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Abyss; + +[HarmonyPatch(typeof(AbyssBuffButton))] +public static class AbyssBuffButton_Patch +{ + [HarmonyPatch(nameof(AbyssBuffButton.SetType)), HarmonyPostfix] + private static void SetType(AbyssBuffButton __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + var regex = new Regex("([^\\s]+)\n价格:(\\d+)"); + + if (!regex.IsMatch(__instance.description.text)) + return; + + var match = regex.Match(__instance.description.text); + var groupCount = match.Groups.Count; + + List dynamicParts = []; + + for (var i = 1; i < groupCount; i++) + { + var groupValue = match.Groups[i].Value; + + var translatedValue = StringStore.translationString.ContainsKey(groupValue) + ? StringStore.translationString[groupValue] + : groupValue; + + dynamicParts.Add(translatedValue); + MelonLogger.Msg(translatedValue); + } + + __instance.description.text = string.Format( + StringStore.translationStringRegex["([^\\s]+)\n价格:(\\d+)"], + [..dynamicParts] + ); + + __instance.description.font = fontAsset; + } + + [HarmonyPatch(nameof(AbyssBuffButton.SetSold)), HarmonyPostfix] + private static void SetSold(AbyssBuffButton __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + __instance.description.text = StringStore.TranslateText(__instance.description.text); + __instance.description.font = fontAsset; + } +} +#endif diff --git a/Source/Patches/Modes/Abyss/AbyssBuffData_Patch.cs b/Source/Patches/Modes/Abyss/AbyssBuffData_Patch.cs new file mode 100644 index 0000000..deceaa0 --- /dev/null +++ b/Source/Patches/Modes/Abyss/AbyssBuffData_Patch.cs @@ -0,0 +1,127 @@ +#if false +using System.Text.Json; +using HarmonyLib; + +namespace PvZ_Fusion_Translator.Patches.Modes.Abyss; + +[HarmonyPatch(typeof(AbyssBuffData))] +public static class AbyssBuffData_Patch +{ + [HarmonyPatch(nameof(AbyssBuffData.LoadData)), HarmonyPostfix] + public static void Pre_LoadData(AbyssBuffData __instance) + { + // ReSharper disable once Unity.UnknownResource + var originalAbyssBuffStr = Resources.Load("AbyssBuffData").text; + + Dictionary> originalAbyssBuffData = + JsonSerializer.Deserialize>>(originalAbyssBuffStr); + + List infos = originalAbyssBuffData["infos"]; + + Il2CppSystem.Collections.Generic.Dictionary> result = + new(); + + var abyssBuffDataDir = Path.Combine( + FileLoader.GetAssetDir(FileLoader.AssetType.Strings, Utils.Language), + "abyss_buffs.json" + ); + + if (!File.Exists(abyssBuffDataDir)) + File.WriteAllText(abyssBuffDataDir, originalAbyssBuffStr); + + var abyssBuffData = JsonSerializer.Deserialize>(File.ReadAllText(abyssBuffDataDir)); + + foreach (AbyssBuffInfo originalTuple in infos) + { + Il2CppSystem.ValueTuple translatedTuple = new() + { + Item1 = abyssBuffData.TryGetValue(originalTuple.name, out var item1) + ? item1 + : originalTuple.name, + Item2 = abyssBuffData.TryGetValue(originalTuple.introduce, out var item2) + ? item2 + : originalTuple.introduce, + Item3 = originalTuple.value, + }; + + foreach (var x in AbyssBuffData.buffDatas) + if (x.Value.Item1 == originalTuple.name) + { + AbyssBuffData.buffDatas[x.Key] = translatedTuple; + break; + } + } + } +} + +// ReSharper disable InconsistentNaming +public enum AbyssBuffClone +{ + 生存_聚塑, + 生存_启命, + 生存_坚定, + 生存_弥合, + 生存_警戒, + 生存_霸体, + 生存_共存, + 生存_护盾, + 生存_治疗, + 生存_主宰, + 寒冰_聚塑, + 寒冰_刺骨, + 寒冰_凛风, + 寒冰_冻结, + 寒冰_保护, + 寒冰_折磨, + 寒冰_扩散, + 寒冰_凝神, + 寒冰_破冰, + 寒冰_永冻, + 魅惑_聚塑, + 魅惑_感应, + 魅惑_催眠, + 魅惑_无畏, + 魅惑_脆弱, + 魅惑_黑曜, + 魅惑_转世, + 魅惑_支援, + 魅惑_沉重, + 魅惑_共鸣, + 烈焰_聚塑, + 烈焰_爆破, + 烈焰_怒火, + 烈焰_红唇, + 烈焰_融化, + 烈焰_燃烧, + 烈焰_浴火, + 烈焰_鬼火, + 烈焰_诅咒, + 烈焰_太阳, + 通用_断水, + 通用_千斤, + 通用_急迫, + 通用_折扣, + 通用_密植, + 通用_超级, + 通用_究极, + 通用_极速, + 通用_强力, + 通用_专注, + 通用_迸发, + 通用_投资, + 通用_机遇, + 通用_命运, + 通用_时停, + 通用_升级, + 蒜毒_聚塑, + 蒜毒_腐蚀, + 蒜毒_侵蚀, + 蒜毒_血清, + 蒜毒_混乱, + 蒜毒_虚弱, + 蒜毒_反胃, + 蒜毒_虫噬, + 蒜毒_百毒, + 蒜毒_爆裂, +} +#endif diff --git a/Source/Patches/Modes/Abyss/AbyssBuffMenu_Patch.cs b/Source/Patches/Modes/Abyss/AbyssBuffMenu_Patch.cs new file mode 100644 index 0000000..2036d3d --- /dev/null +++ b/Source/Patches/Modes/Abyss/AbyssBuffMenu_Patch.cs @@ -0,0 +1,111 @@ +#if false +using System.Text.Json; +using System.Text.RegularExpressions; +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Abyss; + +[HarmonyPatch(typeof(AbyssBuffMenu))] +public static class AbyssBuffMenu_Patch +{ +#pragma warning disable CA2211 + public static Dictionary AbyssBuffData = new(); +#pragma warning restore CA2211 + [HarmonyPatch(nameof(AbyssBuffMenu.Awake)), HarmonyPostfix] + public static void Post_Awake(AbyssBuffMenu __instance) + { + LoadAbyssBuffData(); + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) + { + text.text = StringStore.TranslateText(text.text); + text.font = fontAsset; + } + + TranslateWindows(__instance, fontAsset); + } + + [HarmonyPatch(nameof(AbyssBuffMenu.SelectWindow)), HarmonyPostfix] + public static void Post_SelectWindow(AbyssBuffMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + TranslateWindows(__instance, fontAsset); + } + + [HarmonyPatch(nameof(AbyssBuffMenu.SetFavorite)), HarmonyPostfix] + public static void Post_SetFavorite(AbyssBuffMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) + { + text.text = StringStore.TranslateText(text.text); + text.font = fontAsset; + } + } + + public static void TranslateWindows(AbyssBuffMenu __instance, TMP_FontAsset fontAsset) + { + foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) + { + if (AbyssBuffData.TryGetValue(text.text, out var value)) + text.text = value; + else + { + var translatedRegex = TranslateAbyssBuffRegex(text.text); + + if (translatedRegex != null) + text.text = translatedRegex; + } + + text.font = fontAsset; + } + } + + public static void LoadAbyssBuffData() + { + AbyssBuffData.Clear(); + + var abyssBuffText = "{}"; + + if (!Core.Instance.ConfigUseLocal.Value) + { + var abyssBuffsContent = Utils.GetDataFromWeb( + $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language}/Strings/abyss_buffs.json" + ) + .Result; + + if (abyssBuffsContent != null) + abyssBuffText = abyssBuffsContent; + else + { + var abyssBuffsPath = Path.Combine( + GetAssetDir(FileLoader.AssetType.Strings, Utils.Language), + "abyss_buffs.json" + ); + + if (File.Exists(abyssBuffsPath)) + abyssBuffText = File.ReadAllText(abyssBuffsPath); + } + } + else + abyssBuffText = File.ReadAllText( + Path.Combine(FileLoader.GetAssetDir(FileLoader.AssetType.Strings, Utils.Language), "abyss_buffs.json") + ); + + AbyssBuffData = JsonSerializer.Deserialize>(abyssBuffText); + } + + public static string TranslateAbyssBuffRegex(string originalText) => + (from x in AbyssBuffData + where x.Key.Contains("{value}") + let pattern = Regex.Escape(x.Key).Replace("\\{value}", "(\\d+)") + where Regex.IsMatch(originalText, pattern) + let regex = new Regex(pattern) + let match = regex.Match(originalText) + select string.Format(x.Value.Replace("value", "0"), match.Groups[1].Value)).FirstOrDefault(); +} +#endif diff --git a/Source/Patches/Modes/Abyss/AbyssCheckInBag_Patch.cs b/Source/Patches/Modes/Abyss/AbyssCheckInBag_Patch.cs new file mode 100644 index 0000000..d54c1e3 --- /dev/null +++ b/Source/Patches/Modes/Abyss/AbyssCheckInBag_Patch.cs @@ -0,0 +1,15 @@ +#if false +using HarmonyLib; + +namespace PvZ_Fusion_Translator.Patches.Modes.Abyss; + +[HarmonyPatch(typeof(AbyssCheckInBag))] +public static class AbyssCheckInBag_Patch +{ + [HarmonyPatch(nameof(AbyssCheckInBag.MoveFromBag)), HarmonyPostfix] + private static void MoveFromBag(AbyssCheckInBag __instance) => AbyssMenu2.Instance.UpdateIcons(); + + [HarmonyPatch(nameof(AbyssCheckInBag.SellIcon)), HarmonyPostfix] + private static void SellIcon(AbyssCheckInBag __instance) => AbyssMenu2.Instance.UpdateIcons(); +} +#endif diff --git a/Source/Patches/Modes/Abyss/AbyssCheckSellMenu_Patch.cs b/Source/Patches/Modes/Abyss/AbyssCheckSellMenu_Patch.cs new file mode 100644 index 0000000..88a9487 --- /dev/null +++ b/Source/Patches/Modes/Abyss/AbyssCheckSellMenu_Patch.cs @@ -0,0 +1,15 @@ +#if false +using HarmonyLib; + +namespace PvZ_Fusion_Translator.Patches.Modes.Abyss; + +[HarmonyPatch(typeof(AbyssCheckSellMenu))] +public static class AbyssCheckSellMenu_Patch +{ + [HarmonyPatch(nameof(AbyssCheckSellMenu.SellIcon)), HarmonyPostfix] + private static void SellIcon(AbyssCheckSellMenu __instance) => AbyssMenu2.Instance.UpdateIcons(); + + [HarmonyPatch(nameof(AbyssCheckSellMenu.MoveInBag)), HarmonyPostfix] + private static void MoveInBag(AbyssCheckSellMenu __instance) => AbyssMenu2.Instance.UpdateIcons(); +} +#endif diff --git a/Source/Patches/Modes/Abyss/AbyssDevelopMenu_Patch.cs b/Source/Patches/Modes/Abyss/AbyssDevelopMenu_Patch.cs new file mode 100644 index 0000000..50c8ac9 --- /dev/null +++ b/Source/Patches/Modes/Abyss/AbyssDevelopMenu_Patch.cs @@ -0,0 +1,48 @@ +#if false +using System.Text.RegularExpressions; +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Abyss; + +[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); + + TextMeshProUGUI upgradeCostText = + __instance.transform.FindChild("UpgradeCost").GetComponent(); + + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + const string RegexStr = "([^\\s]+)\n当前等级:([^\\s]+)\n\n升级条件:\n([^\\s]+)\n\n升级消耗:([^\\s]+)"; + var regex = new Regex(RegexStr); + + if (!regex.IsMatch(upgradeCostText.text)) + return; + + var match = regex.Match(upgradeCostText.text); + var groupCount = match.Groups.Count; + + List dynamicParts = []; + + for (var i = 1; i < groupCount; i++) + { + var groupValue = match.Groups[i].Value; + + var translatedValue = StringStore.translationString.ContainsKey(groupValue) + ? StringStore.translationString[groupValue] + : groupValue; + + dynamicParts.Add(translatedValue); + } + + upgradeCostText.text = string.Format(StringStore.translationStringRegex[RegexStr], [..dynamicParts]); + upgradeCostText.font = fontAsset; + } +} +#endif diff --git a/Source/Patches/Modes/Abyss/AbyssGoods_Patch.cs b/Source/Patches/Modes/Abyss/AbyssGoods_Patch.cs new file mode 100644 index 0000000..eefd9ae --- /dev/null +++ b/Source/Patches/Modes/Abyss/AbyssGoods_Patch.cs @@ -0,0 +1,18 @@ +#if false +using HarmonyLib; + +namespace PvZ_Fusion_Translator.Patches.Modes.Abyss; + +[HarmonyPatch(typeof(AbyssGoods))] +public static class AbyssGoods_Patch +{ + [HarmonyPostfix, HarmonyPatch(nameof(AbyssGoods.Start))] + private static void Start(AbyssGoods __instance) + { + __instance.costText.text = StringStore.TranslateText(__instance.costText.text, false); + __instance.costText_shadow.text = StringStore.TranslateText(__instance.costText_shadow.text, false); + __instance.hasText.text = StringStore.TranslateText(__instance.hasText.text, false); + __instance.hasText_shadow.text = StringStore.TranslateText(__instance.hasText_shadow.text, false); + } +} +#endif diff --git a/Source/Patches/Modes/Abyss/AbyssInfo_Patch.cs b/Source/Patches/Modes/Abyss/AbyssInfo_Patch.cs new file mode 100644 index 0000000..c439084 --- /dev/null +++ b/Source/Patches/Modes/Abyss/AbyssInfo_Patch.cs @@ -0,0 +1,5 @@ +#if false +namespace PvZ_Fusion_Translator.Patches.Modes.Abyss; + +public class AbyssInfo_Patch; +#endif diff --git a/Source/Patches/Modes/Abyss/AbyssLevelEnter_Patch.cs b/Source/Patches/Modes/Abyss/AbyssLevelEnter_Patch.cs new file mode 100644 index 0000000..ffa83d6 --- /dev/null +++ b/Source/Patches/Modes/Abyss/AbyssLevelEnter_Patch.cs @@ -0,0 +1,14 @@ +#if false +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Abyss; + +[HarmonyPatch(typeof(AbyssLevelEnter))] +public static class AbyssLevelEnter_Patch +{ + [HarmonyPatch(nameof(AbyssLevelEnter.SetLevel)), HarmonyPostfix] + private static void SetLevel(AbyssLevelEnter __instance) => + __instance.levelName = StringStore.TranslateText(__instance.levelName); +} +#endif diff --git a/Source/Patches/Modes/Abyss/AbyssMenu2_Patch.cs b/Source/Patches/Modes/Abyss/AbyssMenu2_Patch.cs new file mode 100644 index 0000000..052103e --- /dev/null +++ b/Source/Patches/Modes/Abyss/AbyssMenu2_Patch.cs @@ -0,0 +1,88 @@ +#if false +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine.UI; + +namespace PvZ_Fusion_Translator.Patches.Modes.Abyss; + +[HarmonyPatch(typeof(AbyssMenu2))] +public static class AbyssMenu2_Patch +{ + private static void UpdateAbyss2Text(AbyssMenu2 __instance) + { + var 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); + + Transform optionsTransform = __instance.transform.FindChild("Options").transform; + + foreach (AbyssBuffButton abyssBuffButton in optionsTransform.GetComponentsInChildren()) + { + foreach (TextMeshProUGUI textMesh in abyssBuffButton.GetComponentsInChildren()) + textMesh.text = StringStore.TranslateText(textMesh.text); + } + + foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) + { + text.text = StringStore.TranslateText(text.text); + text.font = fontAsset; + } + } + + [HarmonyPatch(nameof(AbyssMenu2.Start)), HarmonyPostfix] + private static void Start(AbyssMenu2 __instance) + { + UpdateAbyss2Text(__instance); + + Utils.ConvertButtonText(__instance.transform, "Help"); + + // custom bag text :D + + __instance.transform.FindChild("Bag").FindChild("text").GetComponent().text += "_深渊"; + + Utils.ConvertButtonText(__instance.transform, "Bag"); + } + + [HarmonyPatch(nameof(AbyssMenu2.UpdateIcons)), HarmonyPostfix] + private static void UpdateIcons(AbyssMenu2 __instance) => UpdateAbyss2Text(__instance); + + [HarmonyPatch(nameof(AbyssMenu2.UpdateBuff)), HarmonyPostfix] + private static void UpdateBuff(AbyssMenu2 __instance) => UpdateAbyss2Text(__instance); + + [HarmonyPatch(nameof(AbyssMenu2.BuyBuff)), HarmonyPostfix] + private static void BuyBuff(AbyssMenu2 __instance) => UpdateAbyss2Text(__instance); + + [HarmonyPatch(nameof(AbyssMenu2.ShowBag)), HarmonyPostfix] + private static void ShowBag(AbyssMenu2 __instance) => UpdateAbyss2Text(__instance); +} +#endif diff --git a/Source/Patches/Modes/Abyss/AbyssMenu_Patch.cs b/Source/Patches/Modes/Abyss/AbyssMenu_Patch.cs new file mode 100644 index 0000000..46594bf --- /dev/null +++ b/Source/Patches/Modes/Abyss/AbyssMenu_Patch.cs @@ -0,0 +1,48 @@ +#if false +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Abyss; + +[HarmonyPatch(typeof(AbyssMenu))] +public static class AbyssMenu_Patch +{ + [HarmonyPatch(nameof(AbyssMenu.Awake)), HarmonyPostfix] + private static void Awake(AbyssMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.levelInfo) + { + txt.text = StringStore.TranslateText( + txt.text, + "第(\\d+)关\n场景:([^\\s]+)\n总波数:(\\d+)波\n特殊环境:([^\\s]+)\n难度:(\\d+)" + ); + + txt.font = fontAsset; + } + + foreach (var text in __instance.GetComponentsInChildren()) + { + text.text = StringStore.TranslateText(text.text); + text.font = fontAsset; + } + } + + [HarmonyPatch(nameof(AbyssMenu.UpdateLevelInfo)), HarmonyPostfix] + private static void UpdateLevelInfo(AbyssMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (TextMeshProUGUI txt in __instance.levelInfo) + { + txt.text = StringStore.TranslateText( + txt.text, + "第(\\d+)关\n场景:([^\\s]+)\n总波数:(\\d+)波\n特殊环境:([^\\s]+)\n难度:(\\d+)" + ); + + txt.font = fontAsset; + } + } +} +#endif diff --git a/Source/Patches/Modes/Abyss/AbyssSelectBuffWindow_Patch.cs b/Source/Patches/Modes/Abyss/AbyssSelectBuffWindow_Patch.cs new file mode 100644 index 0000000..381b11d --- /dev/null +++ b/Source/Patches/Modes/Abyss/AbyssSelectBuffWindow_Patch.cs @@ -0,0 +1,45 @@ +#if false +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Abyss; + +[HarmonyPatch(typeof(AbyssSelectBuffWindow))] +public static class AbyssSelectBuffWindow_Patch +{ + [HarmonyPatch(nameof(AbyssSelectBuffWindow.OnAnimOver)), HarmonyPostfix] + private static void OnAnimOver(AbyssSelectBuffWindow __instance) => TranslateBuffWindow(__instance); + + [HarmonyPatch(nameof(AbyssSelectBuffWindow.SetBuff)), HarmonyPostfix] + private static void SetBuff(AbyssSelectBuffWindow __instance) => TranslateBuffWindow(__instance); + + public static void TranslateBuffWindow(AbyssSelectBuffWindow __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + AbyssBuffMenu_Patch.LoadAbyssBuffData(); + + foreach (TextMeshProUGUI titleText in __instance.titleText) + { + if (AbyssBuffMenu_Patch.abyssBuffData.ContainsKey(titleText.text)) + { + if (titleText.name.Contains("shadow")) + titleText.text = Utils.RemoveColorTags(AbyssBuffMenu_Patch.abyssBuffData[titleText.text]); + else + titleText.text = AbyssBuffMenu_Patch.abyssBuffData[titleText.text]; + } + + titleText.font = fontAsset; + } + + string translatedIntroduceText = AbyssBuffMenu_Patch.abyssBuffData.ContainsKey(__instance.introduce.text) + ? AbyssBuffMenu_Patch.abyssBuffData[__instance.introduce.text] + : AbyssBuffMenu_Patch.TranslateAbyssBuffRegex(__instance.introduce.text); + + if (translatedIntroduceText == null) + return; + + __instance.introduce.text = translatedIntroduceText; + __instance.introduce.font = fontAsset; + } +} +#endif diff --git a/Source/Patches/Modes/Abyss/AbyssSettlementMenu_Patch.cs b/Source/Patches/Modes/Abyss/AbyssSettlementMenu_Patch.cs new file mode 100644 index 0000000..19547c4 --- /dev/null +++ b/Source/Patches/Modes/Abyss/AbyssSettlementMenu_Patch.cs @@ -0,0 +1,58 @@ +#if false +using System.Text.RegularExpressions; +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Abyss; + +[HarmonyPatch(typeof(AbyssSettlementMenu))] +public static class AbyssSettlementMenu_Patch +{ + [HarmonyPatch(nameof(AbyssSettlementMenu.InitSettle)), HarmonyPostfix] + private static void InitSettle(AbyssSettlementMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + string[] regexStrList = + [ + "第(\\d+)关\n通关用时:(\\d+)分(\\d+)秒\n杀敌数量:(\\d+)\n关卡叶绿素产出:(\\d+)\n极限模式产出:(\\d+)\n非首胜无额外产出\n产出叶绿素总计:(\\d+)", + "第(\\d+)关\n通关用时:(\\d+)分(\\d+)秒\n杀敌数量:(\\d+)\n关卡叶绿素产出:(\\d+)\n极限模式产出:(\\d+)\n首胜产出:(\\d+)\n剩余小推车数量:(\\d+),获得叶绿素:(\\d+)\n产出叶绿素总计:(\\d+)", + "第(\\d+)关\n通关用时:(\\d+)分(\\d+)秒\n杀敌数量:(\\d+)\n关卡叶绿素产出:(\\d+)\n首胜产出:(\\d+)\n剩余小推车数量:(\\d+),获得叶绿素:(\\d+)\n产出叶绿素总计:(\\d+)", + "第(\\d+)关\n通关用时:(\\d+)分(\\d+)秒\n杀敌数量:(\\d+)\n关卡叶绿素产出:(\\d+)\n困难模式产出:(\\d+)\n首胜产出:(\\d+)\n剩余小推车数量:(\\d+),获得叶绿素:(\\d+)\n产出叶绿素总计:(\\d+)", + "第(\\d+)关\n通关用时:(\\d+)分(\\d+)秒\n杀敌数量:(\\d+)\n关卡叶绿素产出:(\\d+)\n非首胜无额外产出\n产出叶绿素总计:(\\d+)", + "第(\\d+)关\n通关用时:(\\d+)分(\\d+)秒\n杀敌数量:(\\d+)\n关卡叶绿素产出:(\\d+)\n困难模式产出:(\\d+)\n非首胜无额外产出\n产出叶绿素总计:(\\d+)", + ]; + + foreach (var regexStr in regexStrList) + { + var regex = new Regex(regexStr); + + if (!regex.IsMatch(__instance.settleInfo.text)) + continue; + + var match = regex.Match(__instance.settleInfo.text); + var groupCount = match.Groups.Count; + + List dynamicParts = []; + + for (var i = 1; i < groupCount; i++) + { + var groupValue = match.Groups[i].Value; + + var translatedValue = StringStore.translationString.ContainsKey(groupValue) + ? StringStore.translationString[groupValue] + : groupValue; + + dynamicParts.Add(translatedValue); + } + + __instance.settleInfo.text = string.Format( + StringStore.translationStringRegex[regexStr], + [..dynamicParts] + ); + + __instance.settleInfo.font = fontAsset; + } + } +} +#endif diff --git a/Source/Patches/Modes/Abyss/AbyssStoreMenu_Patch.cs b/Source/Patches/Modes/Abyss/AbyssStoreMenu_Patch.cs new file mode 100644 index 0000000..7ab6c54 --- /dev/null +++ b/Source/Patches/Modes/Abyss/AbyssStoreMenu_Patch.cs @@ -0,0 +1,22 @@ +#if false +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Abyss; + +[HarmonyPatch(typeof(AbyssStoreMenu))] +public static class AbyssStoreMenu_Patch +{ + [HarmonyPatch(nameof(AbyssStoreMenu.Update)), HarmonyPostfix] + private static void Update(AbyssStoreMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (TextMeshProUGUI text in __instance.GetComponentsInChildren()) + { + text.text = StringStore.TranslateText(text.text); + text.font = fontAsset; + } + } +} +#endif diff --git a/Source/Patches/Modes/Harvest/GardenBagMenu_Patch.cs b/Source/Patches/Modes/Harvest/GardenBagMenu_Patch.cs new file mode 100644 index 0000000..712fb8d --- /dev/null +++ b/Source/Patches/Modes/Harvest/GardenBagMenu_Patch.cs @@ -0,0 +1,19 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Harvest; + +[HarmonyPatch(typeof(GardenBagMenu))] +public static class GardenBagMenu_Patch +{ + [HarmonyPatch(nameof(GardenBagMenu.Awake)), HarmonyPostfix] + private static void Awake(GardenBagMenu __instance) + { + _ = FontStore.LoadTMPFont(Utils.Language.ToString()); + + var closeButtonTransform = __instance.transform.Find("Close"); + + foreach (var text in closeButtonTransform.GetComponentsInChildren()) + text.text = StringStore.TranslateText("合上"); + } +} diff --git a/Source/Patches/Modes/Harvest/GardenCard_Patch.cs b/Source/Patches/Modes/Harvest/GardenCard_Patch.cs new file mode 100644 index 0000000..fa239ba --- /dev/null +++ b/Source/Patches/Modes/Harvest/GardenCard_Patch.cs @@ -0,0 +1,16 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Harvest; + +[HarmonyPatch(typeof(GardenCard))] +public static class GardenCard_Patch +{ + [HarmonyPatch(nameof(GardenCard.Start)), HarmonyPostfix] + private static void Start(GardenCard __instance) => + __instance.text.text = StringStore.TranslateText(__instance.text.text).Replace("26", "16"); + + [HarmonyPatch(nameof(GardenCard.ChangeCardSprite)), HarmonyPostfix] + private static void ChangeCardSprite(GardenCard __instance) => + __instance.text.text = StringStore.TranslateText(__instance.text.text).Replace("26", "16"); +} diff --git a/Source/Patches/Modes/Harvest/TreasureConfirmMenu_Patch.cs b/Source/Patches/Modes/Harvest/TreasureConfirmMenu_Patch.cs new file mode 100644 index 0000000..9527418 --- /dev/null +++ b/Source/Patches/Modes/Harvest/TreasureConfirmMenu_Patch.cs @@ -0,0 +1,20 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Harvest; + +[HarmonyPatch(typeof(TreasureConfirmMenu))] +public static class TreasureConfirmMenu_Patch +{ + [HarmonyPatch(nameof(TreasureConfirmMenu.SetText)), HarmonyPostfix] + private static void SetText(TreasureConfirmMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + } +} diff --git a/Source/Patches/Modes/Harvest/TreasureEquipmentMenu_Patch.cs b/Source/Patches/Modes/Harvest/TreasureEquipmentMenu_Patch.cs new file mode 100644 index 0000000..29d5dbc --- /dev/null +++ b/Source/Patches/Modes/Harvest/TreasureEquipmentMenu_Patch.cs @@ -0,0 +1,32 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Harvest; + +[HarmonyPatch(typeof(TreasureEquipmentMenu))] +public static class TreasureEquipmentMenu_Patch +{ + [HarmonyPatch(nameof(TreasureEquipmentMenu.Awake)), HarmonyPostfix] + private static void Awake(TreasureEquipmentMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + } + + [HarmonyPatch(nameof(TreasureEquipmentMenu.UpdateCards)), HarmonyPostfix] + private static void UpdateCards(TreasureEquipmentMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + } +} diff --git a/Source/Patches/Modes/Harvest/TreasureEvacuateMenu_Patch.cs b/Source/Patches/Modes/Harvest/TreasureEvacuateMenu_Patch.cs new file mode 100644 index 0000000..349ba76 --- /dev/null +++ b/Source/Patches/Modes/Harvest/TreasureEvacuateMenu_Patch.cs @@ -0,0 +1,23 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Harvest; + +[HarmonyPatch(typeof(TreasureEvacuateMenu))] +public static class TreasureEvacuateMenu_Patch +{ + [HarmonyPatch(nameof(TreasureEvacuateMenu.Start)), HarmonyPostfix] + private static void Start(TreasureEvacuateMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + + if (txt.name.Contains("text (1)")) + txt.name += "_EVACUATE"; + } + } +} diff --git a/Source/Patches/Modes/Harvest/TreasureMainMenu_Patch.cs b/Source/Patches/Modes/Harvest/TreasureMainMenu_Patch.cs new file mode 100644 index 0000000..16a00be --- /dev/null +++ b/Source/Patches/Modes/Harvest/TreasureMainMenu_Patch.cs @@ -0,0 +1,20 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Harvest; + +[HarmonyPatch(typeof(TreasureMainMenu))] +public static class TreasureMainMenu_Patch +{ + [HarmonyPatch(nameof(TreasureMainMenu.Update)), HarmonyPostfix] + private static void Update(TreasureMainMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + } +} diff --git a/Source/Patches/Modes/Harvest/TreasureManager_Patch.cs b/Source/Patches/Modes/Harvest/TreasureManager_Patch.cs new file mode 100644 index 0000000..c4e7b39 --- /dev/null +++ b/Source/Patches/Modes/Harvest/TreasureManager_Patch.cs @@ -0,0 +1,26 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Harvest; + +[HarmonyPatch(typeof(TreasureManager))] +public static class TreasureManager_Patch +{ + [HarmonyPatch(nameof(TreasureManager.Update)), HarmonyPostfix] + private static void Update(TreasureManager __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.evaText) + { + txt.autoSizeTextContainer = false; + + if (txt.text == "Evacuate") + continue; + + txt.text = StringStore.TranslateText(txt.text); + txt.name = txt.text + "_EVACUATE"; + txt.font = fontAsset; + } + } +} diff --git a/Source/Patches/Modes/Harvest/TreasureStoreMenu_Patch.cs b/Source/Patches/Modes/Harvest/TreasureStoreMenu_Patch.cs new file mode 100644 index 0000000..81bb3f5 --- /dev/null +++ b/Source/Patches/Modes/Harvest/TreasureStoreMenu_Patch.cs @@ -0,0 +1,20 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Harvest; + +[HarmonyPatch(typeof(TreasureStoreMenu))] +public static class TreasureStoreMenu_Patch +{ + [HarmonyPatch(nameof(TreasureStoreMenu.InitCards)), HarmonyPostfix] + private static void InitCards(TreasureStoreMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + } +} diff --git a/Source/Patches/Modes/Harvest/TreasureUpgradeMenu_Patch.cs b/Source/Patches/Modes/Harvest/TreasureUpgradeMenu_Patch.cs new file mode 100644 index 0000000..9d61ef3 --- /dev/null +++ b/Source/Patches/Modes/Harvest/TreasureUpgradeMenu_Patch.cs @@ -0,0 +1,54 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; +using UnityEngine.UI; + +namespace PvZ_Fusion_Translator.Patches.Modes.Harvest; + +[HarmonyPatch(typeof(TreasureUpgradeMenu))] +public static class TreasureUpgradeMenu_Patch +{ + [HarmonyPatch(nameof(TreasureUpgradeMenu.Start)), HarmonyPostfix] + private static void Start(TreasureUpgradeMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + } + + [HarmonyPatch(nameof(TreasureUpgradeMenu.UpgradeWareHouse)), HarmonyPostfix] + private static void UpgradeWareHouse(TreasureUpgradeMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + } + + [HarmonyPatch(nameof(TreasureUpgradeMenu.InitWareHouseUpgrade)), HarmonyPostfix] + private static void InitWareHouseUpgrade(TreasureUpgradeMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + + foreach (var txt in __instance.GetComponentsInChildren()) + { + var newTxtObj = Utils.ConvertToTextMeshProUGUI(txt.gameObject, txt.transform.parent, "text"); + var newTxt = newTxtObj.GetComponent(); + newTxt.text = StringStore.TranslateText("植物商店"); + newTxt.autoSizeTextContainer = true; + newTxt.color = new(0, 0, 0.3922f, 1); + } + } +} diff --git a/Source/Patches/Modes/Harvest/TreasureWarehouseMenu_Patch.cs b/Source/Patches/Modes/Harvest/TreasureWarehouseMenu_Patch.cs new file mode 100644 index 0000000..56d0dac --- /dev/null +++ b/Source/Patches/Modes/Harvest/TreasureWarehouseMenu_Patch.cs @@ -0,0 +1,56 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Harvest; + +[HarmonyPatch(typeof(TreasureWarehouseMenu))] +public static class TreasureWarehouseMenu_Patch +{ + [HarmonyPatch(nameof(TreasureWarehouseMenu.InitCards)), HarmonyPostfix] + private static void InitCards(TreasureWarehouseMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + } + + [HarmonyPatch(nameof(TreasureWarehouseMenu.QuickSell)), HarmonyPostfix] + private static void QuickSell(TreasureWarehouseMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + } + + [HarmonyPatch(nameof(TreasureWarehouseMenu.FastSell)), HarmonyPostfix] + private static void FastSell(TreasureWarehouseMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + } + + [HarmonyPatch(nameof(TreasureWarehouseMenu.EnterStore)), HarmonyPostfix] + private static void EnterStore(TreasureWarehouseMenu __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + } +} diff --git a/Source/Patches/Modes/Odyssey/MultipleChoiceMenu_Patch.cs b/Source/Patches/Modes/Odyssey/MultipleChoiceMenu_Patch.cs new file mode 100644 index 0000000..8f9dbd0 --- /dev/null +++ b/Source/Patches/Modes/Odyssey/MultipleChoiceMenu_Patch.cs @@ -0,0 +1,46 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey; + +[HarmonyPatch(typeof(MultipleChoiceMenu))] +public static class MultipleChoiceMenu_Patch +{ + public static TMP_FontAsset FontAsset => FontStore.LoadTMPFont(Utils.Language.ToString()); + + [HarmonyPatch(nameof(MultipleChoiceMenu.Awake)), HarmonyPatch(nameof(MultipleChoiceMenu.Cancel)), + HarmonyPatch(nameof(MultipleChoiceMenu.Refresh)), HarmonyPatch(nameof(MultipleChoiceMenu.TurnPage)), + HarmonyPatch(nameof(MultipleChoiceMenu.UpdateWindow)), HarmonyPostfix] + public static void Awake(MultipleChoiceMenu __instance) + { + foreach (var window in __instance.windows) + { + TranslateWindowText(window.title); + TranslateWindowText(window.introduce); + } + + foreach (var txt in __instance.GetComponentsInChildren() + .SelectMany(button => button.GetComponentsInChildren())) + { + txt.text = StringStore.TranslationString.ContainsKey(txt.text + "_MC") + ? StringStore.TranslateText(txt.text + "_MC") + : StringStore.TranslateText(txt.text); + + txt.font = FontAsset; + } + } + + public static void TranslateWindowText(TextMeshProUGUI txt) + { + txt.font = FontAsset; + + if (StringStore.CustomLevelString.TryGetValue(txt.text, out var value)) + txt.text = value; + else if (Utils.GetPlantNameFromAlmanac(txt.text) != "") + txt.text = Utils.GetPlantNameFromAlmanac(txt.text); + else + txt.text = StringStore.TranslationString.ContainsKey(txt.text + "_MC") + ? StringStore.TranslateText(txt.text + "_MC") + : StringStore.TranslateText(txt.text); + } +} diff --git a/Source/Patches/Modes/Odyssey/OppositeBuffManager_Patch.cs b/Source/Patches/Modes/Odyssey/OppositeBuffManager_Patch.cs new file mode 100644 index 0000000..58f312e --- /dev/null +++ b/Source/Patches/Modes/Odyssey/OppositeBuffManager_Patch.cs @@ -0,0 +1,47 @@ +#if false +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey; + +[HarmonyPatch(typeof(OppositeBuffManager))] +public static class OppositeBuffManager_Patch +{ + public static Dictionary buffLinks = TravelMgr_Patch.buffLinks; + + public static Dictionary> translatedTravelBuffs = + TravelMgr_Patch.translatedTravelBuffs; + + public const string BadPattern = @"^但(.*)"; + + public static readonly string BadFormat = StringStore.translationStringRegex.ContainsKey(BadPattern) + ? StringStore.translationStringRegex[BadPattern] + : "But, {0}"; + + public static TMP_FontAsset fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + [HarmonyPatch(nameof(OppositeBuffManager.SetText)), HarmonyPostfix] + private static void SetText(OppositeBuffManager __instance) + { + if (TravelMgr_Patch.travelBuffString.ContainsKey(__result)) + __result = TravelMgr_Patch.travelBuffString[__result]; + else if (TravelMgr_Patch.travelBuffString.ContainsKey(TravelMgr_Patch.RemoveBuffName(__result))) + __result = TravelMgr_Patch.travelBuffString[TravelMgr_Patch.RemoveBuffName(__result)]; + } + + public static void TranslateOppositeText( + Il2CppSystem.Collections.Generic.List textList, + Il2CppSystem.Object buff, + bool isBad = false + ) + { + var buffText = TravelMgr.Instance.GetText(buff); + + foreach (var text in textList) + { + text.text = isBad ? string.Format(BadFormat, buffText) : buffText; + text.font = fontAsset; + } + } +} +#endif diff --git a/Source/Patches/Modes/Odyssey/ShootingManager_Patch.cs b/Source/Patches/Modes/Odyssey/ShootingManager_Patch.cs new file mode 100644 index 0000000..5678e28 --- /dev/null +++ b/Source/Patches/Modes/Odyssey/ShootingManager_Patch.cs @@ -0,0 +1,575 @@ +using HarmonyLib; + +namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey; + +[HarmonyPatch(typeof(ShootingManager))] +public static class ShootingManager_Patch +{ + [HarmonyPatch(nameof(ShootingManager.RegisterCoreBuff)), HarmonyPatch(nameof(ShootingManager.RegisterExpertBuff)), + HarmonyPatch(nameof(ShootingManager.RegisterGetPlantBuff)), + HarmonyPatch(nameof(ShootingManager.RegisterOtherBuff)), HarmonyPostfix] + public static void UpgradeBuff(ShootingManager __instance, ref MultipleChoiceMenu menu) => + MultipleChoiceMenu_Patch.Awake(menu); + + public static void GetBuffs() + { + /*#region code + + AbyssSwordStar t0 = new(); + Bamboo t1 = new(); + BigChomper t4 = new(); + BigGatling t5 = new(); + CabbageCannon t6 = new(); + Cabbagepult t7 = new(); + Cactus t8 = new(); + Caltrop t9 = new(); + CaltropNut t10 = new(); + CattailLour t11 = new(); + CherryChomper t12 = new(); + CherryGatling t13 = new(); + CherrySquash t14 = new(); + Chomper t15 = new(); + Cornpult t17 = new(); + DoomCactus t20 = new(); + DoomChomper t21 = new(); + DoomSniper t22 = new(); + EmeraleBlover t23 = new(); + FireMelon t24 = new(); + FumeShroom t25 = new(); + GarlicFume t26 = new(); + GloomShroom t28 = new(); + GoldCabbage t29 = new(); + HelmetGatling t30 = new(); + HypnoEmperor t31 = new(); + HypnoNut t32 = new(); + HypnoShroom t33 = new(); + IceFumeShroom t34 = new(); + IcePuff t35 = new(); + IFVIronPuff t36 = new(); + IronPuff t37 = new(); + LanternSplit t38 = new(); + LanternUmbrella t39 = new(); + LaserUmbrella t40 = new(); + LotusBamboo t41 = new(); + Melonpult t42 = new(); + NuclearSquash t43 = new(); + ObsidianSpike t44 = new(); + ObsidianWallNut t45 = new(); + PeaMine t46 = new(); + Peashooter t47 = new(); + PortalCorn t48 = new(); + PotatoMine t49 = new(); + ScaredyDoom t54 = new(); + ScaredyShroom t55 = new(); + SmallPuff t57 = new(); + SniperPea t58 = new(); + SnowGatlingPuff t59 = new(); + SpikeRock t61 = new(); + Squalour t62 = new(); + Squash t63 = new(); + StarFruit t64 = new(); + SuperChomper t66 = new(); + SuperHypno t67 = new(); + SuperMelon t68 = new(); + SuperStar t69 = new(); + SuperThreePeater t70 = new(); + SwordStar t71 = new(); + TallNut t72 = new(); + ThreeMine t73 = new(); + ThreePeater t74 = new(); + ThreeSquash t75 = new(); + UltimateBamboo t76 = new(); + UltimateBigChomper t77 = new(); + UltimateBigGatling t78 = new(); + UltimateBlover t79 = new(); + UltimateCabbage t80 = new(); + UltimateCabbageCannon t81 = new(); + UltimateCactus t82 = new(); + UltimateChomper t83 = new(); + UltimateCorn t84 = new(); + UltimateDoomScared t85 = new(); + UltimateFume t86 = new(); + UltimateGatling t87 = new(); + UltimateGloom t88 = new(); + UltimateHelmetGatling t89 = new(); + UltimateHypno t90 = new(); + UltimateLanternSplit t91 = new(); + UltimateMelon t92 = new(); + UltimateMinigun t93 = new(); + UltimatePoisonFume t94 = new(); + UltimateSniperGatling t95 = new(); + UltimateSpring t96 = new(); + UltimateStar t97 = new(); + UltimateStarTorch t98 = new(); + UltimateTallNut t99 = new(); + UltimateWinterMelon t100 = new(); + Umbrellaleaf t101 = new(); + WallNut t103 = new(); + WinterMelon t104 = new(); + + Dictionary t = new(); + + #region 3 + + if(t0.Buffs != null) + { + Utils.TryAdd(t, t0.Role, t0.Role); + } + + if(t1.Buffs != null) + { + Utils.TryAdd(t, t1.Role, t1.Role); + } + + if(t4.Buffs != null) + { + Utils.TryAdd(t, t4.Role, t4.Role); + } + + if(t5.Buffs != null) + { + Utils.TryAdd(t, t5.Role, t5.Role); + } + + if(t6.Buffs != null) + { + Utils.TryAdd(t, t6.Role, t6.Role); + } + + if(t7.Buffs != null) + { + Utils.TryAdd(t, t7.Role, t7.Role); + } + + if(t8.Buffs != null) + { + Utils.TryAdd(t, t8.Role, t8.Role); + } + + if(t9.Buffs != null) + { + Utils.TryAdd(t, t9.Role, t9.Role); + } + + if(t10.Buffs != null) + { + Utils.TryAdd(t, t10.Role, t10.Role); + } + + if(t11.Buffs != null) + { + Utils.TryAdd(t, t11.Role, t11.Role); + } + + if(t12.Buffs != null) + { + Utils.TryAdd(t, t12.Role, t12.Role); + } + + if(t13.Buffs != null) + { + Utils.TryAdd(t, t13.Role, t13.Role); + } + + if(t14.Buffs != null) + { + Utils.TryAdd(t, t14.Role, t14.Role); + } + + if(t15.Buffs != null) + { + Utils.TryAdd(t, t15.Role, t15.Role); + } + + if(t17.Buffs != null) + { + Utils.TryAdd(t, t17.Role, t17.Role); + } + + if(t20.Buffs != null) + { + Utils.TryAdd(t, t20.Role, t20.Role); + } + + if(t21.Buffs != null) + { + Utils.TryAdd(t, t21.Role, t21.Role); + } + + if(t22.Buffs != null) + { + Utils.TryAdd(t, t22.Role, t22.Role); + } + + if(t23.Buffs != null) + { + Utils.TryAdd(t, t23.Role, t23.Role); + } + + if(t24.Buffs != null) + { + Utils.TryAdd(t, t24.Role, t24.Role); + } + + if(t25.Buffs != null) + { + Utils.TryAdd(t, t25.Role, t25.Role); + } + + if(t26.Buffs != null) + { + Utils.TryAdd(t, t26.Role, t26.Role); + } + + if(t28.Buffs != null) + { + Utils.TryAdd(t, t28.Role, t28.Role); + } + + if(t29.Buffs != null) + { + Utils.TryAdd(t, t29.Role, t29.Role); + } + + if(t30.Buffs != null) + { + Utils.TryAdd(t, t30.Role, t30.Role); + } + + if(t31.Buffs != null) + { + Utils.TryAdd(t, t31.Role, t31.Role); + } + + if(t32.Buffs != null) + { + Utils.TryAdd(t, t32.Role, t32.Role); + } + + if(t33.Buffs != null) + { + Utils.TryAdd(t, t33.Role, t33.Role); + } + + if(t34.Buffs != null) + { + Utils.TryAdd(t, t34.Role, t34.Role); + } + + if(t35.Buffs != null) + { + Utils.TryAdd(t, t35.Role, t35.Role); + } + + if(t36.Buffs != null) + { + Utils.TryAdd(t, t36.Role, t36.Role); + } + + if(t37.Buffs != null) + { + Utils.TryAdd(t, t37.Role, t37.Role); + } + + if(t38.Buffs != null) + { + Utils.TryAdd(t, t38.Role, t38.Role); + } + + if(t39.Buffs != null) + { + Utils.TryAdd(t, t39.Role, t39.Role); + } + + if(t40.Buffs != null) + { + Utils.TryAdd(t, t40.Role, t40.Role); + } + + if(t41.Buffs != null) + { + Utils.TryAdd(t, t41.Role, t41.Role); + } + + if(t42.Buffs != null) + { + Utils.TryAdd(t, t42.Role, t42.Role); + } + + if(t43.Buffs != null) + { + Utils.TryAdd(t, t43.Role, t43.Role); + } + + if(t44.Buffs != null) + { + Utils.TryAdd(t, t44.Role, t44.Role); + } + + if(t45.Buffs != null) + { + Utils.TryAdd(t, t45.Role, t45.Role); + } + + if(t46.Buffs != null) + { + Utils.TryAdd(t, t46.Role, t46.Role); + } + + if(t47.Buffs != null) + { + Utils.TryAdd(t, t47.Role, t47.Role); + } + + if(t48.Buffs != null) + { + Utils.TryAdd(t, t48.Role, t48.Role); + } + + if(t49.Buffs != null) + { + Utils.TryAdd(t, t49.Role, t49.Role); + } + + if(t54.Buffs != null) + { + Utils.TryAdd(t, t54.Role, t54.Role); + } + + if(t55.Buffs != null) + { + Utils.TryAdd(t, t55.Role, t55.Role); + } + + if(t57.Buffs != null) + { + Utils.TryAdd(t, t57.Role, t57.Role); + } + + if(t58.Buffs != null) + { + Utils.TryAdd(t, t58.Role, t58.Role); + } + + if(t59.Buffs != null) + { + Utils.TryAdd(t, t59.Role, t59.Role); + } + + if(t61.Buffs != null) + { + Utils.TryAdd(t, t61.Role, t61.Role); + } + + if(t62.Buffs != null) + { + Utils.TryAdd(t, t62.Role, t62.Role); + } + + if(t63.Buffs != null) + { + Utils.TryAdd(t, t63.Role, t63.Role); + } + + if(t64.Buffs != null) + { + Utils.TryAdd(t, t64.Role, t64.Role); + } + + if(t66.Buffs != null) + { + Utils.TryAdd(t, t66.Role, t66.Role); + } + + if(t67.Buffs != null) + { + Utils.TryAdd(t, t67.Role, t67.Role); + } + + if(t68.Buffs != null) + { + Utils.TryAdd(t, t68.Role, t68.Role); + } + + if(t69.Buffs != null) + { + Utils.TryAdd(t, t69.Role, t69.Role); + } + + if(t70.Buffs != null) + { + Utils.TryAdd(t, t70.Role, t70.Role); + } + + if(t71.Buffs != null) + { + Utils.TryAdd(t, t71.Role, t71.Role); + } + + if(t72.Buffs != null) + { + Utils.TryAdd(t, t72.Role, t72.Role); + } + + if(t73.Buffs != null) + { + Utils.TryAdd(t, t73.Role, t73.Role); + } + + if(t74.Buffs != null) + { + Utils.TryAdd(t, t74.Role, t74.Role); + } + + if(t75.Buffs != null) + { + Utils.TryAdd(t, t75.Role, t75.Role); + } + + if(t76.Buffs != null) + { + Utils.TryAdd(t, t76.Role, t76.Role); + } + + if(t77.Buffs != null) + { + Utils.TryAdd(t, t77.Role, t77.Role); + } + + if(t78.Buffs != null) + { + Utils.TryAdd(t, t78.Role, t78.Role); + } + + if(t79.Buffs != null) + { + Utils.TryAdd(t, t79.Role, t79.Role); + } + + if(t80.Buffs != null) + { + Utils.TryAdd(t, t80.Role, t80.Role); + } + + if(t81.Buffs != null) + { + Utils.TryAdd(t, t81.Role, t81.Role); + } + + if(t82.Buffs != null) + { + Utils.TryAdd(t, t82.Role, t82.Role); + } + + if(t83.Buffs != null) + { + Utils.TryAdd(t, t83.Role, t83.Role); + } + + if(t84.Buffs != null) + { + Utils.TryAdd(t, t84.Role, t84.Role); + } + + if(t85.Buffs != null) + { + Utils.TryAdd(t, t85.Role, t85.Role); + } + + if(t86.Buffs != null) + { + Utils.TryAdd(t, t86.Role, t86.Role); + } + + if(t87.Buffs != null) + { + Utils.TryAdd(t, t87.Role, t87.Role); + } + + if(t88.Buffs != null) + { + Utils.TryAdd(t, t88.Role, t88.Role); + } + + if(t89.Buffs != null) + { + Utils.TryAdd(t, t89.Role, t89.Role); + } + + if(t90.Buffs != null) + { + Utils.TryAdd(t, t90.Role, t90.Role); + } + + if(t91.Buffs != null) + { + Utils.TryAdd(t, t91.Role, t91.Role); + } + + if(t92.Buffs != null) + { + Utils.TryAdd(t, t92.Role, t92.Role); + } + + if(t93.Buffs != null) + { + Utils.TryAdd(t, t93.Role, t93.Role); + } + + if(t94.Buffs != null) + { + Utils.TryAdd(t, t94.Role, t94.Role); + } + + if(t95.Buffs != null) + { + Utils.TryAdd(t, t95.Role, t95.Role); + } + + if(t96.Buffs != null) + { + Utils.TryAdd(t, t96.Role, t96.Role); + } + + if(t97.Buffs != null) + { + Utils.TryAdd(t, t97.Role, t97.Role); + } + + if(t98.Buffs != null) + { + Utils.TryAdd(t, t98.Role, t98.Role); + } + + if(t99.Buffs != null) + { + Utils.TryAdd(t, t99.Role, t99.Role); + } + + if(t100.Buffs != null) + { + Utils.TryAdd(t, t100.Role, t100.Role); + } + + if(t101.Buffs != null) + { + Utils.TryAdd(t, t101.Role, t101.Role); + } + + if(t103.Buffs != null) + { + Utils.TryAdd(t, t103.Role, t103.Role); + } + + if(t104.Buffs != null) + { + Utils.TryAdd(t, t104.Role, t104.Role); + } + + #endregion + + File.WriteAllText("tge_roles.json", FileLoader.SerializeWithIndentation(t)); + + #endregion*/ + } +} diff --git a/Source/Patches/Modes/Odyssey/SynergyDisplay_Patch.cs b/Source/Patches/Modes/Odyssey/SynergyDisplay_Patch.cs new file mode 100644 index 0000000..40e89e2 --- /dev/null +++ b/Source/Patches/Modes/Odyssey/SynergyDisplay_Patch.cs @@ -0,0 +1,19 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey; + +[HarmonyPatch(typeof(SynergyDisplay))] +public static class SynergyDisplay_Patch +{ + [HarmonyPatch(nameof(SynergyDisplay.Start)), HarmonyPostfix] + public static void Start(SynergyDisplay __instance) => + __instance.text.text = TranslateInvestDisplay(__instance.text.text); + + public static string TranslateInvestDisplay(string originalText) + { + var parts = originalText.Split("\n\n"); + var translatedParts = parts.Select(part => StringStore.TranslateColorText(part)).ToList(); + return string.Join("\n\n", translatedParts); + } +} diff --git a/Source/Patches/Modes/Odyssey/TravelAdvantureMenu_Patch.cs b/Source/Patches/Modes/Odyssey/TravelAdvantureMenu_Patch.cs new file mode 100644 index 0000000..ce26516 --- /dev/null +++ b/Source/Patches/Modes/Odyssey/TravelAdvantureMenu_Patch.cs @@ -0,0 +1,28 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey; + +[HarmonyPatch(typeof(TravelAdvantureMenu))] +public static class TravelAdvantureMenu_Patch +{ + [HarmonyPatch(nameof(TravelAdvantureMenu.Awake)), HarmonyPostfix] + public static void Awake(TravelAdvantureMenu __instance) + { + foreach (var button in __instance.GetComponentsInChildren()) + { + var plantName = Utils.GetPlantNameFromAlmanac(button.levelName.text); + + if (Utils.Language == Utils.LanguageEnum.Arabic) + button.levelName.text = StringStore.TranslateText(button.levelName.text); + else + button.levelName.text = plantName != "" ? plantName : StringStore.TranslateText(button.levelName.text); + } + } + + [HarmonyPatch(nameof(TravelAdvantureMenu.LookWeak)), HarmonyPostfix] + public static void LookWeak(TravelAdvantureMenu __instance) => Awake(__instance); + + [HarmonyPatch(nameof(TravelAdvantureMenu.LookUlti)), HarmonyPostfix] + public static void LookUlti(TravelAdvantureMenu __instance) => Awake(__instance); +} diff --git a/Source/Patches/Modes/Odyssey/TravelBuffMenu_Patch.cs b/Source/Patches/Modes/Odyssey/TravelBuffMenu_Patch.cs new file mode 100644 index 0000000..fead17e --- /dev/null +++ b/Source/Patches/Modes/Odyssey/TravelBuffMenu_Patch.cs @@ -0,0 +1,24 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey; + +[HarmonyPatch(typeof(TravelBuffMenu))] +public static class TravelBuffMenu_Patch +{ + [HarmonyPatch(nameof(TravelBuffMenu.RefeshOptions)), HarmonyPostfix] + public static void RefeshOptions(TravelBuffMenu __instance) + { + foreach (var button in __instance.options) + TravelBuffOptionButton_Patch.TranslateOptionButton(button); + } + + [HarmonyPatch(nameof(TravelBuffMenu.Awake)), HarmonyPostfix] + public static void Awake(TravelBuffMenu __instance) + { + var refreshTransform = __instance.transform.Find("Refresh"); + + foreach (var text in refreshTransform.GetComponentsInChildren()) + text.text = StringStore.TranslateText(text.text); + } +} diff --git a/Source/Patches/Modes/Odyssey/TravelBuffMgr_Patch.cs b/Source/Patches/Modes/Odyssey/TravelBuffMgr_Patch.cs new file mode 100644 index 0000000..98f9eca --- /dev/null +++ b/Source/Patches/Modes/Odyssey/TravelBuffMgr_Patch.cs @@ -0,0 +1,23 @@ +#if false +using HarmonyLib; + +namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey; + +[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), 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); + } +} +#endif diff --git a/Source/Patches/Modes/Odyssey/TravelBuffOptionButton_Patch.cs b/Source/Patches/Modes/Odyssey/TravelBuffOptionButton_Patch.cs new file mode 100644 index 0000000..45736d8 --- /dev/null +++ b/Source/Patches/Modes/Odyssey/TravelBuffOptionButton_Patch.cs @@ -0,0 +1,35 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; +using static PvZ_Fusion_Translator.Patches.Modes.Odyssey.TravelMgr_Patch; + +namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey; + +[HarmonyPatch(typeof(TravelBuffOptionButton))] +public static class TravelBuffOptionButton_Patch +{ + [HarmonyPatch(nameof(TravelBuffOptionButton.Awake)), HarmonyPostfix] + public static void Awake(TravelBuffOptionButton __instance) => TranslateOptionButton(__instance); + + [HarmonyPatch(nameof(TravelBuffOptionButton.OnAnimOver)), HarmonyPostfix] + public static void OnAnimOver(TravelBuffOptionButton __instance) => TranslateOptionButton(__instance); + + public static void TranslateOptionButton(TravelBuffOptionButton button) + { + if (TravelBuffString.ContainsKey(button.introduce.text)) + { + var translatedBuff = TravelBuffString[button.introduce.text]; + button.introduce.text = AddBuffName(translatedBuff); + } + + if (!Utils.CheckForUntranslatedText(button.introduce.text)) + button.introduce.text = AddBuffName(button.introduce.text); + + if (!TravelBuffString.ContainsKey(button.introduce.text) && + Utils.CheckForUntranslatedText(button.introduce.text)) + button.introduce.text = StringStore.TranslateText(button.introduce.text); + } +} + +//List buffSet = translatedTravelBuffs[buffLinks[__instance.buffType]]; +//string buff = (__instance.show != null) ? buffSet[__instance.buffIndex] : StringStore.TranslateText("无"); +//__instance.introduce.text = buff; diff --git a/Source/Patches/Modes/Odyssey/TravelBuff_Patch.cs b/Source/Patches/Modes/Odyssey/TravelBuff_Patch.cs new file mode 100644 index 0000000..df2122d --- /dev/null +++ b/Source/Patches/Modes/Odyssey/TravelBuff_Patch.cs @@ -0,0 +1,19 @@ +#if false +using HarmonyLib; + +namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey; + +[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); + } +} +#endif diff --git a/Source/Patches/Modes/Odyssey/TravelInvestMenu_Patch.cs b/Source/Patches/Modes/Odyssey/TravelInvestMenu_Patch.cs new file mode 100644 index 0000000..476adb7 --- /dev/null +++ b/Source/Patches/Modes/Odyssey/TravelInvestMenu_Patch.cs @@ -0,0 +1,24 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey; + +[HarmonyPatch(typeof(TravelInvestMenu))] +public static class TravelInvestMenu_Patch +{ + [HarmonyPatch(nameof(TravelInvestMenu.Start)), HarmonyPostfix] + private static void Start(TravelInvestMenu __instance) + { + var titleText = __instance.transform.Find("Title"); + var shadowText = titleText.GetComponent(); + + var regularText = titleText.transform.Find("Title2").GetComponent(); + regularText.text = StringStore.TranslateText(regularText.text); + + shadowText.text = Utils.RemoveColorTags(regularText.text); + } + + [HarmonyPatch(nameof(TravelInvestMenu.RefreshBuff)), HarmonyPostfix] + private static void RefreshBuff(TravelInvestMenu __instance, ref TravelBuffOptionButton option) => + TravelBuffOptionButton_Patch.TranslateOptionButton(option); +} diff --git a/Source/Patches/Modes/Odyssey/TravelLookBuff_Patch.cs b/Source/Patches/Modes/Odyssey/TravelLookBuff_Patch.cs new file mode 100644 index 0000000..c15256d --- /dev/null +++ b/Source/Patches/Modes/Odyssey/TravelLookBuff_Patch.cs @@ -0,0 +1,57 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; +using static PvZ_Fusion_Translator.Patches.Modes.Odyssey.TravelMgr_Patch; + +namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey; + +[HarmonyPatch(typeof(TravelLookBuff))] +public static class TravelLookBuff_Patch +{ + [HarmonyPatch(nameof(TravelLookBuff.Clear)), HarmonyPostfix] + public static void Post_Clear(TravelLookBuff __instance) + { + __instance.introduce.text = StringStore.TranslateText("无"); + __instance.set = false; + + foreach (var text in __instance.transform.FindChild("Images") + .FindChild("Button") + .GetComponentsInChildren()) + text.text = StringStore.TranslateText(text.text); + } + + [HarmonyPatch(nameof(TravelLookBuff.OnMouseUpAsButton)), HarmonyPostfix] + public static void Post_OnMouseUpAsButton(TravelLookBuff __instance) + { + foreach (var text in __instance.transform.FindChild("Images") + .FindChild("Button") + .GetComponentsInChildren()) + text.text = StringStore.TranslateText(text.text); + } + + [HarmonyPatch(nameof(TravelLookBuff.SetBuff)), HarmonyPostfix] + public static void Post_SetBuff(TravelLookBuff __instance) + { + /*SortedDictionary buffSet = translatedTravelBuffs[buffLinks[__instance.buffType]]; + string buffText = buffSet.ContainsKey(__instance.buffIndex) ? buffSet[__instance.buffIndex] : StringStore.TranslateText(__instance.introduce.text); + __instance.introduce.text = buffText;*/ + + foreach (var text in __instance.transform.FindChild("Images") + .FindChild("Introduce") + .GetComponentsInChildren()) + { + if (TravelBuffString.TryGetValue(text.text, out var translatedBuff)) + text.text = AddBuffName(translatedBuff); + + if (!Utils.CheckForUntranslatedText(text.text)) + text.text = AddBuffName(text.text); + + if (!TravelBuffString.ContainsKey(text.text) && Utils.CheckForUntranslatedText(text.text)) + text.text = StringStore.TranslateText(text.text); + } + + foreach (var text in __instance.transform.FindChild("Images") + .FindChild("Button") + .GetComponentsInChildren()) + text.text = StringStore.TranslateText(text.text); + } +} diff --git a/Source/Patches/Modes/Odyssey/TravelLookMenu_Patch.cs b/Source/Patches/Modes/Odyssey/TravelLookMenu_Patch.cs new file mode 100644 index 0000000..ad6f659 --- /dev/null +++ b/Source/Patches/Modes/Odyssey/TravelLookMenu_Patch.cs @@ -0,0 +1,42 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey; + +[HarmonyPatch(typeof(TravelLookMenu))] +public static class TravelLookMenu_Patch +{ +#pragma warning disable CA2211 + public static string SavedAssetString = ""; +#pragma warning restore CA2211 + [HarmonyPatch(nameof(TravelLookMenu.Start)), HarmonyPostfix] + private static void Postfix_Start(TravelLookMenu __instance) + { + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText(txt.text); + txt.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + + var quitButtonTransform = __instance.transform.Find("Quit"); + + foreach (var txt in quitButtonTransform.GetComponentsInChildren()) + { + txt.text = StringStore.TranslateText("合上"); + txt.font = FontStore.LoadTMPFont(Utils.Language.ToString()); + } + + __instance.treasureText.text = StringStore.TranslateText(__instance.treasureText.text); + SavedAssetString = __instance.treasureText.text; + } + + [HarmonyPatch(nameof(TravelLookMenu.Update)), HarmonyPostfix] + private static void Update(TravelLookMenu __instance) + { + if (SavedAssetString == __instance.treasureText.text) + return; + + __instance.treasureText.text = StringStore.TranslateText(__instance.treasureText.text); + SavedAssetString = __instance.treasureText.text; + } +} diff --git a/Source/Patches/Modes/Odyssey/TravelMgr_Patch.cs b/Source/Patches/Modes/Odyssey/TravelMgr_Patch.cs new file mode 100644 index 0000000..40ac83f --- /dev/null +++ b/Source/Patches/Modes/Odyssey/TravelMgr_Patch.cs @@ -0,0 +1,312 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey; + +public sealed class TravelBuffInfo(string nameA = "", string descA = "") +{ + public readonly string Name = nameA; + public readonly string Desc = descA; +} + +public sealed class TravelBuffSet +{ + public readonly SortedDictionary + AdvancedBuffs, + UltimateBuffs, + Debuffs, + Unlocks, + InvestmentBuffs; + + private readonly Dictionary> _travelBuffSets; + + public TravelBuffSet() + { + AdvancedBuffs = new(); + UltimateBuffs = new(); + Debuffs = new(); + Unlocks = new(); + InvestmentBuffs = new(); + + _travelBuffSets = new() + { + { "advancedBuffs", AdvancedBuffs }, + { "ultimateBuffs", UltimateBuffs }, + { "debuffs", Debuffs }, + { "unlocks", Unlocks }, + { "investmentBuffs", InvestmentBuffs }, + }; + } + + public SortedDictionary TryGet(string name) => + name switch + { + "advancedBuffs" => AdvancedBuffs, + "ultimateBuffs" => UltimateBuffs, + "debuffs" => Debuffs, + "unlocks" => Unlocks, + "investmentBuffs" => InvestmentBuffs, + _ => null, + }; + + public IEnumerator>> GetEnumerator() => + _travelBuffSets.Select(item => (item.Key, item.Value)).GetEnumerator(); +} + +[HarmonyPatch(typeof(TravelMgr))] +public static class TravelMgr_Patch +{ + public static readonly TravelBuffSet TemplateTravelBuffs = new(); + + public static readonly Dictionary TravelBuffString = new(); +#pragma warning disable CA2211 + public static TravelBuffSet DumpedTravelBuffs = new(); + + public static TravelBuffSet TranslatedTravelBuffs = new(); + + public static Dictionary BuffLinks = new() + { + { BuffType.AdvancedBuff, "advancedBuffs" }, + { BuffType.UltimateBuff, "ultimateBuffs" }, + { BuffType.Debuff, "debuffs" }, + { BuffType.UnlockPlant, "unlocks" }, + { BuffType.InvestmentBuff, "investmentBuffs" }, + }; +#pragma warning restore CA2211 + [HarmonyPatch(nameof(TravelMgr.GetText)), HarmonyPostfix] + public static void GetText(TravelMgr __instance, ref string result) + { + if (TravelBuffString.TryGetValue(result, out var value)) + result = value; + else if (TravelBuffString.ContainsKey(RemoveBuffName(result))) + result = TravelBuffString[RemoveBuffName(result)]; + else + result = StringStore.TranslateText(result); + } + + public static void DumpTravelBuffs() + { + TravelMgr.Instance.GetPlantBuffUnlockCount(PlantType.DoomGatling); + + DumpedTravelBuffs = new(); + TravelBuffString.Clear(); + + foreach (var pair in TravelDictionary.advancedBuffsText) + { + Utils.TryAdd(DumpedTravelBuffs.AdvancedBuffs, (int)pair.Key, new("", pair.Value)); + Utils.TryAdd(TravelBuffString, pair.Value, pair.Value); + } + + foreach (var pair in TravelDictionary.ultimateBuffsText) + { + Utils.TryAdd(DumpedTravelBuffs.UltimateBuffs, (int)pair.Key, new("", pair.Value)); + Utils.TryAdd(TravelBuffString, pair.Value, pair.Value); + } + + foreach (var pair in TravelDictionary.debuffData) + { + Utils.TryAdd(DumpedTravelBuffs.Debuffs, (int)pair.Key, new("", pair.Value.Item1)); + Utils.TryAdd(TravelBuffString, pair.Value.Item1, pair.Value.Item1); + } + + foreach (var pair in TravelDictionary.unlocksText) + { + Utils.TryAdd(DumpedTravelBuffs.Unlocks, (int)pair.Key, new("", pair.Value)); + Utils.TryAdd(TravelBuffString, pair.Value, pair.Value); + } + + foreach (var pair in TravelMgr.InvestBuffsData) + { + Utils.TryAdd( + DumpedTravelBuffs.InvestmentBuffs, + (int)pair.Key, + new("", pair.Value.Description) + ); + + Utils.TryAdd(TravelBuffString, pair.Value.Description, pair.Value.Description); + } + + File.WriteAllText( + Path.Combine(FileLoader.GetAssetDir(FileLoader.AssetType.Dumps), "travel_buffs.json"), + FileLoader.SerializeWithIndentation(DumpedTravelBuffs) + ); + + var translatedTravelBuffsPath = Path.Combine( + FileLoader.GetAssetDir(FileLoader.AssetType.Strings, Utils.Language), + "travel_buffs.json" + ); + + if (File.Exists(translatedTravelBuffsPath)) + return; + + File.WriteAllText(translatedTravelBuffsPath, FileLoader.SerializeWithIndentation(DumpedTravelBuffs)); + TranslatedTravelBuffs = DumpedTravelBuffs; + } + + //System.Text.Json.JsonSerializer.Deserialize>>(travelBuffsContent); + public static void GenerateTranslatedTravelBuffs(string travelBuffsContent) + { + if (!Core.IsInitialized) + return; + + DumpTravelBuffs(); + + var travelBuffs = Newtonsoft.Json.JsonConvert.DeserializeObject(travelBuffsContent); + TranslatedTravelBuffs = travelBuffs; + TravelBuffString.Clear(); + + foreach (var i in travelBuffs) + { + var originalBuffSet = DumpedTravelBuffs.TryGet(i.Item1); + + foreach (var (key, originalBuff) in originalBuffSet) + { + var translatedBuffSet = travelBuffs.TryGet(i.Item1); + + if (originalBuff.Desc != RemoveBuffName(originalBuff.Desc)) + continue; + + if (translatedBuffSet.TryGetValue(key, out var value)) + Utils.TryAdd(TravelBuffString, originalBuff.Desc, value.Desc); +#if false + var translatedBuffSet = travelBuffs[i.Key]; + + if (!translatedBuffSet.ContainsKey(j.Key)) + continue; + + string translatedBuff = travelBuffs[i.Key][j.Key]; + travelBuffString[originalBuff] = translatedBuff; +#endif + } + } + + var travelBuffsToSave = FileLoader.SerializeWithIndentation(TranslatedTravelBuffs); + var stringDir = FileLoader.GetAssetDir(FileLoader.AssetType.Strings, Utils.Language); + File.WriteAllText(Path.Combine(stringDir, "travel_buffs.json"), travelBuffsToSave); + } + + public static string MatchTravelBuff(string originalText) + { + var res = ""; + + foreach (var i in DumpedTravelBuffs) + { + foreach (var j in DumpedTravelBuffs.TryGet(i.Item1)) + if (j.Value.Desc == originalText || j.Value.Desc == RemoveBuffName(originalText)) + { + var translatedBuffSet = TranslatedTravelBuffs.TryGet(i.Item1); + + if (translatedBuffSet.TryGetValue(j.Key, out var value)) + res = value.Desc; + + break; + } + + if (res != "") + break; + } + + return res; + } + + public static string RemoveBuffName(string buffText) + { + var res = buffText; + var firstColon = res.IndexOf(":", StringComparison.Ordinal); + + if (firstColon > 0) + res = res[(firstColon + 1)..]; + + return res; + } + + public static readonly Dictionary ModifierNameDict = new() + { + { "advancedBuffs", "COMMON_MODIFIER_TAG" }, + { "ultimateBuffs", "EPIC_MODIFIER_TAG" }, + { "debuffs", "ZOMBIE_MODIFIER_TAG" }, + { "unlocks", "UNLOCK_MODIFIER_TAG" }, + { "investmentBuffs", "INVEST_MODIFIER_TAG" }, + }; + + public static readonly Dictionary FallbackNameDict = new() + { + { "COMMON_MODIFIER_TAG", "Common Modifier" }, + { "EPIC_MODIFIER_TAG", "Epic Modifier" }, + { "ZOMBIE_MODIFIER_TAG", "Zombie Modifier" }, + { "UNLOCK_MODIFIER_TAG", "Unlock Modifier" }, + { "INVEST_MODIFIER_TAG", "Investment Modifier" }, + }; + + public static string TranslateNameTag(string originalText) + { + var nameTag = ModifierNameDict[originalText]; + + return StringStore.TranslationString.ContainsKey(nameTag) + ? StringStore.TranslateText(nameTag) + : FallbackNameDict[nameTag]; + } + + public static ValueTuple FindBuffData(string buffText) + { + ValueTuple res = new(); + + foreach (var pair1 in TranslatedTravelBuffs) + { + foreach (var pair2 in pair1.Item2.Where(pair2 => buffText == pair2.Value.Desc)) + { + if (pair2.Value.Name != "") + { + res.Item1 = pair2.Value.Name; + res.Item4 = true; + } + else + { + res.Item1 = TranslateNameTag(pair1.Item1); + res.Item4 = false; + } + + res.Item2 = pair2.Key; + } + } + + foreach (var pair1 in DumpedTravelBuffs) + { + foreach (var pair2 in pair1.Item2.Where(pair2 => buffText == pair2.Value.Desc)) + { + (res.Item1, res.Item4) = pair2.Value.Name != "" + ? (pair2.Value.Name, true) + : (TranslateNameTag(pair1.Item1), false); + + res.Item2 = pair2.Key; + } + } + + var finalBuffText = TravelBuffString.TryGetValue(buffText, out var value) + ? value + : StringStore.TranslateText(buffText); + + res.Item3 = finalBuffText; + + return res; + } + + // public static string FallbackFBuffStr = "{0}: {1}"; + + public static string AddBuffName(string buffText) + { + var translatedBuff = buffText; + + if (Utils.CheckForUntranslatedText(buffText)) + if (TravelBuffString.TryGetValue(buffText, out var value)) + translatedBuff = value; + + var buffData = FindBuffData(translatedBuff); + + if (buffData is not { Item1: not null, Item3: not null }) + return translatedBuff; + + var buffFStr = StringStore.TranslationStringRegex.GetValueOrDefault("BUFF_NAME_FORMAT", "{0}: {1}"); + return string.Format(buffFStr, buffData.Item1, buffData.Item3); + } +} diff --git a/Source/Patches/Modes/Odyssey/TravelRefresh_Patch.cs b/Source/Patches/Modes/Odyssey/TravelRefresh_Patch.cs new file mode 100644 index 0000000..ae4aeca --- /dev/null +++ b/Source/Patches/Modes/Odyssey/TravelRefresh_Patch.cs @@ -0,0 +1,22 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey; + +[HarmonyPatch(typeof(TravelRefresh))] +public static class TravelRefresh_Patch +{ + [HarmonyPatch(nameof(TravelRefresh.Awake)), HarmonyPostfix] + private static void Awake(TravelRefresh __instance) + { + __instance.text = StringStore.TranslateText(__instance.text); + __instance.text_shadow = StringStore.TranslateText(__instance.text_shadow); + } + + [HarmonyPatch(nameof(TravelRefresh.OnMouseUpAsButton)), HarmonyPostfix] + private static void OnMouseUpAsButton(TravelRefresh __instance) + { + __instance.text = StringStore.TranslateText(__instance.text); + __instance.text_shadow = StringStore.TranslateText(__instance.text_shadow); + } +} diff --git a/Source/Patches/Modes/Odyssey/TravelStoreWindow_Patch.cs b/Source/Patches/Modes/Odyssey/TravelStoreWindow_Patch.cs new file mode 100644 index 0000000..dd7b489 --- /dev/null +++ b/Source/Patches/Modes/Odyssey/TravelStoreWindow_Patch.cs @@ -0,0 +1,81 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; +using System.Text.RegularExpressions; +using static PvZ_Fusion_Translator.Patches.Modes.Odyssey.TravelMgr_Patch; + +namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey; + +[HarmonyPatch(typeof(TravelStoreWindow))] +public static class TravelStoreWindow_Patch +{ + [HarmonyPatch(nameof(TravelStoreWindow.SetType)), HarmonyPostfix] + private static void SetType(TravelStoreWindow __instance) + { +#if false + var buffSet = translatedTravelBuffs[buffLinks[__instance.buffType]]; + + var buff = __instance.show != null && __instance.introduce.text != "词条已选完" + ? buffSet[__instance.buffIndex] + : StringStore.TranslateText("词条已选完"); +#endif + var originalText = __instance.introduce.text; + const string AffinityPattern = "([\\s\\S]+)(\\\n)([\\s\\S]+)(<\\/color>)"; + + if (Regex.IsMatch(__instance.introduce.text, AffinityPattern, RegexOptions.Singleline)) + { + var match = Regex.Match(__instance.introduce.text, AffinityPattern, RegexOptions.Singleline); + var startText = match.Groups[1].Value; + var affinityText = match.Groups[3].Value; + var affinities = TranslateAffinities(affinityText); + __instance.introduce.text = AddBuffName(startText) + affinities; + } + else + __instance.introduce.text = AddBuffName(originalText); + + foreach (var text in __instance.buttonText) + text.text = StringStore.TranslateText(text.text); + } + + [HarmonyPatch(nameof(TravelStoreWindow.UpdateButtonText)), HarmonyPostfix] + private static void UpdateButtonText(TravelStoreWindow __instance) + { + foreach (var text in __instance.buttonText) + text.text = StringStore.TranslateText(text.text); + } + + public static string TranslateAffinities(string originalText) + { + List translatedAffinities = []; + var lines = originalText.Split('\n'); + + foreach (var line in lines) + { + if (string.IsNullOrEmpty(line)) + continue; + + var fStr = StringStore.TranslationStringRegex.GetValueOrDefault("【([^\\s]+)】_IV", "[{0}]"); + + // Extract dynamic parts from the original text + var regex = new Regex("【([^\\s]+)】"); + var match = regex.Match(line); + var groupCount = match.Groups.Count; + + // List to hold formatted dynamic parts + List dynamicParts = []; + + // Loop through each group and determine its translation + for (var i = 1; i < groupCount; i++) + { + var groupValue = match.Groups[i].Value; + var translatedValue = StringStore.TranslationString.GetValueOrDefault(groupValue, groupValue); + dynamicParts.Add(translatedValue); + } + + // Format the output string with dynamic parts + var translatedAffinity = string.Format(fStr, [..dynamicParts]); + translatedAffinities.Add(translatedAffinity); + } + + return $"\n{string.Join("\n", translatedAffinities)}"; + } +} diff --git a/Source/Patches/Modes/Odyssey/TravelStore_Patch.cs b/Source/Patches/Modes/Odyssey/TravelStore_Patch.cs new file mode 100644 index 0000000..ecb75d7 --- /dev/null +++ b/Source/Patches/Modes/Odyssey/TravelStore_Patch.cs @@ -0,0 +1,60 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey; + +[HarmonyPatch(typeof(TravelStore))] +public static class TravelStore_Patch +{ + [HarmonyPatch(nameof(TravelStore.Start)), HarmonyPostfix] + private static void Start(TravelStore __instance) => TranslateStoreText(__instance); + + [HarmonyPatch(nameof(TravelStore.Update)), HarmonyPostfix] + private static void Update(TravelStore __instance) => TranslateStoreText(__instance); + + [HarmonyPatch(nameof(TravelStore.RefreshBuff)), HarmonyPostfix] + private static void RefreshBuff(TravelStore __instance) => TranslateStoreText(__instance); + + [HarmonyPatch(nameof(TravelStore.SelectBuff)), HarmonyPostfix] + private static void SelectBuff(TravelStore __instance, ref TravelStoreWindow window) + { + TranslateStoreText(__instance); + + foreach (var text in window.buttonText) + text.text = StringStore.TranslateText(text.text); + + __instance.investText.text = TranslateInvestText(__instance.investText.text); + __instance.investTextshadow.text = TranslateInvestText(__instance.investTextshadow.text); + } + + public static void TranslateStoreText(TravelStore __instance) + { + __instance.investText.text = TranslateInvestText(__instance.investText.text); + __instance.investTextshadow.text = TranslateInvestText(__instance.investTextshadow.text); + + foreach (var text in __instance.pointText) + text.text = StringStore.TranslateText(text.text); + + foreach (var text in __instance.refreshText) + text.text = StringStore.TranslateText(text.text); + + foreach (var text in __instance.transform.Find("Quit").GetComponentsInChildren()) + text.text = StringStore.TranslateText("合上"); + } + + public static string TranslateInvestText(string investText) + { + if (!Utils.CheckForUntranslatedText(investText)) + return investText; + + var investStats = investText.Split("\n\n"); + + var translatedInvestStats = investStats + .Select(investStat => investStat.Split("\n")) + .Select(lines => lines.Select(line => StringStore.TranslateColorText(line)).ToList()) + .Select(translatedLines => string.Join("\n", translatedLines)) + .ToList(); + + return string.Join("\n\n", translatedInvestStats); + } +} diff --git a/Source/Patches/Modes/Odyssey/TravelSynergyMenu_Patch.cs b/Source/Patches/Modes/Odyssey/TravelSynergyMenu_Patch.cs new file mode 100644 index 0000000..4dc3e29 --- /dev/null +++ b/Source/Patches/Modes/Odyssey/TravelSynergyMenu_Patch.cs @@ -0,0 +1,87 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; +using System.Text.RegularExpressions; + +namespace PvZ_Fusion_Translator.Patches.Modes.Odyssey; + +[HarmonyPatch(typeof(TravelSynergyMenu))] +public static class TravelSynergyMenu_Patch +{ + [HarmonyPatch(nameof(TravelSynergyMenu.Awake)), HarmonyPostfix] + public static void Awake(TravelSynergyMenu __instance) + { + var background = __instance.transform.Find("Background"); + var tip = __instance.transform.Find("Text (TMP)"); + + foreach (var text in background.GetComponentsInChildren()) + text.text = StringStore.TranslateText(text.text); + + foreach (var text in tip.GetComponentsInChildren()) + text.text = StringStore.TranslateText(text.text); + } +} + +[HarmonyPatch(typeof(SynergyNode))] +public static class SynergyNode_Patch +{ + [HarmonyPatch(nameof(SynergyNode.InitNode)), HarmonyPostfix] + public static void InitNode(SynergyNode __instance) + { + var firstNewlineIndex = __instance.synergyTitle.text.IndexOf("\n", StringComparison.Ordinal); + var title = __instance.synergyTitle.text[..firstNewlineIndex]; + var description = __instance.synergyTitle.text[(firstNewlineIndex + 1)..]; + description = description[..8] == "" ? description[8..] : description; + + const string Pattern = @"]+>[\s\S]*?(?:<\/color>|$)|(?:<(?!color=)|[^<])+"; + const string SmallPattern = "(]+>)(.*?)()"; + var matches = Regex.Matches(description, Pattern); + var translatedDescription = ""; + + foreach (Match match in matches) + { + var colorMatch = Regex.Match(match.Value, SmallPattern, RegexOptions.Singleline); + + if (colorMatch.Success) + translatedDescription += colorMatch.Groups[1].Value + + TranslateSegment(colorMatch.Groups[2].Value) + + colorMatch.Groups[3].Value; + else + translatedDescription += TranslateSegment(match.Value) + "\n"; + } + + __instance.synergyTitle.text = + "" + StringStore.TranslateColorText(title) + "\n" + translatedDescription; + } + + public static string TranslateSegment(string text) + { + var res = ""; + + var parts = SplitSecondNewLines(text); + + foreach (var part in parts) + { + var temp = ""; + var lines = part.Split('\n'); + + if (lines.Length > 1) + temp = StringStore.TranslateText(lines[0]) + "\n" + StringStore.TranslateText(lines[1]); + + res += temp + "\n"; + } + + return res[..^1]; + } + + public static List SplitSecondNewLines(string originalText) + { + var results = new List(); + + var lines = originalText.Split('\n'); + + for (var i = 0; i < lines.Length; i += 2) + results.Add(i + 1 < lines.Length ? lines[i] + "\n" + lines[i + 1] : lines[i]); + + return results; + } +} diff --git a/Source/Patches/Modes/Starbound/AdvantureEvolutionMenu_Patch.cs b/Source/Patches/Modes/Starbound/AdvantureEvolutionMenu_Patch.cs new file mode 100644 index 0000000..fb84b70 --- /dev/null +++ b/Source/Patches/Modes/Starbound/AdvantureEvolutionMenu_Patch.cs @@ -0,0 +1,51 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Starbound; + +[HarmonyPatch(typeof(AdvantureEvolutionMenu))] +public static class AdvantureEvolutionMenu_Patch +{ + [HarmonyPatch(nameof(AdvantureMenu.Awake)), HarmonyPostfix] + public static void Awake(AdvantureEvolutionMenu __instance) + { + foreach (var text in __instance.GetComponentsInChildren()) + text.text = StringStore.TranslateColorText(text.text); + + var baseWindow = __instance.transform.Find("BaseWindow"); + var advancedWindow = __instance.transform.Find("AdvancedWindow"); + + if (baseWindow != null) + foreach (var text in baseWindow.GetComponentsInChildren() + .Where(text => text.gameObject.name.Contains("Name"))) + text.text = Utils.GetPlantNameFromAlmanac(__instance.thePlantType); + + if (advancedWindow == null) + return; + + foreach (var text in advancedWindow.GetComponentsInChildren() + .Where(text => text.gameObject.name.Contains("Name"))) + text.text = Utils.GetPlantNameFromAlmanac(__instance.thePlantType); + } + + [HarmonyPatch(nameof(AdvantureEvolutionMenu.UpdateText)), HarmonyPostfix] + public static void UpdateText(AdvantureEvolutionMenu __instance) + { + foreach (var text in __instance.GetComponentsInChildren()) + text.text = StringStore.TranslateColorText(text.text); + } + + [HarmonyPatch(nameof(AdvantureEvolutionMenu.RollEvolution)), HarmonyPostfix] + public static void RollEvolution(AdvantureEvolutionMenu __instance) + { + foreach (var text in __instance.GetComponentsInChildren()) + text.text = StringStore.TranslateColorText(text.text); + } + + [HarmonyPatch(nameof(AdvantureEvolutionMenu.RollEvolutionGood)), HarmonyPostfix] + public static void RollEvolutionGood(AdvantureEvolutionMenu __instance) + { + foreach (var text in __instance.GetComponentsInChildren()) + text.text = StringStore.TranslateColorText(text.text); + } +} diff --git a/Source/Patches/Modes/Starbound/AdvantureHelpMenu_Patch.cs b/Source/Patches/Modes/Starbound/AdvantureHelpMenu_Patch.cs new file mode 100644 index 0000000..238f3ca --- /dev/null +++ b/Source/Patches/Modes/Starbound/AdvantureHelpMenu_Patch.cs @@ -0,0 +1,15 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Starbound; + +[HarmonyPatch(typeof(AdvantureHelpMenu))] +public static class AdvantureHelpMenu_Patch +{ + [HarmonyPatch(nameof(AdvantureHelpMenu.InitText)), HarmonyPostfix] + private static void InitText(AdvantureHelpMenu __instance) + { + foreach (var text in __instance.GetComponentsInChildren()) + text.text = StringStore.TranslateText(text.text); + } +} diff --git a/Source/Patches/Modes/Starbound/AdvantureMenu2_Patch.cs b/Source/Patches/Modes/Starbound/AdvantureMenu2_Patch.cs new file mode 100644 index 0000000..0b337ac --- /dev/null +++ b/Source/Patches/Modes/Starbound/AdvantureMenu2_Patch.cs @@ -0,0 +1,19 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Starbound; + +[HarmonyPatch(typeof(AdvantureMenu2))] +public static class AdvantureMenu2_Patch +{ + [HarmonyPatch(nameof(AdvantureMenu2.Awake)), HarmonyPostfix] + private static void Awake(AdvantureMenu2 __instance) + { + foreach (var text in __instance.GetComponentsInChildren()) + text.text = StringStore.TranslateText(text.text); + } + + [HarmonyPatch(nameof(AdvantureMenu2.AdjustDifficulty)), HarmonyPostfix] + private static void AdjustDifficulty(AdvantureMenu2 __instance) => + __instance.difficulty.text = StringStore.TranslateText(__instance.difficulty.text); +} diff --git a/Source/Patches/Modes/Starbound/AdvantureMenu_Patch.cs b/Source/Patches/Modes/Starbound/AdvantureMenu_Patch.cs new file mode 100644 index 0000000..5f2c077 --- /dev/null +++ b/Source/Patches/Modes/Starbound/AdvantureMenu_Patch.cs @@ -0,0 +1,43 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Starbound; + +[HarmonyPatch(typeof(AdvantureMenu))] +public static class AdvantureMenu_Patch +{ + [HarmonyPatch(nameof(AdvantureMenu.Start)), HarmonyPostfix] + private static void Start(AdvantureMenu __instance) => TranslateAdvantureMenu(__instance); + + [HarmonyPatch(nameof(AdvantureMenu.ChangeDifficulty)), HarmonyPostfix] + private static void ChangeDifficulty(AdvantureMenu __instance) => TranslateAdvantureMenu(__instance); + + [HarmonyPatch(nameof(AdvantureMenu.GetChapterDifficulty)), HarmonyPostfix] + private static void GetChapterDifficulty(AdvantureMenu __instance) => TranslateAdvantureMenu(__instance); + + [HarmonyPatch(nameof(AdvantureMenu.UpdateChapterDifficulty)), HarmonyPostfix] + private static void UpdateChapterDifficulty(AdvantureMenu __instance) => TranslateAdvantureMenu(__instance); + + [HarmonyPatch(nameof(AdvantureMenu.UpdateStarCount)), HarmonyPostfix] + private static void UpdateStarCount(AdvantureMenu __instance) => TranslateAdvantureMenu(__instance); + + public static void TranslateAdvantureMenu(AdvantureMenu __instance) + { + var hasSbString = StringStore.TranslationString.ContainsKey(__instance.difficulty.text + "_SB"); + + __instance.difficulty.text = Utils.RemoveSizeTags( + hasSbString + ? StringStore.TranslateText(__instance.difficulty.text + "_SB") + : StringStore.TranslateText(__instance.difficulty.text) + ); + + __instance.chapterDifficulty.text = StringStore.TranslateText(__instance.chapterDifficulty.text); + __instance.starCount.text = StringStore.TranslateText(__instance.starCount.text); + + foreach (var text in __instance.title) + text.text = StringStore.TranslateText(text.text); + + foreach (var text in __instance.GetComponentsInChildren()) + text.text = StringStore.TranslateText(text.text); + } +} diff --git a/Source/Patches/Modes/Starbound/AdvantureMissionMenu_Patch.cs b/Source/Patches/Modes/Starbound/AdvantureMissionMenu_Patch.cs new file mode 100644 index 0000000..0c1c55c --- /dev/null +++ b/Source/Patches/Modes/Starbound/AdvantureMissionMenu_Patch.cs @@ -0,0 +1,41 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Starbound; + +[HarmonyPatch(typeof(AdvantureMissionMenu))] +public static class AdvantureMissionMenu_Patch +{ + [HarmonyPatch(nameof(AdvantureMissionMenu.Awake)), HarmonyPostfix] + private static void Awake(AdvantureMissionMenu __instance) + { + foreach (var text in __instance.contant.GetComponentsInChildren()) + text.text = StringStore.TranslateColorText(text.text); +#if false + foreach (var text in __instance.GetComponentsInChildren()) + text.text = StringStore.TranslateText(text.text); +#endif + } + + [HarmonyPatch(nameof(AdvantureMissionMenu.InitText)), HarmonyPostfix] + private static void InitText(AdvantureMissionMenu __instance) + { + foreach (var text in __instance.contant.GetComponentsInChildren()) + text.text = StringStore.TranslateColorText(text.text); +#if false + foreach (var text in __instance.GetComponentsInChildren()) + text.text = StringStore.TranslateText(text.text); +#endif + } + + [HarmonyPatch(nameof(AdvantureMissionMenu.SwitchAward)), HarmonyPostfix] + private static void SwitchAward(AdvantureMissionMenu __instance) + { + foreach (var text in __instance.contant.GetComponentsInChildren()) + text.text = StringStore.TranslateColorText(text.text); +#if false + foreach (var text in __instance.GetComponentsInChildren()) + text.text = StringStore.TranslateText(text.text); +#endif + } +} diff --git a/Source/Patches/Modes/Starbound/AdvantureStarMenu_Patch.cs b/Source/Patches/Modes/Starbound/AdvantureStarMenu_Patch.cs new file mode 100644 index 0000000..6230b24 --- /dev/null +++ b/Source/Patches/Modes/Starbound/AdvantureStarMenu_Patch.cs @@ -0,0 +1,43 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Starbound; + +[HarmonyPatch(typeof(AdvantureStarMenu))] +public static class AdvantureStarMenu_Patch +{ + [HarmonyPatch(nameof(AdvantureStarMenu.Awake)), HarmonyPostfix] + private static void Awake(AdvantureStarMenu __instance) + { + foreach (var text in __instance.GetComponentsInChildren()) + text.text = StringStore.TranslateText(text.text); + } + + [HarmonyPatch(nameof(AdvantureStarMenu.GetNodes)), HarmonyPostfix] + private static void GetNodes(AdvantureStarMenu __instance) + { + foreach (var text in __instance.GetComponentsInChildren()) + text.text = StringStore.TranslateText(text.text); + } + + [HarmonyPatch(nameof(AdvantureStarMenu.UpdateStarText)), HarmonyPostfix] + private static void UpdateStarText(AdvantureStarMenu __instance) + { + foreach (var text in __instance.GetComponentsInChildren()) + text.text = StringStore.TranslateText(text.text); + } + + [HarmonyPatch(nameof(AdvantureStarMenu.InitTalents)), HarmonyPostfix] + private static void InitTalents(AdvantureStarMenu __instance) + { + foreach (var text in __instance.GetComponentsInChildren()) + text.text = StringStore.TranslateText(text.text); + } + + [HarmonyPatch(nameof(AdvantureStarMenu.ResetAward)), HarmonyPostfix] + private static void ResetAward(AdvantureStarMenu __instance) + { + foreach (var text in __instance.GetComponentsInChildren()) + text.text = StringStore.TranslateText(text.text); + } +} diff --git a/Source/Patches/Modes/Super Editor/CustomButton_enterGame_Patch.cs b/Source/Patches/Modes/Super Editor/CustomButton_enterGame_Patch.cs new file mode 100644 index 0000000..5ce9a45 --- /dev/null +++ b/Source/Patches/Modes/Super Editor/CustomButton_enterGame_Patch.cs @@ -0,0 +1,108 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; +using System.Text.Encodings.Web; +using System.Text.Json; + +namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor; + +[HarmonyPatch(typeof(CustomButton_enterGame))] +public static class CustomButtonEnterGamePatch +{ + [HarmonyPatch(nameof(CustomButton_enterGame.LoadOnlineLevelAsync)), HarmonyPostfix] + public static void LoadOnlineLevelAsync(CustomButton_enterGame __instance) + { + var dumpPath = Path.Combine(FileLoader.GetAssetDir(FileLoader.AssetType.Dumps), "custom_level_data.json"); + var dumpData = new Dictionary(); + + if (!File.Exists(dumpPath)) + File.WriteAllText( + dumpPath, + JsonSerializer.Serialize( + dumpData, + new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + } + ) + ); + + dumpData = JsonSerializer.Deserialize>(File.ReadAllText(dumpPath)); + + var dumpStringsPath = Path.Combine( + FileLoader.GetAssetDir(FileLoader.AssetType.Dumps), + "custom_level_strings.json" + ); + + var dumpStringsData = new Dictionary(); + + if (!File.Exists(dumpStringsPath)) + File.WriteAllText( + dumpStringsPath, + JsonSerializer.Serialize( + dumpStringsData, + new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + } + ) + ); + + dumpStringsData = JsonSerializer.Deserialize>(File.ReadAllText(dumpStringsPath)); + + if (__instance.onlineLevelInfo != null) + { + var levelId = __instance.onlineLevelInfo.levelId; + + if (levelId != null) + { + var serializedLevel = __instance.serializedLevel; + + if (CustomLevelMenu_Patch.TranslatedLevelData.TryGetValue(levelId, out var levelData)) + { + __instance.levelName.text = levelData.Name; + serializedLevel.name = levelData.Name; + serializedLevel.boardConfig.startTip = levelData.StartTip; + } + else + { + var dumpedLevelData = new TranslatedLevelData( + __instance.onlineLevelInfo.levelName, + serializedLevel.boardConfig.startTip + ); + + dumpData[levelId] = dumpedLevelData; + } + + // foreach(var _ in level.levelData.SerializedLevelData) + } + } + else + __instance.levelName.text = StringStore.TranslateText(__instance.levelName.text); + + File.WriteAllText( + dumpPath, + JsonSerializer.Serialize( + dumpData, + new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + } + ) + ); + + File.WriteAllText( + dumpStringsPath, + JsonSerializer.Serialize( + dumpStringsData, + new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + } + ) + ); + } +} diff --git a/Source/Patches/Modes/Super Editor/CustomLevelMenu_Patch.cs b/Source/Patches/Modes/Super Editor/CustomLevelMenu_Patch.cs new file mode 100644 index 0000000..11ba24b --- /dev/null +++ b/Source/Patches/Modes/Super Editor/CustomLevelMenu_Patch.cs @@ -0,0 +1,164 @@ +using HarmonyLib; +using Newtonsoft.Json; +using PvZ_Fusion_Translator.AssetStore; +using System.Text.Encodings.Web; +using System.Text.Json; + +namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor; + +[HarmonyPatch(typeof(CustomLevelMenu))] +public static class CustomLevelMenu_Patch +{ +#pragma warning disable CA2211 + public static float RequestTimer; + + public static Dictionary TranslatedLevelData = new(); +#pragma warning restore CA2211 + [HarmonyPatch(nameof(CustomLevelMenu.LoadOnlineFiles)), HarmonyPostfix] + public static void LoadOnlineFiles(CustomLevelMenu __instance) + { + if (!Core.Instance.ConfigUseLocal.Value) + LoadOnlineData(); + else + LoadLocalData(); + } + + [HarmonyPatch(nameof(CustomLevelMenu.InitLocalWindows)), HarmonyPostfix] + public static void InitWindows(CustomLevelMenu __instance) => TranslateLevelButtons(__instance); + + [HarmonyPatch(nameof(CustomLevelMenu.InitOnlineWindow)), HarmonyPostfix] + public static void InitOnlineWindow(CustomLevelMenu __instance) => TranslateLevelButtons(__instance); + + [HarmonyPatch(nameof(CustomLevelMenu.ReloadFiles)), HarmonyPostfix] + public static void ReloadFiles(CustomLevelMenu __instance) => TranslateLevelButtons(__instance); + + public static void TranslateLevelButtons(CustomLevelMenu __instance) + { + var dumpPath = Path.Combine(FileLoader.GetAssetDir(FileLoader.AssetType.Dumps), "custom_level_data.json"); + var dumpData = new Dictionary(); + + if (!File.Exists(dumpPath)) + File.WriteAllText( + dumpPath, + System.Text.Json.JsonSerializer.Serialize( + dumpData, + new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + } + ) + ); + + foreach (var level in __instance.levels) + if (level.onlineLevelInfo != null) + { + var levelId = level.onlineLevelInfo.levelId; + + if (levelId == null) + continue; + + if (TranslatedLevelData.TryGetValue(levelId, out var levelData)) + { + level.levelName.text = levelData.Name; + level.serializedLevel.name = levelData.Name; + level.serializedLevel.boardConfig.startTip = levelData.StartTip; + } + else + { + var dumpedLevelData = new TranslatedLevelData( + level.onlineLevelInfo.levelName, + level.serializedLevel.boardConfig.startTip + ); + + dumpData.Add(levelId, dumpedLevelData); + } + } + else + level.levelName.text = StringStore.TranslateText(level.levelName.text); + + File.WriteAllText( + dumpPath, + System.Text.Json.JsonSerializer.Serialize( + dumpData, + new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + } + ) + ); + } + + public static async Task> GetTranslatedLevelData() + { + var levelDataString = await Utils.GetDataFromWeb( + $"https://raw.githubusercontent.com/Teyliu/PVZF-Translation/refs/heads/main/PvZ_Fusion_Translator/Localization/{Utils.Language}/Strings/custom_level_data.json" + ); + + if (levelDataString != null) + { + var levelDataJson = JsonConvert.DeserializeObject>(levelDataString); + return levelDataJson; + } + + new CancellationTokenSource().Cancel(); + return null; + } + + public static void LoadOnlineData() + { + if (RequestTimer > 0) + { + Log.LogInfo( + $"Please wait before requesting levels again! Current cooldown: {Math.Round(RequestTimer, 3)}s" + ); + + return; + } + + // 5 seconds between request attempts to prevent any issues with GitHub + RequestTimer = 5f; + TranslatedLevelData = new(); + + var translatedLevelDataRequest = Task.Run(GetTranslatedLevelData); + + if (translatedLevelDataRequest.Result == null) + { + Log.LogError($"Couldn't find level data for {Utils.Language}!"); + return; + } + + TranslatedLevelData = translatedLevelDataRequest.Result; + Log.LogInfo($"Successfully loaded level data for {Utils.Language}!"); + } + + public static void LoadLocalData() + { + TranslatedLevelData = new(); + + var assetDir = Path.Combine( + FileLoader.GetAssetDir(FileLoader.AssetType.Strings, Utils.Language), + "custom_level_data.json" + ); + + if (!File.Exists(assetDir)) + { + File.CreateText(assetDir); + File.WriteAllText(assetDir, "{}"); + } + + var levelDataString = File.ReadAllText(assetDir); + var levelDataJson = JsonConvert.DeserializeObject>(levelDataString); + TranslatedLevelData = levelDataJson; + } +} + +public sealed class TranslatedLevelData(string name, string startTip) +{ + // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Global + public string Name { get; set; } = name; + + // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Global + public string StartTip { get; set; } = startTip; +} diff --git a/Source/Patches/Modes/Super Editor/CustomMenuPage_event_Patch_B.cs b/Source/Patches/Modes/Super Editor/CustomMenuPage_event_Patch_B.cs new file mode 100644 index 0000000..6b8bb3d --- /dev/null +++ b/Source/Patches/Modes/Super Editor/CustomMenuPage_event_Patch_B.cs @@ -0,0 +1,17 @@ +#if false +using HarmonyLib; +using PvZ_Fusion_Translator.Patches.Modes.Super_Editor.GameLevel.EventNodes; + +namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor; + +[HarmonyPatch(typeof(CustomMenuPage_event))] // ReSharper disable once InconsistentNaming +public static class CustomMenuPage_event_Patch +{ + [HarmonyPatch(nameof(CustomMenuPage_event.InitializeNodeEditor)), HarmonyPostfix] + public static void InitializeNodeEditor(CustomMenuPage_event __instance) + { + RuntimeEventNodeEditor_Patch.Update(__instance.nodeEditor); + NodeInfoPanel_Patch.UpdatePanelContent(__instance.nodeInfoPanel); + } +} +#endif diff --git a/Source/Patches/Modes/Super Editor/CustomMenuPage_initZombies_Patch.cs b/Source/Patches/Modes/Super Editor/CustomMenuPage_initZombies_Patch.cs new file mode 100644 index 0000000..de0e9ae --- /dev/null +++ b/Source/Patches/Modes/Super Editor/CustomMenuPage_initZombies_Patch.cs @@ -0,0 +1,16 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor; + +[HarmonyPatch(typeof(CustomMenuPage_initZombies))] +public static class CustomMenuPageInitZombiesPatch +{ + [HarmonyPatch(nameof(CustomMenuPage_initZombies.SubWave)), HarmonyPostfix] + public static void SubWave(CustomMenuPage_initZombies __instance) => + __instance.currentWaveText.text = StringStore.TranslateText(__instance.currentWaveText.text); + + [HarmonyPatch(nameof(CustomMenuPage_initZombies.AddWave)), HarmonyPostfix] + public static void AddWave(CustomMenuPage_initZombies __instance) => + __instance.currentWaveText.text = StringStore.TranslateText(__instance.currentWaveText.text); +} diff --git a/Source/Patches/Modes/Super Editor/CustomMenuPage_page3_Patch.cs b/Source/Patches/Modes/Super Editor/CustomMenuPage_page3_Patch.cs new file mode 100644 index 0000000..669e2e1 --- /dev/null +++ b/Source/Patches/Modes/Super Editor/CustomMenuPage_page3_Patch.cs @@ -0,0 +1,22 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor; + +[HarmonyPatch(typeof(CustomMenu_page3))] +public static class CustomMenuPagePage3Patch +{ + [HarmonyPatch(nameof(CustomMenu_page3.UpdateCardsText)), HarmonyPostfix] + public static void UpdateCardsText(CustomMenu_page3 __instance) + { + var plantName = Utils.GetPlantNameFromAlmanac(__instance.nameText.text); + __instance.nameText.text = plantName != "" ? plantName : StringStore.TranslateText(__instance.nameText.text); + } + + [HarmonyPatch(nameof(CustomMenu_page3.UpdateAdvancedInfo)), HarmonyPostfix] + public static void UpdateAdvancedInfo(CustomMenu_page3 __instance) + { + var plantName = Utils.GetPlantNameFromAlmanac(__instance.nameText.text); + __instance.nameText.text = plantName != "" ? plantName : StringStore.TranslateText(__instance.nameText.text); + } +} diff --git a/Source/Patches/Modes/Super Editor/CustomMenuPage_shooting_Patch.cs b/Source/Patches/Modes/Super Editor/CustomMenuPage_shooting_Patch.cs new file mode 100644 index 0000000..4fcb3d2 --- /dev/null +++ b/Source/Patches/Modes/Super Editor/CustomMenuPage_shooting_Patch.cs @@ -0,0 +1,33 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor; + +[HarmonyPatch(typeof(CustomMenuPage_shooting))] +public static class CustomMenuPageShootingPatch +{ + [HarmonyPatch(nameof(CustomMenuPage_shooting.CreateRoute)), HarmonyPostfix] + public static void CreateRoute(CustomMenuPage_shooting __instance) => TranslateRoutes(__instance); + + [HarmonyPatch(nameof(CustomMenuPage_shooting.CreateStage)), HarmonyPostfix] + public static void CreateStage(CustomMenuPage_shooting __instance) => TranslateRoutes(__instance); + + [HarmonyPatch(nameof(CustomMenuPage_shooting.Awake)), HarmonyPostfix] + public static void Awake(CustomMenuPage_shooting __instance) => TranslateRoutes(__instance); + + [HarmonyPatch(nameof(CustomMenuPage_shooting.SearchRoute)), HarmonyPostfix] + public static void SearchRoute(CustomMenuPage_shooting __instance) => TranslateRoutes(__instance); + + [HarmonyPatch(nameof(CustomMenuPage_shooting.SearchAllRoute)), HarmonyPostfix] + public static void SearchAllRoute(CustomMenuPage_shooting __instance) => TranslateRoutes(__instance); + + public static void TranslateRoutes(CustomMenuPage_shooting __instance) + { + foreach (var text in __instance.scollContent.GetComponentsInChildren()) + if (text.name == "PlantText") + { + var plantName = Utils.GetPlantNameFromAlmanac(text.text); + text.text = plantName != "" ? plantName : StringStore.TranslateText(text.text); + } + } +} diff --git a/Source/Patches/Modes/Super Editor/CustomOnlineMenu_Patch.cs b/Source/Patches/Modes/Super Editor/CustomOnlineMenu_Patch.cs new file mode 100644 index 0000000..9ed876c --- /dev/null +++ b/Source/Patches/Modes/Super Editor/CustomOnlineMenu_Patch.cs @@ -0,0 +1,70 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; +using System.Text.Encodings.Web; +using System.Text.Json; + +namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor; + +[HarmonyPatch(typeof(CustomOnlineMenu))] +public static class CustomOnlineMenu_Patch +{ + [HarmonyPatch(nameof(CustomOnlineMenu.EditLevel)), HarmonyPostfix] + public static void EditLevel(CustomOnlineMenu __instance) => TranslateLevelName(__instance); + + [HarmonyPatch(nameof(CustomOnlineMenu.Start)), HarmonyPostfix] + public static void Start(CustomOnlineMenu __instance) => TranslateLevelName(__instance); + + public static void TranslateLevelName(CustomOnlineMenu __instance) + { + var translatedText = StringStore.TranslateText(__instance.title.text); + __instance.title.text = translatedText; + __instance.title2.text = translatedText; + + TranslateLevelData(__instance.levelData); + } + + public static void TranslateLevelData(CustomLevelData levelData) + { + var dumpData = new Dictionary(); + + if (levelData != null) + { + var levelId = levelData.levelId; + + if (levelId != null) + { + if (CustomLevelMenu_Patch.TranslatedLevelData.TryGetValue(levelId, out var translatedLevelData)) + { + levelData.Name = translatedLevelData.Name; + levelData.SerializedLevelData.name = translatedLevelData.Name; + levelData.SerializedLevelData.boardConfig.startTip = translatedLevelData.StartTip; + } + else + { + var dumpedLevelData = new TranslatedLevelData( + levelData.Name, + levelData.SerializedLevelData.boardConfig.startTip + ); + + dumpData.Add(levelId, dumpedLevelData); + } + } + } + else + levelData.Name = StringStore.TranslateText(levelData.Name); + + var dumpPath = Path.Combine(FileLoader.GetAssetDir(FileLoader.AssetType.Dumps), "custom_level_data.json"); + + File.WriteAllText( + dumpPath, + JsonSerializer.Serialize( + dumpData, + new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + } + ) + ); + } +} diff --git a/Source/Patches/Modes/Super Editor/GameLevel/EventNodes/RuntimeEventNodeEditor_Patch.cs b/Source/Patches/Modes/Super Editor/GameLevel/EventNodes/RuntimeEventNodeEditor_Patch.cs new file mode 100644 index 0000000..c3537fe --- /dev/null +++ b/Source/Patches/Modes/Super Editor/GameLevel/EventNodes/RuntimeEventNodeEditor_Patch.cs @@ -0,0 +1,43 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; +using PvZ_Fusion_Translator.Patches.BaseTextObjects; + +namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor.GameLevel.EventNodes; + +[HarmonyPatch(typeof(RuntimeEventNodeEditor))] +public static class RuntimeEventNodeEditor_Patch +{ + public static TMP_FontAsset FontAsset => FontStore.LoadTMPFont(Utils.Language.ToString()); + + [HarmonyPatch(nameof(RuntimeEventNodeEditor.Update)), HarmonyPostfix] + public static void Update(RuntimeEventNodeEditor __instance) + { + // Translate the new screens. (version 3.7) + TranslateFullTransform(__instance.nodeInfoPanel.transform); + TranslateFullTransform(__instance.attributePanel.transform); + TranslateFullTransform(__instance.canvas.transform); + + if (__instance.TryGetComponent(out var eventNodeContextMenu)) + TranslateFullTransform(eventNodeContextMenu.transform); + } + + public static void TranslateFullTransform(Transform transform) + { + if (transform == null) + return; + + foreach (var txt in transform.GetComponentsInChildren()) + { + txt.text = RuntimeNodeUI_Patch.TranslateCodeText(txt.text); + txt.font = FontAsset; + } + + foreach (var inputField in transform.GetComponentsInChildren()) + { + TMP_InputField_Patch.OnEnable(inputField); + + foreach (var txt in inputField.GetComponentsInChildren(true)) + txt.text = RuntimeNodeUI_Patch.TranslateCodeText(txt.text); + } + } +} diff --git a/Source/Patches/Modes/Super Editor/GameLevel/EventNodes/RuntimeNodeUI_Patch.cs b/Source/Patches/Modes/Super Editor/GameLevel/EventNodes/RuntimeNodeUI_Patch.cs new file mode 100644 index 0000000..91985f0 --- /dev/null +++ b/Source/Patches/Modes/Super Editor/GameLevel/EventNodes/RuntimeNodeUI_Patch.cs @@ -0,0 +1,119 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; +using PvZ_Fusion_Translator.Patches.BaseTextObjects; + +namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor.GameLevel.EventNodes; + +[HarmonyPatch(typeof(RuntimeNodeUI))] +public static class RuntimeNodeUI_Patch +{ + [HarmonyPatch(nameof(RuntimeNodeUI.Awake)), HarmonyPatch(nameof(RuntimeNodeUI.CreatePorts)), + HarmonyPatch(nameof(RuntimeNodeUI.CreateValueEditUI)), HarmonyPatch(nameof(RuntimeNodeUI.GetPortUI)), + HarmonyPatch(nameof(RuntimeNodeUI.UpdateDisplay)), HarmonyPatch(nameof(RuntimeNodeUI.UpdateSelectionVisual)), + HarmonyPatch(nameof(RuntimeNodeUI.UpdateVisable)), HarmonyPostfix] + public static void Post_UpdateDisplay(RuntimeNodeUI __instance) + { + if (!__instance.isActiveAndEnabled) + return; + + if (__instance.Node == null) + return; + + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + __instance.titleText.text = TranslateCodeText(__instance.titleText.text); + __instance.titleText.font = fontAsset; + + foreach (var txt in __instance.inputPortsContainer.GetComponentsInChildren()) + { + txt.text = TranslateCodeText(txt.text); + txt.font = fontAsset; + } + + foreach (var txt in __instance.outputPortsContainer.GetComponentsInChildren()) + { + txt.text = TranslateCodeText(txt.text); + txt.font = fontAsset; + } + + if ( + __instance.GetComponentsInChildren().Count == 0 && + __instance.GetComponentsInChildren().Count == 0 && + __instance.Node.nodeType != "PlantTypeValueNode" && + __instance.Node.nodeType != "SinglePlantTypeListNode" && + __instance.Node.nodeType != "ZombieTypeValueNode" + ) + return; + + if (__instance.Node != null) + { + if (__instance.Node.nodeType == "PlantTypeValueNode") + foreach (var txt in __instance.GetComponentsInChildren()) + if (txt.gameObject.name.Contains("Label")) + if (Utils.CheckForUntranslatedText(txt.text)) + { + var castedNode = __instance.Node.TryCast(); + + if (castedNode == null) + continue; + + _ = castedNode.value_PortName; + var plantName = Utils.GetPlantNameFromAlmanac(castedNode.value, true); + txt.text = plantName != "" ? plantName : StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + + if (__instance.Node.nodeType == "SinglePlantTypeListNode") + foreach (var txt in __instance.GetComponentsInChildren()) + if (txt.gameObject.name.Contains("Label")) + if (Utils.CheckForUntranslatedText(txt.text)) + { + var castedNode = __instance.Node.TryCast(); + + if (castedNode == null) + continue; + + _ = castedNode.plantTypeList_PortName; + var plantName = Utils.GetPlantNameFromAlmanac(castedNode.plantType, true); + txt.text = plantName != "" ? plantName : StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + + if (__instance.Node.nodeType == "ZombieTypeValueNode") + foreach (var txt in __instance.GetComponentsInChildren()) + if (txt.gameObject.name.Contains("Label")) + if (Utils.CheckForUntranslatedText(txt.text)) + { + var castedNode = __instance.Node.TryCast(); + + if (castedNode == null) + continue; + + _ = castedNode.value_PortName; + var zombieName = Utils.GetZombieNameFromAlmanac(castedNode.value, true); + txt.text = zombieName != "" ? zombieName : StringStore.TranslateText(txt.text); + txt.font = fontAsset; + } + } + + if (__instance.GetComponentsInChildren().Count > 0) + foreach (var dropdown in __instance.GetComponentsInChildren()) + TMP_Dropdown_Patch.CreateDropdownList(dropdown); + + if (__instance.GetComponentsInChildren().Count <= 0) + return; + + foreach (var inputField in __instance.GetComponentsInChildren()) + { + TMP_InputField_Patch.OnEnable(inputField); + + foreach (var txt in inputField.GetComponentsInChildren(true)) + txt.text = TranslateCodeText(txt.text); + } + } + + public static string TranslateCodeText(string originalText) => + StringStore.TranslationString.ContainsKey(originalText + "_code") + ? StringStore.TranslateText(originalText + "_code") + : StringStore.TranslateText(originalText); +} diff --git a/Source/Patches/Modes/Super Editor/GameLevel/LevelManager_Patch.cs b/Source/Patches/Modes/Super Editor/GameLevel/LevelManager_Patch.cs new file mode 100644 index 0000000..9564f0f --- /dev/null +++ b/Source/Patches/Modes/Super Editor/GameLevel/LevelManager_Patch.cs @@ -0,0 +1,317 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; +using System.Text.Encodings.Web; +using System.Text.Json; + +namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor.GameLevel; + +[HarmonyPatch(typeof(LevelManager))] +public static class LevelManager_Patch +{ + [HarmonyPatch(nameof(LevelManager.SaveLevelData)), HarmonyPrefix] + public static void Pre_SaveLevelData(LevelManager __instance, ref SerializedLevelData serializedLevelData) + { + if (serializedLevelData.name == "未命名关卡") + serializedLevelData.name = StringStore.TranslationString.ContainsKey("LEVEL_UNNAMED") + ? StringStore.TranslateText("LEVEL_UNNAMED") + : "Unnamed"; + } + + public static void ExportLevelStrings(SerializedLevelData serializedLevelData) + { + var levelDataString = JsonUtility.ToJson(serializedLevelData); + var referenceLevelData = Newtonsoft.Json.JsonConvert.DeserializeObject(levelDataString); + var eventNodeGraph = serializedLevelData.eventNodeGraph; + eventNodeGraph.BuildCache(); + + var stringValueNodeIds = new List(); + var stringConcatNodeIds = new List(); + var showTextNodeIds = new List(); + var addOptionNodeIds = new List(); + + foreach (var reference in referenceLevelData.References.RefIds) + { + var nodeType = reference.Data.NodeType; + var nodeId = reference.Data.NodeId; + + switch (nodeType) + { + case "ShowTextNode": + if (!showTextNodeIds.Contains(nodeId)) + showTextNodeIds.Add(nodeId); + + break; + case "AddMultipleChoiceOptionNode": + if (!addOptionNodeIds.Contains(nodeId)) + addOptionNodeIds.Add(nodeId); + + break; + } + } + + foreach (var reference in referenceLevelData.References.RefIds) + { + var nodeType = reference.Data.NodeType; + var nodeId = reference.Data.NodeId; + + switch (nodeType) + { + case "StringValueNode": + case "FloatToStringNode": + case "StringConcatNode": + stringValueNodeIds.Add(nodeId); + + if (nodeType == "StringConcatNode") + stringConcatNodeIds.Add(nodeId); + + break; + } + } + + Dictionary> stringConcatNodePairs = new(); + + foreach (var connection in eventNodeGraph.connections) + { + var sourceNodeId = connection.sourceNodeId; + _ = connection.sourcePortName; + var targetNodeId = connection.targetNodeId; + var targetPortName = connection.targetPortName; + + if (!stringValueNodeIds.Contains(sourceNodeId)) + continue; + + if (!stringConcatNodeIds.Contains(targetNodeId)) + continue; + + if (stringConcatNodePairs.ContainsKey(targetNodeId)) + { + var temp = stringConcatNodePairs[targetNodeId]; + + switch (targetPortName) + { + case "A": + temp.Item1 = sourceNodeId; + stringConcatNodePairs[targetNodeId] = temp; + break; + case "B": + temp.Item2 = sourceNodeId; + stringConcatNodePairs[targetNodeId] = temp; + break; + } + } + else + { + stringConcatNodePairs.Add(targetNodeId, new()); + var temp = stringConcatNodePairs[targetNodeId]; + + switch (targetPortName) + { + case "A": + temp.Item1 = sourceNodeId; + stringConcatNodePairs[targetNodeId] = temp; + break; + case "B": + temp.Item2 = sourceNodeId; + stringConcatNodePairs[targetNodeId] = temp; + break; + } + } + } + + string GetStringNodeValue(EventNodeBase eventNodeBase) + { + var stringValue = ""; + + switch (eventNodeBase.nodeType) + { + case "StringValueNode": + var stringNode = eventNodeBase.Cast(); + stringValue = stringNode.value; + break; + case "FloatToStringNode": + stringValue = "([^\\s]+)"; + break; + case "StringConcatNode": + var stringConcatNode = eventNodeBase.Cast(); + stringConcatNode.InitializeConnections(eventNodeGraph); + + stringValue = GetStringNodeValue(stringConcatNode.aSourceNode) + + GetStringNodeValue(stringConcatNode.bSourceNode); + + break; + } + + return stringValue; + } + + var baseDumpDir = FileLoader.GetAssetDir(FileLoader.AssetType.Dumps); + var levelDumpDir = Path.Combine(baseDumpDir, "CustomLevels.json"); + + if (!File.Exists(levelDumpDir)) + File.WriteAllText(levelDumpDir, "{}"); + + var dump = JsonSerializer.Deserialize>(File.ReadAllText(levelDumpDir)); + + foreach (var showTextNode in showTextNodeIds + .Select(showTextNodeId => eventNodeGraph.GetNodeById(showTextNodeId).Cast())) + { + showTextNode.InitializeConnections(eventNodeGraph); + var value = GetStringNodeValue(showTextNode.textSourceNode); + dump.TryAdd(value, value); + } + + foreach (var addOptionNode in addOptionNodeIds.Select( + addOptionId => eventNodeGraph.GetNodeById(addOptionId).Cast() + )) + { + addOptionNode.InitializeConnections(eventNodeGraph); + var titleValue = GetStringNodeValue(addOptionNode.titleSourceNode); + dump.TryAdd(titleValue, titleValue); + var descriptionValue = GetStringNodeValue(addOptionNode.descriptionSourceNode); + dump.TryAdd(descriptionValue, descriptionValue); + } + + File.WriteAllText( + levelDumpDir, + JsonSerializer.Serialize( + dump, + new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + } + ) + ); + } + + // Reference level data classes. + public sealed class ReferenceLevelData + { + public References References { get; set; } + } + + // ReSharper disable once ClassNeverInstantiated.Global + public sealed class Data + { + public string NodeId { get; set; } + + public string NodeType { get; set; } + + public Position Position { get; set; } + + public string NodeName { get; set; } + + public string PlantPortName { get; set; } + + public string ColumnPortName { get; set; } + + public string RowPortName { get; set; } + + public string PlantTypePortName { get; set; } + + public object Value { get; set; } + + public string ValuePortName { get; set; } + + public string PlantTypeAPortName { get; set; } + + public string PlantTypeBPortName { get; set; } + + public string EqualPortName { get; set; } + + public string TriggerPortName { get; set; } + + public string CountPortName { get; set; } + + public string OutputPortName { get; set; } + + public string IndexPortName { get; set; } + + public string PlantsPortName { get; set; } + + public string PlantListPortName { get; set; } + + public string LoopBodyPortName { get; set; } + + public string CurrentPlantPortName { get; set; } + + public string CurrentIndexPortName { get; set; } + + public string OnCompletedPortName { get; set; } + + public string ConditionPortName { get; set; } + + public string ThenPortName { get; set; } + + public string ElsePortName { get; set; } + + public string APortName { get; set; } + + public string BPortName { get; set; } + + public string ResultPortName { get; set; } + + public string ShouldResetPortName { get; set; } + + public string OnCountPortName { get; set; } + + public int? StartValue { get; set; } + + public string ValueAPortName { get; set; } + + public string ValueBPortName { get; set; } + + public string GreaterPortName { get; set; } + + public string LessPortName { get; set; } + + public string DisplayText { get; set; } + + public double? Duration { get; set; } + + public string TextPortName { get; set; } + + public string DurationPortName { get; set; } + + public string INTPortName { get; set; } + + public string FloatPortName { get; set; } + } + + // ReSharper disable once ClassNeverInstantiated.Global + public sealed class Position + { + public double X { get; set; } + + public double Y { get; set; } + } + + // ReSharper disable once ClassNeverInstantiated.Global + public sealed class References + { + public int Version { get; set; } + + // ReSharper disable once CollectionNeverUpdated.Global + public List RefIds { get; set; } + } + + // ReSharper disable once ClassNeverInstantiated.Global + public sealed class RefId + { + public int Rid { get; set; } + + public Type Type { get; set; } + + public Data Data { get; set; } + } + + // ReSharper disable once ClassNeverInstantiated.Global + public sealed class Type + { + public string Class { get; set; } + + public string Ns { get; set; } + + public string ASM { get; set; } + } +} diff --git a/Source/Patches/Modes/Super Editor/RhythmGame/RhythmGameChartEditorUI_Patch.cs b/Source/Patches/Modes/Super Editor/RhythmGame/RhythmGameChartEditorUI_Patch.cs new file mode 100644 index 0000000..67c9090 --- /dev/null +++ b/Source/Patches/Modes/Super Editor/RhythmGame/RhythmGameChartEditorUI_Patch.cs @@ -0,0 +1,66 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor.RhythmGame; + +[HarmonyPatch(typeof(RhythmGameChartEditorUI))] +public static class RhythmGameChartEditorUI_Patch +{ + [HarmonyPatch(nameof(RhythmGameChartEditorUI.Awake)), HarmonyPostfix] + public static void Awake(RhythmGameChartEditorUI __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.GetComponentsInChildren()) + { + txt.font = fontAsset; + + if (!Utils.CheckForUntranslatedText(txt.text)) + continue; + + txt.text = StringStore.TranslateText(txt.text); + } + + foreach (var txt in __instance.dropdown.GetComponentsInChildren(true)) + txt.text = StringStore.TranslateText(txt.text); + } + + [HarmonyPatch(nameof(RhythmGameChartEditorUI.Start)), HarmonyPostfix] + public static void Start(RhythmGameChartEditorUI __instance) => Awake(__instance); + + [HarmonyPatch(nameof(RhythmGameChartEditorUI.InitializeSubSystems)), HarmonyPostfix] + public static void InitializeSubSystems(RhythmGameChartEditorUI __instance) => Awake(__instance); + + [HarmonyPatch(nameof(RhythmGameChartEditorUI.Update)), HarmonyPostfix] + public static void Update(RhythmGameChartEditorUI __instance) + { + var fontAsset = FontStore.LoadTMPFont(Utils.Language.ToString()); + + foreach (var txt in __instance.transform.Find("TopPanel").GetComponentsInChildren()) + { + txt.font = fontAsset; + txt.text = StringStore.TranslateText(txt.text); + } + + foreach (var txt in __instance.transform.GetComponentsInChildren() + .SelectMany( + b => b.GetComponentsInChildren().Where(t => Utils.CheckForUntranslatedText(t.text)) + )) + txt.text = StringStore.TranslateText(txt.text); + + foreach (var txt in __instance.dropdown.GetComponentsInChildren(true) + .Where(txt => Utils.CheckForUntranslatedText(txt.text))) + txt.text = Utils.RemoveSizeTags(StringStore.TranslateText(txt.text)); + } + + [HarmonyPatch(nameof(RhythmGameChartEditorUI.UpdateUI)), HarmonyPostfix] + public static void UpdateUI(RhythmGameChartEditorUI __instance) + { + foreach (var txt in __instance.dropdown.GetComponentsInChildren(true)) + txt.text = StringStore.TranslateText(txt.text); + } + + [HarmonyPatch(nameof(RhythmGameChartEditorUI.UpdateSelectedNoteInfo)), HarmonyPostfix] + public static void UpdateSelectedNoteInfo(RhythmGameChartEditorUI __instance) => + __instance.selectedNoteInfoText.text = StringStore.TranslateText(__instance.selectedNoteInfoText.text); +} diff --git a/Source/Patches/Modes/Super Editor/RhythmGame/RhythmGameManager_Patch.cs b/Source/Patches/Modes/Super Editor/RhythmGame/RhythmGameManager_Patch.cs new file mode 100644 index 0000000..10df0a3 --- /dev/null +++ b/Source/Patches/Modes/Super Editor/RhythmGame/RhythmGameManager_Patch.cs @@ -0,0 +1,44 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.Modes.Super_Editor.RhythmGame; + +[HarmonyPatch(typeof(RhythmGameManager))] +public static class RhythmGameManager_Patch +{ + [HarmonyPatch(nameof(RhythmGameManager.Awake)), HarmonyPatch(nameof(RhythmGameManager.ComboUpdate)), HarmonyPostfix] + public static void Awake(RhythmGameManager __instance) + { + if (!__instance.comboText) + return; + + __instance.comboText.autoSizeTextContainer = false; + __instance.comboText.ForceMeshUpdate(); + } + + [HarmonyPatch(nameof(RhythmGameManager.OnNoteClicked)), HarmonyPostfix] + public static void OnNoteClicked(RhythmGameManager __instance) + { + if (!__instance.particle) + return; + + var txtParticle = __instance.particle.GetComponent(); + + if (!txtParticle) + return; + + var txt = txtParticle.text.GetComponent(); + + if (!txt) + return; + + var originalKey = StringStore.TranslationString.FirstOrDefault(x => x.Value == txt.text).Key; + + txt.text = StringStore.TranslationString.ContainsKey(originalKey + "_RG") + ? StringStore.TranslateText(originalKey + "_RG") + : StringStore.TranslateText(txt.text); + + txt.autoSizeTextContainer = false; + txt.ForceMeshUpdate(); + } +} diff --git a/Source/Patches/OtherManagers/AchievementClip_Patch.cs b/Source/Patches/OtherManagers/AchievementClip_Patch.cs new file mode 100644 index 0000000..b60aad6 --- /dev/null +++ b/Source/Patches/OtherManagers/AchievementClip_Patch.cs @@ -0,0 +1,63 @@ +#if false +using HarmonyLib; +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) + { + var (achievementDir, fontAsset) = ModFeatures.IsMultiLanguage + ? (GetAssetDir(AssetType.Almanac, Utils.Language), FontStore.LoadTMPFont(Utils.Language.ToString())) + : (GetAssetDir(AssetType.Almanac), FontStore.LoadTMPFont()); + + var path = Path.Combine(achievementDir, "AchievementsTextTranslate.json"); + + if (!File.Exists(path)) + return; + + var 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; + } +} + +// ReSharper disable once ClassNeverInstantiated.Global +public sealed class AchievementObject +{ + public Achievement achievement { get; set; } + + // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Global + public string Name { get; set; } + + // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Global + public string Text { get; set; } + + public AchievementObject(Achievement achievement = Achievement.Welcome, string name = "", string text = "") + { + this.achievement = achievement; + Name = name; + Text = text; + } +} +#endif diff --git a/Source/Patches/OtherManagers/GardenUI_Patch.cs b/Source/Patches/OtherManagers/GardenUI_Patch.cs new file mode 100644 index 0000000..bd4594a --- /dev/null +++ b/Source/Patches/OtherManagers/GardenUI_Patch.cs @@ -0,0 +1,12 @@ +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +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); +} diff --git a/Source/Patches/OtherManagers/MenuText_Patch.cs b/Source/Patches/OtherManagers/MenuText_Patch.cs new file mode 100644 index 0000000..930b1f8 --- /dev/null +++ b/Source/Patches/OtherManagers/MenuText_Patch.cs @@ -0,0 +1,19 @@ +#if false +using HarmonyLib; +using PvZ_Fusion_Translator.AssetStore; + +namespace PvZ_Fusion_Translator.Patches.OtherManagers; + +[HarmonyPatch(typeof(MenuText))] +public static class MenuText_Patch +{ + [HarmonyPatch(nameof(MenuText.UpdateText), typeof(string)), HarmonyPostfix] + private static void UpdateTextPatch(MenuText __instance) + { + var text1 = __instance.transform.GetChild(0).Find("text1").GetComponent(); + text1.text = StringStore.TranslateText(text1.text); + var text = __instance.transform.GetChild(0).Find("text").GetComponent(); + text.text = StringStore.TranslateText(text1.text); + } +} +#endif diff --git a/Source/Patches/OtherManagers/ThanksMenu_Patch.cs b/Source/Patches/OtherManagers/ThanksMenu_Patch.cs new file mode 100644 index 0000000..07510fa --- /dev/null +++ b/Source/Patches/OtherManagers/ThanksMenu_Patch.cs @@ -0,0 +1,20 @@ +using HarmonyLib; +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) + { + var textTransform = __instance.transform.GetChild(0).GetComponent(); + + if (textTransform == null) + return; + + textTransform.text = StringStore.TranslateText(textTransform.text); + textTransform.autoSizeTextContainer = true; + } +} diff --git a/Source/PvZ Fusion Translator.csproj b/Source/PvZ Fusion Translator.csproj new file mode 100644 index 0000000..dee6099 --- /dev/null +++ b/Source/PvZ Fusion Translator.csproj @@ -0,0 +1,64 @@ + + + disable + false + latest + 1.0.0.0 + /home/emik/PvZ + enable + en-US + net6.0 + 1.0.0.0 + true + PvZ_Fusion_Translator + PvZ_Fusion_Translator + false + BepInEx + + + $(DefineConstants);BEPINEX + + https://api.nuget.org/v3/index.json; + https://nuget.bepinex.dev/v3/index.json; + https://nuget.samboy.dev/v3/index.json + + + + $(DefineConstants);MELONLOADER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/Utils.cs b/Source/Utils.cs new file mode 100644 index 0000000..6958efd --- /dev/null +++ b/Source/Utils.cs @@ -0,0 +1,668 @@ +using PvZ_Fusion_Translator.AssetStore; +using PvZ_Fusion_Translator.Patches.GameObjects; +using PvZ_Fusion_Translator.Patches.GameObjects.ButtonObjects; +using PvZ_Fusion_Translator.Patches.GameObjects.MinorObjects; +using System.Diagnostics; +using System.Reflection; +using System.Text.RegularExpressions; +using UnityEngine.Experimental.Rendering; +using UnityEngine.UI; + +namespace PvZ_Fusion_Translator; + +public static class Utils +{ + internal static bool TryReplaceTexture2D(Texture2D ogTexture) + { + if (ogTexture == null) + return false; + + if (!TextureStore.TextureDict.TryGetValue(ogTexture.name, out var textureData)) + return false; + + try + { + ImageConversion.LoadImage(ogTexture, textureData); + + 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); + 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."); + + var array = File.ReadAllBytes(path); + + Texture2D texture2D = new( + 2, + 2, + GraphicsFormat.R8G8B8A8_UNorm, + TextureCreationFlags.None, + 1, + IntPtr.Zero, + null + ); + + ImageConversion.LoadImage(texture2D, array); + return texture2D; + } + + internal static Texture2D LoadImage(byte[] bytes) + { + if (bytes == null) + throw new FileNotFoundException("Byte array was null."); + + Texture2D texture2D = new( + 2, + 2, + GraphicsFormat.R8G8B8A8_UNorm, + TextureCreationFlags.None, + 1, + IntPtr.Zero, + null + ); + + ImageConversion.LoadImage(texture2D, bytes); + return texture2D; + } + + public static Color HexToColor(string hex) + { + var r = int.Parse(hex.TrimStart("#")[..2], System.Globalization.NumberStyles.HexNumber) / 255f; + var g = int.Parse(hex.TrimStart("#")[2..4], System.Globalization.NumberStyles.HexNumber) / 255f; + var b = int.Parse(hex.TrimStart("#")[4..6], System.Globalization.NumberStyles.HexNumber) / 255f; + return new(r, g, b); + } + + public static void OpenSaveDirectory() + { + var saveDirectory = Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), + "AppData", + "LocalLow", + "LanPiaoPiao", + "PlantsVsZombiesRH" + ); + + Process.Start("explorer.exe", saveDirectory); + } + + public static void OpenOnlineAlmanac() + { + const string Website = "https://carroti4ch.itch.io/almanac"; + Process.Start(new ProcessStartInfo(Website) { UseShellExecute = true }); + } + + public static string RemoveColorTags(string text) + { + if (string.IsNullOrEmpty(text)) + return text ?? string.Empty; + + // Remove opening color tags like + var withoutOpenTags = Regex.Replace(text, "]+>", string.Empty, RegexOptions.IgnoreCase); + // Remove closing color tags like + var withoutCloseTags = Regex.Replace(withoutOpenTags, "", string.Empty, RegexOptions.IgnoreCase); + return withoutCloseTags; + } + + public static string RemoveSizeTags(string text) + { + if (string.IsNullOrEmpty(text)) + return text ?? string.Empty; + + // Remove opening size tags like + var withoutOpenTags = Regex.Replace(text, "]+>", string.Empty, RegexOptions.IgnoreCase); + // Remove closing size tags like + var withoutCloseTags = Regex.Replace(withoutOpenTags, "", string.Empty, RegexOptions.IgnoreCase); + return withoutCloseTags; + } + + public static string RemoveFormatTags(string text) + { + if (string.IsNullOrEmpty(text)) + return text ?? string.Empty; + + var withoutUnderlineTags = Regex.Replace(text, "", string.Empty, RegexOptions.IgnoreCase); + + var withoutUnderlineCloseTags = Regex.Replace( + withoutUnderlineTags, + "", + string.Empty, + RegexOptions.IgnoreCase + ); + + var withoutItalicTags = Regex.Replace( + withoutUnderlineCloseTags, + "", + string.Empty, + RegexOptions.IgnoreCase + ); + + var withoutItalicCloseTags = Regex.Replace( + withoutItalicTags, + "", + string.Empty, + RegexOptions.IgnoreCase + ); + + return withoutItalicCloseTags; + } + + public static string RemoveAllTags(string text) + { + if (string.IsNullOrEmpty(text)) + return text ?? string.Empty; + + return RemoveColorTags(RemoveSizeTags(RemoveFormatTags(text))); + } + + public static GameObject ConvertToTextMeshProUGUI(GameObject originalText, Transform parent, string name) + { + GameObject newObj = new(name) + { + transform = + { + position = originalText.transform.position, + }, + }; + + newObj.AddComponent(); + newObj.AddComponent(); + newObj.AddComponent(); + newObj.transform.SetParent(parent); + newObj.transform.localScale = Vector3.one; + + UnityEngine.Object.Destroy(originalText); + return newObj; + } + + public static void ConvertButtonText(Transform original, string name) + { + var fontAsset = FontStore.LoadTMPFont(Language.ToString()); + + var transform = original.FindChild(name); + var textTransform = transform.FindChild("text"); + var text = textTransform.GetComponent().text; + var color = textTransform.GetComponent().color; + + var newGoBackText = ConvertToTextMeshProUGUI(textTransform.gameObject, transform, "text2") + .GetComponent(); + + newGoBackText.autoSizeTextContainer = true; + newGoBackText.text = StringStore.TranslateText(text); + newGoBackText.font = fontAsset; + newGoBackText.color = color; + } + + public static string GetPlantNameFromAlmanac(PlantType thePlantType, bool removeTags = false, bool log = false) + { + var foundPlantName = false; + var thePlantName = ""; + + if (PlantIndices.ContainsKey((int)thePlantType)) + { + foundPlantName = true; + thePlantName = PlantIndices[(int)thePlantType].Value; + } + + if (!foundPlantName) + { + if (log) + Log.LogInfo("Couldn't find plant name!"); + + thePlantName = ""; + } + + thePlantName = removeTags ? RemoveAllTags(thePlantName) : thePlantName; + + return thePlantName; + } + + public static string GetPlantNameFromAlmanac( + string theOriginalPlantName, + bool removeTags = false, + bool log = false + ) + { + var foundPlantName = false; + var thePlantName = ""; + + if (PlantIndiceString.TryGetValue(theOriginalPlantName, out var value)) + { + foundPlantName = true; + thePlantName = value; + } + + if (!foundPlantName) + { + if (log) + Log.LogInfo("Couldn't find plant name!"); + + thePlantName = ""; + } + + thePlantName = removeTags ? RemoveAllTags(thePlantName) : thePlantName; + + return thePlantName; + } + + public static string GetZombieNameFromAlmanac(ZombieType theZombieType, bool removeTags = false) + { + var theZombieName = ""; + var json = AlmanacZombieMenu_Patch.AlmanacJson; + var zombieData = JsonUtility.FromJson(json); + + foreach (var zombieInfo in zombieData.zombies) + if ((int)zombieInfo.theZombieType == (int)theZombieType) + theZombieName = zombieInfo.name; + + theZombieName = removeTags ? RemoveAllTags(theZombieName) : theZombieName; + + return theZombieName; + } + +#pragma warning disable CA2211 + public static Dictionary> PlantIndices = new(); + + public static Dictionary PlantIndiceString = new(); +#pragma warning restore CA2211 + public static void RegisterPlantIndices() + { + PlantIndices = new(); + PlantIndiceString = new(); + + var dumpDir = FileLoader.GetAssetDir(FileLoader.AssetType.Dumps); + var originalPath = Path.Combine(dumpDir, "LawnStrings.json"); + + if (!File.Exists(originalPath)) + Log.LogError($"LawnStrings.json file not found at path: {originalPath}"); + else + try + { + var originalJson = File.ReadAllText(originalPath); + var translatedJson = AlmanacPlantMenu_Patch.AlmanacJson; + + var originalPlantData = JsonUtility.FromJson(originalJson); + var translatedPlantData = JsonUtility.FromJson(translatedJson); + + foreach (var originalPlantInfo in originalPlantData.plants) + { + if (!PlantIndiceString.ContainsKey(originalPlantInfo.name)) + PlantIndiceString.Add(originalPlantInfo.name, originalPlantInfo.name); + + Il2CppPlantInfo translatedPlantInfo = null; + + foreach (var info in translatedPlantData.plants) + if (info.seedType == originalPlantInfo.seedType) + translatedPlantInfo = info; + + if (translatedPlantInfo is not { name: not null }) + continue; + + KeyValuePair temp = new(translatedPlantInfo.seedType, translatedPlantInfo.name); + PlantIndices.Add(originalPlantInfo.seedType, temp); + PlantIndiceString[originalPlantInfo.name] = translatedPlantInfo.name; + } + } + catch (Exception e) + { + Log.LogError(e); + } + } + + public static void TryAdd(Dictionary dict, TA key, TB val) => dict[key] = val; + + public static void TryAdd(SortedDictionary dict, TA key, TB val) => dict[key] = val; + + public static AssetBundle GetAssetBundle(Assembly assembly, string assetBundlePath, bool log = false) + { + try + { + if (assembly == null) + throw new($"AssetBundle {assetBundlePath} was null."); + + using var manifestResourceStream = + assembly.GetManifestResourceStream($"PvZ_Fusion_Translator.Resources.{assetBundlePath}"); + + if (manifestResourceStream == null) + throw new("Stream was null."); + + var array = new byte[manifestResourceStream.Length]; + _ = manifestResourceStream.Read(array, 0, array.Length); + var assetBundle = AssetBundle.LoadFromMemory(array); + ArgumentNullException.ThrowIfNull(assetBundle); + + if (log) + Log.LogDebug($"AssetBundle {assetBundlePath} has successfully been loaded."); + + return assetBundle; + } + catch (Exception value) + { + throw new ArgumentException($"Failed to load {assetBundlePath}. \n{value}"); + } + } + + public static AssetBundle GetAssetBundle(string path) + { + var assetBundle = AssetBundle.LoadFromFile(path); + return assetBundle; + } +#if false + public static readonly Dictionary> recipeLinks = new(); + + public static void RegisterRecipeLinks() + { + recipeLinks.Clear(); + + Il2CppSystem.Array mixData = MixData.data.Cast(); + var rows = mixData.GetLength(0); + var columns = mixData.GetLength(1); + + foreach (var seedType in from PlantType plantType in Enum.GetValues(typeof(PlantType)) select (int)plantType) + { + recipeLinks.Add(seedType, new()); + + if (seedType > 0) + foreach (var checks in Enum.GetValues(typeof(PlantType)) + .Cast() + .Where(checkType => checkType > 0) + .Select( + int[] (checkType) => + [ + mixData.GetValue(seedType, (int)checkType).Unbox(), + mixData.GetValue((int)checkType, seedType).Unbox(), + ] + )) + { + if (checks[0] != 0) + recipeLinks[seedType].Add(checks[0]); + + if (checks[1] != 0) + recipeLinks[seedType].Add(checks[1]); + } + + if (recipeLinks[seedType].Count > 0) + Log.LogDebug($"Found {recipeLinks[seedType].Count} fusions for {seedType}!"); + } + } +#endif + public static readonly Regex UntranslatedRegex = new("\\p{IsCJKUnifiedIdeographs}+"); + + public static bool CheckForUntranslatedText(string text) + { + try + { + var match = UntranslatedRegex.Match(text); + return match.Success; + } + catch (Exception e) + { + Log.LogError(e); + } + + return false; + } + + public static void WarnLocalData() + { + var newMenu = GameAPP.UIManager.Push(UIType.ConfirmMenu, GameAPP.canvasUp); + var confirmMenu = newMenu.gameObject.GetComponent(); + + var modeTo = Core.Instance.ConfigUseLocal.Value ? "online mode" : "local mode"; + + confirmMenu.SetTitle( + $"WARNING: This button is meant for translator testing and can overwrite/interfere with the translation files saved in your installation. Proceed with caution. You are switching to {modeTo}.\nOnline Mode: Default, strings will auto-sync with the latest version when opening the game\nLocal Mode: Strings are only loaded from your installaion and do not update (meant for translators)" + ); + + confirmMenu.transform.Find("window/text").GetComponent().text = RemoveColorTags( + confirmMenu.transform.Find("window/text").GetComponent().text + ); + + var confirmButton = confirmMenu.transform.Find("Image").GetComponent(); + _ = confirmMenu.transform.Find("Image2").GetComponent(); + + confirmButton.clickEvent = new(); + confirmButton.clickEvent.AddListener(new Action(SwapLocalData)); + confirmButton.clickEvent.AddListener(new Action(CursorChange.SetDefaultCursor)); + confirmButton.clickEvent.AddListener(new Action(() => GameAPP.UIManager.Pop())); + } + + public static void SwapLocalData() + { + Core.Instance.ConfigUseLocal.Value = !Core.Instance.ConfigUseLocal.Value; + ChangeLanguage(Language.ToString()); + var sourceMsg = $"Translation Source:\n{(Core.Instance.ConfigUseLocal.Value ? "Local" : "Online")}"; + OptLanguageBtn_Patch.FlashMessage(OptLanguageBtn_Patch.ToggleSlots[2], sourceMsg, 0.1f, false); + CursorChange.SetDefaultCursor(); + } + + public static async Task GetDataFromWeb(string url, bool isLog = true) + { + if (isLog) + Log.LogInfo($"Attempting to read {url}"); + + try + { + var dataRequest = await s_client.GetAsync(url); + + if (dataRequest.StatusCode == System.Net.HttpStatusCode.OK) + { + if (isLog) + Log.LogInfo($"Successfully loaded data from {url}!"); + + var content = await dataRequest.Content.ReadAsStringAsync(); + return content; + } + + if (isLog) + { + Log.LogError($"Failed to load data from {url}! Falling back..."); + Log.LogError($"Status code: {dataRequest.StatusCode}"); + } + + new CancellationTokenSource().Cancel(); + return null; + } + catch (Exception ex) + { + Log.LogError($"Failed to load data from {url}! Falling back..."); + Log.LogError(ex); + new CancellationTokenSource().Cancel(); + return null; + } + } + + public static async Task GetByteDataFromWeb(string url, bool isLog = true) + { + if (isLog) + Log.LogInfo($"Attempting to read {url}"); + + try + { + var dataRequest = await s_client.GetAsync(url); + + if (dataRequest.StatusCode == System.Net.HttpStatusCode.OK) + { + if (isLog) + Log.LogInfo($"Successfully loaded data from {url}!"); + + var content = await dataRequest.Content.ReadAsByteArrayAsync(); + return content; + } + + if (isLog) + { + Log.LogError($"Failed to load data from {url}! Falling back..."); + Log.LogError($"Status code: {dataRequest.StatusCode}"); + } + + new CancellationTokenSource().Cancel(); + return null; + } + catch (Exception ex) + { + Log.LogError($"Failed to load data from {url}! Falling back..."); + Log.LogError(ex); + new CancellationTokenSource().Cancel(); + return null; + } + } + + public static async Task GetDataFromWebWithInput(string url, bool isLog = true) + { + if (isLog) + Log.LogInfo($"Attempting to read {url}"); + + using var request = new HttpRequestMessage(); + request.Method = HttpMethod.Get; + request.RequestUri = new(url); + + request.Headers.Add("Accept", "*/*"); + request.Headers.Add("Accept-Encoding", "gzip, deflate, br"); + request.Headers.Add("User-Agent", "TranslatorMod"); + + var dataRequest = await s_client.SendAsync(request); + + if (dataRequest.StatusCode == System.Net.HttpStatusCode.OK) + { + if (isLog) + Log.LogInfo($"Successfully loaded data from {url}!"); + + var content = await dataRequest.Content.ReadAsStringAsync(); + return content; + } + + if (isLog) + { + Log.LogError($"Failed to load data from {url}! Falling back..."); + Log.LogError($"Status code: {dataRequest.StatusCode}"); + } + + new CancellationTokenSource().Cancel(); + return null; + } + + public static int CalculateGameVersion(string gameVersion) + { + var res = 0; + var gameVersionParts = gameVersion.Split('.'); + + var startingPower = Math.Max(gameVersionParts.Length, 3); + + for (var i = 0; i < startingPower; i++) + { + var factor = 0; + + if (i < gameVersionParts.Length) + factor = int.Parse(gameVersionParts[i]); + + var power = startingPower - i; + res += factor * (int)Math.Pow(10, power - 1); + } + + return res; + } + + internal static void ChangeLanguage(string language) + { + UnityEngine.Debug.Assert(ModFeatures.IsMultiLanguage, nameof(ModFeatures.IsMultiLanguage)); + OldLanguage = Language; + + if (Enum.TryParse(language, out LanguageEnum lang)) + Language = lang; + else + // Handle invalid language string + Log.LogError($"Invalid language string: {language}"); + + //WarningStore.isWarningMessageLoaded = false; + FontStore.Reload(); + StringStore.Reload(); + TextureStore.Reload(); + FileLoader.SaveLanguage(); + RegisterPlantIndices(); + Zombie_Patch.LoadHpStrings(); + } +#pragma warning disable CA2211 // ReSharper disable once NotAccessedField.Global + public static LanguageEnum OldLanguage; + public static LanguageEnum Language; + + public enum LanguageEnum + { + // first column + English, + ChineseCn, + French, + + //Italian, + German, + Spanish, + + // second column + //Portuguese, + //Javanese, + //Filipino, + Vietnamese, + Indonesian, + + //Russian, //NOTE: legacy language + Japanese, + + // third column + Korean, + Ukrainian, + + // Slovak, + //Polish, + //Turkish, + Arabic, + Romanian, + + LangEnd, + } + + public static Dictionary LanguageNames = new() + { + { LanguageEnum.English, "English" }, + { LanguageEnum.ChineseCn, "简体中文" }, + { LanguageEnum.French, "Français" }, + { LanguageEnum.German, "Deutsch" }, + { LanguageEnum.Spanish, "Español" }, + { LanguageEnum.Vietnamese, "Tiếng Việt" }, + { LanguageEnum.Indonesian, "Bahasa Indonesia" }, + { LanguageEnum.Japanese, "日本語" }, + { LanguageEnum.Korean, "한국어" }, + { LanguageEnum.Ukrainian, "українська" }, + { LanguageEnum.Arabic, "ﺔﻴﺑﺮﻌﻟا" }, + { LanguageEnum.Romanian, "Română" }, + }; + + public static Dictionary ToggleNames = new() + { + { ToggleEnum.Textures, "Change Texture\nSource" }, + { ToggleEnum.Audio, "Change Audio\nSource" }, + { ToggleEnum.SwapLocal, "Change Translation\nSource" }, + }; + + private static readonly HttpClient s_client = new(); +#pragma warning restore CA2211 + public enum ToggleEnum + { + Textures, + Audio, + SwapLocal, + ToggleEnd, + } +}