using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using TMPro; using TextUpgradesUIScale.Patches; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("DarkSpider90")] [assembly: Guid("a27adabc-310b-43d6-8584-f2e1ec7a34cb")] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = "")] [assembly: AssemblyTitle("TextUpgradesUIScale")] [assembly: AssemblyDescription("Resizes the R.E.P.O. upgrades UI text for large upgrade lists.")] [assembly: AssemblyFileVersion("1.2.1.0")] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyProduct("TextUpgradesUIScale")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: AssemblyVersion("1.2.1.0")] namespace TextUpgradesUIScale { [BepInPlugin("DarkSpider90.TextUpgradesUIScale", "TextUpgradesUIScale", "1.2.1")] public class Plugin : BaseUnityPlugin { private const string ModGuid = "DarkSpider90.TextUpgradesUIScale"; private const string ModName = "TextUpgradesUIScale"; private const string ModVersion = "1.2.1"; private readonly Harmony harmony = new Harmony("DarkSpider90.TextUpgradesUIScale"); internal static ManualLogSource Log { get; private set; } internal static ConfigEntry ModEnabled { get; private set; } internal static ConfigEntry StartShrinkingAfterUpgradesCount { get; private set; } internal static ConfigEntry ShrinkEveryUpgrades { get; private set; } internal static ConfigEntry ShrinkStep { get; private set; } internal static ConfigEntry LineSpacing { get; private set; } internal static ConfigEntry MaxTextWidthBeforeShrinking { get; private set; } private void Awake() { Log = ((BaseUnityPlugin)this).Logger; BindConfig(); Log.LogInfo((object)"Loaded TextUpgradesUIScale 1.2.1 for R.E.P.O. v0.4.0 UI."); harmony.PatchAll(typeof(StatsUIPatch)); } private void BindConfig() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected O, but got Unknown //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Expected O, but got Unknown ModEnabled = ((BaseUnityPlugin)this).Config.Bind("General", "EnableMod", true, "Enable or disable the mod."); StartShrinkingAfterUpgradesCount = ((BaseUnityPlugin)this).Config.Bind("Text fitting", "StartShrinkingAfterUpgradesCount", 10, new ConfigDescription("Start shrinking text after this many active upgrades.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), new object[0])); ShrinkEveryUpgrades = ((BaseUnityPlugin)this).Config.Bind("Text fitting", "ShrinkEveryUpgrades", 2, new ConfigDescription("Shrink text once per this many additional upgrades.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 20), new object[0])); ShrinkStep = ((BaseUnityPlugin)this).Config.Bind("Text fitting", "ShrinkStep", 0.07f, new ConfigDescription("Text scale removed per shrink step. 0.07 means 7%.", (AcceptableValueBase)(object)new AcceptableValueRange(0.01f, 0.5f), new object[0])); LineSpacing = ((BaseUnityPlugin)this).Config.Bind("Layout", "LineSpacing", -4f, new ConfigDescription("Extra vertical spacing between upgrade rows while scaled. Negative values make the list tighter.", (AcceptableValueBase)(object)new AcceptableValueRange(-30f, 30f), new object[0])); MaxTextWidthBeforeShrinking = ((BaseUnityPlugin)this).Config.Bind("Layout", "MaxTextWidthBeforeShrinking", 0f, new ConfigDescription("Shrink text if the upgrade names become wider than this value. Set to 0 to disable width-based shrinking.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 2000f), new object[0])); } } } namespace TextUpgradesUIScale.Patches { [HarmonyPatch(typeof(StatsUI), "Fetch")] public static class StatsUIPatch { private const float TechnicalMinimumScale = 0.05f; private static readonly FieldInfo TextField = AccessTools.Field(typeof(StatsUI), "Text"); private static readonly FieldInfo NumbersTextField = AccessTools.Field(typeof(StatsUI), "textNumbers"); private static readonly FieldInfo PlayerUpgradesField = AccessTools.Field(typeof(StatsUI), "playerUpgrades"); private static TextMeshProUGUI _cachedMainText; private static TextMeshProUGUI _cachedNumbersText; private static float _defaultFontSize; private static float _defaultNumbersFontSize; private static bool _defaultAutoSizing; private static bool _defaultNumbersAutoSizing; private static bool _defaultWordWrapping; private static bool _defaultNumbersWordWrapping; private static TextOverflowModes _defaultOverflowMode; private static TextOverflowModes _defaultNumbersOverflowMode; private static VerticalAlignmentOptions _defaultVerticalAlignment; private static VerticalAlignmentOptions _defaultNumbersVerticalAlignment; private static float _defaultLineSpacing; private static float _defaultNumbersLineSpacing; private static bool _defaultFontSizeInitialized; private static bool _loggedMissingFields; private static bool _loggedException; public static void Postfix(StatsUI __instance) { try { TextMeshProUGUI val = (TextMeshProUGUI)((TextField == null) ? null : /*isinst with value type is only supported in some contexts*/); TextMeshProUGUI val2 = (TextMeshProUGUI)((NumbersTextField == null) ? null : /*isinst with value type is only supported in some contexts*/); Dictionary dictionary = ((PlayerUpgradesField == null) ? null : (PlayerUpgradesField.GetValue(__instance) as Dictionary)); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || dictionary == null) { LogMissingFieldsOnce(); return; } CaptureDefaultsIfNeeded(val, val2); if (!Plugin.ModEnabled.Value) { RestoreTextColumns(val, val2); return; } int activeUpgradesCount = CountActiveUpgrades(dictionary); float scaleForUpgradeCount = GetScaleForUpgradeCount(activeUpgradesCount); scaleForUpgradeCount = ApplyWidthLimit(val, scaleForUpgradeCount); if (scaleForUpgradeCount >= 0.999f) { RestoreTextColumns(val, val2); return; } ConfigureTextColumn(val, _defaultLineSpacing); ConfigureTextColumn(val2, _defaultNumbersLineSpacing); ((TMP_Text)val).fontSize = _defaultFontSize * scaleForUpgradeCount; ((TMP_Text)val2).fontSize = _defaultNumbersFontSize * scaleForUpgradeCount; } catch (Exception ex) { if (!_loggedException) { _loggedException = true; if (Plugin.Log != null) { Plugin.Log.LogWarning((object)("[TextUpgradesUIScale] Failed to resize StatsUI text: " + ex.Message)); } } } } private static void CaptureDefaultsIfNeeded(TextMeshProUGUI mainText, TextMeshProUGUI numbersText) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) if (!_defaultFontSizeInitialized || !((Object)(object)_cachedMainText == (Object)(object)mainText) || !((Object)(object)_cachedNumbersText == (Object)(object)numbersText)) { _cachedMainText = mainText; _cachedNumbersText = numbersText; _defaultFontSize = ((TMP_Text)mainText).fontSize; _defaultNumbersFontSize = ((TMP_Text)numbersText).fontSize; _defaultAutoSizing = ((TMP_Text)mainText).enableAutoSizing; _defaultNumbersAutoSizing = ((TMP_Text)numbersText).enableAutoSizing; _defaultWordWrapping = ((TMP_Text)mainText).enableWordWrapping; _defaultNumbersWordWrapping = ((TMP_Text)numbersText).enableWordWrapping; _defaultOverflowMode = ((TMP_Text)mainText).overflowMode; _defaultNumbersOverflowMode = ((TMP_Text)numbersText).overflowMode; _defaultVerticalAlignment = ((TMP_Text)mainText).verticalAlignment; _defaultNumbersVerticalAlignment = ((TMP_Text)numbersText).verticalAlignment; _defaultLineSpacing = ((TMP_Text)mainText).lineSpacing; _defaultNumbersLineSpacing = ((TMP_Text)numbersText).lineSpacing; _defaultFontSizeInitialized = true; } } private static int CountActiveUpgrades(Dictionary playerUpgrades) { int num = 0; foreach (KeyValuePair playerUpgrade in playerUpgrades) { if (playerUpgrade.Value > 0) { num++; } } return num; } private static void ConfigureTextColumn(TextMeshProUGUI text, float defaultLineSpacing) { ((TMP_Text)text).enableAutoSizing = false; ((TMP_Text)text).enableWordWrapping = false; ((TMP_Text)text).overflowMode = (TextOverflowModes)0; ((TMP_Text)text).verticalAlignment = (VerticalAlignmentOptions)256; ((TMP_Text)text).lineSpacing = defaultLineSpacing + Plugin.LineSpacing.Value; } private static void RestoreTextColumns(TextMeshProUGUI mainText, TextMeshProUGUI numbersText) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) RestoreTextColumn(mainText, _defaultFontSize, _defaultAutoSizing, _defaultWordWrapping, _defaultOverflowMode, _defaultVerticalAlignment, _defaultLineSpacing); RestoreTextColumn(numbersText, _defaultNumbersFontSize, _defaultNumbersAutoSizing, _defaultNumbersWordWrapping, _defaultNumbersOverflowMode, _defaultNumbersVerticalAlignment, _defaultNumbersLineSpacing); } private static void RestoreTextColumn(TextMeshProUGUI text, float fontSize, bool autoSizing, bool wordWrapping, TextOverflowModes overflowMode, VerticalAlignmentOptions verticalAlignment, float lineSpacing) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) ((TMP_Text)text).fontSize = fontSize; ((TMP_Text)text).enableAutoSizing = autoSizing; ((TMP_Text)text).enableWordWrapping = wordWrapping; ((TMP_Text)text).overflowMode = overflowMode; ((TMP_Text)text).verticalAlignment = verticalAlignment; ((TMP_Text)text).lineSpacing = lineSpacing; } private static float GetScaleForUpgradeCount(int activeUpgradesCount) { int num = Mathf.Max(0, Plugin.StartShrinkingAfterUpgradesCount.Value); if (activeUpgradesCount <= num) { return 1f; } int num2 = Mathf.Max(1, Plugin.ShrinkEveryUpgrades.Value); float num3 = Mathf.Clamp(Plugin.ShrinkStep.Value, 0.01f, 0.5f); int num4 = Mathf.Max(0, activeUpgradesCount - num); int num5 = Mathf.CeilToInt((float)num4 / (float)num2); return ClampScale(1f - (float)num5 * num3); } private static float ApplyWidthLimit(TextMeshProUGUI mainText, float currentScale) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) float value = Plugin.MaxTextWidthBeforeShrinking.Value; if (value <= 1f) { return currentScale; } ConfigureTextColumn(mainText, _defaultLineSpacing); ((TMP_Text)mainText).fontSize = _defaultFontSize * currentScale; float x = ((TMP_Text)mainText).GetPreferredValues(((TMP_Text)mainText).text, float.PositiveInfinity, float.PositiveInfinity).x; if (x <= value) { return currentScale; } float num = 0.05f; float num2 = currentScale; for (int i = 0; i < 8; i++) { float num3 = (num + num2) * 0.5f; ((TMP_Text)mainText).fontSize = _defaultFontSize * num3; float x2 = ((TMP_Text)mainText).GetPreferredValues(((TMP_Text)mainText).text, float.PositiveInfinity, float.PositiveInfinity).x; if (x2 <= value) { num = num3; } else { num2 = num3; } } return ClampScale(num); } private static float ClampScale(float scale) { return Mathf.Clamp(scale, 0.05f, 1f); } private static void LogMissingFieldsOnce() { if (!_loggedMissingFields) { _loggedMissingFields = true; if (Plugin.Log != null) { Plugin.Log.LogWarning((object)"[TextUpgradesUIScale] Could not access StatsUI text fields. The game UI may have changed."); } } } } }