360 lines
No EOL
11 KiB
C#
360 lines
No EOL
11 KiB
C#
#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<int, OptionButtonData> LanguageBtnDict = new();
|
|
public static Dictionary<int, OptionButtonData> 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<Utils.LanguageEnum> AvailableLanguages;
|
|
private static List<Utils.ToggleEnum> 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<Utils.LanguageEnum>()
|
|
.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<Transform>())
|
|
{
|
|
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<Utils.ToggleEnum>()
|
|
.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<Transform>())
|
|
{
|
|
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);
|
|
|
|
UpdateButtonText(btn, Utils.LanguageNames[lang], 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[toggle];
|
|
UpdateButtonText(btn, StringStore.TranslateText(buttonText), FontStore.LoadTMPFont(Utils.Language.ToString()));
|
|
if(i == 2)
|
|
{
|
|
string sourceMsg = "<size=10>" + (!(Utils.useLocal) ? "Translation Source:\nOnline" : "Translation Source:\nLocal");
|
|
FlashMessage(btn, sourceMsg, 0.1f, false);
|
|
}
|
|
}
|
|
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<TextMeshProUGUI>();
|
|
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<TextMeshProUGUI>();
|
|
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);
|
|
|
|
if(useTimer)
|
|
{
|
|
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" && type != "SwapLocal") return;
|
|
|
|
if(type == "Textures")
|
|
{
|
|
Utils.customTextures = !Utils.customTextures;
|
|
MelonPreferences.SetEntryValue<bool>("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<bool>("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, "<size=10>Toggled custom textures!", 0.1f);
|
|
}
|
|
else if (toggleType == "Audio")
|
|
{
|
|
FlashMessage(toggleData.Button, "<size=10>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 |